Commit 9a6089c7c00222faff84fda42585cd80850a605f

Authored by yibo
1 parent 57d9cf5d

fix(server): 骨架验收等待真实验证码投递;通过通知允许本地 http 链接

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
apps/voko-server/tools/scenarios/voko-alpha/skeleton.mjs
... ... @@ -60,7 +60,12 @@ try {
60 60  
61 61 const sent = await call('POST', '/api/voko/auth/send-code', { body: { email, locale: 'en' } })
62 62 check('send-code', sent.status === 200, sent)
63   - const log = await db('email_delivery_logs').where({ to_email: email, template: 'verify-code', status: 'sent' }).orderBy('created_at', 'desc').first()
  63 + // auth.sendCode 不等待 SMTP 就返回,这里等真实投递落库(最多 30 秒)。
  64 + let log
  65 + for (let i = 0; i < 30 && log === undefined; i += 1) {
  66 + log = await db('email_delivery_logs').where({ to_email: email, template: 'verify-code', status: 'sent' }).orderBy('created_at', 'desc').first()
  67 + if (log === undefined) await new Promise((resolve) => setTimeout(resolve, 1000))
  68 + }
64 69 check('验证码邮件已投递并记录', log !== undefined, { email })
65 70 const code = JSON.parse(log.metadata_json).code
66 71  
... ...
docs/voko/upstream.md
... ... @@ -17,6 +17,7 @@
17 17 | `tools/scripts/mysql-dev.js` | 默认库 `voko`,默认 env 文件 `apps/voko-server/.env` |
18 18 | `packages/llm-router/package.json` | 测试脚本加 `--passWithNoTests`(上游该包目前没有测试文件,`vitest run` 会以 1 退出) |
19 19 | `pnpm-workspace.yaml` | 只保留 `apps/*`、`packages/*` |
  20 +| `packages/email/src/templates/waitlist-invite.js` | `inviteUrl` 允许 `http://localhost`(本地验收用),其余仍须 https(2026-10-10) |
20 21 | `apps/voko-server/src/assembly/security.js`、`google-oauth.js`、`email-delivery-log.js` | 从 visual-game-server 原样复制(security.js 只改了一条报错文案) |
21 22  
22 23 ## 待裁剪(原样搬入,后续处理)
... ...
packages/email/src/templates/waitlist-invite.js
... ... @@ -69,7 +69,9 @@ function requiredHttpsUrl(value) {
69 69 if (typeof value !== 'string' || value.trim() === '') fail('missing field "inviteUrl"')
70 70 const url = value.trim()
71 71 try {
72   - if (new URL(url).protocol === 'https:') return url
  72 + const parsed = new URL(url)
  73 + // 本地开发的前端是 http://localhost,其余环境必须 https。
  74 + if (parsed.protocol === 'https:' || parsed.hostname === 'localhost') return url
73 75 } catch (error) {
74 76 fail(`inviteUrl is invalid: ${error instanceof Error ? error.message : String(error)}`)
75 77 }
... ...