import 'dart:convert'; import 'package:logging/logging.dart'; import 'package:pshared/api/errors/unauthorized.dart'; import 'package:pshared/api/responses/token.dart'; import 'package:pshared/config/constants.dart'; import 'package:pshared/service/secure_storage.dart'; class AuthorizationStorage { static final _logger = Logger('service.authorization.storage'); static Future _getTokenData(String tokenKey) async { _logger.fine('Getting token data'); final String? tokenJson = await SecureStorageService.get(tokenKey); if (tokenJson == null || tokenJson.isEmpty) { throw ErrorUnauthorized(); } return TokenData.fromJson(jsonDecode(tokenJson)); } static Future _checkTokenUsable(String keyName) async { final hasKey = await SecureStorageService.containsKey(keyName); if (!hasKey) return false; try { final tokenData = await _getTokenData(keyName); return tokenData.expiration.isAfter(DateTime.now()); } catch (e, st) { _logger.warning('Error reading token from $keyName: $e', e, st); rethrow; } } static Future isAuthorizationStored() async { _logger.fine('Checking if authorization is stored'); final accessUsable = await _checkTokenUsable(Constants.accessTokenStorageKey); if (accessUsable) return true; final refreshUsable = await _checkTokenUsable(Constants.refreshTokenStorageKey); if (refreshUsable) return true; return false; } static Future getAccessToken() async { _logger.fine('Getting access token'); return _getTokenData(Constants.accessTokenStorageKey); } static Future getRefreshToken() async { _logger.fine('Getting refresh token'); return _getTokenData(Constants.refreshTokenStorageKey); } static Future updateToken(TokenData tokenData) async { _logger.fine('Storing access token...'); final tokenJson = jsonEncode(tokenData.toJson()); await SecureStorageService.set(Constants.accessTokenStorageKey, tokenJson); } static Future updateRefreshToken(TokenData tokenData) async { _logger.fine('Storing refresh token...'); final refreshTokenJson = jsonEncode(tokenData.toJson()); await SecureStorageService.set(Constants.refreshTokenStorageKey, refreshTokenJson); } static Future removeTokens() { return Future.wait([ SecureStorageService.delete(Constants.refreshTokenStorageKey), SecureStorageService.delete(Constants.accessTokenStorageKey), ]); } }