import type { Auth } from "better-auth"; import type { Context } from "hono"; import type { Principal } from "../principal/principal.js"; /** * Loose-typed Better-Auth session shape returned by `auth.api.getSession`. * Kept loose so plugin-extended sessions (passkeys, organisations, * twoFactor) flow through without forcing this package to track every * Better-Auth plugin's type extensions. */ export type BetterAuthSessionResult = { readonly user: Record; readonly session: Record; } | null; /** * Service slot registered by `createAuthPlugin` in the host's * `ServiceRegistry`. Downstream plugins (api-plugin-user, * api-plugin-vault) call `ctx.getService("authService")` to read the * current principal, the Better-Auth instance, or to manually resolve * a session from arbitrary headers. */ export interface AuthService { /** * Returns the typed `Principal` attached to the current request * context, or `null` for anonymous requests. The session middleware * is responsible for populating `c.get("user")`. */ getCurrentPrincipal(c: Context): Principal | null; /** * Returns the underlying Better-Auth instance — useful for plugins * that need to call Better-Auth API endpoints directly (e.g. * organisation membership listings). */ getBetterAuthInstance(): Auth; /** * Resolves a session from arbitrary request headers. Plugins * authenticating a stand-alone request (cron-triggered work, raw * WebSocket upgrades) use this to get the same session shape the * middleware would have produced. */ getSession(headers: Headers): Promise; } /** * Inputs required to build the `AuthService` impl. Kept explicit so * the factory is testable without the full plugin lifecycle. */ export interface CreateAuthServiceOptions { readonly auth: Auth; } /** * Construct the canonical `AuthService` implementation backed by the * supplied Better-Auth instance. */ export function createAuthService( options: CreateAuthServiceOptions ): AuthService { const { auth } = options; return { getCurrentPrincipal(c) { const value = c.get("user"); return value ?? null; }, getBetterAuthInstance() { return auth; }, async getSession(headers) { const result = (await auth.api.getSession({ headers, })) as BetterAuthSessionResult; return result; }, }; }