express-insights
Version:
Production-ready Express middleware for backend health monitoring with metrics, HTML/JSON output, authentication, and service checks.
55 lines (45 loc) • 1.78 kB
JavaScript
const validator = require('validator');
function validateAllowedOrigins(origins, logger) {
let allowed = [];
if (!origins && process.env.ALLOWED_ORIGINS) {
allowed = process.env.ALLOWED_ORIGINS.split(',').map((o) => o.trim());
} else if (typeof origins === 'string') {
allowed = [origins];
} else if (Array.isArray(origins)) {
allowed = origins;
}
const validOrigins = allowed.filter((origin) => {
if (!origin) return false;
const isValid = validator.isURL(origin, { require_protocol: true });
if (!isValid) logger.warn(`Invalid CORS origin: ${origin}`);
return isValid;
});
if (validOrigins.length === 0 && allowed.length > 0) {
throw new Error('No valid CORS origins provided');
}
return validOrigins;
}
function applyCorsHeaders(req, res, corsConfig, logger) {
if (!corsConfig) return true;
if (corsConfig === true) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
return true;
}
const allowedOrigins = validateAllowedOrigins(corsConfig.allowedOrigins, logger);
const origin = req.get('Origin');
if (!origin) {
logger.warn('No Origin header provided in request', { ip: req.ip });
return true;
}
if (allowedOrigins.includes(origin)) {
res.header('Access-Control-Allow-Origin', origin);
res.header('Access-Control-Allow-Methods', 'GET');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
return true;
}
logger.warn(`Unauthorized CORS origin: ${origin}`, { ip: req.ip });
return false;
}
module.exports = { validateAllowedOrigins, applyCorsHeaders };