import 'dart:collection'; import 'dart:convert'; import 'package:flutter/services.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:result_monad/result_monad.dart'; import '../models/auth/basic_credentials.dart'; import '../models/auth/profile.dart'; import '../models/exec_error.dart'; class SecretsService { static const _basicProfilesKey = 'basic_profiles'; static const _oauthProfilesKey = 'oauth_profiles'; final _cachedProfiles = {}; List get profiles => UnmodifiableListView(_cachedProfiles); final _secureStorage = const FlutterSecureStorage( iOptions: IOSOptions( accessibility: KeychainAccessibility.first_unlock, ), ); FutureResult, ExecError> initialize() async { return await loadProfiles(); } FutureResult, ExecError> clearCredentials() async { try { await _secureStorage.delete(key: _basicProfilesKey); await _secureStorage.delete(key: _oauthProfilesKey); return Result.ok(profiles); } on PlatformException catch (e) { return Result.error(ExecError( type: ErrorType.localError, message: e.message ?? '', )); } } FutureResult, ExecError> addOrUpdateProfile( Profile profile) async { try { _cachedProfiles.add(profile); return await saveCredentials(); } on PlatformException catch (e) { return Result.error(ExecError( type: ErrorType.localError, message: e.message ?? '', )); } } FutureResult, ExecError> removeProfile(Profile profile) async { try { _cachedProfiles.remove(profile); return await saveCredentials(); } on PlatformException catch (e) { return Result.error(ExecError( type: ErrorType.localError, message: e.message ?? '', )); } } FutureResult, ExecError> loadProfiles() async { try { final basicJson = await _secureStorage.read(key: _basicProfilesKey); if (basicJson == null) { return Result.ok(profiles); } final basicCreds = (jsonDecode(basicJson) as List) .map((json) => Profile.fromJson(json, BasicCredentials.fromJson)) .toList(); _cachedProfiles.addAll(basicCreds); return Result.ok(profiles); } on PlatformException catch (e) { return Result.error(ExecError( type: ErrorType.localError, message: e.message ?? '', )); } } FutureResult, ExecError> saveCredentials() async { try { final basicCredsJson = _cachedProfiles .where((p) => p.credentials is BasicCredentials) .map((p) => p.toJson()) .toList(); final basicCredsString = jsonEncode(basicCredsJson); await _secureStorage.write( key: _basicProfilesKey, value: basicCredsString); return Result.ok(profiles); } on PlatformException catch (e) { return Result.error(ExecError( type: ErrorType.localError, message: e.message ?? '', )); } } }