This repository has been archived on 2026-08-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
melo-app/lib/services/auth_service.dart
T

173 lines
5.2 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import '../config/app_config.dart';
import '../services/melo_logger.dart';
/// Baka-Auth Service JWT-basierte Authentifizierung
/// Integriert mit https://baka-net.de/auth
class AuthService {
static final AuthService _instance = AuthService._();
factory AuthService() => _instance;
AuthService._();
String? _token;
String _user = '';
bool _initialisiert = false;
bool get istEingeloggt => _token != null && _token!.isNotEmpty;
String get benutzer => _user;
String? get token => _token;
/// Auth-Header für API-Requests
Map<String, String> get authHeader => {
'Authorization': 'Bearer ${_token ?? ''}',
'Content-Type': 'application/json',
};
/// Lädt gespeicherten Token beim App-Start
Future<void> initialisieren() async {
if (_initialisiert) return;
try {
final prefs = await SharedPreferences.getInstance();
_token = prefs.getString('baka_token');
_user = prefs.getString('baka_user') ?? '';
if (_token != null && _token!.isNotEmpty) {
MeloLogger().zustand('auth_restored', {'user': _user});
}
} catch (e) {
MeloLogger().fehler('auth_init', e);
}
_initialisiert = true;
}
/// Login über Baka-Auth-Server
/// Gibt true zurück bei Erfolg, false bei Fehler
Future<AuthResult> login(String user, String password) async {
try {
final response = await http
.post(
Uri.parse('${AppConfig.authUrl}/login'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'username': user,
'password': password,
}),
)
.timeout(const Duration(seconds: 10));
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
_token = data['token'] as String?;
_user = user;
if (_token != null && _token!.isNotEmpty) {
// Token speichern
final prefs = await SharedPreferences.getInstance();
await prefs.setString('baka_token', _token!);
await prefs.setString('baka_user', _user);
MeloLogger().aktion('auth_login_ok', {'user': _user});
return AuthResult.ok;
}
}
// Fehler vom Server parsen
String fehler = 'Unbekannter Fehler';
try {
final data = jsonDecode(response.body);
fehler = data['error'] as String? ?? 'Login fehlgeschlagen (${response.statusCode})';
} catch (_) {
fehler = 'Server nicht erreichbar (${response.statusCode})';
}
MeloLogger().fehler('auth_login_fail', fehler);
return AuthResult.fehlgeschlagen(fehler);
} catch (e) {
final msg = 'Keine Verbindung zum Auth-Server';
MeloLogger().fehler('auth_login_error', e);
return AuthResult.fehlgeschlagen(msg);
}
}
/// Registrierung über Baka-Auth-Server
Future<AuthResult> registrieren(String user, String password, String email) async {
try {
final response = await http
.post(
Uri.parse('${AppConfig.authUrl}/register'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'username': user,
'password': password,
'email': email,
}),
)
.timeout(const Duration(seconds: 10));
if (response.statusCode == 200 || response.statusCode == 201) {
final data = jsonDecode(response.body);
_token = data['token'] as String?;
_user = user;
if (_token != null && _token!.isNotEmpty) {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('baka_token', _token!);
await prefs.setString('baka_user', _user);
MeloLogger().aktion('auth_register_ok', {'user': _user});
return AuthResult.ok;
}
}
String fehler = 'Registrierung fehlgeschlagen';
try {
final data = jsonDecode(response.body);
fehler = data['error'] as String? ?? fehler;
} catch (_) {}
return AuthResult.fehlgeschlagen(fehler);
} catch (e) {
return AuthResult.fehlgeschlagen('Keine Verbindung zum Server');
}
}
/// Token beim Server validieren
Future<bool> tokenPruefen() async {
if (_token == null) return false;
try {
final response = await http
.get(
Uri.parse('${AppConfig.authUrl}/verify'),
headers: authHeader,
)
.timeout(const Duration(seconds: 5));
return response.statusCode == 200;
} catch (_) {
return false;
}
}
/// Ausloggen Token löschen
Future<void> logout() async {
_token = null;
_user = '';
final prefs = await SharedPreferences.getInstance();
await prefs.remove('baka_token');
await prefs.remove('baka_user');
MeloLogger().aktion('auth_logout', {});
}
}
/// Ergebnis eines Auth-Versuchs
class AuthResult {
final bool erfolg;
final String? fehler;
const AuthResult._(this.erfolg, this.fehler);
static const ok = AuthResult._(true, null);
static AuthResult fehlgeschlagen(String msg) => AuthResult._(false, msg);
}