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:
Stephan D committed 2026-09-11 15:36:58 +02:00
1 parent d9318053e8
commit 27424ed886
15 files changed
+708

No files matched your search

@@ -0,0 +1,46 @@
import 'package:flutter/foundation.dart';
import '../models/auth.dart';
/// Shared operation lifecycle adapted from Sendico's ChangeNotifier providers.
/// Reset invalidates pending results; it does not cancel service-side work.
abstract class AuthProvider extends ChangeNotifier {
AuthState _state = const AuthState.idle();
int _generation = 0;
bool _disposed = false;
AuthState get state => _state;
@protected
Future<void> run(Future<AuthResult> Function() operation) async {
if (_disposed || _state.isLoading) return;
final generation = ++_generation;
_state = const AuthState.loading();
notifyListeners();
try {
final result = await operation();
if (_disposed || generation != _generation) return;
_state = AuthState.success(result);
} catch (error) {
if (_disposed || generation != _generation) return;
// Never retain or expose arbitrary exceptions that may contain credentials.
_state = AuthState.failure(
error is AuthException ? error.code : AuthError.unexpected,
);
}
if (!_disposed && generation == _generation) notifyListeners();
}
void reset() {
if (_disposed) return;
++_generation;
_state = const AuthState.idle();
notifyListeners();
}
@override
void dispose() {
_disposed = true;
++_generation;
super.dispose();
}
}