Skip to content

feat(mfa): offer passkey enrollment during the login-time MFA setup#63

Open
lakhansamani wants to merge 1 commit into
mainfrom
feat/mfa-session-passkey-setup
Open

feat(mfa): offer passkey enrollment during the login-time MFA setup#63
lakhansamani wants to merge 1 commit into
mainfrom
feat/mfa-session-passkey-setup

Conversation

@lakhansamani

Copy link
Copy Markdown
Contributor

Summary

  • AuthorizerMFASetup now offers passkey as a real enrollment option during the login-time (token-withheld) MFA offer screen, wired through AuthorizerBasicAuthLogin/AuthorizerSignup/AuthorizerRoot/AuthorizerPasskeyLogin (all previously hardcoded passkey: false).
  • OAuth/magic-link return now branches on the backend's new mfa_gate redirect param: renders AuthorizerVerifyOtp (challenge) for an already-configured factor instead of always showing the setup screen.
  • AuthorizerPasskeyLogin's "verify" step renders the real challenge form instead of telling the user to sign in with a password.
  • Removed a stale AuthorizerVerifyOtp useEffect that misfired an "Email or Phone Number is required" error on the now-legitimate session-only resolution path.

Depends on authorizerdev/authorizer-js#47 (the SDK changes this consumes) and the corresponding backend PR on authorizerdev/authorizer (feat/enforce-mfa-passkey-gate).

Test plan

  • npx tsc --noEmit — clean
  • npm run build — clean
  • Manually verified against a local backend build: passkey "Set up" now renders on the MFA setup screen (screenshot-confirmed); mfa_gate=verify correctly renders the OTP challenge screen instead of setup
  • Full email-OTP MFA setup flow (setup → mailpit delivery → verify → token issued → next login challenges instead of re-offering) verified end to end against the linked SDK/backend changes

AuthorizerMFASetup hardcoded passkey: false everywhere it was rendered
with loginContext set (login/signup/OAuth/passkey-primary), and
force-hid the option whenever loginContext was present at all -
because webauthn_registration_options/verify required a bearer token
that doesn't exist until the MFA gate is satisfied. The backend
(authorizerdev/authorizer, authorizerdev/authorizer-js#47) now
supports authenticating that ceremony via the MFA session cookie
instead, so passkey is a real option here.

Also, using the new mfaGate signal on the OAuth/magic-link return
path: route to AuthorizerVerifyOtp for an already-configured factor
instead of always showing the setup screen, and let
AuthorizerPasskeyLogin's verify step render the same challenge form
(previously told the user to sign in with a password instead).

Removed a stale useEffect in AuthorizerVerifyOtp that flagged "Email
or Phone Number is required" on mount even for the legitimate
session-only resolution path these two flows now exercise.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant