Skip to main content
Glama
auth.ts4.19 kB
import { logMessage } from "../utils/logs.js"; import { AuthManager, AuthResult } from "./types.js"; import { LocalKeyManager } from "./local-key-manager.js"; import { SupabaseAuthManager } from "./supabase-auth-manager.js"; let _authManager: AuthManager | null = null; function getAuthManager(): AuthManager { if (!_authManager) { _authManager = process.env.NEXT_PUBLIC_SUPABASE_URL ? new SupabaseAuthManager() : new LocalKeyManager(); } return _authManager; } export const _resetAuthManager = (manager: AuthManager | null = null) => { _authManager = manager; }; export async function validateToken(token: string | undefined): Promise<AuthResult> { if (!token) { return { success: false, message: 'No token provided', orgId: '', } } // Authenticate using the appropriate manager (handles both JWT and API keys) const authResult = await getAuthManager().authenticate(token); return { ...authResult, orgId: authResult.orgId || '', message: authResult.success ? 'Authentication successful' : 'Authentication failed' } } // ============================================================================ // EXPRESS-SPECIFIC AUTHENTICATION MIDDLEWARE // ============================================================================ // HTTP Middleware for Express export const authMiddleware = async (req: any, res: any, next: any) => { // Skip authentication for health check if (req.path === '/health') return res.status(200).send('OK'); const token = extractTokenFromExpressRequest(req); const authResult = await validateToken(token); // If authentication fails, return 401 error if (!authResult.success) { logMessage('warn', `Authentication failed for token: ${token}`); return res.status(401).send(getAuthErrorHTML(token)); } // Add orgId to request object req.orgId = authResult.orgId; req.headers["orgId"] = authResult.orgId; req.authInfo = { token: token, clientId: authResult.orgId, userId: authResult.userId, orgName: authResult.orgName, orgRole: authResult.orgRole }; return next(); }; // Extract token from various sources export const extractTokenFromExpressRequest = (source: { headers?: any, query?: any } | { connectionParams?: any, extra?: any }): string | undefined => { if ('headers' in source) { // HTTP request return source.headers?.authorization?.split(" ")?.[1]?.trim() || source.query?.token; } else if ('connectionParams' in source) { // WebSocket connection return source.connectionParams?.Authorization?.split(" ")?.[1]?.trim() || source.extra?.request?.url?.split("token=")?.[1]?.split("&")?.[0] || source.extra?.request?.url?.split("superglueApiKey=")?.[1]?.split("&")?.[0]; } return undefined; }; // Helper Functions function getAuthErrorHTML(token: string | undefined) { return ` <html> <body style="display: flex; justify-content: center; align-items: center; height: 100vh; font-family: sans-serif;"> <div style="text-align: center;"> <h1>🔐 Authentication ${token ? 'Failed' : 'Required'}</h1> <p>Please provide a valid auth token via:</p> <ul style="list-style: none; padding: 0;"> <li>Authorization header: <code>Authorization: Bearer TOKEN</code></li> <li>Query parameter: <code>?token=TOKEN</code></li> <li>WebSocket connectionParams: <code>{ "Authorization": "Bearer TOKEN" }</code></li> </ul> </div> </body> </html> `; } // ============================================================================ // FASTIFY-SPECIFIC AUTHENTICATION // ============================================================================ // Extract token from Fastify request export const extractTokenFromFastifyRequest = (request: any): string | undefined => { // Check Authorization header const authHeader = request.headers.authorization; if (authHeader && authHeader.startsWith('Bearer ')) { return authHeader.split(' ')[1]?.trim(); } // Check query parameter if (request.query?.token) { return request.query.token; } return undefined; };

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/superglue-ai/superglue'

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