Ver código fonte

Made recovery key creation a two-step wizard

Sebastian Stenzel 5 anos atrás
pai
commit
f82fddc8fe

+ 1 - 0
main/ui/src/main/java/org/cryptomator/ui/common/FxmlFile.java

@@ -17,6 +17,7 @@ public enum FxmlFile {
 	PREFERENCES("/fxml/preferences.fxml"), //
 	QUIT("/fxml/quit.fxml"), //
 	RECOVERYKEY_CREATE("/fxml/recoverykey_create.fxml"), //
+	RECOVERYKEY_DISPLAY("/fxml/recoverykey_display.fxml"), //
 	REMOVE_VAULT("/fxml/remove_vault.fxml"), //
 	UNLOCK("/fxml/unlock.fxml"),
 	UNLOCK_SUCCESS("/fxml/unlock_success.fxml"), //

+ 4 - 0
main/ui/src/main/java/org/cryptomator/ui/controls/NiceSecurePasswordField.java

@@ -67,6 +67,10 @@ public class NiceSecurePasswordField extends StackPane {
 	public void requestFocus() {
 		passwordField.requestFocus();
 	}
+	
+	public String getText() {
+		return passwordField.getText();
+	}
 
 	public StringProperty textProperty() {
 		return passwordField.textProperty();

+ 0 - 3
main/ui/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyComponent.java

@@ -36,9 +36,6 @@ public interface RecoveryKeyComponent {
 		@BindsInstance
 		Builder vault(@RecoveryKeyWindow Vault vault);
 
-		@BindsInstance
-		Builder password(@Nullable CharSequence password);
-
 		@BindsInstance
 		Builder owner(@Named("keyRecoveryOwner") Stage owner);
 

+ 11 - 25
main/ui/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyCreationController.java

@@ -1,14 +1,16 @@
 package org.cryptomator.ui.recoverykey;
 
+import dagger.Lazy;
 import javafx.beans.property.ReadOnlyStringProperty;
-import javafx.beans.property.SimpleStringProperty;
 import javafx.beans.property.StringProperty;
 import javafx.fxml.FXML;
+import javafx.scene.Scene;
 import javafx.stage.Stage;
 import org.cryptomator.common.vaults.Vault;
-import org.cryptomator.cryptofs.CryptoFileSystemProvider;
 import org.cryptomator.cryptolib.api.InvalidPassphraseException;
 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.NiceSecurePasswordField;
 import org.slf4j.Logger;
@@ -17,7 +19,6 @@ import org.slf4j.LoggerFactory;
 import javax.annotation.Nullable;
 import javax.inject.Inject;
 import java.io.IOException;
-import java.util.Arrays;
 import java.util.concurrent.ExecutorService;
 
 @RecoveryKeyScoped
@@ -26,28 +27,21 @@ public class RecoveryKeyCreationController implements FxController {
 	private static final Logger LOG = LoggerFactory.getLogger(RecoveryKeyCreationController.class);
 
 	private final Stage window;
+	private final Lazy<Scene> successScene;
 	private final Vault vault;
 	private final ExecutorService executor;
-	private final CharSequence prefilledPassword;
 	private final RecoveryKeyFactory recoveryKeyFactory;
-	private final StringProperty recoveryKey;
+	private final StringProperty recoveryKeyProperty;
 	public NiceSecurePasswordField passwordField;
 
 	@Inject
-	public RecoveryKeyCreationController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, RecoveryKeyFactory recoveryKeyFactory, ExecutorService executor, @Nullable CharSequence prefilledPassword) {
+	public RecoveryKeyCreationController(@RecoveryKeyWindow Stage window, @FxmlScene(FxmlFile.RECOVERYKEY_DISPLAY) Lazy<Scene> successScene, @RecoveryKeyWindow Vault vault, RecoveryKeyFactory recoveryKeyFactory, ExecutorService executor, @RecoveryKeyWindow StringProperty recoveryKey) {
 		this.window = window;
+		this.successScene = successScene;
 		this.vault = vault;
 		this.executor = executor;
-		this.prefilledPassword = prefilledPassword;
 		this.recoveryKeyFactory = recoveryKeyFactory;
-		this.recoveryKey = new SimpleStringProperty();
-	}
-	
-	@FXML
-	public void initialize() {
-		if (prefilledPassword != null) {
-			passwordField.setPassword(prefilledPassword);
-		}
+		this.recoveryKeyProperty = recoveryKey;
 	}
 	
 	@FXML
@@ -55,7 +49,8 @@ public class RecoveryKeyCreationController implements FxController {
 		Tasks.create(() -> {
 			return recoveryKeyFactory.createRecoveryKey(vault.getPath(), passwordField.getCharacters());
 		}).onSuccess(result -> {
-			recoveryKey.set(result);
+			recoveryKeyProperty.set(result);
+			window.setScene(successScene.get());
 		}).onError(IOException.class, e -> {
 			LOG.error("Creation of recovery key failed.", e);
 		}).onError(InvalidPassphraseException.class, e -> {
@@ -67,14 +62,5 @@ public class RecoveryKeyCreationController implements FxController {
 	public void close() {
 		window.close();
 	}
-	
-	/* Getter/Setter */
 
-	public ReadOnlyStringProperty recoveryKeyProperty() {
-		return recoveryKey;
-	}
-
-	public String getRecoveryKey() {
-		return recoveryKey.get();
-	}
 }

+ 37 - 0
main/ui/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyDisplayController.java

@@ -0,0 +1,37 @@
+package org.cryptomator.ui.recoverykey;
+
+import javafx.beans.property.ReadOnlyStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.fxml.FXML;
+import javafx.stage.Stage;
+import org.cryptomator.ui.common.FxController;
+
+import javax.inject.Inject;
+
+@RecoveryKeyScoped
+public class RecoveryKeyDisplayController implements FxController {
+
+	private final Stage window;
+	private final StringProperty recoveryKeyProperty;
+
+	@Inject
+	public RecoveryKeyDisplayController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow StringProperty recoveryKey) {
+		this.window = window;
+		this.recoveryKeyProperty = recoveryKey;
+	}
+
+	@FXML
+	public void close() {
+		window.close();
+	}
+
+	/* Getter/Setter */
+
+	public ReadOnlyStringProperty recoveryKeyProperty() {
+		return recoveryKeyProperty;
+	}
+
+	public String getRecoveryKey() {
+		return recoveryKeyProperty.get();
+	}
+}

+ 24 - 0
main/ui/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyModule.java

@@ -4,6 +4,8 @@ import dagger.Binds;
 import dagger.Module;
 import dagger.Provides;
 import dagger.multibindings.IntoMap;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
 import javafx.scene.Scene;
 import javafx.scene.image.Image;
 import javafx.stage.Modality;
@@ -43,6 +45,15 @@ abstract class RecoveryKeyModule {
 		windowIcon.ifPresent(stage.getIcons()::add);
 		return stage;
 	}
+	
+	@Provides
+	@RecoveryKeyWindow
+	@RecoveryKeyScoped
+	static StringProperty provideRecoveryKeyProperty() {
+		return new SimpleStringProperty();
+	}
+	
+	// ------------------
 
 	@Provides
 	@FxmlScene(FxmlFile.RECOVERYKEY_CREATE)
@@ -51,10 +62,23 @@ abstract class RecoveryKeyModule {
 		return fxmlLoaders.createScene("/fxml/recoverykey_create.fxml");
 	}
 
+	@Provides
+	@FxmlScene(FxmlFile.RECOVERYKEY_DISPLAY)
+	@RecoveryKeyScoped
+	static Scene provideRecoveryKeyDisplayScene(@RecoveryKeyWindow FXMLLoaderFactory fxmlLoaders) {
+		return fxmlLoaders.createScene("/fxml/recoverykey_display.fxml");
+	}
+
 	// ------------------
 
 	@Binds
 	@IntoMap
 	@FxControllerKey(RecoveryKeyCreationController.class)
 	abstract FxController bindRecoveryKeyCreationController(RecoveryKeyCreationController controller);
+
+	@Binds
+	@IntoMap
+	@FxControllerKey(RecoveryKeyDisplayController.class)
+	abstract FxController bindRecoveryKeyDisplayController(RecoveryKeyDisplayController controller);
+	
 }

+ 5 - 19
main/ui/src/main/resources/fxml/recoverykey_create.fxml

@@ -3,13 +3,9 @@
 <?import javafx.geometry.Insets?>
 <?import javafx.scene.control.Button?>
 <?import javafx.scene.control.ButtonBar?>
-<?import javafx.scene.control.TextField?>
-<?import javafx.scene.layout.StackPane?>
+<?import javafx.scene.layout.HBox?>
 <?import javafx.scene.layout.VBox?>
-<?import javafx.scene.shape.Circle?>
-<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
 <?import org.cryptomator.ui.controls.NiceSecurePasswordField?>
-<?import javafx.scene.layout.HBox?>
 <VBox xmlns="http://javafx.com/javafx"
 	  xmlns:fx="http://javafx.com/fxml"
 	  fx:controller="org.cryptomator.ui.recoverykey.RecoveryKeyCreationController"
@@ -22,23 +18,13 @@
 		<Insets topRightBottomLeft="12"/>
 	</padding>
 	<children>
-		<StackPane alignment="CENTER">
-			<Circle styleClass="glyph-icon-primary" radius="36"/>
-			<FontAwesome5IconView styleClass="glyph-icon-white" glyph="CHECK" glyphSize="36"/>
-		</StackPane>
-
-		<HBox>
-			<NiceSecurePasswordField fx:id="passwordField" HBox.hgrow="ALWAYS"/>
-			<Button text="TODO create recovery key" onAction="#createRecoveryKey" HBox.hgrow="NEVER"/>
-		</HBox>
-		
-		<!-- TODO use TextArea instead -->
-		<TextField editable="false" text="${controller.recoveryKey}"/>
+		<NiceSecurePasswordField fx:id="passwordField" HBox.hgrow="ALWAYS"/>
 
 		<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
-			<ButtonBar buttonMinWidth="120" buttonOrder="+C">
+			<ButtonBar buttonMinWidth="120" buttonOrder="C+X">
 				<buttons>
-					<Button text="%generic.button.done" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
+					<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close" />
+					<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#createRecoveryKey" disable="${passwordField.text.empty}"/>
 				</buttons>
 			</ButtonBar>
 		</VBox>

+ 42 - 0
main/ui/src/main/resources/fxml/recoverykey_display.fxml

@@ -0,0 +1,42 @@
+<?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.TextField?>
+<?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.recoverykey.RecoveryKeyDisplayController"
+	  minWidth="400"
+	  maxWidth="400"
+	  minHeight="145"
+	  spacing="12"
+	  alignment="TOP_CENTER">
+	<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="CHECK" glyphSize="24"/>
+			</StackPane>
+			
+			<!-- TODO use TextArea instead -->
+			<TextField editable="false" text="${controller.recoveryKey}" HBox.hgrow="ALWAYS"/>
+		</HBox>
+
+		<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
+			<ButtonBar buttonMinWidth="120" buttonOrder="+C">
+				<buttons>
+					<Button text="%generic.button.done" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
+				</buttons>
+			</ButtonBar>
+		</VBox>
+	</children>
+</VBox>