import 'package:flutter_appauth/flutter_appauth.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import '../config.dart'; /// Authentification OIDC pocket-id (Authorization Code + PKCE, client public). /// Le jeton d'identité (JWT) est stocké de façon sécurisée et envoyé à l'API. class AuthService { final _appAuth = const FlutterAppAuth(); final _storage = const FlutterSecureStorage(); static const _kIdToken = 'id_token'; static const _kRefresh = 'refresh_token'; static const _kExpiry = 'access_expiry'; Future get idToken => _storage.read(key: _kIdToken); Future isLoggedIn() async => (await idToken) != null; Future login() async { final result = await _appAuth.authorizeAndExchangeCode( AuthorizationTokenRequest( Config.oidcClientId, Config.oidcRedirect, issuer: Config.oidcIssuer, scopes: Config.oidcScopes, promptValues: ['login'], ), ); if (result.idToken == null) return false; await _storage.write(key: _kIdToken, value: result.idToken); await _storage.write(key: _kRefresh, value: result.refreshToken); await _storage.write( key: _kExpiry, value: result.accessTokenExpirationDateTime?.toIso8601String(), ); return true; } /// Rafraîchit le jeton si expiré (via refresh_token), renvoie l'id_token courant. Future validToken() async { final expiry = await _storage.read(key: _kExpiry); final refresh = await _storage.read(key: _kRefresh); if (expiry != null && refresh != null) { final exp = DateTime.tryParse(expiry); if (exp != null && exp.isBefore(DateTime.now().add(const Duration(seconds: 30)))) { try { final r = await _appAuth.token(TokenRequest( Config.oidcClientId, Config.oidcRedirect, issuer: Config.oidcIssuer, refreshToken: refresh, scopes: Config.oidcScopes, )); if (r.idToken != null) { await _storage.write(key: _kIdToken, value: r.idToken); await _storage.write(key: _kRefresh, value: r.refreshToken ?? refresh); await _storage.write( key: _kExpiry, value: r.accessTokenExpirationDateTime?.toIso8601String(), ); } } catch (_) {/* on garde l'ancien token, l'API renverra 401 si mort */} } } return idToken; } Future logout() async => _storage.deleteAll(); }