import jwt from "jsonwebtoken"; import type { H3Event } from "h3"; import { User } from "../models/User"; export interface AuthUser { userId: string; username: string; roles: string[]; permissions: { canEdit: boolean; canModerate: boolean; canAdmin: boolean; }; } export async function verifyAuth(event: H3Event): Promise { const config = useRuntimeConfig(); const token = getCookie(event, "auth-token"); if (!token) { return null; } try { const decoded = jwt.verify(token, config.jwtSecret as string) as AuthUser; return decoded; } catch (error) { return null; } } export async function requireAuth(event: H3Event): Promise { const user = await verifyAuth(event); if (!user) { throw createError({ statusCode: 401, statusMessage: "Authentication required", }); } return user; } export async function requireRole( event: H3Event, requiredRoles: string[], ): Promise { const user = await requireAuth(event); const hasRole = requiredRoles.some((role) => user.roles.includes(role)); if (!hasRole) { throw createError({ statusCode: 403, statusMessage: "Insufficient permissions", }); } return user; } export async function checkAccessLevel( event: H3Event, accessLevel: "public" | "member" | "cohort" | "admin", cohorts?: string[], ): Promise { // Public content is always accessible if (accessLevel === "public") { return true; } const user = await verifyAuth(event); // No user = no access to protected content if (!user) { return false; } // Check access levels switch (accessLevel) { case "member": // Any authenticated user has member access return true; case "cohort": // Check if user belongs to required cohorts if (!cohorts || cohorts.length === 0) { return true; // No specific cohort required } return cohorts.some((cohort) => user.roles.includes(`cohort-${cohort}`)); case "admin": // Only admins have admin access return user.permissions.canAdmin || user.roles.includes("admin"); default: return false; } }