Quellcode des ICON CRM (3)

This commit is contained in:
2026-09-14 16:55:34 +02:00
parent 0a597ae527
commit 28763fed6d
25 changed files with 6158 additions and 0 deletions
+62
View File
@@ -0,0 +1,62 @@
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 || '12h',
});
}
/**
* 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();
}