const fs = require('fs'); const path = require('path'); function parseDomains() { try { return { domains: JSON.parse(process.env.DOMAINS || '[]'), domainsAllowed: JSON.parse(process.env.DOMAINS_ALLOWED || '[]'), }; } catch { return { domains: [], domainsAllowed: [] }; } } function createCorsOptions(domains = [], domainsAllowed = [], isProduction = false) { // 1️⃣ Prepara la lista host ammessi (senza porta) const baseHosts = isProduction ? domains.flatMap((d) => [d.hostname, `api.${d.hostname}`, `test.${d.hostname}`, `testapi.${d.hostname}`]) : ['localhost', '127.0.0.1']; const extraHosts = domainsAllowed.map((d) => d.replace(/^https?:\/\//, '').split(':')[0]); const allowedHosts = [...new Set([...baseHosts, ...extraHosts])]; // 2️⃣ Funzione di validazione origin (accetta qualsiasi porta) const originValidator = (origin, callback) => { if (!origin) return callback(null, true); // Postman, curl, ecc. try { const url = new URL(origin); const host = url.hostname.toLowerCase(); if (allowedHosts.includes(host)) { // if (!isProduction) console.log(`✅ [CORS OK] ${origin}`); return callback(null, true); } if (!isProduction) { console.warn(`⚠️ [CORS DEV] origin non ammessa: ${origin} (host: ${host})`); return callback(null, true); // in dev permetti tutto } console.error(`❌ [CORS BLOCKED] ${origin}`); return callback(new Error(`CORS denied for origin ${origin}`), false); } catch (err) { console.error(`❌ [CORS ERROR] parsing origin: ${origin} -> ${err.message}`); return callback(new Error('CORS denied: invalid origin'), false); } }; // 3️⃣ Restituisce l’oggetto completo per il middleware cors() return { origin: originValidator, credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'], allowedHeaders: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization', 'x-auth', 'x-refrtok'], exposedHeaders: ['x-auth', 'x-refrtok'], maxAge: 86400, // 24 ore di caching per la preflight response preflightContinue: false, optionsSuccessStatus: 204, }; } async function getCredentials(hostname) { const key = fs.readFileSync(`/etc/letsencrypt/live/${hostname}/${process.env.PATH_CERT_KEY}`, 'utf8'); const cert = fs.readFileSync(`/etc/letsencrypt/live/${hostname}/${process.env.PATH_SERVER_CRT}`, 'utf8'); return { key, cert, secureProtocol: 'TLSv1_2_method', secureOptions: require('constants').SSL_OP_NO_SSLv3 | require('constants').SSL_OP_NO_TLSv1, }; } module.exports = { parseDomains, createCorsOptions, getCredentials };