diff --git a/README.md b/README.md index 63c72c421..d5cf5ea8e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build](https://github.com/cryptomator/cryptomator/workflows/Build/badge.svg)](https://github.com/cryptomator/cryptomator/actions?query=workflow%3ABuild) [![Known Vulnerabilities](https://snyk.io/test/github/cryptomator/cryptomator/badge.svg?targetFile=main%2Fpom.xml)](https://snyk.io/test/github/cryptomator/cryptomator?targetFile=main%2Fpom.xml) -[![Codacy Badge](https://api.codacy.com/project/badge/Grade/2a0adf3cec6a4143b91035d3924178f1)](https://www.codacy.com/app/cryptomator/cryptomator?utm_source=github.com&utm_medium=referral&utm_content=cryptomator/cryptomator&utm_campaign=Badge_Grade) +[![Codacy Badge](https://app.codacy.com/project/badge/Grade/2a0adf3cec6a4143b91035d3924178f1)](https://www.codacy.com/gh/cryptomator/cryptomator/dashboard) [![Twitter](https://img.shields.io/badge/twitter-@Cryptomator-blue.svg?style=flat)](http://twitter.com/Cryptomator) [![Crowdin](https://badges.crowdin.net/cryptomator/localized.svg)](https://translate.cryptomator.org/) [![Latest Release](https://img.shields.io/github/release/cryptomator/cryptomator.svg)](https://github.com/cryptomator/cryptomator/releases/latest) @@ -17,11 +17,26 @@ Cryptomator is provided free of charge as an open-source project despite the hig ### Gold Sponsors -[gee-whiz](https://www.gee-whiz.de/) + + + + + + + +
gee-whizProxy-Hub
### Silver Sponsors -[![TheBestVPN](https://cryptomator.org/img/sponsors/thebestvpn.png)](https://thebestvpn.com/) + + + + + + +
TheBestVPN
+ +- [Jameson Lopp](https://www.lopp.net/) --- diff --git a/main/commons/src/main/java/org/cryptomator/common/vaults/FuseVolume.java b/main/commons/src/main/java/org/cryptomator/common/vaults/FuseVolume.java index 5400f8ff2..9af77408c 100644 --- a/main/commons/src/main/java/org/cryptomator/common/vaults/FuseVolume.java +++ b/main/commons/src/main/java/org/cryptomator/common/vaults/FuseVolume.java @@ -45,7 +45,9 @@ public class FuseVolume extends AbstractVolume { try { Mounter mounter = FuseMountFactory.getMounter(); EnvironmentVariables envVars = EnvironmentVariables.create() // - .withFlags(splitFlags(mountFlags)).withMountPoint(mountPoint) // + .withFlags(splitFlags(mountFlags)) // + .withMountPoint(mountPoint) // + .withFileNameTranscoder(mounter.defaultFileNameTranscoder()) // .build(); this.mount = mounter.mount(root, envVars); } catch (CommandFailedException | FuseNotSupportedException e) { diff --git a/main/pom.xml b/main/pom.xml index 3930a3931..ddd4262ec 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -30,14 +30,14 @@ 1.0.0-beta2 1.0.0-beta2 1.0.0-beta1 - 1.2.9 + 1.3.0 1.2.4 - 1.1.4 + 1.2.0 15 3.11 - 3.12.0 + 3.13.0 2.1.0 30.1-jre 2.32 @@ -218,12 +218,6 @@ test - - - com.fasterxml.jackson.core - jackson-databind - 2.10.5.1 - diff --git a/main/suppression.xml b/main/suppression.xml index 6fe12f417..43acf2e8d 100644 --- a/main/suppression.xml +++ b/main/suppression.xml @@ -1,11 +1,6 @@ - - - com.fasterxml.jackson.core:jackson-databind:2.10.5.1 - CVE-2020-25649 - ^org\.cryptomator:fuse-nio-adapter:.*$ diff --git a/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java b/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java index 73c04fe5f..917e704fc 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java +++ b/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java @@ -86,7 +86,7 @@ public class FxApplication extends Application { } private void hasVisibleStagesChanged(@SuppressWarnings("unused") ObservableValue observableValue, @SuppressWarnings("unused") boolean oldValue, boolean newValue) { - LOG.warn("has visible stages: {}", newValue); + LOG.debug("has visible stages: {}", newValue); if (newValue) { trayIntegration.ifPresent(TrayIntegrationProvider::restoredFromTray); } else { diff --git a/main/ui/src/main/java/org/cryptomator/ui/fxapp/UpdateCheckerModule.java b/main/ui/src/main/java/org/cryptomator/ui/fxapp/UpdateCheckerModule.java index 596e704e9..ef8621f3b 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/fxapp/UpdateCheckerModule.java +++ b/main/ui/src/main/java/org/cryptomator/ui/fxapp/UpdateCheckerModule.java @@ -15,6 +15,7 @@ import javafx.beans.property.StringProperty; import javafx.concurrent.ScheduledService; import javafx.concurrent.Task; import javafx.util.Duration; +import java.io.UncheckedIOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; @@ -39,8 +40,13 @@ public abstract class UpdateCheckerModule { @Provides @FxApplicationScoped - static HttpClient provideHttpClient() { - return HttpClient.newHttpClient(); + static Optional provideHttpClient() { + try { + return Optional.of(HttpClient.newHttpClient()); + } catch (UncheckedIOException e) { + LOG.error("HttpClient for update check cannot be created.", e); + return Optional.empty(); + } } @Provides @@ -66,11 +72,20 @@ public abstract class UpdateCheckerModule { @Provides @FxApplicationScoped - static ScheduledService provideCheckForUpdatesService(ExecutorService executor, HttpClient httpClient, HttpRequest checkForUpdatesRequest, @Named("checkForUpdatesInterval") ObjectBinding period) { + static ScheduledService provideCheckForUpdatesService(ExecutorService executor, Optional httpClient, HttpRequest checkForUpdatesRequest, @Named("checkForUpdatesInterval") ObjectBinding period) { ScheduledService service = new ScheduledService<>() { @Override protected Task createTask() { - return new UpdateCheckerTask(httpClient, checkForUpdatesRequest); + if (httpClient.isPresent()) { + return new UpdateCheckerTask(httpClient.get(), checkForUpdatesRequest); + } else { + return new Task<>() { + @Override + protected String call() { + throw new NullPointerException("No HttpClient present."); + } + }; + } } }; service.setOnFailed(event -> LOG.error("Failed to execute update service", service.getException())); diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoading.java b/main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoading.java similarity index 72% rename from main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoading.java rename to main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoading.java index 2d7a8a921..51f9302c8 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoading.java +++ b/main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoading.java @@ -1,4 +1,4 @@ -package org.cryptomator.ui.unlock.masterkeyfile; +package org.cryptomator.ui.keyloading; import javax.inject.Qualifier; import java.lang.annotation.Documented; @@ -9,6 +9,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; @Qualifier @Documented @Retention(RUNTIME) -@interface MasterkeyFileLoading { +public @interface KeyLoading { } diff --git a/main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoadingComponent.java b/main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoadingComponent.java new file mode 100644 index 000000000..fc274d2a7 --- /dev/null +++ b/main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoadingComponent.java @@ -0,0 +1,28 @@ +package org.cryptomator.ui.keyloading; + +import dagger.BindsInstance; +import dagger.Subcomponent; +import org.cryptomator.common.vaults.Vault; + +import javafx.stage.Stage; + +@KeyLoadingScoped +@Subcomponent(modules = {KeyLoadingModule.class}) +public interface KeyLoadingComponent { + + @KeyLoading + KeyLoadingStrategy keyloadingStrategy(); + + @Subcomponent.Builder + interface Builder { + + @BindsInstance + Builder vault(@KeyLoading Vault vault); + + @BindsInstance + Builder window(@KeyLoading Stage window); + + KeyLoadingComponent build(); + } + +} diff --git a/main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoadingModule.java b/main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoadingModule.java new file mode 100644 index 000000000..6621c5e92 --- /dev/null +++ b/main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoadingModule.java @@ -0,0 +1,48 @@ +package org.cryptomator.ui.keyloading; + +import dagger.Module; +import dagger.Provides; +import org.cryptomator.common.vaults.Vault; +import org.cryptomator.cryptofs.VaultConfig.UnverifiedVaultConfig; +import org.cryptomator.ui.common.DefaultSceneFactory; +import org.cryptomator.ui.common.FxController; +import org.cryptomator.ui.common.FxmlLoaderFactory; +import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingModule; + +import javax.inject.Provider; +import java.net.URI; +import java.util.Map; +import java.util.Optional; +import java.util.ResourceBundle; + +@Module(includes = {MasterkeyFileLoadingModule.class}) +abstract class KeyLoadingModule { + + @Provides + @KeyLoading + @KeyLoadingScoped + static FxmlLoaderFactory provideFxmlLoaderFactory(Map, Provider> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) { + return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle); + } + + @Provides + @KeyLoading + @KeyLoadingScoped + static Optional provideKeyId(@KeyLoading Vault vault) { + return vault.getUnverifiedVaultConfig().map(UnverifiedVaultConfig::getKeyId); + } + + @Provides + @KeyLoading + @KeyLoadingScoped + static KeyLoadingStrategy provideKeyLoaderProvider(@KeyLoading Optional keyId, Map strategies) { + if (keyId.isEmpty()) { + return KeyLoadingStrategy.failed(new IllegalArgumentException("No key id provided")); + } else { + String scheme = keyId.get().getScheme(); + var fallback = KeyLoadingStrategy.failed(new IllegalArgumentException("Unsupported key id " + scheme)); + return strategies.getOrDefault(scheme, fallback); + } + } + +} diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingScoped.java b/main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoadingScoped.java similarity index 70% rename from main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingScoped.java rename to main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoadingScoped.java index 1eeac1e84..5f4355f96 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingScoped.java +++ b/main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoadingScoped.java @@ -1,4 +1,4 @@ -package org.cryptomator.ui.unlock.masterkeyfile; +package org.cryptomator.ui.keyloading; import javax.inject.Scope; import java.lang.annotation.Documented; @@ -8,6 +8,6 @@ import java.lang.annotation.RetentionPolicy; @Scope @Documented @Retention(RetentionPolicy.RUNTIME) -@interface MasterkeyFileLoadingScoped { +public @interface KeyLoadingScoped { } diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/KeyLoadingComponent.java b/main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoadingStrategy.java similarity index 65% rename from main/ui/src/main/java/org/cryptomator/ui/unlock/KeyLoadingComponent.java rename to main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoadingStrategy.java index ec7e8d89b..80f65b6bc 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/KeyLoadingComponent.java +++ b/main/ui/src/main/java/org/cryptomator/ui/keyloading/KeyLoadingStrategy.java @@ -1,10 +1,9 @@ -package org.cryptomator.ui.unlock; +package org.cryptomator.ui.keyloading; import org.cryptomator.cryptolib.api.MasterkeyLoader; import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException; -@FunctionalInterface -public interface KeyLoadingComponent { +public interface KeyLoadingStrategy { /** * @return A reusable masterkey loader, preconfigured with the vault of the current unlock process @@ -32,9 +31,19 @@ public interface KeyLoadingComponent { // no-op } - static KeyLoadingComponent exceptional(Exception exception) { + /** + * A key loading strategy that will always fail by throwing a {@link MasterkeyLoadingFailedException}. + * + * @param exception The cause of the failure. If not alreay an {@link MasterkeyLoadingFailedException}, it will get wrapped. + * @return A new KeyLoadingStrategy that will always fail with an {@link MasterkeyLoadingFailedException}. + */ + static KeyLoadingStrategy failed(Exception exception) { return () -> { - throw new MasterkeyLoadingFailedException("Can not load key", exception); + if (exception instanceof MasterkeyLoadingFailedException e) { + throw e; + } else { + throw new MasterkeyLoadingFailedException("Can not load key", exception); + } }; } diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingContext.java b/main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/MasterkeyFileLoadingContext.java similarity index 72% rename from main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingContext.java rename to main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/MasterkeyFileLoadingContext.java index 298ba1d09..7445d581d 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingContext.java +++ b/main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/MasterkeyFileLoadingContext.java @@ -1,4 +1,4 @@ -package org.cryptomator.ui.unlock.masterkeyfile; +package org.cryptomator.ui.keyloading.masterkeyfile; import dagger.Lazy; import org.cryptomator.cryptolib.api.InvalidPassphraseException; @@ -8,9 +8,9 @@ import org.cryptomator.ui.common.Animations; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; import org.cryptomator.ui.common.UserInteractionLock; +import org.cryptomator.ui.keyloading.KeyLoading; +import org.cryptomator.ui.keyloading.KeyLoadingScoped; import org.cryptomator.ui.unlock.UnlockCancelledException; -import org.cryptomator.ui.unlock.masterkeyfile.MasterkeyFileLoadingModule.MasterkeyFileProvision; -import org.cryptomator.ui.unlock.masterkeyfile.MasterkeyFileLoadingModule.PasswordEntry; import javax.inject.Inject; import javafx.application.Platform; @@ -21,21 +21,21 @@ import java.nio.CharBuffer; import java.nio.file.Path; import java.util.concurrent.atomic.AtomicReference; -@MasterkeyFileLoadingScoped -public class MasterkeyFileLoadingContext implements MasterkeyFileLoaderContext { +@KeyLoadingScoped +class MasterkeyFileLoadingContext implements MasterkeyFileLoaderContext { private final Stage window; private final Lazy passphraseEntryScene; private final Lazy selectMasterkeyFileScene; - private final UserInteractionLock passwordEntryLock; - private final UserInteractionLock masterkeyFileProvisionLock; + private final UserInteractionLock passwordEntryLock; + private final UserInteractionLock masterkeyFileProvisionLock; private final AtomicReference password; private final AtomicReference filePath; private boolean wrongPassword; @Inject - public MasterkeyFileLoadingContext(@MasterkeyFileLoading Stage window, @FxmlScene(FxmlFile.UNLOCK_ENTER_PASSWORD) Lazy passphraseEntryScene, @FxmlScene(FxmlFile.UNLOCK_SELECT_MASTERKEYFILE) Lazy selectMasterkeyFileScene, UserInteractionLock passwordEntryLock, UserInteractionLock masterkeyFileProvisionLock, AtomicReference password, AtomicReference filePath) { + public MasterkeyFileLoadingContext(@KeyLoading Stage window, @FxmlScene(FxmlFile.UNLOCK_ENTER_PASSWORD) Lazy passphraseEntryScene, @FxmlScene(FxmlFile.UNLOCK_SELECT_MASTERKEYFILE) Lazy selectMasterkeyFileScene, UserInteractionLock passwordEntryLock, UserInteractionLock masterkeyFileProvisionLock, AtomicReference password, AtomicReference filePath) { this.window = window; this.passphraseEntryScene = passphraseEntryScene; this.selectMasterkeyFileScene = selectMasterkeyFileScene; @@ -53,7 +53,7 @@ public class MasterkeyFileLoadingContext implements MasterkeyFileLoaderContext { assert filePath.get() == null; try { - if (askForCorrectMasterkeyFile() == MasterkeyFileProvision.MASTERKEYFILE_PROVIDED) { + if (askForCorrectMasterkeyFile() == MasterkeyFileLoadingModule.MasterkeyFileProvision.MASTERKEYFILE_PROVIDED) { return filePath.get(); } else { throw new UnlockCancelledException("Choosing masterkey file cancelled."); @@ -64,7 +64,7 @@ public class MasterkeyFileLoadingContext implements MasterkeyFileLoaderContext { } } - private MasterkeyFileProvision askForCorrectMasterkeyFile() throws InterruptedException { + private MasterkeyFileLoadingModule.MasterkeyFileProvision askForCorrectMasterkeyFile() throws InterruptedException { Platform.runLater(() -> { window.setScene(selectMasterkeyFileScene.get()); window.show(); @@ -87,7 +87,7 @@ public class MasterkeyFileLoadingContext implements MasterkeyFileLoaderContext { assert password.get() == null; try { - if (askForPassphrase() == PasswordEntry.PASSWORD_ENTERED) { + if (askForPassphrase() == MasterkeyFileLoadingModule.PasswordEntry.PASSWORD_ENTERED) { assert password.get() != null; return CharBuffer.wrap(password.get()); } else { @@ -99,7 +99,7 @@ public class MasterkeyFileLoadingContext implements MasterkeyFileLoaderContext { } } - private PasswordEntry askForPassphrase() throws InterruptedException { + private MasterkeyFileLoadingModule.PasswordEntry askForPassphrase() throws InterruptedException { Platform.runLater(() -> { window.setScene(passphraseEntryScene.get()); window.show(); diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingFinisher.java b/main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/MasterkeyFileLoadingFinisher.java similarity index 78% rename from main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingFinisher.java rename to main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/MasterkeyFileLoadingFinisher.java index 8a16d3a12..f872cb697 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingFinisher.java +++ b/main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/MasterkeyFileLoadingFinisher.java @@ -1,8 +1,10 @@ -package org.cryptomator.ui.unlock.masterkeyfile; +package org.cryptomator.ui.keyloading.masterkeyfile; import org.cryptomator.common.keychain.KeychainManager; import org.cryptomator.common.vaults.Vault; import org.cryptomator.integrations.keychain.KeychainAccessException; +import org.cryptomator.ui.keyloading.KeyLoading; +import org.cryptomator.ui.keyloading.KeyLoadingScoped; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,8 +16,8 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -@MasterkeyFileLoadingScoped -public class MasterkeyFileLoadingFinisher { +@KeyLoadingScoped +class MasterkeyFileLoadingFinisher { private static final Logger LOG = LoggerFactory.getLogger(MasterkeyFileLoadingFinisher.class); @@ -26,7 +28,7 @@ public class MasterkeyFileLoadingFinisher { private final KeychainManager keychain; @Inject - MasterkeyFileLoadingFinisher(@MasterkeyFileLoading Vault vault, @Named("savedPassword") Optional storedPassword, AtomicReference enteredPassword, @Named("savePassword")AtomicBoolean shouldSavePassword, KeychainManager keychain) { + MasterkeyFileLoadingFinisher(@KeyLoading Vault vault, @Named("savedPassword") Optional storedPassword, AtomicReference enteredPassword, @Named("savePassword") AtomicBoolean shouldSavePassword, KeychainManager keychain) { this.vault = vault; this.storedPassword = storedPassword; this.enteredPassword = enteredPassword; diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingModule.java b/main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/MasterkeyFileLoadingModule.java similarity index 73% rename from main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingModule.java rename to main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/MasterkeyFileLoadingModule.java index 9c3530357..31b123f53 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingModule.java +++ b/main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/MasterkeyFileLoadingModule.java @@ -1,15 +1,15 @@ -package org.cryptomator.ui.unlock.masterkeyfile; +package org.cryptomator.ui.keyloading.masterkeyfile; import dagger.Binds; import dagger.Module; import dagger.Provides; import dagger.multibindings.IntoMap; +import dagger.multibindings.StringKey; import org.cryptomator.common.keychain.KeychainManager; import org.cryptomator.common.vaults.Vault; import org.cryptomator.cryptolib.common.MasterkeyFileAccess; import org.cryptomator.cryptolib.common.MasterkeyFileLoader; import org.cryptomator.integrations.keychain.KeychainAccessException; -import org.cryptomator.ui.common.DefaultSceneFactory; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxControllerKey; import org.cryptomator.ui.common.FxmlFile; @@ -17,21 +17,21 @@ import org.cryptomator.ui.common.FxmlLoaderFactory; import org.cryptomator.ui.common.FxmlScene; import org.cryptomator.ui.common.UserInteractionLock; import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent; +import org.cryptomator.ui.keyloading.KeyLoading; +import org.cryptomator.ui.keyloading.KeyLoadingScoped; +import org.cryptomator.ui.keyloading.KeyLoadingStrategy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Named; -import javax.inject.Provider; import javafx.scene.Scene; import java.nio.file.Path; -import java.util.Map; import java.util.Optional; -import java.util.ResourceBundle; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; @Module(subcomponents = {ForgetPasswordComponent.class}) -abstract class MasterkeyFileLoadingModule { +public abstract class MasterkeyFileLoadingModule { private static final Logger LOG = LoggerFactory.getLogger(MasterkeyFileLoadingModule.class); @@ -46,27 +46,27 @@ abstract class MasterkeyFileLoadingModule { } @Provides - @MasterkeyFileLoadingScoped - static MasterkeyFileLoader provideMasterkeyFileLoader(MasterkeyFileAccess masterkeyFileAccess, @MasterkeyFileLoading Vault vault, MasterkeyFileLoadingContext context) { + @KeyLoadingScoped + static MasterkeyFileLoader provideMasterkeyFileLoader(MasterkeyFileAccess masterkeyFileAccess, @KeyLoading Vault vault, MasterkeyFileLoadingContext context) { return masterkeyFileAccess.keyLoader(vault.getPath(), context); } @Provides - @MasterkeyFileLoadingScoped + @KeyLoadingScoped static UserInteractionLock providePasswordEntryLock() { return new UserInteractionLock<>(null); } @Provides - @MasterkeyFileLoadingScoped + @KeyLoadingScoped static UserInteractionLock provideMasterkeyFileProvisionLock() { return new UserInteractionLock<>(null); } @Provides @Named("savedPassword") - @MasterkeyFileLoadingScoped - static Optional provideStoredPassword(KeychainManager keychain, @MasterkeyFileLoading Vault vault) { + @KeyLoadingScoped + static Optional provideStoredPassword(KeychainManager keychain, @KeyLoading Vault vault) { if (!keychain.isSupported()) { return Optional.empty(); } else { @@ -80,42 +80,35 @@ abstract class MasterkeyFileLoadingModule { } @Provides - @MasterkeyFileLoadingScoped + @KeyLoadingScoped static AtomicReference provideUserProvidedMasterkeyPath() { return new AtomicReference<>(); } @Provides - @MasterkeyFileLoadingScoped + @KeyLoadingScoped static AtomicReference providePassword(@Named("savedPassword") Optional storedPassword) { return new AtomicReference<>(storedPassword.orElse(null)); } @Provides @Named("savePassword") - @MasterkeyFileLoadingScoped + @KeyLoadingScoped static AtomicBoolean provideSavePasswordFlag(@Named("savedPassword") Optional storedPassword) { return new AtomicBoolean(storedPassword.isPresent()); } - @Provides - @MasterkeyFileLoading - @MasterkeyFileLoadingScoped - static FxmlLoaderFactory provideFxmlLoaderFactory(Map, Provider> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) { - return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle); - } - @Provides @FxmlScene(FxmlFile.UNLOCK_ENTER_PASSWORD) - @MasterkeyFileLoadingScoped - static Scene provideUnlockScene(@MasterkeyFileLoading FxmlLoaderFactory fxmlLoaders) { + @KeyLoadingScoped + static Scene provideUnlockScene(@KeyLoading FxmlLoaderFactory fxmlLoaders) { return fxmlLoaders.createScene(FxmlFile.UNLOCK_ENTER_PASSWORD); } @Provides @FxmlScene(FxmlFile.UNLOCK_SELECT_MASTERKEYFILE) - @MasterkeyFileLoadingScoped - static Scene provideUnlockSelectMasterkeyFileScene(@MasterkeyFileLoading FxmlLoaderFactory fxmlLoaders) { + @KeyLoadingScoped + static Scene provideUnlockSelectMasterkeyFileScene(@KeyLoading FxmlLoaderFactory fxmlLoaders) { return fxmlLoaders.createScene(FxmlFile.UNLOCK_SELECT_MASTERKEYFILE); } @@ -129,5 +122,10 @@ abstract class MasterkeyFileLoadingModule { @FxControllerKey(SelectMasterkeyFileController.class) abstract FxController bindUnlockSelectMasterkeyFileController(SelectMasterkeyFileController controller); + @Binds + @IntoMap + @KeyLoadingScoped + @StringKey("masterkeyfile") + abstract KeyLoadingStrategy bindMasterkeyFileLoadingStrategy(MasterkeyFileLoadingStrategy strategy); } diff --git a/main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/MasterkeyFileLoadingStrategy.java b/main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/MasterkeyFileLoadingStrategy.java new file mode 100644 index 000000000..ae6694198 --- /dev/null +++ b/main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/MasterkeyFileLoadingStrategy.java @@ -0,0 +1,38 @@ +package org.cryptomator.ui.keyloading.masterkeyfile; + +import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException; +import org.cryptomator.cryptolib.common.MasterkeyFileLoader; +import org.cryptomator.ui.keyloading.KeyLoading; +import org.cryptomator.ui.keyloading.KeyLoadingStrategy; + +import javax.inject.Inject; + +@KeyLoading +class MasterkeyFileLoadingStrategy implements KeyLoadingStrategy { + + private final MasterkeyFileLoader masterkeyFileLoader; + private final MasterkeyFileLoadingContext context; + private final MasterkeyFileLoadingFinisher finisher; + + @Inject + public MasterkeyFileLoadingStrategy(MasterkeyFileLoader masterkeyFileLoader, MasterkeyFileLoadingContext context, MasterkeyFileLoadingFinisher finisher) { + this.masterkeyFileLoader = masterkeyFileLoader; + this.context = context; + this.finisher = finisher; + } + + @Override + public MasterkeyFileLoader masterkeyLoader() { + return masterkeyFileLoader; + } + + @Override + public boolean recoverFromException(MasterkeyLoadingFailedException exception) { + return context.recoverFromException(exception); + } + + @Override + public void cleanup(boolean unlockedSuccessfully) { + finisher.cleanup(unlockedSuccessfully); + } +} diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/PassphraseEntryController.java b/main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/PassphraseEntryController.java similarity index 92% rename from main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/PassphraseEntryController.java rename to main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/PassphraseEntryController.java index 914a2a91b..d4356be85 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/PassphraseEntryController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/PassphraseEntryController.java @@ -1,4 +1,4 @@ -package org.cryptomator.ui.unlock.masterkeyfile; +package org.cryptomator.ui.keyloading.masterkeyfile; import org.cryptomator.common.keychain.KeychainManager; import org.cryptomator.common.vaults.Vault; @@ -7,7 +7,9 @@ import org.cryptomator.ui.common.UserInteractionLock; import org.cryptomator.ui.common.WeakBindings; import org.cryptomator.ui.controls.NiceSecurePasswordField; import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent; -import org.cryptomator.ui.unlock.masterkeyfile.MasterkeyFileLoadingModule.PasswordEntry; +import org.cryptomator.ui.keyloading.KeyLoading; +import org.cryptomator.ui.keyloading.KeyLoadingScoped; +import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingModule.PasswordEntry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,7 +41,7 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -@MasterkeyFileLoadingScoped +@KeyLoadingScoped public class PassphraseEntryController implements FxController { private static final Logger LOG = LoggerFactory.getLogger(PassphraseEntryController.class); @@ -67,7 +69,7 @@ public class PassphraseEntryController implements FxController { public Animation unlockAnimation; @Inject - public PassphraseEntryController(@MasterkeyFileLoading Stage window, @MasterkeyFileLoading Vault vault, AtomicReference password, @Named("savePassword") AtomicBoolean savePassword, @Named("savedPassword") Optional savedPassword, UserInteractionLock passwordEntryLock, ForgetPasswordComponent.Builder forgetPassword, KeychainManager keychain) { + public PassphraseEntryController(@KeyLoading Stage window, @KeyLoading Vault vault, AtomicReference password, @Named("savePassword") AtomicBoolean savePassword, @Named("savedPassword") Optional savedPassword, UserInteractionLock passwordEntryLock, ForgetPasswordComponent.Builder forgetPassword, KeychainManager keychain) { this.window = window; this.vault = vault; this.password = password; diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/SelectMasterkeyFileController.java b/main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/SelectMasterkeyFileController.java similarity index 80% rename from main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/SelectMasterkeyFileController.java rename to main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/SelectMasterkeyFileController.java index 62ad5764f..39be2b36e 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/SelectMasterkeyFileController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/SelectMasterkeyFileController.java @@ -1,8 +1,10 @@ -package org.cryptomator.ui.unlock.masterkeyfile; +package org.cryptomator.ui.keyloading.masterkeyfile; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.UserInteractionLock; -import org.cryptomator.ui.unlock.masterkeyfile.MasterkeyFileLoadingModule.MasterkeyFileProvision; +import org.cryptomator.ui.keyloading.KeyLoading; +import org.cryptomator.ui.keyloading.KeyLoadingScoped; +import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingModule.MasterkeyFileProvision; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,7 +18,7 @@ import java.nio.file.Path; import java.util.ResourceBundle; import java.util.concurrent.atomic.AtomicReference; -@MasterkeyFileLoadingScoped +@KeyLoadingScoped public class SelectMasterkeyFileController implements FxController { private static final Logger LOG = LoggerFactory.getLogger(SelectMasterkeyFileController.class); @@ -27,7 +29,7 @@ public class SelectMasterkeyFileController implements FxController { private final ResourceBundle resourceBundle; @Inject - public SelectMasterkeyFileController(@MasterkeyFileLoading Stage window, AtomicReference masterkeyPath, UserInteractionLock masterkeyFileProvisionLock, ResourceBundle resourceBundle) { + public SelectMasterkeyFileController(@KeyLoading Stage window, AtomicReference masterkeyPath, UserInteractionLock masterkeyFileProvisionLock, ResourceBundle resourceBundle) { this.window = window; this.masterkeyPath = masterkeyPath; this.masterkeyFileProvisionLock = masterkeyFileProvisionLock; diff --git a/main/ui/src/main/java/org/cryptomator/ui/launcher/AppLaunchEventHandler.java b/main/ui/src/main/java/org/cryptomator/ui/launcher/AppLaunchEventHandler.java index b8d1f5372..0ab11d374 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/launcher/AppLaunchEventHandler.java +++ b/main/ui/src/main/java/org/cryptomator/ui/launcher/AppLaunchEventHandler.java @@ -1,5 +1,6 @@ package org.cryptomator.ui.launcher; +import org.cryptomator.common.vaults.Vault; import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.ui.fxapp.FxApplication; import org.slf4j.Logger; @@ -55,7 +56,7 @@ class AppLaunchEventHandler { case REVEAL_APP -> fxApplicationStarter.get().thenAccept(FxApplication::showMainWindow); case OPEN_FILE -> fxApplicationStarter.get().thenRun(() -> { Platform.runLater(() -> { - event.getPathsToOpen().forEach(this::addVault); + event.getPathsToOpen().forEach(this::addOrRevealVault); }); }); default -> LOG.warn("Unsupported event type: {}", event.getType()); @@ -63,13 +64,18 @@ class AppLaunchEventHandler { } // TODO dedup MainWindowController... - private void addVault(Path potentialVaultPath) { + private void addOrRevealVault(Path potentialVaultPath) { assert Platform.isFxApplicationThread(); try { + final Vault v; if (potentialVaultPath.getFileName().toString().equals(MASTERKEY_FILENAME)) { - vaultListManager.add(potentialVaultPath.getParent()); + v = vaultListManager.add(potentialVaultPath.getParent()); } else { - vaultListManager.add(potentialVaultPath); + v = vaultListManager.add(potentialVaultPath); + } + + if (v.isUnlocked()) { + fxApplicationStarter.get().thenAccept(app -> app.getVaultService().reveal(v)); } LOG.debug("Added vault {}", potentialVaultPath); } catch (NoSuchFileException e) { diff --git a/main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java index e8aae56fb..90311bd5b 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java +++ b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java @@ -87,6 +87,11 @@ abstract class MainWindowModule { @FxControllerKey(VaultListController.class) abstract FxController bindVaultListController(VaultListController controller); + @Binds + @IntoMap + @FxControllerKey(VaultListContextMenuController.class) + abstract FxController bindVaultListContextMenuController(VaultListContextMenuController controller); + @Binds @IntoMap @FxControllerKey(VaultDetailController.class) diff --git a/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java new file mode 100644 index 000000000..b0866d80f --- /dev/null +++ b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java @@ -0,0 +1,135 @@ +package org.cryptomator.ui.mainwindow; + +import com.tobiasdiez.easybind.EasyBind; +import com.tobiasdiez.easybind.optional.ObservableOptionalValue; +import com.tobiasdiez.easybind.optional.OptionalBinding; +import org.cryptomator.common.keychain.KeychainManager; +import org.cryptomator.common.vaults.Vault; +import org.cryptomator.common.vaults.VaultState; +import org.cryptomator.ui.common.FxController; +import org.cryptomator.ui.fxapp.FxApplication; +import org.cryptomator.ui.removevault.RemoveVaultComponent; +import org.cryptomator.ui.vaultoptions.SelectedVaultOptionsTab; +import org.cryptomator.ui.vaultoptions.VaultOptionsComponent; + +import javax.inject.Inject; +import javafx.beans.binding.Binding; +import javafx.beans.binding.Bindings; +import javafx.beans.property.ObjectProperty; +import javafx.fxml.FXML; +import javafx.stage.Stage; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Optional; + +import static org.cryptomator.common.vaults.VaultState.ERROR; +import static org.cryptomator.common.vaults.VaultState.LOCKED; +import static org.cryptomator.common.vaults.VaultState.MISSING; +import static org.cryptomator.common.vaults.VaultState.NEEDS_MIGRATION; +import static org.cryptomator.common.vaults.VaultState.UNLOCKED; + +@MainWindowScoped +public class VaultListContextMenuController implements FxController { + + private final ObservableOptionalValue selectedVault; + private final Stage mainWindow; + private final FxApplication application; + private final KeychainManager keychain; + private final RemoveVaultComponent.Builder removeVault; + private final VaultOptionsComponent.Builder vaultOptionsWindow; + private final OptionalBinding selectedVaultState; + private final Binding selectedVaultPassphraseStored; + private final Binding selectedVaultRemovable; + private final Binding selectedVaultUnlockable; + private final Binding selectedVaultLockable; + + @Inject + VaultListContextMenuController(ObjectProperty selectedVault, @MainWindow Stage mainWindow, FxApplication application, KeychainManager keychain, RemoveVaultComponent.Builder removeVault, VaultOptionsComponent.Builder vaultOptionsWindow) { + this.selectedVault = EasyBind.wrapNullable(selectedVault); + this.mainWindow = mainWindow; + this.application = application; + this.keychain = keychain; + this.removeVault = removeVault; + this.vaultOptionsWindow = vaultOptionsWindow; + + this.selectedVaultState = this.selectedVault.mapObservable(Vault::stateProperty); + this.selectedVaultPassphraseStored = this.selectedVault.map(this::isPasswordStored).orElse(false); + this.selectedVaultRemovable = selectedVaultState.map(EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION)::contains).orElse(false); + this.selectedVaultUnlockable = selectedVaultState.map(LOCKED::equals).orElse(false); + this.selectedVaultLockable = selectedVaultState.map(UNLOCKED::equals).orElse(false); + + } + + private boolean isPasswordStored(Vault vault) { + return keychain.getPassphraseStoredProperty(vault.getId()).get(); + } + + @FXML + public void didClickRemoveVault() { + selectedVault.ifValuePresent(v -> { + removeVault.vault(v).build().showRemoveVault(); + }); + } + + @FXML + public void didClickShowVaultOptions() { + selectedVault.ifValuePresent(v -> { + vaultOptionsWindow.vault(v).build().showVaultOptionsWindow(SelectedVaultOptionsTab.ANY); + }); + } + + @FXML + public void didClickUnlockVault() { + selectedVault.ifValuePresent(v -> { + application.startUnlockWorkflow(v, Optional.of(mainWindow)); + }); + } + + @FXML + public void didClickLockVault() { + selectedVault.ifValuePresent(v -> { + application.startLockWorkflow(v, Optional.of(mainWindow)); + }); + } + + @FXML + public void didClickRevealVault() { + selectedVault.ifValuePresent(v -> { + application.getVaultService().reveal(v); + }); + } + + // Getter and Setter + + public Binding selectedVaultUnlockableProperty() { + return selectedVaultUnlockable; + } + + public boolean isSelectedVaultUnlockable() { + return selectedVaultUnlockable.getValue(); + } + + public Binding selectedVaultLockableProperty() { + return selectedVaultLockable; + } + + public boolean isSelectedVaultLockable() { + return selectedVaultLockable.getValue(); + } + + public Binding selectedVaultRemovableProperty() { + return selectedVaultRemovable; + } + + public boolean isSelectedVaultRemovable() { + return selectedVaultRemovable.getValue(); + } + + public Binding selectedVaultPassphraseStoredProperty() { + return selectedVaultPassphraseStored; + } + + public boolean isSelectedVaultPassphraseStored() { + return selectedVaultPassphraseStored.getValue(); + } +} diff --git a/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java index fc751d862..04ea9f152 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java @@ -4,9 +4,6 @@ import org.cryptomator.common.vaults.Vault; import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent; import org.cryptomator.ui.common.FxController; -import org.cryptomator.ui.removevault.RemoveVaultComponent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.beans.binding.Bindings; @@ -17,30 +14,30 @@ import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.scene.control.ListView; +import javafx.scene.input.ContextMenuEvent; +import javafx.scene.input.MouseEvent; @MainWindowScoped public class VaultListController implements FxController { - private static final Logger LOG = LoggerFactory.getLogger(VaultListController.class); private final ObservableList vaults; private final ObjectProperty selectedVault; private final VaultListCellFactory cellFactory; private final AddVaultWizardComponent.Builder addVaultWizard; - private final RemoveVaultComponent.Builder removeVault; - private final BooleanBinding noVaultSelected; private final BooleanBinding emptyVaultList; + public ListView vaultList; @Inject - VaultListController(ObservableList vaults, ObjectProperty selectedVault, VaultListCellFactory cellFactory, AddVaultWizardComponent.Builder addVaultWizard, RemoveVaultComponent.Builder removeVault) { + VaultListController(ObservableList vaults, ObjectProperty selectedVault, VaultListCellFactory cellFactory, AddVaultWizardComponent.Builder addVaultWizard) { this.vaults = vaults; this.selectedVault = selectedVault; this.cellFactory = cellFactory; this.addVaultWizard = addVaultWizard; - this.removeVault = removeVault; - this.noVaultSelected = selectedVault.isNull(); + this.emptyVaultList = Bindings.isEmpty(vaults); + selectedVault.addListener(this::selectedVaultDidChange); } @@ -56,6 +53,19 @@ public class VaultListController implements FxController { } } }); + vaultList.addEventFilter(MouseEvent.MOUSE_RELEASED, this::deselect); + vaultList.addEventFilter(ContextMenuEvent.CONTEXT_MENU_REQUESTED, request -> { + if (selectedVault.get() == null) { + request.consume(); + } + }); + } + + private void deselect(MouseEvent released) { + if (released.getY() > (vaultList.getItems().size() * vaultList.fixedCellSizeProperty().get())) { + vaultList.getSelectionModel().clearSelection(); + released.consume(); + } } private void selectedVaultDidChange(@SuppressWarnings("unused") ObservableValue observableValue, @SuppressWarnings("unused") Vault oldValue, Vault newValue) { @@ -70,16 +80,6 @@ public class VaultListController implements FxController { addVaultWizard.build().showAddVaultWizard(); } - @FXML - public void didClickRemoveVault() { - Vault v = selectedVault.get(); - if (v != null) { - removeVault.vault(v).build().showRemoveVault(); - } else { - LOG.debug("Cannot remove a vault if none is selected."); - } - } - // Getter and Setter public BooleanBinding emptyVaultListProperty() { @@ -90,11 +90,4 @@ public class VaultListController implements FxController { return emptyVaultList.get(); } - public BooleanBinding noVaultSelectedProperty() { - return noVaultSelected; - } - - public boolean isNoVaultSelected() { - return noVaultSelected.get(); - } } diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/KeyLoadingModule.java b/main/ui/src/main/java/org/cryptomator/ui/unlock/KeyLoadingModule.java deleted file mode 100644 index 98bd478d0..000000000 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/KeyLoadingModule.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.cryptomator.ui.unlock; - -import dagger.Module; -import dagger.Provides; -import dagger.multibindings.IntoMap; -import dagger.multibindings.StringKey; -import org.cryptomator.common.vaults.Vault; -import org.cryptomator.cryptofs.VaultConfig.UnverifiedVaultConfig; -import org.cryptomator.ui.unlock.masterkeyfile.MasterkeyFileLoadingComponent; - -import javafx.stage.Stage; -import java.net.URI; -import java.util.Map; -import java.util.Optional; - -@Module(subcomponents = {MasterkeyFileLoadingComponent.class}) -abstract class KeyLoadingModule { - - @Provides - @UnlockScoped - static Optional provideKeyId(@UnlockWindow Vault vault) { - return vault.getUnverifiedVaultConfig().map(UnverifiedVaultConfig::getKeyId); - } - - @Provides - @UnlockScoped - static KeyLoadingComponent provideKeyLoaderProvider(Optional keyId, Map keyLoaderProviders) { - if (keyId.isEmpty()) { - return KeyLoadingComponent.exceptional(new IllegalArgumentException("No key id provided")); - } else { - String scheme = keyId.get().getScheme(); - return keyLoaderProviders.getOrDefault(scheme, KeyLoadingComponent.exceptional(new IllegalArgumentException("Unsupported key id " + scheme))); - } - } - - @Provides - @IntoMap - @StringKey("masterkeyfile") - static KeyLoadingComponent provideMasterkeyFileLoadingComponet(MasterkeyFileLoadingComponent.Builder compBuilder, @UnlockWindow Stage window, @UnlockWindow Vault vault) { - return compBuilder.unlockWindow(window).vault(vault).build(); - } - -} diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockComponent.java b/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockComponent.java index fee0e74a5..9c0338c5b 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockComponent.java +++ b/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockComponent.java @@ -16,7 +16,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; @UnlockScoped -@Subcomponent(modules = {UnlockModule.class, KeyLoadingModule.class}) +@Subcomponent(modules = {UnlockModule.class}) public interface UnlockComponent { ExecutorService defaultExecutorService(); diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockModule.java b/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockModule.java index f7e25dd4f..3c1267e65 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockModule.java +++ b/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockModule.java @@ -12,6 +12,8 @@ import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlLoaderFactory; import org.cryptomator.ui.common.FxmlScene; import org.cryptomator.ui.common.StageFactory; +import org.cryptomator.ui.keyloading.KeyLoadingComponent; +import org.cryptomator.ui.keyloading.KeyLoadingStrategy; import javax.inject.Named; import javax.inject.Provider; @@ -22,7 +24,7 @@ import java.util.Map; import java.util.Optional; import java.util.ResourceBundle; -@Module +@Module(subcomponents = {KeyLoadingComponent.class}) abstract class UnlockModule { @Provides @@ -48,6 +50,13 @@ abstract class UnlockModule { return stage; } + @Provides + @UnlockWindow + @UnlockScoped + static KeyLoadingStrategy provideKeyLoadingStrategy(KeyLoadingComponent.Builder compBuilder, @UnlockWindow Vault vault, @UnlockWindow Stage window) { + return compBuilder.vault(vault).window(window).build().keyloadingStrategy(); + } + @Provides @FxmlScene(FxmlFile.UNLOCK_SUCCESS) @UnlockScoped diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java b/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java index aab68b536..06b42155e 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java +++ b/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java @@ -12,6 +12,8 @@ import org.cryptomator.ui.common.ErrorComponent; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; import org.cryptomator.ui.common.VaultService; +import org.cryptomator.ui.keyloading.KeyLoadingComponent; +import org.cryptomator.ui.keyloading.KeyLoadingStrategy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,17 +43,17 @@ public class UnlockWorkflow extends Task { private final Lazy successScene; private final Lazy invalidMountPointScene; private final ErrorComponent.Builder errorComponent; - private final KeyLoadingComponent keyLoadingComp; + private final KeyLoadingStrategy keyLoadingStrategy; @Inject - UnlockWorkflow(@UnlockWindow Stage window, @UnlockWindow Vault vault, VaultService vaultService, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy successScene, @FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT) Lazy invalidMountPointScene, ErrorComponent.Builder errorComponent, KeyLoadingComponent keyLoadingComp) { + UnlockWorkflow(@UnlockWindow Stage window, @UnlockWindow Vault vault, VaultService vaultService, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy successScene, @FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT) Lazy invalidMountPointScene, ErrorComponent.Builder errorComponent, @UnlockWindow KeyLoadingStrategy keyLoadingStrategy) { this.window = window; this.vault = vault; this.vaultService = vaultService; this.successScene = successScene; this.invalidMountPointScene = invalidMountPointScene; this.errorComponent = errorComponent; - this.keyLoadingComp = keyLoadingComp; + this.keyLoadingStrategy = keyLoadingStrategy; setOnFailed(event -> { Throwable throwable = event.getSource().getException(); @@ -78,17 +80,17 @@ public class UnlockWorkflow extends Task { private void attemptUnlock() throws IOException, VolumeException, InvalidMountPointException, CryptoException { boolean success = false; try { - vault.unlock(keyLoadingComp.masterkeyLoader()); + vault.unlock(keyLoadingStrategy.masterkeyLoader()); success = true; } catch (MasterkeyLoadingFailedException e) { - if (keyLoadingComp.recoverFromException(e)) { + if (keyLoadingStrategy.recoverFromException(e)) { LOG.info("Unlock attempt threw {}. Reattempting...", e.getClass().getSimpleName()); attemptUnlock(); } else { throw e; } } finally { - keyLoadingComp.cleanup(success); + keyLoadingStrategy.cleanup(success); } } diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingComponent.java b/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingComponent.java deleted file mode 100644 index ab3252e28..000000000 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/masterkeyfile/MasterkeyFileLoadingComponent.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.cryptomator.ui.unlock.masterkeyfile; - -import dagger.BindsInstance; -import dagger.Subcomponent; -import org.cryptomator.common.vaults.Vault; -import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException; -import org.cryptomator.cryptolib.common.MasterkeyFileLoader; -import org.cryptomator.ui.unlock.KeyLoadingComponent; - -import javafx.stage.Stage; - -@MasterkeyFileLoadingScoped -@Subcomponent(modules = {MasterkeyFileLoadingModule.class}) -public interface MasterkeyFileLoadingComponent extends KeyLoadingComponent { - - MasterkeyFileLoadingFinisher finisher(); - - MasterkeyFileLoadingContext context(); - - @Override - MasterkeyFileLoader masterkeyLoader(); - - @Override - default boolean recoverFromException(MasterkeyLoadingFailedException exception) { - return context().recoverFromException(exception); - } - - @Override - default void cleanup(boolean unlockedSuccessfully) { - finisher().cleanup(unlockedSuccessfully); - } - - @Subcomponent.Builder - interface Builder { - - @BindsInstance - Builder vault(@MasterkeyFileLoading Vault vault); - - @BindsInstance - Builder unlockWindow(@MasterkeyFileLoading Stage unlockWindow); - - MasterkeyFileLoadingComponent build(); - } - -} diff --git a/main/ui/src/main/resources/fxml/unlock_enter_password.fxml b/main/ui/src/main/resources/fxml/unlock_enter_password.fxml index ff9cc675d..5fb55dd01 100644 --- a/main/ui/src/main/resources/fxml/unlock_enter_password.fxml +++ b/main/ui/src/main/resources/fxml/unlock_enter_password.fxml @@ -14,7 +14,7 @@ - - @@ -15,13 +13,9 @@ fx:controller="org.cryptomator.ui.mainwindow.VaultListController" minWidth="206"> - + - - - - - + diff --git a/main/ui/src/main/resources/fxml/vault_list_cell.fxml b/main/ui/src/main/resources/fxml/vault_list_cell.fxml index e86f084c1..ce8664639 100644 --- a/main/ui/src/main/resources/fxml/vault_list_cell.fxml +++ b/main/ui/src/main/resources/fxml/vault_list_cell.fxml @@ -13,6 +13,7 @@ prefWidth="200" spacing="12" alignment="CENTER_LEFT"> + diff --git a/main/ui/src/main/resources/fxml/vault_list_contextmenu.fxml b/main/ui/src/main/resources/fxml/vault_list_contextmenu.fxml new file mode 100644 index 000000000..bd8f19204 --- /dev/null +++ b/main/ui/src/main/resources/fxml/vault_list_contextmenu.fxml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/main/ui/src/main/resources/i18n/strings.properties b/main/ui/src/main/resources/i18n/strings.properties index c38ecf37f..0830f00f0 100644 --- a/main/ui/src/main/resources/i18n/strings.properties +++ b/main/ui/src/main/resources/i18n/strings.properties @@ -101,9 +101,9 @@ unlock.unlockBtn=Unlock ## unlock.chooseMasterkey.filePickerTitle=Select Masterkey File ## Success -unlock.success.message=Unlocked "%s" successfully! Your vault is now accessible. +unlock.success.message=Unlocked "%s" successfully! Your vault is now accessible via its virtual drive. unlock.success.rememberChoice=Remember choice, don't show this again -unlock.success.revealBtn=Reveal Vault +unlock.success.revealBtn=Reveal Drive ## Failure unlock.error.heading=Unable to unlock vault ### Invalid Mount Point @@ -229,7 +229,12 @@ main.dropZone.dropVault=Add this vault main.dropZone.unknownDragboardContent=If you want to add a vault, drag it to this window ## Vault List main.vaultlist.emptyList.onboardingInstruction=Click here to add a vault -main.vaultlist.contextMenu.remove=Remove Vault… +main.vaultlist.contextMenu.remove=Remove… +main.vaultlist.contextMenu.lock=Lock +main.vaultlist.contextMenu.unlock=Unlock… +main.vaultlist.contextMenu.unlockNow=Unlock Now +main.vaultlist.contextMenu.vaultoptions=Show Vault Options +main.vaultlist.contextMenu.reveal=Reveal Drive main.vaultlist.addVaultBtn=Add Vault ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_ar.properties b/main/ui/src/main/resources/i18n/strings_ar.properties index d14749c9e..e9292b402 100644 --- a/main/ui/src/main/resources/i18n/strings_ar.properties +++ b/main/ui/src/main/resources/i18n/strings_ar.properties @@ -97,9 +97,8 @@ unlock.title=افتح الحافظة unlock.passwordPrompt=‮أدخل كلمة السر لـ "‪%s‬": unlock.unlockBtn=افتح ## Success -unlock.success.message=تم فتح المخزن "%s" بنجاح! يمكنك الوصول إليه الآن. unlock.success.rememberChoice=تذكر اختياري ولا تظهر هذا مرة أخرى -unlock.success.revealBtn=افتح الحافظة +unlock.success.revealBtn=اظهار القرص ## Failure unlock.error.heading=غير قادر على فتح الخزنة ### Invalid Mount Point @@ -195,7 +194,10 @@ main.dropZone.dropVault=أضف هذا المخزن main.dropZone.unknownDragboardContent=إذا كنت ترغب في إضافة مخزن، قم بسحبه إلى هذه النافذة ## Vault List main.vaultlist.emptyList.onboardingInstruction=انقر هنا لإضافة خزنة -main.vaultlist.contextMenu.remove=حذف الخزنة… +main.vaultlist.contextMenu.lock=قفل +main.vaultlist.contextMenu.unlock=فتح… +main.vaultlist.contextMenu.unlockNow=افتح الان +main.vaultlist.contextMenu.reveal=اظهار القرص main.vaultlist.addVaultBtn=أضِف مخزنًا ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_bs.properties b/main/ui/src/main/resources/i18n/strings_bs.properties index 680c87890..a427b7f53 100644 --- a/main/ui/src/main/resources/i18n/strings_bs.properties +++ b/main/ui/src/main/resources/i18n/strings_bs.properties @@ -97,9 +97,8 @@ unlock.title=Otključaj sef unlock.passwordPrompt=Unesite lozinku za "%s": unlock.unlockBtn=Otključaj ## Success -unlock.success.message=Uspješno ste otključali "%s"! Vaš sef je sada dostupan. unlock.success.rememberChoice=Zapamtite izbor, ne pokazujte ovo ponovo -unlock.success.revealBtn=Otkrij sef +unlock.success.revealBtn=Otkrij pogon ## Failure unlock.error.heading=Sef nije moguće otključati ### Invalid Mount Point @@ -222,7 +221,10 @@ main.dropZone.dropVault=Dodajte ovaj sef main.dropZone.unknownDragboardContent=Ako želite dodati sef, povucite ga u ovaj prozor ## Vault List main.vaultlist.emptyList.onboardingInstruction=Kliknite ovdje da dodate sef -main.vaultlist.contextMenu.remove=Ukloni Sef… +main.vaultlist.contextMenu.lock=Zaključaj +main.vaultlist.contextMenu.unlock=Otključaj… +main.vaultlist.contextMenu.unlockNow=Otključaj sada +main.vaultlist.contextMenu.reveal=Otkrij pogon main.vaultlist.addVaultBtn=Dodaj sef ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_ca.properties b/main/ui/src/main/resources/i18n/strings_ca.properties index ed20adecf..be814a57b 100644 --- a/main/ui/src/main/resources/i18n/strings_ca.properties +++ b/main/ui/src/main/resources/i18n/strings_ca.properties @@ -98,9 +98,8 @@ unlock.passwordPrompt=Introduïu la contrasenya de "%s": unlock.savePassword=Recorda la contrasenya unlock.unlockBtn=Desbloqueja ## Success -unlock.success.message="%s" s'ha desbloquejat correctament! Ja es pot accedir a la caixa forta. unlock.success.rememberChoice=Recorda l'elecció. No ho tornis a mostrar. -unlock.success.revealBtn=Mostra la caixa forta +unlock.success.revealBtn=Mostra la unitat ## Failure unlock.error.heading=No ha estat possible desblocar la caixa forta ### Invalid Mount Point @@ -223,7 +222,10 @@ main.dropZone.dropVault=Afegeix aquesta caixa forta main.dropZone.unknownDragboardContent=Si voleu afegir una caixa forta, arrossegueu-la a aquesta finestra ## Vault List main.vaultlist.emptyList.onboardingInstruction=Feu clic aquí per afegir una caixa forta -main.vaultlist.contextMenu.remove=Elimina la caixa forta… +main.vaultlist.contextMenu.lock=Bloqueja +main.vaultlist.contextMenu.unlock=Desbloca… +main.vaultlist.contextMenu.unlockNow=Desbloqueja ara +main.vaultlist.contextMenu.reveal=Mostra la unitat main.vaultlist.addVaultBtn=Afegir una caixa forta ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_cs.properties b/main/ui/src/main/resources/i18n/strings_cs.properties index ee4f9b92a..363ac857d 100644 --- a/main/ui/src/main/resources/i18n/strings_cs.properties +++ b/main/ui/src/main/resources/i18n/strings_cs.properties @@ -98,9 +98,8 @@ unlock.passwordPrompt=Zadejte heslo pro "%s": unlock.savePassword=Zapamatovat heslo unlock.unlockBtn=Odemknout ## Success -unlock.success.message=Trezor "%s" byl úspěšně odemčen a nyní je dostupný. unlock.success.rememberChoice=Pamatovat si volbu, nezobrazovat to znovu -unlock.success.revealBtn=Zobrazit trezor +unlock.success.revealBtn=Zobrazit jednotku ## Failure unlock.error.heading=Nelze odemknout trezor ### Invalid Mount Point @@ -109,6 +108,8 @@ unlock.error.invalidMountPoint.existing=Připojovací bod %s již existuje nebo # Lock ## Force +lock.forced.heading=Běžné uzamčení selhalo +lock.forced.confirmBtn=Přesto uzamknout ## Failure # Migration @@ -218,7 +219,11 @@ main.dropZone.dropVault=Přidat tento trezor main.dropZone.unknownDragboardContent=Pokud chcete přidat trezor, přetáhněte jej do tohoto okna ## Vault List main.vaultlist.emptyList.onboardingInstruction=Klikněte zde pro přidání nového trezoru -main.vaultlist.contextMenu.remove=Odstranit trezor… +main.vaultlist.contextMenu.remove=Odstranit… +main.vaultlist.contextMenu.lock=Zamknout +main.vaultlist.contextMenu.unlock=Odemknout… +main.vaultlist.contextMenu.unlockNow=Odemknout nyní +main.vaultlist.contextMenu.reveal=Zobrazit jednotku main.vaultlist.addVaultBtn=Přidat trezor ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_de.properties b/main/ui/src/main/resources/i18n/strings_de.properties index d5e541f6e..e500aab6c 100644 --- a/main/ui/src/main/resources/i18n/strings_de.properties +++ b/main/ui/src/main/resources/i18n/strings_de.properties @@ -98,9 +98,9 @@ unlock.passwordPrompt=Gib das Passwort für „%s“ ein: unlock.savePassword=Passwort merken unlock.unlockBtn=Entsperren ## Success -unlock.success.message=„%s“ erfolgreich entsperrt! Nun kannst du auf deinen Tresor zugreifen. +unlock.success.message=„%s“ erfolgreich entsperrt! Nun kannst du über das virtuelle Laufwerk auf deinen Tresor zugreifen. unlock.success.rememberChoice=Auswahl speichern und nicht mehr anzeigen -unlock.success.revealBtn=Tresor anzeigen +unlock.success.revealBtn=Laufwerk anzeigen ## Failure unlock.error.heading=Tresor konnte nicht entsperrt werden ### Invalid Mount Point @@ -223,7 +223,12 @@ main.dropZone.dropVault=Diesen Tresor hinzufügen main.dropZone.unknownDragboardContent=Wenn Sie einen Tresor hinzufügen möchten, ziehen Sie ihn in dieses Fenster ## Vault List main.vaultlist.emptyList.onboardingInstruction=Klicke hier, um einen Tresor hinzuzufügen -main.vaultlist.contextMenu.remove=Tresor entfernen… +main.vaultlist.contextMenu.remove=Entfernen … +main.vaultlist.contextMenu.lock=Sperren +main.vaultlist.contextMenu.unlock=Entsperren … +main.vaultlist.contextMenu.unlockNow=Jetzt entsperren +main.vaultlist.contextMenu.vaultoptions=Tresoroptionen anzeigen +main.vaultlist.contextMenu.reveal=Laufwerk anzeigen main.vaultlist.addVaultBtn=Tresor hinzufügen ## Vault Detail ### Welcome @@ -280,7 +285,7 @@ vaultOptions.mount.customMountFlags=Benutzerdefinierte Mount-Flags vaultOptions.mount.winDriveLetterOccupied=belegt vaultOptions.mount.mountPoint=Einhängepunkt vaultOptions.mount.mountPoint.auto=Automatisch einen passenden Ort auswählen -vaultOptions.mount.mountPoint.driveLetter=Zugewiesenen Laufwerksbuchstaben verwenden +vaultOptions.mount.mountPoint.driveLetter=Laufwerksbuchstaben zuweisen vaultOptions.mount.mountPoint.custom=Pfad selbst wählen vaultOptions.mount.mountPoint.directoryPickerButton=Durchsuchen … vaultOptions.mount.mountPoint.directoryPickerTitle=Wähle ein leeres Verzeichnis diff --git a/main/ui/src/main/resources/i18n/strings_el.properties b/main/ui/src/main/resources/i18n/strings_el.properties index 105219c26..de5d4b147 100644 --- a/main/ui/src/main/resources/i18n/strings_el.properties +++ b/main/ui/src/main/resources/i18n/strings_el.properties @@ -98,9 +98,8 @@ unlock.passwordPrompt=Εισάγετε τον κωδικό για "%s": unlock.savePassword=Απομνημόνευση κωδικού πρόσβασης unlock.unlockBtn=Ξεκλείδωμα ## Success -unlock.success.message="%s" ξεκλειδώθηκε επιτυχώς! Το vault σας είναι διαθέσιμο. unlock.success.rememberChoice=Απομνημόνευση επιλογής, μην ρωτήσεις ξανά -unlock.success.revealBtn=Αποκάλυψη Vault +unlock.success.revealBtn=Αποκάλυψη εικονικού δίσκου ## Failure unlock.error.heading=Αδυναμία ξεκλειδώματος vault ### Invalid Mount Point @@ -223,7 +222,10 @@ main.dropZone.dropVault=Προσθήκη vault main.dropZone.unknownDragboardContent=Αν θέλετε να προσθέσετε ένα vault, σύρετε το σε αυτό το παράθυρο ## Vault List main.vaultlist.emptyList.onboardingInstruction=Κάντε κλικ εδώ για να προσθέσετε ένα vault -main.vaultlist.contextMenu.remove=Διαγραφή Vault… +main.vaultlist.contextMenu.lock=Κλείδωμα +main.vaultlist.contextMenu.unlock=Ξεκλείδωμα… +main.vaultlist.contextMenu.unlockNow=Ξεκλείδωμα τώρα +main.vaultlist.contextMenu.reveal=Αποκάλυψη εικονικού δίσκου main.vaultlist.addVaultBtn=Προσθήκη Vault ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_es.properties b/main/ui/src/main/resources/i18n/strings_es.properties index bea555acd..de683e3a8 100644 --- a/main/ui/src/main/resources/i18n/strings_es.properties +++ b/main/ui/src/main/resources/i18n/strings_es.properties @@ -98,9 +98,9 @@ unlock.passwordPrompt=Ingresar contraseña para "%s": unlock.savePassword=Recordar contraseña unlock.unlockBtn=Desbloquear ## Success -unlock.success.message=¡"%s" se desbloqueó con éxito! La bóveda ya es accesible. +unlock.success.message=¡Desbloqueo de "%s" exitoso! Su bóveda ahora es accesible a través de su unidad virtual. unlock.success.rememberChoice=Recordar opción y no mostrar de nuevo -unlock.success.revealBtn=Revelar bóveda +unlock.success.revealBtn=Revelar unidad ## Failure unlock.error.heading=No se puede desbloquear la bóveda ### Invalid Mount Point @@ -223,7 +223,12 @@ main.dropZone.dropVault=Añadir esta bóveda main.dropZone.unknownDragboardContent=Si desea añadir una bóveda, arrástrela a esta ventana ## Vault List main.vaultlist.emptyList.onboardingInstruction=Hacer clic aquí para añadir una bóveda -main.vaultlist.contextMenu.remove=Eliminar bóveda… +main.vaultlist.contextMenu.remove=Eliminar… +main.vaultlist.contextMenu.lock=Bloquear +main.vaultlist.contextMenu.unlock=Desbloquear… +main.vaultlist.contextMenu.unlockNow=Desbloquear ahora +main.vaultlist.contextMenu.vaultoptions=Mostrar opciones de la bóveda +main.vaultlist.contextMenu.reveal=Revelar unidad main.vaultlist.addVaultBtn=Añadir bóveda ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_fr.properties b/main/ui/src/main/resources/i18n/strings_fr.properties index dbcc83a00..27c9951e2 100644 --- a/main/ui/src/main/resources/i18n/strings_fr.properties +++ b/main/ui/src/main/resources/i18n/strings_fr.properties @@ -98,9 +98,9 @@ unlock.passwordPrompt=Entrez le mot de passe pour “%s” : unlock.savePassword=Mémoriser le mot de passe unlock.unlockBtn=Déverrouiller ## Success -unlock.success.message=“%s” déverrouillé ! Le contenu de votre coffre est maintenant accessible. +unlock.success.message=“%s” déverrouillé ! Le contenu de votre coffre est maintenant accessible par son lecteur virtuel. unlock.success.rememberChoice=Se souvenir de mon choix et ne plus me demander -unlock.success.revealBtn=Révéler le coffre +unlock.success.revealBtn=Révéler le lecteur ## Failure unlock.error.heading=Impossible de déverrouiller le coffre ### Invalid Mount Point @@ -223,7 +223,12 @@ main.dropZone.dropVault=Ajouter ce coffre main.dropZone.unknownDragboardContent=Si vous voulez ajouter un coffre, faites-le glisser dans cette fenêtre ## Vault List main.vaultlist.emptyList.onboardingInstruction=Cliquez ici pour ajouter un coffre -main.vaultlist.contextMenu.remove=Supprimer le coffre… +main.vaultlist.contextMenu.remove=Retirer… +main.vaultlist.contextMenu.lock=Verrouiller +main.vaultlist.contextMenu.unlock=Déverrouiller… +main.vaultlist.contextMenu.unlockNow=Déverrouiller maintenant +main.vaultlist.contextMenu.vaultoptions=Afficher les options du coffre +main.vaultlist.contextMenu.reveal=Révéler le lecteur main.vaultlist.addVaultBtn=Ajouter un coffre ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_hi.properties b/main/ui/src/main/resources/i18n/strings_hi.properties index c2433517a..85d139a01 100644 --- a/main/ui/src/main/resources/i18n/strings_hi.properties +++ b/main/ui/src/main/resources/i18n/strings_hi.properties @@ -106,6 +106,7 @@ main.closeBtn.tooltip=बंद करें main.preferencesBtn.tooltip=प्राथमिकताएं ## Drag 'n' Drop ## Vault List +main.vaultlist.contextMenu.lock=लॉक करें main.vaultlist.addVaultBtn=वाउल्ट डालें ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_hu.properties b/main/ui/src/main/resources/i18n/strings_hu.properties index 4a6d80c2f..6d212b025 100644 --- a/main/ui/src/main/resources/i18n/strings_hu.properties +++ b/main/ui/src/main/resources/i18n/strings_hu.properties @@ -96,7 +96,6 @@ unlock.title=Széf feloldása unlock.passwordPrompt=Írja be a jelszavát a következő széfhez "%s": unlock.unlockBtn=Feloldás ## Success -unlock.success.message="%s" sikreresen feloldásra került! Mostmár hozzáférhet a széféhez. unlock.success.rememberChoice=Jegyezze meg a választást és ne mutassa többet unlock.success.revealBtn=Széf megjelenítése ## Failure @@ -207,7 +206,10 @@ main.dropZone.dropVault=Adja hozzá ezt a széfet main.dropZone.unknownDragboardContent=Ha egy széfet szeretne hozzáadni, akkor húzza át erre az ablakra. ## Vault List main.vaultlist.emptyList.onboardingInstruction=Kattintson ide egy széf hozzáadásához -main.vaultlist.contextMenu.remove=Széf eltávolítása… +main.vaultlist.contextMenu.lock=Zárolás +main.vaultlist.contextMenu.unlock=Feloldás… +main.vaultlist.contextMenu.unlockNow=Azonnali feloldás +main.vaultlist.contextMenu.reveal=Széf megjelenítése main.vaultlist.addVaultBtn=Széf hozzáadása ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_id.properties b/main/ui/src/main/resources/i18n/strings_id.properties index 96ea796fb..20bc657d7 100644 --- a/main/ui/src/main/resources/i18n/strings_id.properties +++ b/main/ui/src/main/resources/i18n/strings_id.properties @@ -109,6 +109,7 @@ main.closeBtn.tooltip=Tutup main.preferencesBtn.tooltip=Preferensi ## Drag 'n' Drop ## Vault List +main.vaultlist.contextMenu.lock=Gembok main.vaultlist.addVaultBtn=Tambah Brankas ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_it.properties b/main/ui/src/main/resources/i18n/strings_it.properties index c11ba1bc3..3636aa968 100644 --- a/main/ui/src/main/resources/i18n/strings_it.properties +++ b/main/ui/src/main/resources/i18n/strings_it.properties @@ -98,9 +98,8 @@ unlock.passwordPrompt=Inserisci la password per "%s": unlock.savePassword=Ricorda la Password unlock.unlockBtn=Sblocca ## Success -unlock.success.message=Sbloccato "%s" con successo! La tua cassaforte è ora accessibile. unlock.success.rememberChoice=Ricorda la scelta, non mostrare ancora -unlock.success.revealBtn=Rivela Cassaforte +unlock.success.revealBtn=Visualizza disco ## Failure unlock.error.heading=Impossibile sbloccare la cassaforte ### Invalid Mount Point @@ -221,7 +220,10 @@ main.dropZone.dropVault=Aggiungi questa cassaforte main.dropZone.unknownDragboardContent=Se vuoi aggiungere una cassaforte, trascinala in questa finestra ## Vault List main.vaultlist.emptyList.onboardingInstruction=Clicca qui per aggiungere una cassaforte -main.vaultlist.contextMenu.remove=Rimuovi Cassaforte… +main.vaultlist.contextMenu.lock=Blocca +main.vaultlist.contextMenu.unlock=Sblocca… +main.vaultlist.contextMenu.unlockNow=Sblocca adesso +main.vaultlist.contextMenu.reveal=Visualizza disco main.vaultlist.addVaultBtn=Aggiungi Cassaforte ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_ja.properties b/main/ui/src/main/resources/i18n/strings_ja.properties index 8f8b8a124..b08180424 100644 --- a/main/ui/src/main/resources/i18n/strings_ja.properties +++ b/main/ui/src/main/resources/i18n/strings_ja.properties @@ -98,9 +98,8 @@ unlock.passwordPrompt="%s" のパスワードを入力してください: unlock.savePassword=パスワードを記憶させる unlock.unlockBtn=解錠 ## Success -unlock.success.message="%s" の解錠に成功しました! 金庫にアクセス可能です。 unlock.success.rememberChoice=選択を記憶させて、再度表示しない -unlock.success.revealBtn=金庫を表示 +unlock.success.revealBtn=ドライブを表示 ## Failure unlock.error.heading=金庫の解錠に失敗 ### Invalid Mount Point @@ -223,7 +222,10 @@ main.dropZone.dropVault=この金庫を追加 main.dropZone.unknownDragboardContent=このウィンドウにドラッグして、金庫を追加 ## Vault List main.vaultlist.emptyList.onboardingInstruction=ここをクリックして金庫を追加 -main.vaultlist.contextMenu.remove=金庫を削除... +main.vaultlist.contextMenu.lock=施錠 +main.vaultlist.contextMenu.unlock=解錠... +main.vaultlist.contextMenu.unlockNow=今すぐ解錠 +main.vaultlist.contextMenu.reveal=ドライブを表示 main.vaultlist.addVaultBtn=金庫を追加 ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_ko.properties b/main/ui/src/main/resources/i18n/strings_ko.properties index c5ca492f6..a78e23445 100644 --- a/main/ui/src/main/resources/i18n/strings_ko.properties +++ b/main/ui/src/main/resources/i18n/strings_ko.properties @@ -67,7 +67,7 @@ addvault.new.readme.storageLocation.10=만일 도움이 필요하신 경우, 다 addvault.new.readme.accessLocation.fileName=WELCOME.rtf addvault.new.readme.accessLocation.1=🔐️ 암호화 된 볼륨 🔐️ addvault.new.readme.accessLocation.2=이것은 당신의 Vault 접근 위치입니다. -addvault.new.readme.accessLocation.3=이 볼륨에 추가된 모든 파일은 Cryptomator로 암호화됩니다. 다른 드라이브/폴더처럼 작업할 수 있습니다. 볼륨의 내용은 복호화 된 것 처럼 보여질 뿐이며, 모든 파일은 항상 암호화되어 하드디스크에 저장됩니다. +addvault.new.readme.accessLocation.3=이 볼륨에 추가된 모든 파일은 Cryptomator로 암호화됩니다. 다른 드라이브/폴더처럼 작업할 수 있습니다. 볼륨의 내용은 복호화 된 것 처럼 보여지지만, 모든 파일은 항상 암호화되어 하드디스크에 저장됩니다. addvault.new.readme.accessLocation.4=이 파일은 지우셔도 무방합니다. ## Existing addvaultwizard.existing.instruction=기존 Vault 의 "masterkey.cryptomator" 파일을 선택하여 주십시요. @@ -98,9 +98,8 @@ unlock.passwordPrompt="%s"의 비밀번호를 입력하십시요. unlock.savePassword=비밀번호 기억 unlock.unlockBtn=잠금해제 ## Success -unlock.success.message="%s"의 잠금해제가 성공적으로 수행되었습니다! 이제 이 Vault의 접근이 가능합니다. unlock.success.rememberChoice=선택 기억함, 다시 묻지 않음 -unlock.success.revealBtn=Vault 표시 +unlock.success.revealBtn=드라이브 표시 ## Failure unlock.error.heading=Vault 잠금을 해제 할 수 없습니다. ### Invalid Mount Point @@ -223,7 +222,10 @@ main.dropZone.dropVault=이 Vault를 추가 main.dropZone.unknownDragboardContent=Vault를 추가하려면, 이 창에 드래그 하십시요. ## Vault List main.vaultlist.emptyList.onboardingInstruction=Vault를 추가하기 위해 이곳을 클릭합니다. -main.vaultlist.contextMenu.remove=Vault 제거... +main.vaultlist.contextMenu.lock=잠금 +main.vaultlist.contextMenu.unlock=잠금해제... +main.vaultlist.contextMenu.unlockNow=지금 잠금해제 +main.vaultlist.contextMenu.reveal=드라이브 표시 main.vaultlist.addVaultBtn=Vault 추가 ## Vault Detail ### Welcome @@ -294,7 +296,7 @@ vaultOptions.masterkey.recoverPasswordBtn=비밀번호 복구 # Recovery Key recoveryKey.title=복구 키 -recoveryKey.enterPassword.prompt="%s"의 복구 키를 표시하려면 비밀번호를 입력하여 주십시요. +recoveryKey.enterPassword.prompt="%s"의 복구 키를 표시하려면 비밀번호를 입력해 주세요. recoveryKey.display.message="%s" 데이터 접근을 복원하는데 사용 할 수 있는 복구 키 입니다: recoveryKey.display.StorageHints=매우 안전한곳에 보관하십시요. 예시:\n • 비밀번호 관리자를 사용하여 저장\n • USB 플래시 드라이브에 저장\n • 종이에 출력 recoveryKey.recover.prompt="%s"의 복구키를 입력하십시요: @@ -302,7 +304,7 @@ recoveryKey.recover.validKey=올바른 복구 키 입니다. recoveryKey.printout.heading=Cryptomator 복구 키\n"%s"\n # New Password -newPassword.promptText=새 비밀번호를 입력하십시요. +newPassword.promptText=새 비밀번호를 입력하세요 newPassword.reenterPassword=새 비밀번호를 확인하여 주십시요. newPassword.passwordsMatch=비밀번호가 일치합니다! newPassword.passwordsDoNotMatch=비밀번호가 일치하지 않습니다. diff --git a/main/ui/src/main/resources/i18n/strings_lv.properties b/main/ui/src/main/resources/i18n/strings_lv.properties index 938ac5833..2812515c2 100644 --- a/main/ui/src/main/resources/i18n/strings_lv.properties +++ b/main/ui/src/main/resources/i18n/strings_lv.properties @@ -95,8 +95,7 @@ unlock.title=Atslēgt glabātuvi unlock.passwordPrompt=Ievadiet "%s" paroli: unlock.unlockBtn=Atslēgt ## Success -unlock.success.message="%s" sekmīgi atslēgts! Jūsu glabātuve tagad ir pieejama. -unlock.success.revealBtn=Atklāt glabātuvi +unlock.success.revealBtn=Atklāt disku ## Failure ### Invalid Mount Point @@ -171,6 +170,9 @@ main.dropZone.dropVault=Pievienot šo glabātuvi main.dropZone.unknownDragboardContent=Ja jūs vēlaties pievienot glabātuvi, velciet to uz šo logu ## Vault List main.vaultlist.emptyList.onboardingInstruction=Spied šeit, lai pievienotu glabātuvi +main.vaultlist.contextMenu.lock=Aizslēgt +main.vaultlist.contextMenu.unlockNow=Atslēgt tagad +main.vaultlist.contextMenu.reveal=Atklāt disku main.vaultlist.addVaultBtn=Pievienot glabātuvi ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_nb.properties b/main/ui/src/main/resources/i18n/strings_nb.properties index 2bda8d0b3..444721b0b 100644 --- a/main/ui/src/main/resources/i18n/strings_nb.properties +++ b/main/ui/src/main/resources/i18n/strings_nb.properties @@ -95,11 +95,11 @@ forgetPassword.confirmBtn=Glem passord # Unlock unlock.title=Lås opp hvelvet unlock.passwordPrompt=Skriv inn passordet for "%s": +unlock.savePassword=Husk passord unlock.unlockBtn=Lås opp ## Success -unlock.success.message=Vellykket opplåsning av "%s"! Hvelvet ditt er nå tilgjengelig. unlock.success.rememberChoice=Husk valget - ikke vis dette igjen -unlock.success.revealBtn=Gjør hvelvet synlig +unlock.success.revealBtn=Gjør enheten synlig ## Failure unlock.error.heading=Klarer ikke å låse opp hvelvet ### Invalid Mount Point @@ -201,6 +201,7 @@ stats.read.accessCount=Lesninger totalt: %d stats.write.throughput.idle=Skrive: inaktiv stats.write.throughput.kibs=Skriver: %.2f kiB/s stats.write.throughput.mibs=Skriver: %.2f MiB/s +stats.write.total.data.none=Data skrevet: - stats.write.total.data.kib=Data skrevet: %.1f kiB stats.write.total.data.mib=Data skrevet: %.1f MiB stats.write.total.data.gib=Data skrevet: %.1f GiB @@ -221,7 +222,10 @@ main.dropZone.dropVault=Legg til dette hvelvet main.dropZone.unknownDragboardContent=Hvis du vil legge til et hvelv, kan du dra det til dette vinduet ## Vault List main.vaultlist.emptyList.onboardingInstruction=Klikk her for å legge til et hvelv -main.vaultlist.contextMenu.remove=Fjern hvelvet… +main.vaultlist.contextMenu.lock=Lås +main.vaultlist.contextMenu.unlock=Lås opp… +main.vaultlist.contextMenu.unlockNow=Lås opp nå +main.vaultlist.contextMenu.reveal=Gjør enheten synlig main.vaultlist.addVaultBtn=Legg til hvelv ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_nl.properties b/main/ui/src/main/resources/i18n/strings_nl.properties index d824bfc7b..0d053ea2b 100644 --- a/main/ui/src/main/resources/i18n/strings_nl.properties +++ b/main/ui/src/main/resources/i18n/strings_nl.properties @@ -97,9 +97,8 @@ unlock.title=Kluis ontgrendelen unlock.passwordPrompt=Voer wachtwoord voor "%s" in: unlock.unlockBtn=Ontgrendel ## Success -unlock.success.message="%s" is met succes ontgrendeld! Uw kluis is nu toegankelijk. unlock.success.rememberChoice=Keuze onthouden en dit niet opnieuw tonen -unlock.success.revealBtn=Toon kluis +unlock.success.revealBtn=Toon Schijf ## Failure unlock.error.heading=Kan kluis niet ontgrendelen ### Invalid Mount Point @@ -221,7 +220,10 @@ main.dropZone.dropVault=Voeg deze kluis toe main.dropZone.unknownDragboardContent=Als u een kluis wilt toevoegen, sleep deze dan naar dit venster ## Vault List main.vaultlist.emptyList.onboardingInstruction=Klik hier om een kluis toe te voegen -main.vaultlist.contextMenu.remove=Verwijder Kluis… +main.vaultlist.contextMenu.lock=Vergrendel +main.vaultlist.contextMenu.unlock=Ontgrendelen… +main.vaultlist.contextMenu.unlockNow=Nu Ontgrendelen +main.vaultlist.contextMenu.reveal=Toon Schijf main.vaultlist.addVaultBtn=Kluis toevoegen ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_nn.properties b/main/ui/src/main/resources/i18n/strings_nn.properties index 7d291d646..d3aab4caa 100644 --- a/main/ui/src/main/resources/i18n/strings_nn.properties +++ b/main/ui/src/main/resources/i18n/strings_nn.properties @@ -96,9 +96,8 @@ unlock.title=Lås opp kvelven unlock.passwordPrompt=Skriv inn passordet for "%s": unlock.unlockBtn=Låse opp ## Success -unlock.success.message=Vellykka opplåsning av "%s"! Kvelven din er no tilgjengeleg. unlock.success.rememberChoice=Hugs valet - ikkje vis dette igjen -unlock.success.revealBtn=Gjer kvelven synleg +unlock.success.revealBtn=Gjer eininga synleg ## Failure ### Invalid Mount Point @@ -178,6 +177,10 @@ main.dropZone.dropVault=Legg til denne kvelven main.dropZone.unknownDragboardContent=Viss du vil legga til ein kvelv, kan du dra det til dette vindauget ## Vault List main.vaultlist.emptyList.onboardingInstruction=Klikk her for å legga til ein kvelv +main.vaultlist.contextMenu.lock=Lås +main.vaultlist.contextMenu.unlock=Lås opp… +main.vaultlist.contextMenu.unlockNow=Lås opp no +main.vaultlist.contextMenu.reveal=Gjer eininga synleg main.vaultlist.addVaultBtn=Legg til kvelv ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_pa.properties b/main/ui/src/main/resources/i18n/strings_pa.properties index 33660d71e..c41562dd2 100644 --- a/main/ui/src/main/resources/i18n/strings_pa.properties +++ b/main/ui/src/main/resources/i18n/strings_pa.properties @@ -95,11 +95,11 @@ forgetPassword.confirmBtn=ਪਾਸਵਰਡ ਭੁੱਲ ਗਏ # Unlock unlock.title=ਵਾਲਟ ਅਣ-ਲਾਕ ਕਰੋ unlock.passwordPrompt="%s" ਲਈ ਪਾਸਵਰਡ ਦਿਓ: +unlock.savePassword=ਪਾਸਵਰਡ ਯਾਦ ਰੱਖੋ unlock.unlockBtn=ਅਣ-ਲਾਕ ਕਰੋ ## Success -unlock.success.message="%s" ਕਾਮਯਾਬੀ ਨਾਲ ਅਣ-ਲਾਕ ਕੀਤਾ! ਤੁਹਾਡਾ ਵਾਲਟ ਹੁਣ ਵਰਤਿਆ ਜਾ ਸਕਦਾ ਹੈ। unlock.success.rememberChoice=ਚੋਣਾਂ ਯਾਦ ਰੱਖੋ, ਇਹ ਮੁੜ ਕੇ ਨਾ ਵੇਖਾਓ -unlock.success.revealBtn=ਵਾਲਟ ਦਿਖਾਓ +unlock.success.revealBtn=ਡਰਾਇਵ ਦਿਖਾਓ ## Failure unlock.error.heading=ਵਾਲਟ ਅਣ-ਲਾਕ ਕਰਨ ਲਈ ਅਸਮਰੱਥ ### Invalid Mount Point @@ -201,6 +201,7 @@ stats.read.accessCount=ਕੁੱਲ ਪੜ੍ਹੇ: %d stats.write.throughput.idle=ਲਿਖੇ: ਵੇਹਲ stats.write.throughput.kibs=ਲਿਖੇ: %.2f kiB/s stats.write.throughput.mibs=ਲਿਖੇ: %.2f MiB/s +stats.write.total.data.none=ਲਿਖਿਆ ਡਾਟਾ: - stats.write.total.data.kib=ਡਾਟਾ ਲਿਖਿਆ: %.1f kiB stats.write.total.data.mib=ਡਾਟਾ ਲਿਖਿਆ: %.1f MiB stats.write.total.data.gib=ਡਾਟਾ ਲਿਖਿਆ: %.1f GiB @@ -221,7 +222,10 @@ main.dropZone.dropVault=ਇਹ ਵਾਲਟ ਜੋੜੋ main.dropZone.unknownDragboardContent=ਜੇ ਤੁਸੀਂ ਵਾਲਟ ਜੋੜਨਾ ਚਾਹੁੰਦੇ ਹੋ ਤਾਂ ਇਸ ਨੂੰ ਬੰਦ ਵਿੰਡੋ ਉੱਤੇ ਖਿੱਚੋ ## Vault List main.vaultlist.emptyList.onboardingInstruction=ਵਾਲਟ ਜੋੜਨ ਲਈ ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ -main.vaultlist.contextMenu.remove=…ਵਾਲਟ ਹਟਾਓ +main.vaultlist.contextMenu.lock=ਲਾਕ ਕਰੋ +main.vaultlist.contextMenu.unlock=ਅਣ-ਲਾਕ ਕਰੋ… +main.vaultlist.contextMenu.unlockNow=ਹੁਣੇ ਅਣ-ਲਾਕ ਕਰੋ +main.vaultlist.contextMenu.reveal=ਡਰਾਇਵ ਦਿਖਾਓ main.vaultlist.addVaultBtn=ਵਾਲਟ ਜੋੜੋ ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_pl.properties b/main/ui/src/main/resources/i18n/strings_pl.properties index f3c18adfe..5aedad03b 100644 --- a/main/ui/src/main/resources/i18n/strings_pl.properties +++ b/main/ui/src/main/resources/i18n/strings_pl.properties @@ -98,9 +98,9 @@ unlock.passwordPrompt=Wprowadź hasło dla "%s": unlock.savePassword=Zapamiętaj hasło unlock.unlockBtn=Odblokuj ## Success -unlock.success.message="%s" został odblokowany! Twój sejf jest teraz dostępny. +unlock.success.message=Odblokowano "%s" pomyślnie! Twój sejf jest teraz dostępny za pomocą dysku wirtualnego. unlock.success.rememberChoice=Zapamiętaj wybór, nie pokazuj tego ponownie -unlock.success.revealBtn=Otwórz sejf +unlock.success.revealBtn=Ujawnij Dysk ## Failure unlock.error.heading=Nie można odblokować sejfu ### Invalid Mount Point @@ -223,7 +223,12 @@ main.dropZone.dropVault=Dodaj ten sejf main.dropZone.unknownDragboardContent=Jeśli chcesz dodać sejf, przeciągnij go do tego okna ## Vault List main.vaultlist.emptyList.onboardingInstruction=Kliknij tutaj, aby dodać sejf -main.vaultlist.contextMenu.remove=Usuń sejf… +main.vaultlist.contextMenu.remove=Usuń… +main.vaultlist.contextMenu.lock=Zablokuj +main.vaultlist.contextMenu.unlock=Odblokuj… +main.vaultlist.contextMenu.unlockNow=Odblokuj teraz +main.vaultlist.contextMenu.vaultoptions=Pokaż opcje sejfu +main.vaultlist.contextMenu.reveal=Otwórz lokalizację main.vaultlist.addVaultBtn=Dodaj sejf ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_pt.properties b/main/ui/src/main/resources/i18n/strings_pt.properties index 4f1ad61f4..977d610cb 100644 --- a/main/ui/src/main/resources/i18n/strings_pt.properties +++ b/main/ui/src/main/resources/i18n/strings_pt.properties @@ -88,9 +88,7 @@ unlock.title=Destrancar Cofre unlock.passwordPrompt=Insira a senha para "%s": unlock.unlockBtn=Destrancar ## Success -unlock.success.message=Desbloqueado "%s" com sucesso! O seu cofre está agora acessível. unlock.success.rememberChoice=Lembrar escolha, não mostrar isto novamente -unlock.success.revealBtn=Revelar Cofre ## Failure ### Invalid Mount Point @@ -140,6 +138,8 @@ main.minimizeBtn.tooltip=Minimizar main.preferencesBtn.tooltip=Preferências ## Drag 'n' Drop ## Vault List +main.vaultlist.contextMenu.lock=Trancar +main.vaultlist.contextMenu.unlockNow=Destrancar agora main.vaultlist.addVaultBtn=Adicionar Cofre ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_pt_BR.properties b/main/ui/src/main/resources/i18n/strings_pt_BR.properties index 6323b2cb6..8c6f034a9 100644 --- a/main/ui/src/main/resources/i18n/strings_pt_BR.properties +++ b/main/ui/src/main/resources/i18n/strings_pt_BR.properties @@ -98,9 +98,8 @@ unlock.passwordPrompt=Digite a senha para "%s": unlock.savePassword=Lembrar Senha unlock.unlockBtn=Desbloquear ## Success -unlock.success.message="%s" foi desbloqueado com sucesso! Seu cofre agora está acessível. unlock.success.rememberChoice=Lembrar opção escolhida, não mostrar isto novamente -unlock.success.revealBtn=Revelar Cofre +unlock.success.revealBtn=Revelar Volume ## Failure unlock.error.heading=Não foi possível desbloquear o cofre ### Invalid Mount Point @@ -202,6 +201,7 @@ stats.read.accessCount=Total de leituras: %d stats.write.throughput.idle=Escrita: ociosa stats.write.throughput.kibs=Escrita: %.2f kiB/s stats.write.throughput.mibs=Escrita: %.2f MiB/s +stats.write.total.data.none=Dados gravados: - stats.write.total.data.kib=Dados gravados: %.1f kiB stats.write.total.data.mib=Dados gravados: %.1f MiB stats.write.total.data.gib=Dados gravados: %.1f GiB @@ -222,7 +222,10 @@ main.dropZone.dropVault=Adicionar este cofre main.dropZone.unknownDragboardContent=Se você quer adicionar um cofre, arraste-o para esta janela ## Vault List main.vaultlist.emptyList.onboardingInstruction=Clique aqui para adicionar um cofre -main.vaultlist.contextMenu.remove=Remover Cofre… +main.vaultlist.contextMenu.lock=Bloquear +main.vaultlist.contextMenu.unlock=Desbloquear… +main.vaultlist.contextMenu.unlockNow=Desbloquear Agora +main.vaultlist.contextMenu.reveal=Revelar Volume main.vaultlist.addVaultBtn=Adicionar Cofre ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_ru.properties b/main/ui/src/main/resources/i18n/strings_ru.properties index ba7b08e0d..7ccfc5930 100644 --- a/main/ui/src/main/resources/i18n/strings_ru.properties +++ b/main/ui/src/main/resources/i18n/strings_ru.properties @@ -98,9 +98,9 @@ unlock.passwordPrompt=Введите пароль для "%s" unlock.savePassword=Запомнить пароль unlock.unlockBtn=Разблокировать ## Success -unlock.success.message=Разблокировка "%s" успешно выполнена! Доступ в хранилище открыт. +unlock.success.message=Разблокировка "%s" успешно выполнена! Доступ в хранилище открыт через его виртуальный диск. unlock.success.rememberChoice=Запомнить выбор и больше не спрашивать -unlock.success.revealBtn=Показать хранилище +unlock.success.revealBtn=Показать диск ## Failure unlock.error.heading=Не удалось разблокировать хранилище ### Invalid Mount Point @@ -223,7 +223,12 @@ main.dropZone.dropVault=Добавить это хранилище main.dropZone.unknownDragboardContent=Если вы хотите добавить хранилище, перетащите его в это окно ## Vault List main.vaultlist.emptyList.onboardingInstruction=Нажмите здесь, чтобы добавить хранилище -main.vaultlist.contextMenu.remove=Удалить хранилище… +main.vaultlist.contextMenu.remove=Удалить… +main.vaultlist.contextMenu.lock=Заблокировать +main.vaultlist.contextMenu.unlock=Разблокировка… +main.vaultlist.contextMenu.unlockNow=Разблокировать +main.vaultlist.contextMenu.vaultoptions=Параметры хранилища +main.vaultlist.contextMenu.reveal=Показать диск main.vaultlist.addVaultBtn=Добавить хранилище ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_sk.properties b/main/ui/src/main/resources/i18n/strings_sk.properties index cbd5a22cc..a1378658d 100644 --- a/main/ui/src/main/resources/i18n/strings_sk.properties +++ b/main/ui/src/main/resources/i18n/strings_sk.properties @@ -96,8 +96,6 @@ unlock.passwordPrompt=Zadajte heslo pre "%s": unlock.savePassword=Odomknúť.uložiťHeslo unlock.unlockBtn=Odomknúť ## Success -unlock.success.message=Úspešne sa odomkol "%s"! Váš trezor je teraz prístupný. -unlock.success.revealBtn=Odhaliť trezor ## Failure unlock.error.heading=Nie je možné odomknúť účet ### Invalid Mount Point @@ -172,7 +170,9 @@ main.preferencesBtn.tooltip=Predvoľby main.debugModeEnabled.tooltip=Debagovací mód je aktivovaný ## Drag 'n' Drop ## Vault List -main.vaultlist.contextMenu.remove=Odstrániť peňaženku… +main.vaultlist.contextMenu.lock=Uzamknúť +main.vaultlist.contextMenu.unlock=Odomknúť… +main.vaultlist.contextMenu.unlockNow=Odomknúť teraz main.vaultlist.addVaultBtn=Pridať trezor ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_sr.properties b/main/ui/src/main/resources/i18n/strings_sr.properties new file mode 100644 index 000000000..9f2898f25 --- /dev/null +++ b/main/ui/src/main/resources/i18n/strings_sr.properties @@ -0,0 +1,75 @@ +# Locale Specific CSS files such as CJK, RTL,... + +# Generics +## Button +## Error + +# Defaults + +# Tray Menu + +# Add Vault Wizard +## Welcome +## New +### Name +### Location +### Password +### Information +## Existing +## Success + +# Remove Vault + +# Change Password + +# Forget Password + +# Unlock +## Success +## Failure +### Invalid Mount Point + +# Lock +## Force +## Failure + +# Migration +## Start +## Run +## Sucess +## Missing file system capabilities +## Impossible + +# Preferences +## General +## Volume +## Updates +## Donation Key +## About + +# Vault Statistics +## Read +## Write + +# Main Window +## Drag 'n' Drop +## Vault List +## Vault Detail +### Welcome +### Locked +### Unlocked +### Missing +### Needs Migration + +# Wrong File Alert + +# Vault Options +## General +## Mount +## Master Key + +# Recovery Key + +# New Password + +# Quit diff --git a/main/ui/src/main/resources/i18n/strings_sv.properties b/main/ui/src/main/resources/i18n/strings_sv.properties index 9677fa732..54b9dd28c 100644 --- a/main/ui/src/main/resources/i18n/strings_sv.properties +++ b/main/ui/src/main/resources/i18n/strings_sv.properties @@ -14,7 +14,7 @@ generic.button.next=Nästa generic.button.print=Skriv ut ## Error generic.error.title=Ett oväntat fel uppstod -generic.error.instruction=Det här borde inte ha hänt. Vänligen rapportera feltexten nedan och inkludera en beskrivning av vilka steg som ledde till detta fel. +generic.error.instruction=Detta borde inte hänt. Vänligen rapportera feltexten nedan och inkludera en beskrivning av vilka steg som ledde till detta fel. # Defaults defaults.vault.vaultName=Valv @@ -56,7 +56,7 @@ addvaultwizard.new.generateRecoveryKeyChoice.no=Nej tack. Här slarvas inga lös addvault.new.readme.storageLocation.fileName=VIKTIGT.rtf addvault.new.readme.storageLocation.1=⚠️ VALVFILER ⚠️ addvault.new.readme.storageLocation.2=Detta är ditt valvs lagringsplats. -addvault.new.readme.storageLocation.3=INTE +addvault.new.readme.storageLocation.3=DU SKA INTE addvault.new.readme.storageLocation.4=• ändra någon fil i denna katalog eller addvault.new.readme.storageLocation.5=• klistra in filer för kryptering i denna katalog. addvault.new.readme.storageLocation.6=Om du vill kryptera filer och se innehållet i valvet, gör följande: @@ -74,7 +74,7 @@ addvaultwizard.existing.instruction=Välj "masterkey.cryptomator" för ditt befi addvaultwizard.existing.chooseBtn=Välj… addvaultwizard.existing.filePickerTitle=Välj Masterkey-fil ## Success -addvaultwizard.success.nextStepsInstructions=Lade till valv "%s".\nDu behöver låsa upp detta valv för att komma åt eller lägga till innehåll. Du kan även låsa upp det vid ett senare tillfälle. +addvaultwizard.success.nextStepsInstructions=Lade till valv "%s".\nDu måste låsa upp detta valv för att komma åt eller lägga till innehåll. Du kan även låsa upp det vid ett senare tillfälle. addvaultwizard.success.unlockNow=Lås upp nu # Remove Vault @@ -98,9 +98,8 @@ unlock.passwordPrompt=Ange lösenord för "%s": unlock.savePassword=Kom ihåg lösenord unlock.unlockBtn=Lås upp ## Success -unlock.success.message="%s" upplåst! Ditt valv är nu åtkomligt. unlock.success.rememberChoice=Kom ihåg valet, visa inte detta igen -unlock.success.revealBtn=Visa valv +unlock.success.revealBtn=Visa enhet ## Failure unlock.error.heading=Kan inte låsa upp valvet ### Invalid Mount Point @@ -126,7 +125,7 @@ migration.run.enterPassword=Ange lösenordet för "%s" migration.run.startMigrationBtn=Migrera valv migration.run.progressHint=Detta kan ta lite tid… ## Sucess -migration.success.nextStepsInstructions="%s" migrerades fullständigt.\nDu kan nu låsa upp ditt valv. +migration.success.nextStepsInstructions="%s" migrerades korrekt.\nDu kan nu låsa upp ditt valv. migration.success.unlockNow=Lås upp nu ## Missing file system capabilities migration.error.missingFileSystemCapabilities.title=Filsystemet stöds ej @@ -137,7 +136,7 @@ migration.error.missingFileSystemCapabilities.reason.READ_ACCESS=Filsystemet til migration.error.missingFileSystemCapabilities.reason.WRITE_ACCESS=Filsystemet tillåter inte att skrivas till. ## Impossible migration.impossible.heading=Kan inte migrera valv -migration.impossible.reason=Valvet kan inte migreras automatiskt eftersom dess lagringsplats eller åtkomstpunkt inte är kompatibel. +migration.impossible.reason=Valvet kan inte migreras automatiskt eftersom dess lagringsplats eller åtkomstpunkt inte är kompatibelt. migration.impossible.moreInfo=Valvet kan fortfarande öppnas med en äldre version. För instruktioner om hur du manuellt migrerar ett valv, besök # Preferences @@ -149,8 +148,8 @@ preferences.general.theme.automatic=Automatiskt preferences.general.theme.light=Ljust preferences.general.theme.dark=Mörkt preferences.general.unlockThemes=Lås upp mörkt läge -preferences.general.showMinimizeButton=Visa minimera knappen -preferences.general.showTrayIcon=Visa tray-ikon (kräver omstart) +preferences.general.showMinimizeButton=Visa minimera-knappen +preferences.general.showTrayIcon=Visa ikon i aktivitetsfältet (kräver omstart) preferences.general.startHidden=Dölj fönster när Cryptomator startar preferences.general.debugLogging=Aktivera loggning för felsökning preferences.general.debugDirectory=Visa loggfiler @@ -171,7 +170,7 @@ preferences.volume.webdav.scheme=WebDAV Schema ## Updates preferences.updates=Uppdateringar preferences.updates.currentVersion=Nuvarande version: %s -preferences.updates.autoUpdateCheck=Kontrollera uppdateringar automatiskt +preferences.updates.autoUpdateCheck=Sök efter uppdateringar automatiskt preferences.updates.checkNowBtn=Kontrollera nu preferences.updates.updateAvailable=Uppdatering till version %s finns tillgänglig. ## Donation Key @@ -223,11 +222,14 @@ main.dropZone.dropVault=Lägg till detta valv main.dropZone.unknownDragboardContent=Om du vill lägga till ett valv, dra in det till detta fönster ## Vault List main.vaultlist.emptyList.onboardingInstruction=Klicka här för att lägga till valv -main.vaultlist.contextMenu.remove=Ta bort valv… +main.vaultlist.contextMenu.lock=Lås +main.vaultlist.contextMenu.unlock=Lås upp… +main.vaultlist.contextMenu.unlockNow=Lås upp nu +main.vaultlist.contextMenu.reveal=Visa enhet main.vaultlist.addVaultBtn=Lägg till valv ## Vault Detail ### Welcome -main.vaultDetail.welcomeOnboarding=Tack för att du väljer Cryptomator för att skydda dina filer. Om du behöver hjälp, kolla in våra kom-gång guider: +main.vaultDetail.welcomeOnboarding=Tack för att du väljer Cryptomator för att skydda dina filer. Om du behöver hjälp kan du kolla in våra guider: ### Locked main.vaultDetail.lockedStatus=LÅST main.vaultDetail.unlockBtn=Lås upp… @@ -246,7 +248,7 @@ main.vaultDetail.throughput.kbps=%.1f kiB/s main.vaultDetail.throughput.mbps=%.1f MiB/s main.vaultDetail.stats=Valv Statistik ### Missing -main.vaultDetail.missing.info=Cryptomator kunde inte hitta ett valv i denna sökväg. +main.vaultDetail.missing.info=Cryptomator kunde inte hitta någt valv i denna sökväg. main.vaultDetail.missing.recheck=Kontrollera igen main.vaultDetail.missing.remove=Ta bort från listan… main.vaultDetail.missing.changeLocation=Ändra valvets plats… diff --git a/main/ui/src/main/resources/i18n/strings_tr.properties b/main/ui/src/main/resources/i18n/strings_tr.properties index c531555a4..3b46959d9 100644 --- a/main/ui/src/main/resources/i18n/strings_tr.properties +++ b/main/ui/src/main/resources/i18n/strings_tr.properties @@ -98,9 +98,9 @@ unlock.passwordPrompt="%s" için şifre girin: unlock.savePassword=Şifreyi Hatırla unlock.unlockBtn=Kilidi Aç ## Success -unlock.success.message="%s" 'nin kilidi başarıyla açıldı! Kasanız şimdi erişilebilir durumda. +unlock.success.message="%s" 'nin kilidi başarıyla açıldı! Kasanız şimdi sanal sürücüsü ile erişilebilir durumda. unlock.success.rememberChoice=Seçimi hatırla, bunu bir daha gösterme -unlock.success.revealBtn=Kasayı Göster +unlock.success.revealBtn=Sürücüyü Göster ## Failure unlock.error.heading=Kasanın kilidi açılamıyor ### Invalid Mount Point @@ -223,7 +223,12 @@ main.dropZone.dropVault=Bu kasayı ekle main.dropZone.unknownDragboardContent=Bir kasa eklemek istiyorsanız, onu bu pencereye sürükleyin ## Vault List main.vaultlist.emptyList.onboardingInstruction=Kasa eklemek için buraya tıklayın -main.vaultlist.contextMenu.remove=Kasayı Sil… +main.vaultlist.contextMenu.remove=Kaldır… +main.vaultlist.contextMenu.lock=Kilitle +main.vaultlist.contextMenu.unlock=Kilit aç… +main.vaultlist.contextMenu.unlockNow=Kilidi Şimdi Aç +main.vaultlist.contextMenu.vaultoptions=Kasa Ayarları'nı Göster +main.vaultlist.contextMenu.reveal=Sürücüyü Göster main.vaultlist.addVaultBtn=Kasa Ekle ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_zh.properties b/main/ui/src/main/resources/i18n/strings_zh.properties index e8181d946..a6227e9f7 100644 --- a/main/ui/src/main/resources/i18n/strings_zh.properties +++ b/main/ui/src/main/resources/i18n/strings_zh.properties @@ -98,9 +98,8 @@ unlock.passwordPrompt=输入 "%s" 的密码 unlock.savePassword=记住密码 unlock.unlockBtn=解锁 ## Success -unlock.success.message=已成功解锁 "%s"! 您现在可以访问该保险库 unlock.success.rememberChoice=记住选项且不再显示 -unlock.success.revealBtn=显示保险库 +unlock.success.revealBtn=显示驱动器 ## Failure unlock.error.heading=无法解锁保险库 ### Invalid Mount Point @@ -223,7 +222,10 @@ main.dropZone.dropVault=添加此保险库 main.dropZone.unknownDragboardContent=如果您想要添加一个保险库,将其拖动到此窗口 ## Vault List main.vaultlist.emptyList.onboardingInstruction=点击此处添加一个保险库 -main.vaultlist.contextMenu.remove=删除保险库… +main.vaultlist.contextMenu.lock=锁定 +main.vaultlist.contextMenu.unlock=解锁… +main.vaultlist.contextMenu.unlockNow=立即解锁 +main.vaultlist.contextMenu.reveal=显示驱动器 main.vaultlist.addVaultBtn=添加保险库 ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/i18n/strings_zh_TW.properties b/main/ui/src/main/resources/i18n/strings_zh_TW.properties index e484651bd..c1afb3720 100644 --- a/main/ui/src/main/resources/i18n/strings_zh_TW.properties +++ b/main/ui/src/main/resources/i18n/strings_zh_TW.properties @@ -95,11 +95,12 @@ forgetPassword.confirmBtn=忘記密碼 # Unlock unlock.title=解鎖加密檔案庫 unlock.passwordPrompt=輸入 "%s" 的密碼: +unlock.savePassword=記住密碼 unlock.unlockBtn=解鎖 ## Success -unlock.success.message=成功解鎖 "%s"!您現在可以存取您的加密檔案庫。 +unlock.success.message=成功解鎖 "%s"!您現在可以存存取您的加密檔案庫。 unlock.success.rememberChoice=記得這個決定,不要再顯示 -unlock.success.revealBtn=顯示加密檔案庫 +unlock.success.revealBtn=顯示磁碟 ## Failure unlock.error.heading=無法解鎖加密檔案庫 ### Invalid Mount Point @@ -222,7 +223,12 @@ main.dropZone.dropVault=加入這個加密檔案庫 main.dropZone.unknownDragboardContent=如果您想加入一個加密檔案庫,請將他拖到這個視窗裡 ## Vault List main.vaultlist.emptyList.onboardingInstruction=點擊此處以加入加密檔案庫 -main.vaultlist.contextMenu.remove=移除加密檔案庫… +main.vaultlist.contextMenu.remove=移除… +main.vaultlist.contextMenu.lock=鎖定 +main.vaultlist.contextMenu.unlock=解鎖… +main.vaultlist.contextMenu.unlockNow=立即解鎖 +main.vaultlist.contextMenu.vaultoptions=顯示加密檔案庫選項 +main.vaultlist.contextMenu.reveal=顯示磁碟 main.vaultlist.addVaultBtn=新增加密檔案庫 ## Vault Detail ### Welcome diff --git a/main/ui/src/main/resources/license/THIRD-PARTY.txt b/main/ui/src/main/resources/license/THIRD-PARTY.txt index c40dfa1d7..7420b0768 100644 --- a/main/ui/src/main/resources/license/THIRD-PARTY.txt +++ b/main/ui/src/main/resources/license/THIRD-PARTY.txt @@ -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 46 third-party dependencies under the following licenses: +Cryptomator uses 45 third-party dependencies under the following licenses: Apache License v2.0: - jffi (com.github.jnr:jffi:1.2.23 - http://github.com/jnr/jffi) - jnr-a64asm (com.github.jnr:jnr-a64asm:1.0.0 - http://nexus.sonatype.org/oss-repository-hosting.html/jnr-a64asm) @@ -30,39 +30,37 @@ Cryptomator uses 46 third-party dependencies under the following licenses: - Java Native Access (net.java.dev.jna:jna:5.7.0 - https://github.com/java-native-access/jna) - Java Native Access Platform (net.java.dev.jna:jna-platform:5.7.0 - https://github.com/java-native-access/jna) - Apache Commons Lang (org.apache.commons:commons-lang3:3.11 - https://commons.apache.org/proper/commons-lang/) - - 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.3 - http://jackrabbit.apache.org/jackrabbit-webdav/) - - Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-http) - - Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-io) - - Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-security) - - Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-server) - - Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-servlet) - - Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-util) - - Jetty :: Utilities :: Ajax(JSON) (org.eclipse.jetty:jetty-util-ajax:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-util-ajax) - - Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-webapp) - - Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-xml) + - Apache HttpCore (org.apache.httpcomponents:httpcore:4.4.14 - http://hc.apache.org/httpcomponents-core-ga) + - Jackrabbit WebDAV Library (org.apache.jackrabbit:jackrabbit-webdav:2.21.5 - http://jackrabbit.apache.org/jackrabbit-webdav/) + - Jetty :: Http Utility (org.eclipse.jetty:jetty-http:10.0.1 - https://eclipse.org/jetty/jetty-http) + - Jetty :: IO Utility (org.eclipse.jetty:jetty-io:10.0.1 - https://eclipse.org/jetty/jetty-io) + - Jetty :: Security (org.eclipse.jetty:jetty-security:10.0.1 - https://eclipse.org/jetty/jetty-security) + - Jetty :: Server Core (org.eclipse.jetty:jetty-server:10.0.1 - https://eclipse.org/jetty/jetty-server) + - Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:10.0.1 - https://eclipse.org/jetty/jetty-servlet) + - Jetty :: Utilities (org.eclipse.jetty:jetty-util:10.0.1 - https://eclipse.org/jetty/jetty-util) + - Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:10.0.1 - https://eclipse.org/jetty/jetty-webapp) + - Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:10.0.1 - https://eclipse.org/jetty/jetty-xml) 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/) - asm-commons (org.ow2.asm:asm-commons:7.1 - http://asm.ow2.org/) - 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.36.v20210114 - https://eclipse.org/jetty/jetty-http) - - Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-io) - - Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-security) - - Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-server) - - Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-servlet) - - Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-util) - - Jetty :: Utilities :: Ajax(JSON) (org.eclipse.jetty:jetty-util-ajax:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-util-ajax) - - Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-webapp) - - Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.36.v20210114 - https://eclipse.org/jetty/jetty-xml) + Eclipse Public License - Version 2.0: + - Jetty :: Http Utility (org.eclipse.jetty:jetty-http:10.0.1 - https://eclipse.org/jetty/jetty-http) + - Jetty :: IO Utility (org.eclipse.jetty:jetty-io:10.0.1 - https://eclipse.org/jetty/jetty-io) + - Jetty :: Security (org.eclipse.jetty:jetty-security:10.0.1 - https://eclipse.org/jetty/jetty-security) + - Jetty :: Server Core (org.eclipse.jetty:jetty-server:10.0.1 - https://eclipse.org/jetty/jetty-server) + - Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:10.0.1 - https://eclipse.org/jetty/jetty-servlet) + - Jetty :: Utilities (org.eclipse.jetty:jetty-util:10.0.1 - https://eclipse.org/jetty/jetty-util) + - Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:10.0.1 - https://eclipse.org/jetty/jetty-webapp) + - Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:10.0.1 - https://eclipse.org/jetty/jetty-xml) 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: - jnr-posix (com.github.jnr:jnr-posix:3.0.54 - http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix) GPLv2+CE: - - Java Servlet API (javax.servlet:javax.servlet-api:3.1.0 - http://servlet-spec.java.net) + - Java Servlet API (javax.servlet:javax.servlet-api:4.0.1 - https://javaee.github.io/servlet-spec/) - javafx-base (org.openjfx:javafx-base:15 - https://openjdk.java.net/projects/openjfx/javafx-base/) - javafx-controls (org.openjfx:javafx-controls:15 - https://openjdk.java.net/projects/openjfx/javafx-controls/) - javafx-fxml (org.openjfx:javafx-fxml:15 - https://openjdk.java.net/projects/openjfx/javafx-fxml/) @@ -72,7 +70,7 @@ Cryptomator uses 46 third-party dependencies under the following licenses: - Java Native Access (net.java.dev.jna:jna:5.7.0 - https://github.com/java-native-access/jna) - Java Native Access Platform (net.java.dev.jna:jna-platform:5.7.0 - https://github.com/java-native-access/jna) MIT License: - - java jwt (com.auth0:java-jwt:3.12.0 - https://github.com/auth0/java-jwt) + - java jwt (com.auth0:java-jwt:3.13.0 - https://github.com/auth0/java-jwt) - jnr-x86asm (com.github.jnr:jnr-x86asm:1.0.2 - http://github.com/jnr/jnr-x86asm) - jnr-fuse (com.github.serceman:jnr-fuse:0.5.5 - https://github.com/SerCeMan/jnr-fuse) - zxcvbn4j (com.nulab-inc:zxcvbn:1.3.0 - https://github.com/nulab/zxcvbn4j)