Skip to main content
Glama
auth-middleware.test.ts7.28 kB
import { describe, it, expect, jest, beforeEach } from '@jest/globals'; import { Request, Response, NextFunction } from 'express'; import { AuthProvider, AuthResult } from '../../src/server/auth/auth-provider.js'; import { createAuthMiddleware } from '../../src/server/auth/auth-middleware.js'; // Mock auth provider class MockAuthProvider implements AuthProvider { private tokenValidResult: AuthResult = { success: true, userId: 'user1', roles: ['user'] }; private tokenInvalidResult: AuthResult = { success: false, error: 'Invalid token' }; private shouldThrow: boolean = false; async authenticate(credentials: any): Promise<AuthResult> { return this.tokenValidResult; } async validateToken(token: string): Promise<AuthResult> { if (this.shouldThrow) { throw new Error('Auth error'); } if (token === 'valid-token') { return this.tokenValidResult; } return this.tokenInvalidResult; } setThrow(shouldThrow: boolean): void { this.shouldThrow = shouldThrow; } } // Mock request, response, and next function function createMockRequestResponse() { const req: Partial<Request> = { headers: {}, path: '/test', query: {}, cookies: {}, auth: undefined, }; const res: Partial<Response> = { status: jest.fn().mockReturnThis(), json: jest.fn().mockReturnThis(), setHeader: jest.fn().mockReturnThis(), end: jest.fn().mockReturnThis(), }; const next: NextFunction = jest.fn(); return { req: req as Request, res: res as Response, next }; } describe('Auth Middleware', () => { let authProvider: MockAuthProvider; let middleware: (req: Request, res: Response, next: NextFunction) => Promise<void | Response>; beforeEach(() => { authProvider = new MockAuthProvider(); middleware = createAuthMiddleware(authProvider); }); it('should pass authentication with valid Bearer token', async () => { const { req, res, next } = createMockRequestResponse(); req.headers.authorization = 'Bearer valid-token'; await middleware(req, res, next); expect(next).toHaveBeenCalled(); expect(req.auth).toEqual({ authenticated: true, userId: 'user1', roles: ['user'], }); }); it('should pass authentication with valid query token', async () => { const { req, res, next } = createMockRequestResponse(); req.query.token = 'valid-token'; await middleware(req, res, next); expect(next).toHaveBeenCalled(); expect(req.auth).toEqual({ authenticated: true, userId: 'user1', roles: ['user'], }); }); it('should pass authentication with valid cookie token', async () => { const { req, res, next } = createMockRequestResponse(); req.cookies = { token: 'valid-token' }; await middleware(req, res, next); expect(next).toHaveBeenCalled(); expect(req.auth).toEqual({ authenticated: true, userId: 'user1', roles: ['user'], }); }); it('should reject authentication with invalid token', async () => { const { req, res, next } = createMockRequestResponse(); req.headers.authorization = 'Bearer invalid-token'; await middleware(req, res, next); expect(next).not.toHaveBeenCalled(); expect(res.status).toHaveBeenCalledWith(401); expect(res.json).toHaveBeenCalledWith({ error: 'Invalid token' }); }); it('should bypass authentication for health endpoint', async () => { const { req, res, next } = createMockRequestResponse(); req.path = '/health'; await middleware(req, res, next); expect(next).toHaveBeenCalled(); expect(req.auth).toEqual({ authenticated: true, userId: 'system', roles: ['system'], }); }); it('should bypass authentication for debug endpoints in development mode', async () => { // Need to recreate middleware with development environment process.env.NODE_ENV = 'development'; const devMiddleware = createAuthMiddleware(authProvider); const { req, res, next } = createMockRequestResponse(); req.path = '/debug/status'; await devMiddleware(req, res, next); expect(next).toHaveBeenCalled(); expect(req.auth).toEqual({ authenticated: true, userId: 'system', roles: ['system'], }); process.env.NODE_ENV = undefined; }); it('should not bypass authentication for debug endpoints in production mode', async () => { process.env.NODE_ENV = 'production'; // Re-create middleware with production environment const productionMiddleware = createAuthMiddleware(authProvider); const { req, res, next } = createMockRequestResponse(); req.path = '/debug/status'; req.headers.authorization = 'Bearer valid-token'; await productionMiddleware(req, res, next); // Should check authentication and pass through since we provided a valid token expect(next).toHaveBeenCalled(); expect(req.auth).toEqual({ authenticated: true, userId: 'user1', roles: ['user'], }); process.env.NODE_ENV = undefined; }); it('should require authentication for SSE endpoints', async () => { const { req, res, next } = createMockRequestResponse(); req.path = '/sse'; await middleware(req, res, next); // Should reject without a token expect(next).not.toHaveBeenCalled(); expect(res.status).toHaveBeenCalledWith(401); }); it('should handle auth errors', async () => { const { req, res, next } = createMockRequestResponse(); req.headers.authorization = 'Bearer valid-token'; authProvider.setThrow(true); await middleware(req, res, next); expect(next).not.toHaveBeenCalled(); expect(res.status).toHaveBeenCalledWith(500); expect(res.json).toHaveBeenCalledWith({ error: 'Authentication error' }); }); it('should reject when no token is provided', async () => { const { req, res, next } = createMockRequestResponse(); await middleware(req, res, next); expect(next).not.toHaveBeenCalled(); expect(res.status).toHaveBeenCalledWith(401); expect(res.json).toHaveBeenCalledWith({ error: 'Authentication required', message: 'Please provide a valid token via Bearer auth header or token query parameter', }); }); it('should handle CORS preflight requests when enabled', async () => { const corsMiddleware = createAuthMiddleware(authProvider, { enableCors: true }); const { req, res, next } = createMockRequestResponse(); req.method = 'OPTIONS'; await corsMiddleware(req, res, next); expect(next).not.toHaveBeenCalled(); expect(res.setHeader).toHaveBeenCalledWith('Access-Control-Allow-Origin', '*'); expect(res.setHeader).toHaveBeenCalledWith( 'Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization' ); expect(res.status).toHaveBeenCalledWith(200); expect(res.end).toHaveBeenCalled(); }); it('should not throw on failure when configured', async () => { const noThrowMiddleware = createAuthMiddleware(authProvider, { throwOnFailure: false }); const { req, res, next } = createMockRequestResponse(); await noThrowMiddleware(req, res, next); expect(next).toHaveBeenCalled(); expect(req.auth).toEqual({ authenticated: false, }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/metcalfc/atrax'

If you have feedback or need assistance with the MCP directory API, please join our Discord server