// Authentifizierungs-Routes const bcrypt = require('bcryptjs'); const { db } = require('../database'); const LDAPService = require('../services/ldap-service'); const { getDefaultRole } = require('../helpers/utils'); // Helper-Funktion für UTF-8 Debug-Logging function logUsernameEncoding(label, username) { if (!username) { console.log(`[${label}] Username is null or undefined`); return; } console.group(`🔍 ${label} - Server Console`); console.log('Original String:', username); console.log('String Length:', username.length); console.log('Type:', typeof username); // UTF-8 Byte-Repräsentation const utf8Bytes = Buffer.from(username, 'utf8'); console.log('UTF-8 Bytes:', Array.from(utf8Bytes)); console.log('UTF-8 Bytes (Hex):', Array.from(utf8Bytes).map(b => '0x' + b.toString(16).padStart(2, '0')).join(' ')); // Einzelne Zeichen analysieren console.log('=== Character Analysis ==='); for (let i = 0; i < username.length; i++) { const char = username[i]; const codePoint = char.codePointAt(0); const utf8BytesForChar = Buffer.from(char, 'utf8'); console.log(`Position ${i}: "${char}" | CodePoint: U+${codePoint.toString(16).toUpperCase().padStart(4, '0')} (${codePoint}) | UTF-8 Bytes: [${Array.from(utf8BytesForChar).join(', ')}]`); } // URL-Encoding Test console.log('=== URL Encoding Test ==='); console.log('encodeURIComponent(username):', encodeURIComponent(username)); console.log('encodeURI(username):', encodeURI(username)); console.groupEnd(); } // Helper-Funktion für erfolgreiche Anmeldung function handleSuccessfulLogin(req, res, user, rememberMe = false) { // Rollen als JSON-Array parsen let roles = []; try { roles = JSON.parse(user.role); if (!Array.isArray(roles)) { // Fallback: Falls kein Array, erstelle Array mit vorhandener Rolle roles = [user.role]; } } catch (e) { // Fallback: Falls kein JSON, erstelle Array mit vorhandener Rolle roles = [user.role || 'mitarbeiter']; } // Standard-Rolle bestimmen: Immer "mitarbeiter" wenn vorhanden, sonst höchste Priorität let defaultRole; if (roles.includes('mitarbeiter')) { defaultRole = 'mitarbeiter'; } else { defaultRole = getDefaultRole(roles); } req.session.userId = user.id; req.session.username = user.username; req.session.roles = roles; req.session.currentRole = defaultRole; req.session.firstname = user.firstname; req.session.lastname = user.lastname; // Session-Gültigkeit setzen: 30 Tage wenn "Angemeldet bleiben" aktiviert, sonst 24 Stunden if (rememberMe) { req.session.cookie.maxAge = 30 * 24 * 60 * 60 * 1000; // 30 Tage } else { req.session.cookie.maxAge = 24 * 60 * 60 * 1000; // 24 Stunden } // Redirect: Immer zu Dashboard wenn Mitarbeiter-Rolle vorhanden, sonst basierend auf Standard-Rolle if (roles.includes('mitarbeiter')) { res.redirect('/dashboard'); } else if (defaultRole === 'admin') { res.redirect('/admin'); } else if (defaultRole === 'verwaltung') { res.redirect('/verwaltung'); } else { res.redirect('/dashboard'); } } // Routes registrieren function registerAuthRoutes(app) { // Login-Seite app.get('/login', (req, res) => { res.render('login', { error: null }); }); // Login-Verarbeitung app.post('/login', (req, res) => { const { username, password, remember_me } = req.body; const rememberMe = remember_me === 'on' || remember_me === true; // Debug-Logging: Empfangener Username vom Client console.log('\n========== LOGIN REQUEST RECEIVED =========='); logUsernameEncoding('Username received from client', username); console.log('Request headers content-type:', req.headers['content-type']); console.log('Request body keys:', Object.keys(req.body)); // Prüfe ob LDAP aktiviert ist LDAPService.getConfig((err, ldapConfig) => { if (err) { console.error('Fehler beim Abrufen der LDAP-Konfiguration:', err); } const isLDAPEnabled = ldapConfig && ldapConfig.enabled === 1; console.log('LDAP enabled:', isLDAPEnabled); // Wenn LDAP aktiviert ist, authentifiziere gegen LDAP if (isLDAPEnabled) { console.log('Starting LDAP authentication...'); LDAPService.authenticate(username, password, (authErr, authSuccess, ldapUserInfo) => { console.log('\n========== LDAP AUTHENTICATION RESULT =========='); console.log('authErr:', authErr ? authErr.message : null); console.log('authSuccess:', authSuccess); console.log('ldapUserInfo:', ldapUserInfo); if (authErr || !authSuccess) { console.log('LDAP authentication failed, trying local database fallback...'); logUsernameEncoding('Username for DB fallback lookup', username); // LDAP-Authentifizierung fehlgeschlagen - prüfe lokale Datenbank als Fallback 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' }); } if (bcrypt.compareSync(password, user.password)) { handleSuccessfulLogin(req, res, user, rememberMe); } else { res.render('login', { error: 'Ungültiger Benutzername oder Passwort' }); } }); } else { // 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; console.log('LDAP authentication successful!'); console.log('Original username:', username); console.log('Canonical username from LDAP:', dbLookupUsername); logUsernameEncoding('Canonical username for DB lookup', dbLookupUsername); 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.' }); } handleSuccessfulLogin(req, res, user, rememberMe); }); } }); } else { // LDAP nicht aktiviert - verwende lokale Authentifizierung // 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' }); } if (bcrypt.compareSync(password, user.password)) { handleSuccessfulLogin(req, res, user, rememberMe); } else { res.render('login', { error: 'Ungültiger Benutzername oder Passwort' }); } }); } }); }); // Logout app.get('/logout', (req, res) => { req.session.destroy(); res.redirect('/login'); }); } module.exports = registerAuthRoutes;