mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-08-17 04:36:02 +00:00
recover button now in VaultListController
This commit is contained in:
@@ -7,13 +7,28 @@ 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 {
|
||||
@@ -23,9 +38,13 @@ public interface AddVaultWizardComponent {
|
||||
|
||||
@FxmlScene(FxmlFile.ADDVAULT_NEW_NAME)
|
||||
Lazy<Scene> sceneNew();
|
||||
|
||||
@FxmlScene(FxmlFile.ADDVAULT_EXISTING)
|
||||
Lazy<Scene> sceneExisting();
|
||||
|
||||
@FxmlScene(FxmlFile.ADDVAULT_SUCCESS)
|
||||
Lazy<Scene> sceneSuccess();
|
||||
|
||||
default void showAddNewVaultWizard(ResourceBundle resourceBundle) {
|
||||
Stage stage = window();
|
||||
stage.setScene(sceneNew().get());
|
||||
@@ -42,6 +61,50 @@ public interface AddVaultWizardComponent {
|
||||
stage.show();
|
||||
}
|
||||
|
||||
default void showRecoverExistingVaultWizard(Window mainWindow, //
|
||||
Dialogs dialogs, //
|
||||
VaultComponent.Factory vaultComponentFactory, //
|
||||
List<MountService> 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 {
|
||||
|
||||
|
||||
+18
-73
@@ -1,16 +1,30 @@
|
||||
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;
|
||||
import org.cryptomator.ui.common.FxmlScene;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationStyle;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||
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.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import java.io.File;
|
||||
@@ -23,27 +37,6 @@ import java.util.ResourceBundle;
|
||||
import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.LOCKED;
|
||||
|
||||
import dagger.Lazy;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
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.integrations.mount.MountService;
|
||||
import org.cryptomator.integrations.uiappearance.Theme;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlScene;
|
||||
import org.cryptomator.ui.dialogs.Dialogs;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationStyle;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@AddVaultWizardScoped
|
||||
public class ChooseExistingVaultController implements FxController {
|
||||
|
||||
@@ -57,13 +50,6 @@ public class ChooseExistingVaultController implements FxController {
|
||||
private final VaultListManager vaultListManager;
|
||||
private final ResourceBundle resourceBundle;
|
||||
private final ObservableValue<Image> screenshot;
|
||||
private final Dialogs dialogs;
|
||||
private final VaultComponent.Factory vaultComponentFactory;
|
||||
private final RecoveryKeyComponent.Factory recoveryKeyWindow;
|
||||
private final List<MountService> mountServices;
|
||||
|
||||
@FXML
|
||||
private CheckBox restoreCheckBox;
|
||||
|
||||
private final BooleanProperty restoreButtonVisible = new SimpleBooleanProperty(false);
|
||||
|
||||
@@ -76,11 +62,7 @@ public class ChooseExistingVaultController implements FxController {
|
||||
@AddVaultWizardWindow ObjectProperty<Vault> vault, //
|
||||
VaultListManager vaultListManager, //
|
||||
ResourceBundle resourceBundle, //
|
||||
FxApplicationStyle applicationStyle, //
|
||||
RecoveryKeyComponent.Factory recoveryKeyWindow, //
|
||||
VaultComponent.Factory vaultComponentFactory, //
|
||||
List<MountService> mountServices, //
|
||||
Dialogs dialogs) {
|
||||
FxApplicationStyle applicationStyle) {
|
||||
this.window = window;
|
||||
this.successScene = successScene;
|
||||
this.appWindows = appWindows;
|
||||
@@ -89,14 +71,6 @@ public class ChooseExistingVaultController implements FxController {
|
||||
this.vaultListManager = vaultListManager;
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.screenshot = applicationStyle.appliedThemeProperty().map(this::selectScreenshot);
|
||||
this.recoveryKeyWindow = recoveryKeyWindow;
|
||||
this.vaultComponentFactory = vaultComponentFactory;
|
||||
this.mountServices = mountServices;
|
||||
this.dialogs = dialogs;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
restoreButtonVisible.bind(restoreCheckBox.selectedProperty());
|
||||
}
|
||||
|
||||
private Image selectScreenshot(Theme theme) {
|
||||
@@ -131,35 +105,6 @@ public class ChooseExistingVaultController implements FxController {
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void restoreVaultConfigWithRecoveryKey() {
|
||||
DirectoryChooser directoryChooser = new DirectoryChooser();
|
||||
|
||||
File selectedDirectory = directoryChooser.showDialog(window);
|
||||
if (selectedDirectory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean hasSubfolderD = new File(selectedDirectory, "d").isDirectory();
|
||||
if (!hasSubfolderD) {
|
||||
dialogs.prepareNoDDirectorySelectedDialog(window).build().showAndWait();
|
||||
return;
|
||||
}
|
||||
|
||||
Vault preparedVault = prepareVault(selectedDirectory, vaultComponentFactory, mountServices);
|
||||
VaultListManager.redetermineVaultState(preparedVault);
|
||||
VaultState.Value state = preparedVault.getState();
|
||||
switch (state) {
|
||||
case VAULT_CONFIG_MISSING -> recoveryKeyWindow.create(preparedVault, window, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_VAULT_CONFIG)).showOnboardingDialogWindow();
|
||||
case ALL_MISSING -> recoveryKeyWindow.create(preparedVault, window, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_ALL)).showOnboardingDialogWindow();
|
||||
default -> {
|
||||
vaultListManager.addVault(preparedVault);
|
||||
vault.set(preparedVault);
|
||||
window.setScene(successScene.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Vault prepareVault(File selectedDirectory, VaultComponent.Factory vaultComponentFactory, List<MountService> mountServices) {
|
||||
Path selectedPath = selectedDirectory.toPath();
|
||||
VaultSettings vaultSettings = VaultSettings.withRandomId();
|
||||
|
||||
@@ -6,6 +6,7 @@ package org.cryptomator.ui.controls;
|
||||
public enum FontAwesome5Icon {
|
||||
ANCHOR("\uF13D"), //
|
||||
ARROW_UP("\uF062"), //
|
||||
ARROWS_ROTATE("\uF021"),
|
||||
BAN("\uF05E"), //
|
||||
BELL("\uF0F3"), //
|
||||
BUG("\uF188"), //
|
||||
|
||||
@@ -58,6 +58,23 @@ public class Dialogs {
|
||||
.setOkButtonKey(BUTTON_KEY_CLOSE);
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareRecoveryVaultAdded(Stage window) {
|
||||
return createDialogBuilder().setOwner(window) //
|
||||
.setTitleKey("recoveryKey.recoverExisting.title") //
|
||||
.setMessageKey("recoveryKey.recoverExisting.message") //
|
||||
.setDescriptionKey("recoveryKey.recoverExisting.description") //
|
||||
.setIcon(FontAwesome5Icon.EXCLAMATION)//
|
||||
.setOkButtonKey(BUTTON_KEY_CLOSE);
|
||||
}
|
||||
public SimpleDialog.Builder prepareRecoveryVaultAlreadyExists(Stage window) {
|
||||
return createDialogBuilder().setOwner(window) //
|
||||
.setTitleKey("recoveryKey.alreadyExists.title") //
|
||||
.setMessageKey("recoveryKey.alreadyExists.message") //
|
||||
.setDescriptionKey("recoveryKey.alreadyExists.description") //
|
||||
.setIcon(FontAwesome5Icon.EXCLAMATION)//
|
||||
.setOkButtonKey(BUTTON_KEY_CLOSE);
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareRecoverPasswordSuccess(Stage window, Stage owner, ResourceBundle resourceBundle) {
|
||||
return createDialogBuilder()
|
||||
.setOwner(window) //
|
||||
@@ -67,7 +84,8 @@ public class Dialogs {
|
||||
.setIcon(FontAwesome5Icon.CHECK)
|
||||
.setOkAction(stage -> {
|
||||
stage.close();
|
||||
if (owner.getTitle().equals(resourceBundle.getString("addvaultwizard.existing.title"))) {
|
||||
String ownerTitle = owner.getTitle();
|
||||
if (ownerTitle != null && ownerTitle.equals(resourceBundle.getString("addvaultwizard.existing.title"))) {
|
||||
owner.close();
|
||||
}
|
||||
})
|
||||
|
||||
@@ -3,9 +3,11 @@ package org.cryptomator.ui.mainwindow;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultComponent;
|
||||
import org.cryptomator.common.vaults.VaultListManager;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||
import org.cryptomator.cryptofs.DirStructure;
|
||||
import org.cryptomator.integrations.mount.MountService;
|
||||
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.VaultService;
|
||||
@@ -13,6 +15,7 @@ import org.cryptomator.ui.dialogs.Dialogs;
|
||||
import org.cryptomator.ui.fxapp.FxFSEventList;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||
import org.cryptomator.ui.preferences.SelectedPreferencesTab;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -42,6 +45,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
@@ -75,6 +79,10 @@ public class VaultListController implements FxController {
|
||||
private final ObservableValue<Double> cellSize;
|
||||
private final Dialogs dialogs;
|
||||
|
||||
private final VaultComponent.Factory vaultComponentFactory;
|
||||
private final RecoveryKeyComponent.Factory recoveryKeyWindow;
|
||||
private final List<MountService> mountServices;
|
||||
|
||||
public ListView<Vault> vaultList;
|
||||
public StackPane root;
|
||||
@FXML
|
||||
@@ -94,6 +102,9 @@ public class VaultListController implements FxController {
|
||||
FxApplicationWindows appWindows, //
|
||||
Settings settings, //
|
||||
Dialogs dialogs, //
|
||||
RecoveryKeyComponent.Factory recoveryKeyWindow, //
|
||||
VaultComponent.Factory vaultComponentFactory, //
|
||||
List<MountService> mountServices, //
|
||||
FxFSEventList fxFSEventList) {
|
||||
this.mainWindow = mainWindow;
|
||||
this.vaults = vaults;
|
||||
@@ -105,6 +116,9 @@ public class VaultListController implements FxController {
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.appWindows = appWindows;
|
||||
this.dialogs = dialogs;
|
||||
this.recoveryKeyWindow = recoveryKeyWindow;
|
||||
this.vaultComponentFactory = vaultComponentFactory;
|
||||
this.mountServices = mountServices;
|
||||
|
||||
this.emptyVaultList = Bindings.isEmpty(vaults);
|
||||
this.unreadEvents = fxFSEventList.unreadEventsProperty();
|
||||
@@ -214,6 +228,11 @@ public class VaultListController implements FxController {
|
||||
addVaultWizard.build().showAddExistingVaultWizard(resourceBundle);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void didClickRecoverExistingVault() {
|
||||
addVaultWizard.build().showRecoverExistingVaultWizard(mainWindow, dialogs, vaultComponentFactory,mountServices,vaultListManager,recoveryKeyWindow);
|
||||
}
|
||||
|
||||
private void pressedShortcutToRemoveVault() {
|
||||
final var vault = selectedVault.get();
|
||||
if (vault != null && EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION).contains(vault.getState())) {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ButtonBar?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
@@ -12,25 +11,21 @@
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.addvaultwizard.ChooseExistingVaultController"
|
||||
prefWidth="450"
|
||||
prefHeight="480">
|
||||
prefHeight="450"
|
||||
spacing="24"
|
||||
alignment="CENTER">
|
||||
<padding>
|
||||
<Insets topRightBottomLeft="24"/>
|
||||
</padding>
|
||||
<children>
|
||||
<ImageView VBox.vgrow="ALWAYS" fitWidth="400" preserveRatio="true" smooth="true" image="${controller.screenshot}"/>
|
||||
|
||||
<Label text="%addvaultwizard.existing.instruction" wrapText="true">
|
||||
<padding>
|
||||
<Insets bottom="6" top="6"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="%addvaultwizard.existing.instruction" wrapText="true" labelFor="$finishButton"/>
|
||||
|
||||
<CheckBox fx:id="restoreCheckBox" text="%addvaultwizard.existing.instruction.restore" wrapText="true"/>
|
||||
<Region VBox.vgrow="ALWAYS"/>
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+CX">
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+X">
|
||||
<buttons>
|
||||
<Button text="%addvaultwizard.existing.restore" ButtonBar.buttonData="NEXT_FORWARD" onAction="#restoreVaultConfigWithRecoveryKey" visible="${controller.restoreButtonVisible}"/>
|
||||
<Button text="%addvaultwizard.existing.chooseBtn" ButtonBar.buttonData="NEXT_FORWARD" onAction="#chooseFileAndNext" defaultButton="true"/>
|
||||
<Button fx:id="finishButton" text="%addvaultwizard.existing.chooseBtn" ButtonBar.buttonData="NEXT_FORWARD" onAction="#chooseFileAndNext" defaultButton="true"/>
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
</children>
|
||||
|
||||
@@ -80,6 +80,11 @@
|
||||
<FontAwesome5IconView glyph="FOLDER_OPEN" textAlignment="CENTER" wrappingWidth="14"/>
|
||||
</graphic>
|
||||
</MenuItem>
|
||||
<MenuItem styleClass="dropdown-button-context-menu-item" text="%main.vaultlist.addVaultBtn.menuItemRecover" onAction="#didClickRecoverExistingVault">
|
||||
<graphic>
|
||||
<FontAwesome5IconView glyph="ARROWS_ROTATE" textAlignment="CENTER" wrappingWidth="14"/>
|
||||
</graphic>
|
||||
</MenuItem>
|
||||
</items>
|
||||
</ContextMenu>
|
||||
</fx:define>
|
||||
|
||||
@@ -96,7 +96,7 @@ addvault.new.readme.accessLocation.3=Any files added to this volume will be encr
|
||||
addvault.new.readme.accessLocation.4=Feel free to remove this file.
|
||||
## Existing
|
||||
addvaultwizard.existing.title=Add Existing Vault
|
||||
addvaultwizard.existing.instruction=Choose the "vault.cryptomator" file of your existing vault. If only a file named "masterkey.cryptomator" exists, select that instead. If your vault.cryptomator lost you can recover it with your RecoveryKey.
|
||||
addvaultwizard.existing.instruction=Choose the "vault.cryptomator" file of your existing vault. If only a file named "masterkey.cryptomator" exists, select that instead.
|
||||
addvaultwizard.existing.instruction.restore=If your vault.cryptomator file went missing you can enable restore mode here.
|
||||
addvaultwizard.existing.restore=Restore…
|
||||
addvaultwizard.existing.chooseBtn=Choose…
|
||||
@@ -404,6 +404,7 @@ main.vaultlist.contextMenu.vaultoptions=Show Vault Options
|
||||
main.vaultlist.contextMenu.reveal=Reveal Drive
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Create New Vault...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Open Existing Vault...
|
||||
main.vaultlist.addVaultBtn.menuItemRecover=Recover Existing Vault...
|
||||
main.vaultlist.showEventsButton.tooltip=Open event view
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Update is available.
|
||||
@@ -534,6 +535,14 @@ recoveryKey.recover.resetVaultConfigSuccess.message=Vault config reset successfu
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.message=Masterkey file reset successful
|
||||
|
||||
### Recover Kram
|
||||
recoveryKey.recoverExisting.title=Vault Added
|
||||
recoveryKey.recoverExisting.message=Recovery Vault added
|
||||
recoveryKey.recoverExisting.description=Your Vault added successfully.
|
||||
|
||||
recoveryKey.alreadyExists.title=Vault Already Exists
|
||||
recoveryKey.alreadyExists.message=Vault already exists in VaultList.
|
||||
recoveryKey.alreadyExists.description=Nothing happend.
|
||||
|
||||
|
||||
recoveryKey.noDDirDetected.title=Invalid Selection
|
||||
recoveryKey.noDDirDetected.description=The selected folder must contain a subfolder named "d".
|
||||
|
||||
Reference in New Issue
Block a user