import { Request, Response } from 'express' /** * Sends a uniform auth-error JSON response. * All auth middleware must go through this function so the shape is identical * to what the errorMiddleware produces for AppError instances. */ export function sendUnauthorized(res: Response, error: string, message: string) { return res.status(401).json({ error, message, statusCode: 401 }) } export function getCookie(req: Request, name: string): string | null { const cookieHeader = req.headers.cookie if (!cookieHeader) return null for (const chunk of cookieHeader.split(';')) { const [rawName, ...rawValue] = chunk.trim().split('=') if (rawName === name) { return decodeURIComponent(rawValue.join('=')) } } return null } export function getBearerToken(req: Request): string | null { const authHeader = req.headers.authorization if (!authHeader?.startsWith('Bearer ')) return null const token = authHeader.slice(7).trim() return token.length > 0 ? token : null } export function getAuthToken(req: Request, cookieName?: string): string | null { // Prefer HttpOnly cookies over bearer tokens so stale script-readable tokens // cannot shadow a valid server-managed session during migration. return (cookieName ? getCookie(req, cookieName) : null) ?? getBearerToken(req) } export function sendForbidden(res: Response, error: string, message: string, extra?: Record) { return res.status(403).json({ error, message, statusCode: 403, ...extra }) } export function sendPaymentRequired(res: Response, error: string, message: string, extra?: Record) { return res.status(402).json({ error, message, statusCode: 402, ...extra }) }