$v) $_SERVER[$k] = $v; }; $reset(['HTTP_AUTHORIZATION' => "Bearer {$token}"]); $check(api_bearer_token() === $token, 'normaler Authorization-Header wird gelesen'); $reset(['REDIRECT_HTTP_AUTHORIZATION' => "Bearer {$token}"]); $check(api_bearer_token() === $token, 'Authorization über REDIRECT_HTTP_AUTHORIZATION (Apache-Umleitung) wird gelesen'); $reset(['HTTP_X_DESKHUB_AUTHORIZATION' => "Bearer {$token}"]); $check(api_bearer_token() === $token, 'Ersatz-Header X-DeskHub-Authorization genügt, wenn Authorization fehlt (Plesk/FPM)'); $reset(['HTTP_AUTHORIZATION' => "Bearer {$token}", 'HTTP_X_DESKHUB_AUTHORIZATION' => "Bearer {$other}"]); $check(api_bearer_token() === $token, 'ist beides vorhanden, gilt Authorization'); $reset(['HTTP_AUTHORIZATION' => '', 'HTTP_X_DESKHUB_AUTHORIZATION' => "Bearer {$token}"]); $check(api_bearer_token() === $token, 'leerer Authorization-Header fällt auf den Ersatz-Header zurück'); $reset([]); $check(api_bearer_token() === null && api_authorization_header() === '', 'ohne Header: kein Token'); $reset(['HTTP_X_DESKHUB_AUTHORIZATION' => 'Basic abc']); $check(api_bearer_token() === null, 'kein Bearer-Schema: abgelehnt'); $reset(['HTTP_X_DESKHUB_AUTHORIZATION' => 'Bearer kurz']); $check(api_bearer_token() === null, 'zu kurzes Token: abgelehnt'); $reset(['HTTP_X_DESKHUB_AUTHORIZATION' => "Bearer {$token}\r\nX-Evil: 1"]); $check(api_bearer_token() === null, 'eingeschleuste Zeilenumbrüche: abgelehnt'); // Klartext aus HTML (Signaturen und Nachrichten in den Apps): Blöcke bleiben getrennt $check(api_plain_text('

Liebe Grüße
Lukas

Inhaber Windelweb
Zweite Zeile
') === "Liebe Grüße\nLukas\n\nInhaber Windelweb\nZweite Zeile", 'Klartext: Absätze und div-Blöcke bleiben getrennt: ' . json_encode(api_plain_text('

Liebe Grüße
Lukas

Inhaber Windelweb
Zweite Zeile
'))); $check(api_plain_text('') === "• Eins\n• Zwei", 'Klartext: Listenpunkte'); $check(api_plain_text("

A

B

") === "A\n\nB", 'Klartext: höchstens eine Leerzeile'); $check(api_plain_text('

Text & mehr <b>

') === 'Text & mehr ', 'Klartext: Entities werden aufgelöst'); $check(api_plain_text(null) === '' && api_plain_text('') === '', 'Klartext: leer'); // Klartext aus HTML (Signaturen und Nachrichten in den Apps): Blöcke bleiben getrennt $check(api_plain_text('

Liebe Grüße
Lukas

Inhaber Windelweb
Zweite Zeile
') === "Liebe Grüße\nLukas\n\nInhaber Windelweb\nZweite Zeile", 'Klartext: Absätze und div-Blöcke bleiben getrennt: ' . json_encode(api_plain_text('

Liebe Grüße
Lukas

Inhaber Windelweb
Zweite Zeile
'))); $check(api_plain_text('') === "• Eins\n• Zwei", 'Klartext: Listenpunkte'); $check(api_plain_text("

A

B

") === "A\n\nB", 'Klartext: höchstens eine Leerzeile'); $check(api_plain_text('

Text & mehr <b>

') === 'Text & mehr ', 'Klartext: Entities werden aufgelöst'); $check(api_plain_text(null) === '' && api_plain_text('') === '', 'Klartext: leer'); // Anwendungs-Code der Apps sendet den Ersatz-Header $desktop = (string) @file_get_contents(dirname(__DIR__, 2) . '/desktop/src/main.js'); if ($desktop !== '') $check(str_contains($desktop, "X-DeskHub-Authorization"), 'Windows-App sendet den Ersatz-Header'); $android = (string) @file_get_contents(dirname(__DIR__, 2) . '/mobile/src/main/java/de/deskhub/staff/data/remote/DeskHubApi.kt'); if ($android !== '') $check(substr_count($android, 'X-DeskHub-Authorization') >= 2, 'Android-App sendet den Ersatz-Header (Anfragen und Bild-Upload)'); // Apache-Regeln $htaccess = (string) file_get_contents(dirname(__DIR__) . '/.htaccess'); $check(str_contains($htaccess, 'E=HTTP_AUTHORIZATION:%{HTTP:Authorization}') && str_contains($htaccess, 'CGIPassAuth On'), '.htaccess reicht den Authorization-Header an PHP weiter'); if ($failures) { fwrite(STDERR, "FEHLER:\n- " . implode("\n- ", $failures) . "\n"); exit(1); } echo "API auth header checks passed.\n";