/** * Copyright (c) 2026 Niolla * All rights reserved. * * This source code is proprietary and confidential. * Unauthorized copying, modification, distribution, or use * of this file, via any medium, is strictly prohibited. */ // app/middleware/permission.middleware.js const hasPermission = (userPermissions, requiredPermission) => { return userPermissions.some(p => { if (p === requiredPermission) return true; // wildcard support if (p.endsWith(".*")) { const prefix = p.slice(0, -2); return requiredPermission.startsWith(prefix); } return false; }); }; const methodToAction = { GET: "view", POST: "create", PUT: "update", PATCH: "update", DELETE: "delete" }; const checkPermission = (baseOrFull, options = {}) => { return (req, res, next) => { if (!req.user) { return res.status(401).json({ success: false, message: "Unauthorized" }); } // admin bypass if (req.user.accountType === "admin") { return next(); } if (typeof baseOrFull !== "string") { return res.status(500).json({ success: false, message: "Permission must be a string" }); } let requiredPermission; if (options.custom) { requiredPermission = baseOrFull; } else { const action = methodToAction[req.method]; if (!action) { return res.status(500).json({ success: false, message: "Unknown HTTP method" }); } requiredPermission = `${baseOrFull}.${action}`; } const userPermissions = req.user.permissions || []; const hasPermission = userPermissions.includes(requiredPermission) || userPermissions.includes(`${baseOrFull}.*`); if (!hasPermission) { return res.status(403).json({ success: false, message: `Forbidden - Missing ${requiredPermission}` }); } next(); }; }; const authorizedAccountType = (allowedTypes) => { return (req, res, next) => { if (!req.user || !allowedTypes.includes(req.user.accountType)) { return res .status(403) .json({ success: false, message: "Forbidden" }); } next(); } } module.exports = {authorizedAccountType, checkPermission};