mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-18 10:41:26 +00:00
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:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public class NiceSecurePasswordField extends StackPane {
|
||||
}
|
||||
|
||||
public void swipe() {
|
||||
passwordField.swipe();;
|
||||
passwordField.swipe();
|
||||
}
|
||||
|
||||
public void selectAll() {
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
30
main/ui/src/main/resources/fxml/new_password.fxml
Normal file
30
main/ui/src/main/resources/fxml/new_password.fxml
Normal 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>
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user