Add reusable two-factor verification for login and money operations (#32)
This commit is contained in:
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;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
enum FactorMethod { email, authenticator }
|
||||
|
||||
enum FactorPurpose { login, topUp, exchange, payout, enable, disable }
|
||||
|
||||
enum FactorError { invalid, expired, locked, cooldown, unavailable, required }
|
||||
|
||||
class FactorException implements Exception {
|
||||
const FactorException(this.code);
|
||||
final FactorError code;
|
||||
}
|
||||
|
||||
class FactorSettings {
|
||||
const FactorSettings({
|
||||
required this.enabled,
|
||||
required this.target,
|
||||
this.method = FactorMethod.email,
|
||||
});
|
||||
final bool enabled;
|
||||
final FactorMethod method;
|
||||
final String target;
|
||||
}
|
||||
|
||||
class FactorChallenge {
|
||||
const FactorChallenge({
|
||||
required this.id,
|
||||
required this.purpose,
|
||||
required this.operation,
|
||||
required this.target,
|
||||
required this.expiresAt,
|
||||
required this.resendAt,
|
||||
this.method = FactorMethod.email,
|
||||
});
|
||||
final String id, operation, target;
|
||||
final FactorPurpose purpose;
|
||||
final FactorMethod method;
|
||||
final DateTime expiresAt, resendAt;
|
||||
}
|
||||
|
||||
class FactorGrant {
|
||||
const FactorGrant(this.token);
|
||||
final String token;
|
||||
}
|
||||
Reference in new issue
Block a user