From 8f3a3403ccd23ec392fc8fef6757693f2a656c97 Mon Sep 17 00:00:00 2001 From: weichen Date: Mon, 19 Oct 2026 16:19:15 +0000 Subject: [PATCH] Fill the OTP card from the user's 2026-10-17 requirements Co-authored-by: Cursor --- .task/feature-auth-one-time-password.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/.task/feature-auth-one-time-password.md b/.task/feature-auth-one-time-password.md index 1b0d178c..f2b89e08 100644 --- a/.task/feature-auth-one-time-password.md +++ b/.task/feature-auth-one-time-password.md @@ -5,21 +5,25 @@ ## 基线与授权 - 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 6c90e6c92aca0968158b6fa50ec8065ba0869913 -- 工作区:/tmp/Agent-System-Dev-execenv-python-fix-wt-feature-auth-one-time-password(worktree);分支:feature/auth-one-time-password +- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-auth-one-time-password(worktree;2026-10-19 由 /tmp 独立克隆迁回主仓,原 worktree 属于 /tmp/Agent-System-Dev-execenv-python-fix 克隆);分支:feature/auth-one-time-password - 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false - 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=a2830f221ea249e90c7f023f05c70b78211975a8a2d991af636fe3b9844b645c;triage_receipt=/tmp/auth-one-time-password-triage-20261017.json;receipt_sha256=321041e16d08aa3385ac9e1610c9eb85386caae8bad4bbbfdac1af6b2a2411c0 -- 授权与交付终点:<本次允许的动作与终点;未授权事项写明> +- 授权与交付终点:用户 2026-10-17 提出密码管理整改(Codex 会话 rollout 01a148d4);2026-10-19 在遗留项推进中选择“恢复交付”。终点:Backend/Frontend PR 经独立 Review 与 CI 合入,Dev 改钉组合验证后经 #518 合入。未授权:部署到 8788 或任何实例、改写线上账户数据、发版打标;部署与业务验收届时单独请示。 - 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进) - 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md) - 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入) - 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收 -- 当前阶段:需求拆解;当前增量:I1(待定义) +- 当前阶段:实施与自检(恢复:组件分支同步最新 main 与缺口补齐);当前增量:I1 - 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位) ## 目标与非目标 -<预期结果、受影响入口/模块/契约;明确不做什么。> +**目标**:账号只用“用户名 + 密码”登录;管理员在页面建号并设置或生成初始密码;忘记密码时管理员只能生成一次性密码;首次登录与一次性密码登录后强制改密;系统不存在“未设密码”状态。 + +**受影响**:Backend `internal/server`(账号、认证、恢复路由)、`internal/store`(账号模型、登录密钥、一次性密码)、`cmd/agent-system`;Frontend 登录页、我的账户、管理员用户管理与 API 封装。 + +**非目标**:不改 IAM 角色与项目权限;不保留恢复提案链路;不改动线上数据;不部署。 ## Agent 实施收据 @@ -39,13 +43,18 @@ | ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 | |---|---|---|---|---|---|---| -| R1 | 待填写 | 待评估 | 待定 | 待定义 | 待确认 | 待评审 | +| R1 | 管理员在页面创建用户,可设置初始密码或生成随机初始密码,不再需要服务端命令行初始化 | 符合:用户 10-17 明确驳回 CLI 初始化 | P0 | 页面建号后用户可直接用初始密码登录;空密码写入被拒绝(内部 pending/bootstrap 兼容除外) | Backend accounts | 纳入 | +| R2 | 忘记密码时管理员只能为用户生成一次性登录密码;明文只在管理员响应中返回一次 | 符合:用户要求删除与之重复的“重置临时密码”和恢复提案 | P0 | 只存在一个管理员找回动作;旧的覆盖常用密码端点已删除 | R1 | 纳入 | +| R3 | 首次登录、或使用一次性密码登录后,必须先修改密码(受限会话,改密前不能访问业务数据) | 符合:用户列明两种触发条件 | P0 | 两种情形均进入强制改密;改密前业务 API 拒绝 | R1/R2 | 纳入 | +| R4 | 管理员已生成一次性密码但用户用原密码登录:登录成功、一次性密码立即失效、不触发改密 | 符合:用户原话 | P0 | 原密码登录后一次性密码不可再用;无强制改密 | R2 | 纳入 | +| R5 | 系统不允许“未设密码”状态;历史空密码账号以管理员首次签发的一次性密码作为初始化路径 | 符合:用户“账户不允许有未设密码这个状态” | P0 | 管理端不再展示“未设密码”;历史空密码账号经一次性密码登录后强制设密 | R2/R3 | 纳入 | +| R6 | 登录页移除一次性 key 登录入口;恢复提案路由与前端调用全部删除 | 符合:用户“登录界面中移除一次性 key 登录,必须使用账号密码登录” | P0 | 登录页只有账号密码;前端不再调用 recovery-proposals;后端无该路由 | — | 纳入 | ## 方案与计划 -- 方案引用:待填写(含对象版本) -- 实施计划引用:待填写(含增量与需求 ID) -- 测试计划引用:待填写(含需求 ID 与验收条件) +- 方案引用:用户 10-17 需求原文(见 R1–R6);svc-deploy U4 一次性登录 Key 文档中的受限会话原则(docs/svc-deploy/u4-one-time-login-key.md) +- 实施计划引用:I1 = 组件分支同步最新 main(冲突交 worker)+ 缺口单元(R5 历史空密码初始化、R6 前端残留调用) +- 测试计划引用:Backend `go test ./internal/store ./internal/server ./cmd/agent-system`;Frontend `test/one-time-password.test.ts`、`test/loginpage.test.ts` 与 `e2e/login-key.playwright.ts`;Dev 改钉后 `make test`(CI GATE) ## 阶段记录