整理内容: - 删除 60+ 临时测试输出文件 (*.txt) - 移动二进制文件到 bin/ 目录 - 移动 Shell 脚本到 scripts/ 目录 - scripts/dev/: check_gitea.sh, check_sub2api.sh, run_tests.sh - scripts/deploy/: deploy_*.sh, simple_deploy.sh - scripts/ops/: fix_nginx.sh, fix_ssl.sh, install_docker.sh - scripts/test/: test_*.sh, test_*.bat - 移动批处理文件到 scripts/ - 移动 Python 脚本到 tools/ - 清理临时日志文件 保留根目录必要文件: - go.mod, go.sum, go.work - Makefile, docker-compose.yml - .env.example, .gitignore - README.md, AGENTS.md, DEPLOY_GUIDE.md 验证: go build ./... && go test ./... 通过
12 KiB
12 KiB
全面系统性审查报告
审查日期: 2026-04-02
审查范围: 后端 Go + 前端 React/TypeScript + PRD 对齐 + API 文档 + E2E 测试 + 安全
审查方法: 多智能体并行审查(后端审查、前端审查、PRD 缺口分析、API 文档审查)
一、执行摘要
综合评分
| 维度 | 得分 | 说明 |
|---|---|---|
| 后端代码质量 | 7.5/10 | 架构清晰,安全基础扎实,但存在 1 个严重问题和 8 个重要问题 |
| 前端代码质量 | 7.0/10 | 安全设计良好(内存 Token、window guard),但存在 4 个严重问题和 22 个重要问题 |
| 功能完整度 | 8.5/10 | 核心功能完整,主要缺口在前端缺失页面和批量操作 |
| E2E 覆盖度 | 6.0/10 | 15 个场景覆盖主流程,但多为"页面存在"级验证 |
| API 文档准确度 | 4.0/10 | 遗漏 38 个端点,文档需大幅更新 |
| 综合评分 | 6.6/10 | 核心链路可用,但距离"可诚实宣称全面收口"还有明显差距 |
问题统计
| 严重级别 | 后端 | 前端 | 总计 |
|---|---|---|---|
| 🔴 严重 | 1 | 4 | 5 |
| 🟡 重要 | 8 | 22 | 30 |
| 💭 轻微 | 12 | 8 | 20 |
| 总计 | 21 | 34 | 55 |
二、后端审查结果
2.1 🔴 严重问题(1 个)
| ID | 文件 | 问题 | 影响 |
|---|---|---|---|
| SEC-NEW-01 | internal/auth/sso.go |
SSO 会话存储在无界内存 map,无清理机制 | 内存泄漏、重启丢失所有 SSO 会话、DoS 风险 |
2.2 🟡 重要问题(8 个)
| ID | 文件 | 问题 |
|---|---|---|
| PERF-01 | internal/api/middleware/ratelimit.go |
SlidingWindowLimiter cleanupInt 死代码 |
| SEC-02 | internal/api/middleware/auth.go |
isJTIBlacklisted 使用 context.Background() |
| SEC-03 | internal/service/auth.go |
登录日志 goroutine 无生命周期管理 |
| SEC-04 | internal/service/webhook.go |
Webhook deliver() 使用 context.Background() |
| CORR-01 | internal/api/handler/auth_handler.go |
handleError 返回原始错误信息给客户端 |
| CORR-02 | internal/api/handler/sso_handler.go |
SSO handler 未检查类型断言(panic 风险) |
| PERF-02 | internal/service/stats.go |
GetUserStats 5+ 次独立 DB 查询(N+5 模式) |
| SEC-05 | internal/service/sms.go |
短信验证码使用非恒定时间比较 |
2.3 历史问题修复状态
| 问题 | 状态 |
|---|---|
| OAuth ValidateToken 始终返回 true | ✅ 已修复 |
| JTI 含可预测时间戳 | ✅ 已修复 |
| TOTP 使用 SHA1 | ✅ 已修复 → SHA256 |
| Refresh 接口无限流 | ✅ 已修复 |
| Webhook SSRF 风险 | ✅ 已修复 |
| Webhook context.Background() | ⚠️ 部分修复(有超时但仍用 Background) |
| 邮件 goroutine context 问题 | ❌ 未修复 |
| SlidingWindowLimiter 清理死代码 | ❌ 未修复 |
| stats N+5 查询 | ❌ 未修复 |
三、前端审查结果
3.1 🔴 严重问题(4 个)
| ID | 文件 | 问题 | 影响 |
|---|---|---|---|
| C01 | LoginPage.tsx:76-79 |
设备指纹存储在 localStorage | XSS 可读取设备追踪信息 |
| C02 | ProfileSecurityPage.tsx:308-314 |
TOTP 流程从 localStorage 读取设备指纹 | XSS 可注入恶意设备指纹 |
| C03 | client.ts:210-221 |
Token 刷新重试可能重复执行非幂等请求 | 可能导致重复创建用户等操作 |
| C04 | oauth.ts:3 |
Open redirect 验证不充分 | 可能被利用进行开放重定向攻击 |
3.2 🟡 重要问题(22 个)
主要类别:
- 性能: 所有管理页面的 table columns 在组件体内定义(6 个页面)
- 代码重复: triggerFileDownload 在 2 个文件中重复,resolveApiBaseUrl 在 2 个文件中重复
- 组件拆分: ProfileSecurityPage 946 行、30+ 状态变量,需要拆分为子组件
- 类型安全: UserEditDrawer、RoleFormModal 的 Form.useForm() 缺少类型参数
- 构建配置: vite.config.js 无代码分割配置
- 静态数据: SettingsPage 使用硬编码静态数据
四、PRD 缺口分析
4.1 功能实现状态
| 功能模块 | 状态 | 说明 |
|---|---|---|
| 邮箱注册 + 激活 | ✅ | 完整实现,E2E 覆盖 |
| 手机号注册 | ✅ | 完整实现 |
| 社交账号登录(9 平台) | ✅ | 完整实现 |
| TOTP 双因素认证 | ✅ | 完整实现,SHA256 |
| 密码重置(邮箱/短信) | ✅ | 完整实现 |
| RBAC 权限管理 | ✅ | 角色继承已修复 |
| 用户管理 CRUD | ✅ | E2E 覆盖 |
| 设备信任管理 | ⚠️ | API 完整,登录流程信任检查已接入 |
| 异地登录检测 | ⚠️ | AnomalyDetector 已注入,缺 GeoIP |
| 批量操作 | ❌ | 前端无批量操作 UI |
| 管理员管理页 | ❌ | 后端 API 存在,前端页缺失 |
| 系统设置页 | ❌ | 前端页缺失 |
| 全局设备管理页 | ❌ | 后端 API 存在,前端页缺失 |
| CAS/SAML SSO | ❌ | PRD 标注可选,建议 v2.0 |
| SDK(Java/Go/Rust) | ❌ | 未实现,建议 v2.0 |
| 防重放攻击 | ❌ | Nonce 机制未实现 |
4.2 关键缺口
- 前端缺失页面(3 个):管理员管理页、系统设置页、全局设备管理页
- 批量操作 UI:用户/角色批量删除、批量分配角色
- 防重放攻击:Nonce 机制未实现
五、API 文档审查
5.1 文档缺口统计
- 代码有但文档无: 38 个端点
- 文档有但代码无: 0 个
- 描述需补充: 2 个端点
5.2 未记录端点分类
| 类别 | 数量 | 端点 |
|---|---|---|
| 自定义字段管理 | 7 | /custom-fields CRUD + /users/me/custom-fields |
| 主题管理 | 7 | /themes CRUD + /theme/active + default |
| SSO | 5 | /sso/authorize, /sso/token, /sso/introspect, /sso/revoke, /sso/userinfo |
| 管理员设备管理 | 5 | /admin/devices CRUD + trust |
| 邮箱/手机绑定 | 6 | /users/me/bind-email/*, /users/me/bind-phone/* |
| 其他 | 8 | OAuth exchange, 短信密码重置, 登录日志导出, 管理员 CRUD |
5.3 建议
- 使用脚本从
router.go自动生成 API 文档骨架 - 补充请求/响应示例
- 更新权限说明
六、E2E 测试审查
6.1 当前覆盖场景(15 个)
| # | 场景 | 覆盖深度 | 说明 |
|---|---|---|---|
| 1 | admin-bootstrap | 🔵 深度 | 完整引导 → 登录 → 登出流程 |
| 2 | public-registration | 🔵 深度 | 注册 → 登录 → 登出流程 |
| 3 | email-activation | 🔵 深度 | 注册 → 收取邮件 → 激活 → 登录 → 登出 |
| 4 | login-surface | 🔵 深度 | 登录页 UI、capabilities、未登录重定向 |
| 5 | auth-workflow | 🔵 深度 | 登录 → 用户详情 → 角色分配 → 创建用户 → 登出 |
| 6 | responsive-login | 🔵 深度 | 三视口登录页验证 |
| 7 | desktop-mobile-navigation | 🔵 深度 | 桌面导航 + 移动端抽屉菜单 |
| 8 | user-management-crud | 🔵 深度 | 创建 → 编辑 → 详情 → 筛选 → 删除 |
| 9 | role-management-crud | 🟡 中等 | 角色列表 + 权限分配弹窗 |
| 10 | device-management | 🟡 中等 | 页面导航 + 列表显示 |
| 11 | login-logs | 🟡 中等 | 页面导航 + 列表显示 |
| 12 | operation-logs | 🟡 中等 | 页面导航 + 列表显示 |
| 13 | webhook-management | 🟡 中等 | 页面导航 + 列表显示 |
| 14 | profile-and-security | 🟡 中等 | 个人资料 + 安全设置可见性 |
| 15 | dashboard-stats | 🟡 中等 | 仪表盘统计卡片验证 |
6.2 E2E 缺口
| 缺口 | 优先级 | 说明 |
|---|---|---|
| 忘记密码流程(邮箱/短信) | 🔴 | PRD 核心流程,无 E2E 覆盖 |
| TOTP 启用/禁用完整流程 | 🟡 | 只验证可见,未验证交互 |
| 社交账号绑定/解绑 | 🟡 | 无 E2E 覆盖 |
| 角色创建/编辑/删除 | 🟡 | 只验证列表,未验证 CRUD |
| 权限 CRUD | 🟡 | 无 E2E 覆盖 |
| Webhook 创建/编辑/删除 | 🟡 | 只验证页面存在 |
| 用户导入/导出 | 🟡 | 无 E2E 覆盖 |
| 设备信任/取消信任 | 🟡 | 只验证页面存在 |
| 后台页面响应式 | 🟡 | 仅登录页做响应式验证 |
6.3 防虚假测试检查
✅ 通过项:
- 所有 E2E 测试启动真实后端进程(隔离测试数据库)
- 所有 E2E 测试启动真实前端开发服务器
- 所有 E2E 测试通过真实浏览器(CDP 协议)执行用户操作
- 所有 E2E 测试验证真实 API 响应(非 mock)
- 本地 SMTP 捕获服务验证邮件发送
- 信号收集器监控 console errors、dialogs、popups、request failures、401 responses
七、安全审查
7.1 安全优势
- ✅ 密码使用 Argon2id 哈希
- ✅ 敏感数据使用 crypto/rand 生成
- ✅ Webhook URL 有 SSRF 保护
- ✅ 接口限流已配置(含 refresh 接口)
- ✅ Access Token 仅存储在内存中
- ✅ 前端安装 window guard 阻断 alert/confirm/prompt/open
- ✅ CSRF Token 支持
- ✅ JWT JTI 黑名单机制
7.2 安全风险
| 风险 | 严重级别 | 说明 |
|---|---|---|
| SSO 会话内存泄漏 | 🔴 | 无界 map 无清理 |
| 设备指纹 localStorage | 🔴 | XSS 可读取/注入 |
| Open redirect 验证不足 | 🔴 | 可能被利用 |
| 非恒定时间比较 | 🟡 | SMS/邮箱验证码 |
| 错误信息泄露 | 🟡 | 返回原始错误给客户端 |
| context.Background() 滥用 | 🟡 | 5 处使用 |
八、优先级建议
P0:必须立即修复
- SEC-NEW-01: SSO 会话 map 添加清理机制或持久化
- C01/C02: 移除设备指纹的 localStorage 存储
- C04: 修复 OAuth open redirect 验证
- API.md: 补充 38 个未记录端点
P1:应在当前迭代解决
- SEC-02/03/04: 修复 context.Background() 滥用(5 处)
- SEC-05: SMS/邮箱验证码使用恒定时间比较
- CORR-01: 错误信息分类,不返回原始错误给客户端
- CORR-02: SSO handler 类型断言安全检查
- 前端: 所有管理页面 table columns 使用 useMemo
- 前端: ProfileSecurityPage 拆分为子组件
- E2E: 补充忘记密码流程测试
P2:下一轮持续优化
- PERF-02: stats.go 合并为单次 GROUP BY 查询
- 前端: 提取重复代码(triggerFileDownload、resolveApiBaseUrl)
- 前端: vite.config.js 添加代码分割配置
- 前端: 补齐缺失的服务层测试
- E2E: 深化现有场景的交互验证深度
- 前端: 补齐缺失页面(管理员管理、系统设置、全局设备管理)
- 安全: 实现防重放攻击 Nonce 机制
九、当前项目真实状态
可以说
- 后端核心功能完整,go vet/build/test 全绿
- 前端主后台已成型,15 个页面已实现
- 浏览器级真实 E2E 已覆盖 15 个场景
- 代码架构清晰(handler → service → repository,service → API → component)
- 安全基础扎实(Argon2id、crypto/rand、SSRF 保护、window guard)
不可以说
- "全部功能已闭环"(前端缺 3 个页面 + 批量操作)
- "E2E 测试已充分"(15 个场景多为页面存在级验证)
- "API 文档已完整"(遗漏 38 个端点)
- "无安全风险"(1 个严重 + 4 个严重前端问题待修复)
最诚实的表述
后端能力比较完整,前端主后台已经成型,代码质量总体在可控范围内,但"自动化验证闭环"和"PRD 最后一公里"还没有完全收口。
如果只看代码实现度,项目已经不低;如果按"可审计、可重复、可对外诚实宣称"的标准看,当前还差最后几步:
- 修复 5 个严重安全问题
- 补齐 3 个前端缺失页面
- 深化 E2E 测试覆盖深度
- 同步 API 文档
十、审查方法说明
本次审查采用多智能体并行模式:
- 后端审查智能体: 审查所有 Go 代码(安全、性能、错误处理、架构)
- 前端审查智能体: 审查所有 React/TypeScript 代码(安全、类型、性能、测试)
- PRD 缺口分析智能体: 对比 PRD 与实际实现,识别缺口
- API 文档审查智能体: 对比 API.md 与 router.go,识别文档缺口
审查覆盖:
- 后端: 30+ Go 文件(internal/api、service、repository、middleware、auth、config、database、cmd)
- 前端: 50+ TypeScript/TSX 文件(pages、components、services、lib、app)
- 文档: PRD、API.md、历史审查报告、项目状态文档