Commit Graph
10 Commits
Author SHA1 Message Date
Dustin dfa19c999b v2.50.3 — sanitize.dart gehärtet: Windows-Namen + Traversal-Sequenzen
## lib/utils/sanitize.dart
- Windows-reservierte Namen (CON, NUL, PRN, AUX, COM1-9, LPT1-9) abgefangen — auch mit Endung (CON.txt) und case-insensitiv; COM10/LPT10 bleiben erlaubt
- Mehrfache ..-Sequenzen nach Sonderzeichen-Entfernung → unknown
- Trimmen VOR der Punkt-Prüfung (Regression: ' ..' ergab vorher '..' = Path-Traversal)
- Trailing Punkte/Leerzeichen entfernt (Windows-Dateisystem ignoriert sie)
- Umlaute bleiben erhalten (unicode:true + \p{L}/\p{N} statt ASCII-\w — 'Müller.mp3' wurde vorher zu 'Mller.mp3')

## test/sanitize_test.dart (18 Tests)
- Traversal: Slash/Backslash-Pfade, '..', ' ..', '..:..', versteckte Dateien
- Windows: alle reservierten Namen exakt/mit Endung/case-insensitiv, COM10-Freigabe, Prefix-Fälle (console, LPT1 - Drucker)
- Normalisierung: NULL-Bytes, Steuerzeichen, Sonderzeichen, trailing Dots, leer, 200-Limit, Umlaute
2026-08-04 20:48:31 +02:00
Dustin 5b5f72b548 v2.50.2 — Cloud/Auth-Tests (http-Mocks): LWW-Sync + Token-Ablauf-Pfade
## Testbarkeit (kein neues Package)
- CloudService: http.Client injizierbar (Konstruktor-Parameter, Default unverändert)
- AuthService: http.Client + TokenSpeicher injizierbar; SecureTokenSpeicher kapselt FlutterSecureStorage, @visibleForTesting AuthService.fuerTests
- Alle HTTP-Calls über _client statt Top-Level http.get/post

## test/cloud_service_test.dart (22 Tests)
- login: 200/401/Netzwerkfehler
- verbinde() ohne Benutzer → Status fehler, kein Request
- statusDaten: 200/401(Auth-Fehler)/Netzwerkfehler
- syncChanges LWW-Konflikt-Pfade: updated_at bleibt für Client-Vergleich erhalten, leere/fehlende Changes, 401 → [], Netzwerkfehler → [], since-Body
- syncAll (LWW-Schreibpfad): 200/401
- Playlists, Favoriten, History, listSongs, delete, globalList inkl. Fehlerpfade

## test/auth_service_test.dart (19 Tests)
- initialisieren: 200 → eingeloggt, 401 → Logout + Speicher gelöscht, Netzwerkfehler → Offline-Trust, 5xx → Token bleibt, ohne Token → kein Request
- tokenPruefen: 200/401/Netzwerkfehler/503
- login: ok mit Persistenz, 401, 200-ohne-Token (Fall-Through-Regression), Netzwerkfehler
- logout löscht Speicher, authHeader mit/ohne Bearer
2026-08-04 20:46:51 +02:00
Dustin 8e9d9efc64 v2.49.5 — Play-Next verschiebt statt zu duplizieren + Shuffle-Priorität
## Fix (Code-Review Finding 3, MED)
- spieleAlsNaechstes: Song bereits in der Queue wird an Position nach dem
  aktuellen VERSCHOBEN (inkl. _aktuellerIndex-Anpassung), keine Kopie mehr
- Shuffle: keine Neu-Mischung nach Play-Next — Song wird via
  _pinneInShuffleReihenfolge an die nächste Position gepinnt (Index-
  Korrektur für Verschiebungen, _shufflePos-Nachführung am Reihenende)
- 3 Tests ergänzt: Verschieben statt Duplizieren, Song von vor dem
  aktuellen, Shuffle-Pin (kein Duplikat + naechsterIndex == gepinnter Song)
2026-08-04 16:47:29 +02:00
Dustin c6826db651 v2.49.3 — Shuffle-Edge-Case: Einzel-Song-Queue + Repeat-aus → Queue-Ende
## Fix (Code-Review Finding 1, HIGH)
- _baueShuffleReihenfolge: Index 0 nur noch bei Repeat-playlist in die
  Shuffle-Reihenfolge aufnehmen (Einzel-Song-Queue)
- naechsterIndex: Sicherheitsnetz gegen stale Reihenfolge — Kandidat ==
  aktueller Song bei Repeat-aus liefert null (Queue-Ende) statt denselben
  Song erneut
- Test ergänzt: shuffle + repeat aus + 1-Song-Queue → null
2026-08-04 16:46:08 +02:00
Dustin 4226612065 v2.49 — Lyrics-Service (LRC + Netease)
## LyricsService (neu: lib/services/lyrics_service.dart)
- LyricsZeile-Modell (zeit + text)
- LRC-Parser: [mm:ss], [mm:ss.xx], [mm:ss.xxx], mehrere Zeitstempel/Zeile, [offset:±ms], Meta-Tags ignoriert, Karaoke-Tags <...> entfernt, sortiert
- Quellen: lokale .lrc neben dem Song (song.dateiPfad → .lrc) → Netease-API (Suche + Lyric, public, kein Key) → null
- Keine neuen Packages (nur http)

## Tests (test/lyrics_service_test.dart, 14 neu)
- parseLrc: Formate, Multi-Timestamps, Offset, Sortierung, Karaoke-Tags
- indexFuerPosition: Grenzfälle
- ladeLyrics: lokale .lrc-Datei (Temp-Datei), ohne Datei → null (HTTP im Test geblockt)
- flutter analyze 0 Issues, Tests 35/35
2026-08-04 16:35:19 +02:00
Dustin b97914699e v2.48.5 — Tests für Player-Kern (Shuffle/Repeat/Queue/Sleep-Timer)
## test/player_service_test.dart (neu, 17 Tests)
- Warteschlange: setWarteschlange, unveränderliche Kopie, spieleAlsNaechstes,
  amEndeHinzufuegen, verschiebeInWarteschlange (Index-Anpassung)
- Repeat: aus (Ende → null), titel (immer aktuell), playlist (Wrap von vorn)
- Shuffle: alle anderen Songs genau einmal ohne Wiederholung, kein aktueller
  Song; shuffle+playlist mischt nach Durchlauf neu; Einzel-Song-Queue;
  Ausschluss des aktuellen Index nach Umsortieren
- Sleep-Timer: aktivieren, Restzeit, abbrechen, Ersetzen

flutter analyze 0 Issues, Tests 21/21
2026-08-04 16:27:36 +02:00
Dustin 4c987036bc v2.45.1 — Auto-Scan ohne AudioPlayer: Byte-Parser für Dauer (MP3/M4A/FLAC/WAV), MPEG-Header-Offset fix, WAV Little-Endian fix 2026-08-03 02:47:05 +02:00
Dustin 2d4c7c8b98 v2.32 — Defekte Musik erkennen (Magic Bytes, ffprobe, DB-Flag, UI) 2026-08-01 16:40:42 +02:00
Dustin 36c744d6e3 v2.31 — Login, Einstellungen & Cloud Sync Redesign
- Login-Screen im Melo-Design (Schwarz+Rot) mit Baka-Auth JWT
- AuthService fuer Token-Management ueber baka-net.de/auth
- Registrierungs-Modus + 'Ohne Login fortfahren'
- Navidrome-Credentials optional im Login aufklappbar

- SettingsScreen ersetzt AlertDialog
- BottomNav navigiert statt Dialog zu triggern
- Cloud Sync, Server verbinden, Diagnosedaten, App-Info, Abmelden

- CloudEinstellungen-Dialog entfernt, alles in CloudScreen konsolidiert
- Hardcode login('Baka','') entfernt → AuthService.benutzer
- Gradient-Statuskarte, animierte Segment-Intervall-Auswahl
- JWT Authorization statt Klartext-Passwort

- AppConfig: API-Key defaultValue entfernt (kein Fallback-Leak)
- Build crasht ohne --dart-define MELO_API_KEY

Build: split APK (arm64 19.6M, armeabi 17.1M, x86_64 21.1M)
2026-08-01 15:03:22 +02:00
Dustin-Mike Jens Hähnel 94a4063070 Initial commit 2026-07-23 14:31:28 +02:00