Beim Wiederholungsbesuch die erste Frage des Kunden ("da ist doch nichts
dazugekommen, oder?") und die einzige, die ein einzelnes Protokoll nicht
beantworten kann. Das Werkzeug holt das juengste fruehere Protokoll desselben
Kunden vom Server und vergleicht die Geraetelisten.
KEINE Wiedererkennung ueber MAC: /proc/net/arp ist ab Android 10 gesperrt, im
ausgelieferten Protokoll ND2026-0015 hatten ALLE 68 Geraete keine MAC. Ein
MAC-Diff haette dort bei jedem Besuch "alles neu, alles verschwunden"
gemeldet - schlimmer als gar keine Aussage, weil es im Kundendokument nach
einem umgebauten Netz aussieht. Stattdessen eine Kaskade: MAC (falls
ausnahmsweise da), mDNS-Name, NetBIOS-Name, Hostname, IP+Portmuster. Jede
Zeile nennt, worueber sie zugeordnet wurde - "erkannt ueber IP und Portmuster"
ist eine schwaechere Aussage als "ueber Netzwerkname".
Im Emulator gegen echte Serverdaten geprueft. Dabei ein Fehler gefunden und
behoben: dieselbe Adresse stand gleichzeitig unter "neu" und "nicht mehr
erreichbar", weil sich nur das Portmuster geaendert hatte. Formal richtig, im
Kundendokument aber Unsinn - liest sich wie ein kaputtes Werkzeug. Solche
Faelle haben jetzt eine eigene Kategorie "Gleiche Adresse, andere offene
Ports", die sogar der interessantere Befund ist.
Bewertung bewusst ohne Rot: ein neues Geraet ist erst einmal eine Tatsache,
womoeglich hat der Techniker es selbst angeschlossen. Gelb nur, wenn etwas
fehlt oder die Zuordnung wackelt (ab 50 % schwache Zuordnung).
tools/pruefe-geraetediff.mjs: 20 Faelle, alle mit Geraeten OHNE MAC - so wie
sie beim Kunden ankommen. Der Browser-Mock gibt jedem Geraet eine MAC, dort
saehe auch ein naiver MAC-Diff perfekt aus.
Ausserdem: Server-Adresse wird jetzt geprueft. Eine http://-Adresse wird
abgewiesen, solange die App selbst ueber https laeuft - sie wuerde sonst stumm
scheitern ("Keine Verbindung zum Server", wahrer Grund nur im logcat). Ein
Debug-Build auf http://localhost darf HTTP dagegen, sonst waere der Testbau
unbenutzbar. tools/pruefe-serveradresse.mjs: 11 Faelle.
Neu in api.ts: getProtocol() laedt ein Protokoll samt Geraeten vom Server -
nur lesend, das fruehere Protokoll wird nie ueberschrieben.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
74 lines
2.8 KiB
TypeScript
74 lines
2.8 KiB
TypeScript
/**
|
|
* 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: '' };
|
|
}
|