From 370f911063dedcbf4d7f74a54f5595b624970b7a Mon Sep 17 00:00:00 2001 From: Giuseppe Raffa <77052701+sesee3@users.noreply.github.com> Date: Wed, 15 Apr 2026 23:40:08 +0200 Subject: [PATCH] feat: implement CORS support and update API_URL in environment configuration --- api/src/index.js | 15 +++++++++++++++ console/.env.example | 2 ++ console/src/pages/rulesets.html | 2 +- realtime/src/ws/handler.js | 16 ++++++++++------ 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/api/src/index.js b/api/src/index.js index 7b20121..885547b 100644 --- a/api/src/index.js +++ b/api/src/index.js @@ -12,6 +12,21 @@ const vState = process.env.VERSION_STATE; app.use(express.json()); app.use(parser()); +// CORS per permettere chiamate cross-origin dalla console +app.use((req, res, next) => { + const origin = req.headers.origin; + const allowed = (process.env.CORS_ORIGINS || '').split(',').map(s => s.trim()).filter(Boolean); + // Accetta origini nella whitelist, oppure tutte in dev + if (allowed.length === 0 || allowed.includes(origin)) { + res.setHeader('Access-Control-Allow-Origin', origin || '*'); + } + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key'); + res.setHeader('Access-Control-Allow-Credentials', 'true'); + if (req.method === 'OPTIONS') return res.sendStatus(204); + next(); +}); + app.get('/', (req, res) => { res.redirect('/health'); }); diff --git a/console/.env.example b/console/.env.example index 4528212..10e667b 100644 --- a/console/.env.example +++ b/console/.env.example @@ -7,6 +7,8 @@ VERSION_STATE=pre-release REALTIME_URL= REALTIME_WS_URL= +API_URL= + JWT_SECRET= AUTH_LOGIN_URL= COOKIE_DOMAIN= \ No newline at end of file diff --git a/console/src/pages/rulesets.html b/console/src/pages/rulesets.html index 97115be..508c215 100644 --- a/console/src/pages/rulesets.html +++ b/console/src/pages/rulesets.html @@ -154,7 +154,7 @@ const HAS_DESC = { weather: true, data: false, logs: true }; // ========== API helpers ========== async function api(method, path, body) { - const opts = { method, headers: {} }; + const opts = { method, headers: {}, credentials: 'include' }; if (body) { opts.headers['Content-Type'] = 'application/json'; opts.body = JSON.stringify(body); diff --git a/realtime/src/ws/handler.js b/realtime/src/ws/handler.js index 2f644d2..85670cd 100644 --- a/realtime/src/ws/handler.js +++ b/realtime/src/ws/handler.js @@ -108,17 +108,21 @@ function handleSensorConnection(ws) { try { const packet = decode(data); - // Messaggio di inizializzazione con versioni rulesets + // Messaggio di inizializzazione con versioni rulesets e uptime if (packet._t === 'init') { ws.rulesVersions = packet.rules || {}; - console.log(`[${sensorName}] Rules versions:`, ws.rulesVersions); + ws.sensorUptime = packet.uptime || null; + console.log(`[${sensorName}] Init — rules:`, ws.rulesVersions, '| uptime:', ws.sensorUptime); // Salva in Redis - const rulesFields = []; + const metaFields = []; for (const [type, ver] of Object.entries(ws.rulesVersions)) { - rulesFields.push(`rules_${type}`, ver); + metaFields.push(`rules_${type}`, ver); } - if (rulesFields.length > 0) { - hset(`sensors:${sensorName}`, ...rulesFields); + if (ws.sensorUptime != null) { + metaFields.push('uptime', String(ws.sensorUptime)); + } + if (metaFields.length > 0) { + hset(`sensors:${sensorName}`, ...metaFields); } return; // non scrivere su InfluxDB }