e115934061
Publish `@librechat/data-schemas` to NPM / pack (push) Failing after 8s
Publish `@librechat/client` to NPM / pack (push) Failing after 0s
GitNexus Index / index (push) Failing after 1s
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Has been skipped
Sync Helm Chart Tags / Sync chart tags (push) Failing after 2s
Publish `librechat-data-provider` to NPM / pack (push) Failing after 1s
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Failing after 1s
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Failing after 0s
Sync Helm Chart Tags / Ignore non-main push (push) Has been skipped
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Failing after 1s
Publish `@librechat/client` to NPM / publish-npm (push) Has been cancelled
Publish `librechat-data-provider` to NPM / publish-npm (push) Has been cancelled
GitNexus Index / post-index (push) Has been cancelled
Publish `@librechat/data-schemas` to NPM / publish-npm (push) Has been cancelled
107 lines
3.2 KiB
JavaScript
107 lines
3.2 KiB
JavaScript
const { logger } = require('@librechat/data-schemas');
|
|
const { PrincipalType, PermissionTypes, Permissions } = require('librechat-data-provider');
|
|
const { getRoleByName } = require('~/models');
|
|
|
|
const VALID_PRINCIPAL_TYPES = new Set([
|
|
PrincipalType.USER,
|
|
PrincipalType.GROUP,
|
|
PrincipalType.ROLE,
|
|
]);
|
|
|
|
/**
|
|
* Middleware to check if user has permission to access people picker functionality.
|
|
* Validates requested principal types via `type` (singular) and `types` (comma-separated or array)
|
|
* query parameters against the caller's role permissions:
|
|
* - user: requires VIEW_USERS permission
|
|
* - group: requires VIEW_GROUPS permission
|
|
* - role: requires VIEW_ROLES permission
|
|
* - no type filter (mixed search): requires at least one of the above
|
|
*/
|
|
const checkPeoplePickerAccess = async (req, res, next) => {
|
|
try {
|
|
const user = req.user;
|
|
if (!user || !user.role) {
|
|
return res.status(401).json({
|
|
error: 'Unauthorized',
|
|
message: 'Authentication required',
|
|
});
|
|
}
|
|
|
|
const role = await getRoleByName(user.role);
|
|
if (!role || !role.permissions) {
|
|
return res.status(403).json({
|
|
error: 'Forbidden',
|
|
message: 'No permissions configured for user role',
|
|
});
|
|
}
|
|
|
|
const { type, types } = req.query;
|
|
const peoplePickerPerms = role.permissions[PermissionTypes.PEOPLE_PICKER] || {};
|
|
const canViewUsers = peoplePickerPerms[Permissions.VIEW_USERS] === true;
|
|
const canViewGroups = peoplePickerPerms[Permissions.VIEW_GROUPS] === true;
|
|
const canViewRoles = peoplePickerPerms[Permissions.VIEW_ROLES] === true;
|
|
|
|
const permissionChecks = {
|
|
[PrincipalType.USER]: {
|
|
hasPermission: canViewUsers,
|
|
message: 'Insufficient permissions to search for users',
|
|
},
|
|
[PrincipalType.GROUP]: {
|
|
hasPermission: canViewGroups,
|
|
message: 'Insufficient permissions to search for groups',
|
|
},
|
|
[PrincipalType.ROLE]: {
|
|
hasPermission: canViewRoles,
|
|
message: 'Insufficient permissions to search for roles',
|
|
},
|
|
};
|
|
|
|
const requestedTypes = new Set();
|
|
|
|
if (type && VALID_PRINCIPAL_TYPES.has(type)) {
|
|
requestedTypes.add(type);
|
|
}
|
|
|
|
if (types) {
|
|
const typesArray = Array.isArray(types) ? types : types.split(',');
|
|
for (const t of typesArray) {
|
|
if (VALID_PRINCIPAL_TYPES.has(t)) {
|
|
requestedTypes.add(t);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const requested of requestedTypes) {
|
|
const check = permissionChecks[requested];
|
|
if (!check.hasPermission) {
|
|
return res.status(403).json({
|
|
error: 'Forbidden',
|
|
message: check.message,
|
|
});
|
|
}
|
|
}
|
|
|
|
if (requestedTypes.size === 0 && !canViewUsers && !canViewGroups && !canViewRoles) {
|
|
return res.status(403).json({
|
|
error: 'Forbidden',
|
|
message: 'Insufficient permissions to search for users, groups, or roles',
|
|
});
|
|
}
|
|
|
|
next();
|
|
} catch (error) {
|
|
logger.error(
|
|
`[checkPeoplePickerAccess][${req.user?.id}] error for type=${req.query.type}, types=${req.query.types}`,
|
|
error,
|
|
);
|
|
return res.status(500).json({
|
|
error: 'Internal Server Error',
|
|
message: 'Failed to check permissions',
|
|
});
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
checkPeoplePickerAccess,
|
|
};
|