fix-monero-com-backup-restore-bug (#3339)

* reject backups from other apps

* make compatibility check optional
This commit is contained in:
Serhii
2026-06-25 12:25:57 +03:00
committed by GitHub
parent cda9d09ead
commit 7a9a585543
3 changed files with 106 additions and 22 deletions
@@ -1,6 +1,8 @@
import 'package:cake_wallet/core/backup_service_v3.dart';
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
@@ -18,6 +20,7 @@ class RestoreFromBackupPage extends BasePage {
final RestoreFromBackupViewModel restoreFromBackupViewModel;
final TextEditingController textEditingController;
bool _isStateReactionSet = false;
@override
String get title => S.current.restore_title_from_backup;
@@ -32,22 +35,26 @@ class RestoreFromBackupPage extends BasePage {
@override
Widget body(BuildContext context) {
reaction((_) => restoreFromBackupViewModel.state, (ExecutionState state) {
if (state is FailureState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.of(context).error,
alertContent: state.error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop(),
);
});
});
}
});
if (!_isStateReactionSet) {
_isStateReactionSet = true;
reaction((_) => restoreFromBackupViewModel.state, (ExecutionState state) {
if (state is FailureState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.of(context).error,
alertContent: state.error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop(),
);
});
});
}
});
}
return Center(
child: ConstrainedBox(
@@ -175,6 +182,29 @@ class RestoreFromBackupPage extends BasePage {
}
try {
await restoreFromBackupViewModel.import(textEditingController.text);
} on IncompatibleBackupAppException catch (e) {
final isConfirmed = await showPopUp<bool>(
context: context,
builder: (_) {
return AlertWithTwoActions(
alertTitle: S.current.warning,
alertContent:
'This backup was created in ${e.sourceAppName}, but you are restoring it in ${e.currentAppName}. '
'Please make sure this is the correct backup file before continuing.',
leftButtonText: S.of(context).cancel,
rightButtonText: S.of(context).ok,
actionLeftButton: () => Navigator.of(context).pop(false),
actionRightButton: () => Navigator.of(context).pop(true),
);
},
);
if (isConfirmed ?? false) {
await restoreFromBackupViewModel.import(
textEditingController.text,
checkBackupApp: false,
);
}
} catch (e) {
await showPopUp<void>(
context: context,