mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 06:32:03 +00:00
Gate passkey removal on the same step-up as second-factor removal
DELETE /api/auth/passkeys/{id} took a plain cookie session or a wildcard
Bearer, while DELETE /api/auth/me/mfa/webauthn/{id} beside it demanded a
fresh factor proof. The softer gate sat on the primary sign-in credential:
the last-method check stops an account locking itself out, but nothing
stopped a hijacked session stripping the credentials the owner signs in
with.
The route now goes through requireMfaManagementAuth, the same gate the
security-key removal uses, in a new "if-enrolled" mode. An account with a
second factor pays the full price on either transport — a freshly verified
cookie session, or a factor-proved X-Step-Up elevation on Bearer, so the
native client keeps the capability rather than being sent to the website.
An account with no second factor keeps the contract it had, because a gate
it can never satisfy is not a safeguard but a locked door in front of its
own credential list.
The elevation is spent immediately before the delete, so a foreign id or a
refused last credential does not burn a proof that then has to be minted
again. The route is added to the elevation allowlist with its reason, and
the either-factor enrolment test that was written out three times in the
API kit is now one function.
This commit is contained in:
1 parent
fffdc83ca4
commit
e3be71f0e5
7 files changed
+392
-42
No files matched your search
+19
-4
@@ -2581,9 +2581,17 @@ paths:
|
||||
the account has no password — an account must keep at least one way in.
|
||||
|
||||
|
||||
No step-up: this endpoint takes a plain cookie session or a wildcard Bearer token, where removing a
|
||||
second-factor security key (DELETE /api/auth/me/mfa/webauthn/{id}) requires a fresh factor proof. The asymmetry
|
||||
is in the code as it stands, not a description of intent.
|
||||
Step-up gated for accounts that can clear the gate, on the same mechanism as removing a second-factor security
|
||||
key (DELETE /api/auth/me/mfa/webauthn/{id}). An account with a second factor enrolled — a confirmed TOTP secret
|
||||
or a registered security key — must present a fresh factor proof: a cookie session that completed one within the
|
||||
last five minutes, or, on Bearer, an `X-Step-Up` elevation minted at POST /api/auth/step-up against a re-proved
|
||||
factor (a password-proved elevation is NOT enough). An account with no second factor enrolled is unaffected and
|
||||
keeps the plain session-or-token contract, because a gate it could never satisfy would lock it out of its own
|
||||
credential list.
|
||||
|
||||
|
||||
The elevation is spent only when the deletion is about to happen. A 404 for an unknown id, or the
|
||||
last-credential refusal, leaves it unconsumed and reusable.
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
@@ -2604,7 +2612,14 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"401": *a1
|
||||
"401":
|
||||
description: Not authenticated, or the account has a second factor and the request carried no proof of it fresh enough
|
||||
(`meta.errorCode` = `auth.stepup.required`). Re-prove the factor and retry — on the web by re-verifying, on
|
||||
a native client by minting an elevation at POST /api/auth/step-up. Nothing was removed.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"404":
|
||||
description: No such passkey for this account.
|
||||
content:
|
||||
|
||||
Reference in new issue
Block a user