2.8 KiB
header
(no submodules)
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 typedJoseHeader.serializeHeader(header)—JSON.stringify+ base64url-encode in one call.JoseHeader— strongly-typed shape (every registered parameter).- Unknown parameters survive round-trip.
Usage: Basic Example
import { parseHeader, serializeHeader } from "@suaveplan/jws";
const decoded = parseHeader("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9");
// { alg: "HS256", typ: "JWT" }
const reencoded = serializeHeader(decoded);
Usage: Advanced Example
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>): stringinterface 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.