Fix: Navidrome-Login — Passwort-Sichtbarkeit + Trim (Login fehlgeschlagen)

Systematische Diagnose bewies: App-Code, Server, User 'Baka' und Passwort sind
korrekt (1:1-Nachbau des App-Requests inkl. Salt/Token -> Navidrome status:ok).
Der Fehler lag im auf dem Gerät verwendeten Credential-Wert:
- der alte Build (Ping-Fehlalarm) persistierte ungültige Zugangsdaten,
- verdeckte Tippfehler im obscureText-Passwortfeld blieben unsichtbar.

Fix:
- Passwort-Anzeigen-Umschalter (Auge-Icon) im Login-Dialog.
- URL + Passwort werden getrimmt (Autofill/Tastatur-Leerzeichen).
Ein erfolgreicher Login ueberschreibt die alten gespeicherten Credentials;
der Ping-Fix stellt sicher, dass nur gueltige gespeichert werden.

84/84 Tests gruen, analyze sauber.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tr2UwurtxyJUpWpBSeVmBm
This commit is contained in:
Hermes (Server)
2026-08-20 09:52:07 +02:00
co-authored by Claude Opus 4.8
parent 2e40cc2024
commit 3d1e00646a
2 changed files with 37 additions and 8 deletions
+21 -8
View File
@@ -160,6 +160,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
final passCtrl = TextEditingController();
String selectedUser = 'Dustin';
bool verbindet = false;
bool obscure = true;
String? fehler;
showDialog(
@@ -228,11 +229,20 @@ class _SettingsScreenState extends State<SettingsScreen> {
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<SettingsScreen> {
? 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) {