mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-19 03:01:27 +00:00
Made recovery key creation a two-step wizard
This commit is contained in:
@@ -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"), //
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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.VBox?>
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||
<?import org.cryptomator.ui.controls.NiceSecurePasswordField?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import org.cryptomator.ui.controls.NiceSecurePasswordField?>
|
||||
<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
main/ui/src/main/resources/fxml/recoverykey_display.fxml
Normal file
42
main/ui/src/main/resources/fxml/recoverykey_display.fxml
Normal file
@@ -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>
|
||||
Reference in New Issue
Block a user