diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultModule.java b/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultModule.java index 02327aaf4..4a9dba7ad 100644 --- a/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultModule.java +++ b/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultModule.java @@ -5,21 +5,23 @@ import dagger.Module; import dagger.Provides; import dagger.multibindings.IntoMap; import org.cryptomator.common.vaults.Vault; +import org.cryptomator.ui.changepassword.NewPasswordController; +import org.cryptomator.ui.changepassword.PasswordStrengthUtil; import org.cryptomator.ui.common.DefaultSceneFactory; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxControllerKey; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlLoaderFactory; import org.cryptomator.ui.common.FxmlScene; -import org.cryptomator.ui.changepassword.NewPasswordController; -import org.cryptomator.ui.changepassword.PasswordStrengthUtil; import org.cryptomator.ui.common.StageFactory; import org.cryptomator.ui.fxapp.PrimaryStage; import org.cryptomator.ui.recoverykey.RecoveryKeyDisplayController; import javax.inject.Named; import javax.inject.Provider; +import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; @@ -65,6 +67,13 @@ public abstract class AddVaultModule { return new SimpleStringProperty(""); } + @Provides + @Named("shorteningThreshold") + @AddVaultWizardScoped + static IntegerProperty provideShorteningThreshold() { + return new SimpleIntegerProperty(CreateNewVaultExpertSettingsController.MAX_SHORTENING_THRESHOLD); + } + @Provides @AddVaultWizardWindow @AddVaultWizardScoped @@ -130,6 +139,13 @@ public abstract class AddVaultModule { return fxmlLoaders.createScene(FxmlFile.ADDVAULT_SUCCESS); } + @Provides + @FxmlScene(FxmlFile.ADDVAULT_NEW_EXPERT_SETTINGS) + @AddVaultWizardScoped + static Scene provideCreateNewVaultExpertSettingsScene(@AddVaultWizardWindow FxmlLoaderFactory fxmlLoaders) { + return fxmlLoaders.createScene(FxmlFile.ADDVAULT_NEW_EXPERT_SETTINGS); + } + // ------------------ @Binds @@ -181,4 +197,9 @@ public abstract class AddVaultModule { @FxControllerKey(AddVaultSuccessController.class) abstract FxController bindAddVaultSuccessController(AddVaultSuccessController controller); + @Binds + @IntoMap + @FxControllerKey(CreateNewVaultExpertSettingsController.class) + abstract FxController bindCreateNewVaultExpertSettingsController(CreateNewVaultExpertSettingsController controller); + } diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultExpertSettingsController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultExpertSettingsController.java new file mode 100644 index 000000000..dbf0a0c6e --- /dev/null +++ b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultExpertSettingsController.java @@ -0,0 +1,118 @@ +package org.cryptomator.ui.addvaultwizard; + +import dagger.Lazy; +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 javax.inject.Inject; +import javax.inject.Named; +import javafx.application.Application; +import javafx.beans.binding.Bindings; +import javafx.beans.binding.BooleanBinding; +import javafx.beans.property.IntegerProperty; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.StringProperty; +import javafx.fxml.FXML; +import javafx.scene.Scene; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.stage.Stage; +import java.nio.file.Path; + +@AddVaultWizardScoped +public class CreateNewVaultExpertSettingsController implements FxController { + + public static final int MAX_SHORTENING_THRESHOLD = 220; + public static final int MIN_SHORTENING_THRESHOLD = 36; + private static final String DOCS_NAME_SHORTENING_URL = "https://docs.cryptomator.org/en/1.7/security/architecture/#name-shortening"; + + private final Stage window; + private final Lazy application; + private final Lazy chooseLocationScene; + private final Lazy choosePasswordScene; + private final StringProperty vaultNameProperty; + private final ObjectProperty vaultPathProperty; + private final IntegerProperty shorteningThreshold; + + private final BooleanBinding validShorteningThreshold; + + //FXML + public Label vaultNameLabel; + public Label vaultPathLabel; + public CheckBox expertSettingsCheckBox; + public NumericTextField shorteningThresholdTextField; + + @Inject + CreateNewVaultExpertSettingsController(@AddVaultWizardWindow Stage window, // + Lazy application, // + @FxmlScene(FxmlFile.ADDVAULT_NEW_LOCATION) Lazy chooseLocationScene, // + @FxmlScene(FxmlFile.ADDVAULT_NEW_PASSWORD) Lazy choosePasswordScene, // + @Named("vaultName") StringProperty vaultName, // + ObjectProperty vaultPath, // + @Named("shorteningThreshold") IntegerProperty shorteningThreshold) { + this.window = window; + this.application = application; + this.chooseLocationScene = chooseLocationScene; + this.choosePasswordScene = choosePasswordScene; + this.vaultNameProperty = vaultName; + this.vaultPathProperty = vaultPath; + this.shorteningThreshold = shorteningThreshold; + this.validShorteningThreshold = Bindings.createBooleanBinding(this::isValidShorteningThreshold, shorteningThreshold); + } + + @FXML + public void initialize() { + vaultNameLabel.textProperty().bind(vaultNameProperty); + vaultPathLabel.textProperty().bind(vaultPathProperty.asString()); + shorteningThresholdTextField.setPromptText(MIN_SHORTENING_THRESHOLD + "-" + MAX_SHORTENING_THRESHOLD); + shorteningThresholdTextField.setText(Integer.toString(MAX_SHORTENING_THRESHOLD)); + shorteningThresholdTextField.textProperty().addListener((observable, oldValue, newValue) -> { + try { + int intValue = Integer.parseInt(newValue); + shorteningThreshold.set(intValue); + } catch (NumberFormatException e) { + shorteningThreshold.set(0); //the value is set to 0 to ensure that an invalid value assignment is detected during a NumberFormatException + } + }); + } + + @FXML + public void toggleUseExpertSettings() { + if (!expertSettingsCheckBox.isSelected()) { + shorteningThresholdTextField.setText(Integer.toString(MAX_SHORTENING_THRESHOLD)); + } + } + + @FXML + public void back() { + window.setScene(chooseLocationScene.get()); + } + + @FXML + public void next() { + window.setScene(choosePasswordScene.get()); + } + + public BooleanBinding validShorteningThresholdProperty() { + return validShorteningThreshold; + } + + public boolean isValidShorteningThreshold() { + var value = shorteningThreshold.get(); + return value >= MIN_SHORTENING_THRESHOLD && value <= MAX_SHORTENING_THRESHOLD; + } + + public void openDocs() { + application.get().getHostServices().showDocument(DOCS_NAME_SHORTENING_URL); + } + + public Path getVaultPath() { + return vaultPathProperty.get(); + } + + public String getVaultName() { + return vaultNameProperty.get(); + } +} \ No newline at end of file diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java index 25febe5e1..3178f0ba4 100644 --- a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java +++ b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java @@ -48,7 +48,7 @@ public class CreateNewVaultLocationController implements FxController { private final Stage window; private final Lazy chooseNameScene; - private final Lazy choosePasswordScene; + private final Lazy chooseExpertSettingsScene; private final List locationPresetBtns; private final ObjectProperty vaultPath; private final StringProperty vaultName; @@ -68,10 +68,15 @@ public class CreateNewVaultLocationController implements FxController { public FontAwesome5IconView badLocation; @Inject - CreateNewVaultLocationController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME) Lazy chooseNameScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_PASSWORD) Lazy choosePasswordScene, ObjectProperty vaultPath, @Named("vaultName") StringProperty vaultName, ResourceBundle resourceBundle) { + CreateNewVaultLocationController(@AddVaultWizardWindow Stage window, // + @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME) Lazy chooseNameScene, // + @FxmlScene(FxmlFile.ADDVAULT_NEW_EXPERT_SETTINGS) Lazy chooseExpertSettingsScene, // + ObjectProperty vaultPath, // + @Named("vaultName") StringProperty vaultName, // + ResourceBundle resourceBundle) { this.window = window; this.chooseNameScene = chooseNameScene; - this.choosePasswordScene = choosePasswordScene; + this.chooseExpertSettingsScene = chooseExpertSettingsScene; this.vaultPath = vaultPath; this.vaultName = vaultName; this.resourceBundle = resourceBundle; @@ -151,7 +156,7 @@ public class CreateNewVaultLocationController implements FxController { @FXML public void next() { if (validVaultPath.getValue()) { - window.setScene(choosePasswordScene.get()); + window.setScene(chooseExpertSettingsScene.get()); } } diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultPasswordController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultPasswordController.java index 81c6ce2da..28a73794a 100644 --- a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultPasswordController.java +++ b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultPasswordController.java @@ -10,13 +10,12 @@ import org.cryptomator.cryptolib.api.CryptorProvider; import org.cryptomator.cryptolib.api.Masterkey; import org.cryptomator.cryptolib.api.MasterkeyLoader; import org.cryptomator.cryptolib.common.MasterkeyFileAccess; +import org.cryptomator.ui.changepassword.NewPasswordController; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; -import org.cryptomator.ui.changepassword.NewPasswordController; import org.cryptomator.ui.common.Tasks; import org.cryptomator.ui.fxapp.FxApplicationWindows; -import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy; import org.cryptomator.ui.recoverykey.RecoveryKeyFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,6 +25,7 @@ import javax.inject.Named; import javafx.beans.binding.Bindings; import javafx.beans.binding.ObjectBinding; import javafx.beans.property.BooleanProperty; +import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.StringProperty; @@ -37,7 +37,6 @@ import javafx.scene.control.ToggleGroup; import javafx.stage.Stage; import java.io.IOException; import java.io.UncheckedIOException; -import java.net.URI; import java.nio.channels.WritableByteChannel; import java.nio.file.FileSystem; import java.nio.file.Files; @@ -57,7 +56,7 @@ public class CreateNewVaultPasswordController implements FxController { private static final Logger LOG = LoggerFactory.getLogger(CreateNewVaultPasswordController.class); private final Stage window; - private final Lazy chooseLocationScene; + private final Lazy chooseExpertSettingsScene; private final Lazy recoveryKeyScene; private final Lazy successScene; private final FxApplicationWindows appWindows; @@ -75,6 +74,7 @@ public class CreateNewVaultPasswordController implements FxController { private final BooleanProperty processing; private final BooleanProperty readyToCreateVault; private final ObjectBinding createVaultButtonState; + private final IntegerProperty shorteningThreshold; /* FXML */ public ToggleGroup recoveryKeyChoice; @@ -83,9 +83,25 @@ public class CreateNewVaultPasswordController implements FxController { public NewPasswordController newPasswordSceneController; @Inject - CreateNewVaultPasswordController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_LOCATION) Lazy chooseLocationScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_RECOVERYKEY) Lazy recoveryKeyScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, FxApplicationWindows appWindows, ExecutorService executor, RecoveryKeyFactory recoveryKeyFactory, @Named("vaultName") StringProperty vaultName, ObjectProperty vaultPath, @AddVaultWizardWindow ObjectProperty vault, @Named("recoveryKey") StringProperty recoveryKey, VaultListManager vaultListManager, ResourceBundle resourceBundle, ReadmeGenerator readmeGenerator, SecureRandom csprng, MasterkeyFileAccess masterkeyFileAccess) { + CreateNewVaultPasswordController(@AddVaultWizardWindow Stage window, // + @FxmlScene(FxmlFile.ADDVAULT_NEW_EXPERT_SETTINGS) Lazy chooseExpertSettingsScene, // + @FxmlScene(FxmlFile.ADDVAULT_NEW_RECOVERYKEY) Lazy recoveryKeyScene, // + @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, // + FxApplicationWindows appWindows, // + ExecutorService executor, // + RecoveryKeyFactory recoveryKeyFactory, // + @Named("vaultName") StringProperty vaultName, // + ObjectProperty vaultPath, // + @AddVaultWizardWindow ObjectProperty vault, // + @Named("recoveryKey") StringProperty recoveryKey, // + VaultListManager vaultListManager, // + ResourceBundle resourceBundle, // + @Named("shorteningThreshold") IntegerProperty shorteningThreshold, // + ReadmeGenerator readmeGenerator, // + SecureRandom csprng, // + MasterkeyFileAccess masterkeyFileAccess) { this.window = window; - this.chooseLocationScene = chooseLocationScene; + this.chooseExpertSettingsScene = chooseExpertSettingsScene; this.recoveryKeyScene = recoveryKeyScene; this.successScene = successScene; this.appWindows = appWindows; @@ -103,6 +119,7 @@ public class CreateNewVaultPasswordController implements FxController { this.processing = new SimpleBooleanProperty(); this.readyToCreateVault = new SimpleBooleanProperty(); this.createVaultButtonState = Bindings.when(processing).then(ContentDisplay.LEFT).otherwise(ContentDisplay.TEXT_ONLY); + this.shorteningThreshold = shorteningThreshold; } @FXML @@ -116,7 +133,7 @@ public class CreateNewVaultPasswordController implements FxController { @FXML public void back() { - window.setScene(chooseLocationScene.get()); + window.setScene(chooseExpertSettingsScene.get()); } @FXML @@ -176,7 +193,11 @@ public class CreateNewVaultPasswordController implements FxController { // 2. initialize vault: try { MasterkeyLoader loader = ignored -> masterkey.copy(); - CryptoFileSystemProperties fsProps = CryptoFileSystemProperties.cryptoFileSystemProperties().withCipherCombo(CryptorProvider.Scheme.SIV_GCM).withKeyLoader(loader).build(); + CryptoFileSystemProperties fsProps = CryptoFileSystemProperties.cryptoFileSystemProperties() // + .withCipherCombo(CryptorProvider.Scheme.SIV_GCM) // + .withKeyLoader(loader) // + .withShorteningThreshold(shorteningThreshold.get()) // + .build(); CryptoFileSystemProvider.initialize(path, fsProps, DEFAULT_KEY_ID); // 3. write vault-internal readme file: diff --git a/src/main/java/org/cryptomator/ui/common/FxmlFile.java b/src/main/java/org/cryptomator/ui/common/FxmlFile.java index 3bec75899..d316ba328 100644 --- a/src/main/java/org/cryptomator/ui/common/FxmlFile.java +++ b/src/main/java/org/cryptomator/ui/common/FxmlFile.java @@ -4,6 +4,7 @@ public enum FxmlFile { ADDVAULT_EXISTING("/fxml/addvault_existing.fxml"), // ADDVAULT_NEW_NAME("/fxml/addvault_new_name.fxml"), // ADDVAULT_NEW_LOCATION("/fxml/addvault_new_location.fxml"), // + ADDVAULT_NEW_EXPERT_SETTINGS("/fxml/addvault_new_expert_settings.fxml"), // ADDVAULT_NEW_PASSWORD("/fxml/addvault_new_password.fxml"), // ADDVAULT_NEW_RECOVERYKEY("/fxml/addvault_new_recoverykey.fxml"), // ADDVAULT_SUCCESS("/fxml/addvault_success.fxml"), // diff --git a/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java b/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java index 77c3cb042..33a674b11 100644 --- a/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java +++ b/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java @@ -40,6 +40,7 @@ public enum FontAwesome5Icon { LOCK("\uF023"), // LOCK_OPEN("\uF3C1"), // MAGIC("\uF0D0"), // + PENCIL("\uF303"), // PLUS("\uF067"), // PRINT("\uF02F"), // QUESTION("\uF128"), // diff --git a/src/main/resources/fxml/addvault_new_expert_settings.fxml b/src/main/resources/fxml/addvault_new_expert_settings.fxml new file mode 100644 index 000000000..202f7c4d7 --- /dev/null +++ b/src/main/resources/fxml/addvault_new_expert_settings.fxml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +