createUserAccountService(); // Support both route param and POSTed uuid (POST avoids exposing uuid in URL/history). $uuid = trim((string) ($id ?? '')); if ($uuid === '' && strtoupper((string) ($_SERVER['REQUEST_METHOD'] ?? 'GET')) === 'POST') { $uuid = trim((string) ($_POST['uuid'] ?? '')); } $user = $uuid !== '' ? $userAccountService->findByUuid($uuid) : null; if (!$user) { http_response_code(404); return; } $currentUserId = (int) ($_SESSION['user']['id'] ?? 0); $userId = (int) ($user['id'] ?? 0); // Enforce tenant scope on the target user before rendering any sensitive document. if ($userId <= 0 || !directoryServicesFactory()->createDirectoryScopeGateway()->canAccess('users', $userId, $currentUserId)) { Router::redirect('error/forbidden'); return; } $pdf = UserAccessPdfService::renderUserAccessPdf($user); if ($pdf === '') { // Keep error generic; service handles concrete renderer/asset failures internally. http_response_code(500); return; } $locale = strtolower((string) (\MintyPHP\I18n::$locale ?? \MintyPHP\I18n::$defaultLocale)); $filename = str_starts_with($locale, 'de') ? 'zugangsdaten.pdf' : 'access-details.pdf'; header('Content-Type: application/pdf'); header('Content-Disposition: inline; filename="' . $filename . '"'); header('Cache-Control: private, no-store, max-age=0'); header('Pragma: no-cache'); header('X-Content-Type-Options: nosniff'); header('Content-Length: ' . strlen($pdf)); $output = fopen('php://output', 'wb'); if ($output === false) { http_response_code(500); return; } fwrite($output, $pdf); fclose($output);