V1.1 Verschiedene Anpassungen

This commit is contained in:
2026-02-03 21:32:20 +01:00
parent 952c353118
commit 4be9a365b3
18 changed files with 1068 additions and 114 deletions

229
routes/admin-routes.js Normal file
View File

@@ -0,0 +1,229 @@
// Admin Routes
const bcrypt = require('bcryptjs');
const { db } = require('../database');
const { requireAdmin } = require('../middleware/auth');
// Routes registrieren
function registerAdminRoutes(app) {
// Admin-Bereich
app.get('/admin', requireAdmin, (req, res) => {
db.all('SELECT id, username, firstname, lastname, role, personalnummer, wochenstunden, urlaubstage, created_at FROM users ORDER BY created_at DESC',
(err, users) => {
// LDAP-Konfiguration, Sync-Log und Optionen abrufen
db.get('SELECT * FROM ldap_config WHERE id = 1', (err, ldapConfig) => {
db.all('SELECT * FROM ldap_sync_log ORDER BY sync_started_at DESC LIMIT 10', (err, syncLogs) => {
db.get('SELECT * FROM system_options WHERE id = 1', (err, options) => {
// Parse Rollen für jeden User
const usersWithRoles = (users || []).map(u => {
let roles = [];
try {
roles = JSON.parse(u.role);
if (!Array.isArray(roles)) {
roles = [u.role];
}
} catch (e) {
roles = [u.role || 'mitarbeiter'];
}
return { ...u, roles };
});
res.render('admin', {
users: usersWithRoles,
ldapConfig: ldapConfig || null,
syncLogs: syncLogs || [],
options: options || { saturday_percentage: 100, sunday_percentage: 100 },
user: {
firstname: req.session.firstname,
lastname: req.session.lastname,
roles: req.session.roles || [],
currentRole: req.session.currentRole || 'admin'
}
});
});
});
});
});
});
// Benutzer erstellen
app.post('/admin/users', requireAdmin, (req, res) => {
const { username, password, firstname, lastname, roles, personalnummer, wochenstunden, urlaubstage } = req.body;
const hashedPassword = bcrypt.hashSync(password, 10);
// Normalisiere die optionalen Felder
const normalizedPersonalnummer = personalnummer && personalnummer.trim() !== '' ? personalnummer.trim() : null;
const normalizedWochenstunden = wochenstunden && wochenstunden !== '' ? parseFloat(wochenstunden) : null;
const normalizedUrlaubstage = urlaubstage && urlaubstage !== '' ? parseFloat(urlaubstage) : null;
// Rollen verarbeiten: Erwarte Array, konvertiere zu JSON-String
let rolesArray = [];
if (Array.isArray(roles)) {
rolesArray = roles.filter(r => r && ['mitarbeiter', 'verwaltung', 'admin'].includes(r));
} else if (roles) {
// Fallback: Einzelne Rolle als Array
rolesArray = [roles];
}
// Mindestens eine Rolle erforderlich
if (rolesArray.length === 0) {
rolesArray = ['mitarbeiter']; // Standard-Rolle
}
const rolesJson = JSON.stringify(rolesArray);
db.run('INSERT INTO users (username, password, firstname, lastname, role, personalnummer, wochenstunden, urlaubstage) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
[username, hashedPassword, firstname, lastname, rolesJson, normalizedPersonalnummer, normalizedWochenstunden, normalizedUrlaubstage],
(err) => {
if (err) {
return res.status(400).json({ error: 'Benutzername existiert bereits' });
}
res.json({ success: true });
});
});
// Benutzer löschen
app.delete('/admin/users/:id', requireAdmin, (req, res) => {
const userId = req.params.id;
// Admin darf sich nicht selbst löschen
if (userId == req.session.userId) {
return res.status(400).json({ error: 'Sie können sich nicht selbst löschen' });
}
db.run('DELETE FROM users WHERE id = ?', [userId], (err) => {
if (err) {
return res.status(500).json({ error: 'Fehler beim Löschen' });
}
res.json({ success: true });
});
});
// Benutzer aktualisieren (Personalnummer, Wochenstunden, Urlaubstage, Rollen)
app.put('/admin/users/:id', requireAdmin, (req, res) => {
const userId = req.params.id;
const { personalnummer, wochenstunden, urlaubstage, roles } = req.body;
// Rollen verarbeiten falls vorhanden
let rolesJson = null;
if (roles !== undefined) {
let rolesArray = [];
if (Array.isArray(roles)) {
rolesArray = roles.filter(r => r && ['mitarbeiter', 'verwaltung', 'admin'].includes(r));
}
// Mindestens eine Rolle erforderlich
if (rolesArray.length === 0) {
return res.status(400).json({ error: 'Mindestens eine Rolle ist erforderlich' });
}
rolesJson = JSON.stringify(rolesArray);
}
// SQL-Query dynamisch zusammenstellen
if (rolesJson !== null) {
// Aktualisiere auch Rollen
db.run('UPDATE users SET personalnummer = ?, wochenstunden = ?, urlaubstage = ?, role = ? WHERE id = ?',
[
personalnummer || null,
wochenstunden ? parseFloat(wochenstunden) : null,
urlaubstage ? parseFloat(urlaubstage) : null,
rolesJson,
userId
],
(err) => {
if (err) {
return res.status(500).json({ error: 'Fehler beim Aktualisieren' });
}
res.json({ success: true });
});
} else {
// Nur andere Felder aktualisieren
db.run('UPDATE users SET personalnummer = ?, wochenstunden = ?, urlaubstage = ? WHERE id = ?',
[
personalnummer || null,
wochenstunden ? parseFloat(wochenstunden) : null,
urlaubstage ? parseFloat(urlaubstage) : null,
userId
],
(err) => {
if (err) {
return res.status(500).json({ error: 'Fehler beim Aktualisieren' });
}
res.json({ success: true });
});
}
});
// Optionen laden
app.get('/admin/options', requireAdmin, (req, res) => {
db.get('SELECT * FROM system_options WHERE id = 1', (err, options) => {
if (err) {
return res.status(500).json({ error: 'Fehler beim Laden der Optionen' });
}
// Wenn keine Optionen vorhanden, Standardwerte zurückgeben
if (!options) {
return res.json({
config: {
saturday_percentage: 100,
sunday_percentage: 100,
checkin_root_url: null
}
});
}
res.json({ config: options });
});
});
// Optionen speichern
app.post('/admin/options', requireAdmin, (req, res) => {
const { saturday_percentage, sunday_percentage, checkin_root_url } = req.body;
// Validierung
const satPercent = parseFloat(saturday_percentage);
const sunPercent = parseFloat(sunday_percentage);
if (isNaN(satPercent) || isNaN(sunPercent)) {
return res.status(400).json({ error: 'Ungültige Prozentsätze' });
}
if (satPercent < 100 || satPercent > 200 || sunPercent < 100 || sunPercent > 200) {
return res.status(400).json({ error: 'Prozentsätze müssen zwischen 100 und 200 liegen' });
}
// Validierung der Root URL (optional, kann leer sein)
let rootUrl = checkin_root_url ? checkin_root_url.trim() : null;
if (rootUrl === '') {
rootUrl = null;
}
// Prüfe ob Eintrag existiert
db.get('SELECT id FROM system_options WHERE id = 1', (err, existing) => {
if (err) {
return res.status(500).json({ error: 'Fehler beim Prüfen der Optionen' });
}
if (existing) {
// Update
db.run('UPDATE system_options SET saturday_percentage = ?, sunday_percentage = ?, checkin_root_url = ?, updated_at = CURRENT_TIMESTAMP WHERE id = 1',
[satPercent, sunPercent, rootUrl],
(err) => {
if (err) {
return res.status(500).json({ error: 'Fehler beim Speichern der Optionen' });
}
res.json({ success: true });
});
} else {
// Insert
db.run('INSERT INTO system_options (id, saturday_percentage, sunday_percentage, checkin_root_url) VALUES (1, ?, ?, ?)',
[satPercent, sunPercent, rootUrl],
(err) => {
if (err) {
return res.status(500).json({ error: 'Fehler beim Speichern der Optionen' });
}
res.json({ success: true });
});
}
});
});
}
module.exports = registerAdminRoutes;