47 lines
1.7 KiB
Dart
47 lines
1.7 KiB
Dart
import 'package:shuffle/features/auth/domain/auth_status.dart';
|
|
import 'package:shuffle/features/auth/domain/auth_user.dart';
|
|
// `AuthUser` heißt auch in supabase_flutter; hier ist die Domänenklasse gemeint.
|
|
import 'package:supabase_flutter/supabase_flutter.dart' hide AuthUser;
|
|
|
|
/// Bildet `AuthChangeEvent`s auf [AuthStatus] ab (Spec #1 § 5.5).
|
|
///
|
|
/// Abweichung von der Wortlaut-Zuordnung in § 5.5: Die Recovery bleibt
|
|
/// bestehen, bis `userUpdated` (Passwort geändert) oder `signedOut` eintrifft.
|
|
/// Ein `tokenRefreshed` oder `signedIn` während der Recovery hebt den Guard
|
|
/// nicht auf. Der Zustand lebt nur im Prozess (Spec #1 § 5.4, R12): Aus dem
|
|
/// `amr`-Claim lässt er sich nicht ableiten.
|
|
class AuthStatusTracker {
|
|
bool _recovery = false;
|
|
|
|
/// Status für [session] unter Berücksichtigung der laufenden Recovery.
|
|
AuthStatus statusFor(Session? session) {
|
|
final user = session?.user;
|
|
if (user == null) {
|
|
return const AuthStatus.signedOut();
|
|
}
|
|
final authUser = AuthUser(
|
|
id: user.id,
|
|
email: user.email,
|
|
emailConfirmed: user.emailConfirmedAt != null,
|
|
);
|
|
return _recovery
|
|
? AuthStatus.passwordRecovery(authUser)
|
|
: AuthStatus.signedIn(authUser);
|
|
}
|
|
|
|
/// Verarbeitet ein Ereignis und liefert den neuen Status.
|
|
AuthStatus handle(AuthChangeEvent event, Session? session) {
|
|
switch (event) {
|
|
case AuthChangeEvent.passwordRecovery:
|
|
_recovery = session != null;
|
|
case AuthChangeEvent.signedOut || AuthChangeEvent.userUpdated:
|
|
_recovery = false;
|
|
default:
|
|
break;
|
|
}
|
|
if (session == null) {
|
|
_recovery = false;
|
|
}
|
|
return statusFor(session);
|
|
}
|
|
}
|