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
+13 -15
View File
@@ -1,6 +1,6 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import '../config/app_config.dart';
import '../services/melo_logger.dart';
@@ -11,6 +11,8 @@ class AuthService {
factory AuthService() => _instance;
AuthService._();
final FlutterSecureStorage _secure = const FlutterSecureStorage();
String? _token;
String _user = '';
bool _initialisiert = false;
@@ -34,9 +36,8 @@ class AuthService {
Future<bool> initialisieren() async {
if (_initialisiert) return istEingeloggt;
try {
final prefs = await SharedPreferences.getInstance();
_token = prefs.getString('baka_token');
_user = prefs.getString('baka_user') ?? '';
_token = await _secure.read(key: 'baka_token');
_user = await _secure.read(key: 'baka_user') ?? '';
if (_token != null && _token!.isNotEmpty) {
// Token beim Server validieren (nicht blind vertrauen)
@@ -46,8 +47,8 @@ class AuthService {
MeloLogger().zustand('auth_token_expired', {'user': _user});
_token = null;
_user = '';
await prefs.remove('baka_token');
await prefs.remove('baka_user');
await _secure.delete(key: 'baka_token');
await _secure.delete(key: 'baka_user');
} else {
MeloLogger().zustand('auth_restored', {'user': _user});
}
@@ -100,9 +101,8 @@ class AuthService {
_user = user;
if (_token != null && _token!.isNotEmpty) {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('baka_token', _token!);
await prefs.setString('baka_user', _user);
await _secure.write(key: 'baka_token', value: _token!);
await _secure.write(key: 'baka_user', value: _user);
MeloLogger().aktion('auth_login_ok', {'user': _user});
return AuthResult.ok;
}
@@ -144,9 +144,8 @@ class AuthService {
_user = user;
if (_token != null && _token!.isNotEmpty) {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('baka_token', _token!);
await prefs.setString('baka_user', _user);
await _secure.write(key: 'baka_token', value: _token!);
await _secure.write(key: 'baka_user', value: _user);
MeloLogger().aktion('auth_register_ok', {'user': _user});
return AuthResult.ok;
}
@@ -172,9 +171,8 @@ class AuthService {
Future<void> logout() async {
_token = null;
_user = '';
final prefs = await SharedPreferences.getInstance();
await prefs.remove('baka_token');
await prefs.remove('baka_user');
await _secure.delete(key: 'baka_token');
await _secure.delete(key: 'baka_user');
MeloLogger().aktion('auth_logout', {});
}
}