Merge branch 'release/1.8.0'

This commit is contained in:
Armin Schrenk
2023-04-25 10:45:08 +02:00
111 changed files with 1558 additions and 385 deletions

View File

@@ -1,13 +0,0 @@
# Configuration for probot-no-response - https://github.com/probot/no-response
# Number of days of inactivity before an Issue is closed for lack of response
daysUntilClose: 14
# Label requiring a response
responseRequiredLabel: state:awaiting-response
# Comment to post when closing an Issue for lack of response. Set to `false` to disable
closeComment: >
This issue has been automatically closed because there has been no response
to our request for more information from the original author. With only the
information that is currently in the issue, we don't have enough information
to take action. Please reach out if you have or find the answers we need so
that we can investigate further.

24
.github/stale.yml vendored
View File

@@ -1,24 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 365
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 90
# Issues with these labels will never be considered stale
exemptLabels:
- type:security-issue # never close automatically
- type:feature-request # never close automatically
- type:enhancement # never close automatically
- type:upstream-bug # never close automatically
- state:awaiting-response # handled by different bot
- state:blocked
- state:confirmed
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: true
# Label to use when marking an issue as stale
staleLabel: state:stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

22
.github/workflows/no-response.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
# Configuration for close-stale-issues - https://github.com/marketplace/actions/close-stale-issues
name: 'Close awaiting response issues'
on:
schedule:
- cron: '00 09 * * *'
jobs:
no-response:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v8
with:
days-before-stale: 14
days-before-close: 0
days-before-pr-close: -1
stale-issue-label: 'state:stale'
close-issue-message: "This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further."
only-labels: 'state:awaiting-response'

24
.github/workflows/stale.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
# Configuration for close-stale-issues - https://github.com/marketplace/actions/close-stale-issues
name: 'Close stale issues'
on:
schedule:
- cron: '00 09 * * *'
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v8
with:
days-before-stale: 365
days-before-close: 90
exempt-issue-labels: 'type:security-issue,type:feature-request,type:enhancement,type:upstream-bug,state:awaiting-response,state:blocked,state:confirmed'
exempt-all-milestones: true
stale-issue-label: 'state:stale'
stale-pr-label: 'state:stale'
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'

View File

@@ -66,6 +66,7 @@
</content_rating>
<releases>
<release date="2023-04-25" version="1.8.0"/>
<release date="2023-04-07" version="1.7.5"/>
<release date="2023-04-05" version="1.7.4"/>
<release date="2023-03-15" version="1.7.3"/>

View File

@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId>
<artifactId>cryptomator</artifactId>
<version>1.7.5</version>
<version>1.8.0</version>
<name>Cryptomator Desktop App</name>
<organization>

View File

@@ -1,5 +1,9 @@
package org.cryptomator.common;
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy;
import java.net.URI;
public interface Constants {
String MASTERKEY_FILENAME = "masterkey.cryptomator";
@@ -7,6 +11,7 @@ public interface Constants {
String VAULTCONFIG_FILENAME = "vault.cryptomator";
String CRYPTOMATOR_FILENAME_EXT = ".cryptomator";
String CRYPTOMATOR_FILENAME_GLOB = "*.cryptomator";
URI DEFAULT_KEY_ID = URI.create(MasterkeyFileLoadingStrategy.SCHEME + ":" + MASTERKEY_FILENAME);
byte[] PEPPER = new byte[0];
}

View File

@@ -11,8 +11,8 @@ import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.NewPasswordController;
import org.cryptomator.ui.common.PasswordStrengthUtil;
import org.cryptomator.ui.changepassword.NewPasswordController;
import org.cryptomator.ui.changepassword.PasswordStrengthUtil;
import org.cryptomator.ui.common.StageFactory;
import org.cryptomator.ui.fxapp.PrimaryStage;
import org.cryptomator.ui.recoverykey.RecoveryKeyDisplayController;

View File

@@ -13,7 +13,7 @@ import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.NewPasswordController;
import org.cryptomator.ui.changepassword.NewPasswordController;
import org.cryptomator.ui.common.Tasks;
import org.cryptomator.ui.fxapp.FxApplicationWindows;
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy;
@@ -48,13 +48,13 @@ import java.util.ResourceBundle;
import java.util.concurrent.ExecutorService;
import static java.nio.charset.StandardCharsets.US_ASCII;
import static org.cryptomator.common.Constants.DEFAULT_KEY_ID;
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
@AddVaultWizardScoped
public class CreateNewVaultPasswordController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(CreateNewVaultPasswordController.class);
private static final URI DEFAULT_KEY_ID = URI.create(MasterkeyFileLoadingStrategy.SCHEME + ":" + MASTERKEY_FILENAME); // TODO better place?
private final Stage window;
private final Lazy<Scene> chooseLocationScene;

View File

@@ -9,7 +9,6 @@ import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
import org.cryptomator.integrations.keychain.KeychainAccessException;
import org.cryptomator.ui.common.Animations;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.NewPasswordController;
import org.cryptomator.ui.controls.NiceSecurePasswordField;
import org.cryptomator.ui.fxapp.FxApplicationWindows;
import org.slf4j.Logger;

View File

@@ -10,8 +10,6 @@ import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.NewPasswordController;
import org.cryptomator.ui.common.PasswordStrengthUtil;
import org.cryptomator.ui.common.StageFactory;
import javax.inject.Named;

View File

@@ -1,5 +1,7 @@
package org.cryptomator.ui.common;
package org.cryptomator.ui.changepassword;
import org.cryptomator.common.Passphrase;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.controls.FontAwesome5IconView;
import org.cryptomator.ui.controls.NiceSecurePasswordField;
@@ -91,4 +93,8 @@ public class NewPasswordController implements FxController {
return passwordStrength.get();
}
public Passphrase getNewPassword() {
return passwordField.getCharacters();
}
}

View File

@@ -6,7 +6,7 @@
* Contributors:
* Jean-Noël Charon - initial API and implementation
*******************************************************************************/
package org.cryptomator.ui.common;
package org.cryptomator.ui.changepassword;
import com.nulabinc.zxcvbn.Zxcvbn;
import org.cryptomator.common.Environment;

View File

@@ -9,6 +9,9 @@ public enum FxmlFile {
ADDVAULT_SUCCESS("/fxml/addvault_success.fxml"), //
ADDVAULT_WELCOME("/fxml/addvault_welcome.fxml"), //
CHANGEPASSWORD("/fxml/changepassword.fxml"), //
CONVERTVAULT_HUBTOPASSWORD_START("/fxml/convertvault_hubtopassword_start.fxml"), //
CONVERTVAULT_HUBTOPASSWORD_CONVERT("/fxml/convertvault_hubtopassword_convert.fxml"), //
CONVERTVAULT_HUBTOPASSWORD_SUCCESS("/fxml/convertvault_hubtopassword_success.fxml"), //
ERROR("/fxml/error.fxml"), //
FORGET_PASSWORD("/fxml/forget_password.fxml"), //
HEALTH_START("/fxml/health_start.fxml"), //

View File

@@ -18,6 +18,7 @@ public enum FontAwesome5Icon {
COPY("\uF0C5"), //
CROWN("\uF521"), //
EDIT("\uF044"), //
EXCHANGE_ALT("\uF362"), //
EXCLAMATION("\uF12A"), //
EXCLAMATION_CIRCLE("\uF06A"), //
EXCLAMATION_TRIANGLE("\uF071"), //

View File

@@ -43,7 +43,7 @@ public class SecurePasswordField extends TextField {
private static final char WIPE_CHAR = ' ';
private static final int INITIAL_BUFFER_SIZE = 50;
private static final int GROW_BUFFER_SIZE = 50;
private static final String DEFAULT_PLACEHOLDER = "";
private static final String DEFAULT_PLACEHOLDER = "";
private static final String STYLE_CLASS = "secure-password-field";
private static final KeyCodeCombination SHORTCUT_BACKSPACE = new KeyCodeCombination(KeyCode.BACK_SPACE, KeyCombination.SHORTCUT_DOWN);

View File

@@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.ui.convertvault;
import dagger.BindsInstance;
import dagger.Lazy;
import dagger.Subcomponent;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import javax.inject.Named;
import javafx.scene.Scene;
import javafx.stage.Stage;
@ConvertVaultScoped
@Subcomponent(modules = {ConvertVaultModule.class})
public interface ConvertVaultComponent {
@ConvertVaultWindow
Stage window();
@FxmlScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_START)
Lazy<Scene> hubToPasswordScene();
default void showHubToPasswordWindow() {
Stage stage = window();
stage.setScene(hubToPasswordScene().get());
stage.sizeToScene();
stage.show();
}
@Subcomponent.Factory
interface Factory {
ConvertVaultComponent create(@BindsInstance @ConvertVaultWindow Vault vault, @BindsInstance @Named("convertVaultOwner") Stage owner);
}
}

View File

@@ -0,0 +1,126 @@
package org.cryptomator.ui.convertvault;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.cryptofs.VaultConfig;
import org.cryptomator.ui.changepassword.NewPasswordController;
import org.cryptomator.ui.changepassword.PasswordStrengthUtil;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
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.recoverykey.RecoveryKeyFactory;
import org.cryptomator.ui.recoverykey.RecoveryKeyValidateController;
import javax.inject.Named;
import javax.inject.Provider;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.Map;
import java.util.ResourceBundle;
@Module
abstract class ConvertVaultModule {
//TODO: if this fails, we cannot display an error
@Provides
@ConvertVaultWindow
@ConvertVaultScoped
static VaultConfig.UnverifiedVaultConfig vaultConfig(@ConvertVaultWindow Vault vault) {
try {
return vault.getVaultConfigCache().get();
} catch (IOException e) {
return null;
}
}
@Provides
@ConvertVaultWindow
@ConvertVaultScoped
static StringProperty provideRecoveryKeyProperty() {
return new SimpleStringProperty();
}
@Provides
@ConvertVaultWindow
@ConvertVaultScoped
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@ConvertVaultWindow
@ConvertVaultScoped
static Stage provideStage(StageFactory factory, @Named("convertVaultOwner") Stage owner, ResourceBundle resourceBundle) {
Stage stage = factory.create();
stage.setResizable(false);
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(owner);
stage.setTitle(resourceBundle.getString("convertVault.title"));
return stage;
}
@Provides
@FxmlScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_START)
@ConvertVaultScoped
static Scene provideHubToPasswordStartScene(@ConvertVaultWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_START);
}
@Provides
@FxmlScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_CONVERT)
@ConvertVaultScoped
static Scene provideHubToPasswordConvertScene(@ConvertVaultWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_CONVERT);
}
@Provides
@FxmlScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_SUCCESS)
@ConvertVaultScoped
static Scene provideHubToPasswordSuccessScene(@ConvertVaultWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_SUCCESS);
}
// ------------------
@Binds
@IntoMap
@FxControllerKey(HubToPasswordStartController.class)
abstract FxController bindHubToPasswordStartController(HubToPasswordStartController controller);
@Binds
@IntoMap
@FxControllerKey(HubToPasswordConvertController.class)
abstract FxController bindHubToPasswordConvertController(HubToPasswordConvertController controller);
@Binds
@IntoMap
@FxControllerKey(HubToPasswordSuccessController.class)
abstract FxController bindHubToPasswordSuccessController(HubToPasswordSuccessController controller);
@Provides
@IntoMap
@FxControllerKey(NewPasswordController.class)
static FxController provideNewPasswordController(ResourceBundle resourceBundle, PasswordStrengthUtil strengthRater) {
return new NewPasswordController(resourceBundle, strengthRater);
}
@Provides
@IntoMap
@FxControllerKey(RecoveryKeyValidateController.class)
static FxController bindRecoveryKeyValidateController(@ConvertVaultWindow Vault vault, @ConvertVaultWindow VaultConfig.UnverifiedVaultConfig vaultConfig, @ConvertVaultWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory) {
return new RecoveryKeyValidateController(vault, vaultConfig, recoveryKey, recoveryKeyFactory);
}
}

View File

@@ -0,0 +1,13 @@
package org.cryptomator.ui.convertvault;
import javax.inject.Scope;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Scope
@Documented
@Retention(RetentionPolicy.RUNTIME)
@interface ConvertVaultScoped {
}

View File

@@ -0,0 +1,14 @@
package org.cryptomator.ui.convertvault;
import javax.inject.Qualifier;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Qualifier
@Documented
@Retention(RUNTIME)
@interface ConvertVaultWindow {
}

View File

@@ -0,0 +1,171 @@
package org.cryptomator.ui.convertvault;
import com.google.common.base.Preconditions;
import dagger.Lazy;
import org.cryptomator.common.Constants;
import org.cryptomator.common.Passphrase;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.cryptofs.VaultConfig;
import org.cryptomator.cryptofs.VaultVersionMismatchException;
import org.cryptomator.cryptofs.common.BackupHelper;
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
import org.cryptomator.ui.changepassword.NewPasswordController;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.fxapp.FxApplicationWindows;
import org.cryptomator.ui.recoverykey.RecoveryKeyFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.stage.Stage;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ResourceBundle;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutorService;
import static java.nio.file.StandardOpenOption.CREATE_NEW;
import static java.nio.file.StandardOpenOption.WRITE;
import static org.cryptomator.common.Constants.MASTERKEY_BACKUP_SUFFIX;
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
public class HubToPasswordConvertController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(HubToPasswordConvertController.class);
private final Stage window;
private final Lazy<Scene> successScene;
private final FxApplicationWindows applicationWindows;
private final Vault vault;
private final StringProperty recoveryKey;
private final RecoveryKeyFactory recoveryKeyFactory;
private final MasterkeyFileAccess masterkeyFileAccess;
private final ExecutorService backgroundExecutorService;
private final ResourceBundle resourceBundle;
private final BooleanProperty conversionStarted;
@FXML
NewPasswordController newPasswordController;
public Button convertBtn;
@Inject
public HubToPasswordConvertController(@ConvertVaultWindow Stage window, @FxmlScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_SUCCESS) Lazy<Scene> successScene, FxApplicationWindows applicationWindows, @ConvertVaultWindow Vault vault, @ConvertVaultWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, MasterkeyFileAccess masterkeyFileAccess, ExecutorService backgroundExecutorService, ResourceBundle resourceBundle) {
this.window = window;
this.successScene = successScene;
this.applicationWindows = applicationWindows;
this.vault = vault;
this.recoveryKey = recoveryKey;
this.recoveryKeyFactory = recoveryKeyFactory;
this.masterkeyFileAccess = masterkeyFileAccess;
this.backgroundExecutorService = backgroundExecutorService;
this.resourceBundle = resourceBundle;
this.conversionStarted = new SimpleBooleanProperty(false);
}
@FXML
public void initialize() {
convertBtn.disableProperty().bind(Bindings.createBooleanBinding( //
() -> !newPasswordController.isGoodPassword() || conversionStarted.get(), //
newPasswordController.goodPasswordProperty(), //
conversionStarted));
convertBtn.contentDisplayProperty().bind(Bindings.createObjectBinding( //
() -> conversionStarted.getValue() ? ContentDisplay.LEFT : ContentDisplay.TEXT_ONLY, //
conversionStarted));
convertBtn.textProperty().bind(Bindings.createStringBinding( //
() -> resourceBundle.getString("convertVault.convert.convertBtn." + (conversionStarted.get() ? "processing" : "before")), //
conversionStarted));
}
@FXML
public void close() {
window.close();
}
@FXML
public void convert() {
Preconditions.checkState(newPasswordController.isGoodPassword());
LOG.info("Converting access method of vault {} from hub to password", vault.getPath());
CompletableFuture.runAsync(() -> conversionStarted.setValue(true), Platform::runLater) //
.thenRunAsync(this::convertInternal, backgroundExecutorService) //
.whenCompleteAsync((result, exception) -> {
if (exception == null) {
LOG.info("Conversion of vault {} succeeded.", vault.getPath());
window.setScene(successScene.get());
} else {
LOG.error("Conversion of vault {} failed.", vault.getPath(), exception);
applicationWindows.showErrorWindow(exception, window, null);
}
}, Platform::runLater); //
}
//visible for testing
void convertInternal() throws CompletionException, IllegalArgumentException {
var passphrase = newPasswordController.getNewPassword();
var vaultPath = vault.getPath();
try {
//create masterkey
recoveryKeyFactory.newMasterkeyFileWithPassphrase(vaultPath, recoveryKey.get(), passphrase);
LOG.debug("Successfully created masterkey file for vault {}", vaultPath);
//create password config
Path passwordConfigPath = vaultPath.resolve("passwordBased." + VAULTCONFIG_FILENAME + ".tmp");
passwordConfigPath = createPasswordConfig(passwordConfigPath, vaultPath.resolve(MASTERKEY_FILENAME), passphrase);
//backup hub config
var hubConfigPath = vaultPath.resolve(VAULTCONFIG_FILENAME);
backupHubConfig(hubConfigPath);
//replace hub by password
Files.move(passwordConfigPath, hubConfigPath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
} catch (MasterkeyLoadingFailedException e) {
throw new CompletionException(new IOException("Vault conversion failed", e));
} catch (IOException e) {
throw new CompletionException("Vault conversion failed", e);
} finally {
passphrase.destroy();
}
}
//visible for testing
void backupHubConfig(Path hubConfigPath) throws IOException {
byte[] hubConfigBytes = Files.readAllBytes(hubConfigPath);
Path backupPath = hubConfigPath.resolveSibling(VAULTCONFIG_FILENAME + BackupHelper.generateFileIdSuffix(hubConfigBytes) + MASTERKEY_BACKUP_SUFFIX);
Files.copy(hubConfigPath, backupPath, StandardCopyOption.REPLACE_EXISTING);
LOG.debug("Successfully created hub config backup {}", backupPath.getFileName());
}
//visible for testing
Path createPasswordConfig(Path passwordConfigPath, Path masterkeyFile, Passphrase passphrase) throws IOException, MasterkeyLoadingFailedException {
var unverifiedVaultConfig = vault.getVaultConfigCache().get();
try (var masterkey = masterkeyFileAccess.load(masterkeyFile, passphrase)) {
var hubConfig = unverifiedVaultConfig.verify(masterkey.getEncoded(), unverifiedVaultConfig.allegedVaultVersion());
var passwordConfig = VaultConfig.createNew() //
.cipherCombo(hubConfig.getCipherCombo()) //
.shorteningThreshold(hubConfig.getShorteningThreshold()) //
.build();
if (passwordConfig.getVaultVersion() != hubConfig.getVaultVersion()) {
throw new VaultVersionMismatchException("Only vaults of version " + passwordConfig.getVaultVersion() + " can be converted.");
}
var token = passwordConfig.toToken(Constants.DEFAULT_KEY_ID.toString(), masterkey.getEncoded());
Files.writeString(passwordConfigPath, token, StandardCharsets.US_ASCII, WRITE, CREATE_NEW);
LOG.debug("Successfully created password config {}", passwordConfigPath);
return passwordConfigPath;
}
}
}

View File

@@ -0,0 +1,47 @@
package org.cryptomator.ui.convertvault;
import dagger.Lazy;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.recoverykey.RecoveryKeyValidateController;
import javax.inject.Inject;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class HubToPasswordStartController implements FxController {
private final Stage window;
private final Lazy<Scene> convertScene;
@FXML
RecoveryKeyValidateController recoveryKeyValidateController;
@Inject
public HubToPasswordStartController(@ConvertVaultWindow Stage window, @FxmlScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_CONVERT) Lazy<Scene> convertScene) {
this.window = window;
this.convertScene = convertScene;
}
@FXML
public void initialize() {
}
@FXML
public void close() {
window.close();
}
@FXML
public void next() {
window.setScene(convertScene.get());
}
/* Getter/Setter */
public RecoveryKeyValidateController getValidateController() {
return recoveryKeyValidateController;
}
}

View File

@@ -0,0 +1,32 @@
package org.cryptomator.ui.convertvault;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import javax.inject.Inject;
import javafx.fxml.FXML;
import javafx.stage.Stage;
public class HubToPasswordSuccessController implements FxController {
private final Stage window;
private final Vault vault;
@Inject
HubToPasswordSuccessController(@ConvertVaultWindow Stage window, @ConvertVaultWindow Vault vault) {
this.window = window;
this.vault = vault;
}
@FXML
public void close() {
window.close();
window.getOwner().hide();
}
/* Observables */
public Vault getVault() {
return vault;
}
}

View File

@@ -1,8 +1,10 @@
package org.cryptomator.ui.common;
package org.cryptomator.ui.error;
import dagger.BindsInstance;
import dagger.Subcomponent;
import org.cryptomator.common.Nullable;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import javafx.scene.Scene;
import javafx.stage.Stage;

View File

@@ -1,8 +1,9 @@
package org.cryptomator.ui.common;
package org.cryptomator.ui.error;
import org.cryptomator.common.Environment;
import org.cryptomator.common.ErrorCode;
import org.cryptomator.common.Nullable;
import org.cryptomator.ui.common.FxController;
import javax.inject.Inject;
import javax.inject.Named;

View File

@@ -1,10 +1,16 @@
package org.cryptomator.ui.common;
package org.cryptomator.ui.error;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.common.ErrorCode;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxmlScene;
import javax.inject.Named;
import javax.inject.Provider;

View File

@@ -1,4 +1,4 @@
package org.cryptomator.ui.forgetPassword;
package org.cryptomator.ui.forgetpassword;
import dagger.BindsInstance;
import dagger.Lazy;

View File

@@ -1,4 +1,4 @@
package org.cryptomator.ui.forgetPassword;
package org.cryptomator.ui.forgetpassword;
import org.cryptomator.common.keychain.KeychainManager;
import org.cryptomator.common.vaults.Vault;

View File

@@ -1,4 +1,4 @@
package org.cryptomator.ui.forgetPassword;
package org.cryptomator.ui.forgetpassword;
import dagger.Binds;
import dagger.Module;

View File

@@ -1,4 +1,4 @@
package org.cryptomator.ui.forgetPassword;
package org.cryptomator.ui.forgetpassword;
import javax.inject.Scope;
import java.lang.annotation.Documented;

View File

@@ -1,4 +1,4 @@
package org.cryptomator.ui.forgetPassword;
package org.cryptomator.ui.forgetpassword;
import javax.inject.Qualifier;
import java.lang.annotation.Documented;

View File

@@ -7,9 +7,7 @@ package org.cryptomator.ui.fxapp;
import dagger.Module;
import dagger.Provides;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.common.StageFactory;
import org.cryptomator.ui.error.ErrorComponent;
import org.cryptomator.ui.lock.LockComponent;
import org.cryptomator.ui.mainwindow.MainWindowComponent;
import org.cryptomator.ui.preferences.PreferencesComponent;
@@ -18,13 +16,9 @@ import org.cryptomator.ui.quit.QuitComponent;
import org.cryptomator.ui.traymenu.TrayMenuComponent;
import org.cryptomator.ui.unlock.UnlockComponent;
import javax.inject.Named;
import javafx.scene.image.Image;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.Collections;
import java.util.List;
@Module(includes = {UpdateCheckerModule.class}, subcomponents = {TrayMenuComponent.class, MainWindowComponent.class, PreferencesComponent.class, UnlockComponent.class, LockComponent.class, QuitComponent.class, ErrorComponent.class})
abstract class FxApplicationModule {

View File

@@ -5,7 +5,7 @@ import dagger.Lazy;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultState;
import org.cryptomator.integrations.tray.TrayIntegrationProvider;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.error.ErrorComponent;
import org.cryptomator.ui.lock.LockComponent;
import org.cryptomator.ui.mainwindow.MainWindowComponent;
import org.cryptomator.ui.preferences.PreferencesComponent;

View File

@@ -15,8 +15,6 @@ import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.NewPasswordController;
import org.cryptomator.ui.common.PasswordStrengthUtil;
import org.cryptomator.ui.keyloading.KeyLoading;
import org.cryptomator.ui.keyloading.KeyLoadingScoped;
import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
@@ -153,13 +151,6 @@ public abstract class HubKeyLoadingModule {
@FxControllerKey(AuthFlowController.class)
abstract FxController bindAuthFlowController(AuthFlowController controller);
@Provides
@IntoMap
@FxControllerKey(NewPasswordController.class)
static FxController provideNewPasswordController(ResourceBundle resourceBundle, PasswordStrengthUtil strengthRater) {
return new NewPasswordController(resourceBundle, strengthRater);
}
@Binds
@IntoMap
@FxControllerKey(InvalidLicenseController.class)

View File

@@ -29,8 +29,8 @@ import java.util.concurrent.ExecutionException;
public class HubKeyLoadingStrategy implements KeyLoadingStrategy {
private static final String SCHEME_PREFIX = "hub+";
static final String SCHEME_HUB_HTTP = SCHEME_PREFIX + "http";
static final String SCHEME_HUB_HTTPS = SCHEME_PREFIX + "https";
public static final String SCHEME_HUB_HTTP = SCHEME_PREFIX + "http";
public static final String SCHEME_HUB_HTTPS = SCHEME_PREFIX + "https";
private final Stage window;
private final KeychainManager keychainManager;

View File

@@ -8,7 +8,7 @@ import dagger.multibindings.StringKey;
import org.cryptomator.common.keychain.KeychainManager;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.integrations.keychain.KeychainAccessException;
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
import org.cryptomator.ui.forgetpassword.ForgetPasswordComponent;
import org.cryptomator.ui.keyloading.KeyLoading;
import org.cryptomator.ui.keyloading.KeyLoadingScoped;
import org.cryptomator.ui.keyloading.KeyLoadingStrategy;

View File

@@ -7,7 +7,7 @@ import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.WeakBindings;
import org.cryptomator.ui.controls.NiceSecurePasswordField;
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
import org.cryptomator.ui.forgetpassword.ForgetPasswordComponent;
import org.cryptomator.ui.keyloading.KeyLoading;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@@ -6,7 +6,7 @@ import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.error.ErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;

View File

@@ -38,16 +38,11 @@ public interface RecoveryKeyComponent {
stage.show();
}
@Subcomponent.Builder
interface Builder {
@BindsInstance
Builder vault(@RecoveryKeyWindow Vault vault);
@Subcomponent.Factory
interface Factory {
@BindsInstance
Builder owner(@Named("keyRecoveryOwner") Stage owner);
RecoveryKeyComponent build();
RecoveryKeyComponent create(@BindsInstance @RecoveryKeyWindow Vault vault, @BindsInstance @Named("keyRecoveryOwner") Stage owner);
}
}

View File

@@ -81,7 +81,7 @@ public class RecoveryKeyFactory {
* @throws IllegalArgumentException If the recoveryKey is invalid
* @apiNote This is a long-running operation and should be invoked in a background thread
*/
public void resetPasswordWithRecoveryKey(Path vaultPath, String recoveryKey, CharSequence newPassword) throws IOException, IllegalArgumentException {
public void newMasterkeyFileWithPassphrase(Path vaultPath, String recoveryKey, CharSequence newPassword) throws IOException, IllegalArgumentException {
final byte[] rawKey = decodeRecoveryKey(recoveryKey);
try (var masterkey = new Masterkey(rawKey)) {
Path masterkeyPath = vaultPath.resolve(MASTERKEY_FILENAME);

View File

@@ -13,8 +13,8 @@ import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.NewPasswordController;
import org.cryptomator.ui.common.PasswordStrengthUtil;
import org.cryptomator.ui.changepassword.NewPasswordController;
import org.cryptomator.ui.changepassword.PasswordStrengthUtil;
import org.cryptomator.ui.common.StageFactory;
import javax.inject.Named;
@@ -140,6 +140,13 @@ abstract class RecoveryKeyModule {
@FxControllerKey(RecoveryKeyResetPasswordSuccessController.class)
abstract FxController bindRecoveryKeyResetPasswordSuccessController(RecoveryKeyResetPasswordSuccessController controller);
@Provides
@IntoMap
@FxControllerKey(RecoveryKeyValidateController.class)
static FxController bindRecoveryKeyValidateController(@RecoveryKeyWindow Vault vault, @RecoveryKeyWindow @Nullable VaultConfig.UnverifiedVaultConfig vaultConfig, @RecoveryKeyWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory) {
return new RecoveryKeyValidateController(vault, vaultConfig, recoveryKey, recoveryKeyFactory);
}
@Provides
@IntoMap
@FxControllerKey(NewPasswordController.class)

View File

@@ -1,14 +1,9 @@
package org.cryptomator.ui.recoverykey;
import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
import dagger.Lazy;
import org.cryptomator.common.Nullable;
import org.cryptomator.common.ObservableUtil;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.cryptofs.VaultConfig;
import org.cryptomator.cryptofs.VaultConfigLoadException;
import org.cryptomator.cryptofs.VaultKeyInvalidException;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
@@ -16,96 +11,34 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.Observable;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextFormatter;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
import java.util.Optional;
import java.util.ResourceBundle;
@RecoveryKeyScoped
public class RecoveryKeyRecoverController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(RecoveryKeyCreationController.class);
private static final CharMatcher ALLOWED_CHARS = CharMatcher.inRange('a', 'z').or(CharMatcher.is(' '));
private final Stage window;
private final Vault vault;
private final VaultConfig.UnverifiedVaultConfig unverifiedVaultConfig;
private final StringProperty recoveryKey;
private final ObservableValue<Boolean> recoveryKeyCorrect;
private final ObservableValue<Boolean> recoveryKeyWrong;
private final ObservableValue<Boolean> recoveryKeyInvalid;
private final RecoveryKeyFactory recoveryKeyFactory;
private final ObjectProperty<RecoveryKeyState> recoveryKeyState;
private final Lazy<Scene> resetPasswordScene;
private final AutoCompleter autoCompleter;
private volatile boolean isWrongKey;
public TextArea textarea;
@FXML
RecoveryKeyValidateController recoveryKeyValidateController;
@Inject
public RecoveryKeyRecoverController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, @RecoveryKeyWindow @Nullable VaultConfig.UnverifiedVaultConfig unverifiedVaultConfig, @RecoveryKeyWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, @FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD) Lazy<Scene> resetPasswordScene, ResourceBundle resourceBundle) {
public RecoveryKeyRecoverController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, @RecoveryKeyWindow StringProperty recoveryKey, @FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD) Lazy<Scene> resetPasswordScene, ResourceBundle resourceBundle) {
this.window = window;
window.setTitle(resourceBundle.getString("recoveryKey.recover.title"));
this.vault = vault;
this.unverifiedVaultConfig = unverifiedVaultConfig;
this.recoveryKey = recoveryKey;
this.recoveryKeyFactory = recoveryKeyFactory;
this.resetPasswordScene = resetPasswordScene;
this.autoCompleter = new AutoCompleter(recoveryKeyFactory.getDictionary());
this.recoveryKeyState = new SimpleObjectProperty<>();
this.recoveryKeyCorrect = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.CORRECT::equals, false);
this.recoveryKeyWrong = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.WRONG::equals, false);
this.recoveryKeyInvalid = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.INVALID::equals, false);
}
@FXML
public void initialize() {
recoveryKey.bind(textarea.textProperty());
textarea.textProperty().addListener(((observable, oldValue, newValue) -> validateRecoveryKey()));
}
private TextFormatter.Change filterTextChange(TextFormatter.Change change) {
if (Strings.isNullOrEmpty(change.getText())) {
// pass-through caret/selection changes that don't affect the text
return change;
}
if (!ALLOWED_CHARS.matchesAllOf(change.getText())) {
return null; // reject change
}
String text = change.getControlNewText();
int caretPos = change.getCaretPosition();
if (caretPos == text.length() || text.charAt(caretPos) == ' ') { // are we at the end of a word?
int beginOfWord = Math.max(text.substring(0, caretPos).lastIndexOf(' ') + 1, 0);
String currentWord = text.substring(beginOfWord, caretPos);
Optional<String> suggestion = autoCompleter.autocomplete(currentWord);
if (suggestion.isPresent()) {
String completion = suggestion.get().substring(currentWord.length());
change.setText(change.getText() + completion);
change.setAnchor(caretPos + completion.length());
}
}
return change;
}
@FXML
public void onKeyPressed(KeyEvent keyEvent) {
if (keyEvent.getCode() == KeyCode.TAB && textarea.getAnchor() > textarea.getCaretPosition()) {
// apply autocompletion:
int pos = textarea.getAnchor();
textarea.insertText(pos, " ");
textarea.positionCaret(pos + 1);
}
}
@FXML
@@ -118,85 +51,10 @@ public class RecoveryKeyRecoverController implements FxController {
window.setScene(resetPasswordScene.get());
}
/**
* Checks, if vault config is signed with the given key.
*
* @param key byte array of possible signing key
* @return true, if vault config is signed with this key
*/
private boolean checkKeyAgainstVaultConfig(byte[] key) {
try {
var config = unverifiedVaultConfig.verify(key, unverifiedVaultConfig.allegedVaultVersion());
LOG.info("Provided recovery key matches vault config signature for vault {}", config.getId());
return true;
} catch (VaultKeyInvalidException e) {
LOG.debug("Provided recovery key does not match vault config signature.");
isWrongKey = true;
return false;
} catch (VaultConfigLoadException e) {
LOG.error("Failed to parse vault config", e);
return false;
}
}
private void validateRecoveryKey() {
isWrongKey = false;
var valid = recoveryKeyFactory.validateRecoveryKey(recoveryKey.get(), unverifiedVaultConfig != null ? this::checkKeyAgainstVaultConfig : null);
if (valid) {
recoveryKeyState.set(RecoveryKeyState.CORRECT);
} else if (isWrongKey) { //set via side effect in checkKeyAgainstVaultConfig()
recoveryKeyState.set(RecoveryKeyState.WRONG);
} else {
recoveryKeyState.set(RecoveryKeyState.INVALID);
}
}
/* Getter/Setter */
public Vault getVault() {
return vault;
public RecoveryKeyValidateController getValidateController() {
return recoveryKeyValidateController;
}
public TextFormatter getRecoveryKeyTextFormatter() {
return new TextFormatter<>(this::filterTextChange);
}
public ObservableValue<Boolean> recoveryKeyInvalidProperty() {
return recoveryKeyInvalid;
}
public boolean isRecoveryKeyInvalid() {
return recoveryKeyInvalid.getValue();
}
public ObservableValue<Boolean> recoveryKeyCorrectProperty() {
return recoveryKeyCorrect;
}
public boolean isRecoveryKeyCorrect() {
return recoveryKeyCorrect.getValue();
}
public ObservableValue<Boolean> recoveryKeyWrongProperty() {
return recoveryKeyWrong;
}
public boolean isRecoveryKeyWrong() {
return recoveryKeyWrong.getValue();
}
private enum RecoveryKeyState {
/**
* Recovery key is a valid key and belongs to this vault
*/
CORRECT,
/**
* Recovery key is a valid key, but does not belong to this vault
*/
WRONG,
/**
* Recovery key is not a valid key.
*/
INVALID;
}
}

View File

@@ -5,7 +5,7 @@ import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.NewPasswordController;
import org.cryptomator.ui.changepassword.NewPasswordController;
import org.cryptomator.ui.fxapp.FxApplicationWindows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -76,7 +76,7 @@ public class RecoveryKeyResetPasswordController implements FxController {
@Override
protected Void call() throws IOException, IllegalArgumentException {
recoveryKeyFactory.resetPasswordWithRecoveryKey(vault.getPath(), recoveryKey.get(), newPasswordController.passwordField.getCharacters());
recoveryKeyFactory.newMasterkeyFileWithPassphrase(vault.getPath(), recoveryKey.get(), newPasswordController.passwordField.getCharacters());
return null;
}

View File

@@ -0,0 +1,180 @@
package org.cryptomator.ui.recoverykey;
import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
import org.cryptomator.common.Nullable;
import org.cryptomator.common.ObservableUtil;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.cryptofs.VaultConfig;
import org.cryptomator.cryptofs.VaultConfigLoadException;
import org.cryptomator.cryptofs.VaultKeyInvalidException;
import org.cryptomator.ui.common.FxController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextFormatter;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
public class RecoveryKeyValidateController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(RecoveryKeyCreationController.class);
private static final CharMatcher ALLOWED_CHARS = CharMatcher.inRange('a', 'z').or(CharMatcher.is(' '));
private final Vault vault;
private final VaultConfig.UnverifiedVaultConfig unverifiedVaultConfig;
private final StringProperty recoveryKey;
private final ObservableValue<Boolean> recoveryKeyCorrect;
private final ObservableValue<Boolean> recoveryKeyWrong;
private final ObservableValue<Boolean> recoveryKeyInvalid;
private final RecoveryKeyFactory recoveryKeyFactory;
private final ObjectProperty<RecoveryKeyState> recoveryKeyState;
private final AutoCompleter autoCompleter;
private volatile boolean isWrongKey;
public TextArea textarea;
public RecoveryKeyValidateController(Vault vault, @Nullable VaultConfig.UnverifiedVaultConfig vaultConfig, StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory) {
this.vault = vault;
this.unverifiedVaultConfig = vaultConfig;
this.recoveryKey = recoveryKey;
this.recoveryKeyFactory = recoveryKeyFactory;
this.autoCompleter = new AutoCompleter(recoveryKeyFactory.getDictionary());
this.recoveryKeyState = new SimpleObjectProperty<>();
this.recoveryKeyCorrect = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.CORRECT::equals, false);
this.recoveryKeyWrong = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.WRONG::equals, false);
this.recoveryKeyInvalid = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.INVALID::equals, false);
}
@FXML
public void initialize() {
recoveryKey.bind(textarea.textProperty());
textarea.textProperty().addListener(((observable, oldValue, newValue) -> validateRecoveryKey()));
}
private TextFormatter.Change filterTextChange(TextFormatter.Change change) {
if (Strings.isNullOrEmpty(change.getText())) {
// pass-through caret/selection changes that don't affect the text
return change;
}
if (!ALLOWED_CHARS.matchesAllOf(change.getText())) {
return null; // reject change
}
String text = change.getControlNewText();
int caretPos = change.getCaretPosition();
if (caretPos == text.length() || text.charAt(caretPos) == ' ') { // are we at the end of a word?
int beginOfWord = Math.max(text.substring(0, caretPos).lastIndexOf(' ') + 1, 0);
String currentWord = text.substring(beginOfWord, caretPos);
var suggestion = autoCompleter.autocomplete(currentWord);
if (suggestion.isPresent()) {
String completion = suggestion.get().substring(currentWord.length());
change.setText(change.getText() + completion);
change.setAnchor(caretPos + completion.length());
}
}
return change;
}
@FXML
public void onKeyPressed(KeyEvent keyEvent) {
if (keyEvent.getCode() == KeyCode.TAB && textarea.getAnchor() > textarea.getCaretPosition()) {
// apply autocompletion:
int pos = textarea.getAnchor();
textarea.insertText(pos, " ");
textarea.positionCaret(pos + 1);
}
}
/**
* Checks, if vault config is signed with the given key.
*
* @param key byte array of possible signing key
* @return true, if vault config is signed with this key
*/
private boolean checkKeyAgainstVaultConfig(byte[] key) {
assert unverifiedVaultConfig != null;
try {
var config = unverifiedVaultConfig.verify(key, unverifiedVaultConfig.allegedVaultVersion());
LOG.info("Provided recovery key matches vault config signature for vault {}", config.getId());
return true;
} catch (VaultKeyInvalidException e) {
LOG.debug("Provided recovery key does not match vault config signature.");
isWrongKey = true;
return false;
} catch (VaultConfigLoadException e) {
LOG.error("Failed to parse vault config", e);
return false;
}
}
private void validateRecoveryKey() {
isWrongKey = false;
var valid = recoveryKeyFactory.validateRecoveryKey(recoveryKey.get(), unverifiedVaultConfig != null ? this::checkKeyAgainstVaultConfig : null);
if (valid) {
recoveryKeyState.set(RecoveryKeyState.CORRECT);
} else if (isWrongKey) { //set via side effect in checkKeyAgainstVaultConfig()
recoveryKeyState.set(RecoveryKeyState.WRONG);
} else {
recoveryKeyState.set(RecoveryKeyState.INVALID);
}
}
/* Getter/Setter */
public Vault getVault() {
return vault;
}
public TextFormatter getRecoveryKeyTextFormatter() {
return new TextFormatter<>(this::filterTextChange);
}
public ObservableValue<Boolean> recoveryKeyInvalidProperty() {
return recoveryKeyInvalid;
}
public boolean isRecoveryKeyInvalid() {
return recoveryKeyInvalid.getValue();
}
public ObservableValue<Boolean> recoveryKeyCorrectProperty() {
return recoveryKeyCorrect;
}
public boolean isRecoveryKeyCorrect() {
return recoveryKeyCorrect.getValue();
}
public ObservableValue<Boolean> recoveryKeyWrongProperty() {
return recoveryKeyWrong;
}
public boolean isRecoveryKeyWrong() {
return recoveryKeyWrong.getValue();
}
private enum RecoveryKeyState {
/**
* Recovery key is a valid key and belongs to this vault
*/
CORRECT,
/**
* Recovery key is a valid key, but does not belong to this vault
*/
WRONG,
/**
* Recovery key is not a valid key.
*/
INVALID;
}
}

View File

@@ -0,0 +1,27 @@
package org.cryptomator.ui.vaultoptions;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.convertvault.ConvertVaultComponent;
import javax.inject.Inject;
import javafx.stage.Stage;
public class HubOptionsController implements FxController {
private final Vault vault;
private final Stage window;
private final ConvertVaultComponent.Factory convertVaultFactory;
@Inject
public HubOptionsController(@VaultOptionsWindow Vault vault, @VaultOptionsWindow Stage window, ConvertVaultComponent.Factory convertVaultFactory) {
this.vault = vault;
this.window = window;
this.convertVaultFactory = convertVaultFactory;
}
public void startConversion() {
convertVaultFactory.create(vault,window).showHubToPasswordWindow();
}
}

View File

@@ -4,7 +4,7 @@ import org.cryptomator.common.keychain.KeychainManager;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.changepassword.ChangePasswordComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
import org.cryptomator.ui.forgetpassword.ForgetPasswordComponent;
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -23,14 +23,14 @@ public class MasterkeyOptionsController implements FxController {
private final Vault vault;
private final Stage window;
private final ChangePasswordComponent.Builder changePasswordWindow;
private final RecoveryKeyComponent.Builder recoveryKeyWindow;
private final RecoveryKeyComponent.Factory recoveryKeyWindow;
private final ForgetPasswordComponent.Builder forgetPasswordWindow;
private final KeychainManager keychain;
private final ObservableValue<Boolean> passwordSaved;
@Inject
MasterkeyOptionsController(@VaultOptionsWindow Vault vault, @VaultOptionsWindow Stage window, ChangePasswordComponent.Builder changePasswordWindow, RecoveryKeyComponent.Builder recoveryKeyWindow, ForgetPasswordComponent.Builder forgetPasswordWindow, KeychainManager keychain) {
MasterkeyOptionsController(@VaultOptionsWindow Vault vault, @VaultOptionsWindow Stage window, ChangePasswordComponent.Builder changePasswordWindow, RecoveryKeyComponent.Factory recoveryKeyWindow, ForgetPasswordComponent.Builder forgetPasswordWindow, KeychainManager keychain) {
this.vault = vault;
this.window = window;
this.changePasswordWindow = changePasswordWindow;
@@ -51,12 +51,12 @@ public class MasterkeyOptionsController implements FxController {
@FXML
public void showRecoveryKey() {
recoveryKeyWindow.vault(vault).owner(window).build().showRecoveryKeyCreationWindow();
recoveryKeyWindow.create(vault, window).showRecoveryKeyCreationWindow();
}
@FXML
public void showRecoverVaultDialog() {
recoveryKeyWindow.vault(vault).owner(window).build().showRecoveryKeyRecoverWindow();
recoveryKeyWindow.create(vault, window).showRecoveryKeyRecoverWindow();
}
@FXML

View File

@@ -21,4 +21,9 @@ public enum SelectedVaultOptionsTab {
*/
KEY,
/**
* Show hub tab
*/
HUB
}

View File

@@ -2,6 +2,8 @@ package org.cryptomator.ui.vaultoptions;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.keyloading.hub.HubKeyLoadingStrategy;
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -25,6 +27,7 @@ public class VaultOptionsController implements FxController {
public Tab generalTab;
public Tab mountTab;
public Tab keyTab;
public Tab hubTab;
@Inject
VaultOptionsController(@VaultOptionsWindow Stage window, @VaultOptionsWindow Vault vault, ObjectProperty<SelectedVaultOptionsTab> selectedTabProperty) {
@@ -38,9 +41,13 @@ public class VaultOptionsController implements FxController {
window.setOnShowing(this::windowWillAppear);
selectedTabProperty.addListener(observable -> this.selectChosenTab());
tabPane.getSelectionModel().selectedItemProperty().addListener(observable -> this.selectedTabChanged());
if(!vault.getVaultConfigCache().getUnchecked().getKeyId().getScheme().equals("masterkeyfile")){
var vaultScheme = vault.getVaultConfigCache().getUnchecked().getKeyId().getScheme();
if(!vaultScheme.equals(MasterkeyFileLoadingStrategy.SCHEME)){
tabPane.getTabs().remove(keyTab);
}
if(!(vaultScheme.equals(HubKeyLoadingStrategy.SCHEME_HUB_HTTP) || vaultScheme.equals(HubKeyLoadingStrategy.SCHEME_HUB_HTTPS))){
tabPane.getTabs().remove(hubTab);
}
}
private void selectChosenTab() {
@@ -53,6 +60,7 @@ public class VaultOptionsController implements FxController {
case ANY, GENERAL -> generalTab;
case MOUNT -> mountTab;
case KEY -> keyTab;
case HUB -> hubTab;
};
}

View File

@@ -13,7 +13,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.forgetPassword.ForgetPasswordComponent;
import org.cryptomator.ui.convertvault.ConvertVaultComponent;
import org.cryptomator.ui.forgetpassword.ForgetPasswordComponent;
import org.cryptomator.ui.fxapp.PrimaryStage;
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
@@ -26,7 +27,7 @@ import javafx.stage.Stage;
import java.util.Map;
import java.util.ResourceBundle;
@Module(subcomponents = {ChangePasswordComponent.class, RecoveryKeyComponent.class, ForgetPasswordComponent.class})
@Module(subcomponents = {ChangePasswordComponent.class, RecoveryKeyComponent.class, ForgetPasswordComponent.class, ConvertVaultComponent.class})
abstract class VaultOptionsModule {
@Provides
@@ -84,4 +85,9 @@ abstract class VaultOptionsModule {
@IntoMap
@FxControllerKey(MasterkeyOptionsController.class)
abstract FxController bindMasterkeyOptionsController(MasterkeyOptionsController controller);
@Binds
@IntoMap
@FxControllerKey(HubOptionsController.class)
abstract FxController bindHubOptionsController(HubOptionsController controller);
}

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import org.cryptomator.ui.controls.FontAwesome5Spinner?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.convertvault.HubToPasswordConvertController"
minWidth="400"
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_CENTER">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>
<children>
<fx:include fx:id="newPassword" source="new_password.fxml"/>
<Region VBox.vgrow="ALWAYS"/>
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
<ButtonBar buttonMinWidth="120" buttonOrder="+CI">
<buttons>
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
<Button fx:id="convertBtn" ButtonBar.buttonData="FINISH" defaultButton="true" onAction="#convert"> <!-- for button logic, see controller -->
<graphic>
<FontAwesome5Spinner glyphSize="12"/>
</graphic>
</Button>
</buttons>
</ButtonBar>
</VBox>
</children>
</VBox>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.Button?>
<VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.convertvault.HubToPasswordStartController"
minWidth="400"
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_CENTER">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>
<children>
<fx:include fx:id="recoveryKeyValidate" source="recoverykey_validate.fxml"/>
<Region VBox.vgrow="ALWAYS"/>
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
<ButtonBar buttonMinWidth="120" buttonOrder="+CX">
<buttons>
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#next" disable="${!controller.validateController.recoveryKeyCorrect}"/>
</buttons>
</ButtonBar>
</VBox>
</children>
</VBox>

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import org.cryptomator.ui.controls.FormattedLabel?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Circle?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.Group?>
<HBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.convertvault.HubToPasswordSuccessController"
minWidth="400"
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>
<children>
<Group>
<StackPane>
<padding>
<Insets topRightBottomLeft="6"/>
</padding>
<Circle styleClass="glyph-icon-primary" radius="24"/>
<FontAwesome5IconView styleClass="glyph-icon-white" glyph="CHECK" glyphSize="24"/>
</StackPane>
</Group>
<VBox HBox.hgrow="ALWAYS">
<Label styleClass="label-large" text="%convertVault.success.message" wrapText="true" textAlignment="LEFT">
<padding>
<Insets bottom="6" top="6"/>
</padding>
</Label>
<Label text="%convertVault.hubToPassword.success.description" wrapText="true" textAlignment="LEFT"/>
<Region VBox.vgrow="ALWAYS" minHeight="18"/>
<ButtonBar buttonMinWidth="120" buttonOrder="+C">
<buttons>
<Button text="%generic.button.close" ButtonBar.buttonData="CANCEL_CLOSE" defaultButton="true" cancelButton="true" onAction="#close"/>
</buttons>
</ButtonBar>
</VBox>
</children>
</HBox>

View File

@@ -15,7 +15,7 @@
<?import javafx.scene.shape.Circle?>
<VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.common.ErrorController"
fx:controller="org.cryptomator.ui.error.ErrorController"
prefWidth="450"
prefHeight="450"
spacing="18"

View File

@@ -13,7 +13,7 @@
<?import javafx.scene.layout.Region?>
<HBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.forgetPassword.ForgetPasswordController"
fx:controller="org.cryptomator.ui.forgetpassword.ForgetPasswordController"
minWidth="400"
maxWidth="400"
minHeight="145"

View File

@@ -8,7 +8,7 @@
<?import javafx.scene.layout.VBox?>
<VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.common.NewPasswordController"
fx:controller="org.cryptomator.ui.changepassword.NewPasswordController"
spacing="6"
alignment="CENTER_LEFT">
<fx:define>

View File

@@ -1,16 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import org.cryptomator.ui.controls.FormattedLabel?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.Group?>
<VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.recoverykey.RecoveryKeyRecoverController"
@@ -23,32 +17,8 @@
<Insets topRightBottomLeft="12"/>
</padding>
<children>
<FormattedLabel format="%recoveryKey.recover.prompt" arg1="${controller.vault.displayName}" wrapText="true"/>
<TextArea wrapText="true" prefRowCount="4" fx:id="textarea" textFormatter="${controller.recoveryKeyTextFormatter}" onKeyPressed="#onKeyPressed"/>
<StackPane>
<Label text="Just some Filler" visible="false" graphicTextGap="6">
<graphic>
<FontAwesome5IconView glyph="ANCHOR"/>
</graphic>
</Label>
<Label text="%recoveryKey.recover.correctKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) &amp;&amp; controller.recoveryKeyCorrect}">
<graphic>
<FontAwesome5IconView glyph="CHECK"/>
</graphic>
</Label>
<Label text="%recoveryKey.recover.wrongKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) &amp;&amp; controller.recoveryKeyWrong}">
<graphic>
<FontAwesome5IconView glyph="TIMES" styleClass="glyph-icon-red"/>
</graphic>
</Label>
<Label text="%recoveryKey.recover.invalidKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) &amp;&amp; controller.recoveryKeyInvalid}">
<graphic>
<FontAwesome5IconView glyph="TIMES" styleClass="glyph-icon-red"/>
</graphic>
</Label>
</StackPane>
<fx:include fx:id="recoveryKeyValidate" source="recoverykey_validate.fxml"/>
<Region VBox.vgrow="ALWAYS"/>
@@ -56,7 +26,7 @@
<ButtonBar buttonMinWidth="120" buttonOrder="+CX">
<buttons>
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#recover" disable="${!controller.recoveryKeyCorrect}"/>
<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#recover" disable="${!controller.validateController.recoveryKeyCorrect}"/>
</buttons>
</ButtonBar>
</VBox>

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import org.cryptomator.ui.controls.FormattedLabel?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.recoverykey.RecoveryKeyValidateController"
minWidth="400"
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_CENTER">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>
<children>
<FormattedLabel format="%recoveryKey.recover.prompt" arg1="${controller.vault.displayName}" wrapText="true"/>
<TextArea wrapText="true" prefRowCount="4" fx:id="textarea" textFormatter="${controller.recoveryKeyTextFormatter}" onKeyPressed="#onKeyPressed"/>
<StackPane>
<Label text="Just some Filler" visible="false" graphicTextGap="6">
<graphic>
<FontAwesome5IconView glyph="ANCHOR"/>
</graphic>
</Label>
<Label text="%recoveryKey.recover.correctKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) &amp;&amp; controller.recoveryKeyCorrect}">
<graphic>
<FontAwesome5IconView glyph="CHECK"/>
</graphic>
</Label>
<Label text="%recoveryKey.recover.wrongKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) &amp;&amp; controller.recoveryKeyWrong}">
<graphic>
<FontAwesome5IconView glyph="TIMES" styleClass="glyph-icon-red"/>
</graphic>
</Label>
<Label text="%recoveryKey.recover.invalidKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) &amp;&amp; controller.recoveryKeyInvalid}">
<graphic>
<FontAwesome5IconView glyph="TIMES" styleClass="glyph-icon-red"/>
</graphic>
</Label>
</StackPane>
</children>
</VBox>

View File

@@ -36,5 +36,13 @@
<fx:include source="vault_options_masterkey.fxml"/>
</content>
</Tab>
<Tab fx:id="hubTab" id="HUB" text="%vaultOptions.hub"> <!-- is removed in controller, when config.keyid.scheme is not cryptomator-hub -->
<graphic>
<FontAwesome5IconView glyph="KEY"/>
</graphic>
<content>
<fx:include source="vault_options_hub.fxml"/>
</content>
</Tab>
</tabs>
</TabPane>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.vaultoptions.HubOptionsController"
spacing="6"
alignment="TOP_CENTER">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>
<Label maxWidth="-Infinity" text="%vaultOptions.hub.convertInfo" wrapText="true"/>
<VBox spacing="6" alignment="CENTER">
<Button fx:id="convertHubToPasswordButton" text="%vaultOptions.hub.convertBtn" onAction="#startConversion" maxWidth="Infinity">
<graphic>
<FontAwesome5IconView glyph="EXCHANGE_ALT"/>
</graphic>
</Button>
</VBox>
</VBox>

View File

@@ -434,7 +434,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Forget Saved Password
vaultOptions.masterkey.recoveryKeyExplanation=A recovery key is your only means to restore access to a vault if you lose your password.
vaultOptions.masterkey.showRecoveryKeyBtn=Display Recovery Key
vaultOptions.masterkey.recoverPasswordBtn=Reset Password
## Hub
vaultOptions.hub=Recovery
vaultOptions.hub.convertInfo=You can use the recovery key to convert this Hub vault to a password-based vault in an emergency.
vaultOptions.hub.convertBtn=Convert to Password-Based Vault
# Recovery Key
## Display Recovery Key
@@ -446,7 +449,7 @@ recoveryKey.display.StorageHints=Keep it somewhere very secure, e.g.:\n • Stor
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Reset Password
recoveryKey.recover.prompt=Enter your recovery key for "%s":
recoveryKey.recover.prompt=Enter the recovery key for "%s":
recoveryKey.recover.correctKey=This recovery key is correct
recoveryKey.recover.wrongKey=This recovery key belongs to a different vault
recoveryKey.recover.invalidKey=This recovery key is not valid
@@ -457,6 +460,13 @@ recoveryKey.recover.resetBtn=Reset
recoveryKey.recover.resetSuccess.message=Password reset successful
recoveryKey.recover.resetSuccess.description=You can unlock your vault with the new password.
# Convert Vault
convertVault.title=Convert Vault
convertVault.convert.convertBtn.before=Convert
convertVault.convert.convertBtn.processing=Converting…
convertVault.success.message=Conversion successful
convertVault.hubToPassword.success.description=You can now unlock the vault with the chosen password without requiring Hub access.
# New Password
newPassword.promptText=Enter a new password
newPassword.reenterPassword=Confirm the new password

View File

@@ -284,7 +284,7 @@ vaultOptions.masterkey.changePasswordBtn=تغيير كلمة المرور
vaultOptions.masterkey.forgetSavedPasswordBtn=نسيان كلمة المرور المحفوظة
vaultOptions.masterkey.recoveryKeyExplanation=مفتاح الاسترداد هو وسيلتك الوحيدة لاستعادة الوصول إلى مخزنك إذا فقدت كلمة المرور.
vaultOptions.masterkey.showRecoveryKeyBtn=عرض مفتاح الاسترداد
## Hub
# Recovery Key
## Display Recovery Key
@@ -293,12 +293,13 @@ recoveryKey.display.description=يمكن استخدام مفتاح الاستر
recoveryKey.display.StorageHints=حافظ عليه في مكان ما آمن جداً، على سبيل المثال\n • تخزينه باستخدام مدير كلمات المرور\n • حفظه على محرك أقراص خارجي USB\n • كتابته أو طباعته على الورق
## Reset Password
### Enter Recovery Key
recoveryKey.recover.prompt=أدخل مفتاح الاسترداد الخاص لـ "%s":
recoveryKey.recover.correctKey=هذا مفتاح استرداد صالح
recoveryKey.printout.heading=مفتاح استرداد Cryptomator\n"%s"\n
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
newPassword.promptText=أدخل كلمة مرور جديدة
newPassword.reenterPassword=تأكيد كلمة المرور الجديدة

View File

@@ -425,7 +425,7 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Забыцца на захаван
vaultOptions.masterkey.recoveryKeyExplanation=Ключ аднаўлення гэта адзіная мажлівасць аднавіць доступ да тваёй скарбніцы, калі ты згубіш пароль.
vaultOptions.masterkey.showRecoveryKeyBtn=Паказаць ключ аднаўлення
vaultOptions.masterkey.recoverPasswordBtn=Скінуць пароль
## Hub
# Recovery Key
## Display Recovery Key
@@ -437,7 +437,6 @@ recoveryKey.display.StorageHints=Захоўвай іх у бяспечным м
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Скінуць пароль
recoveryKey.recover.prompt=Увядзі свой ключ аднаўлення для "%s":
recoveryKey.recover.correctKey=Гэта валідны ключ аднаўлення
recoveryKey.recover.wrongKey=Гэты ключ аднаўлення належыць іншай скарбніцы
recoveryKey.recover.invalidKey=Несапраўдны ключ аднаўлення
@@ -448,6 +447,8 @@ recoveryKey.recover.resetBtn=Скінуць
recoveryKey.recover.resetSuccess.message=Пароль паспяхова скінуты
recoveryKey.recover.resetSuccess.description=Ты можаш разамкнуць сваю скарбніцу з дапамогаю новага паролю.
# Convert Vault
# New Password
newPassword.promptText=Увядзі новы пароль
newPassword.reenterPassword=Пацвердзі новы пароль

View File

@@ -157,7 +157,7 @@ vaultOptions.general.vaultName=ভোল্ট এর নাম
## Mount
vaultOptions.mount.mountPoint.directoryPickerButton=নির্বাচন করুন…
## Master Key
## Hub
# Recovery Key
## Display Recovery Key
@@ -166,6 +166,8 @@ vaultOptions.mount.mountPoint.directoryPickerButton=নির্বাচন ক
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
# Quit

View File

@@ -283,7 +283,7 @@ vaultOptions.masterkey.changePasswordBtn=Promjeni lozinku
vaultOptions.masterkey.forgetSavedPasswordBtn=Zaborav spremljenu šifru
vaultOptions.masterkey.recoveryKeyExplanation=Ključ za oporavak je vaše jedino sredstvo za vraćanje pristupa sefu ako izgubite lozinku.
vaultOptions.masterkey.showRecoveryKeyBtn=Pokaži ključ za oporavak
## Hub
# Recovery Key
## Display Recovery Key
@@ -292,12 +292,13 @@ recoveryKey.display.description=Sljedeći ključ za oporavak može se koristiti
recoveryKey.display.StorageHints=Pohranite ga negdje vrlo sigurno, npr.:\n • Spremite ga pomoću menadžera lozinki\n • Spremite ga na USB disk\n • Odštampajte ga na papiru
## Reset Password
### Enter Recovery Key
recoveryKey.recover.prompt=Unesite ključ za oporavak za "%s":
recoveryKey.recover.correctKey=Ključ za oporavak je ispravan
recoveryKey.printout.heading=Cryptomator Ključ za oporavak za \n"%s"\n
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
newPassword.promptText=Unesi novu šifru
newPassword.reenterPassword=Potvrdi novu šifru

View File

@@ -431,7 +431,7 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Oblida la contrasenya desada
vaultOptions.masterkey.recoveryKeyExplanation=La clau de recuperació és l'unic mitjà de restaurar l'accès a la caixa forta en cas de perdre la contrasenya.
vaultOptions.masterkey.showRecoveryKeyBtn=Mostra la clau de recuperació
vaultOptions.masterkey.recoverPasswordBtn=Canviar contrasenya
## Hub
# Recovery Key
## Display Recovery Key
@@ -443,7 +443,6 @@ recoveryKey.display.StorageHints=Conserveu-la en un lloc molt segur. P. ex.:\n
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Canviar contrasenya
recoveryKey.recover.prompt=Introduïu la vostra clau de recuperació de "%s":
recoveryKey.recover.correctKey=La clau de recuperació és vàlida
recoveryKey.recover.wrongKey=Aquesta clau de recuperació pertany a una caixa forta diferent
recoveryKey.recover.invalidKey=Aquesta clau de recuperació no és vàlida
@@ -454,6 +453,8 @@ recoveryKey.recover.resetBtn=Reinicia
recoveryKey.recover.resetSuccess.message=S'ha modificat la contrasenya correctament
recoveryKey.recover.resetSuccess.description=Pots desbloquejar la caixa forta amb la nova contrasenya.
# Convert Vault
# New Password
newPassword.promptText=Introdueix una contrasenya nova
newPassword.reenterPassword=Confirma la nova contrasenya

View File

@@ -382,7 +382,7 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Zapomenout uložené heslo
vaultOptions.masterkey.recoveryKeyExplanation=Obnovovací klíč je váš jediný způsob, jak obnovit přístup k trezoru, pokud ztratíte své heslo.
vaultOptions.masterkey.showRecoveryKeyBtn=Zobrazit klíč k obnově
vaultOptions.masterkey.recoverPasswordBtn=Resetovat heslo
## Hub
# Recovery Key
## Display Recovery Key
@@ -394,13 +394,14 @@ recoveryKey.display.StorageHints=Uchovejte ho někde velmi bezpečně, např.\n
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Resetovat heslo
recoveryKey.recover.prompt=Zadejte váš obnovovací klíč pro "%s":
recoveryKey.recover.correctKey=Toto je platný obnovovací klíč
recoveryKey.printout.heading=Obnovovací klíč Cryptomator\n"%s"\n
### Reset Password
recoveryKey.recover.resetBtn=Resetovat
### Recovery Key Password Reset Success
# Convert Vault
# New Password
newPassword.promptText=Zadejte nové heslo
newPassword.reenterPassword=Potvrď nové heslo

View File

@@ -154,6 +154,8 @@ hub.registerFailed.description=Der opstod en fejl i navngivnings-processen. Kig
hub.unauthorized.message=Adgang nægtet
hub.unauthorized.description=Din enhed er endnu ikke blevet godkendt til at få adgang til denne boks. Spørg boks-ejeren om godkendelse.
### License Exceeded
hub.invalidLicense.message=Ugyldig Hub licens
hub.invalidLicense.description=Din Cryptomator Hub har en ugyldig licens. Få venligst en Hub administrator til at opgradere eller forny licensen.
# Lock
## Force
@@ -272,7 +274,10 @@ preferences.interface.showMinimizeButton=Vis knap til minimering
preferences.interface.showTrayIcon=Vis ikon i system-bakken (kræver genstart)
## Volume
preferences.volume=Virtuelt drev
preferences.volume.type=Drev Type
preferences.volume.type.automatic=Automatisk
preferences.volume.docsTooltip=Åbn dokumentationen for at lære mere om de forskellige typer drev.
preferences.volume.fuseRestartRequired=For at anvende ændringerne skal Cryptomator genstartes.
preferences.volume.tcp.port=TCP port
preferences.volume.supportedFeatures=Den valgte type drev understøtter følgende funktioner:
preferences.volume.feature.mountAuto=Automatisk valg af monteringspunkt
@@ -302,21 +307,27 @@ stats.title=Statistik for %s
stats.cacheHitRate=Cache effektivitet
## Read
stats.read.throughput.idle=Læser: afventer
stats.read.throughput.kibs=Læser: %.2f KiB/s
stats.read.throughput.mibs=Læser: %.2f MiB/s
stats.read.total.data.none=Data læst: -
stats.read.total.data.kib=Data læst: %.1f KiB
stats.read.total.data.mib=Data læst: %.1f MiB
stats.read.total.data.gib=Data læst: %.1f GiB
stats.decr.total.data.none=Data dekrypteret: -
stats.decr.total.data.kib=Data dekrypteret: %.1f KiB
stats.decr.total.data.mib=Data dekrypteret: %.1f MiB
stats.decr.total.data.gib=Data dekrypteret: %.1f GiB
stats.read.accessCount=Totalt antal læsninger: %d
## Write
stats.write.throughput.idle=Skriver: afventer
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
stats.encr.total.data.none=Data krypteret: -
stats.encr.total.data.kib=Data krypteret: %.1f KiB
stats.encr.total.data.mib=Data krypteret: %.1f MiB
stats.encr.total.data.gib=Data krypteret: %.1f GiB
stats.write.accessCount=Totalt antal skrivninger: %d
@@ -359,6 +370,7 @@ main.vaultDetail.lockBtn=Lås
main.vaultDetail.bytesPerSecondRead=Læser:
main.vaultDetail.bytesPerSecondWritten=Skriver:
main.vaultDetail.throughput.idle=afventer
main.vaultDetail.throughput.kbps=%.1f KiB/s
main.vaultDetail.throughput.mbps=%.1f MiB/s
main.vaultDetail.stats=Boks statistik
main.vaultDetail.locateEncryptedFileBtn=Find Krypteret Fil
@@ -421,7 +433,7 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Glem gemt adgangskode
vaultOptions.masterkey.recoveryKeyExplanation=En gendannelsesnøgle er den eneste måde du kan få adgang til din boks på, hvis du har glemt dit password.
vaultOptions.masterkey.showRecoveryKeyBtn=Vis gendannelsesnøgle
vaultOptions.masterkey.recoverPasswordBtn=Nulstil adgangskode
## Hub
# Recovery Key
## Display Recovery Key
@@ -433,8 +445,9 @@ recoveryKey.display.StorageHints=Opbevar den et meget sikkert sted, som fx:\n
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Nulstil adgangskode
recoveryKey.recover.prompt=Indtast din gendannelsesnøgle for "%s":
recoveryKey.recover.correctKey=Dette er en gyldig gendannelsesnøgle
recoveryKey.recover.wrongKey=Denne gendannelsesnøgle tilhører en anden boks
recoveryKey.recover.invalidKey=Denne gendannelsesnøgle er ikke gyldig
recoveryKey.printout.heading=Cryptomator gendannelsesnøgle\n"%s"\n
### Reset Password
recoveryKey.recover.resetBtn=Nulstil
@@ -442,6 +455,8 @@ recoveryKey.recover.resetBtn=Nulstil
recoveryKey.recover.resetSuccess.message=Adgangskod nulstillet
recoveryKey.recover.resetSuccess.description=Du kan nu låse din boks op med den nye adgangskode.
# Convert Vault
# New Password
newPassword.promptText=Skriv en ny adgangskode
newPassword.reenterPassword=Bekræft ny adgangskode

View File

@@ -124,9 +124,9 @@ unlock.success.rememberChoice=Auswahl merken und nicht mehr fragen
unlock.success.revealBtn=Laufwerk anzeigen
## Failure
unlock.error.customPath.message=Tresor kann nicht an benutzerdefinierten Pfad eingehängt werden
unlock.error.customPath.description.notSupported=Wenn du den benutzerdefinierten Pfad weiter verwenden möchtest, gehe bitte in die Einstellungen und wähle einen Laufwerkstyp, der ihn unterstützt. Andernfalls gehe zu den Tresoroptionen und wähle einen unterstützten Einhängepunkt.
unlock.error.customPath.description.notExists=Der benutzerdefinierte Einhängepfad existiert nicht. Erstelle ihn entweder in deinem lokalen Dateisystem oder ändere ihn in den Tresoreinstellungen.
unlock.error.customPath.description.generic=Du hast einen benutzerdefinierten Einhängepfad für diesen Tresor ausgewählt, aber die Verwendung ist fehlgeschlagen. Fehlermeldung: %s
unlock.error.customPath.description.notSupported=Wenn du weiterhin den benutzerdefinierten Pfad verwenden möchtest, öffne die allgemeinen Einstellungen und wähle einen unterstützten Laufwerkstyp. Andernfalls gehe zu den Tresor-Optionen und wähle einen unterstützten Einhängepunkt.
unlock.error.customPath.description.notExists=Der benutzerdefinierte Einhängepunkt existiert nicht. Entweder erstelle ihn in deinem lokalen Dateisystem oder ändere ihn in den Tresor-Optionen.
unlock.error.customPath.description.generic=Du hast für diesen Tresor einen benutzerdefinierten Einhängepunkt ausgewählt, aber die Verwendung ist fehlgeschlagen mit der Meldung: %s
## Hub
hub.noKeychain.message=Zugriff auf Geräteschlüssel nicht möglich
hub.noKeychain.description=Zum Entsperren von Hub-Tresoren wird ein Geräteschlüssel benötigt, der in einem Schlüsselbund gesichert ist. Um fortzufahren, aktiviere „%s“ und wähle in den Einstellungen einen Schlüsselbund.
@@ -155,7 +155,7 @@ hub.unauthorized.message=Zugriff verweigert
hub.unauthorized.description=Dein Gerät wurde noch nicht für den Zugriff auf diesen Tresor autorisiert. Bitte den Tresorbesitzer, dein Gerät zu autorisieren.
### License Exceeded
hub.invalidLicense.message=Hub-Lizenz ungültig
hub.invalidLicense.description=Die Lizenz deiner Cryptomator-Hub-Instanz ist ungültig. Bitte informiere deinen Hub-Administrator, um die Lizenz zu erweitern oder zu erneuern.
hub.invalidLicense.description=Die Lizenz für deine Cryptomator Hub-Instanz ist ungültig. Bitte informiere einen Hub-Administrator, um die Lizenz zu aktualisieren oder zu erneuern.
# Lock
## Force
@@ -433,7 +433,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Gespeichertes Passwort vergessen
vaultOptions.masterkey.recoveryKeyExplanation=Ein Wiederherstellungsschlüssel ist bei Passwortverlust deine einzige Möglichkeit, den Zugriff auf einen Tresor wiederherzustellen.
vaultOptions.masterkey.showRecoveryKeyBtn=Wiederherstellungsschlüssel anzeigen
vaultOptions.masterkey.recoverPasswordBtn=Passwort zurücksetzen
## Hub
vaultOptions.hub=Wiederherstellung
vaultOptions.hub.convertInfo=Im Notfall kannst du den Wiederherstellungsschlüssel verwenden, um diesen Hub-Tresor in einen passwortgeschützten Tresor umzuwandeln.
vaultOptions.hub.convertBtn=In einen passwortgeschützten Tresor umwandeln
# Recovery Key
## Display Recovery Key
@@ -445,7 +448,7 @@ recoveryKey.display.StorageHints=Bewahre ihn möglichst sicher auf, z. B.\n •
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Passwort zurücksetzen
recoveryKey.recover.prompt=Gib deinen Wiederherstellungsschlüssel für %s ein:
recoveryKey.recover.prompt=Gib den Wiederherstellungsschlüssel für "%s" ein:
recoveryKey.recover.correctKey=Dieser Wiederherstellungsschlüssel ist gültig
recoveryKey.recover.wrongKey=Dieser Wiederherstellungsschlüssel gehört zu einem anderen Tresor
recoveryKey.recover.invalidKey=Dieser Wiederherstellungsschlüssel ist ungültig
@@ -456,6 +459,13 @@ recoveryKey.recover.resetBtn=Zurücksetzen
recoveryKey.recover.resetSuccess.message=Passwort erfolgreich zurückgesetzt
recoveryKey.recover.resetSuccess.description=Du kannst deinen Tresor mit dem neuen Passwort entsperren.
# Convert Vault
convertVault.title=Tresor konvertieren
convertVault.convert.convertBtn.before=Konvertieren
convertVault.convert.convertBtn.processing=Konvertierung läuft…
convertVault.success.message=Konvertierung erfolgreich
convertVault.hubToPassword.success.description=Du kannst nun den Tresor mit dem gewählten Passwort entsperren, ohne auf den Hub zuzugreifen.
# New Password
newPassword.promptText=Gib ein neues Passwort ein
newPassword.reenterPassword=Bestätige das neue Passwort

View File

@@ -433,7 +433,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Διαγραφή αποθηκευ
vaultOptions.masterkey.recoveryKeyExplanation=Το κλειδί ασφαλείας είναι ο μόνος τρόπος ανάκτησης πρόσβασης σε ένα vault αν χάσετε τον κωδικό σας.
vaultOptions.masterkey.showRecoveryKeyBtn=Προβολή κλειδιού ανάκτησης
vaultOptions.masterkey.recoverPasswordBtn=Επαναφορά Κωδικού Πρόσβασης
## Hub
vaultOptions.hub=Ανάκτηση
vaultOptions.hub.convertInfo=Μπορείτε να χρησιμοποιήσετε το κλειδί ανάκτησης για να μετατρέψετε αυτό το θησαυ/κιο Hub σε ένα θησαυ/κιο βασισμένο σε κωδικό πρόσβασης σε περίπτωση έκτακτης ανάγκης.
vaultOptions.hub.convertBtn=Μετατροπή σε Κρύπτη Βάσει Κωδικού πρόσβασης
# Recovery Key
## Display Recovery Key
@@ -456,6 +459,13 @@ recoveryKey.recover.resetBtn=Επαναφορά
recoveryKey.recover.resetSuccess.message=Επιτυχής επαναφορά κωδικού πρόσβασης
recoveryKey.recover.resetSuccess.description=Μπορείτε να ξεκλειδώσετε την κρύπτη σας με το νέο κωδικό πρόσβασης.
# Convert Vault
convertVault.title=Μετατροπή Θησαυ/κιου
convertVault.convert.convertBtn.before=Μετατροπή
convertVault.convert.convertBtn.processing=Μετατροπή…
convertVault.success.message=Η Μετατροπή ήταν επιτυχής
convertVault.hubToPassword.success.description=Τώρα μπορείτε να ξεκλειδώσετε το θησαυ/κιο με τον επιλεγμένο κωδικό πρόσβασης χωρίς να απαιτείται πρόσβαση στο Hub.
# New Password
newPassword.promptText=Εισάγετε ένα νέο κωδικό
newPassword.reenterPassword=Επιβεβαιώστε το νέο κωδικό

View File

@@ -11,12 +11,12 @@ generic.button.close=Cerrar
generic.button.copy=Copiar
generic.button.copied=¡Copiado!
generic.button.done=Hecho
generic.button.next=Continuar
generic.button.next=Siguiente
generic.button.print=Imprimir
# Error
error.message=Error %s
error.description=¡Ups! Cryptomator no esperaba que esto sucediera. Puede buscar soluciones existentes para este error. O si aún no se ha notiicado, siéntase libre de hacerlo.
error.message=Ocurrió un error
error.description=Cryptomator no esperaba que esto sucediera. Puede buscar soluciones existentes para este error. O si aún no se ha notificado, siéntase libre de hacerlo.
error.hyperlink.lookup=Buscar este error
error.hyperlink.report=Notificar este error
error.technicalDetails=Detalles:
@@ -56,9 +56,9 @@ addvaultwizard.new.locationIsOk=Ubicación adecuada para la bóveda
addvaultwizard.new.invalidName=Nombre de bóveda no válido
addvaultwizard.new.validName=Nombre de bóveda válido
addvaultwizard.new.validCharacters.message=El nombre de la bóveda puede contener los siguientes caracteres:
addvaultwizard.new.validCharacters.chars=Caracteres de la palabra (por ejemplo, a, o o)
addvaultwizard.new.validCharacters.chars=Caracteres de la palabra (por ejemplo, a, ж o)
addvaultwizard.new.validCharacters.numbers=Números
addvaultwizard.new.validCharacters.dashes=Separación (%s) o subrayado (%s)
addvaultwizard.new.validCharacters.dashes=Guion (%s) o subrayado (%s)
### Password
addvaultwizard.new.createVaultBtn=Crear bóveda
addvaultwizard.new.generateRecoveryKeyChoice=No podrá acceder a sus datos sin su contraseña. ¿Desea una clave de recuperación en caso de que pierda su contraseña?
@@ -91,7 +91,7 @@ addvaultwizard.success.nextStepsInstructions=Bóveda "%s" añadida.\nSe necesita
addvaultwizard.success.unlockNow=Desbloquear ahora
# Remove Vault
removeVault.title=Eliminar bóveda
removeVault.title=Eliminar "%s"
removeVault.message=¿Eliminar bóveda?
removeVault.description=Esto sólo hará que Cryptomator olvide la bóveda. Se la puede añadir de nuevo más tarde. Los archivos cifrados no se eliminarán del disco duro.
removeVault.confirmBtn=Eliminar bóveda
@@ -113,13 +113,13 @@ unlock.passwordPrompt=Ingresar contraseña para "%s":
unlock.savePassword=Recordar contraseña
unlock.unlockBtn=Desbloquear
## Select
unlock.chooseMasterkey.message=Archivo masterkey no encontrado
unlock.chooseMasterkey.description=No se pudo encontrar el archivo de la clave maestra de esta bóveda en la ubicación esperada. Por favor, elija manualmente el archivo de la clave.
unlock.chooseMasterkey.message=Archivo de la clave maestra no encontrado
unlock.chooseMasterkey.description=No se pudo encontrar el archivo de la clave maestra para la bóveda "%s". Por favor, elija manualmente el archivo de la clave.
unlock.chooseMasterkey.filePickerTitle=Seleccione el archivo de la clave maestra
unlock.chooseMasterkey.filePickerMimeDesc=Clave maestra de Cryptomator
## Success
unlock.success.message=Desbloqueo exitoso
unlock.success.description=¡Desbloqueo de "%s" exitoso! Su bóveda ahora es accesible a través de su unidad virtual.
unlock.success.description=El contenido de la bóveda "%s" ahora es accesible a través de su punto de montaje.
unlock.success.rememberChoice=Recordar opción y no mostrar de nuevo
unlock.success.revealBtn=Revelar unidad
## Failure
@@ -133,11 +133,11 @@ hub.noKeychain.description=Para desbloquear las bóvedas de Hub, se requiere una
hub.noKeychain.openBtn=Abrir preferencias
### Waiting
hub.auth.message=Esperando la autenticación…
hub.auth.description=Debe ser redirigido automáticamente a la página de inicio de sesión.
hub.auth.description=Debería ser redirigido automáticamente a la página de inicio de sesión.
hub.auth.loginLink=¿No se ha redireccionado? Haga clic aquí para abrirla.
### Receive Key
hub.receive.message=Procesando la respuesta…
hub.receive.description=Cryptomator está recibiendo y procesando la respuesta del Hub, espere.
hub.receive.description=Cryptomator está recibiendo y procesando la respuesta del Hub. Por favor espere.
### Register Device
hub.register.message=Nombre del dispositivo requerido
hub.register.description=Este parece ser el primer acceso al Hub desde este dispositivo. Para identificarlo y autorizar el acceso, necesita nombrar este dispositivo.
@@ -433,7 +433,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Olvidar contraseña guardada
vaultOptions.masterkey.recoveryKeyExplanation=Una clave de recuperación es el único medio para restaurar el acceso a una bóveda si pierde su contraseña.
vaultOptions.masterkey.showRecoveryKeyBtn=Mostrar clave de recuperación
vaultOptions.masterkey.recoverPasswordBtn=Restablecer contraseña
## Hub
vaultOptions.hub=Recuperación
vaultOptions.hub.convertInfo=Puede utilizar la clave de recuperación para convertir esta bóveda de Hub en una bóveda con contraseña en una emergencia.
vaultOptions.hub.convertBtn=Convertir a Bóveda con Contraseña
# Recovery Key
## Display Recovery Key
@@ -445,7 +448,7 @@ recoveryKey.display.StorageHints=Manténgala en algún lugar seguro, p.ej.:\n
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Restablecer contraseña
recoveryKey.recover.prompt=Ingresar la clave de recuperación para "%s":
recoveryKey.recover.prompt=Ingrese la clave de recuperación para "%s":
recoveryKey.recover.correctKey=Esta es una clave de recuperación válida
recoveryKey.recover.wrongKey=Esta clave de recuperación pertenece a una bóveda diferente
recoveryKey.recover.invalidKey=Esta clave de recuperación no es válida
@@ -456,6 +459,13 @@ recoveryKey.recover.resetBtn=## Reiniciar contraseña\nrecoveryKey.recover.reset
recoveryKey.recover.resetSuccess.message=Contraseña restablecida con éxito
recoveryKey.recover.resetSuccess.description=Puede desbloquear su bóveda con la contraseña nueva.
# Convert Vault
convertVault.title=Convertir bóveda
convertVault.convert.convertBtn.before=Convertir
convertVault.convert.convertBtn.processing=Convirtiendo…
convertVault.success.message=Conversión exitosa
convertVault.hubToPassword.success.description=Ahora puede desbloquear la bóveda con la contraseña elegida sin necesidad de acceso al Hub.
# New Password
newPassword.promptText=Ingrese una contraseña nueva
newPassword.reenterPassword=Confirme la contraseña nueva

View File

@@ -130,7 +130,7 @@ vaultOptions.general.vaultName=نام گاوصندوق
## Mount
vaultOptions.mount.mountPoint.directoryPickerButton=انتخاب کنید…
## Master Key
## Hub
# Recovery Key
## Display Recovery Key
@@ -139,6 +139,8 @@ vaultOptions.mount.mountPoint.directoryPickerButton=انتخاب کنید…
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
# Quit

View File

@@ -139,7 +139,7 @@ vaultOptions.general.vaultName=Pangalan ng Vault
## Mount
vaultOptions.mount.mountPoint.directoryPickerButton=Mamili…
## Master Key
## Hub
# Recovery Key
## Display Recovery Key
@@ -148,6 +148,8 @@ vaultOptions.mount.mountPoint.directoryPickerButton=Mamili…
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
# Quit

View File

@@ -433,7 +433,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Oublier le mot de passe enregistr
vaultOptions.masterkey.recoveryKeyExplanation=Une clé de récupération est le seul moyen de rétablir l'accès à un volume chiffré si vous en perdez le mot de passe.
vaultOptions.masterkey.showRecoveryKeyBtn=Afficher la clé de récupération
vaultOptions.masterkey.recoverPasswordBtn=Réinitialiser le mot de passe
## Hub
vaultOptions.hub=Récupération
vaultOptions.hub.convertInfo=Vous pouvez utiliser la clé de récupération pour convertir ce coffre Hub en coffre basé sur un mot de passe en cas d'urgence.
vaultOptions.hub.convertBtn=Convertir en coffre-fort basé sur mot de passe
# Recovery Key
## Display Recovery Key
@@ -445,7 +448,7 @@ recoveryKey.display.StorageHints=Gardez-la dans un endroit sûr, par ex. :\n •
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Réinitialiser le mot de passe
recoveryKey.recover.prompt=Entrez votre clé de récupération pour "%s":
recoveryKey.recover.prompt=Entrez la clé de récupération pour "%s " :
recoveryKey.recover.correctKey=Cette clé de récupération est correcte
recoveryKey.recover.wrongKey=Cette clé de récupération appartient à un autre coffre
recoveryKey.recover.invalidKey=Cette clé de récupération n'est pas valide
@@ -456,6 +459,13 @@ recoveryKey.recover.resetBtn=Réinitialiser
recoveryKey.recover.resetSuccess.message=Réinitialisation du mot de passe réussie
recoveryKey.recover.resetSuccess.description=Vous pouvez déverrouiller votre coffre avec le nouveau mot de passe.
# Convert Vault
convertVault.title=Convertir le coffre
convertVault.convert.convertBtn.before=Convertir
convertVault.convert.convertBtn.processing=Conversion en cours…
convertVault.success.message=Conversion réussie
convertVault.hubToPassword.success.description=Vous pouvez maintenant déverrouiller le coffre avec le mot de passe choisi sans avoir besoin d'un accès Hub.
# New Password
newPassword.promptText=Entrez un nouveau mot de passe
newPassword.reenterPassword=Confirmez le nouveau mot de passe

View File

@@ -105,7 +105,7 @@ main.closeBtn.tooltip=Pechar
## Mount
## Master Key
## Hub
# Recovery Key
## Display Recovery Key
@@ -114,6 +114,8 @@ main.closeBtn.tooltip=Pechar
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
# Quit

View File

@@ -274,8 +274,10 @@ preferences.interface.showMinimizeButton=הצג כפתור מזעור
preferences.interface.showTrayIcon=הצג צלמית בשורה מטה (דורש הפעלה מחדש)
## Volume
preferences.volume=כונן וירטואלי
preferences.volume.type=סוג נפח
preferences.volume.type.automatic=אוטומטי
preferences.volume.docsTooltip=בכדי ללמוד עוד על סוגי volume ניתן לקרוא את הדוקומנטציה.
preferences.volume.fuseRestartRequired=בכדי להחיל את השינויים נדרשת הפעלה מחדש.
preferences.volume.tcp.port=פורט TCP
preferences.volume.supportedFeatures=סוג ה- volume שבחרת תומך ביכולות הבאות:
preferences.volume.feature.mountAuto=נבחרה בחירת נקודת קישור אוטומטית
@@ -431,7 +433,8 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=שכח סיסמה שמורה
vaultOptions.masterkey.recoveryKeyExplanation=מפתח שחזור הינו הדרך היחידה לשחזור הגישה לכספת אם תאבד את הסיסמה.
vaultOptions.masterkey.showRecoveryKeyBtn=הצג את מפתח השחזור
vaultOptions.masterkey.recoverPasswordBtn=איפוס סיסמה
## Hub
vaultOptions.hub=שחזור
# Recovery Key
## Display Recovery Key
@@ -443,7 +446,6 @@ recoveryKey.display.StorageHints=שמור אותו במקום מאוד בטוח,
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=איפוס סיסמה
recoveryKey.recover.prompt=הקש את מפתח השחזור שלך עבור ״%s״:
recoveryKey.recover.correctKey=מפתח ה recovery נכון
recoveryKey.recover.wrongKey=מפתח ה recovery שייך ל vault אחר
recoveryKey.recover.invalidKey=מפתח ה recovery שגוי
@@ -454,6 +456,8 @@ recoveryKey.recover.resetBtn=איפוס
recoveryKey.recover.resetSuccess.message=איפוס סיסמה הצליח
recoveryKey.recover.resetSuccess.description=ניתן לפתוח את הכספת עם הסיסמה החדשה.
# Convert Vault
# New Password
newPassword.promptText=הקש סיסמה חדשה
newPassword.reenterPassword=לאימות, הקש שוב את הסיסמא החדשה

View File

@@ -252,7 +252,7 @@ vaultOptions.mount.mountPoint.directoryPickerButton=चुनें…
## Master Key
vaultOptions.masterkey=पासवर्ड
vaultOptions.masterkey.changePasswordBtn=पासवर्ड बदलें
## Hub
# Recovery Key
## Display Recovery Key
@@ -262,6 +262,8 @@ recoveryKey.create.description=रिकवरी-की दिखाने क
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
newPassword.promptText=नया पासवर्ड दर्ज करें
newPassword.reenterPassword=नए पासवर्ड की पुष्टि करें

View File

@@ -347,7 +347,7 @@ vaultOptions.masterkey.changePasswordBtn=Promijeni lozinku
vaultOptions.masterkey.forgetSavedPasswordBtn=Zaboravi pohranjenu lozinku
vaultOptions.masterkey.recoveryKeyExplanation=Ključ za oporavak je jedini način povrata pristupa trezoru u slučaju gubitka lozinke.
vaultOptions.masterkey.showRecoveryKeyBtn=Prikaži ključ za oporavak
## Hub
# Recovery Key
## Display Recovery Key
@@ -356,12 +356,13 @@ recoveryKey.display.description=Slijedeći ključ za oporavak može se koristiti
recoveryKey.display.StorageHints=Držite ga na sigurnom mjestu, npr.:\n • Pohranite ga koristeći upravitelja lozinki\n • Sačuvajte ga na USB prijenosnom pogonu\n • Ispišite ga na papir
## Reset Password
### Enter Recovery Key
recoveryKey.recover.prompt=Unesite ključ za oporavak za "%s":
recoveryKey.recover.correctKey=Ovo je valjani ključ za oporavak
recoveryKey.printout.heading=Cryptomator-ov ključ za oporavak\n"%s"\n
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
newPassword.promptText=Unesite novu lozinku
newPassword.reenterPassword=Potvrdite novu lozinku

View File

@@ -369,7 +369,7 @@ vaultOptions.masterkey.changePasswordBtn=Jelszó megváltoztatása
vaultOptions.masterkey.forgetSavedPasswordBtn=Mentett jelszó törlése
vaultOptions.masterkey.recoveryKeyExplanation=A helyreállítási kulcs az egyetlen módja annak, hogy visszaállítsa a széfhez való hozzáférést, ha elveíti a jelszavát.
vaultOptions.masterkey.showRecoveryKeyBtn=Visszaállítási kulcs megjelenítése
## Hub
# Recovery Key
## Display Recovery Key
@@ -378,7 +378,6 @@ recoveryKey.display.description=A következő helyreállítási kulcs használha
recoveryKey.display.StorageHints=Tartsa nagyon biztonságos helyen. pl.:\n •Tárolja egy jelszókezelővel\n •Mentse el egy USB meghajtóra\n •Nyomtassa egy papírra
## Reset Password
### Enter Recovery Key
recoveryKey.recover.prompt=Írja be a visszaállítási kulcsát a következőhöz "%s":
recoveryKey.recover.correctKey=Ez a visszaállítási kulcs érvényes
recoveryKey.recover.wrongKey=Ez a visszaállítási kulcs egy másik széfhez tartozik
recoveryKey.recover.invalidKey=Ez a visszaállítási kulcs nem érvényes
@@ -386,6 +385,8 @@ recoveryKey.printout.heading=Cryptomator visszaállítási kulcs\n"%s"\n
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
newPassword.promptText=Adjon meg egy új jelszót
newPassword.reenterPassword=Az új jelszó megerősítése

View File

@@ -347,7 +347,7 @@ vaultOptions.masterkey.changePasswordBtn=Ubah Kata Sandi
vaultOptions.masterkey.forgetSavedPasswordBtn=Lupa Kata Sandi
vaultOptions.masterkey.recoveryKeyExplanation=Kunci pemulihan adalah satu-satunya cara Anda untuk memulihkan akses ke vault jika Anda kehilangan kata sandi.
vaultOptions.masterkey.showRecoveryKeyBtn=Tampilkan Kunci Pemulihan
## Hub
# Recovery Key
## Display Recovery Key
@@ -356,12 +356,13 @@ recoveryKey.display.description=Kunci pemulihan berikut dapat digunakan untuk me
recoveryKey.display.StorageHints=Simpan di tempat yang sangat aman, misal.:\n • Simpan menggunakan password manager\n • Simpan di USB\n • cetak di kertas
## Reset Password
### Enter Recovery Key
recoveryKey.recover.prompt=Masukkan kunci pemulihan untuk "%s":
recoveryKey.recover.correctKey=Ini adalah kunci pemulihan yang valid
recoveryKey.printout.heading=Kunci Pemulihan Cryptomator\n"%s"\n
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
newPassword.promptText=Masukkan kata sandi baru
newPassword.reenterPassword=Konfirmasi kata sandi baru

View File

@@ -433,7 +433,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Dimentica Password Salvata
vaultOptions.masterkey.recoveryKeyExplanation=Una chiave di recupero è il tuo unico mezzo per ripristinare l'accesso a una cassaforte se perdi la tua password.
vaultOptions.masterkey.showRecoveryKeyBtn=Visualizza la chiave di recupero
vaultOptions.masterkey.recoverPasswordBtn=Reimposta Password
## Hub
vaultOptions.hub=Recupero
vaultOptions.hub.convertInfo=È possibile utilizzare la chiave di recupero per convertire questa cassaforte Hub in una cassaforte basata su password in caso di emergenza.
vaultOptions.hub.convertBtn=Converti in cassaforte basata su password
# Recovery Key
## Display Recovery Key
@@ -445,7 +448,7 @@ recoveryKey.display.StorageHints=Mantienilo da qualche parte molto sicuro, ad es
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Reimposta Password
recoveryKey.recover.prompt=Inserisci la tua chiave di recupero per "%s":
recoveryKey.recover.prompt=Inserisci la chiave di recupero per "%s":
recoveryKey.recover.correctKey=Questa è una chiave di recupero valida
recoveryKey.recover.wrongKey=Questa chiave di recupero appartiene ad una cassaforte diversa
recoveryKey.recover.invalidKey=Questa chiave di recupero non é valida
@@ -456,6 +459,13 @@ recoveryKey.recover.resetBtn=Reimposta
recoveryKey.recover.resetSuccess.message=Password reimpostata correttamente
recoveryKey.recover.resetSuccess.description=Puoi sbloccare la tua cassaforte con la nuova password.
# Convert Vault
convertVault.title=Convertire Cassaforte
convertVault.convert.convertBtn.before=Converti
convertVault.convert.convertBtn.processing=Conversione in corso…
convertVault.success.message=Conversione completata
convertVault.hubToPassword.success.description=Ora puoi sbloccare la cassaforte con la password scelta senza richiedere l'accesso a Hub.
# New Password
newPassword.promptText=Inserisci una nuova password
newPassword.reenterPassword=Conferma la nuova password

View File

@@ -433,7 +433,7 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=保存したパスワードを削
vaultOptions.masterkey.recoveryKeyExplanation=回復キーはパスワードを忘れてしまった場合でも、金庫へのアクセスを回復する唯一の手段です。
vaultOptions.masterkey.showRecoveryKeyBtn=回復キーを表示
vaultOptions.masterkey.recoverPasswordBtn=パスワードをリセット
## Hub
# Recovery Key
## Display Recovery Key
@@ -445,7 +445,6 @@ recoveryKey.display.StorageHints=十分に安全な場所に保存してくだ
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=パスワードをリセット
recoveryKey.recover.prompt="%s" の回復キーを入力してください:
recoveryKey.recover.correctKey=有効な回復キー
recoveryKey.recover.wrongKey=この回復キーは別の金庫に属しています
recoveryKey.recover.invalidKey=この回復キーは有効ではありません
@@ -456,6 +455,8 @@ recoveryKey.recover.resetBtn=リセット
recoveryKey.recover.resetSuccess.message=パスワードをリセットしました
recoveryKey.recover.resetSuccess.description=新しいパスワードで金庫の施錠ができます。
# Convert Vault
# New Password
newPassword.promptText=新しいパスワードを入力してください
newPassword.reenterPassword=新しいパスワードを確認

View File

@@ -16,6 +16,8 @@ generic.button.print=인쇄
# Error
error.message=오류가 발생했습니다
error.description=예상치 못한 에러가 발생했습니다. 온라인에 에러를 검색해서 해결하십시오. 만약 신고된 적이 없는 에러일 경우, 새로 신고해도 좋습니다.
error.hyperlink.lookup=에러 검색하기
error.hyperlink.report=에러 보고하기
error.technicalDetails=상세 정보:
@@ -51,6 +53,12 @@ addvaultwizard.new.fileAlreadyExists=Vault 내에 이미 존재하는 파일 또
addvaultwizard.new.locationDoesNotExist=지정된 디렉터리가 존재하지 않거나 접근 할 수 없습니다.
addvaultwizard.new.locationIsNotWritable=지정된 경로에 쓰기 권한이 없습니다.
addvaultwizard.new.locationIsOk=Vault에 적당한 위치
addvaultwizard.new.invalidName=올바르지 않은 vault 이름입니다
addvaultwizard.new.validName=올바른 vault 이름입니다
addvaultwizard.new.validCharacters.message=Vault 이름에는 다음과 같은 문자들이 포함될 수 있습니다:
addvaultwizard.new.validCharacters.chars=문자 (예시: a, ж or 수)
addvaultwizard.new.validCharacters.numbers=숫자
addvaultwizard.new.validCharacters.dashes=대시 (%s) 또는 언더바 (%s)
### Password
addvaultwizard.new.createVaultBtn=Vault 생성
addvaultwizard.new.generateRecoveryKeyChoice=비밀번호가 없으면 데이터에 접근할 수 없습니다. 비밀번호를 잊었을 때를 대비한 복구 키를 원하십니까?
@@ -74,8 +82,10 @@ addvault.new.readme.accessLocation.2=이것은 당신의 Vault 접근 위치입
addvault.new.readme.accessLocation.3=이 볼륨에 추가된 모든 파일은 Cryptomator로 암호화됩니다. 다른 드라이브/폴더처럼 작업할 수 있습니다. 볼륨의 내용은 복호화 된 것 처럼 보여지지만, 모든 파일은 항상 암호화되어 하드디스크에 저장됩니다.
addvault.new.readme.accessLocation.4=이 파일은 지우셔도 무방합니다.
## Existing
addvaultwizard.existing.instruction=이미 존재하는 vault 폴더 내에서 "vault.cryptomator" 파일을 선택하세요. 만약 "masterkey.cryptomator"만 있다면 그걸 대신 선택하세요.
addvaultwizard.existing.chooseBtn=선택
addvaultwizard.existing.filePickerTitle=Vault 파일 선택
addvaultwizard.existing.filePickerMimeDesc=Cryptomator Vault
## Success
addvaultwizard.success.nextStepsInstructions="%s" Vault가 추가되었습니다.\n이 Vault를 접근하거나 컨텐츠를 추가하려면 잠금해제가 필요합니다. 그렇지만 언제든지 잠금해제가 가능합니다.
addvaultwizard.success.unlockNow=지금 잠금해제
@@ -93,6 +103,7 @@ changepassword.finalConfirmation=비밀번호를 잊어버리면, 데이터에
# Forget Password
forgetPassword.title=비밀번호 분실
forgetPassword.message=저장된 비밀번호를 삭제할까요?
forgetPassword.description=시스템 키체인에서 이 Vault의 저장된 비밀번호가 삭제될 것입니다.
forgetPassword.confirmBtn=비밀번호 분실
@@ -107,6 +118,7 @@ unlock.chooseMasterkey.description=추정되는 위치에서 이 Vault의 마스
unlock.chooseMasterkey.filePickerTitle=마스터키 파일 선택
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator 마스터키
## Success
unlock.success.message=잠금 해제 성공
unlock.success.description="%s"이(가) 성공적으로 잠금해제되었습니다. 이제 이 Vault를 가상드라이브로 접근할 수 있습니다.
unlock.success.rememberChoice=선택 기억함, 다시 묻지 않음
unlock.success.revealBtn=드라이브 표시
@@ -115,6 +127,8 @@ unlock.success.revealBtn=드라이브 표시
### Waiting
### Receive Key
### Register Device
hub.register.nameLabel=기기 이름
hub.register.occupiedMsg=이미 사용된 이름입니다
hub.register.registerBtn=확인
### Registration Success
### Registration Failed
@@ -125,6 +139,7 @@ hub.register.registerBtn=확인
## Force
lock.forced.description=대기 중인 작동이나 파일이 열려있어 "%s"를 잠그는데 실패하였습니다. 이 Vault를 강제로 잠글 수 있으나, 입/출력의 중단은 저장되지 않은 데이터의 유실을 초래할 수 있습니다.
lock.forced.retryBtn=재시도
lock.forced.forceBtn=강제 잠금
## Failure
lock.fail.message=Vault 잠금에 실패하였습니다.
lock.fail.description="%s" Vault를 잠글 수 없습니다. 저장되지 않은 작업이 다른 곳에 저장된 것과 중요한 읽기/쓰기 동작이 완료되었는지 확인 하십시요. Vault를 닫기 위해, Cryptomator 프로세스를 강제로 종료 하십시요.
@@ -133,6 +148,10 @@ lock.fail.description="%s" Vault를 잠글 수 없습니다. 저장되지 않은
migration.title=Vault 업그레이드
## Start
migration.start.header=Vault 업그레이드
migration.start.text=Vault "%s"를 현재 버전의 Cryptomator에서 열기 위해서는 해당 vault를 새 버전으로 업그레이드해야 합니다. 업그레이드를 하기 전에 다음 사항들을 알고 있어야 합니다:
migration.start.remarkUndone=이 업그레이드는 되돌릴 수 없습니다.
migration.start.remarkVersions=과거 버전의 Cryptomator는 업그레이드된 vault를 열 수 없습니다.
migration.start.remarkCanRun=이 vault를 열 때 사용하는 모든 장치가 현재 버전의 Cryptomator를 실행할 수 있는지 확인해야 합니다.
migration.start.confirm=나는 위 정보를 읽고 정말 이해했습니다.
## Run
migration.run.enterPassword="%s"의 비밀번호를 입력하십시요.
@@ -175,6 +194,7 @@ health.check.detail.checkScheduled=검사가 예약되었습니다.
health.check.detail.checkRunning=검사가 현재 실행중입니다...
health.check.detail.checkSkipped=선택된 검사항목이 없습니다.
health.check.detail.checkFinished=검사가 성공적으로 완료되었습니다.
health.check.detail.listFilters.label=필터
health.check.exportBtn=보고서 내보내기
## Result view
## Fix Application
@@ -208,6 +228,8 @@ preferences.interface.showTrayIcon=트레이 아이콘 보기 (재시작 필요)
## Volume
preferences.volume=가상 드라이브
preferences.volume.type.automatic=자동
preferences.volume.tcp.port=TCP 포트
preferences.volume.supportedFeatures=현재 선택한 볼륨 타입은 다음과 같은 기능들을 지원합니다:
## Updates
preferences.updates=업데이트
preferences.updates.currentVersion=현재 버전: %s
@@ -295,6 +317,8 @@ main.vaultDetail.missing.changeLocation=Vault 위치 변경
main.vaultDetail.migrateButton=Vault 업그레이드
main.vaultDetail.migratePrompt=Vault에 접근하기 전, 새로운 포멧으로 업그레이드가 필요합니다.
### Error
main.vaultDetail.error.reload=새로고침
main.vaultDetail.error.windowTitle=Vault 로딩중 에러 발생
# Wrong File Alert
wrongFileAlert.title=파일 암호화 방법
@@ -327,27 +351,39 @@ vaultOptions.mount.winDriveLetterOccupied=사용됨
vaultOptions.mount.mountPoint=마운트 지점
vaultOptions.mount.mountPoint.auto=자동으로 적합한 위치를 선택
vaultOptions.mount.mountPoint.driveLetter=드라이브 문자를 지정하여 사용
vaultOptions.mount.mountPoint.custom=선택한 디렉토리 사용
vaultOptions.mount.mountPoint.directoryPickerButton=선택
vaultOptions.mount.mountPoint.directoryPickerTitle=디렉토리 선택
## Master Key
vaultOptions.masterkey=비밀번호
vaultOptions.masterkey.changePasswordBtn=비밀번호 변경
vaultOptions.masterkey.forgetSavedPasswordBtn=저장된 비밀번호 삭제
vaultOptions.masterkey.recoveryKeyExplanation=복구 키는 비밀번호를 잊어버렸을 때, Vault의 접근을 복원 할 수 있는 유일한 방법입니다.
vaultOptions.masterkey.showRecoveryKeyBtn=복구 키 표시
vaultOptions.masterkey.recoverPasswordBtn=비밀번호 재설정
## Hub
# Recovery Key
## Display Recovery Key
recoveryKey.display.title=복구 키 보기
recoveryKey.create.message=비밀번호가 필요합니다
recoveryKey.create.description="%s"의 복구 키를 표시하려면 비밀번호를 입력해 주세요.
recoveryKey.display.description="%s" 데이터 접근을 복원하는데 사용 할 수 있는 복구 키 입니다:
recoveryKey.display.StorageHints=매우 안전한곳에 보관하십시요. 예시:\n • 비밀번호 관리자를 사용하여 저장\n • USB 플래시 드라이브에 저장\n • 종이에 출력
## Reset Password
### Enter Recovery Key
recoveryKey.recover.prompt="%s"의 복구키를 입력하십시요:
recoveryKey.recover.title=비밀번호 바꾸기
recoveryKey.recover.correctKey=올바른 복구 키 입니다
recoveryKey.recover.wrongKey=이 복구 키는 다른 vault의 키입니다
recoveryKey.recover.invalidKey=해당 복구 키는 유효하지 않습니다
recoveryKey.printout.heading=Cryptomator 복구 키\n"%s"\n
### Reset Password
recoveryKey.recover.resetBtn=초기화
### Recovery Key Password Reset Success
recoveryKey.recover.resetSuccess.message=비밀번호 재설정 성공
recoveryKey.recover.resetSuccess.description=이제 해당 vault를 새 비밀번호로 잠금 해제할 수 있습니다.
# Convert Vault
# New Password
newPassword.promptText=새 비밀번호를 입력하세요
@@ -362,6 +398,8 @@ passwordStrength.messageLabel.3=강함
passwordStrength.messageLabel.4=매우 강함
# Quit
quit.title=앱 종료
quit.message=잠금 해제된 vault들이 존재합니다
quit.lockAndQuitBtn=Vault 잠금 후 종료하기
# Forced Quit

View File

@@ -243,7 +243,7 @@ vaultOptions.masterkey=Parole
vaultOptions.masterkey.changePasswordBtn=Mainīt paroli
vaultOptions.masterkey.recoveryKeyExplanation=Atkopšanas atslēga ir jūsu vienīgais līdzeklis, lai atjaunotu piekļuvi glabātuvei, ja pazaudējat paroli.
vaultOptions.masterkey.showRecoveryKeyBtn=Rādīt atkopšanas atslēgu
## Hub
# Recovery Key
## Display Recovery Key
@@ -252,13 +252,14 @@ recoveryKey.display.description=Šī atjaunošanas atslēga var tikt izmantota,
recoveryKey.display.StorageHints=Glabājiet to drošā vietā, piemēram:\n  • Uzglabājiet to, izmantojot paroļu pārvaldnieku\n  • Saglabājiet to USB zibatmiņā\n  • Izdrukājiet to uz papīra
## Reset Password
### Enter Recovery Key
recoveryKey.recover.prompt=Ievadiet "%s" atjaunošanas atslēgu:
recoveryKey.recover.correctKey=Šī ir derīga atjaunošanas atslēga
recoveryKey.printout.heading=Cryptomator atjaunošanas atslēga\n"%s" \n
### Reset Password
recoveryKey.recover.resetBtn=Atiestatīt
### Recovery Key Password Reset Success
# Convert Vault
# New Password
newPassword.promptText=Ievadiet jauno paroli
newPassword.reenterPassword=Apstipriniet jauno paroli

View File

@@ -92,7 +92,7 @@ hub.register.registerBtn=Потврди
## Mount
## Master Key
## Hub
# Recovery Key
## Display Recovery Key
@@ -101,6 +101,8 @@ hub.register.registerBtn=Потврди
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
# Quit

View File

@@ -431,7 +431,7 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Glem passord
vaultOptions.masterkey.recoveryKeyExplanation=En gjenopprettingsnøkkel er den eneste måten å gjenopprette tilgangen til et hvelv på hvis du mister passordet.
vaultOptions.masterkey.showRecoveryKeyBtn=Vis gjenopprettingsnøkkelen
vaultOptions.masterkey.recoverPasswordBtn=Nullstill passord
## Hub
# Recovery Key
## Display Recovery Key
@@ -443,7 +443,6 @@ recoveryKey.display.StorageHints=Oppbevar den et veldig sikkert sted, f.eks. ved
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Nullstill passordet
recoveryKey.recover.prompt=Skriv inn gjenopprettingsnøkkelen for "%s":
recoveryKey.recover.correctKey=Gjenopprettingsnøkkelen er gyldig
recoveryKey.recover.wrongKey=Gjenopprettingsnøkkelen tilhører et annet hvelv
recoveryKey.recover.invalidKey=Gjennopprettingsnøkkelen er ugyldig
@@ -454,6 +453,8 @@ recoveryKey.recover.resetBtn=Nullstill
recoveryKey.recover.resetSuccess.message=Passordnullstillingen vellykket
recoveryKey.recover.resetSuccess.description=Du kan låse opp hvelvet med det nye passordet.
# Convert Vault
# New Password
newPassword.promptText=Skriv inn et nytt passord
newPassword.reenterPassword=Bekreft det nye passordet

View File

@@ -433,7 +433,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Opgeslagen wachtwoord vergeten
vaultOptions.masterkey.recoveryKeyExplanation=Een herstelsleutel is je enige manier om de toegang tot een kluis te herstellen als je je wachtwoord kwijtraakt.
vaultOptions.masterkey.showRecoveryKeyBtn=Toon herstelsleutel
vaultOptions.masterkey.recoverPasswordBtn=Wachtwoord resetten
## Hub
vaultOptions.hub=Herstel
vaultOptions.hub.convertInfo=U kunt de herstelsleutel gebruiken om deze Hub kluis om te zetten in een wachtwoord-gebaseerde kluis in noodsituaties.
vaultOptions.hub.convertBtn=Converteren naar Wachtwoord-gebaseerde kluis
# Recovery Key
## Display Recovery Key
@@ -445,7 +448,7 @@ recoveryKey.display.StorageHints=Bewaar het op een veilige plek, bv:\n • Bewaa
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Wachtwoord resetten
recoveryKey.recover.prompt=Voer uw herstelsleutel in voor "%s":
recoveryKey.recover.prompt=Voer de herstelsleutel in voor "%s":
recoveryKey.recover.correctKey=Deze herstelsleutel is geldig
recoveryKey.recover.wrongKey=Deze herstelsleutel behoort tot een andere kluis
recoveryKey.recover.invalidKey=Deze herstelsleutel is niet geldig
@@ -456,6 +459,13 @@ recoveryKey.recover.resetBtn=Resetten
recoveryKey.recover.resetSuccess.message=Wachtwoord resetten geslaagd
recoveryKey.recover.resetSuccess.description=Je kunt je kluis ontgrendelen met het nieuwe wachtwoord.
# Convert Vault
convertVault.title=Kluis converteren
convertVault.convert.convertBtn.before=Converteren
convertVault.convert.convertBtn.processing=Converteren…
convertVault.success.message=Conversie succesvol
convertVault.hubToPassword.success.description=U kunt nu de kluis ontgrendelen met het gekozen wachtwoord zonder Hub toegang nodig te hebben.
# New Password
newPassword.promptText=Voer een nieuw wachtwoord in
newPassword.reenterPassword=Bevestig het nieuwe wachtwoord

View File

@@ -243,7 +243,7 @@ vaultOptions.masterkey.changePasswordBtn=Byt passord
vaultOptions.masterkey.forgetSavedPasswordBtn=Gløym passord
vaultOptions.masterkey.recoveryKeyExplanation=Ein "retta opp igjen"-nøkkel er den einaste måten å retta opp igjen tilgangen til ein kvelv på viss du mistar passordet.
vaultOptions.masterkey.showRecoveryKeyBtn=Vis 'Retta opp igjen'-nøkkelen
## Hub
# Recovery Key
## Display Recovery Key
@@ -252,11 +252,12 @@ recoveryKey.display.description=Følgjande gjenopprettingsnøkkel kan brukast ti
recoveryKey.display.StorageHints=Ta vare på han ein veldig sikker stad, t.d. ved å:\n • Lagre han ved hjelp av ein passordkvelv\n • Lagre han på ein USB-minnepenn\n • Skrive han ut på papir
## Reset Password
### Enter Recovery Key
recoveryKey.recover.prompt=Skriv inn gjenopprettingsnøkkelen for "%s":
recoveryKey.printout.heading=Cryptomator-gjenopprettingsnøkkel\n"%s"\n
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
newPassword.promptText=Skriv inn eit nytt passord
newPassword.reenterPassword=Stadfest det nye passordet

View File

@@ -274,7 +274,7 @@ vaultOptions.masterkey.changePasswordBtn=ਪਾਸਵਰਡ ਬਦਲੋ
vaultOptions.masterkey.forgetSavedPasswordBtn=ਸੰਭਾਲਿਆ ਪਾਸਵਰਡ ਭੁੱਲੋ
vaultOptions.masterkey.recoveryKeyExplanation=ਜੇ ਤੁਸੀਂ ਆਪਣਾ ਪਾਸਵਰਡ ਭੁੱਲ ਗਏ ਹੋ ਤਾਂ ਤੁਹਾਡੇ ਵਾਲਟ ਲਈ ਪਹੁੰਚ ਬਹਾਲ ਕਰਨ ਵਾਸਤੇ ਸਿਰਫ਼ ਰਿਕਵਰੀ ਕੁੰਜੀ ਹੀ ਹੈ।
vaultOptions.masterkey.showRecoveryKeyBtn=ਰਿਕਰਵੀ ਕੁੰਜੀ ਦਿਖਾਓ
## Hub
# Recovery Key
## Display Recovery Key
@@ -283,12 +283,13 @@ recoveryKey.display.description="%s" ਲਈ ਪਹੁੰਚ ਬਹਾਲ ਕਰ
recoveryKey.display.StorageHints=ਇਸ ਨੂੰ ਕਿਸੇ ਥਾਂ ਬਹੁਤ ਹੀ ਸੰਭਾਲ ਕੇ ਰੱਖੋ.:\n • ਇਸ ਨੂੰ ਪਾਸਵਰਡ ਮੈਨੇਜਰ ਵਰਤ ਕੇ ਸੰਭਾਲੋ\n • ਇਸ ਨੂੰ USB ਫਲੈਸ਼ ਡਰਾਇਵ ਉੱਤੇ ਸੰਭਾਲੋ\n • ਇਸ ਨੂੰ ਪੇਪਰ ਉੱਤੇ ਛਪ ਲਵੋ
## Reset Password
### Enter Recovery Key
recoveryKey.recover.prompt='%s" ਲਈ ਆਪਣਾ ਰਿਕਵਰੀ ਕੁੰਜੀ ਦਿਓ:
recoveryKey.recover.correctKey=ਇਹ ਜਾਇਜ਼ ਰਿਕਰਵੀ ਕੁੰਜੀ ਹੈ
recoveryKey.printout.heading=Cryptomator ਰਿਕਵਰੀ ਕੁੰਜੀ\n"%s"\n
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
newPassword.promptText=ਨਵਾਂ ਪਾਸਵਰਡ ਦਿਓ
newPassword.reenterPassword=ਨਵੇਂ ਪਾਸਵਰਡ ਦੀ ਤਸਦੀਕ ਕਰੋ

View File

@@ -274,8 +274,10 @@ preferences.interface.showMinimizeButton=Pokaż przycisk minimalizacji
preferences.interface.showTrayIcon=Pokaż ikonę zasobnika (wymaga restartu)
## Volume
preferences.volume=Dysk wirtualny
preferences.volume.type=Typ woluminu
preferences.volume.type.automatic=Automatyczny
preferences.volume.docsTooltip=Sprawdź dokumentację, aby dowiedzieć się więcej o różnych typach udziałów.
preferences.volume.fuseRestartRequired=Aby zastosować zmiany, konieczne jest ponowne uruchomienie Cryptomatora.
preferences.volume.tcp.port=Port TCP
preferences.volume.supportedFeatures=Wybrany typ udziału obsługuje następujące funkcje:
preferences.volume.feature.mountAuto=Automatyczny wybór punktu montowania
@@ -431,7 +433,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Zapomnij zapamiętane hasło
vaultOptions.masterkey.recoveryKeyExplanation=Klucz odzyskiwania jest twoim jedynym sposobem przywrócenia dostępu do sejfu w przypadku utraty hasła.
vaultOptions.masterkey.showRecoveryKeyBtn=Wyświetl klucz odzyskiwania
vaultOptions.masterkey.recoverPasswordBtn=Resetuj hasło
## Hub
vaultOptions.hub=Odzyskanie
vaultOptions.hub.convertInfo=Możesz użyć klucza odzyskiwania, aby przekonwertować ten Hub do sejfu opartego na hasłach w nagłych przypadkach.
vaultOptions.hub.convertBtn=Konwertuj na sejf oparty na hasłach
# Recovery Key
## Display Recovery Key
@@ -443,7 +448,7 @@ recoveryKey.display.StorageHints=Trzymaj go w bezpiecznym miejscu, np.\n • Prz
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Resetuj hasło
recoveryKey.recover.prompt=Wprowadź swój klucz odzyskiwania dla "%s":
recoveryKey.recover.prompt=Wprowadź klucz odzyskiwania dla "%s":
recoveryKey.recover.correctKey=To jest prawidłowy klucz odzyskiwania
recoveryKey.recover.wrongKey=Ten klucz należy do innego sejfu
recoveryKey.recover.invalidKey=Ten klucz jest nieprawidłowy
@@ -454,6 +459,13 @@ recoveryKey.recover.resetBtn=Resetuj
recoveryKey.recover.resetSuccess.message=Hasło zostało zresetowane
recoveryKey.recover.resetSuccess.description=Możesz odblokować sejf przy użyciu nowego hasła.
# Convert Vault
convertVault.title=Konwertuj sejf
convertVault.convert.convertBtn.before=Konwertuj
convertVault.convert.convertBtn.processing=Konwertowanie…
convertVault.success.message=Konwersja zakończona
convertVault.hubToPassword.success.description=Możesz teraz odblokować sejf przy użyciu wybranego hasła bez konieczności dostępu do Huba.
# New Password
newPassword.promptText=Wprowadź nowe hasło
newPassword.reenterPassword=Potwierdź nowe hasło

View File

@@ -382,7 +382,8 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Esqueça a senha salva
vaultOptions.masterkey.recoveryKeyExplanation=Uma chave de recuperação é a única forma de restaurar o acesso a um cofre se perder a senha.
vaultOptions.masterkey.showRecoveryKeyBtn=Exibir Chave de Recuperação
vaultOptions.masterkey.recoverPasswordBtn=Redefinir palavra-passe
## Hub
vaultOptions.hub=Recuperação
# Recovery Key
## Display Recovery Key
@@ -394,7 +395,6 @@ recoveryKey.display.StorageHints=Guarde-a num lugar muito seguro, por exemplo:\n
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Redefinir palavra-passe
recoveryKey.recover.prompt=Insira a chave de recuperação para "%s":
recoveryKey.recover.correctKey=Esta chave de recuperação está certa
recoveryKey.recover.wrongKey=Esta chave de recuperação pertence a um cofre diferente
recoveryKey.recover.invalidKey=Esta chave de recupreação não está certa
@@ -405,6 +405,8 @@ recoveryKey.recover.resetBtn=Repor
recoveryKey.recover.resetSuccess.message=Palavra-passe redefinida com sucesso
recoveryKey.recover.resetSuccess.description=Você pode desbloquear o seu cofre com a nova senha.
# Convert Vault
# New Password
newPassword.promptText=Inserir uma nova palavra-passe
newPassword.reenterPassword=Confirme a nova palavra-passe

View File

@@ -421,7 +421,7 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Esquecer a senha salva
vaultOptions.masterkey.recoveryKeyExplanation=Se você perder a sua senha, a única forma de restaurar acesso a um cofre é através de uma chave de recuperação.
vaultOptions.masterkey.showRecoveryKeyBtn=Exibir chave de recuperação
vaultOptions.masterkey.recoverPasswordBtn=Redefinir Senha
## Hub
# Recovery Key
## Display Recovery Key
@@ -433,7 +433,6 @@ recoveryKey.display.StorageHints=Mantenha-a em um lugar bem seguro, por exemplo:
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Redefinir Senha
recoveryKey.recover.prompt=Digite sua chave de recuperação para "%s":
recoveryKey.recover.correctKey=Esta é uma chave de recuperação válida
recoveryKey.printout.heading=Chave de Recuperação do Cryptomator\n"%s"\n
### Reset Password
@@ -442,6 +441,8 @@ recoveryKey.recover.resetBtn=Redefinir
recoveryKey.recover.resetSuccess.message=Senha redefinida com sucesso
recoveryKey.recover.resetSuccess.description=Você pode desbloquear o seu cofre com a nova senha.
# Convert Vault
# New Password
newPassword.promptText=Digite a nova senha
newPassword.reenterPassword=Confirme a nova senha

View File

@@ -407,7 +407,7 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Parolă salvată uitată
vaultOptions.masterkey.recoveryKeyExplanation=O cheie de recuperare este singurul mijloc de a restabili accesul la un seif în caz că vă pierdeți parola.
vaultOptions.masterkey.showRecoveryKeyBtn=Afișează cheia de recuperare
vaultOptions.masterkey.recoverPasswordBtn=Resetează Parola
## Hub
# Recovery Key
## Display Recovery Key
@@ -419,7 +419,6 @@ recoveryKey.display.StorageHints=Păstrați cheia de recuperare undeva foarte si
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Resetează Parola
recoveryKey.recover.prompt=Introduceți cheia de recuperare pentru "%s:
recoveryKey.recover.correctKey=Cheia de recuperare este validă
recoveryKey.recover.wrongKey=Cheia de recuperare aparţine unui alt seif
recoveryKey.recover.invalidKey=Cheia de recuperare nu este validă
@@ -430,6 +429,8 @@ recoveryKey.recover.resetBtn=Resetează
recoveryKey.recover.resetSuccess.message=Parola a fost resetată cu succes
recoveryKey.recover.resetSuccess.description=Puteți debloca seiful cu parola noua.
# Convert Vault
# New Password
newPassword.promptText=Introduceți o parolă nouă
newPassword.reenterPassword=Confirmaţi noua parolă

View File

@@ -433,7 +433,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Забыть сохранённы
vaultOptions.masterkey.recoveryKeyExplanation=При утере пароля восстановить доступ к хранилищу можно только с помощью ключа восстановления.
vaultOptions.masterkey.showRecoveryKeyBtn=Показать ключ восстановления
vaultOptions.masterkey.recoverPasswordBtn=Сброс пароля
## Hub
vaultOptions.hub=Восстановление
vaultOptions.hub.convertInfo=Ключ восстановления используется для преобразования этого хаб-хранилища в хранилище с паролем в чрезвычайных ситуациях.
vaultOptions.hub.convertBtn=Преобразовать в хранилище с паролем
# Recovery Key
## Display Recovery Key
@@ -456,6 +459,13 @@ recoveryKey.recover.resetBtn=Сброс
recoveryKey.recover.resetSuccess.message=Пароль успешно сброшен
recoveryKey.recover.resetSuccess.description=Вы можете разблокировать хранилище новым паролем.
# Convert Vault
convertVault.title=Преобразовать хранилище
convertVault.convert.convertBtn.before=Преобразовать
convertVault.convert.convertBtn.processing=Преобразование…
convertVault.success.message=Преобразование выполнено
convertVault.hubToPassword.success.description=Теперь вы можете разблокировать хранилище с помощью выбранного пароля, без доступа к хабу.
# New Password
newPassword.promptText=Введите новый пароль
newPassword.reenterPassword=Подтвердите новый пароль

View File

@@ -108,7 +108,7 @@ main.closeBtn.tooltip=වසන්න
## Mount
## Master Key
## Hub
# Recovery Key
## Display Recovery Key
@@ -117,6 +117,8 @@ main.closeBtn.tooltip=වසන්න
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
# Quit

View File

@@ -431,7 +431,7 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Zabudnúť uložené heslo
vaultOptions.masterkey.recoveryKeyExplanation=Kľúč pre obnovu je Vašou jedinou cestou k obnove prístupu do trezoru v prípade straty hesla.
vaultOptions.masterkey.showRecoveryKeyBtn=Ukázať klúč obnovy
vaultOptions.masterkey.recoverPasswordBtn=Resetovanie hesla
## Hub
# Recovery Key
## Display Recovery Key
@@ -443,7 +443,6 @@ recoveryKey.display.StorageHints=Uchovávajte ho na bezpečnom mieste, ako napr.
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Resetovanie hesla
recoveryKey.recover.prompt=Zadajte Váš kľúč obnovy pre "%s":
recoveryKey.recover.correctKey=Toto je platný kľúč obnovy
recoveryKey.recover.wrongKey=Tento kľúč obnovy patrí inému trezoru
recoveryKey.recover.invalidKey=Toto je neplatný kľúč obnovy
@@ -454,6 +453,8 @@ recoveryKey.recover.resetBtn=Resetovať
recoveryKey.recover.resetSuccess.message=Heslo úspešne zresetované
recoveryKey.recover.resetSuccess.description=Môžte odomknúť trezor s novým heslom.
# Convert Vault
# New Password
newPassword.promptText=Zadajte nové heslo
newPassword.reenterPassword=Porvrďte nové heslo

View File

@@ -111,7 +111,7 @@ main.vaultDetail.locateEncryptedFileBtn=Poišči šifrirano datoteko
## Mount
## Master Key
## Hub
# Recovery Key
## Display Recovery Key
@@ -123,6 +123,8 @@ recoveryKey.recover.invalidKey=Obnovitveni ključ ni pravilen
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
# Quit

View File

@@ -286,7 +286,7 @@ vaultOptions.masterkey.changePasswordBtn=Promena lozinke
vaultOptions.masterkey.forgetSavedPasswordBtn=Заборави сачувану лозинку
vaultOptions.masterkey.recoveryKeyExplanation=Резервни кључ је Ваш једини начин да вратите приступ сефу уколико изгубите лозинку.
vaultOptions.masterkey.showRecoveryKeyBtn=Прикажи Резервни Кључ
## Hub
# Recovery Key
## Display Recovery Key
@@ -295,12 +295,13 @@ recoveryKey.display.description=Следећи резервни кључ мож
recoveryKey.display.StorageHints=Чувајте га на веома сигурном месту, нпр.:\n • Похраните га унутар менаџера лозинки\n • Сачувајте га на екстерни диск\n • Одштампајте га на папиру
## Reset Password
### Enter Recovery Key
recoveryKey.recover.prompt=Унесите резервни кључ за "%s":
recoveryKey.recover.correctKey=Ово је исправан резервни кључ
recoveryKey.printout.heading=Cryptomator Резервни Кључ\n"%s"\n
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
newPassword.promptText=Унесите нову лозинку
newPassword.reenterPassword=Потврдите нову лозинку

View File

@@ -219,7 +219,7 @@ vaultOptions.general.actionAfterUnlock.reveal=Otvori disk
vaultOptions.mount.mountPoint.directoryPickerButton=Izaberi…
## Master Key
vaultOptions.masterkey.changePasswordBtn=Promena lozinke
## Hub
# Recovery Key
## Display Recovery Key
@@ -228,6 +228,8 @@ vaultOptions.masterkey.changePasswordBtn=Promena lozinke
### Reset Password
### Recovery Key Password Reset Success
# Convert Vault
# New Password
# Quit

View File

@@ -425,7 +425,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Ta bort sparat lösenord
vaultOptions.masterkey.recoveryKeyExplanation=En återställningsnyckel är ditt enda sätt att återställa åtkomst till ett valv om du förlorar ditt lösenord.
vaultOptions.masterkey.showRecoveryKeyBtn=Visa återsällningsnyckel
vaultOptions.masterkey.recoverPasswordBtn=Återställ lösenord
## Hub
vaultOptions.hub=Återställning
vaultOptions.hub.convertInfo=Du kan använda återställningsnyckeln för att konvertera detta Hub valv till ett lösenordsbaserat valv i en nödsituation.
vaultOptions.hub.convertBtn=Konvertera till Lösenordsbaserat Valv
# Recovery Key
## Display Recovery Key
@@ -437,7 +440,7 @@ recoveryKey.display.StorageHints=Spara den på en säker plats, t.ex:\n • I en
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Återställ lösenord
recoveryKey.recover.prompt=Ange din återställningsnyckel för "%s":
recoveryKey.recover.prompt=Ange återställningsnyckeln för "%s":
recoveryKey.recover.correctKey=Denna återställningsnyckel är korrekt
recoveryKey.recover.wrongKey=Denna återställningsnyckel tillhör ett annat valv
recoveryKey.recover.invalidKey=Denna återställningsnyckel är ogiltig
@@ -448,6 +451,13 @@ recoveryKey.recover.resetBtn=Återställ
recoveryKey.recover.resetSuccess.message=Lösenord återställt
recoveryKey.recover.resetSuccess.description=Du kan låsa upp valvet med det nya lösenordet.
# Convert Vault
convertVault.title=Konvertera valv
convertVault.convert.convertBtn.before=Konvertera
convertVault.convert.convertBtn.processing=Konverterar…
convertVault.success.message=Konverteringen lyckades
convertVault.hubToPassword.success.description=Du kan nu låsa upp valvet med det valda lösenordet utan att behöva Hub-åtkomst.
# New Password
newPassword.promptText=Ange ett nytt lösenord
newPassword.reenterPassword=Bekräfta nytt lösenord

View File

@@ -431,7 +431,7 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Kusahau Neno la siri Iliyohifadhiw
vaultOptions.masterkey.recoveryKeyExplanation=Ufunguo wa kurejesha ni njia yako pekee ya kurejesha ufikiaji wa kuba ikiwa utapoteza nenosiri lako.
vaultOptions.masterkey.showRecoveryKeyBtn=Onyesha Ufunguo wa Ufufuzi
vaultOptions.masterkey.recoverPasswordBtn=Fufua Neno la siri
## Hub
# Recovery Key
## Display Recovery Key
@@ -443,7 +443,6 @@ recoveryKey.display.StorageHints=Weka mahali salama sana, kwa mfano:\n • Hifad
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Fufua Neno la siri
recoveryKey.recover.prompt=Ingiza ufunguo wako wa kurejesha kwa "%s":
recoveryKey.recover.correctKey=Hii ni ufunguo halali wa kurejesha
recoveryKey.recover.wrongKey=Ufunguo huu wa urejeshaji ni wa kuba tofauti
recoveryKey.recover.invalidKey=Ufunguo huu wa kurejesha si sahihi
@@ -454,6 +453,8 @@ recoveryKey.recover.resetBtn=Weka upya
recoveryKey.recover.resetSuccess.message=Kuweka upya nenosiri kumefaulu
recoveryKey.recover.resetSuccess.description=Unaweza kufungua chumba chako kwa kutumia neno la siri jipya.
# Convert Vault
# New Password
newPassword.promptText=Ingiza neno jipya la siri
newPassword.reenterPassword=Thibitisha neno la siri jipya

Some files were not shown because too many files have changed in this diff Show More