relatica/lib/services/secrets_service.dart

107 lines
3.1 KiB
Dart
Raw Normal View History

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 = <Profile>{};
2023-02-27 21:05:46 +00:00
List<Profile> get profiles =>
UnmodifiableListView(List.from(_cachedProfiles));
final _secureStorage = const FlutterSecureStorage(
iOptions: IOSOptions(
accessibility: KeychainAccessibility.first_unlock,
),
);
FutureResult<List<Profile>, ExecError> initialize() async {
return await loadProfiles();
}
FutureResult<List<Profile>, 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<List<Profile>, ExecError> addOrUpdateProfile(
Profile profile) async {
try {
_cachedProfiles.remove(profile);
_cachedProfiles.add(profile);
return await saveCredentials();
} on PlatformException catch (e) {
return Result.error(ExecError(
type: ErrorType.localError,
message: e.message ?? '',
));
}
}
FutureResult<List<Profile>, 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<List<Profile>, ExecError> loadProfiles() async {
try {
final basicJson = await _secureStorage.read(key: _basicProfilesKey);
if (basicJson == null) {
return Result.ok(profiles);
}
final basicCreds = (jsonDecode(basicJson) as List<dynamic>)
.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<List<Profile>, 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 ?? '',
));
}
}
}