3.6 KiB
3.6 KiB
WebAuthn — boundary schemas
(no submodules)
Purpose
Defines the Zod schemas wired at every public surface of @suaveplan/webauthn. They serve as the structural contract for caller-supplied options (register, authenticate) and for the parsed shapes the package returns (ParsedAuthData, ParsedAttestationStmt, ClientDataJSON, CoseKey). The schemas are the single typed boundary between untrusted byte input and the production validation pipeline.
Features
- Strict caller-option shapes for
registerandauthenticate. - Forward-compatible
passthrough()on every authenticator-produced structure so an authenticator that emits extra metadata does not break parsing. - Constrained literal unions for
attestation,userVerification,mediation,residentKey, and the per-format dispatchers so a mistyped enum surfaces at the boundary. - Discriminated
largeBlobauthenticate input (read: truexorwrite: Uint8Array) so the verifier can branch on the shape without re-validating.
Usage: Basic Example
import { WebAuthnRegisterOptionsSchema } from "@suaveplan/webauthn";
const parsed = WebAuthnRegisterOptionsSchema.parse({
rp: { name: "example.com" },
user: { id: new Uint8Array(16), name: "u", displayName: "U" },
challenge: new Uint8Array(32),
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
expectedOrigin: "https://example.com",
expectedRpIdHash: new Uint8Array(32),
});
Usage: Advanced Example
import {
ParsedAuthDataSchema,
WebAuthnAuthenticateOptionsSchema,
} from "@suaveplan/webauthn";
function validate(unsafe: unknown) {
const opts = WebAuthnAuthenticateOptionsSchema.parse(unsafe);
return opts;
}
const auth = ParsedAuthDataSchema.parse({
rpIdHash: new Uint8Array(32),
flags: {
userPresent: true,
userVerified: false,
backupEligible: false,
backupState: false,
attestedCredentialData: false,
extensionsPresent: false,
},
flagsByte: 0x01,
signCount: 0,
});
API Reference
ClientDataJSONSchema— pinnedtype,challenge,origin; passthrough.CoseKeySchema— pinnedkty(int); optionalalg,crv,x,y,n,e,k; passthrough.ParsedAuthDataFlagsSchema— six booleans per W3C L3 §6.1.ParsedAuthDataSchema— fixed prefix + optional attested-credential-data + optional extensions.ParsedAttestationStmtSchema—fmt: string,attStmt: Record<string, unknown>.WebAuthnRegisterOptionsSchema,WebAuthnAuthenticateOptionsSchema— caller options.PrfRegisterInputSchema,PrfAuthenticateInputSchema,LargeBlobRegisterInputSchema,LargeBlobAuthenticateInputSchema— extension inputs.
Implementation Notes
- COSE_Key fields outside the RFC 9052 §7 minimum set are kept on the parsed object via
passthrough()so a verifier can reach into vendor extensions when needed. The structural type narrowing happens inparser/cose-key.tswhere the discriminatedktyarms (EC2,OKP,RSA,Symmetric) are produced. WebAuthnRegisterOptionsSchemadeliberately marksattestationas optional; the W3C default is"none"and the production code applies that default before forwarding to the adapter.LargeBlobAuthenticateInputSchemais az.unionof{ read: true }xor{ write: Uint8Array }so callers cannot request both simultaneously — the same constraint W3C §10.1.3 imposes.- Every options schema accepts a caller-side
Uint8Arrayinstance check rather thanBuffer. This is universal —Bufferwould not load in browsers.