fix: allow bakcups to be created even if one of the wallets is corrupted (#2221)

This commit is contained in:
cyan 2025-04-22 21:41:31 +02:00 committed by GitHub
parent e4a89f4d1e
commit 3e25be6dcf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 22 additions and 6 deletions

View file

@ -265,16 +265,24 @@ class $BackupService {
{String keychainSalt = secrets.backupKeychainSalt}) async { {String keychainSalt = secrets.backupKeychainSalt}) async {
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword); final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
final wallets = await Future.wait(walletInfoSource.values.map((walletInfo) async { final wallets = await Future.wait(walletInfoSource.values.map((walletInfo) async {
try {
return { return {
'name': walletInfo.name, 'name': walletInfo.name,
'type': walletInfo.type.toString(), 'type': walletInfo.type.toString(),
'password': await keyService.getWalletPassword(walletName: walletInfo.name) 'password': await keyService.getWalletPassword(walletName: walletInfo.name)
}; };
} catch (e) {
return {
'name': walletInfo.name,
'type': walletInfo.type.toString(),
'password': ''
};
}
})); }));
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword); final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
final backupPassword = await _secureStorage.read(key: backupPasswordKey); final backupPassword = await _secureStorage.read(key: backupPasswordKey);
final data = utf8.encode( final data = utf8.encode(
json.encode({'wallets': wallets, backupPasswordKey: backupPassword})); json.encode({'wallets': wallets, backupPasswordKey: backupPassword, '_all': await _secureStorage.readAll()}));
final encrypted = await _encryptV2(Uint8List.fromList(data), '$keychainSalt$password'); final encrypted = await _encryptV2(Uint8List.fromList(data), '$keychainSalt$password');
return encrypted; return encrypted;

View file

@ -1629,6 +1629,7 @@ abstract class SecureStorage {
Future<void> delete({required String key}); Future<void> delete({required String key});
// Legacy // Legacy
Future<String?> readNoIOptions({required String key}); Future<String?> readNoIOptions({required String key});
Future<Map<String, String>> readAll();
}"""; }""";
const defaultSecureStorage = """ const defaultSecureStorage = """
class DefaultSecureStorage extends SecureStorage { class DefaultSecureStorage extends SecureStorage {
@ -1667,6 +1668,11 @@ class DefaultSecureStorage extends SecureStorage {
iOptions: useNoIOptions ? IOSOptions() : null, iOptions: useNoIOptions ? IOSOptions() : null,
); );
} }
@override
Future<Map<String, String>> readAll() async {
return await _secureStorage.readAll();
}
}"""; }""";
const fakeSecureStorage = """ const fakeSecureStorage = """
class FakeSecureStorage extends SecureStorage { class FakeSecureStorage extends SecureStorage {
@ -1678,6 +1684,8 @@ class FakeSecureStorage extends SecureStorage {
Future<void> delete({required String key}) async {} Future<void> delete({required String key}) async {}
@override @override
Future<String?> readNoIOptions({required String key}) async => null; Future<String?> readNoIOptions({required String key}) async => null;
@override
Future<Map<String, String>> readAll() async => {};
}"""; }""";
final outputFile = File(secureStoragePath); final outputFile = File(secureStoragePath);
final header = hasFlutterSecureStorage final header = hasFlutterSecureStorage