const Config = require('../models/Config'); const logger = require('../utils/logger'); // Get current configuration (public: userTypes, rules, sections, logo, appName) const getConfig = async (req, res) => { try { const config = await Config.findOne().select('userTypes rules sections logo appName'); if (!config) { return res.status(404).json({ success: false, message: 'Konfiguration nicht gefunden' }); } res.json({ success: true, data: config }); } catch (error) { logger.error('Fehler beim Abrufen der Konfiguration:', error); res.status(500).json({ success: false, message: 'Fehler beim Abrufen der Konfiguration' }); } }; // Get full configuration (admin only) const getFullConfig = async (req, res) => { try { const config = await Config.findOne().populate('updatedBy', 'username'); if (!config) { return res.status(404).json({ success: false, message: 'Konfiguration nicht gefunden' }); } res.json({ success: true, data: config }); } catch (error) { logger.error('Fehler beim Abrufen der vollständigen Konfiguration:', error); res.status(500).json({ success: false, message: 'Fehler beim Abrufen der vollständigen Konfiguration' }); } }; // Update configuration (admin only) const updateConfig = async (req, res) => { try { const { userTypes, rules, sections, appName } = req.body; const adminId = req.user.id; // Validate userTypes if (!Array.isArray(userTypes) || userTypes.some(type => !type.code || !type.label)) { return res.status(400).json({ success: false, message: 'Ungültige Benutzertypen' }); } // Validate rules if (!Array.isArray(rules) || rules.some(rule => typeof rule !== 'string')) { return res.status(400).json({ success: false, message: 'Ungültige Regeln' }); } const updateData = { userTypes, rules, updatedBy: adminId }; if (Array.isArray(sections)) { updateData.sections = sections; } if (typeof appName === 'string' && appName.trim()) { updateData.appName = appName.trim(); } const config = await Config.findOneAndUpdate( {}, updateData, { new: true, upsert: true, runValidators: true } ).populate('updatedBy', 'username'); res.json({ success: true, data: config }); } catch (error) { logger.error('Fehler beim Aktualisieren der Konfiguration:', error); res.status(400).json({ success: false, message: error.message || 'Fehler beim Aktualisieren der Konfiguration' }); } }; // Upload logo (admin only) - accepts base64 data URL const uploadLogo = async (req, res) => { try { const { logo } = req.body; const adminId = req.user.id; if (!logo || typeof logo !== 'string') { return res.status(400).json({ success: false, message: 'Kein Logo-Bild übermittelt' }); } // Only allow safe image data URLs (block SVG to prevent stored XSS) const ALLOWED_LOGO_TYPES = [ 'data:image/jpeg;base64,', 'data:image/png;base64,', 'data:image/webp;base64,' ]; if (!ALLOWED_LOGO_TYPES.some(t => logo.startsWith(t))) { return res.status(400).json({ success: false, message: 'Ungültiges Bildformat. Erlaubt: JPEG, PNG, WebP' }); } const config = await Config.findOneAndUpdate( {}, { logo, updatedBy: adminId }, { new: true, upsert: true } ); res.json({ success: true, data: { logo: config.logo } }); } catch (error) { logger.error('Fehler beim Logo-Upload:', error); res.status(500).json({ success: false, message: 'Fehler beim Logo-Upload' }); } }; // Delete logo (admin only) const deleteLogo = async (req, res) => { try { const adminId = req.user.id; await Config.findOneAndUpdate({}, { logo: null, updatedBy: adminId }); res.json({ success: true }); } catch (error) { logger.error('Fehler beim Löschen des Logos:', error); res.status(500).json({ success: false, message: 'Fehler beim Löschen des Logos' }); } }; module.exports = { getConfig, getFullConfig, updateConfig, uploadLogo, deleteLogo };