RAQIM Deploy
Deploy RAQIM 2026-05-02 19:53
6ec2824
import { Request, Response, NextFunction } from "express";
import jwt from "jsonwebtoken";
import { randomUUID } from "crypto";
import { eq } from "drizzle-orm";
import { db, usersTable } from "@workspace/db";
const JWT_SECRET = process.env.SESSION_SECRET || "raqim-secret-key-change-in-prod";
export interface AuthRequest extends Request {
userId?: string;
userRole?: string;
userStatus?: string;
}
export async function requireAuth(req: AuthRequest, res: Response, next: NextFunction): Promise<void> {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith("Bearer ")) {
res.status(401).json({ error: "unauthorized", message: "No token provided" });
return;
}
const token = authHeader.slice(7);
try {
const payload = jwt.verify(token, JWT_SECRET) as { userId: string; role: string; status: string };
if (payload.status !== "active") {
res.status(403).json({ error: "forbidden", message: "Account is not active" });
return;
}
// Verify the user ID from the token still exists in the DB.
// This catches stale tokens issued before a DB wipe/re-seed.
const row = await db
.select({ id: usersTable.id })
.from(usersTable)
.where(eq(usersTable.id, payload.userId))
.get();
if (!row) {
console.error(`[auth] Token user ${payload.userId} not found in DB — rejecting as stale`);
res.status(401).json({ error: "session_expired", message: "انتهت جلستك، يرجى تسجيل الدخول مجدداً" });
return;
}
req.userId = payload.userId;
req.userRole = payload.role;
req.userStatus = payload.status;
next();
} catch {
res.status(401).json({ error: "unauthorized", message: "Invalid or expired token" });
}
}
export async function requireAdmin(req: AuthRequest, res: Response, next: NextFunction): Promise<void> {
let calledNext = false;
await requireAuth(req, res, () => { calledNext = true; });
if (!calledNext) return;
if (req.userRole !== "admin") {
res.status(403).json({ error: "forbidden", message: "Admin access required" });
return;
}
next();
}
export function generateAccessToken(userId: string, role: string, status: string): string {
return jwt.sign({ userId, role, status }, JWT_SECRET, { expiresIn: "1h" });
}
export function generateRefreshToken(userId: string): string {
return jwt.sign({ userId, type: "refresh", jti: randomUUID() }, JWT_SECRET, { expiresIn: "30d" });
}