diff --git a/CHANGELOG.md b/CHANGELOG.md index c11f729..dc879a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,22 @@ Format angelehnt an [Keep a Changelog](https://keepachangelog.com/de/1.0.0/). ## [Unreleased] +### 🔎 Login-Diagnose: Passwort-Sichtbarkeit + Trim (2026-08-20) +- 🐛 **„Login fehlgeschlagen" trotz korrekter Zugangsdaten:** Systematische + Analyse (App-Code, App-Logs, Caddy/Navidrome-Logs, 1:1-Nachbau des + App-Requests inkl. Salt/Token) hat bewiesen: **App-Code, Server, User „Baka" + und Passwort sind korrekt** — der Fehler lag im auf dem Gerät verwendeten + Credential-Wert (der ältere Build mit dem Ping-Fehlalarm persistierte + ungültige Zugangsdaten; verdeckte Tippfehler im Passwortfeld blieben + unsichtbar). +- 🔧 **Passwort-Anzeigen-Umschalter** (Auge-Icon) im Navidrome-Login — Tippfehler + werden sichtbar. +- 🔧 **URL + Passwort werden getrimmt** (randständige Leerzeichen aus Autofill / + Tastatur entfernt). +- ℹ️ Ein erfolgreicher Login überschreibt die alten (ungültigen) gespeicherten + Zugangsdaten — der Ping-Fix aus dieser Version stellt sicher, dass künftig + nur noch gültige Credentials gespeichert werden. + ### 🔒 Datenschutz: Log-Bereinigung vor Server-Upload (2026-08-20) - ✅ **Was:** Diagnose-Logs werden jetzt zentral bereinigt, bevor sie an `logs.baka-net.de` gehen. Der lokale `debugPrint` bleibt vollständig. diff --git a/lib/settings/settings_screen.dart b/lib/settings/settings_screen.dart index 774823e..a6d4f17 100644 --- a/lib/settings/settings_screen.dart +++ b/lib/settings/settings_screen.dart @@ -160,6 +160,7 @@ class _SettingsScreenState extends State { final passCtrl = TextEditingController(); String selectedUser = 'Dustin'; bool verbindet = false; + bool obscure = true; String? fehler; showDialog( @@ -228,11 +229,20 @@ class _SettingsScreenState extends State { TextField( controller: passCtrl, style: const TextStyle(color: Colors.white), - obscureText: true, - decoration: const InputDecoration( + obscureText: obscure, + decoration: InputDecoration( labelText: 'Passwort', - labelStyle: TextStyle(color: Colors.grey), - border: OutlineInputBorder(), + labelStyle: const TextStyle(color: Colors.grey), + border: const OutlineInputBorder(), + // Anzeigen-Umschalter: verdeckte Tippfehler im Passwort + // sichtbar machen (häufigste Login-Fehlerquelle). + suffixIcon: IconButton( + icon: Icon( + obscure ? Icons.visibility_off : Icons.visibility, + color: Colors.grey, + ), + onPressed: () => setDialogState(() => obscure = !obscure), + ), ), ), if (fehler != null) ...[ @@ -262,16 +272,19 @@ class _SettingsScreenState extends State { ? null : () async { setDialogState(() => verbindet = true); + // Randständige Leerzeichen entfernen (verdeckte + // Fehlerquelle im obscureText-Feld / bei Autofill). + final url = urlCtrl.text.trim(); + final pass = passCtrl.text.trim(); logger.info( - 'Navidrome Login-Versuch (pwLeer=${passCtrl.text.isEmpty})'); - _navidrome.setCredentials( - urlCtrl.text, selectedUser, passCtrl.text); + 'Navidrome Login-Versuch (pwLeer=${pass.isEmpty})'); + _navidrome.setCredentials(url, selectedUser, pass); final ok = await _navidrome.ping(); setDialogState(() => verbindet = false); if (ok && ctx.mounted) { logger.info('Navidrome Login erfolgreich'); await _navidrome.speichereZugangsdaten( - urlCtrl.text, selectedUser, passCtrl.text); + url, selectedUser, pass); if (ctx.mounted) Navigator.pop(ctx); if (mounted) setState(() {}); } else if (ctx.mounted) {