dev
dart 162 lines 5.51 KB
Raw
1 import 'package:cake_wallet/core/secure_storage.dart';
2 import 'package:cake_wallet/entities/secret_store_key.dart';
3 import 'package:cake_wallet/store/authentication_store.dart';
4 import 'package:cake_wallet/store/settings_store.dart';
5 import 'package:cake_wallet/entities/preferences_key.dart';
6 import 'package:shared_preferences/shared_preferences.dart';
7 import 'package:cw_core/utils/print_verbose.dart';
8
9 class ResetService {
10 ResetService({
11 required this.secureStorage,
12 required this.authenticationStore,
13 required this.settingsStore,
14 });
15
16 final SecureStorage secureStorage;
17 final AuthenticationStore authenticationStore;
18 final SettingsStore settingsStore;
19
20 static const List<String> _authKeys = [
21 SecureKey.allowBiometricalAuthenticationKey,
22 SecureKey.useTOTP2FA,
23 SecureKey.shouldRequireTOTP2FAForAccessingWallet,
24 SecureKey.shouldRequireTOTP2FAForSendsToContact,
25 SecureKey.shouldRequireTOTP2FAForSendsToNonContact,
26 SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets,
27 SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
28 SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets,
29 SecureKey.shouldRequireTOTP2FAForAddingContacts,
30 SecureKey.shouldRequireTOTP2FAForCreatingNewWallets,
31 SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
32 SecureKey.selectedCake2FAPreset,
33 SecureKey.totpSecretKey,
34 SecureKey.pinTimeOutDuration,
35 SecureKey.lastAuthTimeMilliseconds,
36 'PIN_CODE_PASSWORD',
37 ];
38
39 static const List<String> _walletPreferencesKeys = [
40 PreferencesKey.currentWalletName,
41 PreferencesKey.currentWalletType,
42 ];
43
44 bool _isAuthKey(String key) => _authKeys.contains(key);
45
46 /// Checks if this is a new install and clears any existing auth data from Storage
47 Future<void> resetAuthDataOnNewInstall(SharedPreferences sharedPreferences) async {
48 try {
49 final isNewInstall = sharedPreferences.getBool(PreferencesKey.isNewInstall) ?? false;
50
51 if (isNewInstall) {
52 await _clearExistingAuthDataOnNewInstall(sharedPreferences);
53 }
54 } catch (e) {
55 printV('Error during new install auth reset: $e');
56 }
57 }
58
59 /// Checks if there's existing auth data that should be cleared on new install
60 Future<void> _clearExistingAuthDataOnNewInstall(SharedPreferences sharedPreferences) async {
61 final allKeys = await secureStorage.readAll();
62 final authKeysFound = <String>[];
63 final walletPrefsFound = <String>[];
64
65 for (final key in allKeys.keys) {
66 if (_isAuthKey(key)) {
67 authKeysFound.add(key);
68 }
69 }
70
71 for (final key in _walletPreferencesKeys) {
72 if (sharedPreferences.containsKey(key)) {
73 walletPrefsFound.add(key);
74 }
75 }
76
77 if (authKeysFound.isNotEmpty || walletPrefsFound.isNotEmpty) {
78 printV(
79 'Found ${authKeysFound.length} existing auth keys in storage: ${authKeysFound.join(', ')}',
80 );
81 printV(
82 'Found ${walletPrefsFound.length} existing wallet preferences: ${walletPrefsFound.join(', ')}',
83 );
84
85 await resetAuthenticationData(sharedPreferences);
86 }
87 }
88
89 /// Resets authentication data auth store, storage and settings store
90 Future<void> resetAuthenticationData(SharedPreferences sharedPreferences) async {
91 try {
92 authenticationStore.state = AuthenticationState.uninitialized;
93
94 await Future.wait([
95 _deleteAuthenticationKeys(),
96 _resetSettingsStoreAuthData(),
97 _clearWalletPreferences(sharedPreferences),
98 ]);
99 } catch (e) {
100 printV('An error occurred during authentication reset: $e');
101 rethrow;
102 }
103 }
104
105 /// Resets authentication-related data in SettingsStore to default values
106 Future<void> _resetSettingsStoreAuthData() async {
107 settingsStore.useTOTP2FA = false;
108 settingsStore.totpSecretKey = '';
109 settingsStore.shouldRequireTOTP2FAForAccessingWallet = false;
110 settingsStore.shouldRequireTOTP2FAForSendsToContact = false;
111 settingsStore.shouldRequireTOTP2FAForSendsToNonContact = false;
112 settingsStore.shouldRequireTOTP2FAForSendsToInternalWallets = false;
113 settingsStore.shouldRequireTOTP2FAForExchangesToInternalWallets = false;
114 settingsStore.shouldRequireTOTP2FAForExchangesToExternalWallets = false;
115 settingsStore.shouldRequireTOTP2FAForAddingContacts = false;
116 settingsStore.shouldRequireTOTP2FAForCreatingNewWallets = false;
117 settingsStore.shouldRequireTOTP2FAForAllSecurityAndBackupSettings = false;
118 settingsStore.allowBiometricalAuthentication = false;
119 }
120
121 Future<void> _clearWalletPreferences(SharedPreferences sharedPreferences) async {
122 final failedDeletions = <String>[];
123
124 for (final key in _walletPreferencesKeys) {
125 try {
126 await sharedPreferences.remove(key);
127 } catch (e) {
128 failedDeletions.add(key);
129 }
130 }
131
132 if (failedDeletions.isNotEmpty) {
133 printV(
134 'Warning: Failed to delete ${failedDeletions.length} wallet preferences: ${failedDeletions.join(', ')}',
135 );
136 } else {
137 printV('All wallet preferences deleted successfully');
138 }
139 }
140
141 Future<void> _deleteAuthenticationKeys() async {
142 final failedDeletions = <String>[];
143
144 final deletionFutures = _authKeys.map((key) async {
145 try {
146 await secureStorage.delete(key: key);
147 } catch (e) {
148 failedDeletions.add(key);
149 }
150 });
151
152 await Future.wait(deletionFutures);
153
154 if (failedDeletions.isNotEmpty) {
155 printV(
156 'Warning: Failed to delete ${failedDeletions.length} auth keys: ${failedDeletions.join(', ')}',
157 );
158 } else {
159 printV('All auth keys deleted successfully');
160 }
161 }
162 }