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

135 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog: Vuetify 前端审计修复
**日期**: 2026-05-31
**主题**: 5个严重问题修复 + DRY 重构 + 类型安全
## 变更摘要
### 1. 提取 useSnackbar composableDRY 重构)
- **新建** `src/composables/useSnackbar.ts` — 统一 snackbar 包装函数
- **新建** `src/types/global.d.ts``Window.$snackbar` 全局类型声明
- **修改 8 个页面** — 删除各自重复的 `function snackbar(...)` 定义,改为 `import { useSnackbar }`
- **修改** `App.vue``(window as any).$snackbar``window.$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.vue``loadServers()` / `browse()` catch 加 snackbar 错误提示
- `SettingsPage.vue``loadSettings()` / `loadAllowlist()` catch 加 snackbar 错误提示
- `DashboardPage.vue``loadStats()` / `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 错误提示正常