mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-17 10:11:27 +00:00
Merge branch 'feature/NewMigrationFlow' into develop
This commit is contained in:
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
@@ -32,9 +32,9 @@
|
||||
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlinx/kotlinx-metadata-jvm/0.1.0/kotlinx-metadata-jvm-0.1.0.jar" />
|
||||
</processorPath>
|
||||
<module name="keychain" />
|
||||
<module name="launcher" />
|
||||
<module name="commons" />
|
||||
<module name="ui" />
|
||||
<module name="launcher" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
|
||||
3
.idea/runConfigurations/Cryptomator_macOS.xml
generated
3
.idea/runConfigurations/Cryptomator_macOS.xml
generated
@@ -1,5 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Cryptomator macOS" type="Application" factoryName="Application">
|
||||
<envs>
|
||||
<env name="LD_LIBRARY_PATH" value="/usr/local/lib" />
|
||||
</envs>
|
||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||
<module name="launcher" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
|
||||
@@ -9,23 +9,20 @@ import com.google.common.base.Strings;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import javafx.beans.Observable;
|
||||
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.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* The settings specific to a single vault.
|
||||
@@ -38,6 +35,7 @@ public class VaultSettings {
|
||||
public static final boolean DEFAULT_USES_INDIVIDUAL_MOUNTPATH = false;
|
||||
public static final boolean DEFAULT_USES_READONLY_MODE = false;
|
||||
public static final String DEFAULT_MOUNT_FLAGS = "";
|
||||
public static final int DEFAULT_FILENAME_LENGTH_LIMIT = -1;
|
||||
|
||||
private static final Random RNG = new Random();
|
||||
|
||||
@@ -51,6 +49,7 @@ public class VaultSettings {
|
||||
private final StringProperty individualMountPath = new SimpleStringProperty();
|
||||
private final BooleanProperty usesReadOnlyMode = new SimpleBooleanProperty(DEFAULT_USES_READONLY_MODE);
|
||||
private final StringProperty mountFlags = new SimpleStringProperty(DEFAULT_MOUNT_FLAGS);
|
||||
private final IntegerProperty filenameLengthLimit = new SimpleIntegerProperty(DEFAULT_FILENAME_LENGTH_LIMIT);
|
||||
|
||||
public VaultSettings(String id) {
|
||||
this.id = Objects.requireNonNull(id);
|
||||
@@ -59,7 +58,7 @@ public class VaultSettings {
|
||||
}
|
||||
|
||||
Observable[] observables() {
|
||||
return new Observable[]{path, mountName, winDriveLetter, unlockAfterStartup, revealAfterMount, usesIndividualMountPath, individualMountPath, usesReadOnlyMode, mountFlags};
|
||||
return new Observable[]{path, mountName, winDriveLetter, unlockAfterStartup, revealAfterMount, usesIndividualMountPath, individualMountPath, usesReadOnlyMode, mountFlags, filenameLengthLimit};
|
||||
}
|
||||
|
||||
private void deriveMountNameFromPath(Path path) {
|
||||
@@ -146,6 +145,10 @@ public class VaultSettings {
|
||||
public StringProperty mountFlags() {
|
||||
return mountFlags;
|
||||
}
|
||||
|
||||
public IntegerProperty filenameLengthLimit() {
|
||||
return filenameLengthLimit;
|
||||
}
|
||||
|
||||
/* Hashcode/Equals */
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ class VaultSettingsJsonAdapter {
|
||||
out.name("individualMountPath").value(value.individualMountPath().get());
|
||||
out.name("usesReadOnlyMode").value(value.usesReadOnlyMode().get());
|
||||
out.name("mountFlags").value(value.mountFlags().get());
|
||||
out.name("filenameLengthLimit").value(value.filenameLengthLimit().get());
|
||||
out.endObject();
|
||||
}
|
||||
|
||||
@@ -43,6 +44,7 @@ class VaultSettingsJsonAdapter {
|
||||
boolean usesIndividualMountPath = VaultSettings.DEFAULT_USES_INDIVIDUAL_MOUNTPATH;
|
||||
boolean usesReadOnlyMode = VaultSettings.DEFAULT_USES_READONLY_MODE;
|
||||
String mountFlags = VaultSettings.DEFAULT_MOUNT_FLAGS;
|
||||
int filenameLengthLimit = VaultSettings.DEFAULT_FILENAME_LENGTH_LIMIT;
|
||||
|
||||
in.beginObject();
|
||||
while (in.hasNext()) {
|
||||
@@ -78,6 +80,9 @@ class VaultSettingsJsonAdapter {
|
||||
case "mountFlags":
|
||||
mountFlags = in.nextString();
|
||||
break;
|
||||
case "filenameLengthLimit":
|
||||
filenameLengthLimit = in.nextInt();
|
||||
break;
|
||||
default:
|
||||
LOG.warn("Unsupported vault setting found in JSON: " + name);
|
||||
in.skipValue();
|
||||
@@ -96,6 +101,7 @@ class VaultSettingsJsonAdapter {
|
||||
vaultSettings.individualMountPath().set(individualMountPath);
|
||||
vaultSettings.usesReadOnlyMode().set(usesReadOnlyMode);
|
||||
vaultSettings.mountFlags().set(mountFlags);
|
||||
vaultSettings.filenameLengthLimit().set(filenameLengthLimit);
|
||||
return vaultSettings;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ import org.cryptomator.cryptofs.CryptoFileSystem;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystemProperties.FileSystemFlags;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||
import org.cryptomator.cryptofs.common.Constants;
|
||||
import org.cryptomator.cryptofs.common.FileSystemCapabilityChecker;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
|
||||
import org.slf4j.Logger;
|
||||
@@ -101,10 +103,19 @@ public class Vault {
|
||||
if (vaultSettings.usesReadOnlyMode().get()) {
|
||||
flags.add(FileSystemFlags.READONLY);
|
||||
}
|
||||
if (vaultSettings.filenameLengthLimit().get() == -1) {
|
||||
LOG.debug("Determining file name length limitations...");
|
||||
int limit = new FileSystemCapabilityChecker().determineSupportedFileNameLength(getPath());
|
||||
vaultSettings.filenameLengthLimit().set(limit);
|
||||
LOG.info("Storing file name length limit of {}", limit);
|
||||
}
|
||||
assert vaultSettings.filenameLengthLimit().get() > 0;
|
||||
CryptoFileSystemProperties fsProps = CryptoFileSystemProperties.cryptoFileSystemProperties() //
|
||||
.withPassphrase(passphrase) //
|
||||
.withFlags(flags) //
|
||||
.withMasterkeyFilename(MASTERKEY_FILENAME) //
|
||||
.withMaxPathLength(vaultSettings.filenameLengthLimit().get() + Constants.MAX_ADDITIONAL_PATH_LENGTH) //
|
||||
.withMaxNameLength(vaultSettings.filenameLengthLimit().get()) //
|
||||
.build();
|
||||
return CryptoFileSystemProvider.newFileSystem(getPath(), fsProps);
|
||||
}
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<!-- cryptomator dependencies -->
|
||||
<cryptomator.cryptofs.version>1.9.7</cryptomator.cryptofs.version>
|
||||
<cryptomator.cryptofs.version>1.9.9</cryptomator.cryptofs.version>
|
||||
<cryptomator.jni.version>2.2.2</cryptomator.jni.version>
|
||||
<cryptomator.fuse.version>1.2.3</cryptomator.fuse.version>
|
||||
<cryptomator.dokany.version>1.1.13</cryptomator.dokany.version>
|
||||
<cryptomator.webdav.version>1.0.10</cryptomator.webdav.version>
|
||||
<cryptomator.dokany.version>1.1.14</cryptomator.dokany.version>
|
||||
<cryptomator.webdav.version>1.0.11</cryptomator.webdav.version>
|
||||
|
||||
<!-- 3rd party dependencies -->
|
||||
<javafx.version>14</javafx.version>
|
||||
|
||||
@@ -13,6 +13,7 @@ public enum FxmlFile {
|
||||
FORGET_PASSWORD("/fxml/forget_password.fxml"), //
|
||||
MAIN_WINDOW("/fxml/main_window.fxml"), //
|
||||
MIGRATION_CAPABILITY_ERROR("/fxml/migration_capability_error.fxml"), //
|
||||
MIGRATION_IMPOSSIBLE("/fxml/migration_impossible.fxml"),
|
||||
MIGRATION_RUN("/fxml/migration_run.fxml"), //
|
||||
MIGRATION_START("/fxml/migration_start.fxml"), //
|
||||
MIGRATION_SUCCESS("/fxml/migration_success.fxml"), //
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.cryptomator.ui.migration;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.stage.Stage;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.fxapp.FxApplication;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class MigrationImpossibleController implements FxController {
|
||||
|
||||
private static final String HELP_URI = "https://docs.cryptomator.org/en/1.5/help/manual-migration/";
|
||||
|
||||
private final FxApplication fxApplication;
|
||||
private final Stage window;
|
||||
private final Vault vault;
|
||||
|
||||
@Inject
|
||||
MigrationImpossibleController(FxApplication fxApplication, @MigrationWindow Stage window, @MigrationWindow Vault vault) {
|
||||
this.fxApplication = fxApplication;
|
||||
this.window = window;
|
||||
this.vault = vault;
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void close() {
|
||||
window.close();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void getMigrationHelp() {
|
||||
fxApplication.getHostServices().showDocument(HELP_URI);
|
||||
}
|
||||
|
||||
/* Getter/Setters */
|
||||
|
||||
public Vault getVault() {
|
||||
return vault;
|
||||
}
|
||||
|
||||
public String getHelpUri() {
|
||||
return HELP_URI;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -83,6 +83,13 @@ abstract class MigrationModule {
|
||||
return fxmlLoaders.createScene("/fxml/migration_capability_error.fxml");
|
||||
}
|
||||
|
||||
@Provides
|
||||
@FxmlScene(FxmlFile.MIGRATION_IMPOSSIBLE)
|
||||
@MigrationScoped
|
||||
static Scene provideMigrationImpossibleScene(@MigrationWindow FXMLLoaderFactory fxmlLoaders) {
|
||||
return fxmlLoaders.createScene("/fxml/migration_impossible.fxml");
|
||||
}
|
||||
|
||||
// ------------------
|
||||
|
||||
@Binds
|
||||
@@ -104,5 +111,9 @@ abstract class MigrationModule {
|
||||
@IntoMap
|
||||
@FxControllerKey(MigrationCapabilityErrorController.class)
|
||||
abstract FxController bindMigrationCapabilityErrorController(MigrationCapabilityErrorController controller);
|
||||
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FxControllerKey(MigrationImpossibleController.class)
|
||||
abstract FxController bindMigrationImpossibleController(MigrationImpossibleController controller);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,10 @@ import javafx.scene.control.ContentDisplay;
|
||||
import javafx.stage.Stage;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultState;
|
||||
import org.cryptomator.cryptofs.FileNameTooLongException;
|
||||
import org.cryptomator.cryptofs.common.FileSystemCapabilityChecker;
|
||||
import org.cryptomator.cryptofs.migration.Migrators;
|
||||
import org.cryptomator.cryptofs.migration.api.MigrationContinuationListener;
|
||||
import org.cryptomator.cryptofs.migration.api.MigrationProgressListener;
|
||||
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
|
||||
import org.cryptomator.keychain.KeychainAccess;
|
||||
@@ -58,6 +60,7 @@ public class MigrationRunController implements FxController {
|
||||
private final ErrorComponent.Builder errorComponent;
|
||||
private final Lazy<Scene> startScene;
|
||||
private final Lazy<Scene> successScene;
|
||||
private final Lazy<Scene> impossibleScene;
|
||||
private final ObjectBinding<ContentDisplay> migrateButtonContentDisplay;
|
||||
private final Lazy<Scene> capabilityErrorScene;
|
||||
private final BooleanProperty migrationButtonDisabled;
|
||||
@@ -66,7 +69,8 @@ public class MigrationRunController implements FxController {
|
||||
public NiceSecurePasswordField passwordField;
|
||||
|
||||
@Inject
|
||||
public MigrationRunController(@MigrationWindow Stage window, @MigrationWindow Vault vault, ExecutorService executor, ScheduledExecutorService scheduler, Optional<KeychainAccess> keychainAccess, @Named("capabilityErrorCause") ObjectProperty<FileSystemCapabilityChecker.Capability> missingCapability, @FxmlScene(FxmlFile.MIGRATION_START) Lazy<Scene> startScene, @FxmlScene(FxmlFile.MIGRATION_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.MIGRATION_CAPABILITY_ERROR) Lazy<Scene> capabilityErrorScene, ErrorComponent.Builder errorComponent) {
|
||||
public MigrationRunController(@MigrationWindow Stage window, @MigrationWindow Vault vault, ExecutorService executor, ScheduledExecutorService scheduler, Optional<KeychainAccess> keychainAccess, @Named("capabilityErrorCause") ObjectProperty<FileSystemCapabilityChecker.Capability> missingCapability, @FxmlScene(FxmlFile.MIGRATION_START) Lazy<Scene> startScene, @FxmlScene(FxmlFile.MIGRATION_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.MIGRATION_CAPABILITY_ERROR) Lazy<Scene> capabilityErrorScene, @FxmlScene(FxmlFile.MIGRATION_IMPOSSIBLE) Lazy<Scene> impossibleScene, ErrorComponent.Builder errorComponent) {
|
||||
|
||||
this.window = window;
|
||||
this.vault = vault;
|
||||
this.executor = executor;
|
||||
@@ -80,6 +84,7 @@ public class MigrationRunController implements FxController {
|
||||
this.capabilityErrorScene = capabilityErrorScene;
|
||||
this.migrationButtonDisabled = new SimpleBooleanProperty();
|
||||
this.migrationProgress = new SimpleDoubleProperty(volatileMigrationProgress);
|
||||
this.impossibleScene = impossibleScene;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
@@ -107,7 +112,7 @@ public class MigrationRunController implements FxController {
|
||||
}, 0, MIGRATION_PROGRESS_UPDATE_MILLIS, TimeUnit.MILLISECONDS);
|
||||
Tasks.create(() -> {
|
||||
Migrators migrators = Migrators.get();
|
||||
migrators.migrate(vault.getPath(), MASTERKEY_FILENAME, password, this::migrationProgressChanged);
|
||||
migrators.migrate(vault.getPath(), MASTERKEY_FILENAME, password, this::migrationProgressChanged, this::migrationRequiresInput);
|
||||
return migrators.needsMigration(vault.getPath(), MASTERKEY_FILENAME);
|
||||
}).onSuccess(needsAnotherMigration -> {
|
||||
if (needsAnotherMigration) {
|
||||
@@ -127,9 +132,14 @@ public class MigrationRunController implements FxController {
|
||||
vault.setState(VaultState.NEEDS_MIGRATION);
|
||||
}).onError(FileSystemCapabilityChecker.MissingCapabilityException.class, e -> {
|
||||
LOG.error("Underlying file system not supported.", e);
|
||||
vault.setState(VaultState.ERROR);
|
||||
vault.setState(VaultState.NEEDS_MIGRATION);
|
||||
missingCapability.set(e.getMissingCapability());
|
||||
window.setScene(capabilityErrorScene.get());
|
||||
}).onError(FileNameTooLongException.class, e -> {
|
||||
LOG.error("Migration failed because the underlying file system does not support long filenames.", e);
|
||||
vault.setState(VaultState.NEEDS_MIGRATION);
|
||||
errorComponent.cause(e).window(window).returnToScene(startScene.get()).build().showErrorScene();
|
||||
window.setScene(impossibleScene.get());
|
||||
}).onError(Exception.class, e -> { // including RuntimeExceptions
|
||||
LOG.error("Migration failed for technical reasons.", e);
|
||||
vault.setState(VaultState.NEEDS_MIGRATION);
|
||||
@@ -149,6 +159,13 @@ public class MigrationRunController implements FxController {
|
||||
};
|
||||
}
|
||||
|
||||
private MigrationContinuationListener.ContinuationResult migrationRequiresInput(MigrationContinuationListener.ContinuationEvent event) {
|
||||
//TODO: creating a new scene seems a little over the top, maybe stick to this scene
|
||||
// my suggestion is to make this quick and dirty by setting some elements unmanaged and invisible and afterwards activate them again
|
||||
// otherwise: We need a more abstract runController which has two subviews (run and halted), see mainWindow for example
|
||||
return MigrationContinuationListener.ContinuationResult.PROCEED;
|
||||
}
|
||||
|
||||
private void loadStoredPassword() {
|
||||
assert keychainAccess.isPresent();
|
||||
char[] storedPw = null;
|
||||
|
||||
@@ -73,7 +73,7 @@ public class UnlockController implements FxController {
|
||||
if (keychainAccess.isPresent()) {
|
||||
loadStoredPassword();
|
||||
} else {
|
||||
savePassword.setDisable(true);
|
||||
savePassword.setSelected(false);
|
||||
}
|
||||
unlockButtonDisabled.bind(vault.stateProperty().isNotEqualTo(VaultState.LOCKED).or(passwordField.textProperty().isEmpty()));
|
||||
}
|
||||
@@ -187,4 +187,8 @@ public class UnlockController implements FxController {
|
||||
public boolean isUnlockButtonDisabled() {
|
||||
return unlockButtonDisabled.get();
|
||||
}
|
||||
|
||||
public boolean isKeychainAccessAvailable() {
|
||||
return keychainAccess.isPresent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -854,7 +854,7 @@
|
||||
.progress-bar > .bar {
|
||||
-fx-background-color: CONTROL_PRIMARY_BG_NORMAL;
|
||||
-fx-background-radius: 4px;
|
||||
-fx-padding: 0.5em;
|
||||
-fx-padding: 1em 0.5em;
|
||||
}
|
||||
|
||||
.progress-bar:indeterminate > .bar {
|
||||
|
||||
@@ -853,7 +853,7 @@
|
||||
.progress-bar > .bar {
|
||||
-fx-background-color: CONTROL_PRIMARY_BG_NORMAL;
|
||||
-fx-background-radius: 4px;
|
||||
-fx-padding: 0.5em;
|
||||
-fx-padding: 1em 0.5em;
|
||||
}
|
||||
|
||||
.progress-bar:indeterminate > .bar {
|
||||
|
||||
52
main/ui/src/main/resources/fxml/migration_impossible.fxml
Normal file
52
main/ui/src/main/resources/fxml/migration_impossible.fxml
Normal file
@@ -0,0 +1,52 @@
|
||||
<?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.Hyperlink?>
|
||||
<?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 javafx.scene.text.Text?>
|
||||
<?import javafx.scene.text.TextFlow?>
|
||||
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||
<VBox xmlns="http://javafx.com/javafx"
|
||||
xmlns:fx="http://javafx.com/fxml"
|
||||
fx:controller="org.cryptomator.ui.migration.MigrationImpossibleController"
|
||||
minWidth="400"
|
||||
maxWidth="400"
|
||||
minHeight="145"
|
||||
spacing="12">
|
||||
<padding>
|
||||
<Insets topRightBottomLeft="12"/>
|
||||
</padding>
|
||||
|
||||
<HBox spacing="12" alignment="CENTER_LEFT" VBox.vgrow="ALWAYS">
|
||||
<StackPane alignment="CENTER" HBox.hgrow="NEVER">
|
||||
<Circle styleClass="glyph-icon-red" radius="24"/>
|
||||
<FontAwesome5IconView styleClass="glyph-icon-white" glyph="TIMES" glyphSize="24"/>
|
||||
</StackPane>
|
||||
<VBox spacing="6">
|
||||
<Label styleClass="label-large" text="%migration.impossible.heading"/>
|
||||
<Label text="%migration.impossible.reason" wrapText="true" HBox.hgrow="ALWAYS"/>
|
||||
<TextFlow>
|
||||
<Text text="%migration.impossible.moreInfo"/>
|
||||
<Text text=" "/>
|
||||
<Hyperlink styleClass="hyperlink-underline" text="docs.cryptomator.org" wrapText="true" onAction="#getMigrationHelp"/>
|
||||
<Text text="."/>
|
||||
</TextFlow>
|
||||
</VBox>
|
||||
</HBox>
|
||||
|
||||
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+C">
|
||||
<buttons>
|
||||
<!-- Button text="Try again" ButtonBar.buttonData="to do" onAction="#retry" / also add button to button bar order-->
|
||||
<Button text="%generic.button.close" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
</VBox>
|
||||
</VBox>
|
||||
@@ -3,6 +3,7 @@
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ButtonBar?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ProgressBar?>
|
||||
<?import javafx.scene.control.ProgressIndicator?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
@@ -19,17 +20,20 @@
|
||||
<Insets topRightBottomLeft="12"/>
|
||||
</padding>
|
||||
<children>
|
||||
<VBox spacing="6">
|
||||
<VBox spacing="6" visible="${!controller.vault.processing}" managed="${!controller.vault.processing}">
|
||||
<FormattedLabel format="%migration.run.enterPassword" arg1="${controller.vault.displayableName}" wrapText="true"/>
|
||||
<NiceSecurePasswordField fx:id="passwordField"/>
|
||||
</VBox>
|
||||
|
||||
<ProgressBar progress="${controller.migrationProgress}" prefWidth="Infinity" visible="${controller.vault.processing}"/>
|
||||
<VBox spacing="6" visible="${controller.vault.processing}" managed="${controller.vault.processing}">
|
||||
<Label text="%migration.run.progressHint" wrapText="true"/>
|
||||
<ProgressBar progress="${controller.migrationProgress}" prefWidth="Infinity"/>
|
||||
</VBox>
|
||||
|
||||
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="B+X">
|
||||
<buttons>
|
||||
<Button text="%generic.button.back" ButtonBar.buttonData="BACK_PREVIOUS" cancelButton="true" onAction="#back"/>
|
||||
<Button text="%generic.button.back" ButtonBar.buttonData="BACK_PREVIOUS" cancelButton="true" onAction="#back" disable="${controller.vault.processing}"/>
|
||||
<Button text="%migration.run.startMigrationBtn" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#migrate" contentDisplay="${controller.migrateButtonContentDisplay}"
|
||||
disable="${controller.migrationButtonDisabled}">
|
||||
<graphic>
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
<VBox spacing="6">
|
||||
<FormattedLabel format="%unlock.passwordPrompt" arg1="${controller.vault.displayableName}" wrapText="true"/>
|
||||
<NiceSecurePasswordField fx:id="passwordField"/>
|
||||
<CheckBox fx:id="savePassword" text="%unlock.savePassword" onAction="#didClickSavePasswordCheckbox"/>
|
||||
<CheckBox fx:id="savePassword" text="%unlock.savePassword" onAction="#didClickSavePasswordCheckbox" disable="${controller.vault.processing}" visible="${controller.keychainAccessAvailable}"/>
|
||||
</VBox>
|
||||
|
||||
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+CI">
|
||||
<buttons>
|
||||
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#cancel"/>
|
||||
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#cancel" disable="${controller.vault.processing}"/>
|
||||
<Button text="%unlock.unlockBtn" ButtonBar.buttonData="FINISH" defaultButton="true" onAction="#unlock" contentDisplay="${controller.unlockButtonState}" disable="${controller.unlockButtonDisabled}">
|
||||
<graphic>
|
||||
<ProgressIndicator progress="-1" prefWidth="12" prefHeight="12"/>
|
||||
|
||||
@@ -108,6 +108,7 @@ migration.start.confirm=Yes, my vault is fully synced
|
||||
## Run
|
||||
migration.run.enterPassword=Enter the password for "%s"
|
||||
migration.run.startMigrationBtn=Migrate Vault
|
||||
migration.run.progressHint=This might take some time…
|
||||
## Sucess
|
||||
migration.success.nextStepsInstructions=Migrated "%s" successfully.\nYou can now unlock your vault.
|
||||
migration.success.unlockNow=Unlock Now
|
||||
@@ -118,6 +119,10 @@ migration.error.missingFileSystemCapabilities.reason.LONG_FILENAMES=The file sys
|
||||
migration.error.missingFileSystemCapabilities.reason.LONG_PATHS=The file system does not support long paths.
|
||||
migration.error.missingFileSystemCapabilities.reason.READ_ACCESS=The file system does not allow to be read.
|
||||
migration.error.missingFileSystemCapabilities.reason.WRITE_ACCESS=The file system does not allow to be written to.
|
||||
## Impossible
|
||||
migration.impossible.heading=Unable to migrate vault
|
||||
migration.impossible.reason=The vault cannot be automatically migrated because its storage location or access point is not compatible.
|
||||
migration.impossible.moreInfo=The vault can still be opened with an older version. For instructions on how to manually migrate a vault, visit
|
||||
|
||||
# Preferences
|
||||
preferences.title=Preferences
|
||||
|
||||
@@ -11,7 +11,7 @@ GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
Cryptomator uses 49 third-party dependencies under the following licenses:
|
||||
Cryptomator uses 50 third-party dependencies under the following licenses:
|
||||
Apache License v2.0:
|
||||
- HKDF-RFC5869 (at.favre.lib:hkdf:1.0.2 - https://github.com/patrickfav/hkdf)
|
||||
- jffi (com.github.jnr:jffi:1.2.23 - http://github.com/jnr/jffi)
|
||||
@@ -32,15 +32,16 @@ Cryptomator uses 49 third-party dependencies under the following licenses:
|
||||
- Java Native Access (net.java.dev.jna:jna:5.1.0 - https://github.com/java-native-access/jna)
|
||||
- Java Native Access Platform (net.java.dev.jna:jna-platform:5.1.0 - https://github.com/java-native-access/jna)
|
||||
- Apache Commons Lang (org.apache.commons:commons-lang3:3.9 - http://commons.apache.org/proper/commons-lang/)
|
||||
- Jackrabbit WebDAV Library (org.apache.jackrabbit:jackrabbit-webdav:2.19.0 - http://jackrabbit.apache.org/jackrabbit-webdav/)
|
||||
- Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Apache HttpCore (org.apache.httpcomponents:httpcore:4.4.13 - http://hc.apache.org/httpcomponents-core-ga)
|
||||
- Jackrabbit WebDAV Library (org.apache.jackrabbit:jackrabbit-webdav:2.21.0 - http://jackrabbit.apache.org/jackrabbit-webdav/)
|
||||
- Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
BSD:
|
||||
- asm (org.ow2.asm:asm:7.1 - http://asm.ow2.org/)
|
||||
- asm-analysis (org.ow2.asm:asm-analysis:7.1 - http://asm.ow2.org/)
|
||||
@@ -48,14 +49,14 @@ Cryptomator uses 49 third-party dependencies under the following licenses:
|
||||
- asm-tree (org.ow2.asm:asm-tree:7.1 - http://asm.ow2.org/)
|
||||
- asm-util (org.ow2.asm:asm-util:7.1 - http://asm.ow2.org/)
|
||||
Eclipse Public License - Version 1.0:
|
||||
- Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.17.v20190418 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
- Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
||||
Eclipse Public License - v 2.0:
|
||||
- jnr-posix (com.github.jnr:jnr-posix:3.0.54 - http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix)
|
||||
GPLv2:
|
||||
|
||||
Reference in New Issue
Block a user