mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 21:32:18 +00:00
fix(auth): let every fresh-factor refusal open the re-proof dialog
A Guardian signed in through single sign-on with a second factor enrolled could not hand a managed profile over once five minutes had passed since sign-in: the handover answered 401 auth.stepup.required, and the panel printed "Confirm your second factor, then try again" with no way to do so. The same held for every action behind requireFreshMfa: creating, editing and ending a managed profile, adding and removing a Guardian, disabling the second factor, rotating recovery codes, removing a security key or a passkey, changing the password, the data wipe, account deletion and the key rotation. The recent-proof routes had the dialog; these had text. - requireFreshMfa names the proofs that clear a stale stamp in meta.methods (the possession proofs the account holds, never a password, which stamps reproofAt only). - The re-proof flow treats that refusal like auth.reproof.required: open the dialog, post the proof to /api/auth/reproof, send the request once more. The flow moves into a React-free module so it can be driven in tests; the hook binds it to the dialog. - The managed-profile mutation hooks take a required proof guard, and every caller passes recentProof.run. The other surfaces wrap their requests in recentProof.run; disabling the second factor asks before its confirmation opens, so the code typed there is not spent twice. - An account with nothing to re-prove in place (single sign-on only, no factor) is told to sign in again when adding a factor, instead of being offered a password it does not have. - step-up-web-caller-guard freezes the gated route methods and fails when a web request to one of them runs outside the flow. An account whose only second factor is the identity provider's is still asked for an app factor on the managed-profile acts: the app cannot see the provider's factor. Enrolling right after a sign-in needs no further proof, and the confirmation stamps the session, so the act follows. Refs #959
This commit is contained in:
1 parent
59f910df5e
commit
99f0607a69
36 files changed
+2122
-466
No files matched your search
+10
-5
@@ -2333,7 +2333,11 @@ paths:
|
||||
/api/mcp/tokens, POST /api/tokens/measurements, POST /api/tokens/workouts, POST /api/tokens/documents, and the
|
||||
admin backup download, upload and restore, the admin data wipe and the admin password reset. Those answer 401
|
||||
`auth.reproof.required` with `meta.methods` (the proofs this account can give) when the session signed in or
|
||||
re-proved more than five minutes ago.
|
||||
re-proved more than five minutes ago. A `totp`, `webauthn` or `passkey` proof here also clears the routes that
|
||||
ask for a fresh second factor (the managed-profile acts, the second-factor and passkey changes, the password
|
||||
change, account deletion, the data wipe and key rotation): on a browser session those answer 401
|
||||
`auth.stepup.required` with `meta.methods` naming the possession proofs the account holds, and the web re-proves
|
||||
here and retries.
|
||||
|
||||
|
||||
The body takes the same shapes as POST /api/auth/step-up. On an account with a second factor only `totp`,
|
||||
@@ -21681,10 +21685,11 @@ paths:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ManagedProfileEnvelope"
|
||||
"401":
|
||||
description: "No fresh second-factor proof (`meta.errorCode: auth.stepup.required`), or none enrolled at all
|
||||
(`meta.errorCode: auth.stepup.mfa_not_enrolled`) — this gate is unconditional, so an account without a
|
||||
second factor cannot create a managed profile until it enrols one. The ordinary unauthenticated 401 arrives
|
||||
here too, including for a Bearer caller, whose transport this gate does not read."
|
||||
description: "No fresh second-factor proof (`meta.errorCode: auth.stepup.required`, with `meta.methods` naming the
|
||||
proofs that clear it at POST /api/auth/reproof), or none enrolled at all (`meta.errorCode:
|
||||
auth.stepup.mfa_not_enrolled`) — this gate is unconditional, so an account without a second factor cannot
|
||||
create a managed profile until it enrols one. The ordinary unauthenticated 401 arrives here too, including
|
||||
for a Bearer caller, whose transport this gate does not read."
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
|
||||
Reference in new issue
Block a user