Files
Nexus/docs/changelog/2026-05-31-vuetify-audit-fix.md
2026-07-08 22:31:31 +08:00

5.8 KiB
Raw Permalink Blame History

Changelog: Vuetify 前端审计修复

日期: 2026-05-31 主题: 5个严重问题修复 + DRY 重构 + 类型安全

变更摘要

1. 提取 useSnackbar composableDRY 重构)

  • 新建 src/composables/useSnackbar.ts — 统一 snackbar 包装函数
  • 新建 src/types/global.d.tsWindow.$snackbar 全局类型声明
  • 修改 8 个页面 — 删除各自重复的 function snackbar(...) 定义,改为 import { useSnackbar }
  • 修改 App.vue(window as any).$snackbarwindow.$snackbar
  • 修改 useWebSocket.ts — 同上

2. API client FormData 支持(🔴 严重 #1 + 🟠 #12

  • 修改 src/api/index.ts:
    • body instanceof FormData 时不设 Content-Type(浏览器自动加 boundary
    • 新增 http.upload() 方法
  • 修改 FilesPage.vue doUpload():
    • fetch('/api/sync/upload')http.upload('/sync/upload', form)
    • 修复:文件上传现在自动携带 JWT Authorization header

3. 修复 6 个静默 catch 块(🔴 严重 #3

  • FilesPage.vueloadServers() / browse() catch 加 snackbar 错误提示
  • SettingsPage.vueloadSettings() / loadAllowlist() catch 加 snackbar 错误提示
  • DashboardPage.vueloadStats() / loadServers() catch 加 snackbar 错误提示

4. SettingsPage API Key 密码验证对话框(🔴 严重 #2

  • 新增 <v-dialog> 密码输入对话框(与 TOTP Disable 对话框模式一致)
  • revealApiKey() → 先弹密码对话框 → doRevealApiKey() 用真实密码调用后端
  • 修复:不再发送空密码 { password: '' } 绕过 re-auth 保护

5. DashboardPage 数据补全(🔴 严重 #5

  • 新增 loadAlerts() — 从 GET /alert-history/?limit=5 加载告警历史
  • 新增 loadSummary() — 从 GET /servers/?per_page=500 计算:
    • Agent 覆盖率(有 agent_version 的服务器比例)
    • CPU 平均值(从 system_info.cpu_usage
    • 内存平均值(从 system_info.mem_usage
  • 新增 WebSocket 实时刷新 — 监听 ws.alerts 变化自动刷新 stats + alerts

6. 消除 as any 类型断言(🔴 严重 #4

  • 新建 src/types/api.ts — 14 个 API 响应 interface:
    • PaginatedResponse<T>, SettingsResponse, AllowlistResponse, BrowseResponse
    • FileEntry, ServerApiItem, AlertLogItem, AlertStatsResponse
    • CommandLogItem, RetryItem, ScriptItem, PushItem, ScheduleItem, AuditItem
  • 修改 12 个页面 — 所有 (res as any).items 改为 http.get<PaginatedResponse<T>>()
  • 结果: as any 从 33 个降到 0 个(src/ 目录完全清零)

涉及文件

文件 操作
src/composables/useSnackbar.ts 新建
src/types/global.d.ts 新建
src/types/api.ts 新建
src/api/index.ts 修改
src/App.vue 修改
src/composables/useWebSocket.ts 修改
src/pages/FilesPage.vue 修改
src/pages/SettingsPage.vue 修改
src/pages/DashboardPage.vue 修改
src/pages/CredentialsPage.vue 修改
src/pages/RetriesPage.vue 修改
src/pages/PushPage.vue 修改
src/pages/ScriptsPage.vue 修改
src/pages/SchedulesPage.vue 修改
src/pages/ServersPage.vue 修改
src/pages/CommandsPage.vue 修改
src/pages/AlertsPage.vue 修改
src/pages/AuditPage.vue 修改
src/pages/TerminalPage.vue 修改

验证

  • vue-tsc --noEmit — TypeScript 零错误
  • vite build — 生产构建通过 (1.53s, Monaco 懒加载)
  • 开发服务器正常启动

Phase 2: Composables + UX + 核心功能 (同日)

Composables 提取 (Step 7)

  • 新建 src/composables/useServerList.ts — 5 个页面复用
  • 新建 src/composables/useServerPagination.ts — ServersPage/DashboardPage 复用
  • 新建 src/utils/status.ts — statusChipColor/statusLabel/formatRelativeTime

表单验证 + 空状态 + Loading (Step 8)

  • 新建 src/utils/validation.ts — 8 个验证规则工厂
  • 12 个空状态 — 9 个文件的 v-data-table 加 <template #no-data>
  • 14 个表单字段 — SettingsPage/ServersPage/ScriptsPage/SchedulesPage/CredentialsPage 加 :rules
  • ~20 个 loading 态 — ScriptsPage/SettingsPage/CredentialsPage/SchedulesPage/FilesPage

核心功能补全 (Step 9)

  • Servers 批量操作(多选 + 健康检查 + 批量删除)
  • Servers CSV 导出
  • Servers 详情面板(系统信息 + 同步日志 tab)
  • Push 同步模式(增量/全量/校验和 + 警告提示)
  • Push ZIP 拖拽上传
  • Push WebSocket 实时进度(逐服务器状态 + 进度条)
  • Scripts 快捷执行面板(临时命令 + Ctrl+Enter
  • Scripts 执行状态追踪(5s 自动轮询 + 停止按钮)
  • Files Monaco 编辑器(全屏 + 语法高亮 + Ctrl+S 保存 + 主题切换)
  • Dashboard WebSocket 实时刷新(watch alerts

新建文件总计

  • src/composables/useSnackbar.ts
  • src/composables/useServerList.ts
  • src/composables/useServerPagination.ts
  • src/types/global.d.ts
  • src/types/api.ts
  • src/utils/status.ts
  • src/utils/validation.ts
  • src/components/MonacoEditor.vue

动机

审计发现 5 个严重问题(安全漏洞 + 数据错误)和大量 DRY 违规/类型安全问题,需要在对接真实 API 数据之前修复。

是否需迁移/重启

  • 不需要数据库迁移
  • 不需要后端重启(纯前端修改)
  • 需要重新构建前端:cd frontend && npx vite build

验证方式

  1. TypeScript: cd frontend && npx vue-tsc --noEmit
  2. 构建: cd frontend && npx vite build
  3. 功能验证:
    • FilesPage 上传 → 携带 JWT(不再 401)
    • SettingsPage API Key → 弹出密码输入对话框
    • Dashboard → 告警历史有数据、Agent 覆盖率/CPU/内存有值
    • 所有页面 snackbar 错误提示正常