docs: consolidate archive, SSOT guide, and agent entry stubs
Move line-walk/delta/phase2/frontend audits and legacy memory into docs/archive/, add functional development SSOT, thin AGENTS/CLAUDE stubs, and regenerate changelog/audit indexes via consolidate_docs.py.
This commit is contained in:
+27
-160
@@ -1,176 +1,43 @@
|
||||
# Nexus 6.0 — Cursor Rules
|
||||
# Nexus 6.0 — Cursor 速查
|
||||
|
||||
## 项目概述
|
||||
Nexus 是一个 2000+ 服务器运维管理平台。技术栈:FastAPI + Async SQLAlchemy + Redis + WebSocket + Telegram (后端),Vue 3 + Vuetify 4 + TypeScript SPA (前端,14页面)。项目 ~99% 完成。
|
||||
> SSOT: [docs/project/nexus-functional-development-guide.md](docs/project/nexus-functional-development-guide.md)
|
||||
> Handoff: [docs/project/AI-HANDOFF-2026-06-03.md](docs/project/AI-HANDOFF-2026-06-03.md)
|
||||
|
||||
## 基本信息
|
||||
- 仓库: http://66.154.115.8:3000/admin/Nexus.git
|
||||
- 本地路径: C:\Users\uzuma\Desktop\svn\Nexus
|
||||
- 生产域名: https://api.synaglobal.vip
|
||||
- 生产 IP: 47.254.123.106,后端端口 8600
|
||||
- 部署路径: /www/wwwroot/api.synaglobal.vip/
|
||||
- 管理员: admin / Nexus@2026
|
||||
- 数据库: MySQL nexus/Nexus@2026!@127.0.0.1:3306/nexus
|
||||
- SSH 别名: ssh nexus (key: id_rsa_nexus)
|
||||
## 栈
|
||||
|
||||
## 目录结构
|
||||
```
|
||||
Nexus/
|
||||
├── server/ ← FastAPI 后端 (Clean Architecture 4层)
|
||||
│ ├── api/ ← API 路由
|
||||
│ ├── domain/ ← SQLAlchemy 模型 (14+张表)
|
||||
│ ├── infrastructure/← SSH 连接池 + Redis + Telegram
|
||||
│ ├── background/ ← 后台任务
|
||||
│ └── config.py ← Pydantic Settings + MySQL 覆盖
|
||||
├── frontend/ ← Vue 3 + Vuetify 4 + TypeScript SPA
|
||||
│ └── src/pages/ ← 14 个页面组件
|
||||
├── web/app/ ← Vite 构建输出 (后端 StaticFiles 挂载点)
|
||||
├── deploy/ ← Supervisor + Nginx + 健康检查脚本
|
||||
├── docs/ ← 设计文档/审计/changelog
|
||||
└── .env ← NOT IN GIT (安装向导生成)
|
||||
```
|
||||
FastAPI + Async SQLAlchemy + Redis · Vue 3 + Vuetify 4 SPA(14 页)· Vite → `web/app/`
|
||||
|
||||
## 实现原则(强制)
|
||||
## 环境(勿在仓库写密码)
|
||||
|
||||
**所有设计和实现都必须是完美实现。**
|
||||
- 生产: `https://api.synaglobal.vip` · 端口 8600 · `ssh nexus`
|
||||
- 本地: `~/Nexus` 或 `$NEXUS_ROOT` · 见 [linux-dev-paths.md](docs/project/linux-dev-paths.md)
|
||||
- 凭据: 仅 `.env`(不入 git)
|
||||
|
||||
- ❌ 不允许为了实现而实现 — 每一行代码必须有明确的目的和质量标准
|
||||
- ❌ 不允许降级实现 — 不得以「先用着」为由降低安全、架构或代码质量标准
|
||||
- ❌ 不允许妥协实现 — 不得在发现问题后选择绕过而非根治
|
||||
- ❌ 不允许留技术债 — 发现问题必须当场修复,不得标注 TODO/FIXME 延后
|
||||
- ✅ 无法完美实现时必须停下来与用户交流后再换方案,不得擅自从权
|
||||
## 关键路径
|
||||
|
||||
## 安全铁律(强制)
|
||||
| 用途 | 路径 |
|
||||
|------|------|
|
||||
| 后端入口 | `server/main.py` |
|
||||
| 前端路由 | `frontend/src/router/index.ts` |
|
||||
| API 客户端 | `frontend/src/api/index.ts` |
|
||||
| Sync | `server/api/sync_v2.py` |
|
||||
| 门控 | `deploy/pre_deploy_check.sh` |
|
||||
| 本地验证 | `bash scripts/local_verify.sh` |
|
||||
|
||||
- ❌ 禁止明文密码出现在前端 JS 变量、localStorage、URL 参数中
|
||||
- ❌ 禁止静默吞错 — except 块不得空 pass 或 return None 掩盖异常
|
||||
- ❌ 禁止硬编码密钥/密码/Token — 必须走配置或环境变量
|
||||
- ❌ 禁止 f-string 拼 SQL — 必须参数化查询
|
||||
- ❌ 禁止未验证的用户输入拼入 shell 命令 — 必须用 shlex.quote() 或 subprocess 参数化
|
||||
- ✅ 敏感操作必须二次验证身份(re-auth pattern)
|
||||
- ✅ API 响应不得返回密码/密钥明文 — 用 password_set 布尔标记
|
||||
- ✅ 所有 CUD 操作必须记录审计日志
|
||||
## 铁律
|
||||
|
||||
## 文档纪律(强制)
|
||||
见 `.cursor/rules/perfect-implementation.mdc` · `nexus-security.mdc` — 完美实现、无静默吞错、无明文密钥、CUD 审计。
|
||||
|
||||
- 新功能/架构变更:先写 docs/design/specs/YYYY-MM-DD-*-design.md,再写代码
|
||||
- 开发前:写 docs/design/plans/ 或 docs/reports/ 技术文档
|
||||
- 项目缺文档的模块:改动时一并补全
|
||||
- 每次修改:在 docs/changelog/YYYY-MM-DD-*.md 留 changelog(行数≥10,不能空壳)
|
||||
## 部署
|
||||
|
||||
## 强制文件修改流程(不可跳步)
|
||||
|
||||
```
|
||||
实现 → WSL本地验证 → ★审计8步★ → 部署 → 健康检查 → 浏览器验证 → changelog
|
||||
```
|
||||
|
||||
进度条(每次改代码必须输出):
|
||||
```
|
||||
□实现 □WSL验证 □审计8步 □部署 □健康检查 □浏览器验证 □changelog
|
||||
```
|
||||
|
||||
审计8步:登记→全文Read→规则扫描H→Closure表→入口表→输入→Sink→归类→DoD
|
||||
|
||||
## 部署流程
|
||||
|
||||
### 后端部署
|
||||
```bash
|
||||
git push origin main
|
||||
ssh nexus "cd /www/wwwroot/api.synaglobal.vip && git fetch --all && git reset --hard origin/main && supervisorctl restart nexus"
|
||||
ssh nexus "sleep 3 && curl -s http://127.0.0.1:8600/health" # 预期: ok
|
||||
bash deploy/pre_deploy_check.sh && bash deploy/deploy-production.sh
|
||||
```
|
||||
|
||||
### 前端部署
|
||||
```bash
|
||||
cd frontend && npx vite build && cd ..
|
||||
tar czf /tmp/nexus-frontend.tar.gz -C web/app index.html assets/
|
||||
scp /tmp/nexus-frontend.tar.gz nexus:/tmp/nexus-frontend.tar.gz
|
||||
ssh nexus "cd /www/wwwroot/api.synaglobal.vip/web/app && tar xzf /tmp/nexus-frontend.tar.gz && rm /tmp/nexus-frontend.tar.gz"
|
||||
前端: `cd frontend && npx vite build` → tar/scp(见 `deploy/deploy-frontend.sh`)
|
||||
|
||||
## 进度条(改代码时输出)
|
||||
|
||||
```
|
||||
|
||||
### 本地开发
|
||||
```bash
|
||||
cd frontend && npm run dev # http://localhost:3000/app/
|
||||
□实现 □本地验证 □审计8步 □部署 □健康检查 □浏览器验证 □changelog
|
||||
```
|
||||
|
||||
## 7道门控 (deploy/pre_deploy_check.sh)
|
||||
|
||||
1. Changelog门 — 文件存在且行数≥10
|
||||
2. Audit门 — 文件存在且含 Step3+Closure+DoD
|
||||
3. Test门 — test_api.py 必须存在且通过
|
||||
4. Lint门 — ruff check server/ 零错误
|
||||
5. Import门 — import server.main 成功
|
||||
6. Security门 — bandit 无 HIGH/MEDIUM
|
||||
7. Review门 — 审计文件包含实际改动文件清单
|
||||
|
||||
## 已确认的关键决策
|
||||
|
||||
| 不可改项 | 原因 |
|
||||
|---------|------|
|
||||
| API_KEY | 加密一致性 + 子服务器认证 |
|
||||
| SECRET_KEY | 加密回退密钥 |
|
||||
| DATABASE_URL | 启动必需 |
|
||||
| ENCRYPTION_KEY | 凭据加密 |
|
||||
|
||||
| 可改项 | 说明 |
|
||||
|--------|------|
|
||||
| system_name/title | 前端显示 |
|
||||
| pool_size/overflow | 安装向导自动推荐 |
|
||||
| redis_url | Redis 连接 |
|
||||
| 告警阈值 | 默认 80% |
|
||||
| Telegram 配置 | 告警推送 |
|
||||
|
||||
## 关键文件速查
|
||||
|
||||
| 用途 | 文件路径 |
|
||||
|------|----------|
|
||||
| 后端入口 | server/main.py |
|
||||
| 数据模型 | server/domain/models/__init__.py |
|
||||
| JWT 认证 | server/api/auth_jwt.py |
|
||||
| 登录 API | server/api/auth.py |
|
||||
| WebSSH | server/api/webssh.py |
|
||||
| WebSocket | server/api/websocket.py |
|
||||
| 设置 CRUD | server/api/settings.py |
|
||||
| 服务器 CRUD | server/api/servers.py |
|
||||
| 快捷命令 | server/api/terminal.py |
|
||||
| Agent 心跳 | server/api/agent.py |
|
||||
| 同步引擎 | server/application/services/sync_engine_v2.py |
|
||||
| 前端入口 | frontend/src/main.ts |
|
||||
| 路由 | frontend/src/router/index.ts |
|
||||
| API 客户端 | frontend/src/api/index.ts |
|
||||
| Auth Store | frontend/src/stores/auth.ts |
|
||||
| 登录页 | frontend/src/pages/LoginPage.vue |
|
||||
| 终端页 | frontend/src/pages/TerminalPage.vue |
|
||||
| Vite 配置 | frontend/vite.config.mts |
|
||||
|
||||
## 已知待续事项(2026-06-01)
|
||||
|
||||
已修复:批量 Agent、JWT 60min+refresh、script-callback API Key、未知心跳丢弃、Admin 列迁移 — 见 `docs/changelog/2026-06-01-bug-remediation.md`。
|
||||
|
||||
| 优先级 | 问题 | 文件 |
|
||||
|--------|------|------|
|
||||
| P2 | 422 handler 是否精简 | server/main.py |
|
||||
| UX | 终端命令栏高亮对齐 | TerminalPage.vue |
|
||||
| 验收 | 告警/Telegram、WebSSH、Sync、三层守护 | 见 handoff §八 |
|
||||
|
||||
## 协作方式(单 Agent)
|
||||
|
||||
- 只与用户直接对话,不分派管理组/工程部/测试部/产品部/设计部,不自动加载 Skill 包。
|
||||
- 规范见 `.cursor/rules/no-department-agents.mdc`、`standards/`、`docs/design/`。
|
||||
|
||||
## 测试分工(强制)
|
||||
|
||||
**由 Agent 完成全部测试与修复验证;用户仅在 Agent 报告通过后做最终验收。**
|
||||
|
||||
Agent 在宣称「已修复 / 可交付」前必须自行完成(有证据:命令输出、生产 URL、浏览器抽测记录):
|
||||
|
||||
1. 本地:`ruff` / `import server.main` / `frontend` type-check(若改前端)
|
||||
2. 能跑则跑:`pytest tests/` 或 `tests/test_api.py`
|
||||
3. 生产或 WSL:`/health`、`test_api`、关键页面浏览器验证
|
||||
4. 更新 `docs/changelog/` + 必要时 `docs/reports/*-verification.md`
|
||||
|
||||
**禁止**把「请你试一下」「请人工确认」当作交付终点;未验证不得让用户代测 bug 是否修好。
|
||||
|
||||
用户终验:Agent 提交「验收清单」后,用户做最后一遍业务确认即可。
|
||||
|
||||
## 用中文回复
|
||||
|
||||
@@ -1,180 +1,44 @@
|
||||
# Nexus 6.0 — Project Memory
|
||||
# Nexus 6.0 — Agent 入口(薄 stub)
|
||||
|
||||
## 项目概述
|
||||
Nexus 是一个 2000+ 服务器运维管理平台,从旧的 MultiSync (PHP + AdminLTE + pymysql) 完全重构为 Clean Architecture (FastAPI + Async SQLAlchemy + Redis + WebSocket + Telegram)。前端已全面迁移到 Tailwind CSS v4 + Alpine.js,PHP 依赖已移除。
|
||||
> **长文 SSOT**: [docs/project/nexus-functional-development-guide.md](docs/project/nexus-functional-development-guide.md) + [附录](docs/project/nexus-functional-development-guide-appendix.md)
|
||||
> **会话接续**: [docs/project/AI-HANDOFF-2026-06-03.md](docs/project/AI-HANDOFF-2026-06-03.md)
|
||||
> **文档总索引**: [docs/README.md](docs/README.md)
|
||||
|
||||
## 仓库结构
|
||||
- **唯一仓库**: Nexus (Gitea, 仓库地址在 .env 中配置)
|
||||
- **不再使用** multi-server-sync 仓库(旧项目,仅保留历史)
|
||||
- **部署路径**: 由 `NEXUS_DEPLOY_PATH` 环境变量决定(安装向导自动写入 .env)
|
||||
- **域名/CORS**: 由 `NEXUS_CORS_ORIGINS` 环境变量决定(安装向导自动写入)
|
||||
## 项目概要
|
||||
|
||||
## 目录结构 (仓库根目录)
|
||||
```
|
||||
Nexus/
|
||||
├── server/ ← Python FastAPI后端 (Clean Architecture 4层)
|
||||
│ ├── api/ ← API路由 (含 install.py 安装向导API)
|
||||
│ ├── domain/ ← SQLAlchemy模型 (14张表)
|
||||
│ ├── infrastructure/← SSH连接池 + Redis + Telegram
|
||||
│ ├── background/ ← 后台任务 (心跳刷新/自检/调度/重试)
|
||||
│ └── config.py ← Pydantic Settings + MySQL覆盖
|
||||
├── web/app/ ← Tailwind+Alpine.js 纯静态前端 (12个HTML页面)
|
||||
│ ├── install.html ← 安装向导 (5步)
|
||||
│ ├── login.html ← JWT登录+TOTP双因素
|
||||
│ └── ... ← index/servers/files/push/scripts等
|
||||
├── deploy/ ← Supervisor配置 + Shell健康检查脚本
|
||||
├── docs/ ← 项目文档
|
||||
├── tests/ ← 测试
|
||||
├── .env ← NOT IN GIT (安装向导生成)
|
||||
└── requirements.txt ← Python依赖
|
||||
Nexus:2000+ 子机运维平台。后端 FastAPI + MySQL + Redis;前端 **Vue 3 + Vuetify 4 + TypeScript SPA**(14 页,`frontend/src/pages/`);构建输出 `web/app/`;安装向导 `web/app/install.html`。
|
||||
|
||||
## 本地开发
|
||||
|
||||
```bash
|
||||
docker compose up -d mysql redis
|
||||
bash scripts/start-dev.sh # API :8600
|
||||
bash scripts/local_verify.sh # L2b
|
||||
cd frontend && npm run dev # :3000/app/
|
||||
```
|
||||
|
||||
## 启动模式
|
||||
- **安装模式** (无 .env): 仅 `/api/install/` + 静态文件可用,其他路由返回503
|
||||
- **正常模式** (有 .env): 完整初始化 DB/Redis/后台任务
|
||||
路径见 [linux-dev-paths.md](docs/project/linux-dev-paths.md)。
|
||||
|
||||
## 实现原则(强制)
|
||||
## 强制约束
|
||||
|
||||
**所有设计和实现都必须是完美实现。** 详见 `.cursor/rules/perfect-implementation.mdc`。
|
||||
- 完美实现:`.cursor/rules/perfect-implementation.mdc`
|
||||
- 安全 / 后端 / 前端:`.cursor/rules/nexus-*.mdc`
|
||||
- 改代码必 `docs/changelog/YYYY-MM-DD-*.md`(≥10 行)
|
||||
- 测试由 Agent 完成;用户只做终验
|
||||
|
||||
| 禁止 | 要求 |
|
||||
|------|------|
|
||||
| 为实现而实现、降级、妥协、技术债(TODO/FIXME 延后) | 每一变更达到安全/架构/质量标准 |
|
||||
| 无法完美实现时擅自从权换方案 | 停下与用户沟通,确认后再换方案 |
|
||||
| 无文档直接开发 | 设计文档 → 技术文档 → 代码 |
|
||||
| 改代码不写 changelog | 每次修改记录到 `docs/changelog/YYYY-MM-DD-*.md` |
|
||||
## 不可改
|
||||
|
||||
文档路径:设计 `docs/design/specs/` · 技术 `docs/design/plans/` 或 `docs/reports/` · 变更 `docs/changelog/`
|
||||
`API_KEY` · `SECRET_KEY` · `ENCRYPTION_KEY` · `DATABASE_URL`
|
||||
|
||||
## AI 接续与标准(切换会话必读)
|
||||
## 部署
|
||||
|
||||
| 文档 | 路径 |
|
||||
|------|------|
|
||||
| 接续 SSOT | `docs/project/AI-HANDOFF-2026-05-23.md` |
|
||||
| **标准转接包(全量)** | `docs/project/standards-transfer-package.md` |
|
||||
| 验收 L0~L5 | `docs/project/development-acceptance-standard.md` |
|
||||
| 系统开发 / 逐行审计 | `standards/system-development-standard.md`、`standards/line-walk-audit-standard-v2.md`、`standards/audit-core-principles.md` |
|
||||
|
||||
逐行审查与开发规范**同等强制**(8 步、Closure 全表、FINDING 须 `文件:行号`、单回复 ≤5 文件)。
|
||||
|
||||
## Cursor 规则与 MCP
|
||||
|
||||
- 规则:`.cursor/rules/`(`perfect-implementation` + `nexus-*` + `audit-line-review` + `no-department-agents`)
|
||||
- 不安装项目级 Skill 包(已移除 superpowers-zh);TDD/调试/验收按 `standards/` 由 Agent 直接执行
|
||||
- MySQL MCP:`docs/project/mysql-mcp-setup.md` · 配置后运行 `python scripts/sync_mysql_mcp_env.py`
|
||||
|
||||
## 已确认的关键决策
|
||||
|
||||
| 决策 | 选择 | 原因 |
|
||||
|------|------|------|
|
||||
| API_KEY | ❌ 禁改,UI不显示 | 加密一致性 + 子服务器认证 |
|
||||
| SECRET_KEY | ❌ 禁改 | 加密回退密钥 |
|
||||
| DATABASE_URL | ❌ 禁改 | 启动必需 |
|
||||
| system_name/title | ✅ 可改 | 前端显示 |
|
||||
| pool_size/overflow | ✅ 可改 | 安装向导自动推荐 |
|
||||
| redis_url | ✅ 可改 | Redis连接 |
|
||||
| 告警阈值 (CPU/mem/disk) | ✅ 可改 | 监控参数 (默认80%) |
|
||||
| Telegram配置 | ✅ 可改 | 告警推送 |
|
||||
| Agent心跳间隔 | 60s | 不太频繁 |
|
||||
| Redis→MySQL刷新 | 10min | 降低MySQL负载 |
|
||||
| 心跳数据流 | Agent→Redis→前端直读→10min→MySQL | 前端实时, MySQL只存历史 |
|
||||
| 告警推送 | WebSocket→前端 + Telegram | 即时感知 |
|
||||
| Python守护 | 3层: Supervisor + Python自检(30s) + Shell(cron 1min) | 全覆盖 |
|
||||
| 安装向导 | install.html + FastAPI API | 纯Python,无PHP依赖 |
|
||||
| 配置源 | 安装向导→config.json+settings表(MySQL)+.env(Python) | 三写一致 |
|
||||
| Agent告警心跳 | CPU/内存>80% 或变化>10% 时主动上报 | 智能监控 |
|
||||
| 仓库统一 | 所有代码统一在Nexus仓库 | 不再用两个仓库 |
|
||||
|
||||
## 实现状态 (Phase A+B+C+D+E) — ~99% 完成
|
||||
|
||||
### ✅ 已完成 (全部6步 + 技术债务 + UX增强)
|
||||
| 模块 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| **Step 0: 基础设施** | | Redis + WebSocket |
|
||||
| E1 WebSocket推送 | server/api/websocket.py | alert/recovery/system broadcast |
|
||||
| E2 心跳→Redis+告警 | server/api/agent.py | Redis write + threshold detection |
|
||||
| E3 Redis→MySQL刷新 | server/background/heartbeat_flush.py | 10min batch |
|
||||
| **Step 1: 数据层** | | 14张表 |
|
||||
| E4 load_settings_from_db | server/config.py | MySQL overrides mutable settings |
|
||||
| **Step 2: 认证层** | | JWT + TOTP |
|
||||
| **Step 3: Web SSH** | | asyncssh + xterm.js |
|
||||
| E5 asyncssh连接池 | server/infrastructure/ssh/asyncssh_pool.py | 引用计数模式 |
|
||||
| E6 WebSSH前端 | web/app/terminal.html | xterm.js + Koko协议 + 自动resize |
|
||||
| **Step 4: Sync引擎** | | 4种同步模式 |
|
||||
| **Step 5: 前端迁移** | | Tailwind+Alpine.js |
|
||||
| E7 13个前端页面 | web/app/*.html | 含install.html安装向导 |
|
||||
| E8 安装向导API | server/api/install.py | 6端点, 无JWT, 临时引擎 |
|
||||
| E9 条件启动模式 | server/main.py | 无.env=安装模式 |
|
||||
| **后台任务** | | |
|
||||
| E10 Python自检 | server/background/self_monitor.py | 30s loop |
|
||||
| E11 Telegram推送 | server/infrastructure/telegram/__init__.py | alert/recovery/system |
|
||||
| E12 /health端点 | server/api/health.py | Shell health_monitor.sh checks this |
|
||||
| **技术债务** | | |
|
||||
| D1 ✅ paramiko删除 | — | pool.py已删除, 全部迁移asyncssh |
|
||||
| D2 ✅ install迁移 | server/api/install.py | PHP→install.html+API |
|
||||
| D3 ✅ WebSSH前端 | web/app/terminal.html | xterm.js+Koko协议+全屏 |
|
||||
| **安全增强** | | |
|
||||
| S1 JWT全局保护 | server/api/*.py | 所有业务API都有JWT验证 |
|
||||
| S2 审计日志 | server/api/*.py | 所有CUD操作记录审计日志 |
|
||||
| S3 登录防暴破 | server/application/services/auth_service.py | 失败计数+15min锁定+429状态码 |
|
||||
| **前端UX增强** | | |
|
||||
| UX1 共享布局 | web/app/layout.js | 11页面统一侧边栏+全局搜索+用户信息 |
|
||||
| UX2 Toast通知 | web/app/api.js | 全局toast()函数,4种类型 |
|
||||
| UX3 全局搜索 | server/api/search.py | 跨服务器/脚本/凭据/调度搜索 |
|
||||
| UX4 服务器详情 | web/app/servers.html | 点击展开详情面板(系统信息/同步日志/SSH会话) |
|
||||
| UX5 脚本编辑 | web/app/scripts.html | 点击脚本名编辑+执行结果格式化 |
|
||||
| UX6 推送增强 | web/app/push.html | 逐服务器状态+进度条+推送历史 |
|
||||
| UX7 审计分页 | web/app/audit.html | 分页控件+操作过滤+每页50条 |
|
||||
| UX8 重试操作 | web/app/retries.html | 手动重试+删除按钮+状态过滤 |
|
||||
| UX9 文件浏览 | web/app/files.html | 面包屑导航+目录排序+父目录链接 |
|
||||
| UX10 登录安全 | web/app/login.html | 密码可见切换+失败计数+429锁定+shake动画 |
|
||||
| **P1功能补全** | | |
|
||||
| P1-1 资产管理 | web/app/assets.html | Platform/Node管理页面 |
|
||||
| P1-2 服务器表单 | web/app/servers.html | 补全platform/node/protocols字段 |
|
||||
| P1-3 Push对接 | web/app/push.html + sync_v2.py | target_path对接+统一SyncEngineV2 |
|
||||
| P1-4 安全设置 | web/app/settings.html | TOTP QR码+修改密码+API Key复制 |
|
||||
| P1-5 WebSSH授权 | server/api/webssh.py | SSH凭据验证+4003关闭码+审计 |
|
||||
| P1-6 Agent认证 | server/api/agent.py | 每服务器API Key + 全局回退 |
|
||||
| P1-7 Config去重 | server/application/services/sync_engine_v2.py | sed去重+备份+_rollback_config() |
|
||||
| **P2安全增强** | | |
|
||||
| P2-1 告警防抖 | server/api/websocket.py | 5分钟冷却+Telegram去重+恢复重置 |
|
||||
| P2-2 命令日志 | web/app/commands.html | 命令/会话双视图+服务器过滤+危险命令高亮 |
|
||||
| P2-3 DB分页 | server/infrastructure/database/server_repo.py | DB层offset/limit+count |
|
||||
| P2-4 Dashboard实时 | web/app/index.html | WS触发stats刷新+声音+标签页闪烁 |
|
||||
| P2-5 移动适配 | web/app/layout.js | <768px侧边栏overlay+backdrop+表格滚动 |
|
||||
| P2-6 会话安全 | server/api/auth_jwt.py + api.js | 8小时超时+JWT updated_at+刷新重用检测 |
|
||||
| P2-7 凭据加密 | server/api/servers.py | Server.password/ssh_key_private Fernet加密存储 |
|
||||
| P2-8 凭据脱敏 | server/api/scripts.py + servers.py | API响应不返回密码,password_set布尔标记 |
|
||||
| P2-9 DB备份 | deploy/db_backup.sh | mysqldump+30天保留+cron集成 |
|
||||
|
||||
### 🔄 待测试
|
||||
- T1: 心跳Redis写入验证
|
||||
- T2: WebSocket连接测试
|
||||
- T3: 3层守护测试 (kill Python→Supervisor重启)
|
||||
- T4: Telegram推送测试
|
||||
- T5: install.html 5步流程测试
|
||||
|
||||
### 测试流程 (用户确认)
|
||||
1. WSL本地基础测试 → 2. 推到仓库 → 3. 外网服务器正式测试
|
||||
|
||||
## 配置三写机制
|
||||
安装向导 Step 3 POST处理同时写入:
|
||||
1. `web/data/config.json` — 共享配置 (API_BASE_URL, DB_*, API_KEY)
|
||||
2. `.env` — Python后端启动必需 (NEXUS_前缀)
|
||||
3. `settings` MySQL表 — 共享动态配置 (api_key, thresholds, Telegram等)
|
||||
|
||||
不可改项 (SECRET_KEY/API_KEY/ENCRYPTION_KEY/DATABASE_URL) 不在MySQL覆盖映射中。
|
||||
|
||||
## 3层守护机制
|
||||
- **Layer 1**: Supervisor — Python崩溃自动重启
|
||||
- **Layer 2**: Python self_monitor — 每30s检查Redis/MySQL/WebSocket
|
||||
- **Layer 3**: Shell health_monitor.sh — 每分钟HTTP GET /health, 连续3次失败→supervisorctl restart + Telegram
|
||||
|
||||
## 数据流
|
||||
```
|
||||
Agent心跳(60s) → Redis(实时) → 前端直读 → 10min批量 → MySQL(历史)
|
||||
告警: CPU/mem/disk > threshold → WebSocket推送浏览器 + Telegram推送手机
|
||||
恢复: 之前告警的指标恢复正常 → 自动推送恢复通知
|
||||
Redis心跳key: heartbeat:{server_id} (HSET, TTL=600s)
|
||||
Redis告警key: alerts:{server_id} (SET, TTL=3600s)
|
||||
```bash
|
||||
bash deploy/pre_deploy_check.sh
|
||||
bash deploy/deploy-production.sh # 需 SSH nexus + 用户批准
|
||||
```
|
||||
|
||||
详情见功能指南 §17–18。
|
||||
|
||||
## 归档文档
|
||||
|
||||
历史审计合并卷:`docs/archive/README.md`
|
||||
|
||||
@@ -1,278 +1,28 @@
|
||||
# Nexus 6.0 — Project Memory
|
||||
# Nexus 6.0 — Agent 入口(薄 stub)
|
||||
|
||||
## 项目概述
|
||||
Nexus 是一个 2000+ 服务器运维管理平台,从旧的 MultiSync (PHP + AdminLTE + pymysql) 完全重构为 Clean Architecture (FastAPI + Async SQLAlchemy + Redis + WebSocket + Telegram)。前端已全面迁移到 Tailwind CSS v4 + Alpine.js,PHP 依赖已移除。
|
||||
> 与 [AGENTS.md](AGENTS.md) 相同入口;长文见 [docs/project/nexus-functional-development-guide.md](docs/project/nexus-functional-development-guide.md)。
|
||||
|
||||
## 仓库结构
|
||||
- **唯一仓库**: Nexus (Gitea, 仓库地址在 .env 中配置)
|
||||
- **不再使用** multi-server-sync 仓库(旧项目,仅保留历史)
|
||||
- **部署路径**: 由 `NEXUS_DEPLOY_PATH` 环境变量决定(安装向导自动写入 .env)
|
||||
- **域名/CORS**: 由 `NEXUS_CORS_ORIGINS` 环境变量决定(安装向导自动写入)
|
||||
## 快速链接
|
||||
|
||||
## 目录结构 (仓库根目录)
|
||||
```
|
||||
Nexus/
|
||||
├── server/ ← Python FastAPI后端 (Clean Architecture 4层)
|
||||
│ ├── api/ ← API路由 (含 install.py 安装向导API)
|
||||
│ ├── domain/ ← SQLAlchemy模型 (14张表)
|
||||
│ ├── infrastructure/← SSH连接池 + Redis + Telegram
|
||||
│ ├── background/ ← 后台任务 (心跳刷新/自检/调度/重试)
|
||||
│ └── config.py ← Pydantic Settings + MySQL覆盖
|
||||
├── web/app/ ← Tailwind+Alpine.js 纯静态前端 (12个HTML页面)
|
||||
│ ├── install.html ← 安装向导 (5步)
|
||||
│ ├── login.html ← JWT登录+TOTP双因素
|
||||
│ └── ... ← index/servers/files/push/scripts等
|
||||
├── deploy/ ← Supervisor配置 + Shell健康检查脚本
|
||||
├── docs/ ← 项目文档
|
||||
├── tests/ ← 测试
|
||||
├── .env ← NOT IN GIT (安装向导生成)
|
||||
└── requirements.txt ← Python依赖
|
||||
```
|
||||
|
||||
## 启动模式
|
||||
- **安装模式** (无 .env): 仅 `/api/install/` + 静态文件可用,其他路由返回503
|
||||
- **正常模式** (有 .env): 完整初始化 DB/Redis/后台任务
|
||||
|
||||
## 已确认的关键决策
|
||||
|
||||
| 决策 | 选择 | 原因 |
|
||||
|------|------|------|
|
||||
| API_KEY | ❌ 禁改,UI不显示 | 加密一致性 + 子服务器认证 |
|
||||
| SECRET_KEY | ❌ 禁改 | 加密回退密钥 |
|
||||
| DATABASE_URL | ❌ 禁改 | 启动必需 |
|
||||
| system_name/title | ✅ 可改 | 前端显示 |
|
||||
| pool_size/overflow | ✅ 可改 | 安装向导自动推荐 |
|
||||
| redis_url | ✅ 可改 | Redis连接 |
|
||||
| 告警阈值 (CPU/mem/disk) | ✅ 可改 | 监控参数 (默认80%) |
|
||||
| Telegram配置 | ✅ 可改 | 告警推送 |
|
||||
| Agent心跳间隔 | 60s | 不太频繁 |
|
||||
| Redis→MySQL刷新 | 10min | 降低MySQL负载 |
|
||||
| 心跳数据流 | Agent→Redis→前端直读→10min→MySQL | 前端实时, MySQL只存历史 |
|
||||
| 告警推送 | WebSocket→前端 + Telegram | 即时感知 |
|
||||
| Python守护 | 3层: Supervisor + Python自检(30s) + Shell(cron 1min) | 全覆盖 |
|
||||
| 安装向导 | install.html + FastAPI API | 纯Python,无PHP依赖 |
|
||||
| 配置源 | 安装向导→config.json+settings表(MySQL)+.env(Python) | 三写一致 |
|
||||
| Agent告警心跳 | CPU/内存>80% 或变化>10% 时主动上报 | 智能监控 |
|
||||
| 仓库统一 | 所有代码统一在Nexus仓库 | 不再用两个仓库 |
|
||||
|
||||
## 实现状态 (Phase A+B+C+D+E) — ~99% 完成
|
||||
|
||||
### ✅ 已完成 (全部6步 + 技术债务 + UX增强)
|
||||
| 模块 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| **Step 0: 基础设施** | | Redis + WebSocket |
|
||||
| E1 WebSocket推送 | server/api/websocket.py | alert/recovery/system broadcast |
|
||||
| E2 心跳→Redis+告警 | server/api/agent.py | Redis write + threshold detection |
|
||||
| E3 Redis→MySQL刷新 | server/background/heartbeat_flush.py | 10min batch |
|
||||
| **Step 1: 数据层** | | 14张表 |
|
||||
| E4 load_settings_from_db | server/config.py | MySQL overrides mutable settings |
|
||||
| **Step 2: 认证层** | | JWT + TOTP |
|
||||
| **Step 3: Web SSH** | | asyncssh + xterm.js |
|
||||
| E5 asyncssh连接池 | server/infrastructure/ssh/asyncssh_pool.py | 引用计数模式 |
|
||||
| E6 WebSSH前端 | web/app/terminal.html | xterm.js + Koko协议 + 自动resize |
|
||||
| **Step 4: Sync引擎** | | 4种同步模式 |
|
||||
| **Step 5: 前端迁移** | | Tailwind+Alpine.js |
|
||||
| E7 13个前端页面 | web/app/*.html | 含install.html安装向导 |
|
||||
| E8 安装向导API | server/api/install.py | 6端点, 无JWT, 临时引擎 |
|
||||
| E9 条件启动模式 | server/main.py | 无.env=安装模式 |
|
||||
| **后台任务** | | |
|
||||
| E10 Python自检 | server/background/self_monitor.py | 30s loop |
|
||||
| E11 Telegram推送 | server/infrastructure/telegram/__init__.py | alert/recovery/system |
|
||||
| E12 /health端点 | server/api/health.py | Shell health_monitor.sh checks this |
|
||||
| **技术债务** | | |
|
||||
| D1 ✅ paramiko删除 | — | pool.py已删除, 全部迁移asyncssh |
|
||||
| D2 ✅ install迁移 | server/api/install.py | PHP→install.html+API |
|
||||
| D3 ✅ WebSSH前端 | web/app/terminal.html | xterm.js+Koko协议+全屏 |
|
||||
| **安全增强** | | |
|
||||
| S1 JWT全局保护 | server/api/*.py | 所有业务API都有JWT验证 |
|
||||
| S2 审计日志 | server/api/*.py | 所有CUD操作记录审计日志 |
|
||||
| S3 登录防暴破 | server/application/services/auth_service.py | 失败计数+15min锁定+429状态码 |
|
||||
| **前端UX增强** | | |
|
||||
| UX1 共享布局 | web/app/layout.js | 11页面统一侧边栏+全局搜索+用户信息 |
|
||||
| UX2 Toast通知 | web/app/api.js | 全局toast()函数,4种类型 |
|
||||
| UX3 全局搜索 | server/api/search.py | 跨服务器/脚本/凭据/调度搜索 |
|
||||
| UX4 服务器详情 | web/app/servers.html | 点击展开详情面板(系统信息/同步日志/SSH会话) |
|
||||
| UX5 脚本编辑 | web/app/scripts.html | 点击脚本名编辑+执行结果格式化 |
|
||||
| UX6 推送增强 | web/app/push.html | 逐服务器状态+进度条+推送历史 |
|
||||
| UX7 审计分页 | web/app/audit.html | 分页控件+操作过滤+每页50条 |
|
||||
| UX8 重试操作 | web/app/retries.html | 手动重试+删除按钮+状态过滤 |
|
||||
| UX9 文件浏览 | web/app/files.html | 面包屑导航+目录排序+父目录链接 |
|
||||
| UX10 登录安全 | web/app/login.html | 密码可见切换+失败计数+429锁定+shake动画 |
|
||||
| **P1功能补全** | | |
|
||||
| P1-1 资产管理 | web/app/assets.html | Platform/Node管理页面 |
|
||||
| P1-2 服务器表单 | web/app/servers.html | 补全platform/node/protocols字段 |
|
||||
| P1-3 Push对接 | web/app/push.html + sync_v2.py | target_path对接+统一SyncEngineV2 |
|
||||
| P1-4 安全设置 | web/app/settings.html | TOTP QR码+修改密码+API Key复制 |
|
||||
| P1-5 WebSSH授权 | server/api/webssh.py | SSH凭据验证+4003关闭码+审计 |
|
||||
| P1-6 Agent认证 | server/api/agent.py | 每服务器API Key + 全局回退 |
|
||||
| P1-7 Config去重 | server/application/services/sync_engine_v2.py | sed去重+备份+_rollback_config() |
|
||||
| **P2安全增强** | | |
|
||||
| P2-1 告警防抖 | server/api/websocket.py | 5分钟冷却+Telegram去重+恢复重置 |
|
||||
| P2-2 命令日志 | web/app/commands.html | 命令/会话双视图+服务器过滤+危险命令高亮 |
|
||||
| P2-3 DB分页 | server/infrastructure/database/server_repo.py | DB层offset/limit+count |
|
||||
| P2-4 Dashboard实时 | web/app/index.html | WS触发stats刷新+声音+标签页闪烁 |
|
||||
| P2-5 移动适配 | web/app/layout.js | <768px侧边栏overlay+backdrop+表格滚动 |
|
||||
| P2-6 会话安全 | server/api/auth_jwt.py + api.js | 8小时超时+JWT updated_at+刷新重用检测 |
|
||||
| P2-7 凭据加密 | server/api/servers.py | Server.password/ssh_key_private Fernet加密存储 |
|
||||
| P2-8 凭据脱敏 | server/api/scripts.py + servers.py | API响应不返回密码,password_set布尔标记 |
|
||||
| P2-9 DB备份 | deploy/db_backup.sh | mysqldump+30天保留+cron集成 |
|
||||
| **P3运维增强** | | |
|
||||
| P3-1 Nginx重定向 | deploy/nginx_https.conf | 注释化301规则:裸页面路径→/app/前缀 |
|
||||
| P3-2 自定义404 | server/main.py | StarletteHTTPExceptionHandler返回空白HTML,隐藏FastAPI标识 |
|
||||
|
||||
### 🔄 待测试
|
||||
- T1: 心跳Redis写入验证
|
||||
- T2: WebSocket连接测试
|
||||
- T3: 3层守护测试 (kill Python→Supervisor重启)
|
||||
- T4: Telegram推送测试
|
||||
- T5: install.html 5步流程测试
|
||||
|
||||
### 测试流程 (用户确认)
|
||||
1. WSL本地基础测试 → 2. 推到仓库 → 3. 外网服务器正式测试
|
||||
|
||||
## 配置三写机制
|
||||
安装向导 Step 3 POST处理同时写入:
|
||||
1. `web/data/config.json` — 共享配置 (API_BASE_URL, DB_*, API_KEY)
|
||||
2. `.env` — Python后端启动必需 (NEXUS_前缀)
|
||||
3. `settings` MySQL表 — 共享动态配置 (api_key, thresholds, Telegram等)
|
||||
|
||||
不可改项 (SECRET_KEY/API_KEY/ENCRYPTION_KEY/DATABASE_URL) 不在MySQL覆盖映射中。
|
||||
|
||||
## 3层守护机制
|
||||
- **Layer 1**: Supervisor — Python崩溃自动重启
|
||||
- **Layer 2**: Python self_monitor — 每30s检查Redis/MySQL/WebSocket
|
||||
- **Layer 3**: Shell health_monitor.sh — 每分钟HTTP GET /health, 连续3次失败→supervisorctl restart + Telegram
|
||||
|
||||
## 实现原则(强制 — 见 `.cursor/rules/perfect-implementation.mdc`)
|
||||
|
||||
**所有设计和实现都必须是完美实现。**
|
||||
|
||||
- ❌ 不允许为了实现而实现 — 每一行代码必须有明确的目的和质量标准
|
||||
- ❌ 不允许降级实现 — 不得以「先用着」为由降低安全、架构或代码质量标准
|
||||
- ❌ 不允许妥协实现 — 不得在发现问题后选择绕过而非根治
|
||||
- ❌ 不允许留技术债 — 发现问题必须当场修复,不得标注 TODO/FIXME 延后
|
||||
- ✅ 无法完美实现时必须停下来与用户交流后再换方案,不得擅自从权
|
||||
|
||||
**文档纪律:**
|
||||
|
||||
- 新功能/架构变更:先写 `docs/design/specs/YYYY-MM-DD-*-design.md`,再写代码
|
||||
- 开发前:写 `docs/design/plans/` 或 `docs/reports/` 技术文档(文件清单、步骤、测试、回滚)
|
||||
- 项目缺文档的模块:改动时一并补全
|
||||
- 每次修改:在 `docs/changelog/YYYY-MM-DD-*.md` 留 changelog
|
||||
|
||||
---
|
||||
|
||||
## 强制文件修改流程(不可跳步)
|
||||
|
||||
```
|
||||
实现 → WSL本地验证 → ★审计8步★ → 部署 → 健康检查 → 浏览器验证 → changelog
|
||||
```
|
||||
|
||||
**进度条(每次改代码必须输出,每完成一步打勾):**
|
||||
|
||||
```
|
||||
□实现 □WSL验证 □审计8步 □部署 □健康检查 □浏览器验证 □changelog
|
||||
```
|
||||
|
||||
用户只需看:没打勾的格子在打勾的格子后面 = 跳步了。
|
||||
跳步 = 严重过程违规,用户说「你跳步了」必须立即停止并补完。
|
||||
|
||||
审计8步(我内部执行,用户不需要检查细节):登记→全文Read→规则扫描H→Closure表→入口表→输入→Sink→归类→DoD
|
||||
审查4维度30项:安全12+逻辑8+性能5+质量5
|
||||
三个铁律:每个文件都要审、每行代码都要看、每个结论都要有证据
|
||||
|
||||
**程序门控 v2(deploy 时自动检查 7 道,不过不让部署):**
|
||||
|
||||
| # | 门 | 检查内容 | 防什么 |
|
||||
|---|----|---------|--------|
|
||||
| 1 | Changelog门 | 文件存在 **且行数≥10** | 空壳changelog |
|
||||
| 2 | Audit门 | 文件存在 **且含 Step3+Closure+DoD** | 空壳审计 |
|
||||
| 3 | Test门 | test_api.py **必须存在**且通过 | 删测试绕过 |
|
||||
| 4 | Lint门 | `ruff check server/` 零错误 | 代码质量问题 |
|
||||
| 5 | Import门 | `import server.main` 成功 | 语法/导入错误 |
|
||||
| 6 | Security门 | `bandit` 无 HIGH/MEDIUM | 安全反模式 |
|
||||
| 7 | Review门 | 审计文件包含实际改动文件清单 | 假审查 |
|
||||
|
||||
门控脚本: `deploy/pre_deploy_check.sh`(7门)
|
||||
门控日志: `deploy/gate_log.jsonl`(每次检查自动追加记录)
|
||||
MCP deploy 工具在 git pull + restart 前自动执行门控检查,任何一门不过返回 `🚫 DEPLOY BLOCKED`
|
||||
MCP gate_log 工具可查看历史门控记录
|
||||
审计模板: `docs/audit/TEMPLATE.md`
|
||||
Lint配置: `ruff.toml`
|
||||
开发依赖: `requirements-dev.txt`(ruff, bandit, pytest)
|
||||
|
||||
## 部署流程(SSH + SCP,不是 MCP deploy)
|
||||
|
||||
**MCP deploy 不可用**(GitHub 等 SaaS 的远程服务器 git pull 无凭据),实际部署用 SSH 命令直接操作:
|
||||
|
||||
### 后端部署
|
||||
|
||||
```bash
|
||||
# 1. Push 本地到 Gitea
|
||||
git push origin main
|
||||
|
||||
# 2. 服务器拉取最新代码 + 重启
|
||||
ssh nexus "cd /www/wwwroot/api.synaglobal.vip && git fetch --all && git reset --hard origin/main && supervisorctl restart nexus"
|
||||
|
||||
# 3. 健康检查
|
||||
ssh nexus "sleep 3 && curl -s http://127.0.0.1:8600/health"
|
||||
# 预期: "ok"(纯文本,非 JSON)
|
||||
```
|
||||
|
||||
### 前端部署(Vuetify SPA)
|
||||
|
||||
Vite 直接输出到 `web/app/`(后端 StaticFiles 挂载点),无需 dist 复制步骤:
|
||||
|
||||
```bash
|
||||
# 一键部署脚本(构建+打包+上传+提取+重启+验证)
|
||||
bash deploy/deploy-frontend.sh
|
||||
|
||||
# 或手动步骤:
|
||||
cd frontend && npx vite build && cd ..
|
||||
tar czf /tmp/nexus-frontend.tar.gz -C web/app index.html assets/
|
||||
scp /tmp/nexus-frontend.tar.gz nexus:/tmp/nexus-frontend.tar.gz
|
||||
ssh nexus "cd /www/wwwroot/api.synaglobal.vip/web/app && tar xzf /tmp/nexus-frontend.tar.gz && rm /tmp/nexus-frontend.tar.gz"
|
||||
ssh nexus "supervisorctl restart nexus"
|
||||
```
|
||||
|
||||
**注意**: 前端构建产物 (`web/app/index.html`, `web/app/assets/`) 已在 `.gitignore` 中,不进入 git。每次部署需重新构建+上传。
|
||||
|
||||
### 浏览器验证
|
||||
```bash
|
||||
curl -s -o /dev/null -w "%{http_code}" http://47.254.123.106:8600/app/ # 预期: 200
|
||||
```
|
||||
|
||||
### 部署常遇问题
|
||||
| 问题 | 解决 |
|
||||
| 用途 | 路径 |
|
||||
|------|------|
|
||||
| `/app/` 返回 404 | AppAuthMiddleware 拦截 — 确认 `/app/` 和 `/app/index.html` 在 `_APP_PUBLIC_PATHS` 中 |
|
||||
| `/app/` 返回旧 HTML (Tailwind/Alpine) | `git reset --hard` 恢复了旧文件 — 需要重新 tar+scp 前端构建产物 |
|
||||
| MCP deploy → git pull 失败 `could not read Username` | 服务器 remote URL 没配 token,用 `git remote set-url` |
|
||||
| Gate 2 Audit BLOCKED | 创建 `docs/audit/YYYY-MM-DD-topic.md`,含 Step3+Closure+DoD |
|
||||
| Gate 3 Test BLOCKED (401) | 服务器 .env 中 `NEXUS_TEST_ADMIN_PASSWORD` 与数据库不一致 |
|
||||
| Gate 6 Security BLOCKED (bandit HIGH) | md5 → sha256 等,参看 bandit 报告修复 |
|
||||
| Gate 7 Review BLOCKED | 审计文件缺少实际改动文件清单 |
|
||||
| 功能 / API / 14 页 | `docs/project/nexus-functional-development-guide.md` |
|
||||
| 附录(sync 端点、调用链) | `docs/project/nexus-functional-development-guide-appendix.md` |
|
||||
| 当前 handoff | `docs/project/AI-HANDOFF-2026-06-03.md` |
|
||||
| 本地验证 | `bash scripts/local_verify.sh` |
|
||||
| 验收 L0–L5 | `docs/project/development-acceptance-standard.md` |
|
||||
| 风险接受(单人运维) | `docs/project/risk-acceptance-single-operator.md` |
|
||||
| 文档索引 | `docs/README.md` |
|
||||
| 历史归档 | `docs/archive/README.md` |
|
||||
|
||||
### 部署信息速查
|
||||
- **部署用户**: root
|
||||
- **部署目录**: `/www/wwwroot/api.synaglobal.vip/`
|
||||
- **Supervisor 服务名**: `nexus`
|
||||
- **Supervisor 配置**: `/www/server/panel/plugin/supervisor/etc/supervisor.conf`
|
||||
- **SSH 别名**: `ssh nexus` (47.254.123.106, key: id_rsa_nexus)
|
||||
- **后端端口**: 8600
|
||||
- **Gitea Token SHA**: `26fee743a9332895b55f79b2dbe2e931dc7c2fe5` (nexus-deploy-token, write:repository)
|
||||
## 栈
|
||||
|
||||
**用户审查清单(验证AI是否偷懒):**
|
||||
1. 看 `deploy/gate_log.jsonl` — 每次门控都有记录,没有记录 = 没过门控
|
||||
2. 看审计文件 — 必须有 Closure 表(每个H的判定+依据)、Step 3 规则扫描、DoD
|
||||
3. 看进度条 — ☑必须在□前面,否则跳步
|
||||
4. 看 changelog — 行数≥10,不能是空壳
|
||||
FastAPI · Vue 3 SPA · Hash 路由 `#/` · 门控 `deploy/pre_deploy_check.sh`(7 道)
|
||||
|
||||
## 流程
|
||||
|
||||
## 数据流
|
||||
```
|
||||
Agent心跳(60s) → Redis(实时) → 前端直读 → 10min批量 → MySQL(历史)
|
||||
告警: CPU/mem/disk > threshold → WebSocket推送浏览器 + Telegram推送手机
|
||||
恢复: 之前告警的指标恢复正常 → 自动推送恢复通知
|
||||
Redis心跳key: heartbeat:{server_id} (HSET, TTL=600s)
|
||||
Redis告警key: alerts:{server_id} (SET, TTL=3600s)
|
||||
实现 → local_verify → 审计(按 diff 量级)→ changelog →(批准)部署
|
||||
```
|
||||
|
||||
强制规则:`.cursor/rules/` · `standards/`
|
||||
|
||||
+7
-316
@@ -1,320 +1,11 @@
|
||||
# Nexus 6.0 项目交接文档
|
||||
# Nexus 6.0 项目交接(已 supersede)
|
||||
|
||||
> **⚠️ 2026-05-23 起请以 SSOT 为准**: [`AI-HANDOFF`](docs/project/AI-HANDOFF-2026-05-23.md) · **全量标准** [`standards-transfer-package`](docs/project/standards-transfer-package.md) · 验收 [`development-acceptance-standard`](docs/project/development-acceptance-standard.md)
|
||||
> 本文保留历史结构;端口模型、待办 backlog、验证清单、否决项均以 SSOT 为准。
|
||||
请以以下文档为准:
|
||||
|
||||
## 项目概述
|
||||
|
||||
**项目名称**: Nexus 6.0
|
||||
**类型**: 2000+ 服务器运维管理平台
|
||||
**架构**: Clean Architecture (FastAPI + Async SQLAlchemy + Redis + WebSocket + Telegram)
|
||||
**前端**: Tailwind CSS v4 + Alpine.js(18 个 HTML 页面,含 `alerts.html`)
|
||||
**状态**: 核心代码 ~98% 完成;**尚未部署**;待办见 SSOT §4、验证见 SSOT §5
|
||||
|
||||
---
|
||||
|
||||
## 仓库信息
|
||||
|
||||
- **仓库地址**: Gitea (地址在 .env 中配置)
|
||||
- **当前工作目录(Linux)**: `~/Nexus`(见 `docs/project/linux-dev-paths.md`)
|
||||
- **Git分支**: 当前在 worktree 分支
|
||||
|
||||
---
|
||||
|
||||
## 技术栈
|
||||
|
||||
| 层级 | 技术 |
|
||||
| 文档 | 路径 |
|
||||
|------|------|
|
||||
| 后端框架 | FastAPI (Python 3.9+) |
|
||||
| 数据库 | MySQL 8.0 + Async SQLAlchemy 2.0 |
|
||||
| 缓存 | Redis |
|
||||
| 实时通信 | WebSocket |
|
||||
| SSH连接 | asyncssh (连接池模式) |
|
||||
| 告警推送 | Telegram Bot API |
|
||||
| 前端 | Tailwind CSS v4 + Alpine.js |
|
||||
| 进程守护 | Supervisor + Python自检 + Shell健康检查 |
|
||||
| 功能开发 SSOT | [docs/project/nexus-functional-development-guide.md](docs/project/nexus-functional-development-guide.md) |
|
||||
| 会话接续 | [docs/project/AI-HANDOFF-2026-06-03.md](docs/project/AI-HANDOFF-2026-06-03.md) |
|
||||
| 文档总索引 | [docs/README.md](docs/README.md) |
|
||||
|
||||
---
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
Nexus/
|
||||
├── server/ # Python FastAPI 后端
|
||||
│ ├── api/ # API路由层 (15个模块)
|
||||
│ │ ├── agent.py # Agent心跳接收
|
||||
│ │ ├── assets.py # Platform/Node资产管理
|
||||
│ │ ├── auth.py # JWT登录/TOTP
|
||||
│ │ ├── auth_jwt.py # JWT验证中间件
|
||||
│ │ ├── files.py # 文件浏览
|
||||
│ │ ├── install.py # 安装向导API
|
||||
│ │ ├── push.py # 推送调度
|
||||
│ │ ├── scripts.py # 脚本库管理
|
||||
│ │ ├── servers.py # 服务器CRUD
|
||||
│ │ ├── settings.py # 系统设置
|
||||
│ │ ├── sync_v2.py # 同步引擎v2 (4种模式)
|
||||
│ │ ├── webssh.py # WebSSH终端
|
||||
│ │ └── websocket.py # WebSocket告警推送
|
||||
│ ├── application/ # 应用服务层
|
||||
│ │ └── services/ # 业务逻辑 (SyncEngineV2等)
|
||||
│ ├── domain/ # 领域层
|
||||
│ │ └── models/ # SQLAlchemy ORM (14张表)
|
||||
│ ├── infrastructure/ # 基础设施层
|
||||
│ │ ├── database/ # 数据库访问 (Repository模式)
|
||||
│ │ ├── redis/ # Redis客户端
|
||||
│ │ ├── ssh/ # SSH连接池 (asyncssh)
|
||||
│ │ └── telegram/ # Telegram推送
|
||||
│ ├── background/ # 后台任务
|
||||
│ │ ├── self_monitor.py # Python自检 (30s)
|
||||
│ │ ├── heartbeat_flush.py # Redis→MySQL刷新 (10min)
|
||||
│ │ ├── scheduler.py # 定时推送调度
|
||||
│ │ └── retry_worker.py # 失败重试队列
|
||||
│ └── config.py # Pydantic Settings
|
||||
├── web/app/ # 前端页面 (15个HTML)
|
||||
│ ├── install.html # 安装向导 (5步)
|
||||
│ ├── login.html # JWT登录+TOTP
|
||||
│ ├── index.html # 仪表盘
|
||||
│ ├── servers.html # 服务器管理
|
||||
│ ├── assets.html # Platform/Node管理
|
||||
│ ├── push.html # 文件推送
|
||||
│ ├── scripts.html # 脚本库
|
||||
│ ├── commands.html # 命令日志查询
|
||||
│ ├── files.html # 远程文件浏览
|
||||
│ ├── settings.html # 系统设置
|
||||
│ ├── audit.html # 审计日志
|
||||
│ ├── retries.html # 重试队列
|
||||
│ ├── terminal.html # WebSSH终端
|
||||
│ ├── api.js # 共享API模块 (JWT+Toast)
|
||||
│ └── layout.js # 共享布局组件
|
||||
├── deploy/ # 部署配置
|
||||
│ ├── supervisor/ # Supervisor配置
|
||||
│ ├── nginx/ # Nginx配置
|
||||
│ └── db_backup.sh # 数据库备份脚本
|
||||
├── docs/ # 项目文档
|
||||
├── requirements.txt # Python依赖
|
||||
└── test_p1_p2.py # 验证测试脚本
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 数据库模型 (14张表)
|
||||
|
||||
| 表名 | 说明 |
|
||||
|------|------|
|
||||
| `admins` | 管理员用户 (JWT+TOTP支持) |
|
||||
| `servers` | 服务器资产 (核心表) |
|
||||
| `platforms` | 平台类型模板 |
|
||||
| `nodes` | 资产节点树 |
|
||||
| `sync_logs` | 同步操作日志 |
|
||||
| `push_schedules` | 定时推送调度 |
|
||||
| `push_retry_jobs` | 失败重试队列 |
|
||||
| `audit_logs` | 审计日志 |
|
||||
| `scripts` | 脚本库 |
|
||||
| `script_executions` | 脚本执行记录 |
|
||||
| `password_presets` | SSH密码预设 |
|
||||
| `db_credentials` | 数据库凭据 |
|
||||
| `ssh_sessions` | WebSSH会话 |
|
||||
| `command_logs` | SSH命令日志 |
|
||||
| `login_attempts` | 登录防暴破记录 |
|
||||
| `settings` | 系统配置键值对 |
|
||||
|
||||
---
|
||||
|
||||
## 核心功能清单
|
||||
|
||||
### P0 核心功能 (已完成)
|
||||
- [x] JWT认证 + TOTP双因素
|
||||
- [x] 登录防暴破 (15分钟锁定)
|
||||
- [x] Agent心跳上报 (Redis实时)
|
||||
- [x] WebSocket实时告警推送
|
||||
- [x] Telegram告警通知
|
||||
- [x] 安装向导 (5步)
|
||||
|
||||
### P1 功能 (已完成)
|
||||
- [x] Platform/Node资产管理
|
||||
- [x] 服务器详情面板 (点击展开)
|
||||
- [x] WebSSH终端 (xterm.js)
|
||||
- [x] 推送页面增强 (逐服务器状态+进度条)
|
||||
- [x] 脚本编辑+执行结果格式化
|
||||
- [x] 全局Toast通知系统
|
||||
- [x] 审计日志分页+过滤
|
||||
- [x] 重试队列手动操作
|
||||
- [x] 文件浏览 (面包屑导航)
|
||||
|
||||
### P2 功能 (已完成)
|
||||
- [x] 告警聚合防抖 (5分钟冷却)
|
||||
- [x] 命令日志查询页面
|
||||
- [x] 服务器列表DB级分页
|
||||
- [x] Dashboard WebSocket实时刷新
|
||||
- [x] 移动端响应式适配
|
||||
- [x] 会话安全加固 (8小时超时)
|
||||
- [x] 服务器凭据Fernet加密存储
|
||||
- [x] 凭据API脱敏 (password_set标记)
|
||||
- [x] 数据库自动备份脚本
|
||||
|
||||
### Sync引擎v2 (4种模式)
|
||||
- [x] S1: 文件同步 (rsync)
|
||||
- [x] S2: 命令批量执行 (SSH)
|
||||
- [x] S3: 配置推送 (sysctl) + 去重 + 回滚
|
||||
- [x] S4: SFTP文件传输
|
||||
|
||||
---
|
||||
|
||||
## 关键Bug修复记录
|
||||
|
||||
| 任务ID | 问题 | 修复内容 |
|
||||
|--------|------|----------|
|
||||
| #81 | DateTime默认求值BUG | 添加`_utcnow()`可调用函数,替换所有`default=datetime.now()` |
|
||||
| #82 | session.py logger未定义 | 添加`import logging`和`logger`定义,移除@property死代码 |
|
||||
| #83 | 审计日志缺失 | 验证所有CUD端点都有审计记录 |
|
||||
| #84 | 模型缺失索引 | 添加7个索引(login_attempts, audit_logs等) |
|
||||
|
||||
---
|
||||
|
||||
## 环境配置
|
||||
|
||||
### 必需环境变量 (.env文件)
|
||||
```bash
|
||||
# 数据库
|
||||
DATABASE_URL=mysql+aiomysql://user:pass@localhost/nexus
|
||||
|
||||
# 安全密钥 (安装时生成)
|
||||
SECRET_KEY=xxx
|
||||
API_KEY=xxx
|
||||
ENCRYPTION_KEY=xxx
|
||||
|
||||
# Redis
|
||||
REDIS_URL=redis://localhost:6379/0
|
||||
|
||||
# Telegram告警 (可选)
|
||||
TELEGRAM_BOT_TOKEN=xxx
|
||||
TELEGRAM_CHAT_ID=xxx
|
||||
|
||||
# 告警阈值
|
||||
CPU_ALERT_THRESHOLD=80
|
||||
MEM_ALERT_THRESHOLD=80
|
||||
DISK_ALERT_THRESHOLD=80
|
||||
```
|
||||
|
||||
### 启动模式
|
||||
- **安装模式** (无.env): 仅 `/api/install/` + 静态文件可用
|
||||
- **正常模式** (有.env): 完整初始化 DB/Redis/后台任务
|
||||
|
||||
---
|
||||
|
||||
## 部署步骤
|
||||
|
||||
### 1. 安装依赖
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 2. 运行安装向导
|
||||
访问 `http://localhost:8000/app/install.html`
|
||||
- Step 1: 数据库配置
|
||||
- Step 2: Redis配置
|
||||
- Step 3: 安全密钥生成
|
||||
- Step 4: Telegram配置 (可选)
|
||||
- Step 5: 创建管理员账号
|
||||
|
||||
### 3. 启动服务 (Supervisor)
|
||||
```bash
|
||||
# 复制配置
|
||||
cp deploy/supervisor/nexus.conf /etc/supervisor/conf.d/
|
||||
supervisorctl reread
|
||||
supervisorctl update
|
||||
supervisorctl start nexus
|
||||
```
|
||||
|
||||
### 4. 验证运行
|
||||
```bash
|
||||
# 健康检查
|
||||
curl http://localhost:8000/health
|
||||
|
||||
# 运行测试
|
||||
python test_p1_p2.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 团队分工建议
|
||||
|
||||
| 角色 | 职责 | 相关文件 |
|
||||
|------|------|----------|
|
||||
| **后端开发** | API开发、业务逻辑 | `server/api/*.py`, `server/application/services/*.py` |
|
||||
| **前端开发** | UI页面、交互逻辑 | `web/app/*.html`, `web/app/api.js`, `web/app/layout.js` |
|
||||
| **DevOps** | 部署、监控、备份 | `deploy/`, `supervisor/`, `nginx/` |
|
||||
| **DBA** | 数据库优化、迁移 | `server/domain/models/`, `server/infrastructure/database/` |
|
||||
| **安全** | 审计、加密、认证 | `server/api/auth*.py`, 凭据加密逻辑 |
|
||||
|
||||
---
|
||||
|
||||
## 监控与告警
|
||||
|
||||
### 3层守护机制
|
||||
1. **Supervisor**: Python崩溃自动重启
|
||||
2. **Python自检** (`self_monitor.py`): 30秒检查Redis/MySQL/WebSocket
|
||||
3. **Shell健康检查** (`health_monitor.sh`): 1分钟HTTP检查,3次失败重启
|
||||
|
||||
### 告警通道
|
||||
- WebSocket → 前端实时通知
|
||||
- Telegram → 手机推送
|
||||
|
||||
### 关键指标
|
||||
- Agent心跳间隔: 60秒
|
||||
- Redis→MySQL刷新: 10分钟
|
||||
- 会话超时: 8小时
|
||||
- 告警冷却: 5分钟
|
||||
|
||||
---
|
||||
|
||||
## 测试验证
|
||||
|
||||
### 已完成的测试
|
||||
```bash
|
||||
# 模块导入测试 (19/19通过)
|
||||
python -c "import server.domain.models; ..."
|
||||
|
||||
# 功能测试 (7/7通过)
|
||||
python test_p1_p2.py
|
||||
# - JWT updated_at claim
|
||||
# - JWT password invalidation
|
||||
# - Alert dedup cooldown
|
||||
# - Server repo pagination
|
||||
# - Config dedup command
|
||||
# - Server dict no password
|
||||
# - Admin.updated_at field
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
### ⚠️ 安全相关
|
||||
1. **API_KEY**: 禁止修改,用于Agent认证
|
||||
2. **SECRET_KEY**: 禁止修改,用于JWT签名
|
||||
3. **ENCRYPTION_KEY**: 禁止修改,用于凭据加密
|
||||
4. 生产环境必须修改默认密码
|
||||
|
||||
### ⚠️ 数据库迁移
|
||||
首次启动会自动执行 `_apply_migrations()`:
|
||||
- 添加 `admins.updated_at` 列
|
||||
- 创建7个索引 (如果不存在)
|
||||
|
||||
### ⚠️ 文件权限
|
||||
- SSH私钥文件需要正确权限 (600)
|
||||
- 日志目录需要写权限
|
||||
|
||||
---
|
||||
|
||||
## 联系方式
|
||||
|
||||
- 项目文档: `docs/`
|
||||
- 配置文件: `.env` (不提交到Git)
|
||||
- 测试脚本: `test_p1_p2.py`
|
||||
|
||||
---
|
||||
|
||||
**交接日期**: 2026/05/22
|
||||
**代码状态**: ✅ 开发完成,待部署测试
|
||||
**Git提交**: 建议提交当前worktree更改到主分支
|
||||
历史全文:[docs/archive/project/PROJECT_HANDOVER.md](docs/archive/project/PROJECT_HANDOVER.md)
|
||||
|
||||
+62
-113
@@ -1,125 +1,74 @@
|
||||
# Nexus 文档索引
|
||||
|
||||
> 最后更新: 2026-06-01
|
||||
> 更新: 2026-06-04 · **唯一导航入口**
|
||||
|
||||
---
|
||||
|
||||
## project/ — 项目概况
|
||||
## 1. 活跃 SSOT(日常必读)
|
||||
|
||||
| 文档 | 说明 |
|
||||
|------|------|
|
||||
| [project/nexus-functional-development-guide.md](project/nexus-functional-development-guide.md) | 功能 / API / 14 页 / 部署 |
|
||||
| [project/nexus-functional-development-guide-appendix.md](project/nexus-functional-development-guide-appendix.md) | sync 端点、调用链、E2E 对照 |
|
||||
| [project/AI-HANDOFF-2026-06-03.md](project/AI-HANDOFF-2026-06-03.md) | **当前** 会话接续(复制提示词) |
|
||||
| [project/development-acceptance-standard.md](project/development-acceptance-standard.md) | 验收 L0–L5 |
|
||||
| [project/local-integration-test.md](project/local-integration-test.md) | `bash scripts/local_verify.sh` |
|
||||
| [project/linux-dev-paths.md](project/linux-dev-paths.md) | Linux 路径 |
|
||||
| [project/risk-acceptance-single-operator.md](project/risk-acceptance-single-operator.md) | 单人运维风险接受 |
|
||||
| [project/script-execution.md](project/script-execution.md) | 脚本执行 |
|
||||
| [project/alert-push-policy.md](project/alert-push-policy.md) | 告警策略 |
|
||||
| [project/deploy.md](project/deploy.md) | 部署补充 |
|
||||
| [project/production-verification-checklist.md](project/production-verification-checklist.md) | L5 清单 |
|
||||
|
||||
根目录 [AGENTS.md](../AGENTS.md) · [CLAUDE.md](../CLAUDE.md) · [.cursorrules](../.cursorrules) 为薄入口。
|
||||
|
||||
---
|
||||
|
||||
## 2. 变更与审计
|
||||
|
||||
| 目录 | 说明 |
|
||||
|------|------|
|
||||
| [changelog/](changelog/) | 每次代码变更(**不归档、不合并**)· [INDEX](changelog/INDEX.md) |
|
||||
| [audit/](audit/) | 门控用审计 · [INDEX](audit/INDEX.md) · `2026-06-04-bug-scan-registry.json` |
|
||||
|
||||
---
|
||||
|
||||
## 3. 活跃报告(`reports/`)
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `project/status.md` | 项目进度总览 + 数据库结构 + 实施进度 |
|
||||
| `project/roadmap.md` | 功能规划 + ADR架构决策(11项) + 技术债务 |
|
||||
| `project/deploy.md` | 部署指南 (Ubuntu 20-24, Nginx+Supervisor) |
|
||||
| **`project/phase-2-audit-remediation.md`** | **Phase 2 审计修复总览(开发 SSOT)** |
|
||||
| **`project/wsl-integration-test.md`** | **WSL 代码验证**(venv → 启动 → smoke,不审 key) |
|
||||
| `project/production-verification-checklist.md` | 首次部署验证清单(逐项勾选) |
|
||||
| `project/alert-push-policy.md` | 告警推送产品策略 + 数据流 |
|
||||
| `project/script-execution.md` | 脚本批量执行平台 SSOT |
|
||||
| `project/audit-line-review-cursor-rule.md` | 逐行走读 Cursor 规则 |
|
||||
| `project/line-walk-audit-standard.md` | 逐行走读判定标准 |
|
||||
| `project/mysql-mcp-setup.md` | Cursor MySQL MCP 安装与 `.env` 同步 |
|
||||
| `project/tech-stack-inventory.md` | 技术栈清单 + 连接池参数对齐 + v1勘误 |
|
||||
| [audit-plugin-run-final-2026-06-04.md](reports/audit-plugin-run-final-2026-06-04.md) | 插件审计总验收 |
|
||||
| [audit-frontend-14p-2026-06-04-closure.md](reports/audit-frontend-14p-2026-06-04-closure.md) | 前端 14 页 closure |
|
||||
| [audit-phase-4-plugin-closure-2026-06-04.md](reports/audit-phase-4-plugin-closure-2026-06-04.md) | Phase4 收尾 |
|
||||
| [2026-06-01-production-verification.md](reports/2026-06-01-production-verification.md) | 生产验证(待更新 L5) |
|
||||
| [2026-06-01-final-acceptance-checklist.md](reports/2026-06-01-final-acceptance-checklist.md) | 终验清单 |
|
||||
|
||||
## design/ — 设计规格与实施计划
|
||||
批量 batch 报告 → [archive/audits/](archive/audits/) 合并卷。
|
||||
|
||||
### 活跃设计
|
||||
| 文件 | 说明 |
|
||||
---
|
||||
|
||||
## 4. 设计与标准
|
||||
|
||||
| 目录 | 说明 |
|
||||
|------|------|
|
||||
| `design/specs/design-standards.md` | **设计标准** — 安全模型/性能基线/代码规范/架构模式 |
|
||||
| `design/specs/2026-05-18-redis-iot-optimization.md` | Redis+实时数据架构 + Key规范 |
|
||||
| `design/specs/2026-05-17-architecture-optimization.md` | 配置分发与部署架构 |
|
||||
| `design/specs/2026-05-19-sprint-planning.md` | Sprint规划 — 已完成升级项 + 待实现建议 |
|
||||
| `design/tech-stack-evaluation.md` | 技术栈评估 + 风险矩阵 + 连接池配置 |
|
||||
| [design/specs/](design/specs/) | 设计规格 |
|
||||
| [design/plans/](design/plans/) | 实施计划 |
|
||||
| [../standards/](../standards/) | 开发与审计标准 |
|
||||
| [project/standards-transfer-package.md](project/standards-transfer-package.md) | 标准转接包 |
|
||||
|
||||
### 已归档设计(历史参考)
|
||||
| 文件 | 说明 |
|
||||
---
|
||||
|
||||
## 5. 归档区
|
||||
|
||||
**[archive/README.md](archive/README.md)** — 2026-06 审计合并卷、旧 handoff、agentmemory、2026-05 审查报告。
|
||||
|
||||
---
|
||||
|
||||
## 6. 工具脚本
|
||||
|
||||
| 脚本 | 用途 |
|
||||
|------|------|
|
||||
| `design/specs/2026-05-16-password-presets-design.md` | ⚠️ 归档 — 密码预设设计(引用旧文件结构) |
|
||||
| `design/specs/2026-05-16-simplified-push-design.md` | ⚠️ 归档 — 简化推送设计(引用旧文件结构) |
|
||||
| `design/specs/2026-05-17-retry-progress-design.md` | ⚠️ 归档 — 重试+进度设计(引用旧文件结构) |
|
||||
| `design/specs/2026-05-17-server-add-optimize-design.md` | ⚠️ 归档 — 服务器添加优化设计(引用旧文件结构) |
|
||||
| `design/specs/2026-05-18-file-manager-v2-design.md` | ⚠️ 归档 — 文件管理器v2设计(引用旧文件结构) |
|
||||
| `design/specs/2026-05-19-code-review-followup.md` | ⚠️ 归档 — PHP代码审查(前端已迁移到Tailwind) |
|
||||
| `design/plans/2026-05-16-password-presets.md` | ⚠️ 归档 — 密码预设实施计划 |
|
||||
| `design/plans/2026-05-16-simplified-push.md` | ⚠️ 归档 — 简化推送实施计划 |
|
||||
| `design/plans/2026-05-17-retry-progress.md` | ⚠️ 归档 — 重试+进度实施计划 |
|
||||
| `design/plans/2026-05-17-server-add-optimize.md` | ⚠️ 归档 — 服务器添加优化实施计划 |
|
||||
| `design/plans/2026-05-18-file-manager-v2.md` | ⚠️ 归档 — 文件管理器v2实施计划 |
|
||||
|
||||
## reports/ — 审查与工作报告
|
||||
|
||||
### Phase 2 逐行走读(2026-05-22~23)
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| **`reports/audit-phase-2-findings-matrix.md`** | **63 条 FINDING 全量状态表** |
|
||||
| `reports/audit-phase-2-walk-closure.md` | 走读闭环 |
|
||||
| `reports/audit-phase-2a`~`2j-line-walk.md` | 各批次逐行报告 |
|
||||
| `reports/2026-05-23-full-audit-report.md` | 7 部门并行初审(与 Phase 2 交叉引用) |
|
||||
| `reports/audit-full-vs-phase2-reconciliation.md` | C1–C12 与 Phase 2 对照表 |
|
||||
|
||||
### 部门审查报告
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `reports/review-cto-2026-05-21.md` | CTO审查 — 连接池/SSH/CORS/依赖(含勘误) |
|
||||
| `reports/review-deploy-architecture-2026-05-21.md` | 运维总监审查 — 部署架构/三层守护/Nginx(含勘误) |
|
||||
| `reports/review-quality-director-2026-05-21.md` | 质量总监审查 — 代码规范/datetime/测试(含勘误) |
|
||||
| `reports/step-0-infrastructure/ecc-security-report.md` | ECC组安全审查 — Redis/Schema/认证/SSH/编码(含勘误) |
|
||||
| `reports/signoff-2026-05-21.md` | 审查签字确认 |
|
||||
| `reports/session-log-2026-05-21.md` | 会话操作日志 |
|
||||
|
||||
### 实施报告
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `reports/implementation-progress-2026-05-21.md` | 6步实施进度总览 |
|
||||
| `reports/step-0-infrastructure/engineering-report.md` | Step 0: 基础设施加固 |
|
||||
| `reports/step-0-infrastructure/ag-code-review-report.md` | Step 0: 代码审查 |
|
||||
| `reports/step-0-infrastructure/testing-report.md` | Step 0: 测试报告 |
|
||||
| `reports/step-1-data-layer/engineering-report.md` | Step 1: 数据层 |
|
||||
| `reports/step-2-auth/engineering-report.md` | Step 2: 认证层 |
|
||||
| `reports/step-3-webssh/engineering-report.md` | Step 3: Web SSH(含paramiko→asyncssh迁移) |
|
||||
| `reports/step-4-sync/engineering-report.md` | Step 4: Sync引擎 |
|
||||
| `reports/step-5-frontend/engineering-report.md` | Step 5: 前端迁移 |
|
||||
| `reports/step-5-frontend/design-review-report.md` | Step 5: 前端设计审查 |
|
||||
| `reports/step-5-frontend/product-department-report.md` | Step 5: 产品部报告 |
|
||||
|
||||
## research/ — 竞品与技术调研
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `research/jumpserver-easynode-architecture-analysis.md` | JumpServer & EasyNode 架构对比分析 |
|
||||
| `research/ag-research-report.md` | AI Agent 调研报告 |
|
||||
|
||||
## changelog/ — 变更记录(强制)
|
||||
|
||||
> **纪律**:每次有意义的代码/配置修改都必须在此目录新增 `YYYY-MM-DD-<主题>.md`。见 `.cursor/rules/perfect-implementation.mdc`。
|
||||
|
||||
### Phase 2 安全与审计(2026-05-22~23)
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `changelog/2026-05-22-security-fixes-p0.md` | P0:WebSSH、中心 exec、crypto |
|
||||
| `changelog/2026-05-22-security-fixes-p1.md` | P1:注入、危险命令、Agent |
|
||||
| `changelog/2026-05-22-audit-p2-fixes.md` | P2 批次修复 |
|
||||
| `changelog/2026-05-22-global-jwt-middleware.md` | 全局 JWT 中间件 |
|
||||
| `changelog/2026-05-22-alert-push-dashboard.md` | 告警策略 + 仪表盘 |
|
||||
| `changelog/2026-05-22-telegram-sanitize-and-security-tests.md` | Telegram 脱敏 + 单测 |
|
||||
| `changelog/2026-05-22-frontend-vendor-selfhost.md` | 前端 vendor 自托管 |
|
||||
| `changelog/2026-05-22-line-walk-audit-standard.md` | 逐行走读标准 |
|
||||
|
||||
### 其他
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `changelog/2026-05-22-implementation-standards-rule.md` | 完美实现与文档纪律全局规则 |
|
||||
| `changelog/2026-05-22-tech-stack-rules-mysql-mcp.md` | 技术栈 Cursor 规则 + MySQL MCP |
|
||||
| `changelog/2026-05-22-local-mysql-full-access-node20-fix.md` | 本地库可写 + Node20 安装修复 |
|
||||
| `changelog/fix-plan-2026-05-20.md` | 代码问题修复计划(13项) |
|
||||
| `changelog/fix-plan-full-2026-05-20.md` | 全量未完成项修复计划(24项) |
|
||||
| `changelog/fix-verification-report-2026-05-20.md` | 修复验证报告 |
|
||||
|
||||
## memory/ — 项目记忆(AI辅助)
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `memory/MEMORY.md` | 记忆索引 |
|
||||
| `memory/mem_*.md` | 17个记忆文件(概述/决策/数据流/守护/模块/测试/等) |
|
||||
|
||||
## 已移除(2026-06-01)
|
||||
|
||||
`docs/team/`、`docs/skills/`、`TEAM_ROLES.md`、`.cursor/skills/` 已删除——不再使用虚拟部门或 superpowers 工作流 Skill。开发规范见 `standards/` 与 `.cursor/rules/`。
|
||||
| `scripts/local_verify.sh` | L2b 本地验证 |
|
||||
| `scripts/consolidate_docs.py` | 文档归档合并(维护用) |
|
||||
| `scripts/run_nexus_acceptance.py` | L4 验收 |
|
||||
| `deploy/pre_deploy_check.sh` | 7 道门控 |
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# Nexus 文档归档区
|
||||
|
||||
> 更新: 2026-06-04
|
||||
|
||||
历史审计、旧 handoff、agentmemory。**日常请先读** [docs/README.md](../README.md)。
|
||||
|
||||
## 合并卷
|
||||
|
||||
| 文件 | 内容 |
|
||||
|------|------|
|
||||
| [audits/2026-06-04-line-walk-merged.md](audits/2026-06-04-line-walk-merged.md) | Line-walk batch |
|
||||
| [audits/2026-06-04-delta-merged.md](audits/2026-06-04-delta-merged.md) | Delta D1–D8 |
|
||||
| [audits/2026-06-04-phase2-merged.md](audits/2026-06-04-phase2-merged.md) | Phase2 P2 |
|
||||
| [audits/2026-06-04-frontend-14p-merged.md](audits/2026-06-04-frontend-14p-merged.md) | 前端 14p |
|
||||
| [memory/agentmemory-2026-05-merged.md](memory/agentmemory-2026-05-merged.md) | 旧 memory |
|
||||
|
||||
原文在对应子目录;changelog 不归档。
|
||||
@@ -0,0 +1,183 @@
|
||||
# Delta D1–D8 合并卷
|
||||
|
||||
> 生成日期: 2026-06-04 · 源文件 8 篇 · 原文 `docs/archive/audits/2026-06-04-delta/`
|
||||
|
||||
## 批次索引
|
||||
|
||||
### `audit-delta-2026-06-04-waveD1.md`
|
||||
|
||||
# Phase 1 Delta 审计 — Wave D1(同步/后台)
|
||||
## 登记
|
||||
## Step 3 — 规则扫描 H(摘要)
|
||||
## 入口表(sync_v2.py API)
|
||||
## Closure 表
|
||||
**len(H)=19, Closure=19**
|
||||
## FINDING(本波)
|
||||
无 P0/P1 新 FINDING。RISK 项与既有运维/单人决策一致,不阻塞。
|
||||
## DoD
|
||||
- [x] len(H) == Closure
|
||||
- [x] FINDING 含行号
|
||||
## 验证
|
||||
|
||||
### `audit-delta-2026-06-04-waveD2.md`
|
||||
|
||||
# Phase 1 Delta 审计 — Wave D2(认证 / 安装 / WS / Agent)
|
||||
## 登记
|
||||
## 入口表
|
||||
### install.py
|
||||
### auth.py
|
||||
### websocket.py
|
||||
### agent.py
|
||||
## Closure 表
|
||||
**len(H)=22, Closure=22**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。RISK:WS query JWT、Agent global key — 见 `docs/project/risk-acceptance-single-operator.md`。
|
||||
## DoD
|
||||
|
||||
### `audit-delta-2026-06-04-waveD3.md`
|
||||
|
||||
# Phase 1 Delta 审计 — Wave D3(服务器 / 设置 / 脚本 / WebSSH)
|
||||
## 登记
|
||||
## 入口表(摘要)
|
||||
### webssh.py
|
||||
### servers.py(主要写操作)
|
||||
### settings.py
|
||||
### scripts.py
|
||||
## Closure 表
|
||||
**len(H)=24, Closure=24**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
## DoD
|
||||
|
||||
### `audit-delta-2026-06-04-waveD4.md`
|
||||
|
||||
# Phase 1 Delta 审计 — Wave D4(前端 Push)
|
||||
## 登记
|
||||
## Step 3 — 规则扫描 H(摘要)
|
||||
## 入口表(前端 → API)
|
||||
## Closure 表
|
||||
**len(H)=17, Closure=17**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
## DoD
|
||||
- [x] len(H) == Closure
|
||||
## 验证
|
||||
|
||||
### `audit-delta-2026-06-04-waveD5.md`
|
||||
|
||||
# Phase 1 Delta 审计 — Wave D5(前端 Files / Terminal)
|
||||
## 登记
|
||||
## Step 3 — 规则扫描 H(摘要)
|
||||
## 入口表(前端 → API / WS)
|
||||
## Closure 表
|
||||
**len(H)=18, Closure=18**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
## DoD
|
||||
- [x] len(H) == Closure
|
||||
## 验证
|
||||
|
||||
### `audit-delta-2026-06-04-waveD6.md`
|
||||
|
||||
# Phase 1 Delta 审计 — Wave D6(认证链 / Login)
|
||||
## 登记
|
||||
## Step 3 — 规则扫描 H(摘要)
|
||||
## 入口表
|
||||
## Closure 表
|
||||
**len(H)=19, Closure=19**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
## DoD
|
||||
- [x] len(H) == Closure
|
||||
## 验证
|
||||
|
||||
### `audit-delta-2026-06-04-waveD7.md`
|
||||
|
||||
# Phase 1 Delta 审计 — Wave D7(Deploy / 本地验证脚本)
|
||||
**标准**: 变更审查(运维/门控;非业务 API 8 步,沿用 Closure 表格式)
|
||||
## 登记
|
||||
## Step 3 — 规则扫描 H(摘要)
|
||||
## 入口表(脚本调用链)
|
||||
## Closure 表
|
||||
**len(H)=16, Closure=16**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
## DoD
|
||||
- [x] len(H) == Closure
|
||||
## 验证
|
||||
|
||||
### `audit-delta-2026-06-04-waveD8-closure.md`
|
||||
|
||||
# Phase 1 Delta 审计 — Wave D8(汇总 Closure)
|
||||
**标准**: Phase 1 收尾 DoD
|
||||
## 汇总表
|
||||
| 波次 | 主题 | 文件数 | H | P0/P1 | 报告 |
|
||||
## 已接受 RISK(跨波重复,不重复开 FINDING)
|
||||
## Registry 更新
|
||||
## Step 3 / Closure / DoD
|
||||
- **len(H) 汇总** = 135,各波 Closure 均已 100% 对齐
|
||||
- **无 P0/P1** 待修项进入 Phase 2
|
||||
## 下一步(计划 Phase 2 / L3)
|
||||
## 验证
|
||||
|
||||
## Closure 摘录(合并)
|
||||
|
||||
| 1 | `server/api/sync_v2.py` | Python | 1656 | 1–200, 680–1080, 1280–1657 + 全文件 `@router`/grep H |
|
||||
| 2 | `server/application/services/sync_engine_v2.py` | Python | 552 | 1–552 全文 |
|
||||
| 3 | `server/background/schedule_runner.py` | Python | 262 | 1–262 全文 |
|
||||
| 4 | `server/background/retry_runner.py` | Python | 169 | 1–169 全文 |
|
||||
| 5 | `server/background/heartbeat_flush.py` | Python | 101 | 1–101 全文 |
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
| H-Install-lock | install.py:344-350 | SAFE | `_reject_if_locked` 阻断突变 |
|
||||
| H-Install-token | install.py:314-327 | SAFE | `secrets.compare_digest` 一次性 token |
|
||||
| H-Install-token | install.py:601 | SAFE | create-admin 必须 token |
|
||||
| H-Install-SQL | install.py:540-544 | SAFE | 参数化 INSERT settings |
|
||||
| H-Install-DDL | install.py:489-503 | SAFE | DDL 幂等 except pass |
|
||||
| H-Install-subprocess | install.py:273-293 | SAFE | crontab/supervisor 固定 argv |
|
||||
| H-Auth-brute | auth.py:125-138 | SAFE | 429/202 由 AuthService |
|
||||
| H-Auth-cookie | auth.py:38-54 | SAFE | HttpOnly + Secure(HTTPS) + SameSite=Lax |
|
||||
| H-Auth-TOTP-IDOR | auth.py:223-259 | SAFE | admin_id 必须等于 JWT sub |
|
||||
| H-Auth-password | auth.py:288-305 | SAFE | bcrypt + token_version 失效 |
|
||||
| H-Auth-webssh | auth.py:330-349 | SAFE | 短效 server-bound token |
|
||||
| H-JWT-middleware | auth_jwt.py:78-146 | SAFE | ASGI 层拦截 /api/* |
|
||||
| H-JWT-public | auth_jwt.py:38-50 | SAFE | 公开前缀含 agent/install/ws |
|
||||
| H-JWT-tv | auth_jwt.py:222-226 | SAFE | token_version 精确匹配 |
|
||||
| H-WS-auth | websocket.py:303-311 | SAFE | 无 token → 4001;无效 → 4401 |
|
||||
| H-WS-auth | websocket.py:366-407 | SAFE | tv + updated_at 双检 |
|
||||
| H-WS-ADR011 | websocket.py:9,300 | RISK | JWT 在 query;单人运维已接受 ADR-011 |
|
||||
| H-Agent-key | agent.py:40-57 | SAFE | compare_digest;handler 二次验 per-server |
|
||||
| H-Agent-unknown | agent.py:193-199 | SAFE | 未知 server 200 discard,不写入 |
|
||||
| H-Agent-global | agent.py:84-92 | RISK | legacy global API_KEY;risk-acceptance 文档 |
|
||||
| H-Agent-callback | agent.py:324-347 | SAFE | rate limit + job secret |
|
||||
| H-Agent-no-exec | agent.py:378 | SAFE | 控制面无 shell exec |
|
||||
| POST | `/{id}/install-agent` 等 | JWT + SSH |
|
||||
| 文件 | H 命中 |
|
||||
| usePushForm.ts | H-Auth, H-Upload, H-Path |
|
||||
| usePushPreview.ts | H-Auth, H-Path |
|
||||
| usePushProgress.ts | H-Auth, H-WS, H-Batch |
|
||||
| PushZipUpload.vue | H-Upload, H-XSS |
|
||||
| PushServerGrid.vue | H-XSS |
|
||||
| useFilesActions.ts | H-Auth, H-Path, H-Delete, H-Upload |
|
||||
| useFilesEditor.ts | H-Auth, H-Size |
|
||||
| useFilesPermissions.ts | H-Auth, H-Sudo |
|
||||
| useTerminalSessions.ts | H-Auth, H-WS, H-Path, H-Cmd |
|
||||
| useTerminalCmdBar.ts | H-Storage, H-Cmd |
|
||||
| LoginPage.vue | H-Secret, H-Redirect, H-Lockout, H-XSS |
|
||||
| auth.ts | H-Token, H-Refresh, H-Profile |
|
||||
| api/index.ts | H-Auth, H-Refresh, H-401 |
|
||||
| router/index.ts | H-Guard, H-Redirect |
|
||||
| wsUrl.ts | H-WS |
|
||||
| pre_deploy_check.sh | H-Gate, H-Secret, H-Git |
|
||||
| local_verify.sh | H-Chain |
|
||||
| local_integration_smoke.sh | H-Health, H-Auth |
|
||||
| start-dev.sh | H-DevBind, H-Env |
|
||||
| docker-compose.yml | H-Port, H-DefaultCreds |
|
||||
| 波次 | 主题 | 文件数 | H | P0/P1 | 报告 |
|
||||
| D1 | sync/后台 | 5 | 19 | 0 | [waveD1](audit-delta-2026-06-04-waveD1.md) |
|
||||
| D2 | auth/agent/ws | 5 | 22 | 0 | [waveD2](audit-delta-2026-06-04-waveD2.md) |
|
||||
| D3 | servers/settings/scripts/webssh | 5 | 24 | 0 | [waveD3](audit-delta-2026-06-04-waveD3.md) |
|
||||
| D4 | 前端 Push | 5 | 17 | 0 | [waveD4](audit-delta-2026-06-04-waveD4.md) |
|
||||
| D5 | 前端 Files/Terminal | 5 | 18 | 0 | [waveD5](audit-delta-2026-06-04-waveD5.md) |
|
||||
| D6 | 认证链 Login | 5 | 19 | 0 | [waveD6](audit-delta-2026-06-04-waveD6.md) |
|
||||
| D7 | Deploy/本地脚本 | 5 | 16 | 0 | [waveD7](audit-delta-2026-06-04-waveD7.md) |
|
||||
| **合计** | | **35** | **135** | **0** | |
|
||||
@@ -0,0 +1,95 @@
|
||||
# Phase 1 Delta 审计 — Wave D1(同步/后台)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**范围**: 推送/sync 核心路径(Code Review batch1 后 delta)
|
||||
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 语言 | 行数 N | Read 范围 |
|
||||
|---|------|------|--------|-----------|
|
||||
| 1 | `server/api/sync_v2.py` | Python | 1656 | 1–200, 680–1080, 1280–1657 + 全文件 `@router`/grep H |
|
||||
| 2 | `server/application/services/sync_engine_v2.py` | Python | 552 | 1–552 全文 |
|
||||
| 3 | `server/background/schedule_runner.py` | Python | 262 | 1–262 全文 |
|
||||
| 4 | `server/background/retry_runner.py` | Python | 169 | 1–169 全文 |
|
||||
| 5 | `server/background/heartbeat_flush.py` | Python | 101 | 1–101 全文 |
|
||||
|
||||
## Step 3 — 规则扫描 H(摘要)
|
||||
|
||||
| 文件 | H 命中 |
|
||||
|------|--------|
|
||||
| sync_v2.py | H-Shell, H-Auth, H-Path, H-Audit, H-Upload |
|
||||
| sync_engine_v2.py | H-Shell, H-AuthN/A, H-Concurrency |
|
||||
| schedule_runner.py | H-Cron, H-Script-exec, H-Lock |
|
||||
| retry_runner.py | H-Lock, H-Retry |
|
||||
| heartbeat_flush.py | H-Redis, H-DB |
|
||||
|
||||
## 入口表(sync_v2.py API)
|
||||
|
||||
| 方法 | 路径 | 鉴权 |
|
||||
|------|------|------|
|
||||
| POST | `/api/sync/files` | JWT `get_current_admin` |
|
||||
| POST | `/api/sync/preview` | 同上 |
|
||||
| POST | `/api/sync/file-ops` | 同上 |
|
||||
| POST | `/api/sync/file-clipboard` | 同上 |
|
||||
| POST | `/api/sync/browse` | 同上 |
|
||||
| POST | `/api/sync/browse-local` | 同上 |
|
||||
| POST | `/api/sync/local-file-ops` | 同上 |
|
||||
| POST | `/api/sync/local-file-preview` | 同上 |
|
||||
| POST | `/api/sync/cancel` | 同上 |
|
||||
| POST | `/api/sync/reconcile-stale-logs` | 同上 |
|
||||
| POST | `/api/sync/validate-source-path` | 同上 |
|
||||
| POST | `/api/sync/diagnose` | 同上 |
|
||||
| POST | `/api/sync/file-diff` | 同上 |
|
||||
| POST | `/api/sync/upload` | 同上 |
|
||||
| POST | `/api/sync/upload-zip` | 同上 |
|
||||
| POST | `/api/sync/verify` | 同上 |
|
||||
| POST | `/api/sync/download` | 同上 |
|
||||
| POST | `/api/sync/read-file` | 同上 |
|
||||
| POST | `/api/sync/write-file` | 同上 |
|
||||
| POST | `/api/sync/chmod` | 同上 |
|
||||
| POST | `/api/sync/compress` | 同上 |
|
||||
| POST | `/api/sync/decompress` | 同上 |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
|---|-----------|------|------|
|
||||
| H-Shell | sync_v2.py:156-173 | SAFE | 远程路径 `normalize_remote_abs_path` + `shlex.quote` |
|
||||
| H-Shell | sync_v2.py:777 | SAFE | `remote_file` 经 `remote_join`+quote;`wc -c && cat` 单路径 |
|
||||
| H-Path | sync_v2.py:721-731 | SAFE | `ensure_under_nexus_upload` + prefix 校验 |
|
||||
| H-Path | sync_v2.py:887-890 | SAFE | 上传文件名去斜杠 |
|
||||
| H-Path | sync_v2.py:999-1005 | SAFE | ZIP slip:`assert_zip_member_safe` |
|
||||
| H-Auth | sync_v2.py:74-1610 | SAFE | 全部 22 路由 `Depends(get_current_admin)` |
|
||||
| H-Audit | sync_v2.py:119-122 等 | SAFE | CUD/敏感操作 `_audit_sync` |
|
||||
| H-Upload | sync_v2.py:876-877 | SAFE | 100MB 上限 |
|
||||
| H-Upload | sync_v2.py:977-978 | SAFE | ZIP 500MB 上限 |
|
||||
| H-Shell | sync_engine_v2.py:433-465 | RISK | `StrictHostKeyChecking=no` 运维惯例;单人环境已接受 |
|
||||
| H-Shell | sync_engine_v2.py:440-445 | RISK | sshpass/SSHPASS;内部工具,凭据加密存储 |
|
||||
| H-Concurrency | sync_engine_v2.py:89-150 | SAFE | `_db_lock` 串行化 sync_log 写 |
|
||||
| H-Cron | schedule_runner.py:58-72 | RISK | 畸形 cron 字段 `int()` 可抛 ValueError;外层 254 行捕获 rollback |
|
||||
| H-Script | schedule_runner.py:198-205 | SAFE | 调度脚本仅 JWT 管理员配置的 schedule 触发 |
|
||||
| H-Lock | schedule_runner.py:125-131 | SAFE | `FOR UPDATE SKIP LOCKED` 防双触发 |
|
||||
| H-Lock | retry_runner.py:67-76 | SAFE | SKIP LOCKED 认领 |
|
||||
| H-Retry | retry_runner.py:22-59 | SAFE | 指数退避 + max_retries |
|
||||
| H-Redis | heartbeat_flush.py:42-48 | SAFE | scan 失败 log+continue |
|
||||
| H-DB | heartbeat_flush.py:57-99 | SAFE | 参数化 ORM update;未知 server_id rowcount 0 跳过 |
|
||||
|
||||
**len(H)=19, Closure=19**
|
||||
|
||||
## FINDING(本波)
|
||||
|
||||
无 P0/P1 新 FINDING。RISK 项与既有运维/单人决策一致,不阻塞。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] len(H) == Closure
|
||||
- [x] Read 覆盖 1..N(sync_v2 大文件分段 + 全路由 grep)
|
||||
- [x] FINDING 含行号
|
||||
- [x] 入口表 + sink 标注
|
||||
- [x] 逐行完成 ✓(D1 五文件)
|
||||
|
||||
## 验证
|
||||
|
||||
- `docker-compose.yml` Redis 发布 6379(修复本地 uvicorn 连 Redis)
|
||||
- 待跑:`bash scripts/local_verify.sh`
|
||||
@@ -0,0 +1,100 @@
|
||||
# Phase 1 Delta 审计 — Wave D2(认证 / 安装 / WS / Agent)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**范围**: Code Review batch2 后 delta — 认证与 Agent 路径
|
||||
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 语言 | 行数 N | Read 范围 |
|
||||
|---|------|------|--------|-----------|
|
||||
| 1 | `server/api/install.py` | Python | 746 | 1–746 全文 |
|
||||
| 2 | `server/api/auth.py` | Python | 374 | 1–374 全文 |
|
||||
| 3 | `server/api/auth_jwt.py` | Python | 274 | 1–274 全文 |
|
||||
| 4 | `server/api/websocket.py` | Python | 552 | 1–552 全文 |
|
||||
| 5 | `server/api/agent.py` | Python | 378 | 1–378 全文 |
|
||||
|
||||
## 入口表
|
||||
|
||||
### install.py
|
||||
|
||||
| 方法 | 路径 | 鉴权 |
|
||||
|------|------|------|
|
||||
| GET | `/api/install/status` | 无(已锁定 404) |
|
||||
| GET | `/api/install/env-check` | 安装模式 + 未 lock |
|
||||
| POST | `/api/install/init-db` | 无 .env + 未 lock |
|
||||
| POST | `/api/install/create-admin` | `install_token` |
|
||||
| POST | `/api/install/lock` | 需已有 admin |
|
||||
| GET | `/api/install/state` | 未 lock |
|
||||
|
||||
### auth.py
|
||||
|
||||
| 方法 | 路径 | 鉴权 |
|
||||
|------|------|------|
|
||||
| POST | `/api/auth/login` | 公开 |
|
||||
| POST | `/api/auth/refresh` | Cookie/body refresh |
|
||||
| POST | `/api/auth/logout` | Cookie |
|
||||
| POST | `/api/auth/totp/*` | JWT + self admin_id |
|
||||
| PUT | `/api/auth/password` | JWT + 当前密码 (+TOTP) |
|
||||
| POST | `/api/auth/webssh-token` | JWT + server 存在 |
|
||||
| GET | `/api/auth/me` | JWT |
|
||||
|
||||
### websocket.py
|
||||
|
||||
| 类型 | 路径 | 鉴权 |
|
||||
|------|------|------|
|
||||
| WS | `/ws/alerts` | Query `?token=` JWT |
|
||||
| WS | `/ws/sync` | 同上 |
|
||||
|
||||
### agent.py
|
||||
|
||||
| 方法 | 路径 | 鉴权 |
|
||||
|------|------|------|
|
||||
| POST | `/api/agent/heartbeat` | X-API-Key + per-server key |
|
||||
| POST | `/api/agent/script-callback` | X-API-Key + job secret + rate limit |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
|---|-----------|------|------|
|
||||
| H-Install-lock | install.py:344-350 | SAFE | `_reject_if_locked` 阻断突变 |
|
||||
| H-Install-token | install.py:314-327 | SAFE | `secrets.compare_digest` 一次性 token |
|
||||
| H-Install-token | install.py:601 | SAFE | create-admin 必须 token |
|
||||
| H-Install-SQL | install.py:540-544 | SAFE | 参数化 INSERT settings |
|
||||
| H-Install-DDL | install.py:489-503 | SAFE | DDL 幂等 except pass |
|
||||
| H-Install-subprocess | install.py:273-293 | SAFE | crontab/supervisor 固定 argv |
|
||||
| H-Auth-brute | auth.py:125-138 | SAFE | 429/202 由 AuthService |
|
||||
| H-Auth-cookie | auth.py:38-54 | SAFE | HttpOnly + Secure(HTTPS) + SameSite=Lax |
|
||||
| H-Auth-TOTP-IDOR | auth.py:223-259 | SAFE | admin_id 必须等于 JWT sub |
|
||||
| H-Auth-password | auth.py:288-305 | SAFE | bcrypt + token_version 失效 |
|
||||
| H-Auth-webssh | auth.py:330-349 | SAFE | 短效 server-bound token |
|
||||
| H-JWT-middleware | auth_jwt.py:78-146 | SAFE | ASGI 层拦截 /api/* |
|
||||
| H-JWT-public | auth_jwt.py:38-50 | SAFE | 公开前缀含 agent/install/ws |
|
||||
| H-JWT-tv | auth_jwt.py:222-226 | SAFE | token_version 精确匹配 |
|
||||
| H-WS-auth | websocket.py:303-311 | SAFE | 无 token → 4001;无效 → 4401 |
|
||||
| H-WS-auth | websocket.py:366-407 | SAFE | tv + updated_at 双检 |
|
||||
| H-WS-ADR011 | websocket.py:9,300 | RISK | JWT 在 query;单人运维已接受 ADR-011 |
|
||||
| H-Agent-key | agent.py:40-57 | SAFE | compare_digest;handler 二次验 per-server |
|
||||
| H-Agent-unknown | agent.py:193-199 | SAFE | 未知 server 200 discard,不写入 |
|
||||
| H-Agent-global | agent.py:84-92 | RISK | legacy global API_KEY;risk-acceptance 文档 |
|
||||
| H-Agent-callback | agent.py:324-347 | SAFE | rate limit + job secret |
|
||||
| H-Agent-no-exec | agent.py:378 | SAFE | 控制面无 shell exec |
|
||||
|
||||
**len(H)=22, Closure=22**
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。RISK:WS query JWT、Agent global key — 见 `docs/project/risk-acceptance-single-operator.md`。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] len(H) == Closure
|
||||
- [x] Read 1..N 全文
|
||||
- [x] 入口表 + sink
|
||||
- [x] 逐行完成 ✓(D2 五文件)
|
||||
|
||||
## 验证
|
||||
|
||||
```bash
|
||||
bash scripts/local_verify.sh # 预期全绿
|
||||
```
|
||||
@@ -0,0 +1,85 @@
|
||||
# Phase 1 Delta 审计 — Wave D3(服务器 / 设置 / 脚本 / WebSSH)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**范围**: Code Review batch2–3 相关路径
|
||||
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 语言 | 行数 N | Read 范围 |
|
||||
|---|------|------|--------|-----------|
|
||||
| 1 | `server/api/webssh.py` | Python | 398 | 1–398 全文 |
|
||||
| 2 | `server/api/servers.py` | Python | 1741 | 1–250, 1059–1290, 1681–1742 + 全路由 grep |
|
||||
| 3 | `server/api/settings.py` | Python | 1403 | 1–130, 280–384, 562–730, 881–930 + grep |
|
||||
| 4 | `server/application/services/script_service.py` | Python | 734 | 1–734 全文 |
|
||||
| 5 | `server/api/scripts.py` | Python | 418 | 1–418 全文 |
|
||||
|
||||
## 入口表(摘要)
|
||||
|
||||
### webssh.py
|
||||
| 类型 | 路径 | 鉴权 |
|
||||
|------|------|------|
|
||||
| WS | `/ws/terminal/{server_id}` | JWT `purpose=webssh` + server_id 绑定 |
|
||||
|
||||
### servers.py(主要写操作)
|
||||
| 方法 | 路径 | 鉴权 |
|
||||
|------|------|------|
|
||||
| POST/PUT/DELETE | `/api/servers/`… | JWT |
|
||||
| POST | `/{id}/agent-key` | JWT + 当前密码 |
|
||||
| POST | `/{id}/install-agent` 等 | JWT + SSH |
|
||||
|
||||
### settings.py
|
||||
| 方法 | 路径 | 鉴权 |
|
||||
|------|------|------|
|
||||
| GET/PUT | `/api/settings/*` | JWT;IMMUTABLE_KEYS 403 |
|
||||
| POST | `/api-key/reveal`, `/telegram/reveal-token` | JWT + re-auth |
|
||||
|
||||
### scripts.py
|
||||
| 方法 | 路径 | 鉴权 |
|
||||
|------|------|------|
|
||||
| CRUD/exec | `/api/scripts/*` | JWT 全路由 |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
|---|-----------|------|------|
|
||||
| H-WS-auth | webssh.py:96-109 | SAFE | webssh JWT + server_id 必须匹配路径 |
|
||||
| H-WS-IDOR | webssh.py:106-108 | SAFE | 非绑定 token → 4003 |
|
||||
| H-WS-cred | webssh.py:127-135 | SAFE | SSH 凭据未配置则拒绝 |
|
||||
| H-WS-audit | webssh.py:137-157 | SAFE | connect/disconnect 审计 |
|
||||
| H-WS-cmdlog | webssh.py:276-290 | SAFE | 命令日志 + dangerous check |
|
||||
| H-WS-ADR011 | webssh.py:92 | RISK | query token;已接受 |
|
||||
| H-Server-mask | servers.py:1692-1698 | SAFE | password_set / 密钥不返回明文 |
|
||||
| H-Server-encrypt | servers.py:1096-1099 | SAFE | Fernet 加密存储 |
|
||||
| H-Server-allowlist | servers.py:1163-1187 | SAFE | UPDATE 字段白名单 |
|
||||
| H-Server-agent-key | servers.py:1251-1288 | SAFE | re-auth 后生成/返回一次 |
|
||||
| H-Server-shell | servers.py:631-633 | SAFE | install cmd shlex.quote |
|
||||
| H-Server-sudo | servers.py:36-60 | RISK | 临时 sudoers;运维必要 |
|
||||
| H-Settings-immutable | settings.py:331-334 | SAFE | api_key 等不可 PUT |
|
||||
| H-Settings-mask | settings.py:114-128 | SAFE | GET 敏感项 value 空 + value_set |
|
||||
| H-Settings-reauth | settings.py:93-98 | SAFE | reveal 需 bcrypt |
|
||||
| H-Settings-SSRF | settings.py:68-88 | SAFE | 订阅 URL 私有 IP 拦截 |
|
||||
| H-Settings-PUT-leak | settings.py:383 | RISK | PUT 响应可能含 telegram 明文;JWT 已认证 |
|
||||
| H-Script-danger | scripts.py:352-359 | SAFE | check_dangerous_command 拒绝 |
|
||||
| H-Script-cred | scripts.py:407-418 | SAFE | 凭据 API 无 password 字段 |
|
||||
| H-Script-allowlist | scripts.py:111-114,303-306 | SAFE | credential/script UPDATE 白名单 |
|
||||
| H-Svc-redact | script_service.py:108-111 | SAFE | 执行记录 command 脱敏 DB_PASS |
|
||||
| H-Svc-ssh | script_service.py:680-698 | SAFE | SSH exec 经 pool |
|
||||
| H-Svc-kill | script_service.py:306-322 | SAFE | kill 命令 pid/log 路径校验 |
|
||||
| H-Svc-server-map | script_service.py:519-523 | SAFE | 预加载 server_map 避免并行竞态 |
|
||||
|
||||
**len(H)=24, Closure=24**
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] len(H) == Closure
|
||||
- [x] Read 覆盖(大文件分段 + 全路由)
|
||||
- [x] 逐行完成 ✓(D3 五文件)
|
||||
|
||||
## 验证
|
||||
|
||||
`bash scripts/local_verify.sh` — 预期全绿
|
||||
@@ -0,0 +1,74 @@
|
||||
# Phase 1 Delta 审计 — Wave D4(前端 Push)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**范围**: Code Review 后 push 页 composables + 组件
|
||||
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 语言 | 行数 N | Read 范围 |
|
||||
|---|------|------|--------|-----------|
|
||||
| 1 | `frontend/src/composables/push/usePushForm.ts` | TS | 101 | 1–101 全文 |
|
||||
| 2 | `frontend/src/composables/push/usePushPreview.ts` | TS | 104 | 1–104 全文 |
|
||||
| 3 | `frontend/src/composables/push/usePushProgress.ts` | TS | 294 | 1–294 全文 |
|
||||
| 4 | `frontend/src/components/push/PushZipUpload.vue` | Vue | 51 | 1–51 全文 |
|
||||
| 5 | `frontend/src/components/push/PushServerGrid.vue` | Vue | 110 | 1–110 全文 |
|
||||
|
||||
**关联(本波未单独登记)**: `usePushPage.ts` 仅编排 lifecycle,无独立 sink。
|
||||
|
||||
## Step 3 — 规则扫描 H(摘要)
|
||||
|
||||
| 文件 | H 命中 |
|
||||
|------|--------|
|
||||
| usePushForm.ts | H-Auth, H-Upload, H-Path |
|
||||
| usePushPreview.ts | H-Auth, H-Path |
|
||||
| usePushProgress.ts | H-Auth, H-WS, H-Batch |
|
||||
| PushZipUpload.vue | H-Upload, H-XSS |
|
||||
| PushServerGrid.vue | H-XSS |
|
||||
|
||||
## 入口表(前端 → API)
|
||||
|
||||
| 调用方 | 方法 | 路径 | 鉴权 |
|
||||
|--------|------|------|------|
|
||||
| usePushForm | POST multipart | `/sync/upload-zip` | http JWT |
|
||||
| usePushPreview | POST | `/sync/preview` | http JWT |
|
||||
| usePushProgress | POST | `/sync/files`, `/sync/cancel` | http JWT |
|
||||
| usePushProgress | WS | `/ws/sync?token=` | JWT query(已接受 RISK) |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
|---|-----------|------|------|
|
||||
| H-Auth | usePushForm.ts:65-67 | SAFE | 经 `@/api` http,Bearer JWT |
|
||||
| H-Upload | usePushForm.ts:52,57 | RISK | 客户端仅 `.zip` 后缀;服务端 ZIP slip/大小限制(D1) |
|
||||
| H-Path | usePushForm.ts:69-72 | SAFE | `source_path` 来自服务端 upload-zip 响应 |
|
||||
| H-Path | usePushForm.ts:38-40 | SAFE | target_path 必填;远程校验在 sync_v2 |
|
||||
| H-Auth | usePushPreview.ts:28-38 | SAFE | preview POST JWT + server_id 参数化 |
|
||||
| H-Concurrency | usePushPreview.ts:72-77 | SAFE | `PREVIEW_CONCURRENCY=4` 限流 |
|
||||
| H-Auth | usePushProgress.ts:237-243 | SAFE | push POST JWT + batch_id |
|
||||
| H-WS | usePushProgress.ts:137-142 | RISK | query token;单人运维已接受 |
|
||||
| H-WS | usePushProgress.ts:79-80 | SAFE | batch_id 过滤防串批 |
|
||||
| H-WS | usePushProgress.ts:165-167 | SAFE | 4401 → forceLogout |
|
||||
| H-Batch | usePushProgress.ts:244-246 | SAFE | 服务端 batch_id 可覆盖客户端 |
|
||||
| H-Cancel | usePushProgress.ts:194-209 | SAFE | cancel 带 batch_id |
|
||||
| H-Timer | usePushProgress.ts:261-275 | SAFE | 300s 安全超时 + dispose 清理 |
|
||||
| H-Secret | usePushForm/Preview/Progress | SAFE | 无 localStorage 密码/密钥 |
|
||||
| H-XSS | PushZipUpload.vue:22 | SAFE | `{{ uploadedZip.name }}` 文本插值 |
|
||||
| H-XSS | PushServerGrid.vue:66-77 | SAFE | 无 v-html;状态 chip 文本插值 |
|
||||
| H-Upload | PushZipUpload.vue:18 | SAFE | `accept=".zip"` + 父 composable 后缀检查 |
|
||||
|
||||
**len(H)=17, Closure=17**
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] len(H) == Closure
|
||||
- [x] 五文件全文 Read
|
||||
- [x] 无 v-html / localStorage 凭据
|
||||
|
||||
## 验证
|
||||
|
||||
`bash scripts/local_verify.sh` — 全绿
|
||||
@@ -0,0 +1,80 @@
|
||||
# Phase 1 Delta 审计 — Wave D5(前端 Files / Terminal)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**范围**: files/terminal composables(Code Review 后 delta)
|
||||
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 语言 | 行数 N | Read 范围 |
|
||||
|---|------|------|--------|-----------|
|
||||
| 1 | `frontend/src/composables/files/useFilesActions.ts` | TS | 609 | 1–609 全文 |
|
||||
| 2 | `frontend/src/composables/files/useFilesEditor.ts` | TS | 163 | 1–163 全文 |
|
||||
| 3 | `frontend/src/composables/files/useFilesPermissions.ts` | TS | 101 | 1–101 全文 |
|
||||
| 4 | `frontend/src/composables/terminal/useTerminalSessions.ts` | TS | 749 | 1–749 全文 |
|
||||
| 5 | `frontend/src/composables/terminal/useTerminalCmdBar.ts` | TS | 108 | 1–108 全文 |
|
||||
|
||||
**关联**: `types.ts` 中 `sanitizeRemotePath`(40–43)已纳入 terminal 路径 H 判定。
|
||||
|
||||
## Step 3 — 规则扫描 H(摘要)
|
||||
|
||||
| 文件 | H 命中 |
|
||||
|------|--------|
|
||||
| useFilesActions.ts | H-Auth, H-Path, H-Delete, H-Upload |
|
||||
| useFilesEditor.ts | H-Auth, H-Size |
|
||||
| useFilesPermissions.ts | H-Auth, H-Sudo |
|
||||
| useTerminalSessions.ts | H-Auth, H-WS, H-Path, H-Cmd |
|
||||
| useTerminalCmdBar.ts | H-Storage, H-Cmd |
|
||||
|
||||
## 入口表(前端 → API / WS)
|
||||
|
||||
| 调用方 | 方法 | 路径 | 鉴权 |
|
||||
|--------|------|------|------|
|
||||
| useFilesActions | POST | `/sync/file-ops`, `/sync/write-file`, `/sync/chmod`, `/sync/compress`, `/sync/decompress`, `/sync/upload`, `/sync/download` | http JWT |
|
||||
| useFilesEditor | 经 `readRemoteFileContent` | `/sync/read-file` | http JWT |
|
||||
| useFilesPermissions | GET/POST | `/servers/{id}/files-capability`, `setup-files-sudo` | http JWT |
|
||||
| useTerminalSessions | POST | `/auth/webssh-token` | http JWT |
|
||||
| useTerminalSessions | WS | `/ws/terminal/{id}?token=` | purpose=webssh JWT |
|
||||
| useTerminalCmdBar | WS DATA | 经 `sendWsData` | 同上 |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
|---|-----------|------|------|
|
||||
| H-Auth | useFilesActions.ts:255-494 | SAFE | 全部经 `@/api` JWT |
|
||||
| H-Path | useFilesActions.ts:297-301,461-464 | SAFE | `validatePathSegment` 拦截 `/` `..` |
|
||||
| H-Path | useFilesActions.ts:340-347 | RISK | rename 未调 validatePathSegment;后端 sync_v2 校验 |
|
||||
| H-Path | useFilesActions.ts:71-78,119 | SAFE | `normalizeRemotePath` / `joinRemotePath` |
|
||||
| H-Delete | useFilesActions.ts:393-414 | SAFE | confirm + 逐条 delete;失败计数 |
|
||||
| H-Upload | useFilesActions.ts:486-494 | SAFE | server_id + remote_path 参数化 POST |
|
||||
| H-Auth | useFilesEditor.ts:94-98 | SAFE | readRemoteFileContent + server_id |
|
||||
| H-Size | useFilesEditor.ts:63-70 | SAFE | 2MB 编辑上限 `FILE_EDITOR_MAX_BYTES` |
|
||||
| H-Auth | useFilesPermissions.ts:65-78 | SAFE | JWT GET/POST |
|
||||
| H-Sudo | useFilesPermissions.ts:73-91 | SAFE | 一键 sudo 走后端 re-auth+SSH;无密码回传 |
|
||||
| H-Storage | useFilesPermissions.ts:56 | SAFE | sessionStorage 仅 hint dismissed 标记 |
|
||||
| H-Auth | useTerminalSessions.ts:279-281 | SAFE | webssh-token 绑定 server_id |
|
||||
| H-WS | useTerminalSessions.ts:293-294 | RISK | query token;单人运维已接受 |
|
||||
| H-WS | useTerminalSessions.ts:350-363 | SAFE | 4001/4003 分支处理 |
|
||||
| H-Path | useTerminalSessions.ts:159-163,513,578 | RISK | `sanitizeRemotePath` 未拦 `;|&$`;cd 字符串拼接;管理员会话 |
|
||||
| H-Cmd | useTerminalSessions.ts:648-655 | SAFE | 快捷命令来自 API/内置白名单 |
|
||||
| H-Cmd | useTerminalCmdBar.ts:21-34 | SAFE | 命令经 WS DATA;后端 dangerous check |
|
||||
| H-Storage | useTerminalCmdBar.ts:7-33 | RISK | localStorage 存命令历史(非密码);UX 便利 |
|
||||
| H-Secret | 五文件 | SAFE | 无 password/api_key 存 localStorage |
|
||||
|
||||
**len(H)=18, Closure=18**
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
可选后续(P2/UX):rename 前端补 `validatePathSegment`;`sanitizeRemotePath` 收紧或 cd 改用引号包裹。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] len(H) == Closure
|
||||
- [x] 五文件全文 Read(大文件分段至 EOF)
|
||||
- [x] 无 v-html / 凭据明文存储
|
||||
|
||||
## 验证
|
||||
|
||||
`bash scripts/local_verify.sh` — 全绿
|
||||
@@ -0,0 +1,76 @@
|
||||
# Phase 1 Delta 审计 — Wave D6(认证链 / Login)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**范围**: 登录页 + auth store + HTTP 客户端 + 路由守卫 + WS URL
|
||||
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 语言 | 行数 N | Read 范围 |
|
||||
|---|------|------|--------|-----------|
|
||||
| 1 | `frontend/src/pages/LoginPage.vue` | Vue | 244 | 1–244 全文 |
|
||||
| 2 | `frontend/src/stores/auth.ts` | TS | 132 | 1–132 全文 |
|
||||
| 3 | `frontend/src/api/index.ts` | TS | 308 | 1–308 全文 |
|
||||
| 4 | `frontend/src/router/index.ts` | TS | 68 | 1–68 全文 |
|
||||
| 5 | `frontend/src/utils/wsUrl.ts` | TS | 23 | 1–23 全文 |
|
||||
|
||||
## Step 3 — 规则扫描 H(摘要)
|
||||
|
||||
| 文件 | H 命中 |
|
||||
|------|--------|
|
||||
| LoginPage.vue | H-Secret, H-Redirect, H-Lockout, H-XSS |
|
||||
| auth.ts | H-Token, H-Refresh, H-Profile |
|
||||
| api/index.ts | H-Auth, H-Refresh, H-401 |
|
||||
| router/index.ts | H-Guard, H-Redirect |
|
||||
| wsUrl.ts | H-WS |
|
||||
|
||||
## 入口表
|
||||
|
||||
| 模块 | 入口 | 鉴权 |
|
||||
|------|------|------|
|
||||
| LoginPage | POST `/auth/login` | 公开 |
|
||||
| LoginPage | GET `/settings/bing-wallpapers` | 公开(auth_jwt 白名单) |
|
||||
| auth store | POST `/auth/refresh`, `/auth/logout`, GET `/auth/me` | refresh cookie / Bearer |
|
||||
| api | `fetchAuthed` 全站 API | Bearer + credentials |
|
||||
| router | `beforeEach` | bootstrapped + isLoggedIn |
|
||||
| wsUrl | WS URL 构建 | 供 terminal/sync 使用 |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
|---|-----------|------|------|
|
||||
| H-Secret | LoginPage.vue:102-103 | SAFE | password 仅组件 ref,不落 localStorage |
|
||||
| H-Secret | auth.ts:26-27 | SAFE | access token 内存 Pinia ref |
|
||||
| H-Redirect | LoginPage.vue:178-179 | SAFE | `startsWith('/') && !startsWith('//')` 防 open redirect |
|
||||
| H-Lockout | LoginPage.vue:186-188 | SAFE | 429 → 15min 本地 lockout UI |
|
||||
| H-TOTP | LoginPage.vue:182-184 | SAFE | TotpRequiredError → 显示 TOTP 字段 |
|
||||
| H-XSS | LoginPage.vue:11-12 | SAFE | `{{ error }}` 文本插值,无 v-html |
|
||||
| H-Refresh | auth.ts:45-66 | SAFE | HttpOnly cookie refresh;失败 silent |
|
||||
| H-Token | auth.ts:36-38 | SAFE | exp 解码仅用于续期阈值 |
|
||||
| H-Profile | auth.ts:89-97 | SAFE | 401 → forceLogout |
|
||||
| H-Auth | api/index.ts:68-70 | SAFE | Bearer 注入 |
|
||||
| H-Refresh | api/index.ts:19-44 | SAFE | 单飞 refreshInFlight 防并发 |
|
||||
| H-Refresh | api/index.ts:84-86 | SAFE | 过期前 5min 主动 refresh |
|
||||
| H-401 | api/index.ts:94-110 | SAFE | 401 重试一次后 forceLogout |
|
||||
| H-Cookie | api/index.ts:27-28,91 | SAFE | credentials: include |
|
||||
| H-Guard | router/index.ts:55-65 | SAFE | 非 public 路由需 isLoggedIn |
|
||||
| H-Guard | router/index.ts:57-58 | SAFE | bootstrapped 前 tryRestoreSession |
|
||||
| H-Public | router/index.ts:18 | SAFE | Login meta.public |
|
||||
| H-WS | wsUrl.ts:17-20 | RISK | token 放 query;已接受 |
|
||||
| H-Wallpaper | LoginPage.vue:121-123 | SAFE | 公开壁纸 API intentional |
|
||||
|
||||
**len(H)=19, Closure=19**
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] len(H) == Closure
|
||||
- [x] 五文件全文 Read
|
||||
- [x] 认证链:内存 token + HttpOnly refresh + 路由守卫
|
||||
|
||||
## 验证
|
||||
|
||||
`bash scripts/local_verify.sh` — 全绿
|
||||
@@ -0,0 +1,78 @@
|
||||
# Phase 1 Delta 审计 — Wave D7(Deploy / 本地验证脚本)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**范围**: 门控脚本 + 本地 dev/verify + docker-compose
|
||||
**标准**: 变更审查(运维/门控;非业务 API 8 步,沿用 Closure 表格式)
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 语言 | 行数 N | Read 范围 |
|
||||
|---|------|------|--------|-----------|
|
||||
| 1 | `deploy/pre_deploy_check.sh` | Bash | 299 | 1–299 全文 |
|
||||
| 2 | `scripts/local_verify.sh` | Bash | 25 | 1–25 全文 |
|
||||
| 3 | `scripts/local_integration_smoke.sh` | Bash | 91 | 1–91 全文 |
|
||||
| 4 | `scripts/start-dev.sh` | Bash | 90 | 1–90 全文 |
|
||||
| 5 | `docker-compose.yml` | YAML | 89 | 1–89 全文 |
|
||||
|
||||
## Step 3 — 规则扫描 H(摘要)
|
||||
|
||||
| 文件 | H 命中 |
|
||||
|------|--------|
|
||||
| pre_deploy_check.sh | H-Gate, H-Secret, H-Git |
|
||||
| local_verify.sh | H-Chain |
|
||||
| local_integration_smoke.sh | H-Health, H-Auth |
|
||||
| start-dev.sh | H-DevBind, H-Env |
|
||||
| docker-compose.yml | H-Port, H-DefaultCreds |
|
||||
|
||||
## 入口表(脚本调用链)
|
||||
|
||||
```
|
||||
local_verify.sh
|
||||
→ start-dev.sh (docker mysql+redis, uvicorn :8600)
|
||||
→ local_integration_smoke.sh (/health, JWT 401, unit tests)
|
||||
→ tests/test_api.py
|
||||
→ ruff check server/ -F
|
||||
|
||||
pre_deploy_check.sh (独立 L3 门控,7+2 pre-flight)
|
||||
```
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
|---|-----------|------|------|
|
||||
| H-Gate | pre_deploy_check.sh:50-74 | SAFE | Changelog 日期+≥10 行 |
|
||||
| H-Gate | pre_deploy_check.sh:76-105 | RISK | 审计路径 `docs/audit/`;delta 报告在 `docs/reports/` 不自动过 Gate2 |
|
||||
| H-Gate | pre_deploy_check.sh:107-131 | SAFE | test_api 必须存在且通过 |
|
||||
| H-Gate | pre_deploy_check.sh:134-160 | SAFE | ruff F;未装则 SKIP |
|
||||
| H-Gate | pre_deploy_check.sh:194-218 | RISK | bandit `-ll` 仅 HIGH;文档写 HIGH/MEDIUM 有漂移 |
|
||||
| H-Gate | pre_deploy_check.sh:221-258 | RISK | Gate7 用 `HEAD~1` diff;未 commit 改动可能漏检 |
|
||||
| H-Gate | pre_deploy_check.sh:261-284 | SAFE | shell/text EOL pre-flight |
|
||||
| H-Chain | local_verify.sh:10-22 | SAFE | 固定顺序 smoke→test_api→ruff |
|
||||
| H-Health | local_integration_smoke.sh:67-70 | SAFE | /health 200 |
|
||||
| H-Auth | local_integration_smoke.sh:72-75 | SAFE | /api/servers/ 无 JWT → 401 |
|
||||
| H-DevBind | start-dev.sh:75-76 | RISK | uvicorn `--host 0.0.0.0` 仅本地 dev |
|
||||
| H-Env | start-dev.sh:29-32 | SAFE | 无 .env 时 generate_env,不写 git |
|
||||
| H-Port | docker-compose.yml:40-41 | SAFE | Redis publish 6379 修复本机 uvicorn 连 Redis |
|
||||
| H-Port | docker-compose.yml:26-27 | RISK | MySQL 3306 暴露主机;dev 惯例 |
|
||||
| H-DefaultCreds | docker-compose.yml:14-17 | RISK | 默认 dev 密码;非生产 compose |
|
||||
| H-Secret | docker-compose.yml:68-70 | SAFE | SECRET/API/ENCRYPTION 从 env 注入,无硬编码 |
|
||||
|
||||
**len(H)=16, Closure=16**
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
**运维备注(非阻塞)**:
|
||||
- Phase1 delta 报告在 `docs/reports/audit-delta-*.md`;部署前若只跑 pre_deploy,需另备 `docs/audit/YYYY-MM-DD-*.md` 或调整 Gate2 路径。
|
||||
- 生产部署仍走 SSH + handoff,不依赖本 compose 默认密码。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] len(H) == Closure
|
||||
- [x] 五文件全文 Read
|
||||
- [x] local_verify 链路可复现
|
||||
|
||||
## 验证
|
||||
|
||||
`bash scripts/local_verify.sh` — 全绿
|
||||
@@ -0,0 +1,50 @@
|
||||
# Phase 1 Delta 审计 — Wave D8(汇总 Closure)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**范围**: D1–D7 delta 波次汇总 + registry 更新
|
||||
**标准**: Phase 1 收尾 DoD
|
||||
|
||||
## 汇总表
|
||||
|
||||
| 波次 | 主题 | 文件数 | H | P0/P1 | 报告 |
|
||||
|------|------|--------|---|-------|------|
|
||||
| D1 | sync/后台 | 5 | 19 | 0 | [waveD1](audit-delta-2026-06-04-waveD1.md) |
|
||||
| D2 | auth/agent/ws | 5 | 22 | 0 | [waveD2](audit-delta-2026-06-04-waveD2.md) |
|
||||
| D3 | servers/settings/scripts/webssh | 5 | 24 | 0 | [waveD3](audit-delta-2026-06-04-waveD3.md) |
|
||||
| D4 | 前端 Push | 5 | 17 | 0 | [waveD4](audit-delta-2026-06-04-waveD4.md) |
|
||||
| D5 | 前端 Files/Terminal | 5 | 18 | 0 | [waveD5](audit-delta-2026-06-04-waveD5.md) |
|
||||
| D6 | 认证链 Login | 5 | 19 | 0 | [waveD6](audit-delta-2026-06-04-waveD6.md) |
|
||||
| D7 | Deploy/本地脚本 | 5 | 16 | 0 | [waveD7](audit-delta-2026-06-04-waveD7.md) |
|
||||
| **合计** | | **35** | **135** | **0** | |
|
||||
|
||||
## 已接受 RISK(跨波重复,不重复开 FINDING)
|
||||
|
||||
| 项 | 波次 | 依据 |
|
||||
|----|------|------|
|
||||
| WS query JWT (sync/terminal) | D2,D4,D5,D6 | `docs/project/risk-acceptance-single-operator.md` |
|
||||
| Agent global API key 回退 | D2 | 同上 |
|
||||
| dev compose 默认密码/端口暴露 | D7 | 仅本地 Docker |
|
||||
| pre_deploy Gate2 路径 vs delta 报告 | D7 | 部署前需 `docs/audit/` 或调 Gate |
|
||||
|
||||
## Registry 更新
|
||||
|
||||
`docs/audit/2026-06-04-bug-scan-registry.json` 新增 `delta_waves[]`(D1–D8 元数据)。
|
||||
|
||||
## Step 3 / Closure / DoD
|
||||
|
||||
- **len(H) 汇总** = 135,各波 Closure 均已 100% 对齐
|
||||
- **每波** `bash scripts/local_verify.sh` 均通过
|
||||
- **无 P0/P1** 待修项进入 Phase 2
|
||||
|
||||
## 下一步(计划 Phase 2 / L3)
|
||||
|
||||
1. `bash deploy/pre_deploy_check.sh`(L3 门控;需当日 `docs/audit/` 若走生产门控)
|
||||
2. Phase 2 高险深审:`servers.py` / `sync_v2.py` / `files.py` 等节选全量 8 步
|
||||
3. L4 Playwright E2E:`frontend/e2e/full-acceptance.spec.mjs`
|
||||
|
||||
## 验证
|
||||
|
||||
```bash
|
||||
bash scripts/local_verify.sh # ✅ 2026-06-04
|
||||
pytest tests/ -q # 建议 Phase1 收尾跑一次全量
|
||||
```
|
||||
@@ -0,0 +1,66 @@
|
||||
# 前端 14p batch 合并卷
|
||||
|
||||
> 生成日期: 2026-06-04 · 源文件 3 篇 · 原文 `docs/archive/audits/2026-06-04-frontend-14p/`
|
||||
|
||||
## 批次索引
|
||||
|
||||
### `audit-frontend-14p-2026-06-04-batch1.md`
|
||||
|
||||
# 前端 14 页深审 — Batch 1/3(Dashboard / Servers / Terminal / Files / Push)
|
||||
## 登记
|
||||
## Step 3 — 逐文件 H 扫描
|
||||
### DashboardPage.vue (415)
|
||||
### ServersPage.vue (477)
|
||||
### TerminalPage.vue (408)
|
||||
### FilesPage.vue (38)
|
||||
### PushPage.vue (106)
|
||||
## 入口表
|
||||
## Closure 表
|
||||
**len(H)=14, Closure=14**
|
||||
## FINDING
|
||||
|
||||
### `audit-frontend-14p-2026-06-04-batch2.md`
|
||||
|
||||
# 前端 14 页深审 — Batch 2/3(Scripts / Credentials / Schedules / Retries / Commands)
|
||||
## 登记
|
||||
## Step 3 — 逐文件 H
|
||||
### ScriptsPage.vue (535)
|
||||
### CredentialsPage.vue (400)
|
||||
### SchedulesPage.vue (295)
|
||||
### RetriesPage.vue (191)
|
||||
### CommandsPage.vue (168)
|
||||
## Closure 表
|
||||
**len(H)=15, Closure=15**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
### `audit-frontend-14p-2026-06-04-batch3.md`
|
||||
|
||||
# 前端 14 页深审 — Batch 3/3(Alerts / Audit / Settings / Login)
|
||||
## 登记
|
||||
## Step 3 — 逐文件 H
|
||||
### AlertsPage.vue (184)
|
||||
### AuditPage.vue (154)
|
||||
### SettingsPage.vue (497)
|
||||
### LoginPage.vue (244)
|
||||
## Closure 表
|
||||
**len(H)=14, Closure=14**
|
||||
## 14 页汇总
|
||||
| 页面 | 行数 | 批次 | P0/P1 |
|
||||
## FINDING
|
||||
|
||||
## Closure 摘录(合并)
|
||||
|
||||
| H | 行号 | 规则 | 命中 |
|
||||
| H1 | 237,304-341 | API JWT | GET stats/alerts/audit/servers |
|
||||
| H2 | 393-397 | WS | useWebSocket 刷新 stats |
|
||||
| H3 | 383-387 | 路由 | server_id query 跳转 |
|
||||
| H4 | 268-345 | 错误 | snackbar 非静默 |
|
||||
| H5 | 405 | 副作用 | bing-wallpaper sync POST |
|
||||
| H | 行号 | 规则 |
|
||||
| H1 | 358-390 | CRUD /scripts JWT |
|
||||
| H2 | 415-419 | exec script_id + server_ids |
|
||||
| H3 | 463-467 | quick command exec |
|
||||
| H4 | 527-528 | poll timer cleanup |
|
||||
| H1 | 142-160 | GET /alert-history 分页+过滤 |
|
||||
| H2 | 147 | loadStats 失败 snackbar |
|
||||
@@ -0,0 +1,96 @@
|
||||
# 前端 14 页深审 — Batch 1/3(Dashboard / Servers / Terminal / Files / Push)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步
|
||||
**说明**: 按路由顺序;每页 **1–N 全文 Read**;编排页含 composable 入口追踪
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 行数 N | Read 范围 |
|
||||
|---|------|--------|-----------|
|
||||
| 1 | `frontend/src/pages/DashboardPage.vue` | 415 | 1–415 全文 |
|
||||
| 2 | `frontend/src/pages/ServersPage.vue` | 477 | 1–477 全文 |
|
||||
| 3 | `frontend/src/pages/TerminalPage.vue` | 408 | 1–408 全文 |
|
||||
| 4 | `frontend/src/pages/FilesPage.vue` | 38 | 1–38 全文 |
|
||||
| 5 | `frontend/src/pages/PushPage.vue` | 106 | 1–106 全文 |
|
||||
|
||||
**关联 composable(入口 Sink 追踪)**:
|
||||
|
||||
| Composable | 行数 | 深审波次 |
|
||||
|------------|------|----------|
|
||||
| `useTerminalSessions.ts` | 749 | D5 + P2-5 webssh 链 |
|
||||
| `useFilesPage.ts` + files/* | — | D5 + P2-1 |
|
||||
| `usePushPage.ts` + push/* | — | D4 + P2-2 |
|
||||
|
||||
## Step 3 — 逐文件 H 扫描
|
||||
|
||||
### DashboardPage.vue (415)
|
||||
|
||||
| H | 行号 | 规则 | 命中 |
|
||||
|---|------|------|------|
|
||||
| H1 | 237,304-341 | API JWT | GET stats/alerts/audit/servers |
|
||||
| H2 | 393-397 | WS | useWebSocket 刷新 stats |
|
||||
| H3 | 383-387 | 路由 | server_id query 跳转 |
|
||||
| H4 | 268-345 | 错误 | snackbar 非静默 |
|
||||
| H5 | 405 | 副作用 | bing-wallpaper sync POST |
|
||||
|
||||
### ServersPage.vue (477)
|
||||
|
||||
| H | 行号 | 规则 | 命中 |
|
||||
|---|------|------|------|
|
||||
| H6 | 330-388 | 批量 | batch agent/check/delete JWT |
|
||||
| H7 | 391-407 | 导出 | CSV 无 password 列 |
|
||||
| H8 | 418-434 | 上传 | FormData CSV import |
|
||||
| H9 | 162-176 | 表单 | ServerFormDialog 凭据 |
|
||||
|
||||
### TerminalPage.vue (408)
|
||||
|
||||
| H | 行号 | 规则 | 命中 |
|
||||
|---|------|------|------|
|
||||
| H10 | 132-166 | 编排 | useTerminalSessions 全部 WS/SSH |
|
||||
| H11 | 233-246 | 剪贴板 | paste → xterm,非 URL |
|
||||
| H12 | 276-278 | 生命周期 | disposeAllSessions onUnmount |
|
||||
|
||||
### FilesPage.vue (38)
|
||||
|
||||
| H | 行号 | 规则 | 命中 |
|
||||
|---|------|------|------|
|
||||
| H13 | 33-37 | 编排 | provideFilesPage + useFilesPage |
|
||||
|
||||
### PushPage.vue (106)
|
||||
|
||||
| H | 行号 | 规则 | 命中 |
|
||||
|---|------|------|------|
|
||||
| H14 | 105 | 编排 | usePushPage 解构 form/progress/preview |
|
||||
|
||||
## 入口表
|
||||
|
||||
| 页面 | 用户输入 | API / WS |
|
||||
|------|----------|----------|
|
||||
| Dashboard | search | GET /servers/*, /alert-history/, /audit/ |
|
||||
| Servers | search, CSV, form | CRUD /servers, batch/*, import |
|
||||
| Terminal | cmd, quickCmd | POST /auth/webssh-token, WS /ws/terminal |
|
||||
| Files | —(组件内) | GET /files/browse, sync/read-file |
|
||||
| Push | path, servers | POST /sync/*, WS /ws/sync |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 判定 | 依据 |
|
||||
|---|------|------|
|
||||
| H1-H5 | SAFE | JWT http;错误有 snackbar |
|
||||
| H2 | RISK | WS query token(已接受 ADR-011) |
|
||||
| H6-H9 | SAFE | 批量需 JWT;CSV 无凭据导出 |
|
||||
| H10-H12 | SAFE | WebSSH token 短期;dispose 清理 |
|
||||
| H13-H14 | SAFE | 逻辑在已审 composable,页壳无 sink |
|
||||
|
||||
**len(H)=14, Closure=14**
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] 5 页全文 Read(Terminal 408 行含 style)
|
||||
- [x] composable 入口表完整
|
||||
- [x] len(H)==Closure
|
||||
@@ -0,0 +1,77 @@
|
||||
# 前端 14 页深审 — Batch 2/3(Scripts / Credentials / Schedules / Retries / Commands)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**标准**: 8 步逐行
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 行数 N | Read 范围 |
|
||||
|---|------|--------|-----------|
|
||||
| 1 | `frontend/src/pages/ScriptsPage.vue` | 535 | 1–535 全文 |
|
||||
| 2 | `frontend/src/pages/CredentialsPage.vue` | 400 | 1–400 全文 |
|
||||
| 3 | `frontend/src/pages/SchedulesPage.vue` | 295 | 1–295 全文 |
|
||||
| 4 | `frontend/src/pages/RetriesPage.vue` | 191 | 1–191 全文 |
|
||||
| 5 | `frontend/src/pages/CommandsPage.vue` | 168 | 1–168 全文 |
|
||||
|
||||
## Step 3 — 逐文件 H
|
||||
|
||||
### ScriptsPage.vue (535)
|
||||
|
||||
| H | 行号 | 规则 |
|
||||
|---|------|------|
|
||||
| H1 | 358-390 | CRUD /scripts JWT |
|
||||
| H2 | 415-419 | exec script_id + server_ids |
|
||||
| H3 | 463-467 | quick command exec |
|
||||
| H4 | 527-528 | poll timer cleanup |
|
||||
|
||||
### CredentialsPage.vue (400)
|
||||
|
||||
| H | 行号 | 规则 |
|
||||
|---|------|------|
|
||||
| H5 | 253-255 | GET 列表无密码 |
|
||||
| H6 | 323-327 | encrypted_pw POST only |
|
||||
| H7 | 306,340,357 | 编辑留空不改 |
|
||||
| H8 | 346-347 | SSH 私钥提交时传输 |
|
||||
|
||||
### SchedulesPage.vue (295)
|
||||
|
||||
| H | 行号 | 规则 |
|
||||
|---|------|------|
|
||||
| H9 | 177 | cron 正则 `^[\d\s*/,\-]+$` |
|
||||
| H10 | 173-189 | buildSchedulePayload 校验 |
|
||||
| H11 | 263-267 | runNow → POST /sync/files |
|
||||
|
||||
### RetriesPage.vue (191)
|
||||
|
||||
| H | 行号 | 规则 |
|
||||
|---|------|------|
|
||||
| H12 | 129-134 | 客户端 filter(展示) |
|
||||
| H13 | 146,160 | retry/delete JWT |
|
||||
|
||||
### CommandsPage.vue (168)
|
||||
|
||||
| H | 行号 | 规则 |
|
||||
|---|------|------|
|
||||
| H14 | 139-153 | 只读 command-logs / ssh-sessions |
|
||||
| H15 | 50 | command 文本展示(后端已存) |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 判定 | 依据 |
|
||||
|---|------|------|
|
||||
| H1-H4 | SAFE/RISK | exec 走后端;H3 RISK 临时命令(后端 dangerous check) |
|
||||
| H5-H8 | SAFE | 无 localStorage;API 脱敏 |
|
||||
| H9-H11 | SAFE | cron/路径校验;sync JWT |
|
||||
| H12-H13 | SAFE | 只读+操作 JWT |
|
||||
| H14-H15 | SAFE | 只读审计视图 |
|
||||
|
||||
**len(H)=15, Closure=15**
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] 5 页全文 Read
|
||||
- [x] len(H)==Closure
|
||||
@@ -0,0 +1,93 @@
|
||||
# 前端 14 页深审 — Batch 3/3(Alerts / Audit / Settings / Login)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**标准**: 8 步逐行
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 行数 N | Read 范围 |
|
||||
|---|------|--------|-----------|
|
||||
| 1 | `frontend/src/pages/AlertsPage.vue` | 184 | 1–184 全文 |
|
||||
| 2 | `frontend/src/pages/AuditPage.vue` | 154 | 1–154 全文 |
|
||||
| 3 | `frontend/src/pages/SettingsPage.vue` | 497 | 1–497 全文 |
|
||||
| 4 | `frontend/src/pages/LoginPage.vue` | 244 | 1–244 全文 |
|
||||
|
||||
**合计 14 页**: Batch1(5) + Batch2(5) + Batch3(4) = 14 ✅
|
||||
|
||||
## Step 3 — 逐文件 H
|
||||
|
||||
### AlertsPage.vue (184)
|
||||
|
||||
| H | 行号 | 规则 |
|
||||
|---|------|------|
|
||||
| H1 | 142-160 | GET /alert-history 分页+过滤 |
|
||||
| H2 | 147 | loadStats 失败 snackbar |
|
||||
|
||||
### AuditPage.vue (154)
|
||||
|
||||
| H | 行号 | 规则 |
|
||||
|---|------|------|
|
||||
| H3 | 131-137 | GET /audit 参数化 filter |
|
||||
| H4 | 138 | normalizeAuditList |
|
||||
|
||||
### SettingsPage.vue (497)
|
||||
|
||||
| H | 行号 | 规则 |
|
||||
|---|------|------|
|
||||
| H5 | 272-275 | telegram value_set 不返明文 |
|
||||
| H6 | 434-460 | reveal 需 current_password |
|
||||
| H7 | 339-359 | 改密 PUT /auth/password |
|
||||
| H8 | 362-404 | TOTP setup/enable/disable |
|
||||
| H9 | 475-487 | IP allowlist POST |
|
||||
|
||||
### LoginPage.vue (244)
|
||||
|
||||
| H | 行号 | 规则 |
|
||||
|---|------|------|
|
||||
| H10 | 177 | auth.login 内存 token |
|
||||
| H11 | 179 | redirect 防开放重定向 `//` |
|
||||
| H12 | 186-188 | 429 lockout 15min |
|
||||
| H13 | 102-103 | password ref 非 localStorage |
|
||||
| H14 | 123 | bing wallpapers 公开 GET |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 判定 | 依据 |
|
||||
|---|------|------|
|
||||
| H1-H2 | SAFE | 只读告警 |
|
||||
| H3-H4 | SAFE | 只读审计+normalize |
|
||||
| H5-H9 | SAFE | 敏感 reveal re-auth;TOTP 流程完整 |
|
||||
| H10-H13 | SAFE | 无持久化密码;redirect 校验 |
|
||||
| H14 | SAFE | 壁纸 URL 无凭据 |
|
||||
|
||||
**len(H)=14, Closure=14**
|
||||
|
||||
## 14 页汇总
|
||||
|
||||
| 页面 | 行数 | 批次 | P0/P1 |
|
||||
|------|------|------|-------|
|
||||
| DashboardPage | 415 | B1 | 0 |
|
||||
| ServersPage | 477 | B1 | 0 |
|
||||
| TerminalPage | 408 | B1 | 0 |
|
||||
| FilesPage | 38 | B1 | 0 |
|
||||
| PushPage | 106 | B1 | 0 |
|
||||
| ScriptsPage | 535 | B2 | 0 |
|
||||
| CredentialsPage | 400 | B2 | 0 |
|
||||
| SchedulesPage | 295 | B2 | 0 |
|
||||
| RetriesPage | 191 | B2 | 0 |
|
||||
| CommandsPage | 168 | B2 | 0 |
|
||||
| AlertsPage | 184 | B3 | 0 |
|
||||
| AuditPage | 154 | B3 | 0 |
|
||||
| SettingsPage | 497 | B3 | 0 |
|
||||
| LoginPage | 244 | B3 | 0 |
|
||||
| **合计** | **4112** | **3 批** | **0** |
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] 14/14 页全文 Read
|
||||
- [x] 3 批 Closure 合计 43 H 全对齐
|
||||
- [x] 4112 行 frontend pages 覆盖完成
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,237 @@
|
||||
# Phase2 P2 合并卷
|
||||
|
||||
> 生成日期: 2026-06-04 · 源文件 9 篇 · 原文 `docs/archive/audits/2026-06-04-phase2/`
|
||||
|
||||
## 批次索引
|
||||
|
||||
### `audit-phase2-2026-06-04-waveP2-1.md`
|
||||
|
||||
# Phase 2 深审 — Wave P2-1(Files / SSH 基础设施)
|
||||
## 登记
|
||||
## 入口表
|
||||
## Closure 表
|
||||
**len(H)=17, Closure=17**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
## L3 门控(同日记录)
|
||||
## DoD
|
||||
- [x] len(H) == Closure
|
||||
## 验证
|
||||
|
||||
### `audit-phase2-2026-06-04-waveP2-2.md`
|
||||
|
||||
# Phase 2 深审 — Wave P2-2(sync_v2 全文 + 路径/Shell 依赖)
|
||||
## 登记
|
||||
## 入口表(sync_v2 全 22 路由)
|
||||
## Closure 表
|
||||
**len(H)=20, Closure=20**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
## DoD
|
||||
- [x] len(H) == Closure
|
||||
## 验证
|
||||
|
||||
### `audit-phase2-2026-06-04-waveP2-3.md`
|
||||
|
||||
# Phase 2 深审 — Wave P2-3(WebSocket / Dashboard 告警链)
|
||||
## 登记
|
||||
## 入口表
|
||||
## Closure 表
|
||||
**len(H)=16, Closure=16**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
## DoD
|
||||
- [x] len(H) == Closure
|
||||
## 验证
|
||||
|
||||
### `audit-phase2-2026-06-04-waveP2-4.md`
|
||||
|
||||
# Phase 2 深审 — Wave P2-4(servers.py 全文)
|
||||
## 登记
|
||||
## 入口表(servers.py 26 路由)
|
||||
## Closure 表
|
||||
**len(H)=20, Closure=20**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
## DoD
|
||||
- [x] len(H) == Closure
|
||||
## 验证
|
||||
|
||||
### `audit-phase2-2026-06-04-waveP2-5.md`
|
||||
|
||||
# Phase 2 深审 — Wave P2-5(webssh.py 全文)
|
||||
## 登记
|
||||
## 入口表
|
||||
## Closure 表
|
||||
**len(H)=17, Closure=17**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
## DoD
|
||||
- [x] len(H) == Closure
|
||||
## 验证
|
||||
|
||||
### `audit-phase2-2026-06-04-waveP2-6.md`
|
||||
|
||||
# Phase 2 深审 — Wave P2-6(sync_engine_v2.py 全文)
|
||||
## 登记
|
||||
## 入口表(服务层,经 sync_v2 API 调用)
|
||||
## Closure 表
|
||||
**len(H)=17, Closure=17**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
## DoD
|
||||
- [x] len(H) == Closure
|
||||
## 验证
|
||||
|
||||
### `audit-phase2-2026-06-04-waveP2-7.md`
|
||||
|
||||
# Phase 2 深审 — Wave P2-7(前端页 5/14)
|
||||
## 登记
|
||||
## Closure 表
|
||||
**len(H)=13, Closure=13**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
## DoD
|
||||
|
||||
### `audit-phase2-2026-06-04-waveP2-8.md`
|
||||
|
||||
# Phase 2 深审 — Wave P2-8(前端页 5/14)
|
||||
## 登记
|
||||
## Closure 表
|
||||
**len(H)=11, Closure=11**
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
### `audit-phase2-2026-06-04-waveP2-9.md`
|
||||
|
||||
# Phase 2 深审 — Wave P2-9(前端页 4/14 + 编排层)
|
||||
## 登记
|
||||
## Closure 表
|
||||
**len(H)=5, Closure=5**
|
||||
## 交叉引用
|
||||
## FINDING
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
## Closure 摘录(合并)
|
||||
|
||||
| SSH | `list_remote_directory` → `ls -la` | 经 pool + server 凭据 |
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
| H-Auth | sync_v2.py:74–1614 | SAFE | 22 路由均 `Depends(get_current_admin)` |
|
||||
| H-Shell | sync_v2.py:156-168 | RISK | `rm -rf` 删目录;JWT+审计+前端 confirm |
|
||||
| H-Shell | sync_v2.py:156,165,168,223-227 | SAFE | path shlex.quote |
|
||||
| H-Path | sync_v2.py:149-165 | SAFE | normalize_remote_abs_path |
|
||||
| H-Clipboard | sync_v2.py:207-208 | SAFE | assert_clipboard_transfer_safe |
|
||||
| H-Sandbox | sync_v2.py:302,341,413,721 | SAFE | ensure_under_nexus_upload |
|
||||
| H-Source | sync_v2.py:548,1096 | SAFE | FORBIDDEN prefixes + resolve |
|
||||
| H-Audit | sync_v2.py:461-475 | SAFE | 失败 log warning+exc_info,非静默 pass |
|
||||
| H-Upload | sync_v2.py:876-877,977-978 | SAFE | 100MB / 500MB 上限 |
|
||||
| H-ZipSlip | sync_v2.py:1000-1005 | SAFE | assert_zip + is_path_under_prefix |
|
||||
| H-Download | sync_v2.py:1244-1272 | SAFE | 100MB + filename sanitize |
|
||||
| H-Read | sync_v2.py:1322-1326 | SAFE | max_size 来自 payload |
|
||||
| H-Write | sync_v2.py:1394-1414 | SAFE | 5MB + etag 409 冲突 |
|
||||
| H-Chmod | sync_v2.py:1507-1514 | SAFE | recursive policy + test -d |
|
||||
| H-Verify | sync_v2.py:1145-1146 | SAFE | sha256sum 路径 shlex.quote |
|
||||
| H-Path | posix_paths.py:46-59 | SAFE | 禁 `..` 与反斜杠 |
|
||||
| H-Path | posix_paths.py:117-136 | SAFE | upload 前缀 + zip-slip |
|
||||
| H-Sudo | remote_shell.py:35-53 | SAFE | bash -c + shlex.quote(command) |
|
||||
| H-Clipboard | remote_path_validation.py:24-33 | SAFE | dest 非源子树 |
|
||||
| H-Parse | unix_ls.py:70-71 | SAFE | 跳过 `.` `..` |
|
||||
| H-WS-Auth | websocket.py:304-311,340-347 | SAFE | 无 token → 4001;无效 → 4401 |
|
||||
| H-WS-Token | websocket.py:366-410 | SAFE | tv/updated_at 与 HTTP JWT 一致 |
|
||||
| H-WS-ADR011 | websocket.py:9,296 | RISK | query JWT;单人运维已接受 |
|
||||
| H-WS-Limit | websocket.py:49-52 | SAFE | MAX_CONNECTIONS=500 |
|
||||
| H-WS-Heartbeat | websocket.py:139-165 | SAFE | 30s ping / 60s zombie |
|
||||
| H-WS-Channel | websocket.py:246-249,531-551 | SAFE | alerts 与 sync 分 channel/manager |
|
||||
| H-WS-Dedup | websocket.py:416-437 | SAFE | Telegram 5min 冷却;WS 仍实时 |
|
||||
| H-WS-Recovery | websocket.py:512-513 | SAFE | recovery 清 cooldown |
|
||||
| H-Frontend-Token | useWebSocket.ts:61 | RISK | URL query token;同 ADR-011 |
|
||||
| H-Frontend-Auth | useWebSocket.ts:114-116 | SAFE | 4001/4401 → forceLogout |
|
||||
| H-Frontend-XSS | useWebSocket.ts:99-102 | SAFE | snackbar 文本插值,无 v-html |
|
||||
| H-Frontend-Singleton | useWebSocket.ts:17-18 | SAFE | 模块级单例;App 统一 connect |
|
||||
| H-Dashboard-Refresh | DashboardPage.vue:393-397 | SAFE | WS alert → reload stats/alerts |
|
||||
| H-Dashboard-API | DashboardPage.vue:302-337 | SAFE | http JWT 拉 stats/alert-history |
|
||||
| H-App-Lifecycle | App.vue:257-259 | SAFE | login connect / logout disconnect |
|
||||
| H-Alert-API | settings.py:768-828 | SAFE | alert-history JWT + 参数化 filter |
|
||||
| H-Auth | servers.py:26×路由 | SAFE | 26 端点均 `get_current_admin` |
|
||||
| H-Mask | servers.py:1692-1698 | SAFE | password_set / agent key 前缀截断 |
|
||||
| H-Encrypt | servers.py:1096-1099,559-562 | SAFE | Fernet encrypt 入库 |
|
||||
| H-Allowlist | servers.py:1163-1187 | SAFE | UPDATE 字段白名单;agent_api_key 排除 |
|
||||
| H-Reauth | servers.py:1256-1260,1479-1483 | SAFE | agent-key/install-cmd 需当前密码 |
|
||||
| H-Reveal | servers.py:1492-1502 | SAFE | install-cmd 不用全局 API_KEY |
|
||||
| H-AgentKey | servers.py:1282-1288 | SAFE | 生成后 display_once 响应 |
|
||||
| H-Fallback | servers.py:626,1321 | RISK | batch/single install 可回退 settings.API_KEY |
|
||||
| H-Shell | servers.py:631-633,1330-1332 | SAFE | install shlex.quote url/key/port |
|
||||
| H-Sudo | servers.py:36-60 | RISK | 临时 sudoers 白名单;运维必要 |
|
||||
| H-SudoPwd | servers.py:1025-1027 | SAFE | sudo -S 密码走 stdin 非 argv |
|
||||
| H-CSV | servers.py:376-388,445-446 | SAFE | formula injection 防御 + 1MB 上限 |
|
||||
| H-CSV | servers.py:499-501 | SAFE | MAX_IMPORT_ROWS=500 |
|
||||
| H-Batch | servers.py:615,686,772,850 | SAFE | Semaphore(5) 并发上限 |
|
||||
| H-Redis | servers.py:179-201,873-877 | SAFE | 心跳 overlay;失败 log warning |
|
||||
| H-Audit | servers.py: CUD/batch | SAFE | 写操作 AuditLog |
|
||||
| H-Crypto | crypto.py:20-26 | SAFE | 无 ENCRYPTION_KEY 则 RuntimeError |
|
||||
| H-Crypto | crypto.py:52-54 | SAFE | decrypt 失败 raise,非静默 |
|
||||
| H-Capability | files_capability.py:31-39 | SAFE | 只读 probe,无密码回传 |
|
||||
| H-Elevation | files_elevation.py:48-55 | SAFE | apply_files_elevation_payload |
|
||||
| H-Purpose | webssh.py:48-49 | SAFE | 拒绝非 webssh purpose |
|
||||
| H-Bind | webssh.py:106-109 | SAFE | token server_id 须匹配路径 |
|
||||
| H-TV | webssh.py:66-76 | SAFE | tv 校验;legacy updated_at +5s grace |
|
||||
| H-Close | webssh.py:97-104 | SAFE | 缺 token→4001;无效→4401 |
|
||||
| H-Issue | auth.py:334-346 | SAFE | 签发前 JWT + server/domain 校验 |
|
||||
| H-Scope | auth_service.py:455-470 | SAFE | JWT 含 server_id + purpose + tv |
|
||||
| H-Expire | auth_service.py:467 | SAFE | 15 分钟短期令牌 |
|
||||
| H-WSQuery | webssh.py:88, useTerminalSessions:293 | RISK | ADR-011 query token(已接受) |
|
||||
| H-Cred | webssh.py:126-135 | SAFE | key/password 配置检查 |
|
||||
| H-Audit | webssh.py:137-146,353-366 | SAFE | connect/disconnect 审计 |
|
||||
| H-Session | webssh.py:148-157,369-376 | SAFE | SshSession 创建/关闭 |
|
||||
| H-DB | webssh.py:111-158 | SAFE | 长连接前关闭 DB session |
|
||||
| H-Pool | webssh.py:167,337 | SAFE | acquire/release + stale retry |
|
||||
| H-CmdLog | webssh.py:277-290,379-398 | SAFE | Enter 触发;2000 字符截断 |
|
||||
| H-Danger | dependencies.py:167-180 | RISK | 危险命令仅 WARN 不阻断(设计) |
|
||||
| H-Resize | webssh.py:293-296 | SAFE | cols/rows 边界默认 80×24 |
|
||||
| H-Error | webssh.py:171,204 | SAFE | SSH 失败不向客户端泄露栈 |
|
||||
| H-Source | sync_engine_v2.py:72-76,327-330 | SAFE | `_nexus_source_path` 拒绝系统路径 |
|
||||
| H-Conc | sync_engine_v2.py:38,79-80 | SAFE | MAX_CONCURRENT=10 + min 入参 |
|
||||
| H-DBLock | sync_engine_v2.py:89,149,190 | SAFE | `_db_lock` 串行写 sync_log/retry |
|
||||
| H-Cancel | sync_engine_v2.py:96-136 | SAFE | Redis cancel flag;失败则继续 push |
|
||||
| H-Retry | sync_engine_v2.py:193-224 | SAFE | 失败自动 pending retry;去重 |
|
||||
| H-Subproc | sync_engine_v2.py:468-473 | SAFE | create_subprocess_exec 参数化 |
|
||||
| H-Shlex | sync_engine_v2.py:456-458 | SAFE | key path shlex.quote |
|
||||
| H-KeyTmp | sync_engine_v2.py:449-455,491-495 | SAFE | 0600 临时 key + finally unlink |
|
||||
| H-Pass | sync_engine_v2.py:440-446 | RISK | sshpass -e;/proc 可见(内网运维可接受) |
|
||||
| H-Remote | sync_engine_v2.py:414 | SAFE | normalize_remote_abs_path |
|
||||
| H-Timeout | sync_engine_v2.py:476-482 | SAFE | RSYNC_TIMEOUT+30 kill |
|
||||
| H-Output | sync_engine_v2.py:486-487 | SAFE | stdout/stderr 截断 10KB |
|
||||
| H-Staging | sync_engine_v2.py:498-516 | SAFE | 仅 manual 全成功才 rmtree staging |
|
||||
| H-Preview | sync_engine_v2.py:364-365 | SAFE | verbose 文件列表上限 200 |
|
||||
| H-Audit | sync_engine_v2.py:267-271,380-391 | SAFE | sync_files 审计;失败 log error |
|
||||
| H-TG | sync_engine_v2.py:274-291 | SAFE | Telegram 失败不阻断 |
|
||||
| H-Gather | sync_engine_v2.py:254-265 | SAFE | gather 异常计入 failed |
|
||||
| H-JWT | 各页 http.* | SAFE | 经 `@/api` JWT 客户端 |
|
||||
| H-WS | DashboardPage:393-397 | RISK | useWebSocket query token(已接受) |
|
||||
| H-Nav | DashboardPage:383-387 | SAFE | server_id 数字 query 路由 |
|
||||
| H-Err | DashboardPage:268-345 | SAFE | load 失败 snackbar |
|
||||
| H-CSV | ServersPage:391-435 | SAFE | import FormData;export 无密码列 |
|
||||
| H-Batch | ServersPage:325-388 | SAFE | batch 端点 JWT;confirm 删除 |
|
||||
| H-Form | ServersPage:162-176 | SAFE | 凭据经 ServerFormDialog composable |
|
||||
| H-Filter | AlertsPage:150-162 | SAFE | 只读分页 API |
|
||||
| H-Audit | AuditPage:126-141 | SAFE | 只读;normalizeAuditList |
|
||||
| H-TG | SettingsPage:272-275 | SAFE | GET 不返 token 明文;value_set |
|
||||
| H-Reveal | SettingsPage:434-460 | SAFE | API Key/TG reveal 需 current_password |
|
||||
| H-Pw | SettingsPage:339-359 | SAFE | 改密 POST;表单 type=password |
|
||||
| H-TOTP | SettingsPage:362-404 | SAFE | setup/enable/disable 走 auth API |
|
||||
| H-CredList | CredentialsPage:253-255 | SAFE | GET 列表无密码明文 |
|
||||
| H-CredPost | CredentialsPage:323-327 | SAFE | encrypted_pw 仅 POST/PUT |
|
||||
| H-CredEdit | CredentialsPage:306,340,357 | SAFE | 编辑留空不修改 |
|
||||
| H-SSH | CredentialsPage:346-347 | SAFE | 私钥仅提交时传输 |
|
||||
| H-Cron | SchedulesPage:177 | SAFE | cron 正则校验 |
|
||||
| H-Sched | SchedulesPage:173-180 | SAFE | 路径/服务器必填 |
|
||||
| H-Retry | RetriesPage:146 | SAFE | retry POST JWT |
|
||||
| H-CmdView | CommandsPage:139-153 | SAFE | 只读 command-logs/sessions |
|
||||
| H-ScriptExec | ScriptsPage:415-419,463-467 | SAFE | exec 走后端 JWT |
|
||||
| H-Quick | ScriptsPage:459-467 | RISK | 临时命令;后端 check_dangerous |
|
||||
| H-Poll | ScriptsPage:527-528 | SAFE | onUnmounted stopPolling |
|
||||
| H-FilesShell | FilesPage.vue:33-37 | SAFE | 逻辑在 useFilesPage(D5) |
|
||||
| H-PushShell | PushPage.vue:105 | SAFE | usePushPage(D4) |
|
||||
| H-TermShell | TerminalPage.vue | SAFE | useTerminalSessions(D5) |
|
||||
| H-Login | LoginPage.vue | SAFE | auth.login 内存 token(D6) |
|
||||
| H-NoStore | 四页 | SAFE | 无 localStorage 存密码 |
|
||||
@@ -0,0 +1,65 @@
|
||||
# Phase 2 深审 — Wave P2-1(Files / SSH 基础设施)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**范围**: 文件浏览 REST + browse service + SSH pool + 前端预读
|
||||
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步(全文 Read)
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 语言 | 行数 N | Read 范围 |
|
||||
|---|------|------|--------|-----------|
|
||||
| 1 | `server/api/files.py` | Python | 77 | 1–77 全文 |
|
||||
| 2 | `server/application/services/files_browse_service.py` | Python | 167 | 1–167 全文 |
|
||||
| 3 | `server/infrastructure/ssh/asyncssh_pool.py` | Python | 436 | 1–436 全文 |
|
||||
| 4 | `server/utils/files_elevation.py` | Python | 55 | 1–55 全文 |
|
||||
| 5 | `frontend/src/utils/filePreload.ts` | TS | 141 | 1–141 全文 |
|
||||
|
||||
## 入口表
|
||||
|
||||
| 方法 | 路径 | 鉴权 |
|
||||
|------|------|------|
|
||||
| GET | `/api/files/browse?server_id=&path=` | JWT + If-None-Match |
|
||||
| POST | `/sync/read-file`(filePreload 调用) | JWT |
|
||||
| SSH | `list_remote_directory` → `ls -la` | 经 pool + server 凭据 |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
|---|-----------|------|------|
|
||||
| H-Auth | files.py:44 | SAFE | `get_current_admin` |
|
||||
| H-Path | files.py:57-60 | SAFE | `normalize_remote_abs_path` |
|
||||
| H-Audit | files.py:72 | SAFE | browse 审计 |
|
||||
| H-ETag | files.py:62-75 | SAFE | 304 减 SSH 负载 |
|
||||
| H-Path | files_browse_service.py:111-116 | SAFE | normalize + shlex.quote |
|
||||
| H-Shell | files_browse_service.py:117-125 | SAFE | 固定 ls 模板;path 已 quote |
|
||||
| H-Cache | files_browse_service.py:46-62 | SAFE | 5s TTL + max 200 |
|
||||
| H-Cred | asyncssh_pool.py:183-192 | SAFE | decrypt 仅内存 connect |
|
||||
| H-HostKey | asyncssh_pool.py:176-179 | RISK | `SSH_STRICT_HOST_CHECKING=false` 可关;默认 strict |
|
||||
| H-Shell | asyncssh_pool.py:306-339 | SAFE | tee/mv/mkdir 路径 shlex.quote |
|
||||
| H-Sudo | asyncssh_pool.py:348-355 | SAFE | elevation 三态 OFF/AUTO/ALWAYS |
|
||||
| H-Pool | asyncssh_pool.py:409-413 | SAFE | timeout 后 close_connection 不 reuse |
|
||||
| H-Exec | asyncssh_pool.py:389-437 | RISK | `exec_ssh_command` 接受任意 command;调用方须 JWT+审计 |
|
||||
| H-Elevation | files_elevation.py:21-28 | SAFE | 未知值回退 AUTO |
|
||||
| H-Auth | filePreload.ts:101-105 | SAFE | read-file JWT + max_size |
|
||||
| H-Cache | filePreload.ts:25-58 | SAFE | 内存 Map;prune 按目录 |
|
||||
| H-Size | filePreload.ts:6-9,67-68 | SAFE | 300KB 预读 / 2MB 编辑上限 |
|
||||
|
||||
**len(H)=17, Closure=17**
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
## L3 门控(同日记录)
|
||||
|
||||
`bash deploy/pre_deploy_check.sh` → **6/7 PASS**,Gate 7 BLOCK(`HEAD~1` 与未提交改动 `.cursorrules`、`docker-compose.yml` 等未列入当日 audit 文件)。属工作区脏树预期;**非代码缺陷**。部署前需 commit + 审计清单对齐或放宽 Gate7 策略。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] len(H) == Closure
|
||||
- [x] 五文件全文 Read
|
||||
- [x] local_verify 通过
|
||||
|
||||
## 验证
|
||||
|
||||
`bash scripts/local_verify.sh` — 全绿
|
||||
@@ -0,0 +1,66 @@
|
||||
# Phase 2 深审 — Wave P2-2(sync_v2 全文 + 路径/Shell 依赖)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**范围**: `sync_v2.py` 1656 行全文 + 路径校验与 SSH 包装
|
||||
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 语言 | 行数 N | Read 范围 |
|
||||
|---|------|------|--------|-----------|
|
||||
| 1 | `server/api/sync_v2.py` | Python | 1656 | 1–1656 全文(分段 Read 至 EOF) |
|
||||
| 2 | `server/utils/posix_paths.py` | Python | 149 | 1–149 全文 |
|
||||
| 3 | `server/infrastructure/ssh/remote_shell.py` | Python | 63 | 1–63 全文 |
|
||||
| 4 | `server/api/remote_path_validation.py` | Python | 33 | 1–33 全文 |
|
||||
| 5 | `server/utils/unix_ls.py` | Python | 115 | 1–115 全文 |
|
||||
|
||||
## 入口表(sync_v2 全 22 路由)
|
||||
|
||||
| 路由 | 鉴权 |
|
||||
|------|------|
|
||||
| POST `/files`, `/preview`, `/file-ops`, `/file-clipboard`, `/browse` | JWT |
|
||||
| POST `/browse-local`, `/local-file-ops`, `/local-file-preview` | JWT + upload 沙箱 |
|
||||
| POST `/cancel`, `/reconcile-stale-logs`, `/validate-source-path`, `/diagnose` | JWT |
|
||||
| POST `/file-diff`, `/upload`, `/upload-zip`, `/verify` | JWT |
|
||||
| POST `/download`, `/read-file`, `/write-file`, `/chmod`, `/compress`, `/decompress` | JWT |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
|---|-----------|------|------|
|
||||
| H-Auth | sync_v2.py:74–1614 | SAFE | 22 路由均 `Depends(get_current_admin)` |
|
||||
| H-Shell | sync_v2.py:156-168 | RISK | `rm -rf` 删目录;JWT+审计+前端 confirm |
|
||||
| H-Shell | sync_v2.py:156,165,168,223-227 | SAFE | path shlex.quote |
|
||||
| H-Path | sync_v2.py:149-165 | SAFE | normalize_remote_abs_path |
|
||||
| H-Clipboard | sync_v2.py:207-208 | SAFE | assert_clipboard_transfer_safe |
|
||||
| H-Sandbox | sync_v2.py:302,341,413,721 | SAFE | ensure_under_nexus_upload |
|
||||
| H-Source | sync_v2.py:548,1096 | SAFE | FORBIDDEN prefixes + resolve |
|
||||
| H-Audit | sync_v2.py:461-475 | SAFE | 失败 log warning+exc_info,非静默 pass |
|
||||
| H-Upload | sync_v2.py:876-877,977-978 | SAFE | 100MB / 500MB 上限 |
|
||||
| H-ZipSlip | sync_v2.py:1000-1005 | SAFE | assert_zip + is_path_under_prefix |
|
||||
| H-Download | sync_v2.py:1244-1272 | SAFE | 100MB + filename sanitize |
|
||||
| H-Read | sync_v2.py:1322-1326 | SAFE | max_size 来自 payload |
|
||||
| H-Write | sync_v2.py:1394-1414 | SAFE | 5MB + etag 409 冲突 |
|
||||
| H-Chmod | sync_v2.py:1507-1514 | SAFE | recursive policy + test -d |
|
||||
| H-Verify | sync_v2.py:1145-1146 | SAFE | sha256sum 路径 shlex.quote |
|
||||
| H-Path | posix_paths.py:46-59 | SAFE | 禁 `..` 与反斜杠 |
|
||||
| H-Path | posix_paths.py:117-136 | SAFE | upload 前缀 + zip-slip |
|
||||
| H-Sudo | remote_shell.py:35-53 | SAFE | bash -c + shlex.quote(command) |
|
||||
| H-Clipboard | remote_path_validation.py:24-33 | SAFE | dest 非源子树 |
|
||||
| H-Parse | unix_ls.py:70-71 | SAFE | 跳过 `.` `..` |
|
||||
|
||||
**len(H)=20, Closure=20**
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] sync_v2 全文 Read(D1 仅 grep+分段,本波补全)
|
||||
- [x] len(H) == Closure
|
||||
- [x] local_verify 通过
|
||||
|
||||
## 验证
|
||||
|
||||
`bash scripts/local_verify.sh` — 全绿
|
||||
@@ -0,0 +1,61 @@
|
||||
# Phase 2 深审 — Wave P2-3(WebSocket / Dashboard 告警链)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**范围**: 后端 WS 双通道 + 前端告警客户端 + Dashboard 刷新
|
||||
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 语言 | 行数 N | Read 范围 |
|
||||
|---|------|------|--------|-----------|
|
||||
| 1 | `server/api/websocket.py` | Python | 552 | 1–552 全文 |
|
||||
| 2 | `frontend/src/composables/useWebSocket.ts` | TS | 178 | 1–178 全文 |
|
||||
| 3 | `frontend/src/pages/DashboardPage.vue` | Vue | 415 | 1–415 全文 |
|
||||
| 4 | `frontend/src/App.vue` | Vue | — | 247–260(WS 生命周期) |
|
||||
| 5 | `server/api/settings.py` | Python | — | 759–828(alert-history GET) |
|
||||
|
||||
## 入口表
|
||||
|
||||
| 通道 | 路径 | 鉴权 |
|
||||
|------|------|------|
|
||||
| WS | `/ws/alerts?token=` | `_verify_ws_token` |
|
||||
| WS | `/ws/sync?token=` | 同上 |
|
||||
| HTTP | GET `/api/alert-history/` | JWT |
|
||||
| HTTP | GET `/api/servers/stats` | JWT(Dashboard) |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
|---|-----------|------|------|
|
||||
| H-WS-Auth | websocket.py:304-311,340-347 | SAFE | 无 token → 4001;无效 → 4401 |
|
||||
| H-WS-Token | websocket.py:366-410 | SAFE | tv/updated_at 与 HTTP JWT 一致 |
|
||||
| H-WS-ADR011 | websocket.py:9,296 | RISK | query JWT;单人运维已接受 |
|
||||
| H-WS-Limit | websocket.py:49-52 | SAFE | MAX_CONNECTIONS=500 |
|
||||
| H-WS-Heartbeat | websocket.py:139-165 | SAFE | 30s ping / 60s zombie |
|
||||
| H-WS-Channel | websocket.py:246-249,531-551 | SAFE | alerts 与 sync 分 channel/manager |
|
||||
| H-WS-Dedup | websocket.py:416-437 | SAFE | Telegram 5min 冷却;WS 仍实时 |
|
||||
| H-WS-Recovery | websocket.py:512-513 | SAFE | recovery 清 cooldown |
|
||||
| H-Frontend-Token | useWebSocket.ts:61 | RISK | URL query token;同 ADR-011 |
|
||||
| H-Frontend-Auth | useWebSocket.ts:114-116 | SAFE | 4001/4401 → forceLogout |
|
||||
| H-Frontend-XSS | useWebSocket.ts:99-102 | SAFE | snackbar 文本插值,无 v-html |
|
||||
| H-Frontend-Singleton | useWebSocket.ts:17-18 | SAFE | 模块级单例;App 统一 connect |
|
||||
| H-Dashboard-Refresh | DashboardPage.vue:393-397 | SAFE | WS alert → reload stats/alerts |
|
||||
| H-Dashboard-API | DashboardPage.vue:302-337 | SAFE | http JWT 拉 stats/alert-history |
|
||||
| H-App-Lifecycle | App.vue:257-259 | SAFE | login connect / logout disconnect |
|
||||
| H-Alert-API | settings.py:768-828 | SAFE | alert-history JWT + 参数化 filter |
|
||||
|
||||
**len(H)=16, Closure=16**
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] len(H) == Closure
|
||||
- [x] websocket 全文 Read
|
||||
- [x] 端到端链:Agent→broadcast_alert→Redis→WS→Dashboard refresh
|
||||
|
||||
## 验证
|
||||
|
||||
`bash scripts/local_verify.sh` — 全绿
|
||||
@@ -0,0 +1,68 @@
|
||||
# Phase 2 深审 — Wave P2-4(servers.py 全文)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**范围**: 服务器 CRUD/Agent/导入/批量 SSH 全文 + 凭据加密/文件能力探测
|
||||
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 语言 | 行数 N | Read 范围 |
|
||||
|---|------|------|--------|-----------|
|
||||
| 1 | `server/api/servers.py` | Python | 1742 | 1–1742 全文(分段 Read 至 EOF) |
|
||||
| 2 | `server/infrastructure/database/crypto.py` | Python | 54 | 1–54 全文 |
|
||||
| 3 | `server/infrastructure/ssh/files_capability.py` | Python | 63 | 1–63 全文 |
|
||||
| 4 | `server/utils/files_elevation.py` | Python | 55 | 1–55 全文(P2-1 已读,本波交叉验证) |
|
||||
| 5 | `server/infrastructure/ssh/remote_shell.py` | Python | 63 | 1–63 全文(P2-1 已读,setup-files-sudo 关联) |
|
||||
|
||||
## 入口表(servers.py 26 路由)
|
||||
|
||||
| 类别 | 路由数 | 鉴权 |
|
||||
|------|--------|------|
|
||||
| CRUD / 列表 / stats | GET/POST/PUT/DELETE | 全部 JWT |
|
||||
| CSV import | POST `/import` | JWT + 1MB/500行 |
|
||||
| 批量 Agent | POST `/batch/*` | JWT + Semaphore(5) |
|
||||
| Agent 单台 | POST `/{id}/install|uninstall|upgrade-agent` | JWT |
|
||||
| 敏感 reveal | POST `/{id}/agent-key`, `agent-install-cmd` | JWT + bcrypt re-auth |
|
||||
| files | GET/POST `files-capability`, `setup-files-sudo` | JWT |
|
||||
| health | POST `/check` | JWT |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
|---|-----------|------|------|
|
||||
| H-Auth | servers.py:26×路由 | SAFE | 26 端点均 `get_current_admin` |
|
||||
| H-Mask | servers.py:1692-1698 | SAFE | password_set / agent key 前缀截断 |
|
||||
| H-Encrypt | servers.py:1096-1099,559-562 | SAFE | Fernet encrypt 入库 |
|
||||
| H-Allowlist | servers.py:1163-1187 | SAFE | UPDATE 字段白名单;agent_api_key 排除 |
|
||||
| H-Reauth | servers.py:1256-1260,1479-1483 | SAFE | agent-key/install-cmd 需当前密码 |
|
||||
| H-Reveal | servers.py:1492-1502 | SAFE | install-cmd 不用全局 API_KEY |
|
||||
| H-AgentKey | servers.py:1282-1288 | SAFE | 生成后 display_once 响应 |
|
||||
| H-Fallback | servers.py:626,1321 | RISK | batch/single install 可回退 settings.API_KEY |
|
||||
| H-Shell | servers.py:631-633,1330-1332 | SAFE | install shlex.quote url/key/port |
|
||||
| H-Sudo | servers.py:36-60 | RISK | 临时 sudoers 白名单;运维必要 |
|
||||
| H-SudoPwd | servers.py:1025-1027 | SAFE | sudo -S 密码走 stdin 非 argv |
|
||||
| H-CSV | servers.py:376-388,445-446 | SAFE | formula injection 防御 + 1MB 上限 |
|
||||
| H-CSV | servers.py:499-501 | SAFE | MAX_IMPORT_ROWS=500 |
|
||||
| H-Batch | servers.py:615,686,772,850 | SAFE | Semaphore(5) 并发上限 |
|
||||
| H-Redis | servers.py:179-201,873-877 | SAFE | 心跳 overlay;失败 log warning |
|
||||
| H-Audit | servers.py: CUD/batch | SAFE | 写操作 AuditLog |
|
||||
| H-Crypto | crypto.py:20-26 | SAFE | 无 ENCRYPTION_KEY 则 RuntimeError |
|
||||
| H-Crypto | crypto.py:52-54 | SAFE | decrypt 失败 raise,非静默 |
|
||||
| H-Capability | files_capability.py:31-39 | SAFE | 只读 probe,无密码回传 |
|
||||
| H-Elevation | files_elevation.py:48-55 | SAFE | apply_files_elevation_payload |
|
||||
|
||||
**len(H)=20, Closure=20**
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] servers.py 1742 行全文 Read(补 D3 分段)
|
||||
- [x] len(H) == Closure
|
||||
- [x] local_verify 通过
|
||||
|
||||
## 验证
|
||||
|
||||
`bash scripts/local_verify.sh` — 全绿
|
||||
@@ -0,0 +1,61 @@
|
||||
# Phase 2 深审 — Wave P2-5(webssh.py 全文)
|
||||
|
||||
**日期**: 2026-06-04
|
||||
**范围**: WebSSH WebSocket 端点 + 令牌签发链 + 前端连接
|
||||
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步
|
||||
|
||||
## 登记
|
||||
|
||||
| # | 文件 | 语言 | 行数 N | Read 范围 |
|
||||
|---|------|------|--------|-----------|
|
||||
| 1 | `server/api/webssh.py` | Python | 401 | 1–401 全文 |
|
||||
| 2 | `server/api/auth.py` | Python | 374 | 330–349(webssh-token 端点) |
|
||||
| 3 | `server/application/services/auth_service.py` | Python | 684 | 412–471(create_webssh_token) |
|
||||
| 4 | `server/api/dependencies.py` | Python | — | 167–180(check_dangerous_command) |
|
||||
| 5 | `frontend/src/composables/terminal/useTerminalSessions.ts` | TS | 749 | 277–311(令牌 + WS URL) |
|
||||
|
||||
## 入口表
|
||||
|
||||
| 方法 | 路径 | 鉴权 |
|
||||
|------|------|------|
|
||||
| WS | `/ws/terminal/{server_id}?token=` | purpose=webssh JWT |
|
||||
| POST | `/api/auth/webssh-token` | JWT + server 存在 |
|
||||
|
||||
## Closure 表
|
||||
|
||||
| H | 文件:行号 | 判定 | 理由 |
|
||||
|---|-----------|------|------|
|
||||
| H-Purpose | webssh.py:48-49 | SAFE | 拒绝非 webssh purpose |
|
||||
| H-Bind | webssh.py:106-109 | SAFE | token server_id 须匹配路径 |
|
||||
| H-TV | webssh.py:66-76 | SAFE | tv 校验;legacy updated_at +5s grace |
|
||||
| H-Close | webssh.py:97-104 | SAFE | 缺 token→4001;无效→4401 |
|
||||
| H-Issue | auth.py:334-346 | SAFE | 签发前 JWT + server/domain 校验 |
|
||||
| H-Scope | auth_service.py:455-470 | SAFE | JWT 含 server_id + purpose + tv |
|
||||
| H-Expire | auth_service.py:467 | SAFE | 15 分钟短期令牌 |
|
||||
| H-WSQuery | webssh.py:88, useTerminalSessions:293 | RISK | ADR-011 query token(已接受) |
|
||||
| H-Cred | webssh.py:126-135 | SAFE | key/password 配置检查 |
|
||||
| H-Audit | webssh.py:137-146,353-366 | SAFE | connect/disconnect 审计 |
|
||||
| H-Session | webssh.py:148-157,369-376 | SAFE | SshSession 创建/关闭 |
|
||||
| H-DB | webssh.py:111-158 | SAFE | 长连接前关闭 DB session |
|
||||
| H-Pool | webssh.py:167,337 | SAFE | acquire/release + stale retry |
|
||||
| H-CmdLog | webssh.py:277-290,379-398 | SAFE | Enter 触发;2000 字符截断 |
|
||||
| H-Danger | dependencies.py:167-180 | RISK | 危险命令仅 WARN 不阻断(设计) |
|
||||
| H-Resize | webssh.py:293-296 | SAFE | cols/rows 边界默认 80×24 |
|
||||
| H-Error | webssh.py:171,204 | SAFE | SSH 失败不向客户端泄露栈 |
|
||||
|
||||
**len(H)=17, Closure=17**
|
||||
|
||||
## FINDING
|
||||
|
||||
无 P0/P1 新 FINDING。
|
||||
|
||||
## DoD
|
||||
|
||||
- [x] webssh.py 401 行全文 Read
|
||||
- [x] 令牌签发链交叉验证
|
||||
- [x] len(H) == Closure
|
||||
- [x] local_verify 通过
|
||||
|
||||
## 验证
|
||||
|
||||
`bash scripts/local_verify.sh` — 全绿
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user