mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-04-03 22:37:20 +02:00
fix: exact-case reserved name check, consistent validation, cleaner createRole
- Remove .toLowerCase() from reserved name check so only exact matches (members, permissions) are rejected, not legitimate names like "Members" - Extract trimmed const in validateRoleName for consistent validation - Add control char check to validateNameParam for parity with body validation - Build createRole roleData conditionally to avoid passing description: undefined - Expand deleteRoleByName JSDoc documenting self-healing design and no-op trade-off
This commit is contained in:
parent
b590951190
commit
1fb205ef54
2 changed files with 21 additions and 10 deletions
|
|
@ -19,6 +19,9 @@ function validateNameParam(name: string): string | null {
|
|||
if (name.length > MAX_NAME_LENGTH) {
|
||||
return `name must not exceed ${MAX_NAME_LENGTH} characters`;
|
||||
}
|
||||
if (CONTROL_CHAR_RE.test(name)) {
|
||||
return 'name contains invalid characters';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -29,13 +32,14 @@ function validateRoleName(name: unknown, required: boolean): string | null {
|
|||
if (typeof name !== 'string' || !name.trim()) {
|
||||
return required ? 'name is required' : 'name must be a non-empty string';
|
||||
}
|
||||
if (name.trim().length > MAX_NAME_LENGTH) {
|
||||
const trimmed = name.trim();
|
||||
if (trimmed.length > MAX_NAME_LENGTH) {
|
||||
return `name must not exceed ${MAX_NAME_LENGTH} characters`;
|
||||
}
|
||||
if (CONTROL_CHAR_RE.test(name)) {
|
||||
if (CONTROL_CHAR_RE.test(trimmed)) {
|
||||
return 'name contains invalid characters';
|
||||
}
|
||||
if (RESERVED_ROLE_NAMES.has(name.trim().toLowerCase())) {
|
||||
if (RESERVED_ROLE_NAMES.has(trimmed)) {
|
||||
return 'name is a reserved path segment';
|
||||
}
|
||||
return null;
|
||||
|
|
@ -154,11 +158,14 @@ export function createAdminRolesHandlers(deps: AdminRolesDeps) {
|
|||
) {
|
||||
return res.status(400).json({ error: 'permissions must be an object' });
|
||||
}
|
||||
const role = await createRoleByName({
|
||||
const roleData: Partial<IRole> = {
|
||||
name: (name as string).trim(),
|
||||
description,
|
||||
permissions: permissions ?? {},
|
||||
});
|
||||
};
|
||||
if (description !== undefined) {
|
||||
roleData.description = description;
|
||||
}
|
||||
const role = await createRoleByName(roleData);
|
||||
return res.status(201).json({ role });
|
||||
} catch (error) {
|
||||
logger.error('[adminRoles] createRole error:', error);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue