0, 'path' => '/', 'httponly' => true, 'secure' => $secure, 'samesite' => 'Lax', ]); session_name('OMSORG_FELIX_APP'); session_start(); function _omsorgcore_config(): array { static $config = null; if ($config === null) { $config = require __DIR__ . '/config.php'; } return $config; } // Stellt sicher, dass $_SESSION['omsorgcore_access_token'] gültig ist - erneuert bei Bedarf still // über den Refresh-Token (Server-seitig, der Browser bekommt nie einen Token zu sehen). function _ensure_fresh_token(): bool { if (empty($_SESSION['omsorgcore_access_token']) || empty($_SESSION['omsorgcore_refresh_token'])) { return false; } $expiresAt = $_SESSION['omsorgcore_access_expires_at'] ?? null; $stillValid = $expiresAt && strtotime($expiresAt) > time() + 30; // 30s Puffer if ($stillValid) { return true; } $result = omsorgcore_refresh(_omsorgcore_config(), $_SESSION['omsorgcore_refresh_token']); if (!$result['ok']) { _clear_omsorgcore_session(); return false; } _apply_token_pair($result['data']); return true; } function _apply_token_pair(array $data): void { $_SESSION['omsorgcore_access_token'] = $data['accessToken']; $_SESSION['omsorgcore_refresh_token'] = $data['refreshToken']; $_SESSION['omsorgcore_access_expires_at'] = $data['expiresAt']; $_SESSION['omsorgcore_must_change_password'] = !empty($data['mustChangePassword']); } function _clear_omsorgcore_session(): void { unset( $_SESSION['omsorgcore_access_token'], $_SESSION['omsorgcore_refresh_token'], $_SESSION['omsorgcore_access_expires_at'], $_SESSION['omsorgcore_must_change_password'], $_SESSION['omsorgcore_profile'], $_SESSION['felix_local_user_id'] ); } // Schreibt Name/E-Mail/Telefon/Avatar/Aktiv-Status in die lokale users-Zeile (per omsorgcore_user_id // gefunden, siehe migrate-users-to-core.php) - hält den Lesecache für die noch nicht migrierten // Seiten aktuell. Legt die Zeile an, falls sie fehlt (z. B. gerade erst über admin.php angelegter User). function _sync_local_user_cache(string $omsorgcoreUserId, string $username, array $profile): int { $name = trim(($profile['firstName'] ?? '') . ' ' . ($profile['lastName'] ?? '')) ?: $username; $stmt = db()->prepare('SELECT id FROM users WHERE omsorgcore_user_id = ?'); $stmt->execute([$omsorgcoreUserId]); $row = $stmt->fetch(); $role = $profile['role'] ?? ''; if ($row) { db()->prepare('UPDATE users SET username=?, name=?, role=?, email=?, telefon=?, avatar=?, active=1 WHERE id=?') ->execute([$username, $name, $role, $profile['email'] ?? '', $profile['phoneNumber'] ?? '', $profile['avatarFileName'] ?? null, $row['id']]); return (int)$row['id']; } db()->prepare( 'INSERT INTO users (username, name, role, password_hash, active, created_at, email, telefon, avatar, omsorgcore_user_id, omsorgcore_employee_id) VALUES (?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?)' )->execute([ $username, $name, $role, '', date('c'), $profile['email'] ?? '', $profile['phoneNumber'] ?? '', $profile['avatarFileName'] ?? null, $omsorgcoreUserId, $profile['employeeId'] ?? null, ]); return (int)db()->lastInsertId(); } // Lädt/cached /api/auth/me in der Session (Username/Rolle/Rechte/Employee-Basisdaten) und hält den // lokalen Lesecache (siehe oben) aktuell. Wird nach Login und bei jedem is_logged_in()-Aufruf ohne // gültigen Cache erneuert. function _refresh_profile(): bool { $result = omsorgcore_me(_omsorgcore_config(), $_SESSION['omsorgcore_access_token']); if (!$result['ok']) { return false; } $_SESSION['omsorgcore_profile'] = $result['data']; $_SESSION['felix_local_user_id'] = _sync_local_user_cache( $result['data']['userId'], $result['data']['username'], $result['data'] ); return true; } function is_logged_in(): bool { if (!_ensure_fresh_token()) { return false; } if (empty($_SESSION['omsorgcore_profile'])) { return _refresh_profile(); } return true; } function must_change_password(): bool { return !empty($_SESSION['omsorgcore_must_change_password']); } function require_login(): void { if (!is_logged_in()) { header('Location: ../index.php'); exit; } if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST)) { verify_csrf(); } if (must_change_password() && basename($_SERVER['SCRIPT_NAME']) !== 'change-password.php') { header('Location: change-password.php'); exit; } } function csrf_token(): string { if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } return $_SESSION['csrf_token']; } function csrf_field(): string { return ''; } function verify_csrf(): void { $token = $_POST['csrf_token'] ?? ''; if (!hash_equals(csrf_token(), $token)) { http_response_code(403); exit('Ungültige Anfrage.'); } } function require_admin(): void { require_login(); if (!is_admin()) { header('Location: ../pages/dashboard.php'); exit; } } function is_admin(): bool { return ($_SESSION['omsorgcore_profile']['role'] ?? null) === 'Administrator'; } // Unverändert wie vorher: current_user()['id']/['name']/['email']/['telefon']/['avatar'] kommen aus // der lokalen users-Zeile (jetzt ein Lesecache, siehe oben) - bestehende Seiten laufen unverändert. function current_user(): array|false { if (empty($_SESSION['felix_local_user_id'])) { return false; } $stmt = db()->prepare('SELECT * FROM users WHERE id = ?'); $stmt->execute([$_SESSION['felix_local_user_id']]); $row = $stmt->fetch(); if (!$row) { return false; } $row['role'] = $_SESSION['omsorgcore_profile']['role'] ?? $row['role']; return $row; } function current_username(): string { return $_SESSION['omsorgcore_profile']['username'] ?? ''; } function current_name(): string { $user = current_user(); return $user ? $user['name'] : ''; } function e(string $s): string { return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }