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,57 @@
# `header`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Parse and serialise RFC 7515 §4.1 JOSE protected headers. Every registered parameter (`alg`, `jku`, `jwk`, `kid`, `x5u`, `x5c`, `x5t`, `x5t#S256`, `typ`, `cty`, `crit`, plus RFC 7797 `b64`) is shape-validated through the Zod schema; non-registered parameters survive round-trip via the schema's catch-all. The `alg` field is the only mandatory parameter; everything else is optional and the decoder preserves bytes verbatim so callers can re-emit the header without canonicalisation surprises.
## Features
- `parseHeader(base64urlString | object)` — base64url-decode + JSON-parse + Zod-shape-check; returns a typed `JoseHeader`.
- `serializeHeader(header)` — `JSON.stringify` + base64url-encode in one call.
- `JoseHeader` — strongly-typed shape (every registered parameter).
- Unknown parameters survive round-trip.
## Usage: Basic Example
```ts
import { parseHeader, serializeHeader } from "@suaveplan/jws";
const decoded = parseHeader("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9");
// { alg: "HS256", typ: "JWT" }
const reencoded = serializeHeader(decoded);
```
## Usage: Advanced Example
```ts
import { JwsError, parseHeader } from "@suaveplan/jws";
try {
parseHeader("eyJhbGciOjQyfQ"); // alg as number
} catch (err) {
if (err instanceof JwsError && err.code === "JWS.HEADER_MALFORMED") {
// The Zod boundary refused a non-string alg.
}
}
// Custom parameter survives round-trip:
const h = parseHeader({ alg: "ES256", custom: { tenant: "acme" } });
console.log(h["custom"]); // { tenant: "acme" }
```
## API Reference
- `parseHeader(input: string | Record<string, unknown>): JoseHeader`
- Decodes a base64url-encoded JSON object header, OR validates an already-parsed object.
- Throws `JwsError(JWS.HEADER_MALFORMED)` on shape failure.
- Throws `JwsError(JWS.BASE64URL_INVALID)` on base64url failure.
- `serializeHeader(header: JoseHeader | Record<string, unknown>): string`
- `interface JoseHeader` — every RFC 7515 §4.1 registered parameter, all readonly.
## Implementation Notes
The schema is `.passthrough()` so consumers retain non-registered parameters — required for downstream RFCs (RFC 7519 JWT, RFC 9202 EAT-JWT, custom tenant claims) that layer additional parameters into the same header structure. Encoding always uses `JSON.stringify` with no replacer, which means insertion order is preserved; callers needing canonical-order headers (e.g. for byte-identical reproduction of an upstream signer's output) should sort their object keys before passing in. The decoder uses a strict UTF-8 `TextDecoder` so malformed UTF-8 sequences fail rather than silently inserting replacement characters into the parsed JSON — a deliberate strictness that catches producers that emit windows-1252 or latin-1 bytes through a misconfigured pipeline.