// HOST-Auth. Zwei getrennte Welten: // • Kundenkonten (accounts) — Register/Login, JWT mit {sub,email} // • Betreiber/Admin — SEPARATES Login mit ADMIN_PASSWORD, JWT mit {role:operator} // Ein Kunde kann NIE Admin werden; Admin ist kein Kundenkonto. import bcrypt from "bcryptjs"; import jwt from "jsonwebtoken"; import { env } from "./env.js"; export async function hashPassword(plain) { return bcrypt.hash(plain, 10); } export async function verifyPassword(plain, hash) { return bcrypt.compare(plain, hash); } // — Kunden-Token — export function signToken(account) { return jwt.sign({ sub: account.id, email: account.email }, env.jwtSecret, { expiresIn: "7d" }); } // — Admin/Betreiber-Token (eigene Rolle, kürzere Laufzeit) — export function signAdminToken() { return jwt.sign({ role: "operator" }, env.jwtSecret, { expiresIn: "12h" }); } // Middleware: eingeloggter Kunde (oder 401). export function requireAuth(req, res, next) { const token = (req.headers.authorization || "").replace(/^Bearer /, ""); if (!token) return res.status(401).json({ error: "Nicht angemeldet." }); try { const p = jwt.verify(token, env.jwtSecret); if (p.role === "operator") return res.status(401).json({ error: "Admin-Token, kein Kundenkonto." }); req.account = { id: p.sub, email: p.email }; next(); } catch { res.status(401).json({ error: "Session ungültig oder abgelaufen." }); } } // Middleware: Betreiber/Admin (Operator-Rolle im Token, oder 403). export function requireAdmin(req, res, next) { const token = (req.headers.authorization || "").replace(/^Bearer /, ""); if (!token) return res.status(401).json({ error: "Nicht angemeldet." }); try { const p = jwt.verify(token, env.jwtSecret); if (p.role !== "operator") return res.status(403).json({ error: "Kein Admin-Zugriff." }); next(); } catch { res.status(401).json({ error: "Session ungültig oder abgelaufen." }); } }