# `session-adapter` — composite `AuthAdapter` _(no submodules)_ ## 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.