Shuffle/app/lib/features/auth/domain/resend_origin.dart
cschlaefke 3805c71225
Some checks failed
CI / flutter (pull_request) Failing after 44s
CI / web-build (pull_request) Successful in 51s
CI / supabase (pull_request) Successful in 3s
CI / supabase-tests (pull_request) Successful in 29s
CI / e2e (pull_request) Successful in 2m44s
fix(auth): address review findings for smtp-neutral handling
Refs #37

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-03 12:24:25 +01:00

50 lines
2.2 KiB
Dart

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,
};