This commit is contained in:
2026-02-02 19:12:40 +01:00
parent c6421049c8
commit 952c353118
17 changed files with 982 additions and 513 deletions

View File

@@ -1,7 +1,7 @@
// LDAP Admin Routes
const { db } = require('../database');
const LDAPService = require('../ldap-service');
const LDAPService = require('../services/ldap-service');
const { requireAdmin } = require('../middleware/auth');
// Routes registrieren
@@ -55,7 +55,7 @@ function registerAdminLDAPRoutes(app) {
bind_password: bind_password ? bind_password.trim() : null,
base_dn: base_dn.trim(),
user_search_filter: user_search_filter ? user_search_filter.trim() : '(objectClass=person)',
username_attribute: username_attribute ? username_attribute.trim() : 'cn',
username_attribute: username_attribute ? username_attribute.trim() : 'sAMAccountName',
firstname_attribute: firstname_attribute ? firstname_attribute.trim() : 'givenName',
lastname_attribute: lastname_attribute ? lastname_attribute.trim() : 'sn',
sync_interval: parseInt(sync_interval) || 0,

View File

@@ -164,7 +164,8 @@ function registerAdminRoutes(app) {
return res.json({
config: {
saturday_percentage: 100,
sunday_percentage: 100
sunday_percentage: 100,
checkin_root_url: null
}
});
}
@@ -174,7 +175,7 @@ function registerAdminRoutes(app) {
// Optionen speichern
app.post('/admin/options', requireAdmin, (req, res) => {
const { saturday_percentage, sunday_percentage } = req.body;
const { saturday_percentage, sunday_percentage, checkin_root_url } = req.body;
// Validierung
const satPercent = parseFloat(saturday_percentage);
@@ -188,6 +189,12 @@ function registerAdminRoutes(app) {
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) {
@@ -196,8 +203,8 @@ function registerAdminRoutes(app) {
if (existing) {
// Update
db.run('UPDATE system_options SET saturday_percentage = ?, sunday_percentage = ?, updated_at = CURRENT_TIMESTAMP WHERE id = 1',
[satPercent, sunPercent],
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' });
@@ -206,8 +213,8 @@ function registerAdminRoutes(app) {
});
} else {
// Insert
db.run('INSERT INTO system_options (id, saturday_percentage, sunday_percentage) VALUES (1, ?, ?)',
[satPercent, sunPercent],
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' });

View File

@@ -2,7 +2,7 @@
const bcrypt = require('bcryptjs');
const { db } = require('../database');
const LDAPService = require('../ldap-service');
const LDAPService = require('../services/ldap-service');
const { getDefaultRole } = require('../helpers/utils');
// Helper-Funktion für erfolgreiche Anmeldung
@@ -76,16 +76,14 @@ function registerAuthRoutes(app) {
// Wenn LDAP aktiviert ist, authentifiziere gegen LDAP
if (isLDAPEnabled) {
LDAPService.authenticate(username, password, (authErr, authSuccess) => {
LDAPService.authenticate(username, password, (authErr, authSuccess, ldapUserInfo) => {
if (authErr || !authSuccess) {
// LDAP-Authentifizierung fehlgeschlagen - prüfe lokale Datenbank als Fallback
// Case-insensitive Suche: COLLATE NOCASE macht den Vergleich case-insensitive
db.get('SELECT * FROM users WHERE username = ? COLLATE NOCASE', [username], (err, user) => {
if (err || !user) {
return res.render('login', { error: 'Ungültiger Benutzername oder Passwort' });
}
// Versuche lokale Authentifizierung
if (bcrypt.compareSync(password, user.password)) {
handleSuccessfulLogin(req, res, user, rememberMe);
} else {
@@ -93,9 +91,10 @@ function registerAuthRoutes(app) {
}
});
} else {
// LDAP-Authentifizierung erfolgreich - hole Benutzer aus Datenbank
// Case-insensitive Suche: COLLATE NOCASE macht den Vergleich case-insensitive
db.get('SELECT * FROM users WHERE username = ? COLLATE NOCASE', [username], (err, user) => {
// LDAP-Authentifizierung erfolgreich - Benutzer anhand des kanonischen LDAP-Benutzernamens aus der DB holen
// (Sync speichert den exakten LDAP-Wert, z. B. "geißlerj" oder "GeisslerJ")
const dbLookupUsername = (ldapUserInfo && ldapUserInfo.username) ? ldapUserInfo.username : username;
db.get('SELECT * FROM users WHERE username = ? COLLATE NOCASE', [dbLookupUsername], (err, user) => {
if (err || !user) {
return res.render('login', { error: 'Benutzer nicht in der Datenbank gefunden. Bitte führen Sie eine LDAP-Synchronisation durch.' });
}

View File

@@ -3,15 +3,36 @@
const { hasRole } = require('../helpers/utils');
const { requireAuth } = require('../middleware/auth');
const { generateCheckinCheckoutQRPDF } = require('../services/pdf-service');
const { db } = require('../database');
// Routes registrieren
function registerDashboardRoutes(app) {
// Check-in Root URL abrufen (öffentlich zugänglich für Konfiguration)
app.get('/api/checkin-root-url', (req, res) => {
db.get('SELECT checkin_root_url FROM system_options WHERE id = 1', (err, options) => {
if (err) {
return res.status(500).json({ error: 'Fehler beim Laden der Root URL' });
}
res.json({
root_url: options && options.checkin_root_url ? options.checkin_root_url : null
});
});
});
// QR-Code-PDF (Check-in/Check-out) nur für eingeloggte Nutzer mit Mitarbeiter-Rolle
app.get('/api/dashboard/qr-pdf', requireAuth, (req, res) => {
// Interne URLs
app.get('/api/dashboard/qr-pdf/internal', requireAuth, (req, res) => {
if (!hasRole(req, 'mitarbeiter')) {
return res.status(403).send('Zugriff verweigert');
}
generateCheckinCheckoutQRPDF(req, res);
generateCheckinCheckoutQRPDF(req, res, 'internal');
});
// Externe URLs
app.get('/api/dashboard/qr-pdf/external', requireAuth, (req, res) => {
if (!hasRole(req, 'mitarbeiter')) {
return res.status(403).send('Zugriff verweigert');
}
generateCheckinCheckoutQRPDF(req, res, 'external');
});
// Dashboard für Mitarbeiter