整理内容: - 删除 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 ./... 通过
297 lines
12 KiB
Markdown
297 lines
12 KiB
Markdown
# 全面系统性审查报告
|
||
|
||
**审查日期**: 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 关键缺口
|
||
|
||
1. **前端缺失页面**(3 个):管理员管理页、系统设置页、全局设备管理页
|
||
2. **批量操作 UI**:用户/角色批量删除、批量分配角色
|
||
3. **防重放攻击**: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:必须立即修复
|
||
|
||
1. **SEC-NEW-01**: SSO 会话 map 添加清理机制或持久化
|
||
2. **C01/C02**: 移除设备指纹的 localStorage 存储
|
||
3. **C04**: 修复 OAuth open redirect 验证
|
||
4. **API.md**: 补充 38 个未记录端点
|
||
|
||
### P1:应在当前迭代解决
|
||
|
||
5. **SEC-02/03/04**: 修复 context.Background() 滥用(5 处)
|
||
6. **SEC-05**: SMS/邮箱验证码使用恒定时间比较
|
||
7. **CORR-01**: 错误信息分类,不返回原始错误给客户端
|
||
8. **CORR-02**: SSO handler 类型断言安全检查
|
||
9. **前端**: 所有管理页面 table columns 使用 useMemo
|
||
10. **前端**: ProfileSecurityPage 拆分为子组件
|
||
11. **E2E**: 补充忘记密码流程测试
|
||
|
||
### P2:下一轮持续优化
|
||
|
||
12. **PERF-02**: stats.go 合并为单次 GROUP BY 查询
|
||
13. **前端**: 提取重复代码(triggerFileDownload、resolveApiBaseUrl)
|
||
14. **前端**: vite.config.js 添加代码分割配置
|
||
15. **前端**: 补齐缺失的服务层测试
|
||
16. **E2E**: 深化现有场景的交互验证深度
|
||
17. **前端**: 补齐缺失页面(管理员管理、系统设置、全局设备管理)
|
||
18. **安全**: 实现防重放攻击 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、历史审查报告、项目状态文档
|