Initial Commit
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
# `options`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines the configuration shape accepted by `createRolledAuthAdapter` and
|
||||
the Zod schema that validates it. Operators wire this from `host.json` or
|
||||
build it programmatically; everything the rest of the package needs flows
|
||||
from a single validated `RolledAuthOptions` value, which keeps invariants
|
||||
(active-key count, prefix shape, TTL positivity) in one place.
|
||||
|
||||
The schema deliberately validates injected functions and the `store`
|
||||
adapter as `unknown` and then refines them later — Zod cannot verify
|
||||
function-argument shapes statically, and TypeScript already does that work
|
||||
at the call boundary.
|
||||
|
||||
## Features
|
||||
|
||||
- Zod schema `RolledAuthOptionsSchema` covering every operator-facing
|
||||
knob.
|
||||
- A `superRefine` cross-field invariant that exactly one key is both
|
||||
`active: true` and non-revoked — keeps sign-time semantics ambiguity-free.
|
||||
- Stable named defaults (`DEFAULT_COOKIE_NAME`, `DEFAULT_ROUTE_PREFIX`,
|
||||
TTLs, rotation period, minimum strength score) so consumers can
|
||||
reference the defaults without re-reading the source.
|
||||
- Two distinct error codes for failures: `DATABASE_REQUIRED` when `store`
|
||||
is missing (operator hooked up nothing), `SIGNING_KEY_NOT_CONFIGURED`
|
||||
for every other schema failure (Zod issues attached as `context`).
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { parseRolledAuthOptions } from "@suaveplan/api-auth-rolled";
|
||||
|
||||
const opts = parseRolledAuthOptions({
|
||||
store: myStore,
|
||||
keys: [{ kid: "k1", privateJwk, publicJwk, active: true }],
|
||||
issuer: "https://api.example.com",
|
||||
audience: "example-frontend",
|
||||
});
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import {
|
||||
DEFAULT_ROTATION_PERIOD_MS,
|
||||
parseRolledAuthOptions,
|
||||
} from "@suaveplan/api-auth-rolled";
|
||||
|
||||
const opts = parseRolledAuthOptions({
|
||||
store,
|
||||
keys,
|
||||
issuer: "https://api.example.com",
|
||||
audience: "example-frontend",
|
||||
routePrefix: "/api/auth",
|
||||
cookieName: "acme.session",
|
||||
cookieSameSite: "strict",
|
||||
cookieSecure: true,
|
||||
sessionTtlSec: 1800,
|
||||
refreshTtlSec: 7 * 24 * 60 * 60,
|
||||
rotationPeriodMs: DEFAULT_ROTATION_PERIOD_MS / 2,
|
||||
minPasswordStrength: 4,
|
||||
strength: { async score(pw) { return 4; } },
|
||||
breach: { async isBreached() { return false; } },
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `parseRolledAuthOptions(raw): RolledAuthOptions` — throws
|
||||
`AuthRolledError` on bad input.
|
||||
- `RolledAuthOptionsSchema` — the Zod schema, re-exported for advanced
|
||||
consumers that want to layer their own refinements.
|
||||
- `DEFAULT_*` constants — every operator-facing default exposed as a
|
||||
named export.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The schema is `strictObject` so unknown keys produce a Zod error rather
|
||||
than silently passing through. The `keys[]` `active` invariant is enforced
|
||||
in `superRefine` rather than as a `transform` so the invariant message
|
||||
appears in the validation issue list instead of as a thrown exception
|
||||
mid-parse. Cross-field invariants that cross the option/store boundary
|
||||
(e.g. "every kid actually resolves to a JWK") are checked later inside the
|
||||
session/token-rotator modules so the options layer remains synchronous and
|
||||
pure.
|
||||
Reference in New Issue
Block a user