Files
Freundebuch/backend/src/routes/admin.js
2026-09-07 12:21:53 +02:00

112 lines
3.5 KiB
JavaScript

const express = require('express');
const { sha256, safeEqual } = require('../utils/hash');
const storage = require('../utils/storage');
const { requireAdmin } = require('../auth');
const { generateBookPdf } = require('../pdf');
const router = express.Router();
const ADMIN_PASSWORD_HASH = (process.env.ADMIN_PASSWORD_HASH || '').trim().toLowerCase();
// --- Admin Login ---
router.post('/login', (req, res) => {
const { password } = req.body || {};
if (!password || !ADMIN_PASSWORD_HASH) {
return res.status(400).json({ error: 'Passwort erforderlich.' });
}
const hash = sha256(password);
if (!safeEqual(hash, ADMIN_PASSWORD_HASH)) {
return res.status(401).json({ error: 'Falsches Passwort.' });
}
req.session.role = 'admin';
req.session.friendId = null;
return res.json({ ok: true });
});
router.post('/logout', (req, res) => {
req.session = null;
res.json({ ok: true });
});
router.get('/session', (req, res) => {
if (req.session && req.session.role) {
return res.json({ role: req.session.role, friendId: req.session.friendId || null });
}
res.json({ role: null });
});
// --- Freunde-Verwaltung (nur Admin) ---
router.get('/friends', requireAdmin, (req, res) => {
const friends = storage.getAllFriendsMeta().map((f) => ({
id: f.id,
folderName: f.folderName,
name: f.name,
createdAt: f.createdAt,
profileImage: f.profileImage,
shareEnabled: !!(f.share && f.share.enabled),
blockCount: (f.blocks || []).length,
}));
res.json({ friends });
});
router.post('/friends', requireAdmin, (req, res) => {
const { name } = req.body || {};
if (!name || !String(name).trim()) {
return res.status(400).json({ error: 'Name erforderlich.' });
}
const meta = storage.createFriend(String(name).trim());
res.json({ friend: meta });
});
router.delete('/friends/:id', requireAdmin, (req, res) => {
const folder = storage.findFolderById(req.params.id);
if (!folder) return res.status(404).json({ error: 'Nicht gefunden.' });
storage.deleteFriend(folder);
res.json({ ok: true });
});
// Freigabe (Share-Link) verwalten
router.post('/friends/:id/share', requireAdmin, (req, res) => {
const folder = storage.findFolderById(req.params.id);
if (!folder) return res.status(404).json({ error: 'Nicht gefunden.' });
const meta = storage.readMeta(folder);
const { enabled, password } = req.body || {};
if (enabled === false) {
meta.share.enabled = false;
storage.writeMeta(folder, meta);
return res.json({ friend: meta });
}
if (!password || String(password).length < 4) {
return res.status(400).json({ error: 'Bitte ein Passwort mit mindestens 4 Zeichen vergeben.' });
}
meta.share.enabled = true;
meta.share.passwordHash = sha256(password);
storage.writeMeta(folder, meta);
res.json({ friend: meta });
});
// --- Freundesbuch-Ansicht (aggregiert, nur Admin) ---
router.get('/book', requireAdmin, (req, res) => {
const friends = storage.getAllFriendsMeta().map((f) => ({
...f,
share: { enabled: !!(f.share && f.share.enabled) }, // Passwort-Hash nie an den Client senden
}));
res.json({ friends });
});
router.get('/book/pdf', requireAdmin, async (req, res) => {
try {
const pdfBuffer = await generateBookPdf();
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename="freundesbuch.pdf"');
res.send(pdfBuffer);
} catch (err) {
console.error('PDF-Export fehlgeschlagen:', err);
res.status(500).json({ error: 'PDF-Export fehlgeschlagen.' });
}
});
module.exports = router;