All checks were successful
Deploy netdiag / deploy (push) Successful in 13s
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
100 lines
5.4 KiB
Markdown
100 lines
5.4 KiB
Markdown
# 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
|