From d664f0a16fd030ed8dae530df66cf6356d6d3aa7 Mon Sep 17 00:00:00 2001 From: Matthew Fosse Date: Mon, 22 Jan 2024 16:30:16 -0800 Subject: [PATCH] Cw 540 encrypt shared (#1269) * start writing migration * save * finishing up migration * more fixes * fixes * migration fixes * remove commented code and ensure widget initialization in root.dart * use securekey static functions everywhere applicable --- lib/core/auth_service.dart | 8 +- lib/core/backup_service.dart | 85 +--- lib/di.dart | 24 +- lib/entities/default_settings_migration.dart | 79 ++++ lib/entities/preferences_key.dart | 26 +- lib/entities/secret_store_key.dart | 65 +++ lib/main.dart | 2 +- lib/src/screens/root/root.dart | 14 +- lib/store/settings_store.dart | 427 ++++++++++++------ .../security_settings_view_model.dart | 2 +- .../wallet_list/wallet_list_view_model.dart | 2 +- 11 files changed, 452 insertions(+), 282 deletions(-) diff --git a/lib/core/auth_service.dart b/lib/core/auth_service.dart index c072bf65e..a99aef31d 100644 --- a/lib/core/auth_service.dart +++ b/lib/core/auth_service.dart @@ -72,11 +72,11 @@ class AuthService with Store { void saveLastAuthTime() { int timestamp = DateTime.now().millisecondsSinceEpoch; - sharedPreferences.setInt(PreferencesKey.lastAuthTimeMilliseconds, timestamp); + secureStorage.write(key: SecureKey.lastAuthTimeMilliseconds, value: timestamp.toString()); } - bool requireAuth() { - final timestamp = sharedPreferences.getInt(PreferencesKey.lastAuthTimeMilliseconds); + Future requireAuth() async { + final timestamp = int.tryParse(await secureStorage.read(key: SecureKey.lastAuthTimeMilliseconds) ?? '0'); final duration = _durationToRequireAuth(timestamp ?? 0); final requiredPinInterval = settingsStore.pinTimeOutDuration; @@ -100,7 +100,7 @@ class AuthService with Store { 'Either route or onAuthSuccess param must be passed.'); if (!conditionToDetermineIfToUse2FA) { - if (!requireAuth() && !_alwaysAuthenticateRoutes.contains(route)) { + if (!(await requireAuth()) && !_alwaysAuthenticateRoutes.contains(route)) { if (onAuthSuccess != null) { onAuthSuccess(true); } else { diff --git a/lib/core/backup_service.dart b/lib/core/backup_service.dart index 7dd0b50f3..9b5c4c8db 100644 --- a/lib/core/backup_service.dart +++ b/lib/core/backup_service.dart @@ -213,8 +213,6 @@ class BackupService { final defaultBuyProvider = data[PreferencesKey.defaultBuyProvider] as int?; final currentTransactionPriorityKeyLegacy = data[PreferencesKey.currentTransactionPriorityKeyLegacy] as int?; - final allowBiometricalAuthentication = - data[PreferencesKey.allowBiometricalAuthenticationKey] as bool?; final currentBitcoinElectrumSererId = data[PreferencesKey.currentBitcoinElectrumSererIdKey] as int?; final currentLanguageCode = data[PreferencesKey.currentLanguageCode] as String?; @@ -227,23 +225,6 @@ class BackupService { data[PreferencesKey.currentDefaultSettingsMigrationVersion] as int?; final moneroTransactionPriority = data[PreferencesKey.moneroTransactionPriority] as int?; final bitcoinTransactionPriority = data[PreferencesKey.bitcoinTransactionPriority] as int?; - final selectedCake2FAPreset = data[PreferencesKey.selectedCake2FAPreset] as int?; - final shouldRequireTOTP2FAForAccessingWallet = - data[PreferencesKey.shouldRequireTOTP2FAForAccessingWallet] as bool?; - final shouldRequireTOTP2FAForSendsToContact = - data[PreferencesKey.shouldRequireTOTP2FAForSendsToContact] as bool?; - final shouldRequireTOTP2FAForSendsToNonContact = - data[PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact] as bool?; - final shouldRequireTOTP2FAForSendsToInternalWallets = - data[PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets] as bool?; - final shouldRequireTOTP2FAForExchangesToInternalWallets = - data[PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets] as bool?; - final shouldRequireTOTP2FAForAddingContacts = - data[PreferencesKey.shouldRequireTOTP2FAForAddingContacts] as bool?; - final shouldRequireTOTP2FAForCreatingNewWallets = - data[PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets] as bool?; - final shouldRequireTOTP2FAForAllSecurityAndBackupSettings = - data[PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings] as bool?; final sortBalanceTokensBy = data[PreferencesKey.sortBalanceBy] as int?; final pinNativeTokenAtTop = data[PreferencesKey.pinNativeTokenAtTop] as bool?; final useEtherscan = data[PreferencesKey.useEtherscan] as bool?; @@ -294,14 +275,7 @@ class BackupService { if (currentTransactionPriorityKeyLegacy != null) await _sharedPreferences.setInt( PreferencesKey.currentTransactionPriorityKeyLegacy, currentTransactionPriorityKeyLegacy); - - if (DeviceInfo.instance.isDesktop) { - await _sharedPreferences.setBool(PreferencesKey.allowBiometricalAuthenticationKey, false); - } else if (allowBiometricalAuthentication != null) { - await _sharedPreferences.setBool( - PreferencesKey.allowBiometricalAuthenticationKey, allowBiometricalAuthentication); - } - + if (currentBitcoinElectrumSererId != null) await _sharedPreferences.setInt( PreferencesKey.currentBitcoinElectrumSererIdKey, currentBitcoinElectrumSererId); @@ -344,43 +318,6 @@ class BackupService { await _sharedPreferences.setInt( PreferencesKey.bitcoinTransactionPriority, bitcoinTransactionPriority); - if (selectedCake2FAPreset != null) - await _sharedPreferences.setInt(PreferencesKey.selectedCake2FAPreset, selectedCake2FAPreset); - - if (shouldRequireTOTP2FAForAccessingWallet != null) - await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForAccessingWallet, - shouldRequireTOTP2FAForAccessingWallet); - - if (shouldRequireTOTP2FAForSendsToContact != null) - await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForSendsToContact, - shouldRequireTOTP2FAForSendsToContact); - - if (shouldRequireTOTP2FAForSendsToNonContact != null) - await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact, - shouldRequireTOTP2FAForSendsToNonContact); - - if (shouldRequireTOTP2FAForSendsToInternalWallets != null) - await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets, - shouldRequireTOTP2FAForSendsToInternalWallets); - - if (shouldRequireTOTP2FAForExchangesToInternalWallets != null) - await _sharedPreferences.setBool( - PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets, - shouldRequireTOTP2FAForExchangesToInternalWallets); - - if (shouldRequireTOTP2FAForAddingContacts != null) - await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForAddingContacts, - shouldRequireTOTP2FAForAddingContacts); - - if (shouldRequireTOTP2FAForCreatingNewWallets != null) - await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets, - shouldRequireTOTP2FAForCreatingNewWallets); - - if (shouldRequireTOTP2FAForAllSecurityAndBackupSettings != null) - await _sharedPreferences.setBool( - PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings, - shouldRequireTOTP2FAForAllSecurityAndBackupSettings); - if (sortBalanceTokensBy != null) await _sharedPreferences.setInt(PreferencesKey.sortBalanceBy, sortBalanceTokensBy); @@ -532,8 +469,6 @@ class BackupService { PreferencesKey.currentPinLength: _sharedPreferences.getInt(PreferencesKey.currentPinLength), PreferencesKey.currentTransactionPriorityKeyLegacy: _sharedPreferences.getInt(PreferencesKey.currentTransactionPriorityKeyLegacy), - PreferencesKey.allowBiometricalAuthenticationKey: - _sharedPreferences.getBool(PreferencesKey.allowBiometricalAuthenticationKey), PreferencesKey.currentBitcoinElectrumSererIdKey: _sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey), PreferencesKey.currentLanguageCode: @@ -550,24 +485,6 @@ class BackupService { _sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority), PreferencesKey.currentFiatApiModeKey: _sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey), - PreferencesKey.selectedCake2FAPreset: - _sharedPreferences.getInt(PreferencesKey.selectedCake2FAPreset), - PreferencesKey.shouldRequireTOTP2FAForAccessingWallet: - _sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAccessingWallet), - PreferencesKey.shouldRequireTOTP2FAForSendsToContact: - _sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToContact), - PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact: - _sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact), - PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets: - _sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets), - PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets: _sharedPreferences - .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets), - PreferencesKey.shouldRequireTOTP2FAForAddingContacts: - _sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAddingContacts), - PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets: - _sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets), - PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings: _sharedPreferences - .getBool(PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings), PreferencesKey.sortBalanceBy: _sharedPreferences.getInt(PreferencesKey.sortBalanceBy), PreferencesKey.pinNativeTokenAtTop: _sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop), diff --git a/lib/di.dart b/lib/di.dart index 61a04bf1c..a37c76b34 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -276,6 +276,7 @@ Future setup({ if (!_isSetupFinished) { getIt.registerSingletonAsync(() => SharedPreferences.getInstance()); + getIt.registerSingleton(secureStorage); } if (!_isSetupFinished) { getIt.registerFactory(() => BackgroundTasks()); @@ -302,7 +303,6 @@ Future setup({ getIt.registerFactory>(() => _nodeSource); getIt.registerFactory>(() => _powNodeSource, instanceName: Node.boxName + "pow"); - getIt.registerSingleton(secureStorage); getIt.registerSingleton(AuthenticationStore()); getIt.registerSingleton(WalletListStore()); getIt.registerSingleton(NodeListStoreBase.instance); @@ -344,17 +344,19 @@ Future setup({ walletInfoSource: _walletInfoSource)); getIt.registerFactoryParam( - (type, _) => AdvancedPrivacySettingsViewModel(type, getIt.get())); + (type, _) => AdvancedPrivacySettingsViewModel(type, getIt.get())); getIt.registerFactory(() => WalletLoadingService( getIt.get(), getIt.get(), (WalletType type) => getIt.get(param1: type))); - - getIt.registerFactoryParam((type, _) => - WalletNewVM(getIt.get(), - getIt.get(param1: type), _walletInfoSource, - getIt.get(param1: type),type: type)); + + getIt.registerFactoryParam((type, _) => WalletNewVM( + getIt.get(), + getIt.get(param1: type), + _walletInfoSource, + getIt.get(param1: type), + type: type)); getIt.registerFactoryParam((WalletType type, _) { return WalletRestorationFromQRVM(getIt.get(), @@ -805,8 +807,7 @@ Future setup({ .registerFactory(() => DFXBuyProvider(wallet: getIt.get().wallet!)); getIt.registerFactory(() => MoonPaySellProvider( - settingsStore: getIt.get().settingsStore, - wallet: getIt.get().wallet!)); + settingsStore: getIt.get().settingsStore, wallet: getIt.get().wallet!)); getIt.registerFactory(() => OnRamperBuyProvider( getIt.get().settingsStore, @@ -919,8 +920,7 @@ Future setup({ (param1, isCreate) => NewWalletTypePage(onTypeSelected: param1, isCreate: isCreate ?? true)); getIt.registerFactoryParam( - (seedPhraseLength, _) - => PreSeedPage(seedPhraseLength)); + (seedPhraseLength, _) => PreSeedPage(seedPhraseLength)); getIt.registerFactoryParam((trade, _) => TradeDetailsViewModel( @@ -954,7 +954,7 @@ Future setup({ getIt.registerFactory(() => BuyAmountViewModel()); getIt.registerFactoryParam( - (isBuyOption, _) => BuySellOptionsPage(getIt.get(), isBuyOption)); + (isBuyOption, _) => BuySellOptionsPage(getIt.get(), isBuyOption)); getIt.registerFactory(() { final wallet = getIt.get().wallet; diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index 22868ae28..1279beeca 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -185,6 +185,9 @@ Future defaultSettingsMigration( case 25: await rewriteSecureStoragePin(secureStorage: secureStorage); break; + case 26: + await insecureStorageMigration(secureStorage: secureStorage, sharedPreferences: sharedPreferences); + break; default: break; } @@ -378,6 +381,82 @@ Node getMoneroDefaultNode({required Box nodes}) { } } +Future insecureStorageMigration({ + required SharedPreferences sharedPreferences, + required FlutterSecureStorage secureStorage, +}) async { + bool? allowBiometricalAuthentication = + sharedPreferences.getBool(SecureKey.allowBiometricalAuthenticationKey); + bool? useTOTP2FA = sharedPreferences.getBool(SecureKey.useTOTP2FA); + bool? shouldRequireTOTP2FAForAccessingWallet = + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForAccessingWallet); + bool? shouldRequireTOTP2FAForSendsToContact = + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForSendsToContact); + bool? shouldRequireTOTP2FAForSendsToNonContact = + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForSendsToNonContact); + bool? shouldRequireTOTP2FAForSendsToInternalWallets = + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets); + bool? shouldRequireTOTP2FAForExchangesToInternalWallets = + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets); + bool? shouldRequireTOTP2FAForExchangesToExternalWallets = + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets); + bool? shouldRequireTOTP2FAForAddingContacts = + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForAddingContacts); + bool? shouldRequireTOTP2FAForCreatingNewWallets = + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForCreatingNewWallets); + bool? shouldRequireTOTP2FAForAllSecurityAndBackupSettings = + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings); + int? selectedCake2FAPreset = sharedPreferences.getInt(SecureKey.selectedCake2FAPreset); + String? totpSecretKey = sharedPreferences.getString(SecureKey.totpSecretKey); + int? pinTimeOutDuration = sharedPreferences.getInt(SecureKey.pinTimeOutDuration); + int? lastAuthTimeMilliseconds = sharedPreferences.getInt(SecureKey.lastAuthTimeMilliseconds); + + try { + await secureStorage.write( + key: SecureKey.allowBiometricalAuthenticationKey, + value: allowBiometricalAuthentication.toString()); + await secureStorage.write(key: SecureKey.useTOTP2FA, value: useTOTP2FA.toString()); + await secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForAccessingWallet, + value: shouldRequireTOTP2FAForAccessingWallet.toString()); + await secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForSendsToContact, + value: shouldRequireTOTP2FAForSendsToContact.toString()); + await secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact, + value: shouldRequireTOTP2FAForSendsToNonContact.toString()); + await secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets, + value: shouldRequireTOTP2FAForSendsToInternalWallets.toString()); + await secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets, + value: shouldRequireTOTP2FAForExchangesToInternalWallets.toString()); + await secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets, + value: shouldRequireTOTP2FAForExchangesToExternalWallets.toString()); + await secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForAddingContacts, + value: shouldRequireTOTP2FAForAddingContacts.toString()); + await secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets, + value: shouldRequireTOTP2FAForCreatingNewWallets.toString()); + await secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings, + value: shouldRequireTOTP2FAForAllSecurityAndBackupSettings.toString()); + await secureStorage.write( + key: SecureKey.selectedCake2FAPreset, value: selectedCake2FAPreset.toString()); + await secureStorage.write(key: SecureKey.totpSecretKey, value: totpSecretKey.toString()); + await secureStorage.write( + key: SecureKey.pinTimeOutDuration, value: pinTimeOutDuration.toString()); + await secureStorage.write( + key: SecureKey.lastAuthTimeMilliseconds, value: lastAuthTimeMilliseconds.toString()); + } catch (e) { + print("Error migrating shared preferences to secure storage!: $e"); + // this actually shouldn't be that big of a problem since we don't delete the old keys in this update + // and we read and write to the new locations when loading storage, the migration is just for extra safety + } +} + Future rewriteSecureStoragePin({required FlutterSecureStorage secureStorage}) async { // the bug only affects ios/mac: if (!Platform.isIOS && !Platform.isMacOS) { diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart index 2d5e64817..75e61b5e8 100644 --- a/lib/entities/preferences_key.dart +++ b/lib/entities/preferences_key.dart @@ -23,8 +23,6 @@ class PreferencesKey { static const walletListOrder = 'wallet_list_order'; static const walletListAscending = 'wallet_list_ascending'; static const currentFiatApiModeKey = 'current_fiat_api_mode'; - static const allowBiometricalAuthenticationKey = 'allow_biometrical_authentication'; - static const useTOTP2FA = 'use_totp_2fa'; static const failedTotpTokenTrials = 'failed_token_trials'; static const disableExchangeKey = 'disable_exchange'; static const exchangeStatusKey = 'exchange_status'; @@ -33,6 +31,7 @@ class PreferencesKey { static const displayActionListModeKey = 'display_list_mode'; static const currentPinLength = 'current_pin_length'; static const currentLanguageCode = 'language_code'; + static const currentSeedPhraseLength = 'current_seed_phrase_length'; static const currentDefaultSettingsMigrationVersion = 'current_default_settings_migration_version'; static const moneroTransactionPriority = 'current_fee_priority_monero'; @@ -47,8 +46,6 @@ class PreferencesKey { static const moneroWalletPasswordUpdateV1Base = 'monero_wallet_update_v1'; static const syncModeKey = 'sync_mode'; static const syncAllKey = 'sync_all'; - static const pinTimeOutDuration = 'pin_timeout_duration'; - static const lastAuthTimeMilliseconds = 'last_auth_time_milliseconds'; static const lastPopupDate = 'last_popup_date'; static const lastAppReviewDate = 'last_app_review_date'; static const sortBalanceBy = 'sort_balance_by'; @@ -75,25 +72,4 @@ class PreferencesKey { static const lastSeenAppVersion = 'last_seen_app_version'; static const shouldShowMarketPlaceInDashboard = 'should_show_marketplace_in_dashboard'; static const isNewInstall = 'is_new_install'; - static const shouldRequireTOTP2FAForAccessingWallet = - 'should_require_totp_2fa_for_accessing_wallets'; - static const shouldRequireTOTP2FAForSendsToContact = - 'should_require_totp_2fa_for_sends_to_contact'; - static const shouldRequireTOTP2FAForSendsToNonContact = - 'should_require_totp_2fa_for_sends_to_non_contact'; - static const shouldRequireTOTP2FAForSendsToInternalWallets = - 'should_require_totp_2fa_for_sends_to_internal_wallets'; - static const shouldRequireTOTP2FAForExchangesToInternalWallets = - 'should_require_totp_2fa_for_exchanges_to_internal_wallets'; - static const shouldRequireTOTP2FAForExchangesToExternalWallets = - 'should_require_totp_2fa_for_exchanges_to_external_wallets'; - static const shouldRequireTOTP2FAForAddingContacts = - 'should_require_totp_2fa_for_adding_contacts'; - static const shouldRequireTOTP2FAForCreatingNewWallets = - 'should_require_totp_2fa_for_creating_new_wallets'; - static const shouldRequireTOTP2FAForAllSecurityAndBackupSettings = - 'should_require_totp_2fa_for_all_security_and_backup_settings'; - static const selectedCake2FAPreset = 'selected_cake_2fa_preset'; - static const totpSecretKey = 'totp_secret_key'; - static const currentSeedPhraseLength = 'current_seed_phrase_length'; } diff --git a/lib/entities/secret_store_key.dart b/lib/entities/secret_store_key.dart index 00ec06767..2ee490c74 100644 --- a/lib/entities/secret_store_key.dart +++ b/lib/entities/secret_store_key.dart @@ -1,3 +1,6 @@ +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + enum SecretStoreKey { moneroWalletPassword, pinCodePassword, backupPassword } const moneroWalletPassword = "MONERO_WALLET_PASSWORD"; @@ -35,3 +38,65 @@ String generateStoreKeyFor({ return _key; } + +class SecureKey { + static const allowBiometricalAuthenticationKey = 'allow_biometrical_authentication'; + static const useTOTP2FA = 'use_totp_2fa'; + static const shouldRequireTOTP2FAForAccessingWallet = + 'should_require_totp_2fa_for_accessing_wallets'; + static const shouldRequireTOTP2FAForSendsToContact = + 'should_require_totp_2fa_for_sends_to_contact'; + static const shouldRequireTOTP2FAForSendsToNonContact = + 'should_require_totp_2fa_for_sends_to_non_contact'; + static const shouldRequireTOTP2FAForSendsToInternalWallets = + 'should_require_totp_2fa_for_sends_to_internal_wallets'; + static const shouldRequireTOTP2FAForExchangesToInternalWallets = + 'should_require_totp_2fa_for_exchanges_to_internal_wallets'; + static const shouldRequireTOTP2FAForExchangesToExternalWallets = + 'should_require_totp_2fa_for_exchanges_to_external_wallets'; + static const shouldRequireTOTP2FAForAddingContacts = + 'should_require_totp_2fa_for_adding_contacts'; + static const shouldRequireTOTP2FAForCreatingNewWallets = + 'should_require_totp_2fa_for_creating_new_wallets'; + static const shouldRequireTOTP2FAForAllSecurityAndBackupSettings = + 'should_require_totp_2fa_for_all_security_and_backup_settings'; + static const selectedCake2FAPreset = 'selected_cake_2fa_preset'; + static const totpSecretKey = 'totp_secret_key'; + static const pinTimeOutDuration = 'pin_timeout_duration'; + static const lastAuthTimeMilliseconds = 'last_auth_time_milliseconds'; + + static Future getInt({ + required FlutterSecureStorage secureStorage, + required SharedPreferences sharedPreferences, + required String key, + }) async { + int? value = int.tryParse((await secureStorage.read(key: key) ?? '')); + value ??= sharedPreferences.getInt(key); + return value; + } + + static Future getBool({ + required FlutterSecureStorage secureStorage, + required SharedPreferences sharedPreferences, + required String key, + }) async { + String? value = (await secureStorage.read(key: key) ?? ''); + if (value.toLowerCase() == "true") { + return true; + } else if (value.toLowerCase() == "false") { + return false; + } else { + return sharedPreferences.getBool(key); + } + } + + static Future getString({ + required FlutterSecureStorage secureStorage, + required SharedPreferences sharedPreferences, + required String key, + }) async { + String? value = await secureStorage.read(key: key); + value ??= sharedPreferences.getString(key); + return value; + } +} diff --git a/lib/main.dart b/lib/main.dart index 165db1ddd..306b109a0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -163,7 +163,7 @@ Future initializeAppConfigs() async { transactionDescriptions: transactionDescriptions, secureStorage: secureStorage, anonpayInvoiceInfo: anonpayInvoiceInfo, - initialMigrationVersion: 25); + initialMigrationVersion: 26); } Future initialSetup( diff --git a/lib/src/screens/root/root.dart b/lib/src/screens/root/root.dart index 5f7fcd205..b3d503162 100644 --- a/lib/src/screens/root/root.dart +++ b/lib/src/screens/root/root.dart @@ -53,13 +53,17 @@ class RootState extends State with WidgetsBindingObserver { @override void initState() { - _requestAuth = widget.authService.requireAuth(); + WidgetsBinding.instance.addPostFrameCallback((_) async { + bool value = await widget.authService.requireAuth(); + setState(() { + _requestAuth = value; + }); + }); _isInactiveController = StreamController.broadcast(); _isInactive = false; _postFrameCallback = false; WidgetsBinding.instance.addObserver(this); super.initState(); - if (DeviceInfo.instance.isMobile) { initUniLinks(); } @@ -105,8 +109,10 @@ class RootState extends State with WidgetsBindingObserver { break; case AppLifecycleState.resumed: - setState(() { - _requestAuth = widget.authService.requireAuth(); + widget.authService.requireAuth().then((value) { + setState(() { + _requestAuth = value; + }); }); break; default: diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart index 7bccc4fc5..191eeb43f 100644 --- a/lib/store/settings_store.dart +++ b/lib/store/settings_store.dart @@ -10,6 +10,7 @@ import 'package:cake_wallet/entities/background_tasks.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/pin_code_required_duration.dart'; import 'package:cake_wallet/entities/preferences_key.dart'; +import 'package:cake_wallet/entities/secret_store_key.dart'; import 'package:cake_wallet/entities/seed_phrase_length.dart'; import 'package:cake_wallet/entities/seed_type.dart'; import 'package:cake_wallet/entities/sort_balance_types.dart'; @@ -24,6 +25,7 @@ import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/themes/theme_list.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; import 'package:package_info/package_info.dart'; @@ -44,7 +46,8 @@ class SettingsStore = SettingsStoreBase with _$SettingsStore; abstract class SettingsStoreBase with Store { SettingsStoreBase( - {required BackgroundTasks backgroundTasks, + {required FlutterSecureStorage secureStorage, + required BackgroundTasks backgroundTasks, required SharedPreferences sharedPreferences, required bool initialShouldShowMarketPlaceInDashboard, required FiatCurrency initialFiatCurrency, @@ -109,6 +112,7 @@ abstract class SettingsStoreBase with Store { TransactionPriority? initialBitcoinCashTransactionPriority}) : nodes = ObservableMap.of(nodes), powNodes = ObservableMap.of(powNodes), + _secureStorage = secureStorage, _sharedPreferences = sharedPreferences, _backgroundTasks = backgroundTasks, fiatCurrency = initialFiatCurrency, @@ -187,8 +191,9 @@ abstract class SettingsStoreBase with Store { final key = 'buyProvider_${walletType.toString()}'; final providerId = sharedPreferences.getString(key); if (providerId != null) { - defaultBuyProviders[walletType] = ProviderType.values - .firstWhere((provider) => provider.id == providerId, orElse: () => ProviderType.askEachTime); + defaultBuyProviders[walletType] = ProviderType.values.firstWhere( + (provider) => provider.id == providerId, + orElse: () => ProviderType.askEachTime); } else { defaultBuyProviders[walletType] = ProviderType.askEachTime; } @@ -198,8 +203,9 @@ abstract class SettingsStoreBase with Store { final key = 'sellProvider_${walletType.toString()}'; final providerId = sharedPreferences.getString(key); if (providerId != null) { - defaultSellProviders[walletType] = ProviderType.values - .firstWhere((provider) => provider.id == providerId, orElse: () => ProviderType.askEachTime); + defaultSellProviders[walletType] = ProviderType.values.firstWhere( + (provider) => provider.id == providerId, + orElse: () => ProviderType.askEachTime); } else { defaultSellProviders[walletType] = ProviderType.askEachTime; } @@ -312,74 +318,6 @@ abstract class SettingsStoreBase with Store { reaction((_) => currentTheme, (ThemeBase theme) => sharedPreferences.setInt(PreferencesKey.currentTheme, theme.raw)); - reaction( - (_) => allowBiometricalAuthentication, - (bool biometricalAuthentication) => sharedPreferences.setBool( - PreferencesKey.allowBiometricalAuthenticationKey, biometricalAuthentication)); - - reaction( - (_) => selectedCake2FAPreset, - (Cake2FAPresetsOptions selectedCake2FAPreset) => sharedPreferences.setInt( - PreferencesKey.selectedCake2FAPreset, selectedCake2FAPreset.serialize())); - - reaction( - (_) => shouldRequireTOTP2FAForAccessingWallet, - (bool requireTOTP2FAForAccessingWallet) => sharedPreferences.setBool( - PreferencesKey.shouldRequireTOTP2FAForAccessingWallet, - requireTOTP2FAForAccessingWallet)); - - reaction( - (_) => shouldRequireTOTP2FAForSendsToContact, - (bool requireTOTP2FAForSendsToContact) => sharedPreferences.setBool( - PreferencesKey.shouldRequireTOTP2FAForSendsToContact, requireTOTP2FAForSendsToContact)); - - reaction( - (_) => shouldRequireTOTP2FAForSendsToNonContact, - (bool requireTOTP2FAForSendsToNonContact) => sharedPreferences.setBool( - PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact, - requireTOTP2FAForSendsToNonContact)); - - reaction( - (_) => shouldRequireTOTP2FAForSendsToInternalWallets, - (bool requireTOTP2FAForSendsToInternalWallets) => sharedPreferences.setBool( - PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets, - requireTOTP2FAForSendsToInternalWallets)); - - reaction( - (_) => shouldRequireTOTP2FAForExchangesToInternalWallets, - (bool requireTOTP2FAForExchangesToInternalWallets) => sharedPreferences.setBool( - PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets, - requireTOTP2FAForExchangesToInternalWallets)); - - reaction( - (_) => shouldRequireTOTP2FAForExchangesToExternalWallets, - (bool requireTOTP2FAForExchangesToExternalWallets) => sharedPreferences.setBool( - PreferencesKey.shouldRequireTOTP2FAForExchangesToExternalWallets, - requireTOTP2FAForExchangesToExternalWallets)); - - reaction( - (_) => shouldRequireTOTP2FAForAddingContacts, - (bool requireTOTP2FAForAddingContacts) => sharedPreferences.setBool( - PreferencesKey.shouldRequireTOTP2FAForAddingContacts, requireTOTP2FAForAddingContacts)); - - reaction( - (_) => shouldRequireTOTP2FAForCreatingNewWallets, - (bool requireTOTP2FAForCreatingNewWallets) => sharedPreferences.setBool( - PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets, - requireTOTP2FAForCreatingNewWallets)); - - reaction( - (_) => shouldRequireTOTP2FAForAllSecurityAndBackupSettings, - (bool requireTOTP2FAForAllSecurityAndBackupSettings) => sharedPreferences.setBool( - PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings, - requireTOTP2FAForAllSecurityAndBackupSettings)); - - reaction( - (_) => useTOTP2FA, (bool use) => sharedPreferences.setBool(PreferencesKey.useTOTP2FA, use)); - - reaction((_) => totpSecretKey, - (String totpKey) => sharedPreferences.setString(PreferencesKey.totpSecretKey, totpKey)); - reaction( (_) => numberOfFailedTokenTrials, (int failedTokenTrail) => @@ -403,11 +341,6 @@ abstract class SettingsStoreBase with Store { (SeedPhraseLength seedPhraseWordCount) => sharedPreferences.setInt( PreferencesKey.currentSeedPhraseLength, seedPhraseWordCount.value)); - reaction( - (_) => pinTimeOutDuration, - (PinCodeRequiredDuration pinCodeInterval) => - sharedPreferences.setInt(PreferencesKey.pinTimeOutDuration, pinCodeInterval.value)); - reaction( (_) => balanceDisplayMode, (BalanceDisplayMode mode) => sharedPreferences.setInt( @@ -485,6 +418,84 @@ abstract class SettingsStoreBase with Store { reaction((_) => lookupsENS, (bool looksUpENS) => _sharedPreferences.setBool(PreferencesKey.lookupsENS, looksUpENS)); + // secure storage keys: + reaction( + (_) => allowBiometricalAuthentication, + (bool biometricalAuthentication) => secureStorage.write( + key: SecureKey.allowBiometricalAuthenticationKey, + value: biometricalAuthentication.toString())); + + reaction( + (_) => selectedCake2FAPreset, + (Cake2FAPresetsOptions selectedCake2FAPreset) => secureStorage.write( + key: SecureKey.selectedCake2FAPreset, + value: selectedCake2FAPreset.serialize().toString())); + + reaction( + (_) => shouldRequireTOTP2FAForAccessingWallet, + (bool requireTOTP2FAForAccessingWallet) => secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForAccessingWallet, + value: requireTOTP2FAForAccessingWallet.toString())); + + reaction( + (_) => shouldRequireTOTP2FAForSendsToContact, + (bool requireTOTP2FAForSendsToContact) => secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForSendsToContact, + value: requireTOTP2FAForSendsToContact.toString())); + + reaction( + (_) => shouldRequireTOTP2FAForSendsToNonContact, + (bool requireTOTP2FAForSendsToNonContact) => secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact, + value: requireTOTP2FAForSendsToNonContact.toString())); + + reaction( + (_) => shouldRequireTOTP2FAForSendsToInternalWallets, + (bool requireTOTP2FAForSendsToInternalWallets) => secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets, + value: requireTOTP2FAForSendsToInternalWallets.toString())); + + reaction( + (_) => shouldRequireTOTP2FAForExchangesToInternalWallets, + (bool requireTOTP2FAForExchangesToInternalWallets) => secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets, + value: requireTOTP2FAForExchangesToInternalWallets.toString())); + + reaction( + (_) => shouldRequireTOTP2FAForExchangesToExternalWallets, + (bool requireTOTP2FAForExchangesToExternalWallets) => secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets, + value: requireTOTP2FAForExchangesToExternalWallets.toString())); + + reaction( + (_) => shouldRequireTOTP2FAForAddingContacts, + (bool requireTOTP2FAForAddingContacts) => secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForAddingContacts, + value: requireTOTP2FAForAddingContacts.toString())); + + reaction( + (_) => shouldRequireTOTP2FAForCreatingNewWallets, + (bool requireTOTP2FAForCreatingNewWallets) => secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets, + value: requireTOTP2FAForCreatingNewWallets.toString())); + + reaction( + (_) => shouldRequireTOTP2FAForAllSecurityAndBackupSettings, + (bool requireTOTP2FAForAllSecurityAndBackupSettings) => secureStorage.write( + key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings, + value: requireTOTP2FAForAllSecurityAndBackupSettings.toString())); + + reaction((_) => useTOTP2FA, + (bool use) => secureStorage.write(key: SecureKey.useTOTP2FA, value: use.toString())); + + reaction((_) => totpSecretKey, + (String totpKey) => secureStorage.write(key: SecureKey.totpSecretKey, value: totpKey)); + + reaction( + (_) => pinTimeOutDuration, + (PinCodeRequiredDuration pinCodeInterval) => secureStorage.write( + key: SecureKey.pinTimeOutDuration, value: pinCodeInterval.value.toString())); + this.nodes.observe((change) { if (change.newValue != null && change.key != null) { _saveCurrentNode(change.newValue!, change.key!); @@ -668,6 +679,7 @@ abstract class SettingsStoreBase with Store { String deviceName; + final FlutterSecureStorage _secureStorage; final SharedPreferences _sharedPreferences; final BackgroundTasks _backgroundTasks; @@ -710,6 +722,7 @@ abstract class SettingsStoreBase with Store { BalanceDisplayMode initialBalanceDisplayMode = BalanceDisplayMode.availableBalance, ThemeBase? initialTheme}) async { final sharedPreferences = await getIt.getAsync(); + final secureStorage = await getIt.get(); final backgroundTasks = getIt.get(); final currentFiatCurrency = FiatCurrency.deserialize( raw: sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey)!); @@ -770,36 +783,6 @@ abstract class SettingsStoreBase with Store { final currentFiatApiMode = FiatApiMode.deserialize( raw: sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey) ?? FiatApiMode.enabled.raw); - final allowBiometricalAuthentication = - sharedPreferences.getBool(PreferencesKey.allowBiometricalAuthenticationKey) ?? false; - final selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize( - raw: sharedPreferences.getInt(PreferencesKey.selectedCake2FAPreset) ?? - Cake2FAPresetsOptions.normal.raw); - final shouldRequireTOTP2FAForAccessingWallet = - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAccessingWallet) ?? false; - final shouldRequireTOTP2FAForSendsToContact = - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToContact) ?? false; - final shouldRequireTOTP2FAForSendsToNonContact = - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact) ?? false; - final shouldRequireTOTP2FAForSendsToInternalWallets = - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets) ?? - false; - final shouldRequireTOTP2FAForExchangesToInternalWallets = sharedPreferences - .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets) ?? - false; - final shouldRequireTOTP2FAForExchangesToExternalWallets = sharedPreferences - .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToExternalWallets) ?? - false; - final shouldRequireTOTP2FAForAddingContacts = - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAddingContacts) ?? false; - final shouldRequireTOTP2FAForCreatingNewWallets = - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets) ?? - false; - final shouldRequireTOTP2FAForAllSecurityAndBackupSettings = sharedPreferences - .getBool(PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings) ?? - false; - final useTOTP2FA = sharedPreferences.getBool(PreferencesKey.useTOTP2FA) ?? false; - final totpSecretKey = sharedPreferences.getString(PreferencesKey.totpSecretKey) ?? ''; final tokenTrialNumber = sharedPreferences.getInt(PreferencesKey.failedTotpTokenTrials) ?? 0; final shouldShowMarketPlaceInDashboard = sharedPreferences.getBool(PreferencesKey.shouldShowMarketPlaceInDashboard) ?? true; @@ -816,18 +799,14 @@ abstract class SettingsStoreBase with Store { actionListDisplayMode.addAll(deserializeActionlistDisplayModes( sharedPreferences.getInt(PreferencesKey.displayActionListModeKey) ?? defaultActionsMode)); var pinLength = sharedPreferences.getInt(PreferencesKey.currentPinLength); - final timeOutDuration = sharedPreferences.getInt(PreferencesKey.pinTimeOutDuration); - final seedPhraseCount = sharedPreferences.getInt(PreferencesKey.currentSeedPhraseLength); - final pinCodeTimeOutDuration = timeOutDuration != null - ? PinCodeRequiredDuration.deserialize(raw: timeOutDuration) - : defaultPinCodeTimeOutDuration; - final seedPhraseWordCount = seedPhraseCount != null - ? SeedPhraseLength.deserialize(raw: seedPhraseCount) - : defaultSeedPhraseLength; final sortBalanceBy = SortBalanceBy.values[sharedPreferences.getInt(PreferencesKey.sortBalanceBy) ?? 0]; final pinNativeTokenAtTop = sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop) ?? true; + final seedPhraseCount = sharedPreferences.getInt(PreferencesKey.currentSeedPhraseLength); + final seedPhraseWordCount = seedPhraseCount != null + ? SeedPhraseLength.deserialize(raw: seedPhraseCount) + : defaultSeedPhraseLength; final useEtherscan = sharedPreferences.getBool(PreferencesKey.useEtherscan) ?? true; final usePolygonScan = sharedPreferences.getBool(PreferencesKey.usePolygonScan) ?? true; final defaultNanoRep = sharedPreferences.getString(PreferencesKey.defaultNanoRep) ?? ""; @@ -929,7 +908,101 @@ abstract class SettingsStoreBase with Store { }); final savedSyncAll = sharedPreferences.getBool(PreferencesKey.syncAllKey) ?? true; + // migrated to secure: + final timeOutDuration = await SecureKey.getInt( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.pinTimeOutDuration, + ); + + final pinCodeTimeOutDuration = timeOutDuration != null + ? PinCodeRequiredDuration.deserialize(raw: timeOutDuration) + : defaultPinCodeTimeOutDuration; + + final allowBiometricalAuthentication = await SecureKey.getBool( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.pinTimeOutDuration, + ) ?? + false; + + final selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize( + raw: await SecureKey.getInt( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.selectedCake2FAPreset, + ) ?? + Cake2FAPresetsOptions.normal.raw); + + final shouldRequireTOTP2FAForAccessingWallet = await SecureKey.getBool( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForAccessingWallet, + ) ?? + false; + final shouldRequireTOTP2FAForSendsToContact = await SecureKey.getBool( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForSendsToContact, + ) ?? + false; + final shouldRequireTOTP2FAForSendsToNonContact = await SecureKey.getBool( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact, + ) ?? + false; + final shouldRequireTOTP2FAForSendsToInternalWallets = await SecureKey.getBool( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets, + ) ?? + false; + final shouldRequireTOTP2FAForExchangesToInternalWallets = await SecureKey.getBool( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets, + ) ?? + false; + final shouldRequireTOTP2FAForExchangesToExternalWallets = await SecureKey.getBool( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets, + ) ?? + false; + final shouldRequireTOTP2FAForAddingContacts = await SecureKey.getBool( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForAddingContacts, + ) ?? + false; + final shouldRequireTOTP2FAForCreatingNewWallets = await SecureKey.getBool( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets, + ) ?? + false; + final shouldRequireTOTP2FAForAllSecurityAndBackupSettings = await SecureKey.getBool( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings, + ) ?? + false; + final useTOTP2FA = await SecureKey.getBool( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.useTOTP2FA, + ) ?? + false; + final totpSecretKey = await SecureKey.getString( + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.useTOTP2FA, + ) ?? + ''; + return SettingsStore( + secureStorage: secureStorage, sharedPreferences: sharedPreferences, initialShouldShowMarketPlaceInDashboard: shouldShowMarketPlaceInDashboard, nodes: nodes, @@ -1055,8 +1128,6 @@ abstract class SettingsStoreBase with Store { shouldSaveRecipientAddress = sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey) ?? shouldSaveRecipientAddress; - useTOTP2FA = sharedPreferences.getBool(PreferencesKey.useTOTP2FA) ?? useTOTP2FA; - totpSecretKey = sharedPreferences.getString(PreferencesKey.totpSecretKey) ?? totpSecretKey; numberOfFailedTokenTrials = sharedPreferences.getInt(PreferencesKey.failedTotpTokenTrials) ?? numberOfFailedTokenTrials; isAppSecure = sharedPreferences.getBool(PreferencesKey.isAppSecureKey) ?? isAppSecure; @@ -1065,41 +1136,10 @@ abstract class SettingsStoreBase with Store { walletListOrder = WalletListOrderType.values[sharedPreferences.getInt(PreferencesKey.walletListOrder) ?? 0]; walletListAscending = sharedPreferences.getBool(PreferencesKey.walletListAscending) ?? true; - allowBiometricalAuthentication = - sharedPreferences.getBool(PreferencesKey.allowBiometricalAuthenticationKey) ?? - allowBiometricalAuthentication; - selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize( - raw: sharedPreferences.getInt(PreferencesKey.selectedCake2FAPreset) ?? - Cake2FAPresetsOptions.normal.raw); - shouldRequireTOTP2FAForAccessingWallet = - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAccessingWallet) ?? false; - shouldRequireTOTP2FAForSendsToContact = - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToContact) ?? false; - shouldRequireTOTP2FAForSendsToNonContact = - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact) ?? false; - shouldRequireTOTP2FAForSendsToInternalWallets = - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets) ?? - false; - shouldRequireTOTP2FAForExchangesToInternalWallets = sharedPreferences - .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets) ?? - false; - shouldRequireTOTP2FAForExchangesToExternalWallets = sharedPreferences - .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToExternalWallets) ?? - false; - shouldRequireTOTP2FAForAddingContacts = - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAddingContacts) ?? false; - shouldRequireTOTP2FAForCreatingNewWallets = - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets) ?? - false; - shouldRequireTOTP2FAForAllSecurityAndBackupSettings = sharedPreferences - .getBool(PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings) ?? - false; + shouldShowMarketPlaceInDashboard = sharedPreferences.getBool(PreferencesKey.shouldShowMarketPlaceInDashboard) ?? shouldShowMarketPlaceInDashboard; - selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize( - raw: sharedPreferences.getInt(PreferencesKey.selectedCake2FAPreset) ?? - Cake2FAPresetsOptions.narrow.raw); exchangeStatus = ExchangeApiMode.deserialize( raw: sharedPreferences.getInt(PreferencesKey.exchangeStatusKey) ?? ExchangeApiMode.enabled.raw); @@ -1188,6 +1228,93 @@ abstract class SettingsStoreBase with Store { if (nanoNode != null) { nodes[WalletType.nano] = nanoNode; } + + // MIGRATED: + + useTOTP2FA = await SecureKey.getBool( + secureStorage: _secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.useTOTP2FA, + ) ?? + useTOTP2FA; + + totpSecretKey = await SecureKey.getString( + secureStorage: _secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.useTOTP2FA, + ) ?? + totpSecretKey; + + allowBiometricalAuthentication = await SecureKey.getBool( + secureStorage: _secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.allowBiometricalAuthenticationKey, + ) ?? + allowBiometricalAuthentication; + + selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize( + raw: await SecureKey.getInt( + secureStorage: _secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.selectedCake2FAPreset, + ) ?? + Cake2FAPresetsOptions.normal.raw); + + shouldRequireTOTP2FAForAccessingWallet = await SecureKey.getBool( + secureStorage: _secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForAccessingWallet, + ) ?? + false; + shouldRequireTOTP2FAForSendsToContact = await SecureKey.getBool( + secureStorage: _secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForSendsToContact, + ) ?? + false; + + shouldRequireTOTP2FAForSendsToNonContact = await SecureKey.getBool( + secureStorage: _secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact, + ) ?? + false; + shouldRequireTOTP2FAForSendsToInternalWallets = await SecureKey.getBool( + secureStorage: _secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets, + ) ?? + false; + shouldRequireTOTP2FAForExchangesToInternalWallets = await SecureKey.getBool( + secureStorage: _secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets, + ) ?? + false; + shouldRequireTOTP2FAForExchangesToExternalWallets = await SecureKey.getBool( + secureStorage: _secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets, + ) ?? + false; + shouldRequireTOTP2FAForAddingContacts = await SecureKey.getBool( + secureStorage: _secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForAddingContacts, + ) ?? + false; + shouldRequireTOTP2FAForCreatingNewWallets = await SecureKey.getBool( + secureStorage: _secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets, + ) ?? + false; + shouldRequireTOTP2FAForAllSecurityAndBackupSettings = await SecureKey.getBool( + secureStorage: _secureStorage, + sharedPreferences: sharedPreferences, + key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings, + ) ?? + false; } Future _saveCurrentNode(Node node, WalletType walletType) async { diff --git a/lib/view_model/settings/security_settings_view_model.dart b/lib/view_model/settings/security_settings_view_model.dart index 5ea4dd4ea..965e65af8 100644 --- a/lib/view_model/settings/security_settings_view_model.dart +++ b/lib/view_model/settings/security_settings_view_model.dart @@ -44,5 +44,5 @@ abstract class SecuritySettingsViewModelBase with Store { setPinCodeRequiredDuration(PinCodeRequiredDuration duration) => _settingsStore.pinTimeOutDuration = duration; - bool checkPinCodeRiquired() => _authService.requireAuth(); + Future checkPinCodeRiquired() => _authService.requireAuth(); } diff --git a/lib/view_model/wallet_list/wallet_list_view_model.dart b/lib/view_model/wallet_list/wallet_list_view_model.dart index 407b6d3bc..a7e27cbf6 100644 --- a/lib/view_model/wallet_list/wallet_list_view_model.dart +++ b/lib/view_model/wallet_list/wallet_list_view_model.dart @@ -161,7 +161,7 @@ abstract class WalletListViewModelBase with Store { } } - bool checkIfAuthRequired() { + Future checkIfAuthRequired() async { return _authService.requireAuth(); } }