Added Krank Button, LDAP Sync auth
This commit is contained in:
170
server.js
170
server.js
@@ -139,56 +139,101 @@ app.get('/login', (req, res) => {
|
||||
app.post('/login', (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
|
||||
db.get('SELECT * FROM users WHERE username = ?', [username], (err, user) => {
|
||||
if (err || !user) {
|
||||
return res.render('login', { error: 'Ungültiger Benutzername oder Passwort' });
|
||||
// Prüfe ob LDAP aktiviert ist
|
||||
LDAPService.getConfig((err, ldapConfig) => {
|
||||
if (err) {
|
||||
console.error('Fehler beim Abrufen der LDAP-Konfiguration:', err);
|
||||
}
|
||||
|
||||
if (bcrypt.compareSync(password, user.password)) {
|
||||
// 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];
|
||||
const isLDAPEnabled = ldapConfig && ldapConfig.enabled === 1;
|
||||
|
||||
// Wenn LDAP aktiviert ist, authentifiziere gegen LDAP
|
||||
if (isLDAPEnabled) {
|
||||
LDAPService.authenticate(username, password, (authErr, authSuccess) => {
|
||||
if (authErr || !authSuccess) {
|
||||
// LDAP-Authentifizierung fehlgeschlagen - prüfe lokale Datenbank als Fallback
|
||||
db.get('SELECT * FROM users WHERE username = ?', [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);
|
||||
} else {
|
||||
res.render('login', { error: 'Ungültiger Benutzername oder Passwort' });
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// LDAP-Authentifizierung erfolgreich - hole Benutzer aus Datenbank
|
||||
db.get('SELECT * FROM users WHERE username = ?', [username], (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);
|
||||
});
|
||||
}
|
||||
} 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;
|
||||
|
||||
// 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');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.render('login', { error: 'Ungültiger Benutzername oder Passwort' });
|
||||
// LDAP nicht aktiviert - verwende lokale Authentifizierung
|
||||
db.get('SELECT * FROM users WHERE username = ?', [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);
|
||||
} else {
|
||||
res.render('login', { error: 'Ungültiger Benutzername oder Passwort' });
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Helper-Funktion für erfolgreiche Anmeldung
|
||||
function handleSuccessfulLogin(req, res, user) {
|
||||
// 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;
|
||||
|
||||
// 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');
|
||||
}
|
||||
}
|
||||
|
||||
// Logout
|
||||
app.get('/logout', (req, res) => {
|
||||
req.session.destroy();
|
||||
@@ -810,7 +855,7 @@ app.post('/api/timesheet/save', requireAuth, (req, res) => {
|
||||
activity3_desc, activity3_hours, activity3_project_number,
|
||||
activity4_desc, activity4_hours, activity4_project_number,
|
||||
activity5_desc, activity5_hours, activity5_project_number,
|
||||
overtime_taken_hours, vacation_type
|
||||
overtime_taken_hours, vacation_type, sick_status
|
||||
} = req.body;
|
||||
const userId = req.session.userId;
|
||||
|
||||
@@ -818,11 +863,21 @@ app.post('/api/timesheet/save', requireAuth, (req, res) => {
|
||||
const normalizedEndTime = (end_time && typeof end_time === 'string' && end_time.trim() !== '') ? end_time.trim() : (end_time || null);
|
||||
const normalizedStartTime = (start_time && typeof start_time === 'string' && start_time.trim() !== '') ? start_time.trim() : (start_time || null);
|
||||
|
||||
// Normalisiere sick_status: Boolean oder 1/0 zu Boolean
|
||||
const isSick = sick_status === true || sick_status === 1 || sick_status === 'true' || sick_status === '1';
|
||||
|
||||
// Gesamtstunden berechnen (aus Start- und Endzeit, nicht aus Tätigkeiten)
|
||||
// Wenn ganzer Tag Urlaub, dann zählt dieser als 8 Stunden normale Arbeitszeit
|
||||
// Wenn ganzer Tag Urlaub oder Krank, dann zählt dieser als 8 Stunden normale Arbeitszeit
|
||||
let total_hours = 0;
|
||||
let finalActivity1Desc = activity1_desc;
|
||||
let finalActivity1Hours = parseFloat(activity1_hours) || 0;
|
||||
|
||||
if (vacation_type === 'full') {
|
||||
total_hours = 8; // Ganzer Tag Urlaub = 8 Stunden normale Arbeitszeit
|
||||
} else if (isSick) {
|
||||
total_hours = 8; // Krank = 8 Stunden normale Arbeitszeit
|
||||
finalActivity1Desc = 'Krank';
|
||||
finalActivity1Hours = 8;
|
||||
} else if (normalizedStartTime && normalizedEndTime) {
|
||||
const start = new Date(`2000-01-01T${normalizedStartTime}`);
|
||||
const end = new Date(`2000-01-01T${normalizedEndTime}`);
|
||||
@@ -844,18 +899,19 @@ app.post('/api/timesheet/save', requireAuth, (req, res) => {
|
||||
activity3_desc = ?, activity3_hours = ?, activity3_project_number = ?,
|
||||
activity4_desc = ?, activity4_hours = ?, activity4_project_number = ?,
|
||||
activity5_desc = ?, activity5_hours = ?, activity5_project_number = ?,
|
||||
overtime_taken_hours = ?, vacation_type = ?,
|
||||
overtime_taken_hours = ?, vacation_type = ?, sick_status = ?,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?`,
|
||||
[
|
||||
normalizedStartTime, normalizedEndTime, break_minutes, total_hours, notes,
|
||||
activity1_desc || null, parseFloat(activity1_hours) || 0, activity1_project_number || null,
|
||||
finalActivity1Desc || null, finalActivity1Hours, activity1_project_number || null,
|
||||
activity2_desc || null, parseFloat(activity2_hours) || 0, activity2_project_number || null,
|
||||
activity3_desc || null, parseFloat(activity3_hours) || 0, activity3_project_number || null,
|
||||
activity4_desc || null, parseFloat(activity4_hours) || 0, activity4_project_number || null,
|
||||
activity5_desc || null, parseFloat(activity5_hours) || 0, activity5_project_number || null,
|
||||
overtime_taken_hours ? parseFloat(overtime_taken_hours) : null,
|
||||
vacation_type || null,
|
||||
isSick ? 1 : 0,
|
||||
row.id
|
||||
],
|
||||
(err) => {
|
||||
@@ -874,17 +930,18 @@ app.post('/api/timesheet/save', requireAuth, (req, res) => {
|
||||
activity3_desc, activity3_hours, activity3_project_number,
|
||||
activity4_desc, activity4_hours, activity4_project_number,
|
||||
activity5_desc, activity5_hours, activity5_project_number,
|
||||
overtime_taken_hours, vacation_type)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
overtime_taken_hours, vacation_type, sick_status)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[
|
||||
userId, date, normalizedStartTime, normalizedEndTime, break_minutes, total_hours, notes,
|
||||
activity1_desc || null, parseFloat(activity1_hours) || 0, activity1_project_number || null,
|
||||
finalActivity1Desc || null, finalActivity1Hours, activity1_project_number || null,
|
||||
activity2_desc || null, parseFloat(activity2_hours) || 0, activity2_project_number || null,
|
||||
activity3_desc || null, parseFloat(activity3_hours) || 0, activity3_project_number || null,
|
||||
activity4_desc || null, parseFloat(activity4_hours) || 0, activity4_project_number || null,
|
||||
activity5_desc || null, parseFloat(activity5_hours) || 0, activity5_project_number || null,
|
||||
overtime_taken_hours ? parseFloat(overtime_taken_hours) : null,
|
||||
vacation_type || null
|
||||
vacation_type || null,
|
||||
isSick ? 1 : 0
|
||||
],
|
||||
(err) => {
|
||||
if (err) {
|
||||
@@ -1049,10 +1106,10 @@ app.post('/api/timesheet/submit', requireAuth, (req, res) => {
|
||||
const { week_start, week_end, version_reason } = req.body;
|
||||
const userId = req.session.userId;
|
||||
|
||||
// Validierung: Prüfen ob alle 7 Tage der Woche ausgefüllt sind
|
||||
db.all(`SELECT id, date, start_time, end_time, vacation_type, updated_at FROM timesheet_entries
|
||||
WHERE user_id = ? AND date >= ? AND date <= ?
|
||||
ORDER BY date, updated_at DESC, id DESC`,
|
||||
// Validierung: Prüfen ob alle 7 Tage der Woche ausgefüllt sind
|
||||
db.all(`SELECT id, date, start_time, end_time, vacation_type, sick_status, updated_at FROM timesheet_entries
|
||||
WHERE user_id = ? AND date >= ? AND date <= ?
|
||||
ORDER BY date, updated_at DESC, id DESC`,
|
||||
[userId, week_start, week_end],
|
||||
(err, entries) => {
|
||||
if (err) {
|
||||
@@ -1097,8 +1154,9 @@ app.post('/api/timesheet/submit', requireAuth, (req, res) => {
|
||||
const dateStr = `${year}-${month}-${day}`;
|
||||
const entry = entriesByDate[dateStr];
|
||||
|
||||
// Wenn ganztägiger Urlaub, dann ist der Tag als ausgefüllt zu betrachten
|
||||
if (entry && entry.vacation_type === 'full') {
|
||||
// Wenn ganztägiger Urlaub oder Krank, dann ist der Tag als ausgefüllt zu betrachten
|
||||
const isSick = entry && (entry.sick_status === 1 || entry.sick_status === true);
|
||||
if (entry && (entry.vacation_type === 'full' || isSick)) {
|
||||
continue; // Tag ist ausgefüllt
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user