mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-09-22 08:12:00 +02:00

* 🏗️ feat: Add Group model and schema with GroupType enum * 🏗️ feat: Introduce Permissions module and refactor role-based access control * 🏗️ feat: Refactor permissions handling and consolidate permission schemas * 🏗️ feat: Refactor role permissions handling and improve role initialization logic * 🏗️ feat: Update Role.spec.js to improve imports and enhance test structure * 🏗️ feat: Update access control logic to ensure proper permission checks in role handling * 🏗️ chore: Bump versions for librechat-data-provider to 0.7.75 and @librechat/data-schemas to 0.0.6 * 🏗️ feat: Improve role permissions handling by ensuring defaults are applied correctly * 🏗️ feat: Update role permissions schema to comment out unused SHARE permission * 🏗️ chore: Bump version of librechat-data-provider to 0.7.77 and remove unused groups field from IUser interface * 🏗️ chore: Downgrade version of librechat-data-provider to 0.7.76 * 🔧 chore: Bump versions for librechat-data-provider to 0.7.77 and data-schemas to 0.0.6 * 🏗️ chore: Update version of librechat-data-provider to 0.7.789 --------- Co-authored-by: Danny Avila <danny@librechat.ai>
78 lines
2.6 KiB
JavaScript
78 lines
2.6 KiB
JavaScript
const { getRoleByName } = require('~/models/Role');
|
|
const { logger } = require('~/config');
|
|
|
|
/**
|
|
* Core function to check if a user has one or more required permissions
|
|
*
|
|
* @param {object} user - The user object
|
|
* @param {PermissionTypes} permissionType - The type of permission to check
|
|
* @param {Permissions[]} permissions - The list of specific permissions to check
|
|
* @param {Record<Permissions, string[]>} [bodyProps] - An optional object where keys are permissions and values are arrays of properties to check
|
|
* @param {object} [checkObject] - The object to check properties against
|
|
* @returns {Promise<boolean>} Whether the user has the required permissions
|
|
*/
|
|
const checkAccess = async (user, permissionType, permissions, bodyProps = {}, checkObject = {}) => {
|
|
if (!user) {
|
|
return false;
|
|
}
|
|
|
|
const role = await getRoleByName(user.role);
|
|
if (role && role.permissions && role.permissions[permissionType]) {
|
|
const hasAnyPermission = permissions.some((permission) => {
|
|
if (role.permissions[permissionType][permission]) {
|
|
return true;
|
|
}
|
|
|
|
if (bodyProps[permission] && checkObject) {
|
|
return bodyProps[permission].some((prop) =>
|
|
Object.prototype.hasOwnProperty.call(checkObject, prop),
|
|
);
|
|
}
|
|
|
|
return false;
|
|
});
|
|
|
|
return hasAnyPermission;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Middleware to check if a user has one or more required permissions, optionally based on `req.body` properties.
|
|
*
|
|
* @param {PermissionTypes} permissionType - The type of permission to check.
|
|
* @param {Permissions[]} permissions - The list of specific permissions to check.
|
|
* @param {Record<Permissions, string[]>} [bodyProps] - An optional object where keys are permissions and values are arrays of `req.body` properties to check.
|
|
* @returns {(req: ServerRequest, res: ServerResponse, next: NextFunction) => Promise<void>} Express middleware function.
|
|
*/
|
|
const generateCheckAccess = (permissionType, permissions, bodyProps = {}) => {
|
|
return async (req, res, next) => {
|
|
try {
|
|
const hasAccess = await checkAccess(
|
|
req.user,
|
|
permissionType,
|
|
permissions,
|
|
bodyProps,
|
|
req.body,
|
|
);
|
|
|
|
if (hasAccess) {
|
|
return next();
|
|
}
|
|
|
|
logger.warn(
|
|
`[${permissionType}] Forbidden: Insufficient permissions for User ${req.user.id}: ${permissions.join(', ')}`,
|
|
);
|
|
return res.status(403).json({ message: 'Forbidden: Insufficient permissions' });
|
|
} catch (error) {
|
|
logger.error(error);
|
|
return res.status(500).json({ message: `Server error: ${error.message}` });
|
|
}
|
|
};
|
|
};
|
|
|
|
module.exports = {
|
|
checkAccess,
|
|
generateCheckAccess,
|
|
};
|