mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-25 06:01:31 +00:00
refactoring forget password dialog ( when unlocking a vault)
This commit is contained in:
@@ -8,6 +8,7 @@ public enum FxmlFile {
|
||||
ADDVAULT_NEW_PASSWORD("/fxml/addvault_new_password.fxml"), //
|
||||
ADDVAULT_SUCCESS("/fxml/addvault_success.fxml"), //
|
||||
CHANGEPASSWORD("/fxml/changepassword.fxml"), //
|
||||
FORGET_PASSWORD("/fxml/forget_password.fxml"), //
|
||||
MAIN_WINDOW("/fxml/main_window.fxml"), //
|
||||
MIGRATION_RUN("/fxml/migration_run.fxml"), //
|
||||
MIGRATION_START("/fxml/migration_start.fxml"), //
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.cryptomator.ui.forgetPassword;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
@Qualifier
|
||||
@Documented
|
||||
@Retention(RUNTIME)
|
||||
public @interface ForgetPassword {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.cryptomator.ui.forgetPassword;
|
||||
|
||||
import dagger.BindsInstance;
|
||||
import dagger.Lazy;
|
||||
import dagger.Subcomponent;
|
||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlScene;
|
||||
|
||||
import javax.inject.Named;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@ForgetPasswordScoped
|
||||
@Subcomponent(modules = {ForgetPasswordModule.class})
|
||||
public interface ForgetPasswordComponent {
|
||||
|
||||
@ForgetPassword
|
||||
ReadOnlyBooleanProperty confirmedProperty();
|
||||
|
||||
@ForgetPassword
|
||||
Stage window();
|
||||
|
||||
@FxmlScene(FxmlFile.FORGET_PASSWORD)
|
||||
Lazy<Scene> scene();
|
||||
|
||||
default CompletableFuture<Boolean> showForgetPassword() {
|
||||
CompletableFuture<Boolean> result = new CompletableFuture<>();
|
||||
Stage stage = window();
|
||||
stage.setScene(scene().get());
|
||||
stage.sizeToScene();
|
||||
stage.show();
|
||||
stage.setOnHidden(evt -> result.complete(confirmedProperty().get()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Subcomponent.Builder
|
||||
interface Builder {
|
||||
|
||||
@BindsInstance
|
||||
Builder vault(@ForgetPassword Vault vault);
|
||||
|
||||
@BindsInstance
|
||||
Builder owner(@Named("forgetPasswordOwner") Stage owner);
|
||||
|
||||
ForgetPasswordComponent build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.cryptomator.ui.forgetPassword;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.stage.Stage;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.keychain.KeychainAccess;
|
||||
import org.cryptomator.keychain.KeychainAccessException;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Optional;
|
||||
|
||||
@ForgetPasswordScoped
|
||||
public class ForgetPasswordController implements FxController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ForgetPasswordController.class);
|
||||
|
||||
private final Stage window;
|
||||
private final Vault vault;
|
||||
private final Optional<KeychainAccess> keychainAccess;
|
||||
private final BooleanProperty confirmedResult;
|
||||
|
||||
@Inject
|
||||
public ForgetPasswordController(@ForgetPassword Stage window, @ForgetPassword Vault vault, Optional<KeychainAccess> keychainAccess, @ForgetPassword BooleanProperty confirmedResult) {
|
||||
this.window = window;
|
||||
this.vault = vault;
|
||||
this.keychainAccess = keychainAccess;
|
||||
this.confirmedResult = confirmedResult;
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void close() {
|
||||
window.close();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void finish() {
|
||||
if (keychainAccess.isPresent()) {
|
||||
try {
|
||||
keychainAccess.get().deletePassphrase(vault.getId());
|
||||
LOG.debug("Forgot password for vault {}.", vault.getDisplayableName());
|
||||
confirmedResult.setValue(true);
|
||||
} catch (KeychainAccessException e) {
|
||||
LOG.error("Failed to remove entry from system keychain.", e);
|
||||
confirmedResult.setValue(false);
|
||||
}
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package org.cryptomator.ui.forgetPassword;
|
||||
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import dagger.multibindings.IntoMap;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import org.cryptomator.ui.common.FXMLLoaderFactory;
|
||||
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 javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@Module
|
||||
abstract class ForgetPasswordModule {
|
||||
|
||||
@Provides
|
||||
@ForgetPassword
|
||||
@ForgetPasswordScoped
|
||||
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, ResourceBundle resourceBundle) {
|
||||
return new FXMLLoaderFactory(factories, resourceBundle);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ForgetPassword
|
||||
@ForgetPasswordScoped
|
||||
static Stage provideStage(ResourceBundle resourceBundle, @Named("windowIcon") Optional<Image> windowIcon, @Named("forgetPasswordOwner") Stage owner) {
|
||||
Stage stage = new Stage();
|
||||
stage.setTitle(resourceBundle.getString("forgetPassword.title"));
|
||||
stage.setResizable(false);
|
||||
stage.initModality(Modality.WINDOW_MODAL);
|
||||
stage.initOwner(owner);
|
||||
windowIcon.ifPresent(stage.getIcons()::add);
|
||||
return stage;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@FxmlScene(FxmlFile.FORGET_PASSWORD)
|
||||
@ForgetPasswordScoped
|
||||
static Scene provideForgetPasswordScene(@ForgetPassword FXMLLoaderFactory fxmlLoaders, @ForgetPassword Stage window) {
|
||||
return fxmlLoaders.createScene("/fxml/forget_password.fxml");
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ForgetPassword
|
||||
@ForgetPasswordScoped
|
||||
static BooleanProperty provideConfirmedProperty() {
|
||||
return new SimpleBooleanProperty(false);
|
||||
}
|
||||
|
||||
@Binds
|
||||
@ForgetPassword
|
||||
@ForgetPasswordScoped
|
||||
abstract ReadOnlyBooleanProperty bindReadOnlyConfirmedProperty(@ForgetPassword BooleanProperty confirmedProperty);
|
||||
|
||||
// ------------------
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FxControllerKey(ForgetPasswordController.class)
|
||||
abstract FxController bindForgetPasswordController(ForgetPasswordController controller);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.cryptomator.ui.forgetPassword;
|
||||
|
||||
import javax.inject.Scope;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Scope
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ForgetPasswordScoped {
|
||||
|
||||
}
|
||||
@@ -12,13 +12,10 @@ import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.value.WritableValue;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ContentDisplay;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Duration;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultState;
|
||||
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
|
||||
@@ -30,8 +27,7 @@ import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlScene;
|
||||
import org.cryptomator.ui.common.Tasks;
|
||||
import org.cryptomator.ui.controls.NiceSecurePasswordField;
|
||||
import org.cryptomator.ui.controls.SecurePasswordField;
|
||||
import org.cryptomator.ui.util.DialogBuilderUtil;
|
||||
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -55,12 +51,13 @@ public class UnlockController implements FxController {
|
||||
private final Optional<KeychainAccess> keychainAccess;
|
||||
private final ResourceBundle resourceBundle;
|
||||
private final Lazy<Scene> successScene;
|
||||
private final ForgetPasswordComponent.Builder forgetPassword;
|
||||
private final BooleanProperty unlockButtonDisabled;
|
||||
public NiceSecurePasswordField passwordField;
|
||||
public CheckBox savePassword;
|
||||
|
||||
@Inject
|
||||
public UnlockController(@UnlockWindow Stage window, @UnlockWindow Vault vault, ExecutorService executor, Optional<KeychainAccess> keychainAccess, ResourceBundle resourceBundle, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy<Scene> successScene) {
|
||||
public UnlockController(@UnlockWindow Stage window, @UnlockWindow Vault vault, ExecutorService executor, Optional<KeychainAccess> keychainAccess, ResourceBundle resourceBundle, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy<Scene> successScene, ForgetPasswordComponent.Builder forgetPassword) {
|
||||
this.window = window;
|
||||
this.vault = vault;
|
||||
this.executor = executor;
|
||||
@@ -68,6 +65,7 @@ public class UnlockController implements FxController {
|
||||
this.keychainAccess = keychainAccess;
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.successScene = successScene;
|
||||
this.forgetPassword = forgetPassword;
|
||||
this.unlockButtonDisabled = new SimpleBooleanProperty();
|
||||
}
|
||||
|
||||
@@ -128,21 +126,7 @@ public class UnlockController implements FxController {
|
||||
@FXML
|
||||
private void didClickSavePasswordCheckbox() {
|
||||
if (!savePassword.isSelected() && hasStoredPassword()) {
|
||||
Alert confirmDialog = DialogBuilderUtil.buildConfirmationDialog( //
|
||||
resourceBundle.getString("unlock.deleteSavedPasswordDialog.title"), //
|
||||
resourceBundle.getString("unlock.deleteSavedPasswordDialog.header"), //
|
||||
resourceBundle.getString("unlock.deleteSavedPasswordDialog.content"), //
|
||||
SystemUtils.IS_OS_MAC_OSX ? ButtonType.CANCEL : ButtonType.OK);
|
||||
Optional<ButtonType> choice = confirmDialog.showAndWait();
|
||||
if (ButtonType.OK.equals(choice.get())) {
|
||||
try {
|
||||
keychainAccess.get().deletePassphrase(vault.getId());
|
||||
} catch (KeychainAccessException e) {
|
||||
LOG.error("Failed to remove entry from system keychain.", e);
|
||||
}
|
||||
} else if (ButtonType.CANCEL.equals(choice.get())) {
|
||||
savePassword.setSelected(true);
|
||||
}
|
||||
forgetPassword.vault(vault).build().showForgetPassword().thenAccept(forgotten -> savePassword.setSelected(!forgotten));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ 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.forgetPassword.ForgetPasswordComponent;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
@@ -23,7 +24,7 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@Module
|
||||
@Module(subcomponents={ForgetPasswordComponent.class})
|
||||
abstract class UnlockModule {
|
||||
|
||||
@Provides
|
||||
|
||||
40
main/ui/src/main/resources/fxml/forget_password.fxml
Normal file
40
main/ui/src/main/resources/fxml/forget_password.fxml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ButtonBar?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||
<VBox xmlns="http://javafx.com/javafx"
|
||||
xmlns:fx="http://javafx.com/fxml"
|
||||
fx:controller="org.cryptomator.ui.forgetPassword.ForgetPasswordController"
|
||||
minWidth="400"
|
||||
maxWidth="400"
|
||||
minHeight="145"
|
||||
spacing="12">
|
||||
<padding>
|
||||
<Insets topRightBottomLeft="12"/>
|
||||
</padding>
|
||||
<children>
|
||||
<HBox spacing="12" alignment="CENTER_LEFT" VBox.vgrow="ALWAYS">
|
||||
<StackPane alignment="CENTER" HBox.hgrow="NEVER">
|
||||
<Circle styleClass="glyph-icon-primary" radius="24"/>
|
||||
<FontAwesome5IconView styleClass="glyph-icon-white" glyph="QUESTION" glyphSize="24"/>
|
||||
</StackPane>
|
||||
<Label text="%forgetPassword.information" wrapText="true" textAlignment="LEFT" HBox.hgrow="ALWAYS"/>
|
||||
</HBox>
|
||||
|
||||
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+CI">
|
||||
<buttons>
|
||||
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" defaultButton="true" cancelButton="true" onAction="#close"/>
|
||||
<Button text="%forgetPassword.confirmBtn" ButtonBar.buttonData="FINISH" onAction="#finish"/>
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
</VBox>
|
||||
</children>
|
||||
</VBox>
|
||||
@@ -68,6 +68,11 @@ 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
|
||||
forgetPassword.title=Forget Password
|
||||
forgetPassword.information=TODO Yalla Yalla
|
||||
forgetPassword.confirmBtn=Ok, forget
|
||||
|
||||
# Unlock
|
||||
unlock.title=Unlock Vault
|
||||
unlock.passwordPrompt=Enter password for "%s":
|
||||
|
||||
@@ -145,3 +145,4 @@ passwordStrength.messageLabel.4=Sehr stark
|
||||
# Quit
|
||||
quit.prompt=Cryptomator beenden? Es sind noch Tresore entsperrt.
|
||||
quit.lockAndQuit=Sperren und beenden
|
||||
forgetPassword.information=TODO Yalla Yalla
|
||||
|
||||
Reference in New Issue
Block a user