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

Matthew Fosse committed Jan 22, 2024 at 16:30 UTC d664f0a16fd030ed8dae530df66cf6356d6d3aa7
11 files changed +452 -282
lib/core/auth_service.dart
+4 -4
@@ -72,11 +72,11 @@ class AuthService with Store {
72
73 void saveLastAuthTime() {
74 int timestamp = DateTime.now().millisecondsSinceEpoch;
75 - sharedPreferences.setInt(PreferencesKey.lastAuthTimeMilliseconds, timestamp);
75 + secureStorage.write(key: SecureKey.lastAuthTimeMilliseconds, value: timestamp.toString());
76 }
77
78 - bool requireAuth() {
79 - final timestamp = sharedPreferences.getInt(PreferencesKey.lastAuthTimeMilliseconds);
78 + Future<bool> requireAuth() async {
79 + final timestamp = int.tryParse(await secureStorage.read(key: SecureKey.lastAuthTimeMilliseconds) ?? '0');
80 final duration = _durationToRequireAuth(timestamp ?? 0);
81 final requiredPinInterval = settingsStore.pinTimeOutDuration;
82
@@ -100,7 +100,7 @@ class AuthService with Store {
100 'Either route or onAuthSuccess param must be passed.');
101
102 if (!conditionToDetermineIfToUse2FA) {
103 - if (!requireAuth() && !_alwaysAuthenticateRoutes.contains(route)) {
103 + if (!(await requireAuth()) && !_alwaysAuthenticateRoutes.contains(route)) {
104 if (onAuthSuccess != null) {
105 onAuthSuccess(true);
106 } else {
lib/core/backup_service.dart
+1 -84
@@ -213,8 +213,6 @@ class BackupService {
213 final defaultBuyProvider = data[PreferencesKey.defaultBuyProvider] as int?;
214 final currentTransactionPriorityKeyLegacy =
215 data[PreferencesKey.currentTransactionPriorityKeyLegacy] as int?;
216 - final allowBiometricalAuthentication =
217 - data[PreferencesKey.allowBiometricalAuthenticationKey] as bool?;
216 final currentBitcoinElectrumSererId =
217 data[PreferencesKey.currentBitcoinElectrumSererIdKey] as int?;
218 final currentLanguageCode = data[PreferencesKey.currentLanguageCode] as String?;
@@ -227,23 +225,6 @@ class BackupService {
225 data[PreferencesKey.currentDefaultSettingsMigrationVersion] as int?;
226 final moneroTransactionPriority = data[PreferencesKey.moneroTransactionPriority] as int?;
227 final bitcoinTransactionPriority = data[PreferencesKey.bitcoinTransactionPriority] as int?;
230 - final selectedCake2FAPreset = data[PreferencesKey.selectedCake2FAPreset] as int?;
231 - final shouldRequireTOTP2FAForAccessingWallet =
232 - data[PreferencesKey.shouldRequireTOTP2FAForAccessingWallet] as bool?;
233 - final shouldRequireTOTP2FAForSendsToContact =
234 - data[PreferencesKey.shouldRequireTOTP2FAForSendsToContact] as bool?;
235 - final shouldRequireTOTP2FAForSendsToNonContact =
236 - data[PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact] as bool?;
237 - final shouldRequireTOTP2FAForSendsToInternalWallets =
238 - data[PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets] as bool?;
239 - final shouldRequireTOTP2FAForExchangesToInternalWallets =
240 - data[PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets] as bool?;
241 - final shouldRequireTOTP2FAForAddingContacts =
242 - data[PreferencesKey.shouldRequireTOTP2FAForAddingContacts] as bool?;
243 - final shouldRequireTOTP2FAForCreatingNewWallets =
244 - data[PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets] as bool?;
245 - final shouldRequireTOTP2FAForAllSecurityAndBackupSettings =
246 - data[PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings] as bool?;
228 final sortBalanceTokensBy = data[PreferencesKey.sortBalanceBy] as int?;
229 final pinNativeTokenAtTop = data[PreferencesKey.pinNativeTokenAtTop] as bool?;
230 final useEtherscan = data[PreferencesKey.useEtherscan] as bool?;
@@ -294,14 +275,7 @@ class BackupService {
275 if (currentTransactionPriorityKeyLegacy != null)
276 await _sharedPreferences.setInt(
277 PreferencesKey.currentTransactionPriorityKeyLegacy, currentTransactionPriorityKeyLegacy);
297 -
298 - if (DeviceInfo.instance.isDesktop) {
299 - await _sharedPreferences.setBool(PreferencesKey.allowBiometricalAuthenticationKey, false);
300 - } else if (allowBiometricalAuthentication != null) {
301 - await _sharedPreferences.setBool(
302 - PreferencesKey.allowBiometricalAuthenticationKey, allowBiometricalAuthentication);
303 - }
304 -
278 +
279 if (currentBitcoinElectrumSererId != null)
280 await _sharedPreferences.setInt(
281 PreferencesKey.currentBitcoinElectrumSererIdKey, currentBitcoinElectrumSererId);
@@ -344,43 +318,6 @@ class BackupService {
318 await _sharedPreferences.setInt(
319 PreferencesKey.bitcoinTransactionPriority, bitcoinTransactionPriority);
320
347 - if (selectedCake2FAPreset != null)
348 - await _sharedPreferences.setInt(PreferencesKey.selectedCake2FAPreset, selectedCake2FAPreset);
349 -
350 - if (shouldRequireTOTP2FAForAccessingWallet != null)
351 - await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForAccessingWallet,
352 - shouldRequireTOTP2FAForAccessingWallet);
353 -
354 - if (shouldRequireTOTP2FAForSendsToContact != null)
355 - await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForSendsToContact,
356 - shouldRequireTOTP2FAForSendsToContact);
357 -
358 - if (shouldRequireTOTP2FAForSendsToNonContact != null)
359 - await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact,
360 - shouldRequireTOTP2FAForSendsToNonContact);
361 -
362 - if (shouldRequireTOTP2FAForSendsToInternalWallets != null)
363 - await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets,
364 - shouldRequireTOTP2FAForSendsToInternalWallets);
365 -
366 - if (shouldRequireTOTP2FAForExchangesToInternalWallets != null)
367 - await _sharedPreferences.setBool(
368 - PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
369 - shouldRequireTOTP2FAForExchangesToInternalWallets);
370 -
371 - if (shouldRequireTOTP2FAForAddingContacts != null)
372 - await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForAddingContacts,
373 - shouldRequireTOTP2FAForAddingContacts);
374 -
375 - if (shouldRequireTOTP2FAForCreatingNewWallets != null)
376 - await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets,
377 - shouldRequireTOTP2FAForCreatingNewWallets);
378 -
379 - if (shouldRequireTOTP2FAForAllSecurityAndBackupSettings != null)
380 - await _sharedPreferences.setBool(
381 - PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
382 - shouldRequireTOTP2FAForAllSecurityAndBackupSettings);
383 -
321 if (sortBalanceTokensBy != null)
322 await _sharedPreferences.setInt(PreferencesKey.sortBalanceBy, sortBalanceTokensBy);
323
@@ -532,8 +469,6 @@ class BackupService {
469 PreferencesKey.currentPinLength: _sharedPreferences.getInt(PreferencesKey.currentPinLength),
470 PreferencesKey.currentTransactionPriorityKeyLegacy:
471 _sharedPreferences.getInt(PreferencesKey.currentTransactionPriorityKeyLegacy),
535 - PreferencesKey.allowBiometricalAuthenticationKey:
536 - _sharedPreferences.getBool(PreferencesKey.allowBiometricalAuthenticationKey),
472 PreferencesKey.currentBitcoinElectrumSererIdKey:
473 _sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey),
474 PreferencesKey.currentLanguageCode:
@@ -550,24 +485,6 @@ class BackupService {
485 _sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority),
486 PreferencesKey.currentFiatApiModeKey:
487 _sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey),
553 - PreferencesKey.selectedCake2FAPreset:
554 - _sharedPreferences.getInt(PreferencesKey.selectedCake2FAPreset),
555 - PreferencesKey.shouldRequireTOTP2FAForAccessingWallet:
556 - _sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAccessingWallet),
557 - PreferencesKey.shouldRequireTOTP2FAForSendsToContact:
558 - _sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToContact),
559 - PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact:
560 - _sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact),
561 - PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets:
562 - _sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets),
563 - PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets: _sharedPreferences
564 - .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets),
565 - PreferencesKey.shouldRequireTOTP2FAForAddingContacts:
566 - _sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAddingContacts),
567 - PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets:
568 - _sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets),
569 - PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings: _sharedPreferences
570 - .getBool(PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings),
488 PreferencesKey.sortBalanceBy: _sharedPreferences.getInt(PreferencesKey.sortBalanceBy),
489 PreferencesKey.pinNativeTokenAtTop:
490 _sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop),
lib/di.dart
+12 -12
@@ -276,6 +276,7 @@ Future<void> setup({
276
277 if (!_isSetupFinished) {
278 getIt.registerSingletonAsync<SharedPreferences>(() => SharedPreferences.getInstance());
279 + getIt.registerSingleton<FlutterSecureStorage>(secureStorage);
280 }
281 if (!_isSetupFinished) {
282 getIt.registerFactory(() => BackgroundTasks());
@@ -302,7 +303,6 @@ Future<void> setup({
303 getIt.registerFactory<Box<Node>>(() => _nodeSource);
304 getIt.registerFactory<Box<Node>>(() => _powNodeSource, instanceName: Node.boxName + "pow");
305
305 - getIt.registerSingleton<FlutterSecureStorage>(secureStorage);
306 getIt.registerSingleton(AuthenticationStore());
307 getIt.registerSingleton<WalletListStore>(WalletListStore());
308 getIt.registerSingleton(NodeListStoreBase.instance);
@@ -344,17 +344,19 @@ Future<void> setup({
344 walletInfoSource: _walletInfoSource));
345
346 getIt.registerFactoryParam<AdvancedPrivacySettingsViewModel, WalletType, void>(
347 - (type, _) => AdvancedPrivacySettingsViewModel(type, getIt.get<SettingsStore>()));
347 + (type, _) => AdvancedPrivacySettingsViewModel(type, getIt.get<SettingsStore>()));
348
349 getIt.registerFactory<WalletLoadingService>(() => WalletLoadingService(
350 getIt.get<SharedPreferences>(),
351 getIt.get<KeyService>(),
352 (WalletType type) => getIt.get<WalletService>(param1: type)));
353 -
354 - getIt.registerFactoryParam<WalletNewVM, WalletType, void>((type, _) =>
355 - WalletNewVM(getIt.get<AppStore>(),
356 - getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
357 - getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),type: type));
353 +
354 + getIt.registerFactoryParam<WalletNewVM, WalletType, void>((type, _) => WalletNewVM(
355 + getIt.get<AppStore>(),
356 + getIt.get<WalletCreationService>(param1: type),
357 + _walletInfoSource,
358 + getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
359 + type: type));
360
361 getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) {
362 return WalletRestorationFromQRVM(getIt.get<AppStore>(),
@@ -805,8 +807,7 @@ Future<void> setup({
807 .registerFactory<DFXBuyProvider>(() => DFXBuyProvider(wallet: getIt.get<AppStore>().wallet!));
808
809 getIt.registerFactory<MoonPaySellProvider>(() => MoonPaySellProvider(
808 - settingsStore: getIt.get<AppStore>().settingsStore,
809 - wallet: getIt.get<AppStore>().wallet!));
810 + settingsStore: getIt.get<AppStore>().settingsStore, wallet: getIt.get<AppStore>().wallet!));
811
812 getIt.registerFactory<OnRamperBuyProvider>(() => OnRamperBuyProvider(
813 getIt.get<AppStore>().settingsStore,
@@ -919,8 +920,7 @@ Future<void> setup({
920 (param1, isCreate) => NewWalletTypePage(onTypeSelected: param1, isCreate: isCreate ?? true));
921
922 getIt.registerFactoryParam<PreSeedPage, int, void>(
922 - (seedPhraseLength, _)
923 - => PreSeedPage(seedPhraseLength));
923 + (seedPhraseLength, _) => PreSeedPage(seedPhraseLength));
924
925 getIt.registerFactoryParam<TradeDetailsViewModel, Trade, void>((trade, _) =>
926 TradeDetailsViewModel(
@@ -954,7 +954,7 @@ Future<void> setup({
954 getIt.registerFactory(() => BuyAmountViewModel());
955
956 getIt.registerFactoryParam<BuySellOptionsPage, bool, void>(
957 - (isBuyOption, _) => BuySellOptionsPage(getIt.get<DashboardViewModel>(), isBuyOption));
957 + (isBuyOption, _) => BuySellOptionsPage(getIt.get<DashboardViewModel>(), isBuyOption));
958
959 getIt.registerFactory(() {
960 final wallet = getIt.get<AppStore>().wallet;
lib/entities/default_settings_migration.dart
+79
@@ -185,6 +185,9 @@ Future<void> defaultSettingsMigration(
185 case 25:
186 await rewriteSecureStoragePin(secureStorage: secureStorage);
187 break;
188 + case 26:
189 + await insecureStorageMigration(secureStorage: secureStorage, sharedPreferences: sharedPreferences);
190 + break;
191 default:
192 break;
193 }
@@ -378,6 +381,82 @@ Node getMoneroDefaultNode({required Box<Node> nodes}) {
381 }
382 }
383
384 +Future<void> insecureStorageMigration({
385 + required SharedPreferences sharedPreferences,
386 + required FlutterSecureStorage secureStorage,
387 +}) async {
388 + bool? allowBiometricalAuthentication =
389 + sharedPreferences.getBool(SecureKey.allowBiometricalAuthenticationKey);
390 + bool? useTOTP2FA = sharedPreferences.getBool(SecureKey.useTOTP2FA);
391 + bool? shouldRequireTOTP2FAForAccessingWallet =
392 + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForAccessingWallet);
393 + bool? shouldRequireTOTP2FAForSendsToContact =
394 + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForSendsToContact);
395 + bool? shouldRequireTOTP2FAForSendsToNonContact =
396 + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForSendsToNonContact);
397 + bool? shouldRequireTOTP2FAForSendsToInternalWallets =
398 + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets);
399 + bool? shouldRequireTOTP2FAForExchangesToInternalWallets =
400 + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets);
401 + bool? shouldRequireTOTP2FAForExchangesToExternalWallets =
402 + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets);
403 + bool? shouldRequireTOTP2FAForAddingContacts =
404 + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForAddingContacts);
405 + bool? shouldRequireTOTP2FAForCreatingNewWallets =
406 + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForCreatingNewWallets);
407 + bool? shouldRequireTOTP2FAForAllSecurityAndBackupSettings =
408 + sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings);
409 + int? selectedCake2FAPreset = sharedPreferences.getInt(SecureKey.selectedCake2FAPreset);
410 + String? totpSecretKey = sharedPreferences.getString(SecureKey.totpSecretKey);
411 + int? pinTimeOutDuration = sharedPreferences.getInt(SecureKey.pinTimeOutDuration);
412 + int? lastAuthTimeMilliseconds = sharedPreferences.getInt(SecureKey.lastAuthTimeMilliseconds);
413 +
414 + try {
415 + await secureStorage.write(
416 + key: SecureKey.allowBiometricalAuthenticationKey,
417 + value: allowBiometricalAuthentication.toString());
418 + await secureStorage.write(key: SecureKey.useTOTP2FA, value: useTOTP2FA.toString());
419 + await secureStorage.write(
420 + key: SecureKey.shouldRequireTOTP2FAForAccessingWallet,
421 + value: shouldRequireTOTP2FAForAccessingWallet.toString());
422 + await secureStorage.write(
423 + key: SecureKey.shouldRequireTOTP2FAForSendsToContact,
424 + value: shouldRequireTOTP2FAForSendsToContact.toString());
425 + await secureStorage.write(
426 + key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact,
427 + value: shouldRequireTOTP2FAForSendsToNonContact.toString());
428 + await secureStorage.write(
429 + key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets,
430 + value: shouldRequireTOTP2FAForSendsToInternalWallets.toString());
431 + await secureStorage.write(
432 + key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
433 + value: shouldRequireTOTP2FAForExchangesToInternalWallets.toString());
434 + await secureStorage.write(
435 + key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets,
436 + value: shouldRequireTOTP2FAForExchangesToExternalWallets.toString());
437 + await secureStorage.write(
438 + key: SecureKey.shouldRequireTOTP2FAForAddingContacts,
439 + value: shouldRequireTOTP2FAForAddingContacts.toString());
440 + await secureStorage.write(
441 + key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets,
442 + value: shouldRequireTOTP2FAForCreatingNewWallets.toString());
443 + await secureStorage.write(
444 + key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
445 + value: shouldRequireTOTP2FAForAllSecurityAndBackupSettings.toString());
446 + await secureStorage.write(
447 + key: SecureKey.selectedCake2FAPreset, value: selectedCake2FAPreset.toString());
448 + await secureStorage.write(key: SecureKey.totpSecretKey, value: totpSecretKey.toString());
449 + await secureStorage.write(
450 + key: SecureKey.pinTimeOutDuration, value: pinTimeOutDuration.toString());
451 + await secureStorage.write(
452 + key: SecureKey.lastAuthTimeMilliseconds, value: lastAuthTimeMilliseconds.toString());
453 + } catch (e) {
454 + print("Error migrating shared preferences to secure storage!: $e");
455 + // this actually shouldn't be that big of a problem since we don't delete the old keys in this update
456 + // and we read and write to the new locations when loading storage, the migration is just for extra safety
457 + }
458 +}
459 +
460 Future<void> rewriteSecureStoragePin({required FlutterSecureStorage secureStorage}) async {
461 // the bug only affects ios/mac:
462 if (!Platform.isIOS && !Platform.isMacOS) {
lib/entities/preferences_key.dart
+1 -25
@@ -23,8 +23,6 @@ class PreferencesKey {
23 static const walletListOrder = 'wallet_list_order';
24 static const walletListAscending = 'wallet_list_ascending';
25 static const currentFiatApiModeKey = 'current_fiat_api_mode';
26 - static const allowBiometricalAuthenticationKey = 'allow_biometrical_authentication';
27 - static const useTOTP2FA = 'use_totp_2fa';
26 static const failedTotpTokenTrials = 'failed_token_trials';
27 static const disableExchangeKey = 'disable_exchange';
28 static const exchangeStatusKey = 'exchange_status';
@@ -33,6 +31,7 @@ class PreferencesKey {
31 static const displayActionListModeKey = 'display_list_mode';
32 static const currentPinLength = 'current_pin_length';
33 static const currentLanguageCode = 'language_code';
34 + static const currentSeedPhraseLength = 'current_seed_phrase_length';
35 static const currentDefaultSettingsMigrationVersion =
36 'current_default_settings_migration_version';
37 static const moneroTransactionPriority = 'current_fee_priority_monero';
@@ -47,8 +46,6 @@ class PreferencesKey {
46 static const moneroWalletPasswordUpdateV1Base = 'monero_wallet_update_v1';
47 static const syncModeKey = 'sync_mode';
48 static const syncAllKey = 'sync_all';
50 - static const pinTimeOutDuration = 'pin_timeout_duration';
51 - static const lastAuthTimeMilliseconds = 'last_auth_time_milliseconds';
49 static const lastPopupDate = 'last_popup_date';
50 static const lastAppReviewDate = 'last_app_review_date';
51 static const sortBalanceBy = 'sort_balance_by';
@@ -75,25 +72,4 @@ class PreferencesKey {
72 static const lastSeenAppVersion = 'last_seen_app_version';
73 static const shouldShowMarketPlaceInDashboard = 'should_show_marketplace_in_dashboard';
74 static const isNewInstall = 'is_new_install';
78 - static const shouldRequireTOTP2FAForAccessingWallet =
79 - 'should_require_totp_2fa_for_accessing_wallets';
80 - static const shouldRequireTOTP2FAForSendsToContact =
81 - 'should_require_totp_2fa_for_sends_to_contact';
82 - static const shouldRequireTOTP2FAForSendsToNonContact =
83 - 'should_require_totp_2fa_for_sends_to_non_contact';
84 - static const shouldRequireTOTP2FAForSendsToInternalWallets =
85 - 'should_require_totp_2fa_for_sends_to_internal_wallets';
86 - static const shouldRequireTOTP2FAForExchangesToInternalWallets =
87 - 'should_require_totp_2fa_for_exchanges_to_internal_wallets';
88 - static const shouldRequireTOTP2FAForExchangesToExternalWallets =
89 - 'should_require_totp_2fa_for_exchanges_to_external_wallets';
90 - static const shouldRequireTOTP2FAForAddingContacts =
91 - 'should_require_totp_2fa_for_adding_contacts';
92 - static const shouldRequireTOTP2FAForCreatingNewWallets =
93 - 'should_require_totp_2fa_for_creating_new_wallets';
94 - static const shouldRequireTOTP2FAForAllSecurityAndBackupSettings =
95 - 'should_require_totp_2fa_for_all_security_and_backup_settings';
96 - static const selectedCake2FAPreset = 'selected_cake_2fa_preset';
97 - static const totpSecretKey = 'totp_secret_key';
98 - static const currentSeedPhraseLength = 'current_seed_phrase_length';
75 }
lib/entities/secret_store_key.dart
+65
@@ -1,3 +1,6 @@
1 +import 'package:flutter_secure_storage/flutter_secure_storage.dart';
2 +import 'package:shared_preferences/shared_preferences.dart';
3 +
4 enum SecretStoreKey { moneroWalletPassword, pinCodePassword, backupPassword }
5
6 const moneroWalletPassword = "MONERO_WALLET_PASSWORD";
@@ -35,3 +38,65 @@ String generateStoreKeyFor({
38
39 return _key;
40 }
41 +
42 +class SecureKey {
43 + static const allowBiometricalAuthenticationKey = 'allow_biometrical_authentication';
44 + static const useTOTP2FA = 'use_totp_2fa';
45 + static const shouldRequireTOTP2FAForAccessingWallet =
46 + 'should_require_totp_2fa_for_accessing_wallets';
47 + static const shouldRequireTOTP2FAForSendsToContact =
48 + 'should_require_totp_2fa_for_sends_to_contact';
49 + static const shouldRequireTOTP2FAForSendsToNonContact =
50 + 'should_require_totp_2fa_for_sends_to_non_contact';
51 + static const shouldRequireTOTP2FAForSendsToInternalWallets =
52 + 'should_require_totp_2fa_for_sends_to_internal_wallets';
53 + static const shouldRequireTOTP2FAForExchangesToInternalWallets =
54 + 'should_require_totp_2fa_for_exchanges_to_internal_wallets';
55 + static const shouldRequireTOTP2FAForExchangesToExternalWallets =
56 + 'should_require_totp_2fa_for_exchanges_to_external_wallets';
57 + static const shouldRequireTOTP2FAForAddingContacts =
58 + 'should_require_totp_2fa_for_adding_contacts';
59 + static const shouldRequireTOTP2FAForCreatingNewWallets =
60 + 'should_require_totp_2fa_for_creating_new_wallets';
61 + static const shouldRequireTOTP2FAForAllSecurityAndBackupSettings =
62 + 'should_require_totp_2fa_for_all_security_and_backup_settings';
63 + static const selectedCake2FAPreset = 'selected_cake_2fa_preset';
64 + static const totpSecretKey = 'totp_secret_key';
65 + static const pinTimeOutDuration = 'pin_timeout_duration';
66 + static const lastAuthTimeMilliseconds = 'last_auth_time_milliseconds';
67 +
68 + static Future<int?> getInt({
69 + required FlutterSecureStorage secureStorage,
70 + required SharedPreferences sharedPreferences,
71 + required String key,
72 + }) async {
73 + int? value = int.tryParse((await secureStorage.read(key: key) ?? ''));
74 + value ??= sharedPreferences.getInt(key);
75 + return value;
76 + }
77 +
78 + static Future<bool?> getBool({
79 + required FlutterSecureStorage secureStorage,
80 + required SharedPreferences sharedPreferences,
81 + required String key,
82 + }) async {
83 + String? value = (await secureStorage.read(key: key) ?? '');
84 + if (value.toLowerCase() == "true") {
85 + return true;
86 + } else if (value.toLowerCase() == "false") {
87 + return false;
88 + } else {
89 + return sharedPreferences.getBool(key);
90 + }
91 + }
92 +
93 + static Future<String?> getString({
94 + required FlutterSecureStorage secureStorage,
95 + required SharedPreferences sharedPreferences,
96 + required String key,
97 + }) async {
98 + String? value = await secureStorage.read(key: key);
99 + value ??= sharedPreferences.getString(key);
100 + return value;
101 + }
102 +}
lib/main.dart
+1 -1
@@ -163,7 +163,7 @@ Future<void> initializeAppConfigs() async {
163 transactionDescriptions: transactionDescriptions,
164 secureStorage: secureStorage,
165 anonpayInvoiceInfo: anonpayInvoiceInfo,
166 - initialMigrationVersion: 25);
166 + initialMigrationVersion: 26);
167 }
168
169 Future<void> initialSetup(
lib/src/screens/root/root.dart
+10 -4
@@ -53,13 +53,17 @@ class RootState extends State<Root> with WidgetsBindingObserver {
53
54 @override
55 void initState() {
56 - _requestAuth = widget.authService.requireAuth();
56 + WidgetsBinding.instance.addPostFrameCallback((_) async {
57 + bool value = await widget.authService.requireAuth();
58 + setState(() {
59 + _requestAuth = value;
60 + });
61 + });
62 _isInactiveController = StreamController<bool>.broadcast();
63 _isInactive = false;
64 _postFrameCallback = false;
65 WidgetsBinding.instance.addObserver(this);
66 super.initState();
62 -
67 if (DeviceInfo.instance.isMobile) {
68 initUniLinks();
69 }
@@ -105,8 +109,10 @@ class RootState extends State<Root> with WidgetsBindingObserver {
109
110 break;
111 case AppLifecycleState.resumed:
108 - setState(() {
109 - _requestAuth = widget.authService.requireAuth();
112 + widget.authService.requireAuth().then((value) {
113 + setState(() {
114 + _requestAuth = value;
115 + });
116 });
117 break;
118 default:
lib/store/settings_store.dart
+277 -150
@@ -10,6 +10,7 @@ import 'package:cake_wallet/entities/background_tasks.dart';
10 import 'package:cake_wallet/entities/exchange_api_mode.dart';
11 import 'package:cake_wallet/entities/pin_code_required_duration.dart';
12 import 'package:cake_wallet/entities/preferences_key.dart';
13 +import 'package:cake_wallet/entities/secret_store_key.dart';
14 import 'package:cake_wallet/entities/seed_phrase_length.dart';
15 import 'package:cake_wallet/entities/seed_type.dart';
16 import 'package:cake_wallet/entities/sort_balance_types.dart';
@@ -24,6 +25,7 @@ import 'package:cake_wallet/themes/theme_base.dart';
25 import 'package:cake_wallet/themes/theme_list.dart';
26 import 'package:device_info_plus/device_info_plus.dart';
27 import 'package:flutter/material.dart';
28 +import 'package:flutter_secure_storage/flutter_secure_storage.dart';
29 import 'package:hive/hive.dart';
30 import 'package:mobx/mobx.dart';
31 import 'package:package_info/package_info.dart';
@@ -44,7 +46,8 @@ class SettingsStore = SettingsStoreBase with _$SettingsStore;
46
47 abstract class SettingsStoreBase with Store {
48 SettingsStoreBase(
47 - {required BackgroundTasks backgroundTasks,
49 + {required FlutterSecureStorage secureStorage,
50 + required BackgroundTasks backgroundTasks,
51 required SharedPreferences sharedPreferences,
52 required bool initialShouldShowMarketPlaceInDashboard,
53 required FiatCurrency initialFiatCurrency,
@@ -109,6 +112,7 @@ abstract class SettingsStoreBase with Store {
112 TransactionPriority? initialBitcoinCashTransactionPriority})
113 : nodes = ObservableMap<WalletType, Node>.of(nodes),
114 powNodes = ObservableMap<WalletType, Node>.of(powNodes),
115 + _secureStorage = secureStorage,
116 _sharedPreferences = sharedPreferences,
117 _backgroundTasks = backgroundTasks,
118 fiatCurrency = initialFiatCurrency,
@@ -187,8 +191,9 @@ abstract class SettingsStoreBase with Store {
191 final key = 'buyProvider_${walletType.toString()}';
192 final providerId = sharedPreferences.getString(key);
193 if (providerId != null) {
190 - defaultBuyProviders[walletType] = ProviderType.values
191 - .firstWhere((provider) => provider.id == providerId, orElse: () => ProviderType.askEachTime);
194 + defaultBuyProviders[walletType] = ProviderType.values.firstWhere(
195 + (provider) => provider.id == providerId,
196 + orElse: () => ProviderType.askEachTime);
197 } else {
198 defaultBuyProviders[walletType] = ProviderType.askEachTime;
199 }
@@ -198,8 +203,9 @@ abstract class SettingsStoreBase with Store {
203 final key = 'sellProvider_${walletType.toString()}';
204 final providerId = sharedPreferences.getString(key);
205 if (providerId != null) {
201 - defaultSellProviders[walletType] = ProviderType.values
202 - .firstWhere((provider) => provider.id == providerId, orElse: () => ProviderType.askEachTime);
206 + defaultSellProviders[walletType] = ProviderType.values.firstWhere(
207 + (provider) => provider.id == providerId,
208 + orElse: () => ProviderType.askEachTime);
209 } else {
210 defaultSellProviders[walletType] = ProviderType.askEachTime;
211 }
@@ -312,74 +318,6 @@ abstract class SettingsStoreBase with Store {
318 reaction((_) => currentTheme,
319 (ThemeBase theme) => sharedPreferences.setInt(PreferencesKey.currentTheme, theme.raw));
320
315 - reaction(
316 - (_) => allowBiometricalAuthentication,
317 - (bool biometricalAuthentication) => sharedPreferences.setBool(
318 - PreferencesKey.allowBiometricalAuthenticationKey, biometricalAuthentication));
319 -
320 - reaction(
321 - (_) => selectedCake2FAPreset,
322 - (Cake2FAPresetsOptions selectedCake2FAPreset) => sharedPreferences.setInt(
323 - PreferencesKey.selectedCake2FAPreset, selectedCake2FAPreset.serialize()));
324 -
325 - reaction(
326 - (_) => shouldRequireTOTP2FAForAccessingWallet,
327 - (bool requireTOTP2FAForAccessingWallet) => sharedPreferences.setBool(
328 - PreferencesKey.shouldRequireTOTP2FAForAccessingWallet,
329 - requireTOTP2FAForAccessingWallet));
330 -
331 - reaction(
332 - (_) => shouldRequireTOTP2FAForSendsToContact,
333 - (bool requireTOTP2FAForSendsToContact) => sharedPreferences.setBool(
334 - PreferencesKey.shouldRequireTOTP2FAForSendsToContact, requireTOTP2FAForSendsToContact));
335 -
336 - reaction(
337 - (_) => shouldRequireTOTP2FAForSendsToNonContact,
338 - (bool requireTOTP2FAForSendsToNonContact) => sharedPreferences.setBool(
339 - PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact,
340 - requireTOTP2FAForSendsToNonContact));
341 -
342 - reaction(
343 - (_) => shouldRequireTOTP2FAForSendsToInternalWallets,
344 - (bool requireTOTP2FAForSendsToInternalWallets) => sharedPreferences.setBool(
345 - PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets,
346 - requireTOTP2FAForSendsToInternalWallets));
347 -
348 - reaction(
349 - (_) => shouldRequireTOTP2FAForExchangesToInternalWallets,
350 - (bool requireTOTP2FAForExchangesToInternalWallets) => sharedPreferences.setBool(
351 - PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
352 - requireTOTP2FAForExchangesToInternalWallets));
353 -
354 - reaction(
355 - (_) => shouldRequireTOTP2FAForExchangesToExternalWallets,
356 - (bool requireTOTP2FAForExchangesToExternalWallets) => sharedPreferences.setBool(
357 - PreferencesKey.shouldRequireTOTP2FAForExchangesToExternalWallets,
358 - requireTOTP2FAForExchangesToExternalWallets));
359 -
360 - reaction(
361 - (_) => shouldRequireTOTP2FAForAddingContacts,
362 - (bool requireTOTP2FAForAddingContacts) => sharedPreferences.setBool(
363 - PreferencesKey.shouldRequireTOTP2FAForAddingContacts, requireTOTP2FAForAddingContacts));
364 -
365 - reaction(
366 - (_) => shouldRequireTOTP2FAForCreatingNewWallets,
367 - (bool requireTOTP2FAForCreatingNewWallets) => sharedPreferences.setBool(
368 - PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets,
369 - requireTOTP2FAForCreatingNewWallets));
370 -
371 - reaction(
372 - (_) => shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
373 - (bool requireTOTP2FAForAllSecurityAndBackupSettings) => sharedPreferences.setBool(
374 - PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
375 - requireTOTP2FAForAllSecurityAndBackupSettings));
376 -
377 - reaction(
378 - (_) => useTOTP2FA, (bool use) => sharedPreferences.setBool(PreferencesKey.useTOTP2FA, use));
379 -
380 - reaction((_) => totpSecretKey,
381 - (String totpKey) => sharedPreferences.setString(PreferencesKey.totpSecretKey, totpKey));
382 -
321 reaction(
322 (_) => numberOfFailedTokenTrials,
323 (int failedTokenTrail) =>
@@ -403,11 +341,6 @@ abstract class SettingsStoreBase with Store {
341 (SeedPhraseLength seedPhraseWordCount) => sharedPreferences.setInt(
342 PreferencesKey.currentSeedPhraseLength, seedPhraseWordCount.value));
343
406 - reaction(
407 - (_) => pinTimeOutDuration,
408 - (PinCodeRequiredDuration pinCodeInterval) =>
409 - sharedPreferences.setInt(PreferencesKey.pinTimeOutDuration, pinCodeInterval.value));
410 -
344 reaction(
345 (_) => balanceDisplayMode,
346 (BalanceDisplayMode mode) => sharedPreferences.setInt(
@@ -485,6 +418,84 @@ abstract class SettingsStoreBase with Store {
418 reaction((_) => lookupsENS,
419 (bool looksUpENS) => _sharedPreferences.setBool(PreferencesKey.lookupsENS, looksUpENS));
420
421 + // secure storage keys:
422 + reaction(
423 + (_) => allowBiometricalAuthentication,
424 + (bool biometricalAuthentication) => secureStorage.write(
425 + key: SecureKey.allowBiometricalAuthenticationKey,
426 + value: biometricalAuthentication.toString()));
427 +
428 + reaction(
429 + (_) => selectedCake2FAPreset,
430 + (Cake2FAPresetsOptions selectedCake2FAPreset) => secureStorage.write(
431 + key: SecureKey.selectedCake2FAPreset,
432 + value: selectedCake2FAPreset.serialize().toString()));
433 +
434 + reaction(
435 + (_) => shouldRequireTOTP2FAForAccessingWallet,
436 + (bool requireTOTP2FAForAccessingWallet) => secureStorage.write(
437 + key: SecureKey.shouldRequireTOTP2FAForAccessingWallet,
438 + value: requireTOTP2FAForAccessingWallet.toString()));
439 +
440 + reaction(
441 + (_) => shouldRequireTOTP2FAForSendsToContact,
442 + (bool requireTOTP2FAForSendsToContact) => secureStorage.write(
443 + key: SecureKey.shouldRequireTOTP2FAForSendsToContact,
444 + value: requireTOTP2FAForSendsToContact.toString()));
445 +
446 + reaction(
447 + (_) => shouldRequireTOTP2FAForSendsToNonContact,
448 + (bool requireTOTP2FAForSendsToNonContact) => secureStorage.write(
449 + key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact,
450 + value: requireTOTP2FAForSendsToNonContact.toString()));
451 +
452 + reaction(
453 + (_) => shouldRequireTOTP2FAForSendsToInternalWallets,
454 + (bool requireTOTP2FAForSendsToInternalWallets) => secureStorage.write(
455 + key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets,
456 + value: requireTOTP2FAForSendsToInternalWallets.toString()));
457 +
458 + reaction(
459 + (_) => shouldRequireTOTP2FAForExchangesToInternalWallets,
460 + (bool requireTOTP2FAForExchangesToInternalWallets) => secureStorage.write(
461 + key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
462 + value: requireTOTP2FAForExchangesToInternalWallets.toString()));
463 +
464 + reaction(
465 + (_) => shouldRequireTOTP2FAForExchangesToExternalWallets,
466 + (bool requireTOTP2FAForExchangesToExternalWallets) => secureStorage.write(
467 + key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets,
468 + value: requireTOTP2FAForExchangesToExternalWallets.toString()));
469 +
470 + reaction(
471 + (_) => shouldRequireTOTP2FAForAddingContacts,
472 + (bool requireTOTP2FAForAddingContacts) => secureStorage.write(
473 + key: SecureKey.shouldRequireTOTP2FAForAddingContacts,
474 + value: requireTOTP2FAForAddingContacts.toString()));
475 +
476 + reaction(
477 + (_) => shouldRequireTOTP2FAForCreatingNewWallets,
478 + (bool requireTOTP2FAForCreatingNewWallets) => secureStorage.write(
479 + key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets,
480 + value: requireTOTP2FAForCreatingNewWallets.toString()));
481 +
482 + reaction(
483 + (_) => shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
484 + (bool requireTOTP2FAForAllSecurityAndBackupSettings) => secureStorage.write(
485 + key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
486 + value: requireTOTP2FAForAllSecurityAndBackupSettings.toString()));
487 +
488 + reaction((_) => useTOTP2FA,
489 + (bool use) => secureStorage.write(key: SecureKey.useTOTP2FA, value: use.toString()));
490 +
491 + reaction((_) => totpSecretKey,
492 + (String totpKey) => secureStorage.write(key: SecureKey.totpSecretKey, value: totpKey));
493 +
494 + reaction(
495 + (_) => pinTimeOutDuration,
496 + (PinCodeRequiredDuration pinCodeInterval) => secureStorage.write(
497 + key: SecureKey.pinTimeOutDuration, value: pinCodeInterval.value.toString()));
498 +
499 this.nodes.observe((change) {
500 if (change.newValue != null && change.key != null) {
501 _saveCurrentNode(change.newValue!, change.key!);
@@ -668,6 +679,7 @@ abstract class SettingsStoreBase with Store {
679
680 String deviceName;
681
682 + final FlutterSecureStorage _secureStorage;
683 final SharedPreferences _sharedPreferences;
684 final BackgroundTasks _backgroundTasks;
685
@@ -710,6 +722,7 @@ abstract class SettingsStoreBase with Store {
722 BalanceDisplayMode initialBalanceDisplayMode = BalanceDisplayMode.availableBalance,
723 ThemeBase? initialTheme}) async {
724 final sharedPreferences = await getIt.getAsync<SharedPreferences>();
725 + final secureStorage = await getIt.get<FlutterSecureStorage>();
726 final backgroundTasks = getIt.get<BackgroundTasks>();
727 final currentFiatCurrency = FiatCurrency.deserialize(
728 raw: sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey)!);
@@ -770,36 +783,6 @@ abstract class SettingsStoreBase with Store {
783 final currentFiatApiMode = FiatApiMode.deserialize(
784 raw: sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey) ??
785 FiatApiMode.enabled.raw);
773 - final allowBiometricalAuthentication =
774 - sharedPreferences.getBool(PreferencesKey.allowBiometricalAuthenticationKey) ?? false;
775 - final selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize(
776 - raw: sharedPreferences.getInt(PreferencesKey.selectedCake2FAPreset) ??
777 - Cake2FAPresetsOptions.normal.raw);
778 - final shouldRequireTOTP2FAForAccessingWallet =
779 - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAccessingWallet) ?? false;
780 - final shouldRequireTOTP2FAForSendsToContact =
781 - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToContact) ?? false;
782 - final shouldRequireTOTP2FAForSendsToNonContact =
783 - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact) ?? false;
784 - final shouldRequireTOTP2FAForSendsToInternalWallets =
785 - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets) ??
786 - false;
787 - final shouldRequireTOTP2FAForExchangesToInternalWallets = sharedPreferences
788 - .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets) ??
789 - false;
790 - final shouldRequireTOTP2FAForExchangesToExternalWallets = sharedPreferences
791 - .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToExternalWallets) ??
792 - false;
793 - final shouldRequireTOTP2FAForAddingContacts =
794 - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAddingContacts) ?? false;
795 - final shouldRequireTOTP2FAForCreatingNewWallets =
796 - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets) ??
797 - false;
798 - final shouldRequireTOTP2FAForAllSecurityAndBackupSettings = sharedPreferences
799 - .getBool(PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings) ??
800 - false;
801 - final useTOTP2FA = sharedPreferences.getBool(PreferencesKey.useTOTP2FA) ?? false;
802 - final totpSecretKey = sharedPreferences.getString(PreferencesKey.totpSecretKey) ?? '';
786 final tokenTrialNumber = sharedPreferences.getInt(PreferencesKey.failedTotpTokenTrials) ?? 0;
787 final shouldShowMarketPlaceInDashboard =
788 sharedPreferences.getBool(PreferencesKey.shouldShowMarketPlaceInDashboard) ?? true;
@@ -816,18 +799,14 @@ abstract class SettingsStoreBase with Store {
799 actionListDisplayMode.addAll(deserializeActionlistDisplayModes(
800 sharedPreferences.getInt(PreferencesKey.displayActionListModeKey) ?? defaultActionsMode));
801 var pinLength = sharedPreferences.getInt(PreferencesKey.currentPinLength);
819 - final timeOutDuration = sharedPreferences.getInt(PreferencesKey.pinTimeOutDuration);
820 - final seedPhraseCount = sharedPreferences.getInt(PreferencesKey.currentSeedPhraseLength);
821 - final pinCodeTimeOutDuration = timeOutDuration != null
822 - ? PinCodeRequiredDuration.deserialize(raw: timeOutDuration)
823 - : defaultPinCodeTimeOutDuration;
824 - final seedPhraseWordCount = seedPhraseCount != null
825 - ? SeedPhraseLength.deserialize(raw: seedPhraseCount)
826 - : defaultSeedPhraseLength;
802 final sortBalanceBy =
803 SortBalanceBy.values[sharedPreferences.getInt(PreferencesKey.sortBalanceBy) ?? 0];
804 final pinNativeTokenAtTop =
805 sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop) ?? true;
806 + final seedPhraseCount = sharedPreferences.getInt(PreferencesKey.currentSeedPhraseLength);
807 + final seedPhraseWordCount = seedPhraseCount != null
808 + ? SeedPhraseLength.deserialize(raw: seedPhraseCount)
809 + : defaultSeedPhraseLength;
810 final useEtherscan = sharedPreferences.getBool(PreferencesKey.useEtherscan) ?? true;
811 final usePolygonScan = sharedPreferences.getBool(PreferencesKey.usePolygonScan) ?? true;
812 final defaultNanoRep = sharedPreferences.getString(PreferencesKey.defaultNanoRep) ?? "";
@@ -929,7 +908,101 @@ abstract class SettingsStoreBase with Store {
908 });
909 final savedSyncAll = sharedPreferences.getBool(PreferencesKey.syncAllKey) ?? true;
910
911 + // migrated to secure:
912 + final timeOutDuration = await SecureKey.getInt(
913 + secureStorage: secureStorage,
914 + sharedPreferences: sharedPreferences,
915 + key: SecureKey.pinTimeOutDuration,
916 + );
917 +
918 + final pinCodeTimeOutDuration = timeOutDuration != null
919 + ? PinCodeRequiredDuration.deserialize(raw: timeOutDuration)
920 + : defaultPinCodeTimeOutDuration;
921 +
922 + final allowBiometricalAuthentication = await SecureKey.getBool(
923 + secureStorage: secureStorage,
924 + sharedPreferences: sharedPreferences,
925 + key: SecureKey.pinTimeOutDuration,
926 + ) ??
927 + false;
928 +
929 + final selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize(
930 + raw: await SecureKey.getInt(
931 + secureStorage: secureStorage,
932 + sharedPreferences: sharedPreferences,
933 + key: SecureKey.selectedCake2FAPreset,
934 + ) ??
935 + Cake2FAPresetsOptions.normal.raw);
936 +
937 + final shouldRequireTOTP2FAForAccessingWallet = await SecureKey.getBool(
938 + secureStorage: secureStorage,
939 + sharedPreferences: sharedPreferences,
940 + key: SecureKey.shouldRequireTOTP2FAForAccessingWallet,
941 + ) ??
942 + false;
943 + final shouldRequireTOTP2FAForSendsToContact = await SecureKey.getBool(
944 + secureStorage: secureStorage,
945 + sharedPreferences: sharedPreferences,
946 + key: SecureKey.shouldRequireTOTP2FAForSendsToContact,
947 + ) ??
948 + false;
949 + final shouldRequireTOTP2FAForSendsToNonContact = await SecureKey.getBool(
950 + secureStorage: secureStorage,
951 + sharedPreferences: sharedPreferences,
952 + key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact,
953 + ) ??
954 + false;
955 + final shouldRequireTOTP2FAForSendsToInternalWallets = await SecureKey.getBool(
956 + secureStorage: secureStorage,
957 + sharedPreferences: sharedPreferences,
958 + key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets,
959 + ) ??
960 + false;
961 + final shouldRequireTOTP2FAForExchangesToInternalWallets = await SecureKey.getBool(
962 + secureStorage: secureStorage,
963 + sharedPreferences: sharedPreferences,
964 + key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
965 + ) ??
966 + false;
967 + final shouldRequireTOTP2FAForExchangesToExternalWallets = await SecureKey.getBool(
968 + secureStorage: secureStorage,
969 + sharedPreferences: sharedPreferences,
970 + key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets,
971 + ) ??
972 + false;
973 + final shouldRequireTOTP2FAForAddingContacts = await SecureKey.getBool(
974 + secureStorage: secureStorage,
975 + sharedPreferences: sharedPreferences,
976 + key: SecureKey.shouldRequireTOTP2FAForAddingContacts,
977 + ) ??
978 + false;
979 + final shouldRequireTOTP2FAForCreatingNewWallets = await SecureKey.getBool(
980 + secureStorage: secureStorage,
981 + sharedPreferences: sharedPreferences,
982 + key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets,
983 + ) ??
984 + false;
985 + final shouldRequireTOTP2FAForAllSecurityAndBackupSettings = await SecureKey.getBool(
986 + secureStorage: secureStorage,
987 + sharedPreferences: sharedPreferences,
988 + key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
989 + ) ??
990 + false;
991 + final useTOTP2FA = await SecureKey.getBool(
992 + secureStorage: secureStorage,
993 + sharedPreferences: sharedPreferences,
994 + key: SecureKey.useTOTP2FA,
995 + ) ??
996 + false;
997 + final totpSecretKey = await SecureKey.getString(
998 + secureStorage: secureStorage,
999 + sharedPreferences: sharedPreferences,
1000 + key: SecureKey.useTOTP2FA,
1001 + ) ??
1002 + '';
1003 +
1004 return SettingsStore(
1005 + secureStorage: secureStorage,
1006 sharedPreferences: sharedPreferences,
1007 initialShouldShowMarketPlaceInDashboard: shouldShowMarketPlaceInDashboard,
1008 nodes: nodes,
@@ -1055,8 +1128,6 @@ abstract class SettingsStoreBase with Store {
1128 shouldSaveRecipientAddress =
1129 sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey) ??
1130 shouldSaveRecipientAddress;
1058 - useTOTP2FA = sharedPreferences.getBool(PreferencesKey.useTOTP2FA) ?? useTOTP2FA;
1059 - totpSecretKey = sharedPreferences.getString(PreferencesKey.totpSecretKey) ?? totpSecretKey;
1131 numberOfFailedTokenTrials =
1132 sharedPreferences.getInt(PreferencesKey.failedTotpTokenTrials) ?? numberOfFailedTokenTrials;
1133 isAppSecure = sharedPreferences.getBool(PreferencesKey.isAppSecureKey) ?? isAppSecure;
@@ -1065,41 +1136,10 @@ abstract class SettingsStoreBase with Store {
1136 walletListOrder =
1137 WalletListOrderType.values[sharedPreferences.getInt(PreferencesKey.walletListOrder) ?? 0];
1138 walletListAscending = sharedPreferences.getBool(PreferencesKey.walletListAscending) ?? true;
1068 - allowBiometricalAuthentication =
1069 - sharedPreferences.getBool(PreferencesKey.allowBiometricalAuthenticationKey) ??
1070 - allowBiometricalAuthentication;
1071 - selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize(
1072 - raw: sharedPreferences.getInt(PreferencesKey.selectedCake2FAPreset) ??
1073 - Cake2FAPresetsOptions.normal.raw);
1074 - shouldRequireTOTP2FAForAccessingWallet =
1075 - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAccessingWallet) ?? false;
1076 - shouldRequireTOTP2FAForSendsToContact =
1077 - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToContact) ?? false;
1078 - shouldRequireTOTP2FAForSendsToNonContact =
1079 - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact) ?? false;
1080 - shouldRequireTOTP2FAForSendsToInternalWallets =
1081 - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets) ??
1082 - false;
1083 - shouldRequireTOTP2FAForExchangesToInternalWallets = sharedPreferences
1084 - .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets) ??
1085 - false;
1086 - shouldRequireTOTP2FAForExchangesToExternalWallets = sharedPreferences
1087 - .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToExternalWallets) ??
1088 - false;
1089 - shouldRequireTOTP2FAForAddingContacts =
1090 - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAddingContacts) ?? false;
1091 - shouldRequireTOTP2FAForCreatingNewWallets =
1092 - sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets) ??
1093 - false;
1094 - shouldRequireTOTP2FAForAllSecurityAndBackupSettings = sharedPreferences
1095 - .getBool(PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings) ??
1096 - false;
1139 +
1140 shouldShowMarketPlaceInDashboard =
1141 sharedPreferences.getBool(PreferencesKey.shouldShowMarketPlaceInDashboard) ??
1142 shouldShowMarketPlaceInDashboard;
1100 - selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize(
1101 - raw: sharedPreferences.getInt(PreferencesKey.selectedCake2FAPreset) ??
1102 - Cake2FAPresetsOptions.narrow.raw);
1143 exchangeStatus = ExchangeApiMode.deserialize(
1144 raw: sharedPreferences.getInt(PreferencesKey.exchangeStatusKey) ??
1145 ExchangeApiMode.enabled.raw);
@@ -1188,6 +1228,93 @@ abstract class SettingsStoreBase with Store {
1228 if (nanoNode != null) {
1229 nodes[WalletType.nano] = nanoNode;
1230 }
1231 +
1232 + // MIGRATED:
1233 +
1234 + useTOTP2FA = await SecureKey.getBool(
1235 + secureStorage: _secureStorage,
1236 + sharedPreferences: sharedPreferences,
1237 + key: SecureKey.useTOTP2FA,
1238 + ) ??
1239 + useTOTP2FA;
1240 +
1241 + totpSecretKey = await SecureKey.getString(
1242 + secureStorage: _secureStorage,
1243 + sharedPreferences: sharedPreferences,
1244 + key: SecureKey.useTOTP2FA,
1245 + ) ??
1246 + totpSecretKey;
1247 +
1248 + allowBiometricalAuthentication = await SecureKey.getBool(
1249 + secureStorage: _secureStorage,
1250 + sharedPreferences: sharedPreferences,
1251 + key: SecureKey.allowBiometricalAuthenticationKey,
1252 + ) ??
1253 + allowBiometricalAuthentication;
1254 +
1255 + selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize(
1256 + raw: await SecureKey.getInt(
1257 + secureStorage: _secureStorage,
1258 + sharedPreferences: sharedPreferences,
1259 + key: SecureKey.selectedCake2FAPreset,
1260 + ) ??
1261 + Cake2FAPresetsOptions.normal.raw);
1262 +
1263 + shouldRequireTOTP2FAForAccessingWallet = await SecureKey.getBool(
1264 + secureStorage: _secureStorage,
1265 + sharedPreferences: sharedPreferences,
1266 + key: SecureKey.shouldRequireTOTP2FAForAccessingWallet,
1267 + ) ??
1268 + false;
1269 + shouldRequireTOTP2FAForSendsToContact = await SecureKey.getBool(
1270 + secureStorage: _secureStorage,
1271 + sharedPreferences: sharedPreferences,
1272 + key: SecureKey.shouldRequireTOTP2FAForSendsToContact,
1273 + ) ??
1274 + false;
1275 +
1276 + shouldRequireTOTP2FAForSendsToNonContact = await SecureKey.getBool(
1277 + secureStorage: _secureStorage,
1278 + sharedPreferences: sharedPreferences,
1279 + key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact,
1280 + ) ??
1281 + false;
1282 + shouldRequireTOTP2FAForSendsToInternalWallets = await SecureKey.getBool(
1283 + secureStorage: _secureStorage,
1284 + sharedPreferences: sharedPreferences,
1285 + key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets,
1286 + ) ??
1287 + false;
1288 + shouldRequireTOTP2FAForExchangesToInternalWallets = await SecureKey.getBool(
1289 + secureStorage: _secureStorage,
1290 + sharedPreferences: sharedPreferences,
1291 + key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
1292 + ) ??
1293 + false;
1294 + shouldRequireTOTP2FAForExchangesToExternalWallets = await SecureKey.getBool(
1295 + secureStorage: _secureStorage,
1296 + sharedPreferences: sharedPreferences,
1297 + key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets,
1298 + ) ??
1299 + false;
1300 + shouldRequireTOTP2FAForAddingContacts = await SecureKey.getBool(
1301 + secureStorage: _secureStorage,
1302 + sharedPreferences: sharedPreferences,
1303 + key: SecureKey.shouldRequireTOTP2FAForAddingContacts,
1304 + ) ??
1305 + false;
1306 + shouldRequireTOTP2FAForCreatingNewWallets = await SecureKey.getBool(
1307 + secureStorage: _secureStorage,
1308 + sharedPreferences: sharedPreferences,
1309 + key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets,
1310 + ) ??
1311 + false;
1312 + shouldRequireTOTP2FAForAllSecurityAndBackupSettings = await SecureKey.getBool(
1313 + secureStorage: _secureStorage,
1314 + sharedPreferences: sharedPreferences,
1315 + key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
1316 + ) ??
1317 + false;
1318 }
1319
1320 Future<void> _saveCurrentNode(Node node, WalletType walletType) async {
lib/view_model/settings/security_settings_view_model.dart
+1 -1
@@ -44,5 +44,5 @@ abstract class SecuritySettingsViewModelBase with Store {
44 setPinCodeRequiredDuration(PinCodeRequiredDuration duration) =>
45 _settingsStore.pinTimeOutDuration = duration;
46
47 - bool checkPinCodeRiquired() => _authService.requireAuth();
47 + Future<bool> checkPinCodeRiquired() => _authService.requireAuth();
48 }
lib/view_model/wallet_list/wallet_list_view_model.dart
+1 -1
@@ -161,7 +161,7 @@ abstract class WalletListViewModelBase with Store {
161 }
162 }
163
164 - bool checkIfAuthRequired() {
164 + Future<bool> checkIfAuthRequired() async {
165 return _authService.requireAuth();
166 }
167 }