Ajoute l'adapter API distant (infrastructure/remote/auth_api.dart, http_api_client.dart) et le stockage sécurisé du token d'auth (infrastructure/security/secure_storage_auth_token_store.dart), câblés dans app_bootstrap.dart. Étend le modèle Drift (migration schemaVersion 9→10) et la couche application (ports, use cases, entités) pour la session de compte. flutter pub get OK (ajout http, flutter_secure_storage), build_runner OK, dart format appliqué, analyze propre (mêmes infos préexistantes), 109/109 tests verts, build APK debug validé. Premier ticket du chantier "Ajouter les features serveur au client" (#63). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
72 lines
2.0 KiB
Dart
72 lines
2.0 KiB
Dart
import '../../application/application.dart';
|
|
import 'http_api_client.dart';
|
|
|
|
final class HttpRemoteAuthApi implements RemoteAuthApi {
|
|
const HttpRemoteAuthApi(this.client);
|
|
|
|
final HttpApiClient client;
|
|
|
|
@override
|
|
Future<RemoteAuthResult> register({
|
|
required String email,
|
|
required String password,
|
|
String? displayName,
|
|
}) async {
|
|
final registered = await client.postJson(
|
|
'/auth/register',
|
|
body: {
|
|
'email': email,
|
|
'password': password,
|
|
if (displayName != null) 'displayName': displayName,
|
|
},
|
|
expectedStatuses: const {201},
|
|
);
|
|
final userId = _requiredString(registered, 'userId');
|
|
final registeredEmail = _requiredString(registered, 'email');
|
|
final loggedIn = await login(email: email, password: password);
|
|
return RemoteAuthResult(
|
|
userId: userId,
|
|
email: registeredEmail,
|
|
token: loggedIn.token,
|
|
expiresAt: loggedIn.expiresAt,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Future<RemoteAuthResult> login({
|
|
required String email,
|
|
required String password,
|
|
}) async {
|
|
final response = await client.postJson(
|
|
'/auth/login',
|
|
body: {'email': email, 'password': password},
|
|
);
|
|
return RemoteAuthResult(
|
|
userId: response['userId'] is String
|
|
? response['userId'] as String
|
|
: email.trim().toLowerCase(),
|
|
email: response['email'] is String
|
|
? response['email'] as String
|
|
: email.trim().toLowerCase(),
|
|
token: _requiredString(response, 'token'),
|
|
expiresAt: DateTime.parse(_requiredString(response, 'expiresAt')).toUtc(),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Future<void> logout(String token) {
|
|
return client.postEmpty('/auth/logout', bearerToken: token);
|
|
}
|
|
|
|
String _requiredString(Map<String, Object?> json, String key) {
|
|
final value = json[key];
|
|
if (value is String && value.trim().isNotEmpty) {
|
|
return value;
|
|
}
|
|
throw RemoteAuthException(
|
|
RemoteAuthFailure.unknown,
|
|
'$key is missing from auth response.',
|
|
);
|
|
}
|
|
}
|