/** * Prüfung der Server-Adresse — ohne Laufzeit-Import, damit * `tools/pruefe-serveradresse.mjs` sie nachrechnen kann. * * Anlass (16./17.08.2026, im Emulator gefunden): Wird hier eine `http://`-Adresse * eingetragen, funktioniert die App **stumm nicht**. Sie meldet nur „Keine * Verbindung zum Server"; der wahre Grund steht ausschließlich im `logcat`, an * den beim Kunden niemand kommt. Es sind sogar zwei Sperren übereinander: * * 1. **Mixed Content** — die App läuft auf der Origin `https://localhost`; der * WebView blockiert daraus jede `http://`-Anfrage. * 2. **Androids Cleartext-Richtlinie** — ab API 28 ist unverschlüsseltes HTTP * ohne `android:usesCleartextTraffic` grundsätzlich verboten. * * Deshalb wird die Adresse hier abgewiesen, statt sie anzunehmen und den * Techniker vor Ort raten zu lassen. * * WICHTIG — warum nicht einfach „http verbieten": Es hängt an der Origin der * App, nicht an einer festen Regel. Ein Debug-Build mit * `server.androidScheme: 'http'` (der Weg, auf dem die lokale Testinstanz * überhaupt prüfbar ist, siehe KB #1089) läuft selbst auf `http://localhost` * und darf HTTP-Server ansprechen. Die Prüfung fragt deshalb die eigene * Herkunft ab — sonst wäre ausgerechnet der Testbau unbenutzbar. */ export interface AdressPruefung { ok: boolean; /** Meldung für den Benutzer; leer wenn alles in Ordnung ist */ meldung: string; } /** * Server-Adresse prüfen. * * @param eingabe Rohe Eingabe aus dem Feld * @param appProtokoll Protokoll der App-Origin — `window.location.protocol`, * also 'https:' oder 'http:' */ export function pruefeServerAdresse(eingabe: string, appProtokoll: string): AdressPruefung { const url = (eingabe ?? '').trim(); if (!url) { return { ok: false, meldung: 'Server-Adresse fehlt' }; } if (!/^https?:\/\//i.test(url)) { return { ok: false, meldung: 'Adresse muss mit http:// oder https:// beginnen' }; } // Tippfehler wie "https://" ohne Host früh abfangen — sonst schlägt erst der // erste Aufruf fehl, und zwar mit derselben nichtssagenden Meldung. let host = ''; try { host = new URL(url).hostname; } catch { return { ok: false, meldung: 'Adresse ist keine gültige URL' }; } if (!host) { return { ok: false, meldung: 'In der Adresse fehlt der Servername' }; } const appLaeuftUeberHttps = appProtokoll.toLowerCase().startsWith('https'); const zielIstHttp = /^http:\/\//i.test(url); if (zielIstHttp && appLaeuftUeberHttps) { return { ok: false, meldung: 'Diese App kann nur HTTPS-Server erreichen — Android blockiert unverschlüsselte ' + 'Verbindungen aus der App heraus. Mit einer http://-Adresse käme nur „Keine ' + 'Verbindung zum Server", ohne erkennbaren Grund.', }; } return { ok: true, meldung: '' }; }