import { getDb, pruneExpiredSessions } from './db'; export interface AuthUser { id: string; email: string; isAdmin: boolean; } export function authenticateRequest(req: Request): AuthUser | null { const h = req.headers.get('authorization'); const token = h && h.startsWith('Bearer ') ? h.slice(7).trim() : null; if (!token) return null; const db = getDb(); pruneExpiredSessions(); // Deactivated accounts (is_active = 0) must not authenticate even if // they still have a valid session token. The WHERE clause uses // `COALESCE(..., 1)` so that on DBs where the v3 column has not yet // been added the session still resolves — belt + braces for upgrades. const row = db .prepare( `SELECT u.id, u.email, u.is_admin FROM sessions s JOIN users u ON u.id = s.user_id WHERE s.token = ? AND s.expires_at > datetime('now') AND COALESCE(u.is_active, 1) = 1`, ) .get(token) as any; return row ? { id: row.id, email: row.email, isAdmin: !!row.is_admin } : null; } /** Require admin — returns null if not admin. */ export function requireAdmin(req: Request): AuthUser | null { const user = authenticateRequest(req); return user?.isAdmin ? user : null; }