const jwt = require('jsonwebtoken'); const config = require('../config/env'); // Verifiziert das Token und stellt sicher, dass es sich um ein Admin-Token handelt. const authenticateToken = (req, res, next) => { // Try to get token from cookie first (new secure method) let token = req.cookies?.token; // Fallback: Check Authorization header for backward compatibility if (!token) { const authHeader = req.headers['authorization']; token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN } if (!token) { return res.status(401).json({ success: false, message: 'Zugriff verweigert. Kein Token bereitgestellt.' }); } try { const decoded = jwt.verify(token, config.jwtSecret); // Reject tokens issued by a different app (C-01 cross-app auth fix) if (decoded.app && decoded.app !== config.appName) { return res.status(403).json({ success: false, message: 'Ungültiger oder abgelaufener Token.' }); } // Rollenprüfung. Handler-Tokens werden mit demselben Secret signiert; die // app-Prüfung oben greift bei ihnen nicht, weil sie keinen app-Claim tragen. // Ohne diese Zeilen kann ein eingeloggter Hundeführer seinen Bearer-Token // gegen /api/users, /api/config und /api/audit-logs schicken und hat volle // Admin-Rechte. Tokens ohne role stammen aus der Zeit davor und wurden // ausschließlich für Admins ausgestellt. if (decoded.role && decoded.role !== 'admin') { return res.status(403).json({ success: false, message: 'Zugriff verweigert. Keine Administratorrechte.' }); } req.user = decoded; next(); } catch (error) { return res.status(403).json({ success: false, message: 'Ungültiger oder abgelaufener Token.' }); } }; // Wie authenticateToken, blockiert aber nicht: setzt req.user wenn ein gültiges // Admin-Token vorliegt und ruft ansonsten einfach next(). Für Endpunkte wie // /logout, die auch mit abgelaufenem Token funktionieren müssen. const attachUserIfPresent = (req, res, next) => { let token = req.cookies?.token; if (!token) { const authHeader = req.headers['authorization']; token = authHeader && authHeader.split(' ')[1]; } if (token) { try { const decoded = jwt.verify(token, config.jwtSecret); const appOk = !decoded.app || decoded.app === config.appName; const roleOk = !decoded.role || decoded.role === 'admin'; if (appOk && roleOk) { req.user = decoded; } } catch (error) { // Ungültiges Token ist hier kein Fehler – der Aufrufer wird ohne req.user bedient. } } next(); }; module.exports = { authenticateToken, attachUserIfPresent };