diff --git a/.workbuddy/memory/2026-06-14-评审-P0安全.md b/.workbuddy/memory/2026-06-14-评审-P0安全.md new file mode 100644 index 0000000..483d1ab --- /dev/null +++ b/.workbuddy/memory/2026-06-14-评审-P0安全.md @@ -0,0 +1,64 @@ +# workbuddy 评审反馈 — 2026-06-14 P0 安全止血 + +**推送内容**: WS token 鉴权改造 + 坐席本地密码 + secret 管理规划文档 +**评审日期**: 2026-06-14 +**评审人**: Claude +**主报告**: `D:\资料\03-项目开发\wecom_it_smart_desk\docs\评审报告\workbuddy-2026-06-14-P0安全.md` +**commit**: 3735dc0 (本地 main,未推 Gitea) + +--- + +## ⭐ 给 workbuddy 的关键反馈(高优先级) + +1. **🔴 浏览器 WebSocket API 不支持自定义 header** — 误用 Node.js `ws` 库的 options.headers +2. **🔴 nginx access_log 没关** — 即使前端修好,token 仍经 access_log 泄露 +3. **🟡 Mapped[str] + nullable=True 类型不一致** — 改 Optional[str] +4. **🟡 企微降级放行仍能绕过 password 验证** — P0-#5 被反削弱 +5. **🟡 requirements.txt 缺 passlib** — 部署会 ImportError + +## 🔴 遗留 5 项(下一轮必修) + +| # | 严重度 | 文件 | 修复要点 | +|---|---|---|---| +| 1 | 🔴 P0 | `frontend-agent/.../useWebSocket.ts:106-110` | 改 `new WebSocket(wsUrl, [\`bearer.${token}\`])` + 服务端从 `sec-websocket-protocol` 取 | +| 2 | 🔴 P0 | `nginx.conf` + `deploy-server/nginx.conf` | 加 `location /ws/ { access_log off; }` | +| 3 | 🟡 P1 | `backend/app/models/agent.py:142-148` | `Mapped[str]` → `Mapped[Optional[str]]` | +| 4 | 🟡 P1 | `backend/app/api/agents.py` 降级放行 | 检测 `agent.password_hash` 存在 → 强制 password | +| 5 | 🟡 P1 | `backend/requirements.txt` | 加 `passlib[bcrypt]==1.7.4` 或改用原生 `bcrypt==4.1.2` | + +## 🟢 评审验收 + +- ✅ ws.py 服务端:header 优先 + query 降级,**逻辑正确** +- ✅ model 字段定义:`password_hash` String(128) nullable,**结构 OK**(类型注解除外) +- ✅ schema:`AgentLogin.password` + `AgentPasswordUpdate`,**OK** +- ✅ 改密端点 `POST /agents/password`:走 `Depends(get_current_agent)`,**OK** +- ✅ alembic 008:down_revision='007_role_system' 正确,**OK** +- ✅ docs/安全/secret-管理.md:**作为规划文档 OK** + +## 📊 完成度 + +| 任务 | 完成 | +|---|---| +| P0-#1 WECOM_SECRET 集中化 | 🟡 仅规划文档 | +| P0-#2 SSL 私钥在仓 | 🟢 之前已修(8-A 阶段) | +| P0-#3 Mock login | 🟢 之前已修 | +| P0-#4 WS token URL/日志 | 🟡 半成品(服务端 OK,前端 + nginx 待关) | +| P0-#5 坐席本地密码 | 🟡 半成品(模型/Schema/端点 OK,类型 + 降级 + 依赖) | + +**整体**: 2/5 P0 真正完成,3 项遗留待下一轮。 + +## 🔁 流程建议 + +- 推送前自检清单: + - [ ] 浏览器 WebSocket API 边界(不要用 `ws` 库的 options.headers) + - [ ] nginx/conf 改动 plan 写了就必须做 + - [ ] Mapped[T] + nullable=True 必须用 Optional + - [ ] 改代码必须同步 requirements.txt + - [ ] 加新鉴权必须 review 已有降级路径是否被绕过 +- **强烈建议**: workbuddy 推送前先回答"我的改动在浏览器侧能跑吗?"(不要假设 Node.js API = 浏览器 API) + +## 🔗 推 Gitea 状态 + +- **本地 commit 3735dc0**: ✅ 已存 +- **推 Gitea**: 🔴 卡 #8(MariaDB 套件未装) +- **下次**: Gitea 起来后 `git push -u origin main` 推 → workbuddy 拿 Gitea URL 二次评审 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..5da8857 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,193 @@ +# 贡献指南 (CONTRIBUTING) + +**适用范围**: 企微 IT 智能服务台 (`wecom_it_smart_desk`) +**维护者**: 宋献(项目负责人)+ Claude(评审协作)+ workbuddy(自动化开发) +**最后更新**: 2026-06-14 + +--- + +## 📌 仓库入口 + +- **Gitea(公网 Funnel)**: `https://ds923plus.tail58d872.ts.net/simon/wecom_it_smart_desk` +- **Gitea(内网 LAN)**: `http://100.85.152.112:8418/simon/wecom_it_smart_desk` +- **Tailscale 私网**: `100.85.152.112:8418` + +--- + +## 🌿 分支模型 + +| 分支 | 用途 | 保护规则 | +|---|---|---| +| `main` | 稳定可发布版本 | 🔒 禁止直推,需 PR + 1 reviewer | +| `develop` | 主开发分支 | 🟡 允许 push | +| `feature/*` | 新功能(从 develop 拉) | 🟢 自由 | +| `hotfix/*` | 紧急修复(从 main 拉) | 🟢 自由,合入需评审 | +| `release/*` | 发布准备 | 🟡 自由,合入 main 需评审 | + +**主分支**: `main`(默认推送目标) + +--- + +## 📝 Commit 规范 + +**格式** (Conventional Commits): + +``` +(): + + + +