import { Context, Next, State } from "@oak/oak"; import { verifyJWT } from "../lib/jwt.ts"; import { APIErrorCode, APIException, type AuthPayload, } from "../model/interfaces.ts"; import { getUserById } from "../services/user-service.ts"; export interface AuthContext extends Context { state: AuthState; } export interface AuthState extends State { user: AuthPayload; } export async function authMiddleware(ctx: AuthContext, next: Next) { const authHeader = ctx.request.headers.get("Authorization"); if (!authHeader || !authHeader.startsWith("Bearer ")) { throw new APIException( APIErrorCode.UNAUTHORIZED, 401, "Missing or invalid token", ); } const token = authHeader.substring(7); const payload = await verifyJWT(token); if (!payload) { throw new APIException(APIErrorCode.UNAUTHORIZED, 401, "Invalid token"); } try { getUserById(payload.userId); } catch { throw new APIException(APIErrorCode.UNAUTHORIZED, 401, "User not found"); } ctx.state.user = payload; await next(); } export async function adminOnlyMiddleware(ctx: AuthContext, next: Next) { if (!ctx.state.user?.isAdmin) { throw new APIException( APIErrorCode.UNAUTHORIZED, 403, "Admin access required", ); } await next(); }