prepare('SELECT * FROM users WHERE id = ?'); $stmt->execute([$_SESSION['user_id']]); $user = $stmt->fetch(); return $cache = ($user ?: null); } function require_customer_login(): array { $user = current_user(); if (!$user) { flash('error', 'Bitte melden Sie sich an, um fortzufahren.'); redirect(base_path() . '/login.php'); } return $user; } // --------------------------------------------------------------- // Mitarbeiter-Auth // --------------------------------------------------------------- function staff_login(array $staff): void { session_regenerate_id(true); $_SESSION['staff_id'] = $staff['id']; $_SESSION['staff_last_activity'] = time(); staff_touch_activity(get_db(), (int) $staff['id']); } function staff_logout(): void { // Automatische Zeiterfassung: offene Arbeits-Sitzungen beim Logout sofort // abschließen, statt bis zum nächsten Stale-Sweep (Auto-Cron) zu warten. if (!empty($_SESSION['staff_id'])) { finalize_all_sessions_for_staff(get_db(), (int) $_SESSION['staff_id']); } unset($_SESSION['staff_id']); } function current_staff(): ?array { if (empty($_SESSION['staff_id'])) { return null; } static $cache = null; if ($cache !== null) { return $cache; } $stmt = get_db()->prepare('SELECT * FROM staff WHERE id = ? AND is_active = 1'); $stmt->execute([$_SESSION['staff_id']]); $staff = $stmt->fetch(); return $cache = ($staff ?: null); } function require_staff_login(): array { $staff = current_staff(); if (!$staff) { flash('error', 'Bitte melden Sie sich an, um fortzufahren.'); redirect(staff_base_path() . '/login.php'); } // Inaktivitäts-Timeout $timeout = (int)(get_setting('staff_session_timeout', '30') ?: 30); // Minuten $last = $_SESSION['staff_last_activity'] ?? 0; if ($last && (time() - $last) > ($timeout * 60)) { staff_logout(); session_start(); $_SESSION['flash'] = [['type'=>'error','message'=>'Sie wurden wegen Inaktivität abgemeldet.']]; redirect('/staff/login.php'); } $_SESSION['staff_last_activity'] = time(); // Echte Seitenaufrufe zählen als Aktivität (Hintergrund-Abrufe per fetch nicht) if (staff_is_user_navigation()) staff_touch_activity(get_db(), (int) $staff['id']); // "Eingebauter" Ersatz für echte Server-Cronjobs (siehe includes/pseudo_cron.php): // bei jeder authentifizierten Backend-Anfrage werden fällige Jobs im Hintergrund geprüft. pseudo_cron_schedule_background(); return $staff; } function require_admin(): array { $staff = require_staff_login(); if ($staff['role'] !== 'admin') { flash('error', 'Diese Funktion ist nur für Administratoren verfügbar.'); redirect(staff_base_path() . '/reports.php'); } return $staff; } /** * Wie require_admin(), lässt aber zusätzlich Agenten mit einer benutzerdefinierten Rolle * durch, die genau dieses Adminportal-Recht zugewiesen bekommen haben ("Co-Admin" für * einzelne Bereiche, siehe admin_section_permissions() / staff/roles.php). */ function require_admin_or_permission(string $permission): array { $staff = require_staff_login(); if ($staff['role'] !== 'admin' && !has_permission($staff, $permission)) { flash('error', 'Für diese Funktion fehlt die erforderliche Berechtigung.'); redirect(staff_base_path() . '/reports.php'); } return $staff; } /** Pfad-Helfer, damit Includes unabhängig vom Aufrufort funktionieren */ function base_path(): string { return ''; } function staff_base_path(): string { return '/staff'; }