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,81 @@
# `session-adapter` — composite `AuthAdapter`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`AuthAdapter` is the composite shape every concrete session-auth adapter
exports — pairing the per-request `SessionResolver` with the OpenAPI
`SecuritySchemeContribution` and the optional adapter-level CSRF override.
`validateAuthAdapter()` is the boundary helper the host calls before stitching
an adapter into its resolver chain; it throws `AUTH.SECURITY_SCHEME_MISSING`
when the contribution is absent or malformed.
This package owns the marriage of "what does the credential look like on the
wire" (security scheme) and "how do we turn it into a Principal" (resolver) so
that downstream consumers — `api-host`, `api-openapi`, and the host's CSRF
middleware — read a single source-of-truth shape instead of three loosely
coupled fields scattered across every concrete adapter package.
## Features
- `csrf` is optional, intentionally: an unset slot defers to the
`CsrfPolicy.requiresCsrf(scheme)` default, while a set value pins per-adapter
intent (auditable in the host's adapter table).
- `validateAuthAdapter` is identity on the happy path so it composes with
registration pipelines that need to forward the validated value.
## Usage: Basic
```ts
import { type AuthAdapter, validateAuthAdapter } from "@suaveplan/api-auth/session-adapter";
import type { SessionResolver } from "@suaveplan/api-auth/resolver";
declare const jwtResolver: SessionResolver;
const adapter: AuthAdapter = {
resolver: jwtResolver,
securityScheme: {
name: "bearerAuth",
scheme: { type: "http", scheme: "bearer", bearerFormat: "JWT" },
},
};
validateAuthAdapter(adapter);
```
## Usage: Advanced
Register multiple adapters at host startup; the validator centralises the
fail-fast and the host stitches the resolvers into a `SessionResolverChain`:
```ts
import { SessionResolverChain } from "@suaveplan/api-auth/chain";
import { type AuthAdapter, validateAuthAdapter } from "@suaveplan/api-auth/session-adapter";
function buildChain(adapters: readonly AuthAdapter[]): SessionResolverChain {
const validated = adapters.map((a) => validateAuthAdapter(a));
return new SessionResolverChain(validated.map((a) => a.resolver));
}
```
## API Reference
| Symbol | Kind | Description |
|-----------------------|-------------|---------------------------------------------------------------|
| `AuthAdapter` | interface | `{ resolver, securityScheme, csrf? }`. |
| `validateAuthAdapter` | function | Boundary validator; throws `AUTH.SECURITY_SCHEME_MISSING`. |
## Implementation Notes
- `csrf` is a `boolean | undefined` field rather than a richer `CsrfDecision`
record. The host's middleware combines this slot with the per-route override
and the `CsrfPolicy.requiresCsrf` default into a final decision — the
adapter does NOT need three-valued logic for the same intent.
- `validateAuthAdapter` returns its argument unchanged so call sites can write
`const a = validateAuthAdapter(buildAdapter(opts));` without re-binding.
- The structural type is `interface` (not `type`) so concrete adapter packages
MAY use declaration merging to attach extension fields without forking the
contract.