import type { MiddlewareHandler } from 'hono' import type { createAuth } from '../libs/auth' import type { Env } from '../libs/env' import type { HonoEnv } from '../types/hono' import { resolveRequestAuth } from '../libs/request-auth' import { createUnauthorizedError } from '../utils/error' type AuthInstance = ReturnType /** * Session middleware injects the user and session into the Hono context. * It does not block unauthorized requests. */ export function sessionMiddleware(auth: AuthInstance, env: Env): MiddlewareHandler { return async (c, next) => { // NOTICE: auth routes handle session lookup inside better-auth itself, // and `/auth/*` only redirects to the standalone ui-server-auth deployment. // Running the global session middleware on `/api/auth/*`, `/auth/*`, // and the auth discovery endpoints duplicates the same session // read and slows the OIDC login path (`authorize` → `token` → // `get-session`) noticeably. // // `/auth/` and `/api/auth/` are distinct prefixes — `/api/auth/...` // starts with `/api` and won't be matched by the `/auth/` startsWith. if ( c.req.path.startsWith('/auth/') || c.req.path.startsWith('/admin/') || c.req.path === '/admin' || c.req.path.startsWith('/api/auth/') || c.req.path === '/.well-known/oauth-authorization-server/api/auth' ) { c.set('user', null) c.set('session', null) return await next() } const session = await resolveRequestAuth(auth, env, c.req.raw.headers) if (!session) { c.set('user', null) c.set('session', null) return await next() } c.set('user', session.user) c.set('session', session.session) await next() } } /** * Auth guard middleware blocks requests if the user is not authenticated. * Must be used after sessionMiddleware. */ export const authGuard: MiddlewareHandler = async (c, next) => { const user = c.get('user') if (!user) { throw createUnauthorizedError() } await next() }