first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
# WebAuthn — boundary schemas
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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<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 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.