UNPKG

jobnimbus-mcp-client

Version:

JobNimbus MCP Client - Connect Claude Desktop to remote JobNimbus MCP server

76 lines 2.68 kB
/** * API Key Extractor Middleware * Extracts JobNimbus API key from request headers * NEVER stores the key - only passes it through request context */ import { UnauthorizedError, ValidationError } from '../utils/errors.js'; import logger from '../utils/logger.js'; const API_KEY_HEADER = 'x-jobnimbus-api-key'; const INSTANCE_HEADER = 'x-jobnimbus-instance'; /** * Validate API key format */ function isValidApiKeyFormat(apiKey) { // Basic validation - length and characters // JobNimbus API keys can be 16-26 characters if (apiKey.length < 16 || apiKey.length > 256) { return false; } // Only alphanumeric and some special chars return /^[A-Za-z0-9\-_]+$/.test(apiKey); } /** * Extract and validate API key from request */ export const extractApiKey = async (req, res, next) => { try { // Extract API key from header const apiKey = req.headers[API_KEY_HEADER]; if (!apiKey) { throw new UnauthorizedError('API key required in X-JobNimbus-Api-Key header'); } // Validate format if (!isValidApiKeyFormat(apiKey)) { throw new ValidationError('Invalid API key format'); } // Extract instance (stamford or guilford) const instance = req.headers[INSTANCE_HEADER]; if (instance && !['stamford', 'guilford'].includes(instance)) { throw new ValidationError('Invalid instance. Must be "stamford" or "guilford"'); } // Generate client ID for rate limiting (hash of IP + user agent) const clientId = generateClientId(req); // Attach to request context (TEMPORARY - will be cleared) req.apiKey = apiKey; req.instance = instance || 'stamford'; req.clientId = clientId; // Log request (without API key) logger.info('API request received', { clientId, instance: req.instance, path: req.path, method: req.method, }); // Clear API key from memory after response res.on('finish', () => { if (req.apiKey) { req.apiKey = undefined; delete req.apiKey; } }); next(); } catch (error) { next(error); } }; /** * Generate unique client ID for rate limiting */ function generateClientId(req) { const ip = req.ip || req.socket.remoteAddress || 'unknown'; const userAgent = req.headers['user-agent'] || 'unknown'; // Simple hash (in production, use crypto.createHash) return Buffer.from(`${ip}:${userAgent}`).toString('base64').substring(0, 16); } //# sourceMappingURL=apiKeyExtractor.js.map