# /userinfo endpoint ## Purpose `handleUserInfo` implements the OAuth/OIDC userinfo endpoint. Given a `Bearer` authorization header, it looks up the associated access token, verifies it has not expired, and returns the matching user payload shaped by the configured `userShape` (or by a custom `userMapper` when the caller supplies one). The endpoint backs the primary identity-fetch path that production OAuth adapters use after a successful code-exchange, so it is the surface most test scenarios assert against. ## Features - `Bearer ` extraction with regex validation. - Looks up the token in the in-memory access-token map and 401s on unknown or expired tokens. - Dispatches across `github` / `google` / `generic` shapes, or hands the primed payload to a caller-supplied `userMapper`. - All error responses use RFC-6750 `invalid_token` envelopes. ## Usage: Basic ```ts const r = handleUserInfo(state, "Bearer at_abc"); // → { status: 200, body: { id: 42, login: "alice", … } } ``` ## Usage: Advanced Provide a custom mapper to return arbitrary claim shapes: ```ts const state = { ..., options: { ..., userMapper: (primed) => ({ sub: String(primed?.id), groups: ["admins"] }), }, }; ``` ## API Reference - `handleUserInfo(state, authorizationHeader: string | undefined): UserInfoResult` - `interface UserInfoResult` — `{ status: 200 | 401, body: Record }`. ## Implementation Notes The matcher uses `^Bearer\s+(.+)$` (case-sensitive, unicode flag) so RFC-6750's exact-spelling requirement is enforced — "bearer" or "Token" headers are rejected as malformed. Token expiry is checked with `<= Date.now()` so a token whose `expiresAt` equals the current millisecond is treated as expired (defensive boundary). The default branch of the `userShape` switch is unreachable under the typed input and is `/* c8 ignore */`d to keep coverage clean.