mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-03-02 22:30:18 +01:00
141 lines
4.4 KiB
TypeScript
141 lines
4.4 KiB
TypeScript
|
|
import { logger } from '@librechat/data-schemas';
|
||
|
|
import { SystemRoles } from 'librechat-data-provider';
|
||
|
|
import { requireAdmin } from './admin';
|
||
|
|
import type { Response } from 'express';
|
||
|
|
import type { ServerRequest } from '~/types/http';
|
||
|
|
|
||
|
|
jest.mock('@librechat/data-schemas', () => ({
|
||
|
|
...jest.requireActual('@librechat/data-schemas'),
|
||
|
|
logger: {
|
||
|
|
warn: jest.fn(),
|
||
|
|
debug: jest.fn(),
|
||
|
|
},
|
||
|
|
}));
|
||
|
|
|
||
|
|
describe('requireAdmin middleware', () => {
|
||
|
|
let mockReq: Partial<ServerRequest>;
|
||
|
|
let mockRes: Partial<Response>;
|
||
|
|
let mockNext: jest.Mock;
|
||
|
|
let jsonMock: jest.Mock;
|
||
|
|
let statusMock: jest.Mock;
|
||
|
|
|
||
|
|
beforeEach(() => {
|
||
|
|
jsonMock = jest.fn();
|
||
|
|
statusMock = jest.fn().mockReturnValue({ json: jsonMock });
|
||
|
|
|
||
|
|
mockReq = {};
|
||
|
|
mockRes = {
|
||
|
|
status: statusMock,
|
||
|
|
};
|
||
|
|
mockNext = jest.fn();
|
||
|
|
|
||
|
|
(logger.warn as jest.Mock).mockClear();
|
||
|
|
(logger.debug as jest.Mock).mockClear();
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('when no user is present', () => {
|
||
|
|
it('should return 401 with AUTHENTICATION_REQUIRED error', () => {
|
||
|
|
requireAdmin(mockReq as ServerRequest, mockRes as Response, mockNext);
|
||
|
|
|
||
|
|
expect(statusMock).toHaveBeenCalledWith(401);
|
||
|
|
expect(jsonMock).toHaveBeenCalledWith({
|
||
|
|
error: 'Authentication required',
|
||
|
|
error_code: 'AUTHENTICATION_REQUIRED',
|
||
|
|
});
|
||
|
|
expect(mockNext).not.toHaveBeenCalled();
|
||
|
|
expect(logger.warn).toHaveBeenCalledWith('[requireAdmin] No user found in request');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should return 401 when user is undefined', () => {
|
||
|
|
mockReq.user = undefined;
|
||
|
|
|
||
|
|
requireAdmin(mockReq as ServerRequest, mockRes as Response, mockNext);
|
||
|
|
|
||
|
|
expect(statusMock).toHaveBeenCalledWith(401);
|
||
|
|
expect(jsonMock).toHaveBeenCalledWith({
|
||
|
|
error: 'Authentication required',
|
||
|
|
error_code: 'AUTHENTICATION_REQUIRED',
|
||
|
|
});
|
||
|
|
expect(mockNext).not.toHaveBeenCalled();
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('when user does not have admin role', () => {
|
||
|
|
it('should return 403 when user has no role property', () => {
|
||
|
|
mockReq.user = { email: 'user@test.com' } as ServerRequest['user'];
|
||
|
|
|
||
|
|
requireAdmin(mockReq as ServerRequest, mockRes as Response, mockNext);
|
||
|
|
|
||
|
|
expect(statusMock).toHaveBeenCalledWith(403);
|
||
|
|
expect(jsonMock).toHaveBeenCalledWith({
|
||
|
|
error: 'Access denied: Admin privileges required',
|
||
|
|
error_code: 'ADMIN_REQUIRED',
|
||
|
|
});
|
||
|
|
expect(mockNext).not.toHaveBeenCalled();
|
||
|
|
expect(logger.debug).toHaveBeenCalledWith(
|
||
|
|
'[requireAdmin] Access denied for non-admin user: user@test.com',
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should return 403 when user has USER role', () => {
|
||
|
|
mockReq.user = {
|
||
|
|
email: 'user@test.com',
|
||
|
|
role: SystemRoles.USER,
|
||
|
|
} as ServerRequest['user'];
|
||
|
|
|
||
|
|
requireAdmin(mockReq as ServerRequest, mockRes as Response, mockNext);
|
||
|
|
|
||
|
|
expect(statusMock).toHaveBeenCalledWith(403);
|
||
|
|
expect(jsonMock).toHaveBeenCalledWith({
|
||
|
|
error: 'Access denied: Admin privileges required',
|
||
|
|
error_code: 'ADMIN_REQUIRED',
|
||
|
|
});
|
||
|
|
expect(mockNext).not.toHaveBeenCalled();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should return 403 when user has empty string role', () => {
|
||
|
|
mockReq.user = {
|
||
|
|
email: 'user@test.com',
|
||
|
|
role: '',
|
||
|
|
} as ServerRequest['user'];
|
||
|
|
|
||
|
|
requireAdmin(mockReq as ServerRequest, mockRes as Response, mockNext);
|
||
|
|
|
||
|
|
expect(statusMock).toHaveBeenCalledWith(403);
|
||
|
|
expect(jsonMock).toHaveBeenCalledWith({
|
||
|
|
error: 'Access denied: Admin privileges required',
|
||
|
|
error_code: 'ADMIN_REQUIRED',
|
||
|
|
});
|
||
|
|
expect(mockNext).not.toHaveBeenCalled();
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('when user has admin role', () => {
|
||
|
|
it('should call next() and not send response', () => {
|
||
|
|
mockReq.user = {
|
||
|
|
email: 'admin@test.com',
|
||
|
|
role: SystemRoles.ADMIN,
|
||
|
|
} as ServerRequest['user'];
|
||
|
|
|
||
|
|
requireAdmin(mockReq as ServerRequest, mockRes as Response, mockNext);
|
||
|
|
|
||
|
|
expect(mockNext).toHaveBeenCalledTimes(1);
|
||
|
|
expect(mockNext).toHaveBeenCalledWith();
|
||
|
|
expect(statusMock).not.toHaveBeenCalled();
|
||
|
|
expect(jsonMock).not.toHaveBeenCalled();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should not log any warnings or debug messages for admin users', () => {
|
||
|
|
mockReq.user = {
|
||
|
|
email: 'admin@test.com',
|
||
|
|
role: SystemRoles.ADMIN,
|
||
|
|
} as ServerRequest['user'];
|
||
|
|
|
||
|
|
requireAdmin(mockReq as ServerRequest, mockRes as Response, mockNext);
|
||
|
|
|
||
|
|
expect(logger.warn).not.toHaveBeenCalled();
|
||
|
|
expect(logger.debug).not.toHaveBeenCalled();
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|