Files
ICON-CRM/server/src/middleware/auth.js
T
SaschaandClaude Opus 5.5 4adf48f336 Anmeldung gilt 7 Tage statt 12 Stunden
JWT-Laufzeit (JWT_EXPIRES_IN) standardmaessig auf 7d gesetzt, damit
Benutzer nicht mehr taeglich neu anmelden muessen. Doku (Betrieb,
Benutzeranleitung, Glossar) und .env.example angepasst.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 22:10:46 +02:00

63 lines
2.0 KiB
JavaScript

import jwt from 'jsonwebtoken';
import { pool } from '../db.js';
function secret() {
const value = process.env.JWT_SECRET;
if (!value || value.length < 16) {
throw new Error('JWT_SECRET fehlt oder ist zu kurz (min. 16 Zeichen).');
}
return value;
}
export function signToken(user) {
return jwt.sign({ sub: user.id, role: user.role }, secret(), {
expiresIn: process.env.JWT_EXPIRES_IN || '7d',
});
}
/**
* Prueft das Bearer-Token und laedt den aktuellen Benutzer aus der Datenbank.
*
* Die Spaltenliste ist bewusst vollstaendig aufgezaehlt und kein SELECT *:
* das Passwort-Hash soll nicht am Request haengen. Sie muss aber alles
* enthalten, was publicUser() ausliefert - sonst faellt beim Neuladen z. B.
* die Theme-Wahl auf "nichts gewaehlt" zurueck.
*/
export async function requireAuth(req, res, next) {
const header = req.headers.authorization || '';
const token = header.startsWith('Bearer ') ? header.slice(7) : null;
if (!token) return res.status(401).json({ error: 'Nicht angemeldet.' });
let payload;
try {
payload = jwt.verify(token, secret());
} catch {
return res.status(401).json({ error: 'Sitzung abgelaufen. Bitte neu anmelden.' });
}
try {
const [rows] = await pool.query(
`SELECT id, username, email, name, role, color, avatar, theme, theme_mode,
is_active, created_at, updated_at
FROM icon_users WHERE id = ? LIMIT 1`,
[payload.sub]
);
const user = rows[0];
if (!user) return res.status(401).json({ error: 'Benutzer existiert nicht mehr.' });
if (!user.is_active) return res.status(403).json({ error: 'Benutzerkonto ist deaktiviert.' });
req.user = { ...user, is_active: Boolean(user.is_active) };
next();
} catch (err) {
next(err);
}
}
/** Nur Rolle admin - schuetzt Einstellungen und Nutzerverwaltung. */
export function requireAdmin(req, res, next) {
if (req.user?.role !== 'admin') {
return res.status(403).json({ error: 'Diese Aktion ist Administratoren vorbehalten.' });
}
next();
}