merge: admin-web

This commit is contained in:
Nixevol
2026-09-30 15:28:09 +08:00
43 changed files with 2632 additions and 274 deletions
+100
View File
@@ -760,6 +760,51 @@
- 备选:无。
- 影响:无。
### 复审修复 H-01
- 日期:2026-09-30
- 原条款:PRD §8 管理员登录防暴力;审查 #44。
- 实际做法:`httpx.DecodeJSON` 内部 `MaxBytesReader` 1 MiB;`admin.Handler.ServeHTTP` 按路由限制(登录 8 KiB、导入 8 MiB、其余 1 MiB)并设读截止时间;超限 413 JSON `payload_too_large`。CSV 导入不再在 8 MiB 处静默截断。不在 listener 加全局 `ReadTimeout`。
- 原因:公开登录接口与 JSON 解码原先不限大小。
- 备选方案:登录 4 KiB(与注册一致);未采用,8 KiB 对口令字段更宽裕。
- 影响:超大请求快速失败;合法批量 JSON(约 200 KiB)仍低于 1 MiB。
### 复审修复 H-03
- 日期:2026-09-30
- 原条款:PRD F01 停用作废不可恢复;审查 #46。
- 实际做法:注入 Identity 时 `handleEndpointPatch` 给 `patchEndpoint` 传 nil 的 enabled,启停只由 `identity.Disable`/`Enable` 执行。界面部分在 W-05。
- 原因:先写 enabled 再级联失败会留下半生效状态。
- 备选方案:同一事务里写 enabled 与作废;Identity 接口当前不暴露事务。
- 影响:Identity 失败时端仍保持原启用状态。
### 复审修复 H-04
- 日期:2026-09-30
- 原条款:DEVELOPMENT §8 批量开通哈希走并发池;PRD F01 指出行号;审查 #47。
- 实际做法:导入按 `max(1, NumCPU-1)` 并发算哈希并按行下标收集;UNIQUE 冲突返回 409 附行号;哈希失败 500/503。CSV 逐条 `Read()`,用 `FieldPos` / `csv.ParseError` 取物理行号。界面进度与错误表在 W-05。
- 原因:串行 argon2 过慢,且 `i+2` 行号会被空行和跨行字段带偏。
- 备选方案:占满哈希池;未采用,给 MQTT 登录留槽位。
- 影响:导入吞吐上升;冲突不再表现为无行号的 500。
### 复审修复 H-05
- 日期:2026-09-30
- 原条款:PRD F11 最远可定到 365 天后(可配置);审查 #48。
- 实际做法:`validateEndpointFields` 增加 `MaxScheduleSeconds`,开通/修改/导入与端侧改默认延迟同一上限(0 ≤ delay ≤ max)。界面 `:max` 在 W-05。
- 原因:后台原先只检查 `>= 0`,可设出永远发不出消息的端,极大值还会溢出。
- 备选方案:导入超限静默改成上限;未采用,改为行错误让管理员改表。
- 影响:超上限返回 400 或 CSV 行错误。
### 复审修复 H-06
- 日期:2026-09-30
- 原条款:PRD §8 管理员登录防暴力;admin-api 2.4 改密作废其它会话;审查 #49。
- 实际做法:改管理员密码时旧密码校验计入 `LockAdminIP`,锁定返回 429,成功清零。登录写入会话的同一事务删除过期 `admin_sessions`。作废其它会话失败返回 500 并写审计。
- 原因:持有 Cookie 可无限猜旧密码;过期会话从不清理;作废失败被忽略。
- 备选方案:改密失败不返回 401(与契约不符);未采用。W-01 排除改密 401 自动登出。
- 影响:连续 10 次旧密码错误后锁定;过期会话行在下次登录清除。
## 后台网页 W
1. **W1–W3 阶段使用内存假数据,不请求真实 `/api/admin`**
@@ -818,6 +863,61 @@
- 备选:仅文档要求手跑 e2e;未采用。
- 影响:`task itest` 变长;需本机 Go/Node/Chromium。
### 复审修复 W-01
- 日期:2026-09-30
- 原条款:TASKS W1 请求封装;审查 #51;PRD F01 名称可选。
- 实际做法:`requestAdmin` 对 401(排除 login/password)清空会话并跳转登录页,提示一次「登录已过期」;`run()` 不再对 `ApiError` 重复 toast;网络错误「无法连接服务器」、429「请稍后再试」。概览/系统/端/群/投递/令牌加载失败显示 `LoadFailed` 与重试。开通名称改为可选;改密用 n-form rules 按字符数校验,后端 `login.go` 同步 `utf8.RuneCountInString`;清除对话密码加确认。
- 未改:`RegistrationView.vue` / `registration.go`(U-01 归属;本波指令禁止改注册页)。生成新安全码确认留给身份线。
- 原因:会话过期后页面不跳转且错误弹两次;加载失败空白;帮助文字误称 nst_。
- 备选方案:改密 401 也自动登出;未采用,与契约「旧密码错误 401」冲突。
- 影响:改密失败不会踢当前会话;注册页错误提示仍走原逻辑。
### 复审修复 W-04
- 日期:2026-09-30
- 原条款:PRD F01 密码只显示一次并可下载;审查 #54。
- 实际做法:新增 `utils/csv.ts` 按 RFC 4180 引号转义、CRLF、BOM、表头;名称列公式前缀 `'`,密码列不加前缀。`SecretOnceAlert` 增加 `mime`、复制成功/失败提示与 clipboard 回退。开通手填密码时不返回 `login_password`,只提示「已开通 {id}」。导入结果弹窗增加下载。
- 原因:拼接 CSV 会错列;手填密码显示 undefined;明文 HTTP 下 clipboard 不可用。
- 备选方案:密码列也加公式前缀;未采用,避免改写密码。
- 影响:导入下载文件可被 Excel 正确打开。
### 复审修复 W-05
- 日期:2026-09-30
- 原条款:PRD F01/F17 解锁与批量清理;审查 #55;H-03/H-04/H-05 界面部分。
- 实际做法:解锁始终可点,锁定列 HelpTip 说明只反映编号锁。筛选/翻页清空选择;批量确认列出前 20 个编号,删除说明级联,结果列出失败项。编辑只提交变更字段;启用改停用弹确认。导入中禁用按钮并显示预估秒数,校验错误用可滚动表格。默认延迟 `:max` 取自 `limits.max_schedule_seconds`。
- 原因:仅 IP 锁定时无法解锁;跨页多选会误删;PATCH 总带 enabled 可能误停用。
- 备选方案:扩展 LoginLocks 查询任一锁定;留给 P 线。
- 影响:管理员可解除 IP 锁定;停用需二次确认。
### 复审修复 W-02
- 日期:2026-09-30
- 原条款:PRD F17 按时间筛选并查看原因/完整统计;审查 #52。
- 实际做法:投递记录加 `n-date-picker datetimerange` 传 `from_ms`/`to_ms`;列表与详情增加原因;统计六项;详情接收端 `limit=200` 并以「加载更多」翻页。
- 原因:接口已提供字段,页面未接线。
- 备选方案:详情用页码分页;未采用,加载更多更贴合游标。
- 影响:大群投递可看完全部接收端。
### 复审修复 W-03
- 日期:2026-09-30
- 原条款:PRD F17 群成员增减;审查 #53;DEVIATIONS A3.3。
- 实际做法:群详情返回 `member_total`(只增字段)并同步 admin-api 7.8;成员表远程分页。去掉建群编号输入,占位改为「群名称」。移除/转让加确认;加人失败原因译成中文。
- 原因:默认每页 50,千人群看不到后半;前端仍按可自定 id 设计。
- 备选方案:后端按编号前缀搜索;未采用,与现接口「名称包含」一致。
- 影响:网页线改了 `internal/admin/groups.go` 与 admin-api 7.8(issue 允许)。
### 复审修复 W-06
- 日期:2026-09-30
- 原条款:用户界面规则长列表内部滚动;PRD F17 界面中文与自助注册数;审查 #56。
- 实际做法:列表页 `.page-body` 改为 flex 列,筛选不伸缩,表格 `flex-height`。新增 `utils/labels.ts` 译消息/投递状态与原因(原值 title)。运行参数中文标签、键名放 HelpTip。端列表拆成最近上线/离线。概览展示「其中自助注册」,运行时长按天时分。e2e 断言「定时中」。Playwright 双分辨率截图未跑(本波以 Vitest 验收布局类改动)。
- 原因:写死 480 高度双滚动;英文枚举;漏自助数。
- 备选方案:一次性密码改弹窗;仍放顶部不参与伸缩。
- 影响:投递页不再显示 `scheduled` 英文单元格。
### S1.1 传输层可注入假实现(Go / JS)
- 相关文档:DEVELOPMENT 第 9 节单元测试要求「用假的 MQTT/HTTP,不要起真实服务器」。