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,85 @@
# `composition`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Top-level factory `createRolledAuthAdapter` that wires the four
sub-modules (`token-rotator`, `session`, `principal-projection`,
`security-schemes`) into a single `AuthAdapter` ready for the host to
register. Keeping the composition explicit (rather than letting each
sub-module own its own host wiring) means the dependency graph is one
arrow: options flow in, an adapter object flows out, no hidden state.
The returned value extends the `AuthAdapter` contract (`resolver` +
`securityScheme`) with three additional surfaces the future provider
half (`api-auth-rolled-provider`) will consume: `issueToken`,
`verifyToken`, and the rotator handle so operators can wire
`setKeys(...)` from an out-of-band rotation cron.
## Features
- Single entry point — `createRolledAuthAdapter(rawOptions)`.
- Options validated via the package's Zod schema before any wiring runs.
- Defaults filled at the composition layer (cookie name, rotation
period, session TTL) so individual sub-modules stay focused on their
one concern.
- Returned adapter is structurally a valid `AuthAdapter` so any host
that accepts the contract will accept the rolled adapter.
## Usage: Basic
```ts
import { createRolledAuthAdapter } from "@suaveplan/api-auth-rolled";
const adapter = createRolledAuthAdapter({
store,
keys: [
{ kid: "k1", privateJwk, publicJwk, active: true },
],
issuer: "https://api.example.com",
audience: "example-front",
});
host.registerAuthSession(adapter);
```
## Usage: Advanced
```ts
import { createRolledAuthAdapter } from "@suaveplan/api-auth-rolled";
const adapter = createRolledAuthAdapter({
store,
keys: initialKeys,
issuer: "https://api.example.com",
audience: "example-front",
cookieName: "acme.session",
sessionTtlSec: 1800,
rotationPeriodMs: 12 * 60 * 60 * 1000,
});
// Operator rotation cron — fetch new key from KMS, swap atomically.
setInterval(async () => {
if (!adapter.rotator.decide().shouldRotate) return;
const next = await kms.nextKeyset();
adapter.rotator.setKeys(next);
}, 60_000);
```
## API Reference
- `createRolledAuthAdapter(rawOptions: unknown): RolledAuthAdapter`
- `RolledAuthAdapter extends AuthAdapter`: adds `id: "rolled"`, `rotator`,
`issueToken(userId)`, `verifyToken(token)`.
## Implementation Notes
The adapter intentionally keeps `id` as the literal `"rolled"` so a host
running both Better-Auth and rolled can disambiguate by adapter id. The
`securityScheme` slot points at the bearer contribution (the canonical
single-scheme shape) but the `.schemes` map on the contribution exposes
both the cookie and bearer entries — emitters aware of dual-transport
adapters can register both names without a separate adapter property.