import jwt from "jsonwebtoken"; import crypto from "node:crypto"; import User from "../models/User/model.js"; import Access from "../models/Access/model.js"; export const getAccessToken = (payload) => { return jwt.sign(payload, process.env.ECT_KEY, { algorithm: "HS256", expiresIn: "7m", }); }; export const getRefreshToken = () => { return crypto.randomBytes(32).toString("hex"); }; export const authorize = (requiredModule, requiredPermission) => { return async (req, res, next) => { try { const authHeader = req.headers.authorization; if (!authHeader) { throw { code: 401, message: "Bearer Token Missing" }; } const token = authHeader.replace("Bearer ", ""); const verifiedPayload = jwt.verify(token, process.env.ECT_KEY || ""); // 1. Check if User exists const userExists = await User.exists({ _id: verifiedPayload.id }); if (!userExists) { throw { code: 404, message: "User not found" }; } // 2. Fetch Access and Populate Role // Assuming Access model has a 'user' field and a 'role' field const access = await Access.findOne({ user: verifiedPayload.id, }).populate("role"); console.log("access", access?.role?.modules); if (!access || !access.role) { throw { code: 403, message: "No role assigned to this user" }; } // 3. Verify Permissions const hasPermission = access?.role?.modules?.some( (mod) => (mod.module === requiredModule && mod.permission === requiredPermission) || (requiredModule === "generic" && requiredPermission === "generic"), ); if (!hasPermission) { throw { code: 403, message: `Insufficient permissions for ${requiredModule} (${requiredPermission})`, }; } // Success res.locals.user = verifiedPayload; next(); } catch (error) { console.error("AUTH_ERROR", error); res.status(error.code || 401).json(error); } }; };