import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:hub/shared/utils/cache_util.dart'; import 'package:hub/shared/utils/storage_util.dart'; class SecureStorageHelper extends ChangeNotifier implements Storage { static final SecureStorageHelper _instance = SecureStorageHelper._internal(); final FlutterSecureStorage _secureStorage = const FlutterSecureStorage(); factory SecureStorageHelper() => _instance; SecureStorageHelper._internal(); static SecureStorageHelper get instance => _instance; Future setAndCacheString(String key, String value, Function(String) cacheSetter) async { log('SecureStorageHelper -> setAndCacheString value for key: $key to $value'); await _secureStorage.write(key: key, value: value); CacheUtil.instance.set(key, value); cacheSetter(value); } Future setAndCacheBool(String key, bool value, Function(bool) cacheSetter) async { log('SecureStorageHelper -> setAndCacheBool value for key: $key to $value'); await _secureStorage.write(key: key, value: value.toString()); CacheUtil.instance.set(key, value); cacheSetter(value); } Future setAndCacheObject(String key, String value, Function(String) cacheSetter) async { log('SecureStorageHelper -> setAndCacheObject value for key: $key to $value'); await _secureStorage.write(key: key, value: value); CacheUtil.instance.set(key, value); cacheSetter(value); } Future getString(String key) async { var value = CacheUtil.instance.get(key); if (value == null) { value = await _secureStorage.read(key: key); CacheUtil.instance.set(key, value); } log('SecureStorageHelper -> getString $value for key: $key'); return value; } Future getBool(String key) async { var value = CacheUtil.instance.get(key); if (value == null || value == 'null') { value = await _secureStorage.read(key: key); CacheUtil.instance.set(key, value); log('SecureStorageHelper -> getBool $value for key: $key'); return value == 'true'; } log('SecureStorageHelper -> getBool $value for key: $key'); return value == 'true' || value == true; } Future getObject(String key) async { var value = CacheUtil.instance.get(key); if (value == null) { value = await _secureStorage.read(key: key); CacheUtil.instance.set(key, value); } log('SecureStorageHelper -> getObject $value for key: $key'); return value as BuildContext?; } @override Future set(String key, dynamic value, Function(dynamic) cacheSetter) async { if (value is String? || value is String) { await setAndCacheString(key, value!, cacheSetter); } else if (value is bool? || value is bool) { await setAndCacheBool(key, value, cacheSetter); } else if (value is BuildContext || value is BuildContext?) { await setAndCacheObject(key, value.toString(), cacheSetter); } } @override Future get(String key) async { log('SecureStorageHelper -> get value for key: $key'); var stringValue = await getString(key); if (stringValue != null) return stringValue; var boolValue = await getBool(key); if (boolValue != null) return boolValue; var objectValue = await getObject(key); if (objectValue != null) return objectValue; return null; } @override Future delete(String key) async { log('SecureStorageHelper -> delete value for key: $key'); await _secureStorage.delete(key: key); CacheUtil.instance.delete(key); } Future purge() async { log('SecureStorageHelper -> Purging secure storage'); await _secureStorage.deleteAll(); CacheUtil.instance.clear(); } }