Add reusable two-factor verification for login and money operations (#32)

This commit is contained in:
Stephan D committed 2026-09-12 12:44:34 +02:00
1 parent b7a58b1a87
commit fb40f860d2
41 files changed
+2439 -43

No files matched your search

@@ -1,3 +1,5 @@
import 'two_factor.dart';
/// Ephemeral input: never persist, log, or include passwords in provider state.
class LoginRequest {
const LoginRequest({
@@ -25,12 +27,25 @@ class SignupRequest {
/// An operation result, not proof of a session or an authorization decision.
class AuthResult {
const AuthResult({required this.userId, required this.isSimulated});
const AuthResult({
required this.userId,
required this.isSimulated,
this.challenge,
});
final String userId;
final FactorChallenge? challenge;
final bool isSimulated;
}
enum AuthError { invalidCredentials, emailInUse, unavailable, unexpected }
enum AuthError {
invalidCredentials,
emailInUse,
unavailable,
unexpected,
factorLocked,
factorCooldown,
factorRequired,
}
class AuthException implements Exception {
const AuthException(this.code);
@@ -39,7 +54,7 @@ class AuthException implements Exception {
String toString() => 'AuthException(${code.name})';
}
enum AuthStatus { idle, loading, success, error }
enum AuthStatus { idle, loading, challenge, success, error }
class AuthState {
const AuthState._(this.status, {this.result, this.error});
@@ -47,6 +62,8 @@ class AuthState {
const AuthState.loading() : this._(AuthStatus.loading);
const AuthState.success(AuthResult result)
: this._(AuthStatus.success, result: result);
const AuthState.challenge(AuthResult result)
: this._(AuthStatus.challenge, result: result);
const AuthState.failure(AuthError error)
: this._(AuthStatus.error, error: error);
final AuthStatus status;