文件
hyb-oa/.trellis/tasks/07-28-all-account-login-readiness/design.md
T
wangsli 7b86ffb3c9
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s
优化(07-28-all-account-login-readiness): 调整密码框Tab顺序
2026-08-23 19:10:34 +08:00

7.7 KiB

全员登录可用性设计

1. Boundary

本任务在现有企微 OAuth 回调内补充确定性自动绑定,不新增公开认证端点、不读取或记录任何真实密码。普通企微登录只绑定既有 active OA 账户,不创建员工、不修改角色、不写企微通讯录。

1.1 WeCom Direct-login Contract

企微 OAuth callback 得到内部 userid
  -> 已有唯一 binding:直接创建会话
  -> 无 binding:读取该 userid 的企微通讯录资料
       -> 企业邮箱精确匹配唯一 active OA 账户
       -> 目标账户无 binding:事务内 upsert binding + 脱敏审计 + 创建会话
       -> 任何缺失/无匹配/inactive/冲突/API 失败:失败关闭

匹配键优先级固定为已有 userid binding,其次为企微返回的规范化企业邮箱。姓名不得参与自动决策;手机号不作为本轮普通登录兜底,避免号码复用或格式漂移扩大身份边界。

2. Login Baseline

每个 active 账户必须具备以下两类能力,实际真人覆盖另行记录:

  1. WeCom SSO ready:属于当前企微通讯录的员工存在唯一 binding,并由本人完成一次工作台直接登录;首次登录不需要 OA 密码。
  2. password fallback ready:员工本人可通过受控自助路径设置并掌握密码;它是企微异常时的独立回退,不是首次 binding 的前置条件。本轮代表性生产验收不等于每人都已经执行该路径。

inactive/archived 账户不进入本轮登录覆盖率分母。

3. Administrator Recovery

受控终端 -> 精确定位唯一 active 管理员 -> 静默设置一次性密码
  -> 清锁定、撤旧会话、递增 token version、失效旧验证码并留脱敏审计
电脑浏览器 -> 使用一次性密码登录 -> 立即设置本人新密码
手机企微工作台 -> 重新进入并完成 OAuth userid 校验
  -> 新版 OAuth 回调用 userid 或企微企业邮箱精确匹配既有 active OA 账户
  -> 自动建立唯一 binding 并直接创建会话
  -> 再次从工作台进入并验证免登

一次性密码只允许由用户在受控终端静默输入,或写入仓库外权限为 0600 的临时文件供用户本机读取一次;不得出现在聊天、argv、环境变量、日志或仓库。它只用于管理员账号恢复,不参与企微首次 binding。

若自动匹配缺失或冲突,停止操作并只读核对 userid、企业邮箱和 OA active 账户的唯一映射;不得按姓名猜测、不得用密码登录覆盖 binding。个人设置主动绑定只保留为管理员核实后的显式维护入口。

4. Remaining Active Accounts

其余 active 账户已有 binding,但尚无真实登录证据。每名员工先直接从企微工作台进入,验证 binding 和免登是否可用;企微免登通过后再按优先级安排密码回退,不让密码流程阻塞主入口验收。管理员只记录 password_login_pass、wecom_login_pass、blocked_reason 三类脱敏结果,不收集密码、验证码或完整账号。

邮件未送达时才进入兜底:管理员通过现有 reset-password 接口生成一次性密码,受控现场只显示一次并当面交付;接口强制首次改密、清除锁定、撤销旧会话、使旧凭据失效并写审计。兜底写入需在实际发生前再次获得批准。

5. Failure Matrix

  • 邮件验证码未收到:先核对投递状态和企业邮箱可用性;不反复请求导致限流。确认邮件路径不可用后才考虑管理员一次性密码。
  • 企微内无法同时看登录页和邮箱:改用电脑浏览器完成忘记密码,手机只收验证码;不要为看邮件关闭正在执行 binding 的企微 WebView。
  • 验证码过期/错误:由员工重新请求;不得让管理员代收或索取验证码。
  • 页面显示已发送但未看到新邮件:先只读确认是否真正签发新 code、有效期、失败次数和邮件发送失败计数。新签发会使旧 code 失效;不得混用旧邮件,也不得在请求上限内连续点击重发。
  • 旧验证码被拒绝:归类为“新签发使旧码失效”,证明失败发生在 /reset-password 成功之前;不得据此推断前端缓存或首次改密标记未清除。
  • 正确验证码重设成功后仍跳到改密页:才归类为前端状态/缓存问题,并记录跳转 URL、页面和报错;不要与旧码失效混为一类。
  • 点击登录页“忘记密码”只进入找回页面,不会签发验证码。只有填写企业邮箱并点击“发送验证码/重新发送验证码”才会请求签发;页面导航次数不能作为验证码请求次数。
  • 账号或邮箱锁定:只读确认锁定类别和窗口;使用现有解锁接口前另行批准。
  • 企微仍显示 unbound:确认是否在企微内打开、OAuth 回调是否取得内部 userid、现有 binding 是否指向另一账户;不得按姓名猜测绑定。
  • binding conflict:失败关闭,保留原映射和审计,单独核实身份后再提出精确修正。
  • 邮箱验证码登录成功但必须改密页面要求未知旧密码:说明员工走了 /email-login 路径;它不同于会清除首次改密标记的 /reset-password,返回忘记密码流程,不绕过旧密码校验。

6. Rollback

  • 员工自助重设密码后旧密码和旧会话按设计失效,无需回滚到旧密码。
  • 新 binding 若经本人验证仍错误,只能在精确确认原/目标映射后使用现有解绑/绑定路径恢复;不得直接删除数据库记录。
  • 任一员工未来出现阻断时不影响其他员工使用;按实际覆盖记录个人缺口,不把代表性系统 PASS 改写为全员真人 PASS。

7. Prevention

新账号从创建/导入进入 active 后,不得只以“有密码哈希/有 binding 行”宣告可用。启用完成必须包含安全凭据交付、首次改密、密码登录和企微成员本人工作台免登四项;缺一项则保持 onboarding 未完成并由管理员跟踪。

8. Compatibility And Audit

  • 已有 binding 的 3 个账户保持原路径,不额外请求通讯录详情。
  • 自动补绑定使用现有 wecom_identity_bindings 唯一约束,并在同一事务内二次核对 userid 与员工两侧冲突。
  • 新审计动作只记录匹配方式和布尔字段,不记录完整 userid、邮箱或企微原始 payload。
  • 未绑定页面不再指示员工输入密码完成正常绑定;错误只显示稳定类别,完整身份资料不得进入 URL、日志或前端状态。
  • 生产回填先 dry-run 汇总唯一匹配、无匹配和冲突计数,另行批准后才 apply。

9. Password Input Sequential Focus

认证表单采用国内连续填表优先的顺序焦点:密码输入框按 Tab 跳过框内显示/隐藏按钮并进入 DOM 中下一个顺序表单控件。登录页现有“忘记密码?”链接仍保持键盘可达;按钮继续使用原生 button type="button",保留“显示密码/隐藏密码”可访问名称、按下状态和目标输入关联,鼠标与触屏行为不变;不得通过正数 tabIndex 人工重排表单。

组件级调整同时覆盖登录、修改密码和忘记密码页,避免三个认证入口产生不同键盘习惯。测试固定顺序焦点、点击切换、可访问名称、输入值保留以及确认密码框 Enter 提交;不改变认证 API 或生产配置。

10. Representative Password-Recovery Evidence

系统能力与逐人覆盖分开记录:生产 /ready、认证 capabilities、SMTP 连接/认证和 1 次真人完整重置/登录共同证明共享链路可用;个人邮箱访问、投递和账号特例只有本人操作才能证明。任务收口允许系统链路 PASS,但覆盖率保持 4/6,另外 2 人标记为预计可用而非真人 PASS。