webauthn.jsPublicKeyCredential API (which uses binary ArrayBuffer values) and the server-side JSON API (which expects base64url-encoded strings). Three main functions handle distinct lifecycle stages: convertPublicKeyCredentialRequestOptions decodes server-provided challenge/user IDs into ArrayBuffer form for the browser API; convertRegisterCredential packs a freshly created credential into the JSON shape the server expects for registration; convertAuthenticateCredential does the same for authentication assertions.decodeBase64url — Converts a URL-safe base64 string to an ArrayBuffer. Uses the atob bridge: first reconstructs standard base64 (replacing -→+, _→/, adding padding), then decodes via atob, and copies each character's charCode into a Uint8Array backed by a new ArrayBuffer.
bufferToBase64url — The inverse: iterates a Uint8Array view, builds a binary string via String.fromCharCode, encodes with btoa, then converts to URL-safe form.
convertCredentials — Helper extracted during refactoring that converts an array of credential descriptor objects (with rawId and id fields) from base64url strings to ArrayBuffer, for both allowCredentials and excludeCredentials lists.
Registration (convertRegisterCredential) packs: rawId, clientDataJSON, attestationObject, and transports from the credential response, plus request metadata (requestId, challenge, sessionToken). Authentication (convertAuthenticateCredential) packs: authenticatorData, signature, userHandle instead of the attestation fields. Both wrap the result in the same envelope structure that the server-side REST endpoints expect.
This file represents the production WebAuthn implementation, distinct from the vendored webauthn-json.js library. The team started with manual bit-manipulation base64 decoding (using a reverse lookup table), then refactored to the simpler atob/btoa-based approach. The separate registration/authentication functions and the convertCredentials helper were extracted from an initially monolithic credential conversion.
| Commit | What changed |
|---|---|
9c86a74e5 | Extracted the inline allowCredentials/excludeCredentials conversion loops into a shared convertCredentials(dest, src) helper function. Reduced duplication: both credential lists now call the same helper. The excludeCredentials conversion from the original convertPublicKeyCredentialRequestOptions was also added here, completing the credential list handling. |
c6ba8d11c | Two significant additions: (1) Added credential list conversion inside convertPublicKeyCredentialRequestOptions to handle allowCredentials arrays — each credential's rawId and id are decoded from base64url; (2) Added convertAuthenticateCredential as a dedicated function for authentication assertions (previously, registration and authentication were handled by a single convertCredential function). The old function was renamed to convertRegisterCredential to clarify its purpose. |
4c5cc21e9 | Refactored convertCredential to return the result object directly instead of assigning to an intermediate result variable, and added the challenge field to the output envelope — a critical fix since the server needs the original challenge to verify the credential. |
4a70ca329 | Fixed the credential response field extraction using destructuring: const { response } = credential; — the previous code incorrectly read clientDataJSON, attestationObject, and transports from the top-level credential object instead of from credential.response, which would have produced undefined values. This was a critical bug fix. |
ddccb2e68 | Major refactor of the base64url encoding/decoding approach. The original hand-rolled bit-manipulation decoder (using a reverse lookup table and manual bit shifting) was replaced with the simpler atob/btoa-based approach. Also converted convertPublicKeyCredentialRequestOptions from mutation-based (modifying the input in place) to copy-based (using JSON.parse(JSON.stringify(...)) to deep-clone first). Added the first version of convertCredential for registration encoding. |
05c32c27f | Initial WebAuthn commit: created the base64url decoder and the first version of convertPublicKeyCredentialRequestOptions. Used the parameter name registerData and accessed challenge/user.id via registerData.publicKey.challenge, reflecting an earlier API shape that was later simplified. |