Skip to content

feat: add WebAuthn/passkey SDK methods#41

Merged
lakhansamani merged 3 commits into
mainfrom
feat/webauthn-passkey-sdk
Jul 11, 2026
Merged

feat: add WebAuthn/passkey SDK methods#41
lakhansamani merged 3 commits into
mainfrom
feat/webauthn-passkey-sdk

Conversation

@lakhansamani

Copy link
Copy Markdown
Contributor

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).

  • 6 GraphQL wrapper methods + webauthn_credentials query, matching the server schema exactly (register/login options + verify, delete credential, list).
  • High-level ceremony drivers (registerPasskey/loginWithPasskey) using the native PublicKeyCredential.parseCreationOptionsFromJSON/parseRequestOptionsFromJSON/toJSON APIs (no hand-rolled base64url), plus exported low-level ops for callers who drive the ceremony themselves.
  • Reuses the existing AuthToken type for login and AuthorizerSDKError from 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+ (isWebauthnSupported exported for feature detection — worth a README note).

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.
@lakhansamani lakhansamani merged commit b926a7a into main Jul 11, 2026
2 checks passed
@lakhansamani lakhansamani deleted the feat/webauthn-passkey-sdk branch July 11, 2026 09:25
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