diff --git a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyCreationController.java b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyCreationController.java index 456de11f4..e67ca87c6 100644 --- a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyCreationController.java +++ b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyCreationController.java @@ -104,7 +104,7 @@ public class RecoveryKeyCreationController implements FxController { descriptionLabel.formatProperty().set(resourceBundle.getString("recoveryKey.recover.description")); cancelButton.setOnAction((_) -> back()); cancelButton.setText(resourceBundle.getString("generic.button.back")); - nextButton.setOnAction((_) -> restoreWithPassword()); + nextButton.setOnAction((_) -> restoreWithPasswordAsync()); } } @@ -137,11 +137,47 @@ public class RecoveryKeyCreationController implements FxController { } @FXML - public void restoreWithPassword() { + public void restoreWithPasswordAsync() { + Task task = RecoveryKeyTasks.createTask(this::restoreWithPassword); + task.setOnScheduled(_ -> { + LOG.debug("Restoring vault configuration with password for {}.", vault.getDisplayablePath()); + }); + + task.setOnSucceeded(_ -> { + LOG.debug("Restored vault configuration for {}.", vault.getDisplayablePath()); + try { + if (!vaultListManager.isAlreadyAdded(vault.getPath())) { + vaultListManager.add(vault.getPath()); + } + window.close(); + dialogs.prepareRecoverPasswordSuccess((Stage) window.getOwner()) // + .setTitleKey("recover.recoverVaultConfig.title") // + .setMessageKey("recoveryKey.recover.resetVaultConfigSuccess.message") // + .setDescriptionKey("recoveryKey.recover.resetMasterkeyFileSuccess.description") + .build().showAndWait(); + } catch (IOException e) { + LOG.error("Failed to add vault to list.", e); + appWindows.showErrorWindow(e, window, null); + } + }); + + task.setOnFailed(_ -> { + if (task.getException() instanceof InvalidPassphraseException e) { + LOG.info("Password invalid", e); + Animations.createShakeWindowAnimation(window).play(); + } else { + LOG.error("Recovery process failed.", task.getException()); + appWindows.showErrorWindow(task.getException(), window, null); + } + }); + + executor.submit(task); + } + + void restoreWithPassword() throws IOException, CryptoException { try (RecoveryDirectory recoveryDirectory = RecoveryDirectory.create(vault.getPath())) { Path recoveryPath = recoveryDirectory.getRecoveryPath(); - Path masterkeyFilePath = vault.getPath().resolve(MASTERKEY_FILENAME); try (Masterkey masterkey = MasterkeyService.load(masterkeyFileAccess, masterkeyFilePath, passwordField.getCharacters())) { @@ -152,23 +188,6 @@ public class RecoveryKeyCreationController implements FxController { } recoveryDirectory.moveRecoveredFile(VAULTCONFIG_FILENAME); - - if (!vaultListManager.isAlreadyAdded(vault.getPath())) { - vaultListManager.add(vault.getPath()); - } - window.close(); - dialogs.prepareRecoverPasswordSuccess((Stage)window.getOwner()) // - .setTitleKey("recover.recoverVaultConfig.title") // - .setMessageKey("recoveryKey.recover.resetVaultConfigSuccess.message") // - .setDescriptionKey("recoveryKey.recover.resetMasterkeyFileSuccess.description") - .build().showAndWait(); - - } catch (InvalidPassphraseException e) { - LOG.info("Password invalid", e); - Animations.createShakeWindowAnimation(window).play(); - } catch (IOException | CryptoException | IllegalStateException e) { - LOG.error("Recovery process failed", e); - appWindows.showErrorWindow(e, window, null); } } diff --git a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyResetPasswordController.java b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyResetPasswordController.java index 0c06ba9b2..b57758b67 100644 --- a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyResetPasswordController.java +++ b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyResetPasswordController.java @@ -117,14 +117,46 @@ public class RecoveryKeyResetPasswordController implements FxController { @FXML public void next() { switch (recoverType.get()) { - case RESTORE_ALL -> restorePassword(); + case RESTORE_ALL -> restorePasswordAsync(); case RESTORE_MASTERKEY, RESET_PASSWORD -> resetPassword(); default -> resetPassword(); // Fallback } } @FXML - public void restorePassword() { + public void restorePasswordAsync() { + Task task = RecoveryKeyTasks.createTask(this::restorePassword); + + task.setOnScheduled(_ -> { + LOG.debug("Restoring vault configuration for {}.", vault.getDisplayablePath()); + }); + + task.setOnSucceeded(_ -> { + LOG.debug("Restored vault configuration for {}.", vault.getDisplayablePath()); + try { + if (!vaultListManager.isAlreadyAdded(vault.getPath())) { + vaultListManager.add(vault.getPath()); + } + window.close(); + dialogs.prepareRecoverPasswordSuccess((Stage) window.getOwner()) // + .setTitleKey("recover.recoverVaultConfig.title") // + .setMessageKey("recoveryKey.recover.resetVaultConfigSuccess.message") // + .build().showAndWait(); + } catch (IOException e) { + LOG.error("Failed to add vault to list.", e); + appWindows.showErrorWindow(e, window, null); + } + }); + + task.setOnFailed(_ -> { + LOG.error("Recovery process failed.", task.getException()); + appWindows.showErrorWindow(task.getException(), window, null); + }); + + executor.submit(task); + } + + void restorePassword() throws IOException, CryptoException { try (RecoveryDirectory recoveryDirectory = RecoveryDirectory.create(vault.getPath())) { Path recoveryPath = recoveryDirectory.getRecoveryPath(); MasterkeyService.recoverFromRecoveryKey(recoveryKey.get(), recoveryKeyFactory, recoveryPath, newPasswordController.passwordField.getCharacters()); @@ -135,19 +167,6 @@ public class RecoveryKeyResetPasswordController implements FxController { recoveryDirectory.moveRecoveredFile(MASTERKEY_FILENAME); recoveryDirectory.moveRecoveredFile(VAULTCONFIG_FILENAME); - - if (!vaultListManager.isAlreadyAdded(vault.getPath())) { - vaultListManager.add(vault.getPath()); - } - window.close(); - dialogs.prepareRecoverPasswordSuccess((Stage)window.getOwner()) // - .setTitleKey("recover.recoverVaultConfig.title") // - .setMessageKey("recoveryKey.recover.resetVaultConfigSuccess.message") // - .build().showAndWait(); - - } catch (IOException | CryptoException e) { - LOG.error("Recovery process failed", e); - appWindows.showErrorWindow(e, window, null); } } diff --git a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyTasks.java b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyTasks.java new file mode 100644 index 000000000..ba6caf249 --- /dev/null +++ b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyTasks.java @@ -0,0 +1,25 @@ +package org.cryptomator.ui.recoverykey; + +import javafx.concurrent.Task; + +final class RecoveryKeyTasks { + + private RecoveryKeyTasks() { + } + + @FunctionalInterface + interface TaskAction { + void run() throws Exception; + } + + static Task createTask(TaskAction action) { + return new Task() { + @Override + protected Void call() throws Exception { + action.run(); + return null; + } + }; + } + +}