diff --git a/src/main/java/org/cryptomator/common/vaults/VaultListManager.java b/src/main/java/org/cryptomator/common/vaults/VaultListManager.java index c7e03ae70..cb084359a 100644 --- a/src/main/java/org/cryptomator/common/vaults/VaultListManager.java +++ b/src/main/java/org/cryptomator/common/vaults/VaultListManager.java @@ -72,7 +72,7 @@ public class VaultListManager { autoLocker.init(); } - public boolean containsVault(Path vaultPath) { + public boolean isAlreadyAdded(Path vaultPath) { assert vaultPath.isAbsolute(); assert vaultPath.normalize().equals(vaultPath); return vaultList.stream().anyMatch(v -> vaultPath.equals(v.getPath())); @@ -127,7 +127,7 @@ public class VaultListManager { public void addVault(Vault vault) { Path path = vault.getPath().normalize().toAbsolutePath(); - if (!containsVault(path)) { + if (!isAlreadyAdded(path)) { vaultList.add(vault); } } diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultWizardComponent.java b/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultWizardComponent.java index cd68bf254..5b01a6b2f 100644 --- a/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultWizardComponent.java +++ b/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultWizardComponent.java @@ -7,28 +7,13 @@ package org.cryptomator.ui.addvaultwizard; import dagger.Lazy; import dagger.Subcomponent; -import org.cryptomator.common.recovery.RecoveryActionType; -import org.cryptomator.common.vaults.Vault; -import org.cryptomator.common.vaults.VaultComponent; -import org.cryptomator.common.vaults.VaultListManager; -import org.cryptomator.common.vaults.VaultState; -import org.cryptomator.integrations.mount.MountService; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; -import org.cryptomator.ui.dialogs.Dialogs; -import org.cryptomator.ui.recoverykey.RecoveryKeyComponent; -import javafx.beans.property.SimpleObjectProperty; import javafx.scene.Scene; -import javafx.stage.DirectoryChooser; import javafx.stage.Stage; -import javafx.stage.Window; -import java.io.File; -import java.util.List; import java.util.ResourceBundle; -import static org.cryptomator.ui.addvaultwizard.ChooseExistingVaultController.prepareVault; - @AddVaultWizardScoped @Subcomponent(modules = {AddVaultModule.class}) public interface AddVaultWizardComponent { @@ -42,9 +27,6 @@ public interface AddVaultWizardComponent { @FxmlScene(FxmlFile.ADDVAULT_EXISTING) Lazy sceneExisting(); - @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) - Lazy sceneSuccess(); - default void showAddNewVaultWizard(ResourceBundle resourceBundle) { Stage stage = window(); stage.setScene(sceneNew().get()); @@ -61,50 +43,6 @@ public interface AddVaultWizardComponent { stage.show(); } - default void showRecoverExistingVaultWizard(Window mainWindow, // - Dialogs dialogs, // - VaultComponent.Factory vaultComponentFactory, // - List mountServices, // - VaultListManager vaultListManager, // - RecoveryKeyComponent.Factory recoveryKeyWindow) { - Stage stage = window(); - DirectoryChooser directoryChooser = new DirectoryChooser(); - - while (true) { - File selectedDirectory = directoryChooser.showDialog(mainWindow); - if (selectedDirectory == null) { - return; - } - - boolean hasSubfolderD = new File(selectedDirectory, "d").isDirectory(); - if (!hasSubfolderD) { - dialogs.prepareNoDDirectorySelectedDialog(stage).build().showAndWait(); - continue; - } - - Vault preparedVault = prepareVault(selectedDirectory, vaultComponentFactory, mountServices); - - if (!vaultListManager.containsVault(preparedVault.getPath())) { - vaultListManager.addVault(preparedVault); - dialogs.prepareRecoveryVaultAdded(stage).setOkAction(Stage::close).build().showAndWait(); - } - - VaultListManager.redetermineVaultState(preparedVault); - VaultState.Value state = preparedVault.getState(); - - switch (state) { - case VAULT_CONFIG_MISSING -> recoveryKeyWindow.create(preparedVault, stage, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_VAULT_CONFIG)) // - .showOnboardingDialogWindow(); - case ALL_MISSING -> recoveryKeyWindow.create(preparedVault, stage, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_ALL)) // - .showOnboardingDialogWindow(); - default -> dialogs.prepareRecoveryVaultAlreadyExists(stage)// - .setOkAction(Stage::close)// - .build().showAndWait(); - } - break; - } - } - @Subcomponent.Builder interface Builder { diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java index 0eda9ae2b..27c9f6204 100644 --- a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java +++ b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java @@ -2,12 +2,8 @@ package org.cryptomator.ui.addvaultwizard; import dagger.Lazy; import org.apache.commons.lang3.SystemUtils; -import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.common.vaults.Vault; -import org.cryptomator.common.vaults.VaultComponent; -import org.cryptomator.common.vaults.VaultConfigCache; import org.cryptomator.common.vaults.VaultListManager; -import org.cryptomator.integrations.mount.MountService; import org.cryptomator.integrations.uiappearance.Theme; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxmlFile; @@ -18,9 +14,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; -import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; import javafx.scene.Scene; @@ -30,12 +24,10 @@ import javafx.stage.Stage; import java.io.File; import java.io.IOException; import java.nio.file.Path; -import java.util.List; import java.util.Objects; import java.util.ResourceBundle; import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB; -import static org.cryptomator.common.vaults.VaultState.Value.LOCKED; @AddVaultWizardScoped public class ChooseExistingVaultController implements FxController { @@ -51,9 +43,6 @@ public class ChooseExistingVaultController implements FxController { private final ResourceBundle resourceBundle; private final ObservableValue screenshot; - private final BooleanProperty restoreButtonVisible = new SimpleBooleanProperty(false); - - @Inject ChooseExistingVaultController(@AddVaultWizardWindow Stage window, // @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, // @@ -105,33 +94,6 @@ public class ChooseExistingVaultController implements FxController { } } - public static Vault prepareVault(File selectedDirectory, VaultComponent.Factory vaultComponentFactory, List mountServices) { - Path selectedPath = selectedDirectory.toPath(); - VaultSettings vaultSettings = VaultSettings.withRandomId(); - vaultSettings.path.set(selectedPath); - if (selectedPath.getFileName() != null) { - vaultSettings.displayName.set(selectedPath.getFileName().toString()); - } else { - vaultSettings.displayName.set("defaultVaultName"); - } - - var wrapper = new VaultConfigCache(vaultSettings); - Vault vault = vaultComponentFactory.create(vaultSettings, wrapper, LOCKED, null).vault(); - try { - VaultListManager.determineVaultState(vault.getPath(), vaultSettings); - } catch (IOException e) { - LOG.warn("Failed to determine vault state for {}", vaultSettings.path.get(), e); - } - - //due to https://github.com/cryptomator/cryptomator/issues/2880#issuecomment-1680313498 - var nameOfWinfspLocalMounter = "org.cryptomator.frontend.fuse.mount.WinFspMountProvider"; - if (SystemUtils.IS_OS_WINDOWS && vaultSettings.path.get().toString().contains("Dropbox") && mountServices.stream().anyMatch(s -> s.getClass().getName().equals(nameOfWinfspLocalMounter))) { - vaultSettings.mountService.setValue(nameOfWinfspLocalMounter); - } - - return vault; - } - /* Getter */ public ObservableValue screenshotProperty() { diff --git a/src/main/java/org/cryptomator/ui/dialogs/Dialogs.java b/src/main/java/org/cryptomator/ui/dialogs/Dialogs.java index 6e5d91ecd..5ba3e1eb3 100644 --- a/src/main/java/org/cryptomator/ui/dialogs/Dialogs.java +++ b/src/main/java/org/cryptomator/ui/dialogs/Dialogs.java @@ -58,19 +58,19 @@ public class Dialogs { .setOkButtonKey(BUTTON_KEY_CLOSE); } - public SimpleDialog.Builder prepareRecoveryVaultAdded(Stage window) { + public SimpleDialog.Builder prepareRecoveryVaultAdded(Stage window, String displayName) { return createDialogBuilder().setOwner(window) // .setTitleKey("recoveryKey.recoverExisting.title") // .setMessageKey("recoveryKey.recoverExisting.message") // - .setDescriptionKey("recoveryKey.recoverExisting.description") // - .setIcon(FontAwesome5Icon.EXCLAMATION)// + .setDescriptionKey("recoveryKey.recoverExisting.description", displayName) // + .setIcon(FontAwesome5Icon.CHECK)// .setOkButtonKey(BUTTON_KEY_CLOSE); } - public SimpleDialog.Builder prepareRecoveryVaultAlreadyExists(Stage window) { + public SimpleDialog.Builder prepareRecoveryVaultAlreadyExists(Stage window, String displayName) { return createDialogBuilder().setOwner(window) // .setTitleKey("recoveryKey.alreadyExists.title") // .setMessageKey("recoveryKey.alreadyExists.message") // - .setDescriptionKey("recoveryKey.alreadyExists.description") // + .setDescriptionKey("recoveryKey.alreadyExists.description", displayName) // .setIcon(FontAwesome5Icon.EXCLAMATION)// .setOkButtonKey(BUTTON_KEY_CLOSE); } diff --git a/src/main/java/org/cryptomator/ui/dialogs/SimpleDialog.java b/src/main/java/org/cryptomator/ui/dialogs/SimpleDialog.java index 08f77849e..5efe4abfe 100644 --- a/src/main/java/org/cryptomator/ui/dialogs/SimpleDialog.java +++ b/src/main/java/org/cryptomator/ui/dialogs/SimpleDialog.java @@ -30,7 +30,7 @@ public class SimpleDialog { FxmlLoaderFactory loaderFactory = FxmlLoaderFactory.forController( // new SimpleDialogController(resolveText(builder.messageKey, null), // - resolveText(builder.descriptionKey, null), // + resolveText(builder.descriptionKey, builder.descriptionArgs), // builder.icon, // resolveText(builder.okButtonKey, null), // builder.cancelButtonKey != null ? resolveText(builder.cancelButtonKey, null) : null, // @@ -66,6 +66,7 @@ public class SimpleDialog { private String[] titleArgs; private String messageKey; private String descriptionKey; + private String[] descriptionArgs; private String okButtonKey; private String cancelButtonKey; private FontAwesome5Icon icon; @@ -93,8 +94,9 @@ public class SimpleDialog { return this; } - public Builder setDescriptionKey(String descriptionKey) { + public Builder setDescriptionKey(String descriptionKey, String... args) { this.descriptionKey = descriptionKey; + this.descriptionArgs = args; return this; } diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java index 2c95da688..e836eff9c 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java @@ -1,10 +1,14 @@ package org.cryptomator.ui.mainwindow; import org.apache.commons.lang3.SystemUtils; +import org.cryptomator.common.recovery.RecoveryActionType; import org.cryptomator.common.settings.Settings; +import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.common.vaults.Vault; import org.cryptomator.common.vaults.VaultComponent; +import org.cryptomator.common.vaults.VaultConfigCache; import org.cryptomator.common.vaults.VaultListManager; +import org.cryptomator.common.vaults.VaultState; import org.cryptomator.cryptofs.CryptoFileSystemProvider; import org.cryptomator.cryptofs.DirStructure; import org.cryptomator.integrations.mount.MountService; @@ -25,6 +29,7 @@ import javafx.beans.binding.BooleanBinding; import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; @@ -40,6 +45,7 @@ import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseEvent; import javafx.scene.input.TransferMode; import javafx.scene.layout.StackPane; +import javafx.stage.DirectoryChooser; import javafx.stage.Stage; import java.io.File; import java.io.IOException; @@ -230,7 +236,71 @@ public class VaultListController implements FxController { @FXML public void didClickRecoverExistingVault() { - addVaultWizard.build().showRecoverExistingVaultWizard(mainWindow, dialogs, vaultComponentFactory,mountServices,vaultListManager,recoveryKeyWindow); + DirectoryChooser directoryChooser = new DirectoryChooser(); + + while (true) { + File selectedDirectory = directoryChooser.showDialog(mainWindow); + if (selectedDirectory == null) { + return; + } + + boolean hasSubfolderD = new File(selectedDirectory, "d").isDirectory(); + if (!hasSubfolderD) { + dialogs.prepareNoDDirectorySelectedDialog(mainWindow).build().showAndWait(); + continue; + } + + Vault preparedVault = prepareVault(selectedDirectory, vaultComponentFactory, mountServices); + + if (vaultListManager.get(preparedVault.getPath()).isPresent()) { + dialogs.prepareRecoveryVaultAlreadyExists(mainWindow, vaultListManager.get(preparedVault.getPath()).get().getDisplayName()) // + .setOkAction(Stage::close) // + .build().showAndWait(); + break; + } + + VaultListManager.redetermineVaultState(preparedVault); + VaultState.Value state = preparedVault.getState(); + + switch (state) { + case VAULT_CONFIG_MISSING -> + recoveryKeyWindow.create(preparedVault, mainWindow, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_VAULT_CONFIG)).showOnboardingDialogWindow(); + case ALL_MISSING -> + recoveryKeyWindow.create(preparedVault, mainWindow, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_ALL)).showOnboardingDialogWindow(); + case LOCKED -> { + vaultListManager.addVault(preparedVault); + dialogs.prepareRecoveryVaultAdded(mainWindow, preparedVault.getDisplayName()).setOkAction(Stage::close).build().showAndWait(); + } + } + break; + } + } + + public static Vault prepareVault(File selectedDirectory, VaultComponent.Factory vaultComponentFactory, List mountServices) { + Path selectedPath = selectedDirectory.toPath(); + VaultSettings vaultSettings = VaultSettings.withRandomId(); + vaultSettings.path.set(selectedPath); + if (selectedPath.getFileName() != null) { + vaultSettings.displayName.set(selectedPath.getFileName().toString()); + } else { + vaultSettings.displayName.set("defaultVaultName"); + } + + var wrapper = new VaultConfigCache(vaultSettings); + Vault vault = vaultComponentFactory.create(vaultSettings, wrapper, LOCKED, null).vault(); + try { + VaultListManager.determineVaultState(vault.getPath(), vaultSettings); + } catch (IOException e) { + LOG.warn("Failed to determine vault state for {}", vaultSettings.path.get(), e); + } + + //due to https://github.com/cryptomator/cryptomator/issues/2880#issuecomment-1680313498 + var nameOfWinfspLocalMounter = "org.cryptomator.frontend.fuse.mount.WinFspMountProvider"; + if (SystemUtils.IS_OS_WINDOWS && vaultSettings.path.get().toString().contains("Dropbox") && mountServices.stream().anyMatch(s -> s.getClass().getName().equals(nameOfWinfspLocalMounter))) { + vaultSettings.mountService.setValue(nameOfWinfspLocalMounter); + } + + return vault; } private void pressedShortcutToRemoveVault() { diff --git a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyCreationController.java b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyCreationController.java index 56b0aab5e..b4c1db68a 100644 --- a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyCreationController.java +++ b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyCreationController.java @@ -100,9 +100,9 @@ public class RecoveryKeyCreationController implements FxController { @FXML public void initialize() { - if (recoverType.get().equals(RecoveryActionType.SHOW_KEY)) { + if (recoverType.get() == RecoveryActionType.SHOW_KEY) { window.setTitle(resourceBundle.getString("recoveryKey.display.title")); - } else if (recoverType.get().equals(RecoveryActionType.RESTORE_VAULT_CONFIG)) { + } else if (recoverType.get() == RecoveryActionType.RESTORE_VAULT_CONFIG) { window.setTitle(resourceBundle.getString("recoveryKey.recoverVaultConfig.title")); descriptionLabel.formatProperty().set(resourceBundle.getString("recoveryKey.recover.description")); cancelButton.setOnAction((_) -> back()); @@ -156,7 +156,7 @@ public class RecoveryKeyCreationController implements FxController { recoveryDirectory.moveRecoveredFile(VAULTCONFIG_FILENAME); - if (!vaultListManager.containsVault(vault.getPath())) { + if (!vaultListManager.isAlreadyAdded(vault.getPath())) { vaultListManager.add(vault.getPath()); } window.close(); diff --git a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyExpertSettingsController.java b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyExpertSettingsController.java index 1555eac68..f84529b1e 100644 --- a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyExpertSettingsController.java +++ b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyExpertSettingsController.java @@ -21,8 +21,6 @@ import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; import org.cryptomator.ui.controls.NumericTextField; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @RecoveryKeyScoped public class RecoveryKeyExpertSettingsController implements FxController { @@ -42,10 +40,10 @@ public class RecoveryKeyExpertSettingsController implements FxController { private final Lazy recoverScene; private final BooleanBinding validShorteningThreshold; - @FXML public CheckBox expertSettingsCheckBox; - @FXML public NumericTextField shorteningThresholdTextField; - - private static final Logger LOG = LoggerFactory.getLogger(RecoveryKeyExpertSettingsController.class); + @FXML + public CheckBox expertSettingsCheckBox; + @FXML + public NumericTextField shorteningThresholdTextField; @Inject public RecoveryKeyExpertSettingsController(@RecoveryKeyWindow Stage window, // @@ -105,19 +103,21 @@ public class RecoveryKeyExpertSettingsController implements FxController { @FXML public void back() { - if(recoverType.get().equals(RecoveryActionType.RESTORE_ALL) && vault.getState().equals(VaultState.Value.VAULT_CONFIG_MISSING)) + if (recoverType.get() == RecoveryActionType.RESTORE_ALL && vault.getState() == VaultState.Value.VAULT_CONFIG_MISSING) { window.setScene(recoverScene.get()); - else if(recoverType.get().equals(RecoveryActionType.RESTORE_ALL) && vault.getState().equals(VaultState.Value.ALL_MISSING)) + } else if (recoverType.get() == RecoveryActionType.RESTORE_ALL && vault.getState() == VaultState.Value.ALL_MISSING) { window.setScene(recoverScene.get()); - else if(recoverType.get().equals(RecoveryActionType.RESTORE_VAULT_CONFIG)) + } else if (recoverType.get() == RecoveryActionType.RESTORE_VAULT_CONFIG) { window.setScene(onBoardingScene.get()); + } } @FXML public void next() { - if(recoverType.get().equals(RecoveryActionType.RESTORE_VAULT_CONFIG)) + if (recoverType.get() == RecoveryActionType.RESTORE_VAULT_CONFIG) { window.setScene(createScene.get()); - else + } else { window.setScene(resetPasswordScene.get()); + } } } diff --git a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyResetPasswordController.java b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyResetPasswordController.java index 2733e4a7a..460372ca1 100644 --- a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyResetPasswordController.java +++ b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyResetPasswordController.java @@ -143,7 +143,7 @@ public class RecoveryKeyResetPasswordController implements FxController { recoveryDirectory.moveRecoveredFile(MASTERKEY_FILENAME); recoveryDirectory.moveRecoveredFile(VAULTCONFIG_FILENAME); - if (!vaultListManager.containsVault(vault.getPath())) { + if (!vaultListManager.isAlreadyAdded(vault.getPath())) { vaultListManager.add(vault.getPath()); } window.close(); diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index 9abc37c27..008a6c945 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -536,13 +536,12 @@ recoveryKey.recover.resetMasterkeyFileSuccess.message=Masterkey file reset succe ### Recover Kram recoveryKey.recoverExisting.title=Vault Added -recoveryKey.recoverExisting.message=Recovery Vault added -recoveryKey.recoverExisting.description=Your Vault added successfully. +recoveryKey.recoverExisting.message=The vault was added successfully +recoveryKey.recoverExisting.description=Your vault "%s" has been added to your vault list. No recovery process was started. recoveryKey.alreadyExists.title=Vault Already Exists -recoveryKey.alreadyExists.message=Vault already exists in VaultList. -recoveryKey.alreadyExists.description=Nothing happend. - +recoveryKey.alreadyExists.message=This vault has already been added +recoveryKey.alreadyExists.description=Your vault "%s" is already present in your vault list and was therefore not added again. recoveryKey.noDDirDetected.title=Invalid Selection recoveryKey.noDDirDetected.description=The selected folder must contain a subfolder named "d".