feat(mfa): MFA behavior redesign SDK update#46
Open
lakhansamani wants to merge 8 commits into
Open
Conversation
The AuthResponse test claimed to check 'vice versa' but only verified
that interface fields appeared in the fragment. Fixed by adding reverse
check that each fragment token maps to an interface field, correctly
extracting only top-level tokens from authTokenFragment to handle the
nested user { userFragment } sub-selection.
Added new User <-> userFragment test with full bidirectional coverage,
matching the existing Meta test pattern. Both reverse-direction checks
now catch drift where fragments contain fields not in the interface.
JSDoc on parseMfaRedirectParams noting it needs an absolute URL (window.location.href), not .search/.pathname. querySync's AuthResponse check now uses exact top-level token membership on both sides, matching the Meta/User checks instead of a looser substring check on the forward direction.
3.3.0-rc.1 is already published to npm without skipMfaSetup, emailOtpMfaSetup, smsOtpMfaSetup, or parseMfaRedirectParams - reusing that version string left every clean npm install of authorizer-react silently resolving a stale SDK.
email/smsOtpMfaSetup's TOTP twin - settings-mode TOTP enrollment for
an already-authenticated caller, backed by the backend's new
totp_mfa_setup mutation. Returns the enrollment payload
(authenticator_scanner_image/secret/recovery_codes) directly rather
than just a message, since nothing is sent anywhere for TOTP - the
caller scans/enters it, then completes enrollment via
verifyOtp({ is_totp: true }).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings authorizer-js up to date with authorizer#686 (MFA behavior redesign — withheld-token first-time setup, WebAuthn/Email/SMS as MFA factors, lockout + admin recovery, OAuth login gated the same way as password login). Supersedes #45 (closed as superseded — targeted the older, now-merged #685 contract).
Meta/User/AuthResponse/UpdateUserRequestwith the new fields (is_mfa_enforced,has_skipped_mfa_setup_at,mfa_locked_at,should_offer_webauthn_mfa_verify/_setup,should_offer_email_otp_mfa_setup,should_offer_sms_otp_mfa_setup,reset_mfa), plus 3 new request types.Authorizer:skipMfaSetup,lockMfa,emailOtpMfaSetup,smsOtpMfaSetup— all GraphQL+REST dual-protocol, matchingverifyOtp's existing pattern (the backend now has full REST/gRPC parity for these mutations too).parseMfaRedirectParams(url), a standalone helper for themfa_required/mfa_methodsquery params the backend's OAuth callback now appends instead of the normalstate/codeon a redirect that requires MFA.__test__/querySync.test.ts: a regression guard asserting every field onAuthResponse/Meta/Userhas a matching token in its hand-written GraphQL query/fragment string, and vice versa — this exact drift class (field added to a type, forgotten in the query string) has shipped twice in this project's history already.Design doc:
docs/superpowers/specs/2026-07-15-mfa-behavior-redesign-js-sdk-design.md(local only, gitignored in this repo).Process
3-task plan, each implemented and independently reviewed (task-scoped spec + quality gate); a final whole-branch review across all commits (opus) found no Critical/Important issues — every new field/method spot-checked directly against the backend's
schema.graphqlsand confirmed to match exactly, including nullability.Known gap (out of scope, tracked separately)
Self-service deletion of a single non-passkey MFA method (remove just TOTP, keep Email-OTP) doesn't exist on the backend yet — only the admin's all-or-nothing
reset_mfa. Deferred by explicit decision, not part of this PR.Test plan
npx tsc --noEmitcleanquerySync,mfaMethods,mfaRedirect, plus every pre-existing suite)__test__/index.test.ts's testcontainers integration suite needsAUTHORIZER_IMAGEpointed at a PR-#686 build to exercise the new schema — currently fails against the default 2.3.0 image (reproduces identically at the base commit, not a regression from this PR)