馃 distributed transcription service thistle.dunkirk.sh
1// Helper functions for route authentication and error handling 2 3import db from "../db/schema"; 4import type { User } from "./auth"; 5import { getSessionFromRequest, getUserBySession } from "./auth"; 6import { AuthErrors } from "./errors"; 7 8export interface AuthenticatedRequest extends Request { 9 user: User; 10} 11 12export function requireAuth(req: Request): User { 13 const sessionId = getSessionFromRequest(req); 14 if (!sessionId) { 15 throw AuthErrors.required(); 16 } 17 18 const user = getUserBySession(sessionId); 19 if (!user) { 20 throw AuthErrors.invalidSession(); 21 } 22 23 return user; 24} 25 26export function requireAdmin(req: Request): User { 27 const user = requireAuth(req); 28 29 if (user.role !== "admin") { 30 throw AuthErrors.adminRequired(); 31 } 32 33 return user; 34} 35 36export function hasActiveSubscription(userId: number): boolean { 37 const subscription = db 38 .query<{ status: string }, [number]>( 39 "SELECT status FROM subscriptions WHERE user_id = ? AND status IN ('active', 'trialing', 'past_due') ORDER BY created_at DESC LIMIT 1", 40 ) 41 .get(userId); 42 43 return !!subscription; 44} 45 46export function requireSubscription(req: Request): User { 47 const user = requireAuth(req); 48 49 // Admins bypass subscription requirement 50 if (user.role === "admin") { 51 return user; 52 } 53 54 if (!hasActiveSubscription(user.id)) { 55 throw AuthErrors.subscriptionRequired(); 56 } 57 58 return user; 59}