821cf12ade
Append CR when executing quick commands (fixes trim stripping saved \r) and allow optional dedicated Telegram bot for server offline alerts only. Co-authored-by: Cursor <cursoragent@cursor.com>
116 lines
5.6 KiB
Markdown
116 lines
5.6 KiB
Markdown
# 审计报告 — 快捷命令回车修复 + 离线告警 Telegram 分流
|
||
|
||
**日期**: 2026-06-13
|
||
**范围**: 本会话两项功能(不含工作区其它未提交变更如 remote-browser 删除)
|
||
**方法**: 定向 diff 走读 + 安全/契约检查 + 已有 pytest 证据
|
||
**审计员**: Agent(定向审计,非全仓 Phase 2 走读)
|
||
|
||
---
|
||
|
||
## 1. 变更摘要
|
||
|
||
| 功能 | 核心改动 | 风险面 |
|
||
|------|----------|--------|
|
||
| 终端快捷命令回车 | `formatQuickCmdForSend` + `execQuickCmd` 发送时补 `\r` | 前端 WebSSH 数据流 |
|
||
| 离线告警 Telegram 分流 | `TELEGRAM_OFFLINE_*` + `resolve_offline_telegram_credentials` + 设置页/API | 凭据存储、出站 Telegram |
|
||
|
||
---
|
||
|
||
## 2. 审计文件(5 个)
|
||
|
||
| # | 文件 | 行数 | 状态 |
|
||
|---|------|------|------|
|
||
| 1 | `server/infrastructure/telegram/__init__.py` | 401 | 逐行完成 ✓ |
|
||
| 2 | `server/api/settings.py`(offline 段 ~1188–1342) | 段 | 逐行完成 ✓ |
|
||
| 3 | `frontend/src/composables/useTerminalQuickCommands.ts` | 80 | 逐行完成 ✓ |
|
||
| 4 | `frontend/src/composables/terminal/useTerminalSessions.ts`(execQuickCmd) | 段 | 逐行完成 ✓ |
|
||
| 5 | `frontend/src/pages/SettingsPage.vue`(离线 Bot 段) | 段 | 逐行完成 ✓ |
|
||
|
||
辅助:`TerminalQuickCommandsSettings.vue`(-2 行)、`server/config.py`(+4 映射)、测试 2 文件。
|
||
|
||
---
|
||
|
||
## 3. API 入口表(新增)
|
||
|
||
| 方法 | 路径 | 鉴权 |
|
||
|------|------|------|
|
||
| PUT | `/api/settings/telegram_offline_bot_token` | JWT `get_current_admin` |
|
||
| PUT | `/api/settings/telegram_offline_chat_id` | JWT |
|
||
| POST | `/api/settings/telegram/offline/test` | JWT |
|
||
| GET | `/api/settings/telegram/offline/chats` | JWT |
|
||
| POST | `/api/settings/telegram/offline/reveal-token` | JWT + 审计 |
|
||
|
||
既有 `broadcast_offline_alert` → `send_telegram_offline_alert` 无新 HTTP 面。
|
||
|
||
---
|
||
|
||
## 4. Closure 表
|
||
|
||
| ID | 规则/检查点 | 文件:行 | 结论 | 说明 |
|
||
|----|-------------|---------|------|------|
|
||
| H1 | 敏感凭据不入 GET 明文 | settings.py SENSITIVE_KEYS | **SAFE** | `telegram_offline_bot_token` 已加入掩码集 |
|
||
| H2 | reveal 写 audit_logs | settings.py:1324–1331 | **SAFE** | `reveal_offline_telegram_token` |
|
||
| H3 | 出站消息 HTML 转义 | telegram/__init__.py:189–195 | **SAFE** | `html.escape` 用于名称/心跳 |
|
||
| H4 | 离线专用半配不误发 | telegram/__init__.py:96–107 | **SAFE** | 仅 token 或仅 chat 时整组回退默认 Bot |
|
||
| H5 | 资源告警仍走默认 Bot | telegram/__init__.py:163 | **SAFE** | `send_telegram_alert` 未改路由 |
|
||
| H6 | `send_telegram` 参数化不破坏默认调用 | telegram/__init__.py:110–118 | **SAFE** | 默认 `bot_token/chat_id=None` 行为不变 |
|
||
| H7 | MUTABLE_KEYS 白名单 | settings.py:47–48 | **SAFE** | 两新键已列入 |
|
||
| H8 | 快捷命令 `\r` 与 `trim()` 冲突 | useTerminalQuickCommands.ts:43–49 | **SAFE** | 发送时 `formatQuickCmdForSend` 根治 |
|
||
| H9 | 内置命令 DB 带 `\r` 幂等 | useTerminalQuickCommands.ts:21–23 | **SAFE** | 先去尾再追加 |
|
||
| H10 | 多行快捷命令语义 | useTerminalQuickCommands.ts:21–23 | **SAFE** | 与命令栏一致:整段一条命令 + 单次 `\r` |
|
||
| H11 | 测试覆盖通道路由 | test_telegram_offline_channel.py | **SAFE** | 4 case 含 dedicated/fallback/partial |
|
||
| H12 | reveal 加载态共用 | SettingsPage.vue:886–911 vs 离线 toggle | **FINDING P3** | 离线与默认共用 `revealingTelegramToken`,并发点击可能互斥显示 |
|
||
| H13 | test 端点重复 httpx | settings.py:1268–1309 | **FINDING P3** | 可复用 `send_telegram(..., bot_token, chat_id)` 减重复 |
|
||
| H14 | 新 API 错误文案 i18n | settings.py:1253,1264 | **FINDING P3** | `http_errors_zh` 未收录 `telegram_offline_*` 键名错误 |
|
||
| H15 | 子机恢复在线 Telegram | server_offline_monitor.py | **INFO** | 仅 offline 边沿推送,无「恢复在线」通知(既有设计,非回归) |
|
||
| H16 | Layer3 巡检不同步离线 Bot | settings.py:416–422 | **SAFE** | 仅默认 token 写 .env,符合设计文档 |
|
||
| H17 | 无静默吞错 | telegram/__init__.py:136–138 | **SAFE** | 失败打 error 日志 |
|
||
| H18 | CUD 审计 | settings.py set_setting | **SAFE** | PUT 走既有 `update_setting` 审计 |
|
||
|
||
`len(H)=18`,Closure=18。
|
||
|
||
---
|
||
|
||
## 5. 严重度汇总
|
||
|
||
| 级别 | 数量 | 项 |
|
||
|------|------|-----|
|
||
| **P0** | 0 | — |
|
||
| **P1** | 0 | — |
|
||
| **P2** | 0 | — |
|
||
| **P3** | 3 | H12 加载态共用;H13 test 重复代码;H14 错误文案 i18n |
|
||
| **INFO** | 1 | H15 无离线恢复 Telegram |
|
||
|
||
**合并结论**: **可合并 / 可部署**。无安全阻断项;P3 可在后续小 PR 打磨。
|
||
|
||
---
|
||
|
||
## 6. 测试证据
|
||
|
||
```
|
||
pytest tests/test_telegram_offline_channel.py → 4 passed
|
||
pytest tests/test_terminal_quick_commands.py → 1 passed
|
||
bash scripts/local_verify.sh → 26/26 + ruff
|
||
frontend npm run build → OK
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 建议(可选跟进)
|
||
|
||
1. **H12**: 为离线 Token 增加独立 `revealingOfflineTelegramToken`,避免与默认 Bot 眼睛按钮抢 loading。
|
||
2. **H13**: `telegram_offline_test_send` 改为 `await send_telegram(message, bot_token=token, chat_id=chat_id)`。
|
||
3. **H14**: 在 `server/utils/http_errors_zh.py` 补充 `telegram_offline_bot_token 未配置` 等映射。
|
||
|
||
---
|
||
|
||
## 8. 验收对照(设计文档)
|
||
|
||
| 验收项 | 结果 |
|
||
|--------|------|
|
||
| 专用 Bot+Chat 配置后离线走专用通道 | ✓ 代码 + 单测 |
|
||
| 未配置专用时回退默认 | ✓ 单测 |
|
||
| CPU/内存等仍走默认 | ✓ 未改 `send_telegram_alert` |
|
||
| 设置页保存/检测/测试 | ✓ UI + API 已实现 |
|
||
| 快捷命令点击执行带回车 | ✓ `formatQuickCmdForSend` + 构建验证 |
|