dolibarr.netdiag/ChangeLog.md
Eduard Wisch 9f07896b05
All checks were successful
Deploy netdiag / deploy (push) Successful in 13s
Doku + Version 1.1.1: die Whitelist-Falle steht jetzt im README [deploy]
Version auf 1.1.1 gezogen — auf Prod lief sonst eine 1.1.0, die nicht der
1.1.0 im Repo entspricht (die vier Bugfixes gingen ohne Versionssprung raus).

ChangeLog 1.1.1 mit allen vier Fehlern, der Rechtelücke im GET-Zweig und den
neuen Monitor-Feldern.

README:
- Neuer Abschnitt "Neue Messart aus der App aufnehmen" mit den DREI Stellen in
  netdiag.lib.php und der Spalte "wenn vergessen". Das ist die Falle, in die
  hier schon zweimal getappt wurde - einmal mit erfundenen Testdaten, einmal
  mit 'typ' statt 'type'. Feldnamen immer aus dem erzeugenden App-Code ablesen.
- Anmeldung laeuft ueber awlauth (stand noch "JWT-Auth")
- Rechteprüfung je Endpunkt dokumentiert, inkl. der Begruendung, warum der
  GET-Zweig auch 'write' akzeptiert
- Hinweis, dass '?jwt=' nur fuer den PDF-Download existiert und in Logs landet
2026-08-16 19:56:10 +02:00

5.4 KiB

Changelog NetDiag

1.1.1 — 2026-08-16

Vier stille Fehler im Kundendokument und im Sync

Alle vier waren bereits ausgeliefert und fielen nicht auf, weil das PDF ja weiterhin erzeugt wurde — nur ohne die betroffene Zeile. Gefunden durch einen systematischen Abgleich der Whitelist gegen den erzeugenden App-Code.

  • 'typ' war ein toter Schlüssel. Kein Werkzeug erzeugt ihn; die App reicht ein LinkInfo-Objekt durch, dort heißt das Feld 'type'. Folge: im Abnahmebeleg für eine Netzwerkdose fehlte die Angabe, ob per LAN oder WLAN gemessen wurde. Zusätzlich 'rssi' aufgenommen — bei einer WLAN-Dose ist der Empfangspegel der eigentliche Messwert und wurde bisher verworfen. Die Rohwerte sind englisch; netdiagKundentext() bildet sie jetzt ab (ethernet → „LAN (Kabel)"), sonst stünde „Anschlussart: ethernet" im Abnahmeprotokoll eines deutschen Handwerksbetriebs.
  • Leeres Array druckte „Offene Ports: " ohne Wert. Die Leerprüfung ist ein elseif hinter dem Array-Zweig und wurde nie erreicht. Betraf ausgerechnet die guten Ergebnisse: Portscan ohne offenen Port, IP-Konflikt ohne Konflikt, IP-Scan ohne Veränderung. Jetzt „keine" — Weglassen wäre schlechter, weil der Kunde sonst nicht unterscheiden kann, ob nichts gefunden oder nichts geprüft wurde.
  • 'error' fehlte in der Whitelist. Der IP-Konflikt gibt im Abbruchfall { error: … } mit roter Ampel zurück — im Kundendokument stand eine rote Ampel ohne einen Buchstaben Erklärung. Die App vereinheitlicht künftig auf 'fehler', aber Altdaten lassen sich nicht ändern.
  • tool/category/label wurden beim Sync nicht auf die Spaltenlänge gekürzt (varchar 64/32/255). Bei striktem SQL-Modus kippt ein zu langes Label den gesamten Sync per rollback() — der Techniker steht beim Kunden mit einem Protokoll da, das sich nicht abschließen lässt, weil eine Beschriftung zu lang war. Die App setzt Labels durch Verketten zusammen, 255 Zeichen sind erreichbar. found_via wurde 20 Zeilen darüber längst gekappt.

Rechteprüfung im GET-Zweig der Protokoll-API

Bisher prüfte der GET-Zweig gar nichts: jeder angemeldete Benutzer konnte mit einer geratenen ID ein fremdes Protokoll samt Geräteliste, IP-Adressen und offenen Ports abrufen (der POST-Zweig verlangte seit jeher write). Das ist beim Kunden erhobene Netzstruktur und gehört hinter ein Recht.

write wird bewusst mit akzeptiert: die Rechte sind in Dolibarr einzeln vergebbar, und ein Techniker mit Schreib- ohne ausdrückliches Leserecht dürfte nicht ausgesperrt werden — das wäre erst beim Kunden aufgefallen.

Geräte-Monitor erscheint jetzt im Kundendokument

Die App liefert ab dieser Version eine Auswertung der Dauerüberwachung als richtige Messung (Verfügbarkeit, Ausfallzeit, Aussetzer je Gerät). Die sechs neuen Schlüssel sind in der Whitelist ergänzt — ohne sie stünde im PDF nur die Ampel.

Kleinigkeit

netdiagDauerLesbar(): „1 Tage 0 Std" → „1 Tag". floor() liefert in PHP einen Float, und 1.0 === 1 ist false — die Einzahl hatte deshalb nie gegriffen.

1.1.0 — 2026-08-14

Anmeldung läuft über das zentrale Auth-Modul (awlauth)

NetDiag war die letzte AWL-App mit eigenem Login: eigenes JWT, eigener Schlüssel (NETDIAG_API_JWT_SECRET), eigene Gültigkeitsdauer, keine Möglichkeit, ein verlorenes Handy gezielt abzumelden. Ab sofort stellt awlauth das Token aus — dasselbe Token, derselbe Schlüssel und dieselbe Sitzungs-Registry wie bei den sechs Browser-Apps.

  • api/auth.php prüft das Passwort über awlauth_login(). Damit greifen dort auch die Brute-Force-Bremse (5 Fehlversuche je IP in 15 min, 10 je Benutzername in 30 min) und die einheitliche, nicht-verräterische Fehlermeldung. Das Token kommt aus awlauth_issue_bearer() und legt eine Sitzungszeile an — das Gerät erscheint als „NetDiag-App · Android" in der awlauth-Geräteliste und ist dort einzeln abmeldbar.
  • netdiag_api_authenticate() prüft zuerst das awlauth-Token. Ein abgelaufenes oder widerrufenes Token führt sofort zu 401, auch wenn die Signatur noch stimmt.
  • Übergangsweise wird ein bereits ausgestelltes altes netdiag-JWT weiterhin akzeptiert, damit die Umstellung niemanden mitten im Einsatz aussperrt. Dieser Pfad entfällt, sobald alle Geräte einmal neu angemeldet sind.
  • Ohne aktives awlauth-Modul läuft NetDiag unverändert mit dem eigenen JWT weiter.

Die Antwortform von auth.php ist bewusst unverändert ({token, expiresIn, user}). Bereits installierte APKs laufen nach einer einmaligen Neuanmeldung ohne Update weiter.

CORS enger gefasst

Access-Control-Allow-Origin: * ist raus. Die API liefert Kundendaten aus; ein Wildcard erlaubt jeder beliebigen Webseite, die Antwort auszulesen, sobald sie an ein Token kommt. Erlaubt sind jetzt nur die App-Origins (https://localhost, capacitor://localhost, http://localhost, ionic://localhost) und der Vite-Dev-Server; dazu Vary: Origin. Anfragen ohne Origin-Header (nativer HTTP-Client, der APK-Downloader im Kotlin-Plugin, curl) bekommen wie bisher eine Antwort — dort greift die Same-Origin-Policy ohnehin nicht.

1.0.0

  • Erstversion
  • Datenmodell: Protokoll, Gerät, Messung
  • JSON-API: auth, customers, orders, protocols (Sync), pdf
  • Tab "Netzwerk-Diagnose" an Kunde und Auftrag
  • PDF-Protokoll-Generator + ECM-Ablage
  • Backend: Protokoll-Liste und Detailansicht
  • Admin: Token-Einstellung, QR-Code zum App-Download