4.3 KiB
Changelog: 全站 bug 审查修复 (前端9项 + 后端5项)
日期: 2026-06-01 变更摘要: 全站巡检发现并修复 14 个 bug(1 P0 + 9 P1 + 4 P2),涵盖前端全局搜索崩溃、TOTP登录流程断裂、服务器编辑域名污染、后端Redis阻塞、并发session竞态等
动机
对 Nexus 全站进行系统性 bug 审查,发现多个影响生产使用的问题。最严重的 3 个:全局搜索因 http 未导入直接崩溃、TOTP 双因素登录完全不可用、编辑服务器后域名被端口字符串污染导致后续连接失败。
涉及文件
| 文件 | 变更类型 | 说明 |
|---|---|---|
frontend/src/App.vue |
修改 | 添加 http 导入 |
frontend/src/pages/LoginPage.vue |
修改 | TOTP异常捕获 + 锁定倒计时响应式 |
frontend/src/pages/ServersPage.vue |
修改 | 编辑时 domain 不再拼接端口 |
frontend/src/pages/PushPage.vue |
修改 | Set 索引 → 迭代器 |
frontend/src/pages/SettingsPage.vue |
修改 | API字符串值转数字 |
frontend/src/api/index.ts |
修改 | 删除重复 getList 定义 |
frontend/src/pages/TerminalPage.vue |
修改 | 路径验证正则放松 |
frontend/src/composables/useWebSocket.ts |
修改 | 关闭旧连接再建新连接 |
server/api/websocket.py |
修改 | redis.keys → scan_iter |
server/application/services/auth_service.py |
修改 | TTL 仅在无TTL时设置 |
server/api/servers.py |
修改 | 批量操作加 asyncio.Lock |
server/api/settings.py |
修改 | 弃用API替换 |
详细变更
前端 P0 修复
- App.vue
http未导入 — 第320行doSearch()调用http.get()但只导入了api,导致ReferenceError: http is not defined。修复:import { api, http } from '@/api'
前端 P1 修复
-
TOTP 登录流程断裂 —
api()在后端返回 202 时抛TotpRequiredError(非ApiError子类),LoginPagecatch 只检查e instanceof ApiError,TOTP 用户看到"网络错误"无法登录。修复:导入TotpRequiredError并在 catch 中优先检查 -
ServersPage 编辑域名污染 —
editServer()设置form.address = domain:port,保存时domain: form.address发送含端口字符串。修复:form.address = item.domain -
PushPage Set 索引无效 —
selectedIds.value[0]对Set<number>返回undefined。修复:selectedIds.value.values().next().value -
SettingsPage 类型转换 — API 返回
value: "80"字符串直接赋值给 number 字段。修复:正则检测纯数字字符串并Number()转换
前端 P2 修复
-
api/index.ts 重复定义 —
getList方法定义两次,删除第二个 -
LoginPage 锁定倒计时 —
remainingMinutescomputed 依赖Date.now()非响应式。修复:使用ref(Date.now())+watch(lockoutUntil)+ 30秒定时器 -
TerminalPage 路径验证过严 — 正则
/^[a-zA-Z0-9/._\-]+$/排除空格/中文/~。修复:/^[^\x00-\x1f\x7f"']+$/仅排除控制字符和引号 -
useWebSocket 连接泄漏 — CONNECTING/CLOSING 状态时创建新连接但不关闭旧连接。修复:关闭旧连接后再创建新的
后端 P1 修复
-
websocket.py redis.keys() 阻塞 —
KEYS命令 O(N) 扫描整个键空间。修复:scan_iter(match="ws:count:*")非阻塞迭代 -
auth_service.py TTL 重置 — 每次
sadd后expire重置 TTL,频繁刷新的管理员 refresh token 键永不过期。修复:ttl = await redis.ttl(key),仅在ttl < 0时设置 expire -
servers.py 并发 session commit — 批量操作中
asyncio.gather并发协程共享同一 db session 并commit()。修复:添加asyncio.Lock()序列化 commit
后端 P2 修复
-
settings.py asyncio.get_event_loop() — Python 3.10+ 弃用。修复:
asyncio.get_running_loop() -
settings.py datetime.utcfromtimestamp() — Python 3.12+ 弃用。修复:
datetime.fromtimestamp(ts, tz=timezone.utc)
是否需迁移/重启
- ✅ 需重启 — 后端代码变更
- ✅ 前端需重新构建部署
验证方式
- 登录页 → 输入 admin/Nexus@2026 → 成功跳转仪表盘 ✓
- 全局搜索框 → 输入"机器人" → 无崩溃(之前会 ReferenceError)✓
- 控制台零错误 ✓
- 健康检查 →
ok✓