# 审计报告 — 快捷命令回车修复 + 离线告警 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` + 构建验证 |
