mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-04-03 14:27:20 +02:00
fix: address convention violations in admin roles handlers
This commit is contained in:
parent
452333ee4d
commit
69093a5d99
3 changed files with 29 additions and 36 deletions
|
|
@ -11,21 +11,6 @@ const requireAdminAccess = requireCapability(SystemCapabilities.ACCESS_ADMIN);
|
|||
const requireReadRoles = requireCapability(SystemCapabilities.READ_ROLES);
|
||||
const requireManageRoles = requireCapability(SystemCapabilities.MANAGE_ROLES);
|
||||
|
||||
async function listUsersByRole(roleName) {
|
||||
const mongoose = require('mongoose');
|
||||
const User = mongoose.models.User;
|
||||
const users = await User.find({ role: roleName })
|
||||
.select('_id name email avatar createdAt')
|
||||
.lean();
|
||||
return users.map((u) => ({
|
||||
userId: String(u._id),
|
||||
name: u.name ?? String(u._id),
|
||||
email: u.email ?? '',
|
||||
avatarUrl: u.avatar,
|
||||
joinedAt: u.createdAt ? u.createdAt.toISOString() : new Date().toISOString(),
|
||||
}));
|
||||
}
|
||||
|
||||
const handlers = createAdminRolesHandlers({
|
||||
listRoles: db.listRoles,
|
||||
getRoleByName: db.getRoleByName,
|
||||
|
|
@ -35,8 +20,7 @@ const handlers = createAdminRolesHandlers({
|
|||
deleteRole: db.deleteRole,
|
||||
findUser: db.findUser,
|
||||
updateUser: db.updateUser,
|
||||
countUsers: db.countUsers,
|
||||
listUsersByRole,
|
||||
listUsersByRole: db.listUsersByRole,
|
||||
});
|
||||
|
||||
router.use(requireJwtAuth, requireAdminAccess);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { SystemRoles } from 'librechat-data-provider';
|
||||
import { logger } from '@librechat/data-schemas';
|
||||
import { SystemRoles } from 'librechat-data-provider';
|
||||
import type { IRole, IUser } from '@librechat/data-schemas';
|
||||
import type { ServerRequest } from '~/types/http';
|
||||
import type { FilterQuery } from 'mongoose';
|
||||
import type { Response } from 'express';
|
||||
import type { ServerRequest } from '~/types/http';
|
||||
|
||||
interface RoleNameParams {
|
||||
name: string;
|
||||
|
|
@ -23,10 +23,7 @@ interface AdminMember {
|
|||
|
||||
export interface AdminRolesDeps {
|
||||
listRoles: () => Promise<IRole[]>;
|
||||
getRoleByName: (
|
||||
name: string,
|
||||
fields?: string | string[] | null,
|
||||
) => Promise<IRole | null>;
|
||||
getRoleByName: (name: string, fields?: string | string[] | null) => Promise<IRole | null>;
|
||||
createRole: (roleData: Partial<IRole>) => Promise<IRole>;
|
||||
updateRoleByName: (name: string, updates: Partial<IRole>) => Promise<IRole | null>;
|
||||
updateAccessPermissions: (
|
||||
|
|
@ -40,8 +37,7 @@ export interface AdminRolesDeps {
|
|||
fields?: string | string[] | null,
|
||||
) => Promise<IUser | null>;
|
||||
updateUser: (userId: string, data: Partial<IUser>) => Promise<IUser | null>;
|
||||
countUsers: (filter?: FilterQuery<IUser>) => Promise<number>;
|
||||
listUsersByRole: (roleName: string) => Promise<AdminMember[]>;
|
||||
listUsersByRole: (roleName: string) => Promise<IUser[]>;
|
||||
}
|
||||
|
||||
export function createAdminRolesHandlers(deps: AdminRolesDeps) {
|
||||
|
|
@ -54,7 +50,7 @@ export function createAdminRolesHandlers(deps: AdminRolesDeps) {
|
|||
deleteRole,
|
||||
findUser,
|
||||
updateUser,
|
||||
countUsers,
|
||||
listUsersByRole,
|
||||
} = deps;
|
||||
|
||||
async function listRolesHandler(_req: ServerRequest, res: Response) {
|
||||
|
|
@ -83,7 +79,10 @@ export function createAdminRolesHandlers(deps: AdminRolesDeps) {
|
|||
|
||||
async function createRoleHandler(req: ServerRequest, res: Response) {
|
||||
try {
|
||||
const { name, permissions } = req.body as { name?: string; permissions?: IRole['permissions'] };
|
||||
const { name, permissions } = req.body as {
|
||||
name?: string;
|
||||
permissions?: IRole['permissions'];
|
||||
};
|
||||
if (!name || typeof name !== 'string' || !name.trim()) {
|
||||
return res.status(400).json({ error: 'name is required' });
|
||||
}
|
||||
|
|
@ -176,7 +175,14 @@ export function createAdminRolesHandlers(deps: AdminRolesDeps) {
|
|||
return res.status(404).json({ error: 'Role not found' });
|
||||
}
|
||||
|
||||
const members = await deps.listUsersByRole(name);
|
||||
const users = await listUsersByRole(name);
|
||||
const members: AdminMember[] = users.map((u) => ({
|
||||
userId: u._id?.toString() ?? '',
|
||||
name: u.name ?? u._id?.toString() ?? '',
|
||||
email: u.email ?? '',
|
||||
avatarUrl: u.avatar,
|
||||
joinedAt: u.createdAt ? u.createdAt.toISOString() : new Date().toISOString(),
|
||||
}));
|
||||
return res.status(200).json({ members });
|
||||
} catch (error) {
|
||||
logger.error('[adminRoles] getRoleMembers error:', error);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
permissionsSchema,
|
||||
removeNullishValues,
|
||||
} from 'librechat-data-provider';
|
||||
import type { IRole } from '~/types';
|
||||
import type { IRole, IUser } from '~/types';
|
||||
import logger from '~/config/winston';
|
||||
|
||||
export interface RoleDeps {
|
||||
|
|
@ -342,9 +342,7 @@ export function createRoleMethods(mongoose: typeof import('mongoose'), deps: Rol
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new custom role. Rejects names that match system roles.
|
||||
*/
|
||||
/** Rejects names that match system roles. */
|
||||
async function createRole(roleData: Partial<IRole>): Promise<IRole> {
|
||||
const { name } = roleData;
|
||||
if (!name || typeof name !== 'string' || !name.trim()) {
|
||||
|
|
@ -369,10 +367,7 @@ export function createRoleMethods(mongoose: typeof import('mongoose'), deps: Rol
|
|||
return role.toObject() as IRole;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a role by name. Guards against deleting system roles.
|
||||
* Reassigns all users with the deleted role back to USER.
|
||||
*/
|
||||
/** Guards against deleting system roles. Reassigns affected users back to USER. */
|
||||
async function deleteRole(roleName: string): Promise<IRole | null> {
|
||||
if (SystemRoles[roleName as keyof typeof SystemRoles]) {
|
||||
throw new Error(`Cannot delete system role: ${roleName}`);
|
||||
|
|
@ -390,6 +385,13 @@ export function createRoleMethods(mongoose: typeof import('mongoose'), deps: Rol
|
|||
return deleted as IRole | null;
|
||||
}
|
||||
|
||||
async function listUsersByRole(roleName: string): Promise<IUser[]> {
|
||||
const User = mongoose.models.User;
|
||||
return (await User.find({ role: roleName })
|
||||
.select('_id name email avatar createdAt')
|
||||
.lean()) as IUser[];
|
||||
}
|
||||
|
||||
return {
|
||||
listRoles,
|
||||
initializeRoles,
|
||||
|
|
@ -399,6 +401,7 @@ export function createRoleMethods(mongoose: typeof import('mongoose'), deps: Rol
|
|||
migrateRoleSchema,
|
||||
createRole,
|
||||
deleteRole,
|
||||
listUsersByRole,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue