feat: implement CORS support and update API_URL in environment configuration
This commit is contained in:
@@ -12,6 +12,21 @@ const vState = process.env.VERSION_STATE;
|
|||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
app.use(parser());
|
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) => {
|
app.get('/', (req, res) => {
|
||||||
res.redirect('/health');
|
res.redirect('/health');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ VERSION_STATE=pre-release
|
|||||||
REALTIME_URL=
|
REALTIME_URL=
|
||||||
REALTIME_WS_URL=
|
REALTIME_WS_URL=
|
||||||
|
|
||||||
|
API_URL=
|
||||||
|
|
||||||
JWT_SECRET=
|
JWT_SECRET=
|
||||||
AUTH_LOGIN_URL=
|
AUTH_LOGIN_URL=
|
||||||
COOKIE_DOMAIN=
|
COOKIE_DOMAIN=
|
||||||
@@ -154,7 +154,7 @@ const HAS_DESC = { weather: true, data: false, logs: true };
|
|||||||
// ========== API helpers ==========
|
// ========== API helpers ==========
|
||||||
|
|
||||||
async function api(method, path, body) {
|
async function api(method, path, body) {
|
||||||
const opts = { method, headers: {} };
|
const opts = { method, headers: {}, credentials: 'include' };
|
||||||
if (body) {
|
if (body) {
|
||||||
opts.headers['Content-Type'] = 'application/json';
|
opts.headers['Content-Type'] = 'application/json';
|
||||||
opts.body = JSON.stringify(body);
|
opts.body = JSON.stringify(body);
|
||||||
|
|||||||
@@ -108,17 +108,21 @@ function handleSensorConnection(ws) {
|
|||||||
try {
|
try {
|
||||||
const packet = decode(data);
|
const packet = decode(data);
|
||||||
|
|
||||||
// Messaggio di inizializzazione con versioni rulesets
|
// Messaggio di inizializzazione con versioni rulesets e uptime
|
||||||
if (packet._t === 'init') {
|
if (packet._t === 'init') {
|
||||||
ws.rulesVersions = packet.rules || {};
|
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
|
// Salva in Redis
|
||||||
const rulesFields = [];
|
const metaFields = [];
|
||||||
for (const [type, ver] of Object.entries(ws.rulesVersions)) {
|
for (const [type, ver] of Object.entries(ws.rulesVersions)) {
|
||||||
rulesFields.push(`rules_${type}`, ver);
|
metaFields.push(`rules_${type}`, ver);
|
||||||
}
|
}
|
||||||
if (rulesFields.length > 0) {
|
if (ws.sensorUptime != null) {
|
||||||
hset(`sensors:${sensorName}`, ...rulesFields);
|
metaFields.push('uptime', String(ws.sensorUptime));
|
||||||
|
}
|
||||||
|
if (metaFields.length > 0) {
|
||||||
|
hset(`sensors:${sensorName}`, ...metaFields);
|
||||||
}
|
}
|
||||||
return; // non scrivere su InfluxDB
|
return; // non scrivere su InfluxDB
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user