Add shared authentication and email verification services
Provide reusable models, injectable service contracts, lifecycle-safe providers and explicit dummy implementations for login, signup and verification. Add focused error and async lifecycle tests. Related to #4 and #5.
This commit is contained in:
1 parent
d9318053e8
commit
27424ed886
15 files changed
+708
No files matched your search
@@ -0,0 +1,56 @@
|
||||
/// Ephemeral input: never persist, log, or include passwords in provider state.
|
||||
class LoginRequest {
|
||||
const LoginRequest({
|
||||
required this.email,
|
||||
required this.password,
|
||||
required this.locale,
|
||||
});
|
||||
final String email;
|
||||
final String password;
|
||||
final String locale;
|
||||
}
|
||||
|
||||
class SignupRequest {
|
||||
const SignupRequest({
|
||||
required this.name,
|
||||
required this.email,
|
||||
required this.password,
|
||||
required this.locale,
|
||||
});
|
||||
final String name;
|
||||
final String email;
|
||||
final String password;
|
||||
final String locale;
|
||||
}
|
||||
|
||||
/// An operation result, not proof of a session or an authorization decision.
|
||||
class AuthResult {
|
||||
const AuthResult({required this.userId, required this.isSimulated});
|
||||
final String userId;
|
||||
final bool isSimulated;
|
||||
}
|
||||
|
||||
enum AuthError { invalidCredentials, emailInUse, unavailable, unexpected }
|
||||
|
||||
class AuthException implements Exception {
|
||||
const AuthException(this.code);
|
||||
final AuthError code;
|
||||
@override
|
||||
String toString() => 'AuthException(${code.name})';
|
||||
}
|
||||
|
||||
enum AuthStatus { idle, loading, success, error }
|
||||
|
||||
class AuthState {
|
||||
const AuthState._(this.status, {this.result, this.error});
|
||||
const AuthState.idle() : this._(AuthStatus.idle);
|
||||
const AuthState.loading() : this._(AuthStatus.loading);
|
||||
const AuthState.success(AuthResult result)
|
||||
: this._(AuthStatus.success, result: result);
|
||||
const AuthState.failure(AuthError error)
|
||||
: this._(AuthStatus.error, error: error);
|
||||
final AuthStatus status;
|
||||
final AuthResult? result;
|
||||
final AuthError? error;
|
||||
bool get isLoading => status == AuthStatus.loading;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
enum VerificationStatus {
|
||||
idle,
|
||||
sending,
|
||||
sent,
|
||||
checking,
|
||||
verified,
|
||||
expired,
|
||||
invalid,
|
||||
error,
|
||||
}
|
||||
|
||||
enum VerificationError { expired, invalid, internal }
|
||||
|
||||
class VerificationException implements Exception {
|
||||
const VerificationException(this.code);
|
||||
final VerificationError code;
|
||||
}
|
||||
|
||||
class VerificationResult {
|
||||
const VerificationResult({required this.isSimulated});
|
||||
final bool isSimulated;
|
||||
}
|
||||
|
||||
class VerificationState {
|
||||
const VerificationState(this.status, {this.isSimulated = false});
|
||||
final VerificationStatus status;
|
||||
final bool isSimulated;
|
||||
bool get isLoading =>
|
||||
status == VerificationStatus.sending ||
|
||||
status == VerificationStatus.checking;
|
||||
}
|
||||
Reference in new issue
Block a user