fix(migrate): 迁移确认只对做确认的会话在 10 分钟内有效,签发和兑换迁移码都给源账户邮箱发通知

This commit is contained in:
Lemon-miaow committed 2026-09-27 02:14:22 +08:00
1 parent 9a89254146
commit ee4065b986
17 files changed
+496 -122

No files matched your search

+20 -8
View File
@@ -5104,9 +5104,12 @@ paths:
description: >
Read-only. Returns the live migration whose source is the authenticated
principal, if any, so the web onboarding can resume the flow: whether a
confirmation step-up is still needed, which factor confirmed it, the named
target, and the one-time code's expiry once issued. active:false when the
caller has no live migration.
confirmation step-up is still needed, which factor confirmed it and until
when, the named target, and the one-time code's expiry once issued. The
step-up counts only for the session that gave it and for 10 minutes, so a
confirmation made in another session, one that lapsed, and a code that
expired unspent all read as initiated. active:false when the caller has no
live migration.
x-felis-face: [external]
x-felis-tier: app
security: [{ sessionCookie: [] }]
@@ -5128,6 +5131,10 @@ paths:
confirm_factor:
type: string
enum: [passkey, email_otp]
confirm_expires_at:
type: string
format: date-time
description: Present while state is confirmed; the code must be issued before it.
code_expires_at: { type: string, format: date-time }
'401':
$ref: '#/components/responses/Unauthorized'
@@ -5335,10 +5342,13 @@ paths:
operationId: migrateIssueCode
summary: Name the target account and mint the one-time migration code (spec §B3 inherit).
description: >
For a confirmed migration, binds the named target account and mints a single
one-time code (only its hash is stored) that the target must redeem while logged
in AS that target — an intercepted code is useless to anyone else. The target
must exist and be neither disabled nor soft-deleted, and cannot be the source.
For a migration confirmed by a step-up in this same session within the last
10 minutes, binds the named target account and mints a single one-time code
(only its hash is stored) that the target must redeem while logged in AS that
target — an intercepted code is useless to anyone else. The target must exist
and be neither disabled nor soft-deleted, and cannot be the source. The
source's verified address is sent a notice naming the target and the expiry,
and another when the code is redeemed.
x-felis-face: [external]
x-felis-tier: app
security: [{ sessionCookie: [] }]
@@ -5377,7 +5387,9 @@ paths:
application/json:
schema: { $ref: '#/components/schemas/Error' }
'409':
description: The migration has not been confirmed by a step-up yet (not_confirmed).
description: >
No step-up from this session within the last 10 minutes, or a code is
already out (not_confirmed).
content:
application/json:
schema: { $ref: '#/components/schemas/Error' }