Authentication
better-auth integration and the withAuthSession helper for authenticating requests inside handlers.
thunder-core builds authentication on better-auth. lib/auth.ts exports a configured better-auth instance (auth) plus betterAuthConfig and capabilities.
better-auth Configuration
The instance uses the MongoDB adapter with plural collection names and enables the admin, passkey, twoFactor, magicLink, and multiSession better-auth plugins. Behaviors worth knowing:
- New users get a Gravatar
imagefallback derived from a SHA-256 hash of their email. - Signup is blocked unless
signupis inBETTER_AUTH_CAPABILITIES. - Password-reset and magic-link emails are sent via the Mailer.
- better-auth is mounted under the
authroute; its handler base path is/auth/api, so better-auth client SDKs should target that base URL.
Read lib/auth.ts for the exact configuration, and routes/auth.ts for the branding/capabilities endpoints and the better-auth UI fallback.
Authenticating a Request - withAuthSession
utils/withAuthSession.ts is the primary helper for authenticating a request inside a handler. It supports three credential strategies, checked in order, and memoizes the result per-request:
- OAuth2 Bearer token (
Authorization: Bearer <access_token>) - verified viaOAuth2.verifyAccessToken; scopes come from the consent (optionally narrowed per tenant via the consent'sresourceGrant[tenantId]). - API key (
X-Api-Key: <secret>) - resolved viaAPIKey.resolve; scopes from the key (optionally narrowed per tenant viaresourceGrant). - Session cookie - resolved via
auth.api.getSession(req).
import { withAuthSession } from "@/plugins/Huruf-Tech/thunder-core/utils/withAuthSession.ts";
const { user, session, tenantId, scopes, auth } = await withAuthSession(req);
// Pass `true` for silent mode (returns void instead of throwing 401 when unauthenticated):
const maybe = await withAuthSession(req, true);tenantIdis read from theX-TENANT-IDrequest header (anObjectId).- It throws
Response.unauthorized()on failure unlesssilentistrue.
See utils/withAuthSession.ts for the exact return type. utils/withCachedOnRequest.ts is the underlying per-request memoization helper (a WeakMap<Request, ...>) - use it to cache expensive per-request computations by key.
Related
- Multi-Tenancy - resolving the active tenant with
withTenant. - Access Control - how every route is permission-gated.