Deduplicated UI code

Made "Enter Password" and "Reenter Password" a reusable component that is included in its original places
preparation for #1018
This commit is contained in:
Sebastian Stenzel
2019-12-17 17:35:16 +01:00
parent c97f146964
commit 148eed172a
10 changed files with 173 additions and 138 deletions

View File

@@ -19,6 +19,8 @@ import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.NewPasswordController;
import org.cryptomator.ui.common.PasswordStrengthUtil;
import org.cryptomator.ui.mainwindow.MainWindow;
import org.cryptomator.ui.recoverykey.RecoveryKeyDisplayController;
@@ -32,6 +34,13 @@ import java.util.ResourceBundle;
@Module
public abstract class AddVaultModule {
@Provides
@AddVaultWizardScoped
@Named("newPassword")
static ObjectProperty<CharSequence> provideNewPasswordProperty() {
return new SimpleObjectProperty<>("");
}
@Provides
@AddVaultWizardWindow
@AddVaultWizardScoped
@@ -169,6 +178,13 @@ public abstract class AddVaultModule {
@FxControllerKey(CreateNewVaultPasswordController.class)
abstract FxController bindCreateNewVaultPasswordController(CreateNewVaultPasswordController controller);
@Provides
@IntoMap
@FxControllerKey(NewPasswordController.class)
static FxController provideNewPasswordController(ResourceBundle resourceBundle, PasswordStrengthUtil strengthRater, @Named("newPassword") ObjectProperty<CharSequence> password) {
return new NewPasswordController(resourceBundle, strengthRater, password);
}
@Binds
@IntoMap
@FxControllerKey(CreateNewVaultRecoveryKeyController.class)

View File

@@ -5,18 +5,14 @@ import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
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.SimpleIntegerProperty;
import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultListManager;
@@ -26,11 +22,7 @@ import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.Tasks;
import org.cryptomator.ui.controls.FontAwesome5IconView;
import org.cryptomator.ui.controls.NiceSecurePasswordField;
import org.cryptomator.ui.common.PasswordStrengthUtil;
import org.cryptomator.ui.recoverykey.RecoveryKeyFactory;
import org.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -69,26 +61,18 @@ public class CreateNewVaultPasswordController implements FxController {
private final StringProperty recoveryKeyProperty;
private final VaultListManager vaultListManager;
private final ResourceBundle resourceBundle;
private final PasswordStrengthUtil strengthRater;
private final ObjectProperty<CharSequence> password;
private final ReadmeGenerator readmeGenerator;
private final IntegerProperty passwordStrength;
private final BooleanProperty processing;
private final BooleanProperty readyToCreateVault;
private final ObjectBinding<ContentDisplay> createVaultButtonState;
public NiceSecurePasswordField passwordField;
public NiceSecurePasswordField reenterField;
public Label passwordStrengthLabel;
public HBox passwordMatchBox;
public FontAwesome5IconView checkmark;
public FontAwesome5IconView cross;
public Label passwordMatchLabel;
public ToggleGroup recoveryKeyChoice;
public Toggle showRecoveryKey;
public Toggle skipRecoveryKey;
@Inject
CreateNewVaultPasswordController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_LOCATION) Lazy<Scene> chooseLocationScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_RECOVERYKEY) Lazy<Scene> recoveryKeyScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy<Scene> successScene, ExecutorService executor, RecoveryKeyFactory recoveryKeyFactory, @Named("vaultName") StringProperty vaultName, ObjectProperty<Path> vaultPath, @AddVaultWizardWindow ObjectProperty<Vault> vault, @Named("recoveryKey") StringProperty recoveryKey, VaultListManager vaultListManager, ResourceBundle resourceBundle, PasswordStrengthUtil strengthRater, ReadmeGenerator readmeGenerator) {
CreateNewVaultPasswordController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_LOCATION) Lazy<Scene> chooseLocationScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_RECOVERYKEY) Lazy<Scene> recoveryKeyScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy<Scene> successScene, ExecutorService executor, RecoveryKeyFactory recoveryKeyFactory, @Named("vaultName") StringProperty vaultName, ObjectProperty<Path> vaultPath, @AddVaultWizardWindow ObjectProperty<Vault> vault, @Named("recoveryKey") StringProperty recoveryKey, VaultListManager vaultListManager, ResourceBundle resourceBundle, @Named("newPassword") ObjectProperty<CharSequence> password, ReadmeGenerator readmeGenerator) {
this.window = window;
this.chooseLocationScene = chooseLocationScene;
this.recoveryKeyScene = recoveryKeyScene;
@@ -101,9 +85,8 @@ public class CreateNewVaultPasswordController implements FxController {
this.recoveryKeyProperty = recoveryKey;
this.vaultListManager = vaultListManager;
this.resourceBundle = resourceBundle;
this.strengthRater = strengthRater;
this.password = password;
this.readmeGenerator = readmeGenerator;
this.passwordStrength = new SimpleIntegerProperty(-1);
this.processing = new SimpleBooleanProperty();
this.readyToCreateVault = new SimpleBooleanProperty();
this.createVaultButtonState = Bindings.createObjectBinding(this::getCreateVaultButtonState, processing);
@@ -111,24 +94,8 @@ public class CreateNewVaultPasswordController implements FxController {
@FXML
public void initialize() {
// binds the actual strength value to the rating of the password util
passwordStrength.bind(Bindings.createIntegerBinding(() -> strengthRater.computeRate(passwordField.getCharacters().toString()), passwordField.textProperty()));
// binding indicating if the passwords not match
BooleanBinding passwordsMatch = Bindings.createBooleanBinding(() -> CharSequence.compare(passwordField.getCharacters(), reenterField.getCharacters()) == 0, passwordField.textProperty(), reenterField.textProperty());
BooleanBinding reenterFieldNotEmpty = reenterField.textProperty().isNotEmpty();
readyToCreateVault.bind(reenterFieldNotEmpty.and(passwordsMatch).and(recoveryKeyChoice.selectedToggleProperty().isNotNull()).and(processing.not()));
// make match indicator invisible when passwords do not match or one is empty
passwordMatchBox.visibleProperty().bind(reenterFieldNotEmpty);
checkmark.visibleProperty().bind(passwordsMatch.and(reenterFieldNotEmpty));
checkmark.managedProperty().bind(checkmark.visibleProperty());
cross.visibleProperty().bind(passwordsMatch.not().and(reenterFieldNotEmpty));
cross.managedProperty().bind(cross.visibleProperty());
passwordMatchLabel.textProperty().bind(Bindings.when(passwordsMatch.and(reenterFieldNotEmpty)).then(resourceBundle.getString("addvaultwizard.new.passwordsMatch")).otherwise(resourceBundle.getString("addvaultwizard.new.passwordsDoNotMatch")));
// bindsings for the password strength indicator
passwordStrengthLabel.textProperty().bind(EasyBind.map(passwordStrength, strengthRater::getStrengthDescription));
// reset radiobuttons on password change
passwordField.textProperty().addListener(evt -> recoveryKeyChoice.selectToggle(null));
reenterField.textProperty().addListener(evt -> recoveryKeyChoice.selectToggle(null));
BooleanBinding isValidNewPassword = Bindings.createBooleanBinding(() -> password.get() != null && password.get().length() > 0, password);
readyToCreateVault.bind(isValidNewPassword.and(recoveryKeyChoice.selectedToggleProperty().isNotNull()).and(processing.not()));
}
@FXML
@@ -139,7 +106,7 @@ public class CreateNewVaultPasswordController implements FxController {
@FXML
public void next() {
Path pathToVault = vaultPathProperty.get();
try {
Files.createDirectory(pathToVault);
} catch (FileAlreadyExistsException e) {
@@ -149,7 +116,7 @@ public class CreateNewVaultPasswordController implements FxController {
// TODO show generic error screen
LOG.error("", e);
}
if (showRecoveryKey.equals(recoveryKeyChoice.getSelectedToggle())) {
showRecoveryKeyScene();
} else if (skipRecoveryKey.equals(recoveryKeyChoice.getSelectedToggle())) {
@@ -163,8 +130,8 @@ public class CreateNewVaultPasswordController implements FxController {
Path pathToVault = vaultPathProperty.get();
processing.set(true);
Tasks.create(() -> {
initializeVault(pathToVault, passwordField.getCharacters());
return recoveryKeyFactory.createRecoveryKey(pathToVault, passwordField.getCharacters());
initializeVault(pathToVault, password.get());
return recoveryKeyFactory.createRecoveryKey(pathToVault, password.get());
}).onSuccess(recoveryKey -> {
initializationSucceeded(pathToVault);
recoveryKeyProperty.set(recoveryKey);
@@ -181,7 +148,7 @@ public class CreateNewVaultPasswordController implements FxController {
Path pathToVault = vaultPathProperty.get();
processing.set(true);
Tasks.create(() -> {
initializeVault(pathToVault, passwordField.getCharacters());
initializeVault(pathToVault, password.get());
}).onSuccess(() -> {
initializationSucceeded(pathToVault);
window.setScene(successScene.get());
@@ -213,7 +180,7 @@ public class CreateNewVaultPasswordController implements FxController {
}
LOG.info("Created vault at {}", path);
}
private void initializationSucceeded(Path pathToVault) {
try {
Vault newVault = vaultListManager.add(pathToVault);
@@ -233,14 +200,6 @@ public class CreateNewVaultPasswordController implements FxController {
return vaultNameProperty;
}
public IntegerProperty passwordStrengthProperty() {
return passwordStrength;
}
public int getPasswordStrength() {
return passwordStrength.get();
}
public BooleanProperty readyToCreateVaultProperty() {
return readyToCreateVault;
}

View File

@@ -3,6 +3,7 @@ package org.cryptomator.ui.changepassword;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
@@ -22,6 +23,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.IOException;
import java.util.ResourceBundle;
@@ -33,47 +35,24 @@ public class ChangePasswordController implements FxController {
private final Stage window;
private final Vault vault;
private final ResourceBundle resourceBundle;
private final PasswordStrengthUtil strengthRater;
private final IntegerProperty passwordStrength;
private final ObjectProperty<CharSequence> newPassword;
public NiceSecurePasswordField oldPasswordField;
public NiceSecurePasswordField newPasswordField;
public NiceSecurePasswordField reenterPasswordField;
public Label passwordStrengthLabel;
public HBox passwordMatchBox;
public FontAwesome5IconView checkmark;
public FontAwesome5IconView cross;
public Label passwordMatchLabel;
public CheckBox finalConfirmationCheckbox;
public Button finishButton;
@Inject
public ChangePasswordController(@ChangePasswordWindow Stage window, @ChangePasswordWindow Vault vault, ResourceBundle resourceBundle, PasswordStrengthUtil strengthRater) {
public ChangePasswordController(@ChangePasswordWindow Stage window, @ChangePasswordWindow Vault vault, @Named("newPassword") ObjectProperty<CharSequence> newPassword) {
this.window = window;
this.vault = vault;
this.resourceBundle = resourceBundle;
this.strengthRater = strengthRater;
this.passwordStrength = new SimpleIntegerProperty(-1);
this.newPassword = newPassword;
}
@FXML
public void initialize() {
//binds the actual strength value to the rating of the password util
passwordStrength.bind(Bindings.createIntegerBinding(() -> strengthRater.computeRate(newPasswordField.getCharacters().toString()), newPasswordField.textProperty()));
//binding indicating if the passwords not match
BooleanBinding passwordsMatch = Bindings.createBooleanBinding(() -> CharSequence.compare(newPasswordField.getCharacters(), reenterPasswordField.getCharacters()) == 0, newPasswordField.textProperty(), reenterPasswordField.textProperty());
BooleanBinding reenterFieldNotEmpty = reenterPasswordField.textProperty().isNotEmpty();
//disable the finish button when passwords do not match or one is empty
finishButton.disableProperty().bind(reenterFieldNotEmpty.not().or(passwordsMatch.not()).or(finalConfirmationCheckbox.selectedProperty().not()));
//make match indicator invisible when passwords do not match or one is empty
passwordMatchBox.visibleProperty().bind(reenterFieldNotEmpty);
checkmark.visibleProperty().bind(passwordsMatch.and(reenterFieldNotEmpty));
checkmark.managedProperty().bind(checkmark.visibleProperty());
cross.visibleProperty().bind(passwordsMatch.not().and(reenterFieldNotEmpty));
cross.managedProperty().bind(cross.visibleProperty());
passwordMatchLabel.textProperty().bind(Bindings.when(passwordsMatch.and(reenterFieldNotEmpty)).then(resourceBundle.getString("changepassword.passwordsMatch")).otherwise(resourceBundle.getString("changepassword.passwordsDoNotMatch")));
passwordStrengthLabel.textProperty().bind(EasyBind.map(passwordStrength, strengthRater::getStrengthDescription));
BooleanBinding hasNotConfirmedCheckbox = finalConfirmationCheckbox.selectedProperty().not();
BooleanBinding isInvalidNewPassword = Bindings.createBooleanBinding(() -> newPassword.get() == null || newPassword.get().length() == 0, newPassword);
finishButton.disableProperty().bind(hasNotConfirmedCheckbox.or(isInvalidNewPassword));
}
@FXML
@@ -84,15 +63,15 @@ public class ChangePasswordController implements FxController {
@FXML
public void finish() {
try {
CryptoFileSystemProvider.changePassphrase(vault.getPath(), MASTERKEY_FILENAME, oldPasswordField.getCharacters(), newPasswordField.getCharacters());
CryptoFileSystemProvider.changePassphrase(vault.getPath(), MASTERKEY_FILENAME, oldPasswordField.getCharacters(), newPassword.get());
LOG.info("Successful changed password for {}", vault.getDisplayableName());
window.close();
} catch (IOException e) {
//TODO
// TODO show generic error screen
LOG.error("IO error occured during password change. Unable to perform operation.", e);
e.printStackTrace();
} catch (InvalidPassphraseException e) {
//TODO
// TODO shake
LOG.info("Wrong old password.");
}
}
@@ -102,12 +81,5 @@ public class ChangePasswordController implements FxController {
public Vault getVault() {
return vault;
}
public IntegerProperty passwordStrengthProperty() {
return passwordStrength;
}
public int getPasswordStrength() {
return passwordStrength.get();
}
}

View File

@@ -4,6 +4,8 @@ import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Modality;
@@ -14,15 +16,25 @@ import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.NewPasswordController;
import org.cryptomator.ui.common.PasswordStrengthUtil;
import javax.inject.Named;
import javax.inject.Provider;
import java.nio.CharBuffer;
import java.util.Map;
import java.util.Optional;
import java.util.ResourceBundle;
@Module
abstract class ChangePasswordModule {
@Provides
@ChangePasswordScoped
@Named("newPassword")
static ObjectProperty<CharSequence> provideNewPasswordProperty() {
return new SimpleObjectProperty<>("");
}
@Provides
@ChangePasswordWindow
@@ -58,5 +70,12 @@ abstract class ChangePasswordModule {
@IntoMap
@FxControllerKey(ChangePasswordController.class)
abstract FxController bindUnlockController(ChangePasswordController controller);
@Provides
@IntoMap
@FxControllerKey(NewPasswordController.class)
static FxController provideNewPasswordController(ResourceBundle resourceBundle, PasswordStrengthUtil strengthRater, @Named("newPassword") ObjectProperty<CharSequence> password) {
return new NewPasswordController(resourceBundle, strengthRater, password);
}
}

View File

@@ -0,0 +1,74 @@
package org.cryptomator.ui.common;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import org.cryptomator.ui.controls.FontAwesome5IconView;
import org.cryptomator.ui.controls.NiceSecurePasswordField;
import org.fxmisc.easybind.EasyBind;
import java.util.ResourceBundle;
public class NewPasswordController implements FxController {
private final ResourceBundle resourceBundle;
private final PasswordStrengthUtil strengthRater;
private final ObjectProperty<CharSequence> password;
private final IntegerProperty passwordStrength = new SimpleIntegerProperty(-1);
public NiceSecurePasswordField passwordField;
public NiceSecurePasswordField reenterField;
public Label passwordStrengthLabel;
public Label passwordMatchLabel;
public FontAwesome5IconView checkmark;
public FontAwesome5IconView cross;
public NewPasswordController(ResourceBundle resourceBundle, PasswordStrengthUtil strengthRater, ObjectProperty<CharSequence> password) {
this.resourceBundle = resourceBundle;
this.strengthRater = strengthRater;
this.password = password;
}
@FXML
public void initialize() {
BooleanBinding passwordsMatch = Bindings.createBooleanBinding(this::hasSamePasswordInBothFields, passwordField.textProperty(), reenterField.textProperty());
BooleanBinding reenterFieldNotEmpty = reenterField.textProperty().isNotEmpty();
passwordStrength.bind(Bindings.createIntegerBinding(() -> strengthRater.computeRate(passwordField.getCharacters().toString()), passwordField.textProperty()));
passwordStrengthLabel.textProperty().bind(EasyBind.map(passwordStrength, strengthRater::getStrengthDescription));
passwordMatchLabel.visibleProperty().bind(reenterFieldNotEmpty);
passwordMatchLabel.graphicProperty().bind(Bindings.when(passwordsMatch.and(reenterFieldNotEmpty)).then(checkmark).otherwise(cross));
passwordMatchLabel.textProperty().bind(Bindings.when(passwordsMatch.and(reenterFieldNotEmpty)).then(resourceBundle.getString("newPassword.passwordsMatch")).otherwise(resourceBundle.getString("newPassword.passwordsDoNotMatch")));
passwordField.textProperty().addListener(this::passwordsDidChange);
reenterField.textProperty().addListener(this::passwordsDidChange);
}
private void passwordsDidChange(@SuppressWarnings("unused") Observable observable) {
if (hasSamePasswordInBothFields()) {
password.set(passwordField.getCharacters());
} else {
password.set("");
}
}
private boolean hasSamePasswordInBothFields() {
return CharSequence.compare(passwordField.getCharacters(), reenterField.getCharacters()) == 0;
}
/* Getter/Setter */
public IntegerProperty passwordStrengthProperty() {
return passwordStrength;
}
public int getPasswordStrength() {
return passwordStrength.get();
}
}

View File

@@ -89,7 +89,7 @@ public class NiceSecurePasswordField extends StackPane {
}
public void swipe() {
passwordField.swipe();;
passwordField.swipe();
}
public void selectAll() {

View File

@@ -5,14 +5,10 @@
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressIndicator?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.VBox?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import org.cryptomator.ui.controls.NiceSecurePasswordField?>
<?import org.cryptomator.ui.controls.PasswordStrengthIndicator?>
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.ToggleGroup?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.addvaultwizard.CreateNewVaultPasswordController"
@@ -27,21 +23,7 @@
<Insets topRightBottomLeft="24"/>
</padding>
<children>
<VBox spacing="6">
<Label text="%addvaultwizard.new.enterPassword" labelFor="$passwordField"/>
<NiceSecurePasswordField fx:id="passwordField"/>
<PasswordStrengthIndicator spacing="6" prefHeight="6" strength="${controller.passwordStrength}"/>
<Label fx:id="passwordStrengthLabel" styleClass="label-secondary" labelFor="$passwordField" alignment="CENTER_RIGHT" maxWidth="Infinity"/>
</VBox>
<VBox spacing="6">
<Label text="%addvaultwizard.new.reenterPassword" labelFor="$reenterField"/>
<NiceSecurePasswordField fx:id="reenterField"/>
<HBox fx:id="passwordMatchBox" spacing="6" alignment="CENTER_RIGHT">
<FontAwesome5IconView fx:id="checkmark" styleClass="glyph-icon-primary" glyph="CHECK"/>
<FontAwesome5IconView fx:id="cross" styleClass="glyph-icon-red" glyph="TIMES"/>
<Label fx:id="passwordMatchLabel" styleClass="label-secondary" labelFor="$reenterField"/>
</HBox>
</VBox>
<fx:include source="/fxml/new_password.fxml"/>
<Region VBox.vgrow="ALWAYS"/>

View File

@@ -28,22 +28,9 @@
</VBox>
<Region prefHeight="12" VBox.vgrow="NEVER"/>
<fx:include source="/fxml/new_password.fxml"/>
<VBox spacing="6">
<Label labelFor="$newPasswordField" text="%changepassword.enterNewPassword"/>
<NiceSecurePasswordField fx:id="newPasswordField"/>
<PasswordStrengthIndicator prefHeight="6" spacing="6" strength="${controller.passwordStrength}"/>
<Label fx:id="passwordStrengthLabel" styleClass="label-secondary" alignment="CENTER_RIGHT" maxWidth="Infinity"/>
</VBox>
<VBox spacing="6">
<Label labelFor="$reenterPasswordField" text="%changepassword.reenterNewPassword"/>
<NiceSecurePasswordField fx:id="reenterPasswordField"/>
<HBox fx:id="passwordMatchBox" spacing="6" alignment="CENTER_RIGHT">
<FontAwesome5IconView fx:id="checkmark" styleClass="glyph-icon-primary" glyph="CHECK"/>
<FontAwesome5IconView fx:id="cross" styleClass="glyph-icon-red" glyph="TIMES"/>
<Label fx:id="passwordMatchLabel" styleClass="label-secondary" labelFor="$reenterPasswordField"/>
</HBox>
</VBox>
<CheckBox fx:id="finalConfirmationCheckbox" text="%changepassword.finalConfirmation" wrapText="true"/>
<Region VBox.vgrow="ALWAYS"/>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.VBox?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import org.cryptomator.ui.controls.NiceSecurePasswordField?>
<?import org.cryptomator.ui.controls.PasswordStrengthIndicator?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.common.NewPasswordController"
spacing="6"
alignment="CENTER_LEFT">
<fx:define>
<FontAwesome5IconView fx:id="checkmark" styleClass="glyph-icon-primary" glyph="CHECK"/>
<FontAwesome5IconView fx:id="cross" styleClass="glyph-icon-red" glyph="TIMES"/>
</fx:define>
<children>
<Label text="%newPassword.promptText" labelFor="$passwordField"/>
<NiceSecurePasswordField fx:id="passwordField"/>
<PasswordStrengthIndicator spacing="6" prefHeight="6" strength="${controller.passwordStrength}"/>
<Label fx:id="passwordStrengthLabel" styleClass="label-secondary" alignment="CENTER_RIGHT" maxWidth="Infinity"/>
<Region/>
<Label text="%newPassword.reenterPassword" labelFor="$reenterField"/>
<NiceSecurePasswordField fx:id="reenterField"/>
<Label fx:id="passwordMatchLabel" styleClass="label-secondary" alignment="CENTER_RIGHT" maxWidth="Infinity" graphicTextGap="6" contentDisplay="LEFT" />
</children>
</VBox>

View File

@@ -40,14 +40,10 @@ addvaultwizard.new.locationPrompt=…
addvaultwizard.new.directoryPickerLabel=Custom Location
addvaultwizard.new.directoryPickerButton=Choose…
addvaultwizard.new.directoryPickerTitle=Select Directory
addvaultwizard.new.enterPassword=Enter a password for the vault
addvaultwizard.new.fileAlreadyExists=Vault can not be created at this path because some object already exists.
addvaultwizard.new.invalidName=Invalid vault name. Please consider a regular directory name.
addvaultwizard.new.ioException=Selected directory failed a basic test. Make sure to have the appropriate access rights and nothing interferes with Cryptomator.
### Password
addvaultwizard.new.reenterPassword=Confirm the password
addvaultwizard.new.passwordsMatch=Passwords match!
addvaultwizard.new.passwordsDoNotMatch=Passwords do not match
addvaultwizard.new.createVaultBtn=Create Vault
addvaultwizard.new.generateRecoveryKeyChoice=You won't be able to access your data without your password. Do you want a recovery key for the case you lose your password?
addvaultwizard.new.generateRecoveryKeyChoice.yes=Yes please, better safe than sorry
@@ -79,10 +75,6 @@ removeVault.confirmBtn=Remove Vault
# Change Password
changepassword.title=Change Password
changepassword.enterOldPassword=Enter the current password for "%s"
changepassword.enterNewPassword=Enter a new password for your vault
changepassword.reenterNewPassword=Confirm the new password
changepassword.passwordsMatch=Passwords match!
changepassword.passwordsDoNotMatch=Passwords do not match
changepassword.finalConfirmation=I understand that I will not be able to recover my data if I forget my password
# Forget Password
@@ -196,7 +188,11 @@ recoveryKey.enterPassword.prompt=Enter your password to show the recovery key fo
recoveryKey.display.message=The following recovery key can be used to restore access to "%s":
recoveryKey.display.StorageHints=Keep it somewhere very secure, e.g.:\n • Store it using a password manager\n • Save it on a USB flash drive\n • Print it on paper
# Misc
# New Password
newPassword.promptText=Enter a new password
newPassword.reenterPassword=Confirm the new password
newPassword.passwordsMatch=Passwords match!
newPassword.passwordsDoNotMatch=Passwords do not match
passwordStrength.messageLabel.0=Very weak
passwordStrength.messageLabel.1=Weak
passwordStrength.messageLabel.2=Fair