Implement T20-F4-B reset-password endpoint with one-time temp password, audit table, frontend wiring, login error envelope parsing, and CreateUser fail-closed for empty password hashes. Recovered test chenwei via env write (password out of band).
2.1 KiB
管理员重置密码 / 登录凭据缺陷 — 问题主记录
更新:2026-09-24。任务:admin-password-reset-2026-09-24。
ISSUE-20260924-admin-reset-dead
问题
管理台「重置密码」按钮调用 authClient.adminResetPassword,客户端硬 throw,后端无 reset-password 路由;UI 仍硬编码 ResetPass123 暗示成功。验收脚本曾重置 chenwei 哈希且不披露口令后,管理员无法通过 UI 恢复访问。
根因
T20-F4 已设计未实施(选项 B 卡产品)。password_changed_at 停在 2026-09-20 证明重置从未入库。
修复
POST /api/v1/admin/users/{id}/reset-password:服务端随机临时口令、must_change_password=true、撤销会话、审计表 user_password_reset_audits(goose 00067);前端接线并去掉硬编码。
状态
resolved(本任务合入后)。
ISSUE-20260924-login-error-envelope
问题
登录失败响应 code=AUTHZ / message=无权访问,前端再把整段 JSON 原文塞进 Error.message,用户误判为权限问题。
根因
httpx.CodeFromStatus(401)=AUTHZ + SafeMessage;auth.ts login 未用信封解析、未优先 error 领域字段。
修复
authErrorMessage 优先取信封 error;不改全局 AUTHZ 映射(事件复用与安全取舍另立专项)。
状态
resolved。
ISSUE-20260924-zombie-credentials
问题
CreateUser 在 PasswordHash=="" 时静默跳过 user_credentials 插入;LEFT JOIN + COALESCE 使登录哈希为空串,任意密码均失败且报错与真凭据错误相同。
盘点(只读,2026-09-24)
| 环境 | total | missing_cred | empty_username |
|---|---|---|---|
| dev | 416 | 263 | 255 |
| test | 9 | 0 | 0 |
| main | 4 | 3 | 0 |
main 三行为 goose 00011 seed(seed-admin 等),非业务用户。本任务不清理存量;仅 fail-closed 防新增。
修复
PgStore/MemoryStore CreateUser 拒绝空哈希;Login 对空哈希记 slog.Warn(user_id) 仍统一 401。
状态
resolved(机制);存量清理 = open / 另授权。