fix: 6 Claude-Audit-Fixes (3 CRIT + 3 HIGH)

CRITICAL:
- Logout: LoginScreen statt MeloHome pushen (home_screen.dart)
- Path Traversal: sanitizeDateiname() zentral + sync-loop abgesichert
- SecureStorage: flutter_secure_storage für Token+Passwort (auth_service, navidrome)

HIGH:
- Seek: PlayerService.seek() reload-frei (audio_handler)
- Play/Pause: Zielzustand statt Toggle für System-Controls
- X-User: Header entfernt, Server verlässt sich auf JWT
This commit is contained in:
Dustin
2026-08-03 01:41:04 +02:00
parent de71119235
commit e46ffa76a3
10 changed files with 76 additions and 34 deletions
+7 -4
View File
@@ -5,8 +5,10 @@ import 'package:crypto/crypto.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import '../models/song.dart';
import '../database/db_helper.dart';
import '../utils/sanitize.dart';
/// Ein Song aus der Subsonic-API
class SubsonicSong {
@@ -63,6 +65,7 @@ class SubsonicAlbum {
class NavidromeService {
final DbHelper _db = DbHelper();
final FlutterSecureStorage _secure = const FlutterSecureStorage();
String _serverUrl = '';
String _user = '';
@@ -86,7 +89,7 @@ class NavidromeService {
final prefs = await SharedPreferences.getInstance();
final url = prefs.getString('navidrome_url');
final user = prefs.getString('navidrome_user');
final pass = prefs.getString('navidrome_pass');
final pass = await _secure.read(key: 'navidrome_pass');
if (url != null && user != null && pass != null && url.isNotEmpty) {
setCredentials(url, user, pass);
}
@@ -101,7 +104,7 @@ class NavidromeService {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('navidrome_url', url);
await prefs.setString('navidrome_user', user);
await prefs.setString('navidrome_pass', password);
await _secure.write(key: 'navidrome_pass', value: password);
} catch (e) {
debugPrint('Fehler beim Speichern der Navidrome-Zugangsdaten: $e');
}
@@ -178,9 +181,9 @@ class NavidromeService {
final musikDir = Directory('${dir.path}/music');
if (!await musikDir.exists()) await musikDir.create(recursive: true);
final safeName = s.titel.replaceAll(RegExp(r'[^\w\s-]'), '').trim();
final safeName = sanitizeDateiname(s.titel);
final kurzId = s.id.length > 8 ? s.id.substring(0, 8) : s.id;
final dateiName = '${safeName.isEmpty ? "song" : safeName}_$kurzId.mp3';
final dateiName = '${safeName}_$kurzId.mp3';
final dateiPfad = '${musikDir.path}/$dateiName';
final file = File(dateiPfad);