refactor: reorganize auth routes by separating view and API endpoints. Added some layer security to the most private apis

This commit is contained in:
Giuseppe Raffa
2026-04-04 19:21:12 +02:00
parent 07673586c2
commit a07abbfeea
6 changed files with 265 additions and 41 deletions

View File

@@ -1,12 +1,42 @@
const crypto = require('crypto');
const API_KEY = process.env.INTERNAL_API_KEY;
/**
* Middleware di autenticazione per servizi interni (container-to-container).
* Verifica l'header 'x-internal-api-key' contro INTERNAL_API_KEY nell'env.
*
* SICUREZZA:
* - Se INTERNAL_API_KEY non è configurata, TUTTE le richieste vengono rifiutate
* - Usa timingSafeEqual per prevenire attacchi timing side-channel
*/
const internalAuth = (req, res, next) => {
const internalToken = req.headers['x-internal-api-key'];
if (internalToken === API_KEY) {
req.user = { id: 'system', role: 'internal_service' };
return next();
// Se la chiave non è configurata nel server, blocca tutto
if (!API_KEY) {
console.error('[SECURITY] INTERNAL_API_KEY absent! All internal requests blocked.');
return res.status(503).json({ error: 'Service not configured correctly' });
}
return res.status(403).json({ error: 'Accesso negato: Richiesta interna non autorizzata' });
const internalToken = req.headers['x-internal-api-key'];
if (!internalToken || typeof internalToken !== 'string') {
return res.status(403).json({ error: 'unauthorized' });
}
// Confronto timing-safe per prevenire timing attacks
try {
const tokenBuffer = Buffer.from(internalToken, 'utf8');
const keyBuffer = Buffer.from(API_KEY, 'utf8');
if (tokenBuffer.length !== keyBuffer.length || !crypto.timingSafeEqual(tokenBuffer, keyBuffer)) {
return res.status(403).json({ error: 'Accesso negato' });
}
} catch {
return res.status(403).json({ error: 'Accesso negato' });
}
req.user = { id: 'system', role: 'internal_service' };
return next();
};
module.exports = internalAuth;

View File

@@ -1,10 +1,21 @@
const jwt = require('../tools/jwt');
/**
* Middleware di autenticazione per utenti finali.
* Verifica il JWT dal cookie 'auth_token' o dall'header 'Authorization: Bearer <token>'.
*
* Se valido, inietta req.user con { user_id, username, session_id }.
*/
const userAuth = (req, res, next) => {
const token = (req.cookies && req.cookies.auth_token) || jwt.getToken(req.headers['authorization']);
if (!token) {
return res.status(401).json({ error: 'Accesso negato: Token utente mancante' });
if (!token || typeof token !== 'string') {
return res.status(401).json({ error: 'Accesso negato: token mancante' });
}
// Limite ragionevole sulla lunghezza del token per evitare abusi
if (token.length > 2048) {
return res.status(400).json({ error: 'Token non valido' });
}
const verified = jwt.verifyToken(token);