import type { Context, MiddlewareHandler } from 'hono' import { deleteCookie, getCookie, setCookie } from 'hono/cookie' import { hasRole, type Role } from '../../shared/enums.ts' import { currentUser, fail, type AppEnv } from '../lib/http.ts' import { createSession, deleteSession, SESSION_COOKIE, validateSession } from './sessions.ts' function writeCookie(c: Context, token: string, expires: Date) { setCookie(c, SESSION_COOKIE, token, { httpOnly: true, sameSite: 'Lax', secure: c.get('config').secureCookies, path: '/', expires }) } /** Loads the user from the session cookie, if any. */ export const loadSession: MiddlewareHandler = async (c, next) => { const token = getCookie(c, SESSION_COOKIE) const session = token ? await validateSession(c.get('db'), token) : null if (token && !session) deleteCookie(c, SESSION_COOKIE, { path: '/' }) if (token && session?.renewedUntil) writeCookie(c, token, session.renewedUntil) c.set('user', session?.user ?? null) await next() } export const requireAuth: MiddlewareHandler = async (c, next) => { currentUser(c) await next() } export function requireRole(minimum: Role): MiddlewareHandler { return async (c, next) => { if (!hasRole(currentUser(c).role, minimum)) throw fail(403, 'You do not have permission to do that') await next() } } export async function startSession(c: Context, userId: string): Promise { const { token, expiresAt } = await createSession(c.get('db'), userId) writeCookie(c, token, expiresAt) } export async function endSession(c: Context): Promise { const token = getCookie(c, SESSION_COOKIE) if (token) await deleteSession(c.get('db'), token) deleteCookie(c, SESSION_COOKIE, { path: '/' }) }