feat: add WebAuthn/passkey SDK methods#41
Merged
Conversation
Wraps the 6 new webauthn_* GraphQL operations (authorizerdev/authorizer#671) and adds the browser-side ceremony glue. Raw methods: webauthnRegistrationOptions/Verify, webauthnLoginOptions/Verify, webauthnCredentials, webauthnDeleteCredential - GraphQL-only (no REST route), so these call graphqlQuery directly rather than through dispatch. High-level orchestration: registerPasskey(name?) and loginWithPasskey(email?) drive the full options -> browser API -> verify round trip in one call. src/webauthn.ts uses the browser's native PublicKeyCredential. parseCreationOptionsFromJSON / parseRequestOptionsFromJSON / credential. toJSON() rather than hand-rolled base64url<->ArrayBuffer conversion - go-webauthn's JSON wire format is the spec-defined RegistrationResponseJSON/ AuthenticationResponseJSON shape those APIs are built around, confirmed by reading the library's struct tags directly rather than assuming. isWebauthnSupported() is exported for callers to feature-detect before showing passkey UI.
registerPasskey/loginWithPasskey previously collapsed every navigator.credentials.create/get rejection (including the very common "user dismissed the passkey picker" case, a NotAllowedError) into a generic Error with only a message - no way for a caller to distinguish cancellation from a real failure the way GraphQL errors already allow via .code. wrapCeremonyError now attaches the DOMException's own standard .name (NotAllowedError, InvalidStateError, etc.) as an additive, non-enumerable .code - the same field GraphQL errors carry - so callers get one consistent way to branch on error kind rather than matching message text. Reuses the browser's own exception names instead of inventing new ones. Also fixed isWebauthnSupported to check for credential.toJSON() support, not just the two parseOptionsFromJSON statics - all three shipped together in the same WebAuthn Level 3 browser releases, but checking only two left a gap where the capability check could pass while the actual toJSON call later fails.
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.
Adds WebAuthn/passkey support to the JS SDK, pairing with the merged server feature (authorizerdev/authorizer#671).
Replaces the auto-closed #40 (its base branch was deleted when its stacked parent #39 merged; same commits, now based on main + merged).
webauthn_credentialsquery, matching the server schema exactly (register/login options + verify, delete credential, list).registerPasskey/loginWithPasskey) using the nativePublicKeyCredential.parseCreationOptionsFromJSON/parseRequestOptionsFromJSON/toJSONAPIs (no hand-rolled base64url), plus exported low-level ops for callers who drive the ceremony themselves.AuthTokentype for login andAuthorizerSDKErrorfrom feat: surface GraphQL extensions.code on returned errors #39.Reviewed clean (verdict: merge): API shape matches server, envelope handling consistent, no secrets mishandled, 7 meaningful unit tests. Non-blocking notes: ceremony glue untested (no jsdom/PublicKeyCredential in Node env — server smoke covers it), and the native JSON APIs require Chrome 119+/Safari 17.4+/Firefox 119+ (
isWebauthnSupportedexported for feature detection — worth a README note).