import { Request, Response, NextFunction } from 'express'; import jwt from 'jsonwebtoken'; import prisma from '../lib/prisma.js'; export interface JwtPayload { userId: string; role: string; isAdmin: boolean; } declare global { namespace Express { interface Request { user?: JwtPayload; } } } export async function authenticate(req: Request, res: Response, next: NextFunction): Promise { const header = req.headers.authorization; if (!header?.startsWith('Bearer ')) { res.status(401).json({ error: 'Missing or invalid Authorization header' }); return; } const token = header.slice(7); try { const payload = jwt.verify(token, process.env.JWT_SECRET!) as JwtPayload; const user = await prisma.user.findUnique({ where: { id: payload.userId }, select: { id: true, role: true, isAdmin: true, isBanned: true }, }); if (!user || user.isBanned) { res.status(401).json({ error: 'Token user no longer exists or is banned. Please login again.' }); return; } req.user = { userId: user.id, role: user.role, isAdmin: user.isAdmin, }; next(); } catch { res.status(401).json({ error: 'Token expired or invalid' }); } } export function requireStaff(req: Request, res: Response, next: NextFunction): void { if (!req.user) { res.status(401).json({ error: 'Unauthorized' }); return; } if (req.user.role !== 'dev' && req.user.role !== 'com') { res.status(403).json({ error: 'Staff access required' }); return; } next(); } export function requireAdmin(req: Request, res: Response, next: NextFunction): void { if (!req.user) { res.status(401).json({ error: 'Unauthorized' }); return; } if (!req.user.isAdmin) { res.status(403).json({ error: 'Admin access required' }); return; } next(); }