WIP: DO NOT MERGE - fix(fxa-settings): passkey registration failures on iOS and Windows Hello#20767
Closed
vpomerleau wants to merge 2 commits into
Closed
WIP: DO NOT MERGE - fix(fxa-settings): passkey registration failures on iOS and Windows Hello#20767vpomerleau wants to merge 2 commits into
vpomerleau wants to merge 2 commits into
Conversation
Because: - WebKit before 26.5.1 crashes the WebContent renderer inside its native PublicKeyCredential.toJSON() when a prf extension output is present, breaking passkey registration on iOS with an uncatchable process trap that no try/catch can recover. This commit: - Serializes the credential manually in toCredentialJSON via the long-standing Level 2 getters (base64url-encode the response ArrayBuffers; read extension results via getClientExtensionResults) instead of native toJSON(), which predate and bypass the broken serializer. Verified on an iOS 26.2 device for both create and get. - Drops the now-unused toJSON global augmentation and hasToJSON guard, and moves the webauthn unit tests onto the manual-serialization path.
Because: - Requesting the WebAuthn PRF extension at registration makes the ceremony fail outright on platform authenticators that can't provision it — notably Windows Hello without the PRF platform update, where create() rejects before any prompt. PRF only powers Phase-2 passwordless Sync; a passkey without it still works for sign-in, so a hard failure blocks registration needlessly. This commit: - When registration fails in a way an optional PRF probe could have caused (the create error categorizes as "unexpected"), keeps the user on the add page with a "Try again" button instead of bouncing to settings. The click is a fresh user activation, so the retry — which strips PRF and reuses the cached options/challenge — runs create() immediately. Success records a non-PRF passkey; a failed retry returns to settings with the generic help-link message. - Adds isRetriableWithoutPrf (reuses the shared error categorizer rather than matching one error name, so other "unexpected" manifestations are covered too) and stripPrfExtension, both unit tested. Surfaces the on-page failure in an error Banner with a short message and a retry action. - Records Glean reasons prf_unsupported / prf_retry_failed for visibility. - Adds a functional test (new prf-unsupported polyfill mode) driving the reject -> on-page retry -> success flow, and updates the WebAuthn polyfill to expose Level 2 getters (the manual-serialization fix reads them) and to carry the DOMException name across the exposeFunction boundary. Closes #FXA-13991
Contributor
Author
|
Closing this exploratory fix - I've linked it in the originating ticket for future work. |
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.
Because
This pull request
toCredentialJSON(packages/fxa-settings/src/lib/passkeys/webauthn.ts) using the WebAuthn Level 2 getters instead of the nativePublicKeyCredential.toJSON()that crashes the WebKit renderer when a PRF output is present (verified on an iOS 26.2 device).create()fails in a way the optional PRF probe could have caused, keeps the user on the add page with an error banner and a "Try again" action (packages/fxa-settings/src/components/Settings/PagePasskeyAdd/index.tsx) instead of returning to settings; the retry strips the PRF extension and reuses the cached options, producing a working passkey without it.isRetriableWithoutPrfandstripPrfExtension(packages/fxa-settings/src/lib/passkeys/prf-fallback.ts), which reuse the shared WebAuthn error categorizer so any "unexpected" ceremony failure is handled, with unit tests.prf_unsupportedandprf_retry_failedreasons, and adds a functional test (a newprf-unsupportedpolyfill mode inpackages/functional-tests/lib/passkeyPolyfill.ts) that drives the reject → on-page retry → success flow.Issue that this pull request solves
Closes: FXA-13991
Checklist
Put an
xin the boxes that applyHow to review (Optional)
webauthn.ts(manual L2 serialization),PagePasskeyAdd/index.tsx(on-page retry flow),prf-fallback.ts(retry predicate).webauthn.ts→prf-fallback.ts→PagePasskeyAdd/index.tsx→ functional test.Screenshots (Optional)
Please attach the screenshots of the changes made in case of change in user interface.
Other information (Optional)
Any other information that is important to this pull request.