# 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 `register` and `authenticate`. - 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 `largeBlob` authenticate input (`read: true` xor `write: Uint8Array`) so the verifier can branch on the shape without re-validating. ## Usage: Basic Example ```ts 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 ```ts 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` — pinned `type`, `challenge`, `origin`; passthrough. - `CoseKeySchema` — pinned `kty` (int); optional `alg`, `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`. - `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 in `parser/cose-key.ts` where the discriminated `kty` arms (`EC2`, `OKP`, `RSA`, `Symmetric`) are produced. - `WebAuthnRegisterOptionsSchema` deliberately marks `attestation` as optional; the W3C default is `"none"` and the production code applies that default before forwarding to the adapter. - `LargeBlobAuthenticateInputSchema` is a `z.union` of `{ 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 `Uint8Array` instance check rather than `Buffer`. This is universal — `Buffer` would not load in browsers.