/** * API Authentication Middleware * Provides API key validation for protected endpoints */ /** * Middleware function to validate API key * Supports both Bearer token and X-API-Key header * @param {Object} req - Express request object * @param {Object} res - Express response object * @param {Function} next - Express next function * @returns {void} */ function apiKeyAuth(req, res, next) { // Check if authentication is disabled via environment variable const authDisabled = process.env.DISABLE_API_AUTH === 'true'; if (authDisabled) { return next(); } // Extract API key from various sources let apiKey = null; // 1. Check Authorization header for Bearer token if (req.headers.authorization && req.headers.authorization.startsWith('Bearer ')) { apiKey = req.headers.authorization.substring(7); // Remove 'Bearer ' prefix } // 2. Check X-API-Key header else if (req.headers['x-api-key']) { apiKey = req.headers['x-api-key']; } // 3. Check query parameter (as fallback, though less secure) else if (req.query && req.query.api_key) { apiKey = req.query.api_key; } // Validate the API key if (!apiKey) { return res.status(401).json({ error: 'Unauthorized', message: 'API key is required' }); } // Get allowed API keys from environment variable const allowedApiKeys = process.env.ALLOWED_API_KEYS; if (!allowedApiKeys) { console.error('ALLOWED_API_KEYS environment variable is not set'); return res.status(500).json({ error: 'Server configuration error', message: 'API authentication is not properly configured' }); } // Split the allowed keys by comma and trim whitespace const validApiKeys = allowedApiKeys.split(',').map(key => key.trim()); // Check if the provided API key is in the allowed list if (!validApiKeys.includes(apiKey)) { return res.status(401).json({ error: 'Unauthorized', message: 'Invalid API key' }); } // API key is valid, proceed to the next middleware/route handler next(); } export default apiKeyAuth;