function csrf_field(): string { $token = htmlspecialchars($_SESSION['csrf_token'] ?? '', ENT_QUOTES, 'UTF-8'); return ''; } function redirect(string $url): never { header("Location: $url"); exit; } function is_logged_in(): bool { return !empty($_SESSION['user_id']); } function require_login(): void { if (!is_logged_in()) { redirect('/index.php'); } // Session-Fingerprint prüfen $fp = sha1(($_SERVER['REMOTE_ADDR'] ?? '') . ($_SERVER['HTTP_USER_AGENT'] ?? '')); if (($_SESSION['fingerprint'] ?? '') !== $fp) { session_destroy(); redirect('/index.php'); } // Session-Timeout prüfen $timeout = (int)$_ENV['SESSION_LIFETIME'] * 60; if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity']) > $timeout) { session_destroy(); redirect('/index.php?timeout=1'); } // ── MFA-Check ──────────────────────────────────────────── // Seiten die OHNE mfa_verified erreichbar sein müssen: $current = $_SERVER['PHP_SELF'] ?? ''; $mfa_pages = [ '/auth/login.php', '/auth/logout.php', '/auth/mfa-verify.php', '/auth/mfa-setup.php', '/auth/mfa-email-send.php', ]; $is_mfa_page = false; foreach ($mfa_pages as $p) { if (str_ends_with($current, $p)) { $is_mfa_page = true; break; } } if (!$is_mfa_page && empty($_SESSION['mfa_verified'])) { redirect('/auth/mfa-verify.php'); } // ── Ende MFA-Check ─────────────────────────────────────── $_SESSION['last_activity'] = time(); } function has_role(string ...$roles): bool { $userRoles = $_SESSION['roles'] ?? []; foreach ($roles as $role) { if (in_array($role, $userRoles, true)) return true; } return false; } function require_role(string ...$roles): void { require_login(); if (!has_role(...$roles)) { http_response_code(403); die('Keine Berechtigung.'); } } // ── Modul-Berechtigungen ───────────────────────────────────── // Granulare Berechtigungen für geschützte Module (Gefahrenzone) // Verwaltet in: Benutzerverwaltung → Gefahrenzone // Tabelle: user_permissions // // Verfügbare Permissions: // intune – Intune/MDM-Dokumentation // software – Software & Lizenzverwaltung // zugaenge_credentials – Zugänge & Credentials (IT-Tresor) // benutzerverwaltung – Benutzerverwaltung // einstellungen – Systemeinstellungen // export – Daten-Export // firmenwechsel – Firmenwechsel/Verrechnungsprozess // ------------------------------------------------------------ function has_permission(string $permission): bool { if (!is_logged_in()) return false; // Superadmin + Admin haben immer alle Berechtigungen if (has_role('superadmin', 'admin')) return true; try { $stmt = db()->prepare(" SELECT COUNT(*) FROM user_permissions WHERE user_id = ? AND permission = ? "); $stmt->execute([$_SESSION['user_id'], $permission]); return (bool)$stmt->fetchColumn(); } catch (Exception $e) { error_log('has_permission Fehler: ' . $e->getMessage()); return false; } } function require_permission(string $permission): void { require_login(); if (!has_permission($permission)) { http_response_code(403); die('Keine Berechtigung.'); } } // ── Audit-Log ──────────────────────────────────────────────── function audit(string $aktion, string $tabelle = null, int $datensatzId = null, $altWert = null, $neuWert = null): void { try { db()->prepare(" INSERT INTO audit_log (tenant_id, user_id, aktion, tabelle, datensatz_id, alt_wert, neu_wert, ip_adresse) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ")->execute([ $_SESSION['tenant_id'] ?? 1, $_SESSION['user_id'] ?? null, $aktion, $tabelle, $datensatzId, $altWert ? json_encode($altWert, JSON_UNESCAPED_UNICODE) : null, $neuWert ? json_encode($neuWert, JSON_UNESCAPED_UNICODE) : null, $_SERVER['REMOTE_ADDR'] ?? null, ]); } catch (Exception $e) { // Audit-Fehler niemals die App zum Absturz bringen error_log('Audit-Log Fehler: ' . $e->getMessage()); } } // ── Settings / Listen aus DB laden ─────────────────────────── // Gibt den Rohwert als String zurück (z.B. für SMTP-Einstellungen) function getSetting(string $key, string $default = ''): string { try { $tid = $_SESSION['tenant_id'] ?? 1; $stmt = db()->prepare("SELECT wert FROM settings WHERE tenant_id = ? AND schluessel = ?"); $stmt->execute([$tid, $key]); $val = $stmt->fetchColumn(); return ($val !== false && $val !== '') ? $val : $default; } catch (Exception $e) { return $default; } } // Gibt mehrzeiligen Wert als gefilteres Array zurück (eine Zeile = ein Eintrag) function getListe(string $key, string $default = ''): array { $raw = getSetting($key, $default); return array_values(array_filter(array_map('trim', explode("\n", $raw)))); }
Fatal error: Uncaught Error: Call to undefined function is_logged_in() in /var/www/leo-invent/public_html/index.php:3 Stack trace: #0 {main} thrown in /var/www/leo-invent/public_html/index.php on line 3