fix(auth): 邮箱验证码按账号累计错误次数封顶并通知
This commit is contained in:
17 files changed
+664
-37
No files matched your search
+36
-11
@@ -2209,7 +2209,9 @@ paths:
|
||||
purpose. An address with no account returns the SAME 202 with no code minted,
|
||||
and the per-recipient cooldown is kept on that path too, so probing reveals
|
||||
nothing (existence is learnt only at the sanctioned /auth/options oracle).
|
||||
Gated on local_auth_enabled.
|
||||
An account that spent its daily wrong-code budget (10 per 24h, across every
|
||||
code) also gets the same 202 and no mail until the window ends. Gated on
|
||||
local_auth_enabled.
|
||||
x-felis-face: [external]
|
||||
x-felis-tier: public
|
||||
security: []
|
||||
@@ -2268,7 +2270,10 @@ paths:
|
||||
under the login purpose, and on success mints a host-only felis_session. An
|
||||
unknown address, a wrong or expired code, and an attempt-exhausted code all
|
||||
return the IDENTICAL 400 invalid_code, so the door is not an existence or
|
||||
lockout oracle. Staff are refused (403) — but only AFTER a valid code is
|
||||
lockout oracle. The 10th wrong code in 24h locks the door for that account
|
||||
until the window ends (the right code then also reads as invalid_code); the
|
||||
owner is told by mail once, and the lock is audited as auth.otp.locked.
|
||||
Staff are refused (403) — but only AFTER a valid code is
|
||||
redeemed, so only the account owner can ever reach that refusal.
|
||||
x-felis-face: [external]
|
||||
x-felis-tier: public
|
||||
@@ -2324,7 +2329,8 @@ paths:
|
||||
staff address, opens an op_login request, and mails a one-time code under the
|
||||
op_login purpose, returning the request handle the browser polls. A non-staff
|
||||
or unknown address gets the SAME 202 with a random, non-persisted handle and no
|
||||
mail, so this never becomes a staff-enumeration oracle. Gated on
|
||||
mail, so this never becomes a staff-enumeration oracle. A staff account that
|
||||
spent its daily wrong-code budget gets the same neutral 202. Gated on
|
||||
local_auth_enabled.
|
||||
x-felis-face: [external]
|
||||
x-felis-tier: public
|
||||
@@ -2415,7 +2421,7 @@ paths:
|
||||
Public, pre-session final leg: mints a host-only staff session only when BOTH
|
||||
factors have landed — the request is approved-and-live AND the mailed code
|
||||
verifies. Every failure (unknown handle, not-yet-approved, wrong or locked code,
|
||||
lost race) collapses into one uniform 400 op_login_invalid, so a code-less
|
||||
an account past its daily wrong-code budget, lost race) collapses into one uniform 400 op_login_invalid, so a code-less
|
||||
caller learns nothing. Admin is re-asserted before the session is issued.
|
||||
x-felis-face: [external]
|
||||
x-felis-tier: public
|
||||
@@ -3768,6 +3774,14 @@ paths:
|
||||
schema: { $ref: '#/components/schemas/Error' }
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'429':
|
||||
description: >-
|
||||
Resend requested before the cooldown elapsed (otp_resend_cooldown); or the
|
||||
account spent its daily wrong-code budget (otp_account_locked, with
|
||||
Retry-After).
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/Error' }
|
||||
'502':
|
||||
$ref: '#/components/responses/MailUndeliverable'
|
||||
|
||||
@@ -3779,8 +3793,10 @@ paths:
|
||||
description: >
|
||||
Consumes a previously delivered code for the authenticated principal. On
|
||||
success the user's email is written and email_verified is set true. Too many
|
||||
incorrect attempts lock the code (429); an unknown, expired, consumed, or
|
||||
mismatched code is a 400.
|
||||
incorrect attempts lock the code (429 otp_locked); 10 wrong codes in 24h,
|
||||
counted across every code, lock the account's email-code door until the
|
||||
window ends (429 otp_account_locked with Retry-After). An unknown, expired,
|
||||
consumed, or mismatched code is a 400.
|
||||
x-felis-face: [external]
|
||||
x-felis-tier: app
|
||||
security: [{ accessJWT: [] }]
|
||||
@@ -3812,7 +3828,9 @@ paths:
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'429':
|
||||
description: Too many incorrect attempts; the code is locked.
|
||||
description: >-
|
||||
Too many incorrect attempts on this code (otp_locked), or the account's
|
||||
daily wrong-code budget is spent (otp_account_locked, with Retry-After).
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/Error' }
|
||||
@@ -4070,7 +4088,10 @@ paths:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/Error' }
|
||||
'429':
|
||||
description: Resend requested before the cooldown elapsed.
|
||||
description: >-
|
||||
Resend requested before the cooldown elapsed (otp_resend_cooldown), or the
|
||||
account's daily wrong-code budget is spent (otp_account_locked, with
|
||||
Retry-After).
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/Error' }
|
||||
@@ -4085,8 +4106,9 @@ paths:
|
||||
description: >
|
||||
Consumes the fresh migrate-purpose email code for the caller's initiated
|
||||
migration and advances it to confirmed with confirm_factor email_otp. Too many
|
||||
wrong attempts lock the code (429 otp_locked); an unknown, expired, consumed, or
|
||||
mismatched code is a 400 invalid_code.
|
||||
wrong attempts lock the code (429 otp_locked), and 10 wrong codes in 24h lock
|
||||
the account's email-code door (429 otp_account_locked with Retry-After); an
|
||||
unknown, expired, consumed, or mismatched code is a 400 invalid_code.
|
||||
x-felis-face: [external]
|
||||
x-felis-tier: app
|
||||
security: [{ accessJWT: [] }]
|
||||
@@ -4127,7 +4149,10 @@ paths:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/Error' }
|
||||
'429':
|
||||
description: The code is locked after too many wrong attempts (otp_locked).
|
||||
description: >-
|
||||
The code is locked after too many wrong attempts (otp_locked), or the
|
||||
account's daily wrong-code budget is spent (otp_account_locked, with
|
||||
Retry-After).
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/Error' }
|
||||
|
||||
Reference in new issue
Block a user