import 'package:shuffle/features/auth/domain/auth_failure.dart'; /// Von wo „E-Mail erneut senden“ ausgelöst wird (Spec #1 § 4.4, F12). enum ResendOrigin { /// CheckEmailScreen: Die Adresse kann frei eingegeben sein. checkEmail, /// LoginScreen nach `email_not_confirmed`: Das Passwort war richtig. login, } /// Wendet die Regel aus F12/F13 für „E-Mail erneut senden“ an. /// /// `null` heißt: wie Erfolg behandeln. Sichtbar bleiben nur Eingabe- und /// Transportfehler sowie die kontounabhängige IP-Drosselung (Allowlist). /// Alles andere (auch `unexpected`, z. B. SMTP-Ausfall) ist auf dem /// CheckEmailScreen neutral, weil es zwischen bekannter und unbekannter /// Adresse unterscheiden kann. Im LoginScreen ist das Konto durch das richtige /// Passwort bewiesen: `unexpected` bleibt sichtbar, `emailSendLimited` wird /// zum Drosselungshinweis ([RateLimited]). AuthFailure? resendFailureFor(AuthFailure failure, ResendOrigin origin) { return switch (failure) { EmailSendLimited() => origin == ResendOrigin.login ? const AuthFailure.rateLimited() : null, // Login: the password was right, the account is proven, so a server // failure (e.g. SMTP outage) is shown instead of hidden (S4). Unexpected() => origin == ResendOrigin.login ? failure : null, InvalidEmail() || RateLimited() || NetworkFailure() => failure, _ => null, }; } /// Registrierung und Passwort-Reset (freie Adresseingabe, F12/F13): Sichtbar /// bleiben nur Eingabefehler (`invalidEmail`, `weakPassword`, /// `registrationRejected` mit bekanntem Grund), Transportfehler und die /// kontounabhängige IP-Drosselung (Allowlist). Alles andere, insbesondere /// `emailSendLimited` und `unexpected` (SMTP-Ausfall), zählt wie Erfolg /// (KTO-01 Kriterium 4). Liefert `null` für „wie Erfolg“, sonst den Fehler. AuthFailure? openEmailInputFailureFor(AuthFailure failure) => switch (failure) { InvalidEmail() || WeakPassword() || RateLimited() || NetworkFailure() => failure, // Defense in depth: only with a known trigger reason (the account-dependent // INSERT trigger); an unknown reason could be an SMTP failure. RegistrationRejected(:final reason) when reason != RegistrationRejectionReason.unknown => failure, _ => null, };