文件
hyb-oa/.trellis/tasks/05-27-oa-auth-delivery-wecom-entry-fix/prd.md
T

7.3 KiB

认证验证码投递与企业微信入口修复

Goal

修复部署后认证入口的两个真实问题:邮箱登录验证码和密码重置验证码无法收到;普通浏览器点击企业微信登录会跳转到只能在企业微信内使用的 OAuth 页面并报错。目标是让认证入口行为和真实能力一致,避免用户误判“验证码已发送”或点击错误入口。

Scope

  • 本任务覆盖后端认证接口、邮件投递能力探测、认证验证码邮件文案、登录页、找回密码页、普通浏览器企业微信入口提示、部署检查和对应自动化测试。
  • 本任务不接入 PC 企业微信扫码登录,不修改企业微信后台配置,不在未获批准时继续修改远端 .env 或部署代码。

What I Already Know

  • 用户反馈:
    • 邮箱收不到登录验证码和密码重置验证码。
    • 点击企业微信登录报错,实际需要在企业微信里点击。
  • 登录验证码和密码重置验证码都通过 sendNotificationEmailSafe + SMTP 邮件服务发送。
  • 公网远端运行时配置显示:
    • emailEnabled=false
    • smtpHost=false
    • smtpUser=false
    • smtpPass=false
    • emailFrom=true
    • smtpPort=587
    • smtpSecure=false
  • 本地 ~/.hyb-oa/live-smoke.env 也没有 SMTP 配置可直接同步。
  • 当前邮箱验证码接口会在账号存在且 active 时创建验证码和审计记录,然后异步调用邮件发送;当邮件服务关闭时,用户仍看到通用成功提示。
  • 当前普通浏览器下只要 wecomEntry ready,就显示“企业微信登录”按钮;点击后进入 /api/auth/wecom/login 并跳转企业微信 OAuth。
  • 当前企业微信入口的 OAuth 设计是企业微信工作台/WebView 入口,不是 PC 浏览器扫码登录。

Diagnosis

  • 邮箱问题的直接原因是公网试运行环境未启用或配置 SMTP,两个验证码功能没有可用邮件通道。
  • 代码体验问题是认证页没有把“邮件服务未启用”和“普通浏览器不支持企业微信 OAuth”转化为清晰交互。
  • 安全约束:验证码请求仍必须避免账号枚举。不能因为邮箱是否存在而返回不同提示。

Discussion Notes

  • 企业邮箱 SMTP 配置复杂度低,前提是企业邮箱已允许客户端 SMTP,且能为专用发件邮箱生成客户端专用密码或授权码。
  • 推荐使用独立发件邮箱,例如 oa 或 no-reply 类账号;不要使用个人员工邮箱或管理员真实登录密码。
  • 试运行环境当前缺 SMTP 配置,因此必须先补远端 .env 并重启 server,才能验证真实收信。
  • PC 企业微信扫码登录是独立能力,不等同于当前“企业微信内 OAuth 免登”。它适合 PC 常用用户,但需要单独配置企业微信授权登录回调域、前端二维码入口和后端扫码回调处理。
  • 当前修复建议先做 SMTP 投递和普通浏览器企业微信入口防误点;PC 企业微信扫码登录可列为后续 P1,不放进本次故障修复 MVP。

Requirements

  • 邮件服务全局未启用或 SMTP 未配置时:
    • 登录页邮箱验证码发送应提示“邮件服务暂未启用,请联系管理员或使用密码登录”,而不是“验证码将发送”。
    • 忘记密码页应给出同类提示。
    • 不暴露输入邮箱是否存在。
  • 公网/部署检查应能发现邮件验证码依赖的 SMTP 未启用状态,避免再次“功能上线但无法收信”。
  • 普通浏览器下:
    • 不提供可点击的企业微信 OAuth 登录按钮。
    • 显示清晰提示:企业微信一键进入需从企业微信工作台或企业微信内打开 OA。
    • 不影响企业微信 WebView 下主 CTA。
  • 企业微信 WebView 下:
    • 企微一键进入仍为主入口。
    • 账号密码/邮箱验证码兜底仍可按现有逻辑出现。
  • 不打印、提交或写入 SMTP 密码、真实邮箱、验证码、token、Secret。

Acceptance Criteria

  • 公网或本地配置缺 SMTP 时,邮箱验证码和忘记密码不再误提示“验证码已发送”。
  • 配置完整时,验证码请求仍返回通用成功,不暴露账号是否存在。
  • 普通浏览器不再点击进入企业微信 OAuth 报错页。
  • 企业微信 WebView 下企业微信主入口不回退。
  • 后端/前端测试覆盖邮件服务未启用提示和普通浏览器企微入口提示。
  • 部署/公网检查能报告邮件投递配置是否 ready。
  • 需要真实收信验证时,仅在获得 SMTP 凭据和远端配置修改批准后执行。

Proposed Implementation

  1. Backend:
    • 增加一个安全的公开认证能力配置接口,或扩展现有公开 auth config,暴露 emailDeliveryReady 这类非敏感布尔值。
    • 在邮箱验证码和忘记密码请求中,若邮件服务全局未配置,返回统一错误(不依赖邮箱是否存在),让前端能提示服务未启用。
  2. Frontend:
    • 登录页邮箱验证码模式根据 emailDeliveryReady 禁用发送按钮并显示说明。
    • 忘记密码页根据 emailDeliveryReady 禁用发送或显示服务未启用说明。
    • 普通浏览器下企业微信区域改为说明性入口,不触发 OAuth;企业微信 WebView 才显示可点击 CTA。
  3. QA:
    • 增加/更新 auth 单测覆盖邮件未配置分支。
    • 更新登录页、忘记密码、企微入口 E2E。
    • 更新 live smoke/env 检查,输出邮件投递 ready 状态但不打印 SMTP 值。
  4. Operations:
    • 若用户提供并批准 SMTP 配置,先备份远端 .env,再写入 SMTP 相关键并重启 server。
    • 配置后执行一次受控真实收信验证,不在日志和记录中保存验证码。

Test Plan

cd server && node --check src/routes/auth.js src/routes/wecomAuth.js src/config.js
cd server && npm test -- --run tests/unit/routes/auth.login.test.js
cd client && npm run typecheck
cd client && npm run build
E2E_BASE_URL=http://127.0.0.1:5173 npx playwright test tests/e2e/login-portal-ux.spec.ts tests/e2e/wecom-entry.spec.ts --workers=1 --reporter=list
node deploy/trialrun/validate-env-contract.js
node scripts/qa/check-live-smoke-env.mjs
python3 ./.trellis/scripts/task.py validate 05-27-oa-auth-delivery-wecom-entry-fix
node scripts/qa/check-trellis-governance.mjs
git diff --check

Out of Scope

  • 不在本任务接入 PC 企业微信扫码登录。
  • 不在未获批准时修改远端 .env。
  • 不在聊天、Trellis、docs 或日志中记录 SMTP 密码、验证码或完整账号。
  • 不修改企业微信后台配置。

Technical Notes

  • Email service: server/src/services/email/index.js
  • Auth routes: server/src/routes/auth.js
  • WeCom auth routes: server/src/routes/wecomAuth.js
  • Login page: client/src/pages/LoginPage.tsx
  • WeCom entry helpers: client/src/lib/wecomEntry.ts
  • Runtime context: client/src/lib/runtimeContext.ts
  • Live env check: scripts/qa/check-live-smoke-env.mjs

Progress Notes

  • 公网 SMTP 配置已完成一次受控验证:有效企业邮箱可以收到登录验证码和密码重置验证码;邮件被企业邮箱归入免提醒邮件。
  • 本地代码已补齐认证能力接口、北京时间有效期文案、邮箱验证码入口禁用态和普通浏览器企业微信入口提示。
  • 截止本记录,代码改动尚未部署到公网;公网 /api/auth/capabilities 仍需部署后验证。