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,7 +60,12 @@ try {
60 60
61 const sent = await call('POST', '/api/voko/auth/send-code', { body: { email, locale: 'en' } }) 61 const sent = await call('POST', '/api/voko/auth/send-code', { body: { email, locale: 'en' } })
62 check('send-code', sent.status === 200, sent) 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 check('验证码邮件已投递并记录', log !== undefined, { email }) 69 check('验证码邮件已投递并记录', log !== undefined, { email })
65 const code = JSON.parse(log.metadata_json).code 70 const code = JSON.parse(log.metadata_json).code
66 71
docs/voko/upstream.md
@@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
17 | `tools/scripts/mysql-dev.js` | 默认库 `voko`,默认 env 文件 `apps/voko-server/.env` | 17 | `tools/scripts/mysql-dev.js` | 默认库 `voko`,默认 env 文件 `apps/voko-server/.env` |
18 | `packages/llm-router/package.json` | 测试脚本加 `--passWithNoTests`(上游该包目前没有测试文件,`vitest run` 会以 1 退出) | 18 | `packages/llm-router/package.json` | 测试脚本加 `--passWithNoTests`(上游该包目前没有测试文件,`vitest run` 会以 1 退出) |
19 | `pnpm-workspace.yaml` | 只保留 `apps/*`、`packages/*` | 19 | `pnpm-workspace.yaml` | 只保留 `apps/*`、`packages/*` |
  20 +| `packages/email/src/templates/waitlist-invite.js` | `inviteUrl` 允许 `http://localhost`(本地验收用),其余仍须 https(2026-10-10) |
20 | `apps/voko-server/src/assembly/security.js`、`google-oauth.js`、`email-delivery-log.js` | 从 visual-game-server 原样复制(security.js 只改了一条报错文案) | 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,7 +69,9 @@ function requiredHttpsUrl(value) {
69 if (typeof value !== 'string' || value.trim() === '') fail('missing field "inviteUrl"') 69 if (typeof value !== 'string' || value.trim() === '') fail('missing field "inviteUrl"')
70 const url = value.trim() 70 const url = value.trim()
71 try { 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 } catch (error) { 75 } catch (error) {
74 fail(`inviteUrl is invalid: ${error instanceof Error ? error.message : String(error)}`) 76 fail(`inviteUrl is invalid: ${error instanceof Error ? error.message : String(error)}`)
75 } 77 }