mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-28 15:40:20 +00:00
Merge branch 'develop' into feature/files-in-use
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
package org.cryptomator.common.recovery;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.cryptomator.common.Constants.MASTERKEY_BACKUP_SUFFIX;
|
||||
|
||||
public final class BackupRestorer {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BackupRestorer.class);
|
||||
|
||||
private BackupRestorer() {}
|
||||
|
||||
public static void restoreIfBackupPresent(Path vaultPath, String filePrefix) {
|
||||
Path targetFile = vaultPath.resolve(filePrefix);
|
||||
|
||||
try (Stream<Path> files = Files.list(vaultPath)) {
|
||||
files.filter(file -> isFileMatchingPattern(file.getFileName().toString(), filePrefix))
|
||||
.max((f1, f2) -> {
|
||||
try {
|
||||
FileTime time1 = Files.getLastModifiedTime(f1);
|
||||
FileTime time2 = Files.getLastModifiedTime(f2);
|
||||
return time1.compareTo(time2);
|
||||
} catch (IOException e) {
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
.ifPresent(backupFile -> copyBackupFile(backupFile, targetFile));
|
||||
} catch (IOException e) {
|
||||
LOG.info("Unable to restore backup files in '{}'", vaultPath, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isFileMatchingPattern(String fileName, String filePrefix) {
|
||||
return fileName.startsWith(filePrefix) && fileName.endsWith(MASTERKEY_BACKUP_SUFFIX);
|
||||
}
|
||||
|
||||
private static void copyBackupFile(Path backupFile, Path configPath) {
|
||||
try {
|
||||
Files.copy(backupFile, configPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
LOG.debug("Backup restored - file: '{}' path: '{}'", backupFile, configPath);
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Unable to copy backup file from '{}' to '{}'", backupFile, configPath, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.cryptomator.common.recovery;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||
import org.cryptomator.cryptolib.api.Masterkey;
|
||||
import org.cryptomator.cryptolib.api.CryptorProvider;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.MasterkeyLoader;
|
||||
|
||||
import static org.cryptomator.common.Constants.DEFAULT_KEY_ID;
|
||||
|
||||
public final class CryptoFsInitializer {
|
||||
|
||||
private CryptoFsInitializer() {}
|
||||
|
||||
public static void init(Path recoveryPath,
|
||||
Masterkey masterkey,
|
||||
int shorteningThreshold,
|
||||
CryptorProvider.Scheme scheme) throws IOException, CryptoException {
|
||||
|
||||
MasterkeyLoader loader = ignored -> masterkey.copy();
|
||||
CryptoFileSystemProperties fsProps = CryptoFileSystemProperties //
|
||||
.cryptoFileSystemProperties() //
|
||||
.withCipherCombo(scheme) //
|
||||
.withKeyLoader(loader) //
|
||||
.withShorteningThreshold(shorteningThreshold) //
|
||||
.build();
|
||||
CryptoFileSystemProvider.initialize(recoveryPath, fsProps, DEFAULT_KEY_ID);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package org.cryptomator.common.recovery;
|
||||
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.Cryptor;
|
||||
import org.cryptomator.cryptolib.api.CryptorProvider;
|
||||
import org.cryptomator.cryptolib.api.Masterkey;
|
||||
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||
import static org.cryptomator.cryptofs.common.Constants.DATA_DIR_NAME;
|
||||
|
||||
public final class MasterkeyService {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MasterkeyService.class);
|
||||
|
||||
private MasterkeyService() {}
|
||||
|
||||
public static void recoverFromRecoveryKey(String recoveryKey, RecoveryKeyFactory recoveryKeyFactory, Path recoveryPath, CharSequence newPassword) throws IOException {
|
||||
recoveryKeyFactory.newMasterkeyFileWithPassphrase(recoveryPath, recoveryKey, newPassword);
|
||||
}
|
||||
|
||||
public static Masterkey load(MasterkeyFileAccess masterkeyFileAccess, Path masterkeyFilePath, CharSequence password) throws IOException {
|
||||
return masterkeyFileAccess.load(masterkeyFilePath, password);
|
||||
}
|
||||
|
||||
public static CryptorProvider.Scheme validateRecoveryKeyAndDetectCombo(RecoveryKeyFactory recoveryKeyFactory, //
|
||||
Vault vault, String recoveryKey, //
|
||||
MasterkeyFileAccess masterkeyFileAccess) throws IOException, CryptoException, NoSuchElementException {
|
||||
String tmpPass = UUID.randomUUID().toString();
|
||||
try (RecoveryDirectory recoveryDirectory = RecoveryDirectory.create(vault.getPath())) {
|
||||
Path tempRecoveryPath = recoveryDirectory.getRecoveryPath();
|
||||
recoverFromRecoveryKey(recoveryKey, recoveryKeyFactory, tempRecoveryPath, tmpPass);
|
||||
Path masterkeyFilePath = tempRecoveryPath.resolve(MASTERKEY_FILENAME);
|
||||
|
||||
try (Masterkey mk = load(masterkeyFileAccess, masterkeyFilePath, tmpPass)) {
|
||||
return detect(mk, vault.getPath()).orElseThrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<CryptorProvider.Scheme> detect(Masterkey masterkey, Path vaultPath) {
|
||||
try (Stream<Path> paths = Files.walk(vaultPath.resolve(DATA_DIR_NAME))) {
|
||||
Optional<Path> c9rFile = paths //
|
||||
.filter(p -> p.toString().endsWith(".c9r")) //
|
||||
.filter(p -> !p.endsWith("dir.c9r")) //
|
||||
.findFirst();
|
||||
if (c9rFile.isEmpty()) {
|
||||
LOG.info("Unable to detect Crypto scheme: No *.c9r file found in {}", vaultPath);
|
||||
return Optional.empty();
|
||||
}
|
||||
return determineScheme(c9rFile.get(), masterkey);
|
||||
} catch (IOException e) {
|
||||
LOG.info("Unable to detect Crypto scheme: Failed to inspect vault", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private static Optional<CryptorProvider.Scheme> determineScheme(Path c9rFile, Masterkey masterkey) {
|
||||
return Arrays.stream(CryptorProvider.Scheme.values()).filter(scheme -> {
|
||||
try (Cryptor cryptor = CryptorProvider.forScheme(scheme).provide(masterkey.copy(), SecureRandom.getInstanceStrong())) {
|
||||
int headerSize = cryptor.fileHeaderCryptor().headerSize();
|
||||
|
||||
ByteBuffer headerBuf = ByteBuffer.allocate(headerSize);
|
||||
|
||||
try (FileChannel channel = FileChannel.open(c9rFile, StandardOpenOption.READ)) {
|
||||
channel.read(headerBuf, 0);
|
||||
}
|
||||
|
||||
headerBuf.flip();
|
||||
cryptor.fileHeaderCryptor().decryptHeader(headerBuf.duplicate());
|
||||
LOG.debug("Detected Crypto scheme: {}", scheme);
|
||||
return true;
|
||||
} catch (IllegalArgumentException | CryptoException e) {
|
||||
LOG.debug("Could not decrypt with scheme: {}", scheme);
|
||||
return false;
|
||||
} catch (IOException | NoSuchAlgorithmException e) {
|
||||
LOG.warn("Unable to detect Crypto scheme: Failed to decrypt .c9r file", e);
|
||||
return false;
|
||||
}
|
||||
}).findFirst();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.cryptomator.common.recovery;
|
||||
|
||||
public enum RecoveryActionType {
|
||||
RESTORE_ALL,
|
||||
RESTORE_MASTERKEY,
|
||||
RESTORE_VAULT_CONFIG,
|
||||
RESET_PASSWORD,
|
||||
SHOW_KEY,
|
||||
CONVERT_VAULT
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.cryptomator.common.recovery;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public final class RecoveryDirectory implements AutoCloseable {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RecoveryDirectory.class);
|
||||
|
||||
private final Path recoveryPath;
|
||||
private final Path vaultPath;
|
||||
|
||||
private RecoveryDirectory(Path vaultPath, Path recoveryPath) {
|
||||
this.vaultPath = vaultPath;
|
||||
this.recoveryPath = recoveryPath;
|
||||
}
|
||||
|
||||
public static RecoveryDirectory create(Path vaultPath) throws IOException {
|
||||
Path tempDir = Files.createTempDirectory("cryptomator");
|
||||
return new RecoveryDirectory(vaultPath, tempDir);
|
||||
}
|
||||
|
||||
public void moveRecoveredFile(String file) throws IOException {
|
||||
Files.move(recoveryPath.resolve(file), vaultPath.resolve(file), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
private void deleteRecoveryDirectory() {
|
||||
try (var paths = Files.walk(recoveryPath)) {
|
||||
paths.sorted(Comparator.reverseOrder()).forEach(p -> {
|
||||
try {
|
||||
Files.delete(p);
|
||||
} catch (IOException e) {
|
||||
LOG.info("Unable to delete {}. Please delete it manually.", p);
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
LOG.error("Failed to clean up recovery directory", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
deleteRecoveryDirectory();
|
||||
}
|
||||
|
||||
public Path getRecoveryPath() {
|
||||
return recoveryPath;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.cryptomator.common.recovery;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultComponent;
|
||||
import org.cryptomator.common.vaults.VaultConfigCache;
|
||||
import org.cryptomator.common.vaults.VaultListManager;
|
||||
import org.cryptomator.integrations.mount.MountService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.LOCKED;
|
||||
|
||||
public final class VaultPreparator {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(VaultPreparator.class);
|
||||
|
||||
private VaultPreparator() {}
|
||||
|
||||
public static Vault prepareVault(Path selectedDirectory, //
|
||||
VaultComponent.Factory vaultComponentFactory, //
|
||||
List<MountService> mountServices, //
|
||||
ResourceBundle resourceBundle) {
|
||||
VaultSettings vaultSettings = VaultSettings.withRandomId();
|
||||
vaultSettings.path.set(selectedDirectory);
|
||||
if (selectedDirectory.getFileName() != null) {
|
||||
vaultSettings.displayName.set(selectedDirectory.getFileName().toString());
|
||||
} else {
|
||||
vaultSettings.displayName.set(resourceBundle.getString("defaults.vault.vaultName"));
|
||||
}
|
||||
|
||||
var wrapper = new VaultConfigCache(vaultSettings);
|
||||
Vault vault = vaultComponentFactory.create(vaultSettings, wrapper, LOCKED, null).vault();
|
||||
try {
|
||||
VaultListManager.determineVaultState(vault.getPath());
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Failed to determine vault state for {}", vaultSettings.path.get(), e);
|
||||
}
|
||||
|
||||
//due to https://github.com/cryptomator/cryptomator/issues/2880#issuecomment-1680313498
|
||||
var nameOfWinfspLocalMounter = "org.cryptomator.frontend.fuse.mount.WinFspMountProvider";
|
||||
if (SystemUtils.IS_OS_WINDOWS && vaultSettings.path.get().toString().contains("Dropbox") && mountServices.stream().anyMatch(s -> s.getClass().getName().equals(nameOfWinfspLocalMounter))) {
|
||||
vaultSettings.mountService.setValue(nameOfWinfspLocalMounter);
|
||||
}
|
||||
|
||||
return vault;
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,6 @@ import org.cryptomator.cryptofs.event.FilesystemEvent;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.MasterkeyLoader;
|
||||
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
|
||||
import org.cryptomator.event.VaultEvent;
|
||||
import org.cryptomator.integrations.mount.MountFailedException;
|
||||
import org.cryptomator.integrations.mount.Mountpoint;
|
||||
import org.cryptomator.integrations.mount.UnmountFailedException;
|
||||
@@ -35,7 +34,6 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
@@ -75,6 +73,7 @@ public class Vault {
|
||||
private final BooleanBinding missing;
|
||||
private final BooleanBinding needsMigration;
|
||||
private final BooleanBinding unknownError;
|
||||
private final BooleanBinding missingVaultConfig;
|
||||
private final ObjectBinding<Mountpoint> mountPoint;
|
||||
private final Mounter mounter;
|
||||
private final Settings settings;
|
||||
@@ -103,6 +102,7 @@ public class Vault {
|
||||
this.processing = Bindings.createBooleanBinding(this::isProcessing, state);
|
||||
this.unlocked = Bindings.createBooleanBinding(this::isUnlocked, state);
|
||||
this.missing = Bindings.createBooleanBinding(this::isMissing, state);
|
||||
this.missingVaultConfig = Bindings.createBooleanBinding(this::isMissingVaultConfig, state);
|
||||
this.needsMigration = Bindings.createBooleanBinding(this::isNeedsMigration, state);
|
||||
this.unknownError = Bindings.createBooleanBinding(this::isUnknownError, state);
|
||||
this.mountPoint = Bindings.createObjectBinding(this::getMountPoint, state);
|
||||
@@ -337,6 +337,14 @@ public class Vault {
|
||||
return state.get() == VaultState.Value.ERROR;
|
||||
}
|
||||
|
||||
public BooleanBinding missingVaultConfigProperty() {
|
||||
return missingVaultConfig;
|
||||
}
|
||||
|
||||
public boolean isMissingVaultConfig() {
|
||||
return state.get() == VaultState.Value.VAULT_CONFIG_MISSING || state.get() == VaultState.Value.ALL_MISSING;
|
||||
}
|
||||
|
||||
public ReadOnlyStringProperty displayNameProperty() {
|
||||
return vaultSettings.displayName;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public class VaultConfigCache {
|
||||
private final VaultSettings settings;
|
||||
private final AtomicReference<VaultConfig.UnverifiedVaultConfig> config;
|
||||
|
||||
VaultConfigCache(VaultSettings settings) {
|
||||
public VaultConfigCache(VaultSettings settings) {
|
||||
this.settings = settings;
|
||||
this.config = new AtomicReference<>(null);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package org.cryptomator.common.vaults;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.recovery.BackupRestorer;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||
@@ -34,9 +35,7 @@ import java.util.ResourceBundle;
|
||||
|
||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.ERROR;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.LOCKED;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.NEEDS_MIGRATION;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.*;
|
||||
|
||||
@Singleton
|
||||
public class VaultListManager {
|
||||
@@ -67,6 +66,12 @@ public class VaultListManager {
|
||||
autoLocker.init();
|
||||
}
|
||||
|
||||
public boolean isAlreadyAdded(Path vaultPath) {
|
||||
assert vaultPath.isAbsolute();
|
||||
assert vaultPath.normalize().equals(vaultPath);
|
||||
return vaultList.stream().anyMatch(v -> vaultPath.equals(v.getPath()));
|
||||
}
|
||||
|
||||
public Vault add(Path pathToVault) throws IOException {
|
||||
Path normalizedPathToVault = pathToVault.normalize().toAbsolutePath();
|
||||
if (CryptoFileSystemProvider.checkDirStructureForVault(normalizedPathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME) == DirStructure.UNRELATED) {
|
||||
@@ -114,59 +119,122 @@ public class VaultListManager {
|
||||
.findAny();
|
||||
}
|
||||
|
||||
public void addVault(Vault vault) {
|
||||
Path path = vault.getPath().normalize().toAbsolutePath();
|
||||
if (!isAlreadyAdded(path)) {
|
||||
vaultList.add(vault);
|
||||
}
|
||||
}
|
||||
|
||||
private Vault create(VaultSettings vaultSettings) {
|
||||
var wrapper = new VaultConfigCache(vaultSettings);
|
||||
try {
|
||||
var vaultState = determineVaultState(vaultSettings.path.get());
|
||||
if (vaultState == LOCKED) { //for legacy reasons: pre v8 vault do not have a config, but they are in the NEEDS_MIGRATION state
|
||||
wrapper.reloadConfig();
|
||||
if (Objects.isNull(vaultSettings.lastKnownKeyLoader.get())) {
|
||||
var keyIdScheme = wrapper.get().getKeyId().getScheme();
|
||||
vaultSettings.lastKnownKeyLoader.set(keyIdScheme);
|
||||
}
|
||||
} else if (vaultState == NEEDS_MIGRATION) {
|
||||
vaultSettings.lastKnownKeyLoader.set(MasterkeyFileLoadingStrategy.SCHEME);
|
||||
}
|
||||
initializeLastKnownKeyLoaderIfPossible(vaultSettings, vaultState, wrapper);
|
||||
|
||||
return vaultComponentFactory.create(vaultSettings, wrapper, vaultState, null).vault();
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Failed to determine vault state for " + vaultSettings.path.get(), e);
|
||||
LOG.warn("Failed to determine vault state for {}", vaultSettings.path.get(), e);
|
||||
return vaultComponentFactory.create(vaultSettings, wrapper, ERROR, e).vault();
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeLastKnownKeyLoaderIfPossible(VaultSettings vaultSettings, VaultState.Value vaultState, VaultConfigCache wrapper) throws IOException {
|
||||
if (vaultSettings.lastKnownKeyLoader.get() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (vaultState) {
|
||||
case LOCKED -> {
|
||||
wrapper.reloadConfig();
|
||||
vaultSettings.lastKnownKeyLoader.set(wrapper.get().getKeyId().getScheme());
|
||||
}
|
||||
case NEEDS_MIGRATION -> {
|
||||
//for legacy reasons: pre v8 vault do not have a config, but they are in the NEEDS_MIGRATION state
|
||||
vaultSettings.lastKnownKeyLoader.set(MasterkeyFileLoadingStrategy.SCHEME);
|
||||
}
|
||||
case VAULT_CONFIG_MISSING -> {
|
||||
//Nothing to do here, since there is no config to read
|
||||
}
|
||||
case MISSING, ALL_MISSING, ERROR, PROCESSING -> {
|
||||
// no config available or not safe to load
|
||||
}
|
||||
default -> {
|
||||
if (Files.exists(vaultSettings.path.get().resolve(VAULTCONFIG_FILENAME))) {
|
||||
try {
|
||||
wrapper.reloadConfig();
|
||||
vaultSettings.lastKnownKeyLoader.set(wrapper.get().getKeyId().getScheme());
|
||||
} catch (IOException e) {
|
||||
LOG.debug("Unable to load config for {}", vaultSettings.path.get(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static VaultState.Value redetermineVaultState(Vault vault) {
|
||||
VaultState state = vault.stateProperty();
|
||||
VaultState.Value previousState = state.getValue();
|
||||
return switch (previousState) {
|
||||
case LOCKED, NEEDS_MIGRATION, MISSING -> {
|
||||
try {
|
||||
var determinedState = determineVaultState(vault.getPath());
|
||||
if (determinedState == LOCKED) {
|
||||
vault.getVaultConfigCache().reloadConfig();
|
||||
}
|
||||
state.set(determinedState);
|
||||
yield determinedState;
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Failed to determine vault state for " + vault.getPath(), e);
|
||||
state.set(ERROR);
|
||||
vault.setLastKnownException(e);
|
||||
yield ERROR;
|
||||
}
|
||||
VaultState.Value previous = state.getValue();
|
||||
|
||||
if (previous.equals(UNLOCKED) || previous.equals(PROCESSING)) {
|
||||
return previous;
|
||||
}
|
||||
|
||||
try {
|
||||
VaultState.Value determined = determineVaultState(vault.getPath());
|
||||
|
||||
if (determined == LOCKED) {
|
||||
vault.getVaultConfigCache().reloadConfig();
|
||||
}
|
||||
case ERROR, UNLOCKED, PROCESSING -> previousState;
|
||||
};
|
||||
|
||||
state.set(determined);
|
||||
return determined;
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Failed to (re)determine vault state for {}", vault.getPath(), e);
|
||||
vault.setLastKnownException(e);
|
||||
state.set(ERROR);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
private static VaultState.Value determineVaultState(Path pathToVault) throws IOException {
|
||||
public static VaultState.Value determineVaultState(Path pathToVault) throws IOException {
|
||||
if (!Files.exists(pathToVault)) {
|
||||
return VaultState.Value.MISSING;
|
||||
return MISSING;
|
||||
}
|
||||
|
||||
VaultState.Value structureResult = checkDirStructure(pathToVault);
|
||||
|
||||
if (structureResult == LOCKED || structureResult == NEEDS_MIGRATION) {
|
||||
return structureResult;
|
||||
}
|
||||
|
||||
Path pathToVaultConfig = pathToVault.resolve(VAULTCONFIG_FILENAME);
|
||||
Path pathToMasterkey = pathToVault.resolve(MASTERKEY_FILENAME);
|
||||
|
||||
if (!Files.exists(pathToVaultConfig)) {
|
||||
BackupRestorer.restoreIfBackupPresent(pathToVault, VAULTCONFIG_FILENAME);
|
||||
}
|
||||
if (!Files.exists(pathToMasterkey)) {
|
||||
BackupRestorer.restoreIfBackupPresent(pathToVault, MASTERKEY_FILENAME);
|
||||
}
|
||||
|
||||
boolean hasConfig = Files.exists(pathToVaultConfig);
|
||||
|
||||
if (!hasConfig && !Files.exists(pathToMasterkey)) {
|
||||
return ALL_MISSING;
|
||||
}
|
||||
if (!hasConfig) {
|
||||
return VAULT_CONFIG_MISSING;
|
||||
}
|
||||
|
||||
return checkDirStructure(pathToVault);
|
||||
}
|
||||
|
||||
private static VaultState.Value checkDirStructure(Path pathToVault) throws IOException {
|
||||
return switch (CryptoFileSystemProvider.checkDirStructureForVault(pathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME)) {
|
||||
case VAULT -> VaultState.Value.LOCKED;
|
||||
case UNRELATED -> VaultState.Value.MISSING;
|
||||
case MAYBE_LEGACY -> Migrators.get().needsMigration(pathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME) ? //
|
||||
VaultState.Value.NEEDS_MIGRATION //
|
||||
: VaultState.Value.MISSING;
|
||||
case VAULT -> LOCKED;
|
||||
case UNRELATED -> MISSING;
|
||||
case MAYBE_LEGACY -> Migrators.get().needsMigration(pathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME) ? NEEDS_MIGRATION : MISSING;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,16 @@ public class VaultState extends ObservableValueBase<VaultState.Value> implements
|
||||
*/
|
||||
MISSING,
|
||||
|
||||
/**
|
||||
* No vault config found at the provided path
|
||||
*/
|
||||
VAULT_CONFIG_MISSING,
|
||||
|
||||
/**
|
||||
* No vault config and masterkey found at the provided path
|
||||
*/
|
||||
ALL_MISSING,
|
||||
|
||||
/**
|
||||
* Vault requires migration to a newer vault format
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.util.ResourceBundle;
|
||||
public class PasswordStrengthUtil {
|
||||
|
||||
private static final int PW_TRUNC_LEN = 100; // truncate very long passwords, since zxcvbn memory and runtime depends vastly on the length
|
||||
private static final String RESSOURCE_PREFIX = "passwordStrength.messageLabel.";
|
||||
private static final List<String> SANITIZED_INPUTS = List.of("cryptomator");
|
||||
|
||||
private final ResourceBundle resourceBundle;
|
||||
@@ -48,13 +47,15 @@ public class PasswordStrengthUtil {
|
||||
}
|
||||
|
||||
public String getStrengthDescription(Number score) {
|
||||
if (score.intValue() == -1) {
|
||||
return String.format(resourceBundle.getString(RESSOURCE_PREFIX + "tooShort"), minPwLength);
|
||||
} else if (resourceBundle.containsKey(RESSOURCE_PREFIX + score.intValue())) {
|
||||
return resourceBundle.getString(RESSOURCE_PREFIX + score.intValue());
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
return switch (score.intValue()) {
|
||||
case -1 -> String.format(resourceBundle.getString("passwordStrength.messageLabel.tooShort"), minPwLength);
|
||||
case 0 -> resourceBundle.getString("passwordStrength.messageLabel.0");
|
||||
case 1 -> resourceBundle.getString("passwordStrength.messageLabel.1");
|
||||
case 2 -> resourceBundle.getString("passwordStrength.messageLabel.2");
|
||||
case 3 -> resourceBundle.getString("passwordStrength.messageLabel.3");
|
||||
case 4 -> resourceBundle.getString("passwordStrength.messageLabel.4");
|
||||
default -> "";
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,9 +42,10 @@ public enum FxmlFile {
|
||||
QUIT("/fxml/quit.fxml"), //
|
||||
QUIT_FORCED("/fxml/quit_forced.fxml"), //
|
||||
RECOVERYKEY_CREATE("/fxml/recoverykey_create.fxml"), //
|
||||
RECOVERYKEY_EXPERT_SETTINGS("/fxml/recoverykey_expert_settings.fxml"), //
|
||||
RECOVERYKEY_ONBOARDING("/fxml/recoverykey_onboarding.fxml"), //
|
||||
RECOVERYKEY_RECOVER("/fxml/recoverykey_recover.fxml"), //
|
||||
RECOVERYKEY_RESET_PASSWORD("/fxml/recoverykey_reset_password.fxml"), //
|
||||
RECOVERYKEY_RESET_PASSWORD_SUCCESS("/fxml/recoverykey_reset_password_success.fxml"), //
|
||||
RECOVERYKEY_SUCCESS("/fxml/recoverykey_success.fxml"), //
|
||||
SHARE_VAULT("/fxml/share_vault.fxml"), //
|
||||
SIMPLE_DIALOG("/fxml/simple_dialog.fxml"), //
|
||||
|
||||
@@ -4,8 +4,10 @@ import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import dagger.multibindings.IntoMap;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.cryptofs.VaultConfig;
|
||||
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||
import org.cryptomator.ui.changepassword.NewPasswordController;
|
||||
import org.cryptomator.ui.changepassword.PasswordStrengthUtil;
|
||||
import org.cryptomator.ui.common.DefaultSceneFactory;
|
||||
@@ -20,6 +22,7 @@ import org.cryptomator.ui.recoverykey.RecoveryKeyValidateController;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.scene.Scene;
|
||||
@@ -119,8 +122,8 @@ abstract class ConvertVaultModule {
|
||||
@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);
|
||||
static FxController provideRecoveryKeyValidateController(@ConvertVaultWindow Vault vault, @ConvertVaultWindow VaultConfig.UnverifiedVaultConfig vaultConfig, @ConvertVaultWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, MasterkeyFileAccess masterkeyFileAccess) {
|
||||
return new RecoveryKeyValidateController(vault, vaultConfig, recoveryKey, recoveryKeyFactory, masterkeyFileAccess, new SimpleObjectProperty<>(RecoveryActionType.CONVERT_VAULT), new SimpleObjectProperty<>(null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ public class DecryptFileNamesViewController implements FxController {
|
||||
}
|
||||
}
|
||||
|
||||
//obvservable getter
|
||||
//observable getter
|
||||
|
||||
public ObservableValue<String> dropZoneTextProperty() {
|
||||
return dropZoneText;
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.cryptomator.ui.dialogs;
|
||||
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.ui.common.DefaultSceneFactory;
|
||||
import org.cryptomator.ui.common.StageFactory;
|
||||
import org.cryptomator.ui.controls.FontAwesome5Icon;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationScoped;
|
||||
@@ -19,17 +20,21 @@ public class Dialogs {
|
||||
|
||||
private final ResourceBundle resourceBundle;
|
||||
private final StageFactory stageFactory;
|
||||
private final DefaultSceneFactory sceneFactory;
|
||||
|
||||
private static final String BUTTON_KEY_CLOSE = "generic.button.close";
|
||||
|
||||
@Inject
|
||||
public Dialogs(ResourceBundle resourceBundle, StageFactory stageFactory) {
|
||||
public Dialogs(ResourceBundle resourceBundle, StageFactory stageFactory, DefaultSceneFactory sceneFactory) {
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.stageFactory = stageFactory;
|
||||
this.sceneFactory = sceneFactory;
|
||||
}
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Dialogs.class);
|
||||
|
||||
private SimpleDialog.Builder createDialogBuilder() {
|
||||
return new SimpleDialog.Builder(resourceBundle, stageFactory);
|
||||
return new SimpleDialog.Builder(resourceBundle, stageFactory, sceneFactory);
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareRemoveVaultDialog(Stage window, Vault vault, ObservableList<Vault> vaults) {
|
||||
@@ -47,6 +52,43 @@ public class Dialogs {
|
||||
});
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareContactHubVaultOwner(Stage window) {
|
||||
return createDialogBuilder().setOwner(window) //
|
||||
.setTitleKey("contactHubVaultOwner.title") //
|
||||
.setMessageKey("contactHubVaultOwner.message") //
|
||||
.setDescriptionKey("contactHubVaultOwner.description") //
|
||||
.setIcon(FontAwesome5Icon.EXCLAMATION)//
|
||||
.setOkButtonKey(BUTTON_KEY_CLOSE);
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareRecoveryVaultAdded(Stage window, String displayName) {
|
||||
return createDialogBuilder().setOwner(window) //
|
||||
.setTitleKey("recover.existing.title") //
|
||||
.setMessageKey("recover.existing.message") //
|
||||
.setDescriptionKey("recover.existing.description", displayName) //
|
||||
.setIcon(FontAwesome5Icon.CHECK)//
|
||||
.setOkButtonKey(BUTTON_KEY_CLOSE);
|
||||
}
|
||||
public SimpleDialog.Builder prepareRecoveryVaultAlreadyExists(Stage window, String displayName) {
|
||||
return createDialogBuilder().setOwner(window) //
|
||||
.setTitleKey("recover.alreadyExists.title") //
|
||||
.setMessageKey("recover.alreadyExists.message") //
|
||||
.setDescriptionKey("recover.alreadyExists.description", displayName) //
|
||||
.setIcon(FontAwesome5Icon.EXCLAMATION)//
|
||||
.setOkButtonKey(BUTTON_KEY_CLOSE);
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareRecoverPasswordSuccess(Stage window) {
|
||||
return createDialogBuilder()
|
||||
.setOwner(window) //
|
||||
.setTitleKey("recoveryKey.recover.title") //
|
||||
.setMessageKey("recoveryKey.recover.resetSuccess.message") //
|
||||
.setDescriptionKey("recoveryKey.recover.resetSuccess.description") //
|
||||
.setIcon(FontAwesome5Icon.CHECK)
|
||||
.setOkAction(Stage::close)
|
||||
.setOkButtonKey(BUTTON_KEY_CLOSE);
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareRemoveCertDialog(Stage window, Settings settings) {
|
||||
return createDialogBuilder() //
|
||||
.setOwner(window) //
|
||||
@@ -69,7 +111,7 @@ public class Dialogs {
|
||||
.setMessageKey("dokanySupportEnd.message") //
|
||||
.setDescriptionKey("dokanySupportEnd.description") //
|
||||
.setIcon(FontAwesome5Icon.EXCLAMATION) //
|
||||
.setOkButtonKey("generic.button.close") //
|
||||
.setOkButtonKey(BUTTON_KEY_CLOSE) //
|
||||
.setCancelButtonKey("dokanySupportEnd.preferencesBtn") //
|
||||
.setOkAction(Stage::close) //
|
||||
.setCancelAction(cancelAction);
|
||||
@@ -83,8 +125,20 @@ public class Dialogs {
|
||||
.setDescriptionKey("retryIfReadonly.description") //
|
||||
.setIcon(FontAwesome5Icon.EXCLAMATION) //
|
||||
.setOkButtonKey("retryIfReadonly.retry") //
|
||||
.setCancelButtonKey("generic.button.close") //
|
||||
.setCancelButtonKey(BUTTON_KEY_CLOSE) //
|
||||
.setOkAction(okAction) //
|
||||
.setCancelAction(Stage::close);
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareNoDDirectorySelectedDialog(Stage window) {
|
||||
return createDialogBuilder() //
|
||||
.setOwner(window) //
|
||||
.setTitleKey("recover.invalidSelection.title") //
|
||||
.setMessageKey("recover.invalidSelection.message") //
|
||||
.setDescriptionKey("recover.invalidSelection.description") //
|
||||
.setIcon(FontAwesome5Icon.EXCLAMATION) //
|
||||
.setOkButtonKey("generic.button.change") //
|
||||
.setOkAction(Stage::close);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.cryptomator.ui.dialogs;
|
||||
|
||||
import org.cryptomator.ui.common.DefaultSceneFactory;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
||||
import org.cryptomator.ui.common.StageFactory;
|
||||
@@ -30,15 +31,15 @@ public class SimpleDialog {
|
||||
|
||||
FxmlLoaderFactory loaderFactory = FxmlLoaderFactory.forController( //
|
||||
new SimpleDialogController(resolveText(builder.messageKey, null), //
|
||||
resolveText(builder.descriptionKey, null), //
|
||||
resolveText(builder.descriptionKey, builder.descriptionArgs), //
|
||||
builder.icon, //
|
||||
resolveText(builder.okButtonKey, null), //
|
||||
builder.cancelButtonKey != null ? resolveText(builder.cancelButtonKey, null) : null, //
|
||||
() -> builder.okAction.accept(dialogStage), //
|
||||
() -> builder.cancelAction.accept(dialogStage)), //
|
||||
Scene::new, builder.resourceBundle);
|
||||
builder.sceneFactory, builder.resourceBundle);
|
||||
|
||||
dialogStage.setScene(new Scene(loaderFactory.load(FxmlFile.SIMPLE_DIALOG.getRessourcePathString()).getRoot()));
|
||||
dialogStage.setScene(loaderFactory.createScene(FxmlFile.SIMPLE_DIALOG));
|
||||
}
|
||||
|
||||
public void showAndWait() {
|
||||
@@ -62,19 +63,22 @@ public class SimpleDialog {
|
||||
private Stage owner;
|
||||
private final ResourceBundle resourceBundle;
|
||||
private final StageFactory stageFactory;
|
||||
private final DefaultSceneFactory sceneFactory;
|
||||
private String titleKey;
|
||||
private String[] titleArgs;
|
||||
private String messageKey;
|
||||
private String descriptionKey;
|
||||
private String[] descriptionArgs;
|
||||
private String okButtonKey;
|
||||
private String cancelButtonKey;
|
||||
private FontAwesome5Icon icon;
|
||||
private Consumer<Stage> okAction = Stage::close;
|
||||
private Consumer<Stage> cancelAction = Stage::close;
|
||||
|
||||
public Builder(ResourceBundle resourceBundle, StageFactory stageFactory) {
|
||||
public Builder(ResourceBundle resourceBundle, StageFactory stageFactory, DefaultSceneFactory sceneFactory) {
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.stageFactory = stageFactory;
|
||||
this.sceneFactory = sceneFactory;
|
||||
}
|
||||
|
||||
public Builder setOwner(Stage owner) {
|
||||
@@ -93,8 +97,9 @@ public class SimpleDialog {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDescriptionKey(String descriptionKey) {
|
||||
public Builder setDescriptionKey(String descriptionKey, String... args) {
|
||||
this.descriptionKey = descriptionKey;
|
||||
this.descriptionArgs = args;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,15 +15,13 @@ import org.cryptomator.ui.lock.LockComponent;
|
||||
import org.cryptomator.ui.mainwindow.MainWindowComponent;
|
||||
import org.cryptomator.ui.preferences.PreferencesComponent;
|
||||
import org.cryptomator.ui.quit.QuitComponent;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||
import org.cryptomator.ui.sharevault.ShareVaultComponent;
|
||||
import org.cryptomator.ui.traymenu.TrayMenuComponent;
|
||||
import org.cryptomator.ui.unlock.UnlockComponent;
|
||||
import org.cryptomator.ui.updatereminder.UpdateReminderComponent;
|
||||
import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.scene.image.Image;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -40,7 +38,8 @@ import java.io.InputStream;
|
||||
HealthCheckComponent.class, //
|
||||
UpdateReminderComponent.class, //
|
||||
ShareVaultComponent.class, //
|
||||
EventViewComponent.class})
|
||||
EventViewComponent.class, //
|
||||
RecoveryKeyComponent.class})
|
||||
abstract class FxApplicationModule {
|
||||
|
||||
private static Image createImageFromResource(String resourceName) throws IOException {
|
||||
|
||||
@@ -28,7 +28,7 @@ import static org.cryptomator.common.vaults.VaultState.Value.*;
|
||||
@FxApplicationScoped
|
||||
public class FxApplicationTerminator {
|
||||
|
||||
private static final Set<VaultState.Value> STATES_ALLOWING_TERMINATION = EnumSet.of(LOCKED, NEEDS_MIGRATION, MISSING, ERROR);
|
||||
private static final Set<VaultState.Value> STATES_ALLOWING_TERMINATION = EnumSet.of(LOCKED, NEEDS_MIGRATION, MISSING, ERROR, VAULT_CONFIG_MISSING, ALL_MISSING);
|
||||
private static final Set<VaultState.Value> STATES_PREVENT_TERMINATION = EnumSet.of(PROCESSING);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FxApplicationTerminator.class);
|
||||
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package org.cryptomator.ui.keyloading.masterkeyfile;
|
||||
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.keyloading.KeyLoading;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javafx.beans.binding.StringBinding;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.WindowEvent;
|
||||
@@ -27,17 +31,41 @@ public class ChooseMasterkeyFileController implements FxController {
|
||||
private final Stage window;
|
||||
private final Vault vault;
|
||||
private final CompletableFuture<Path> result;
|
||||
private final RecoveryKeyComponent.Factory recoveryKeyWindow;
|
||||
private final ResourceBundle resourceBundle;
|
||||
|
||||
@FXML
|
||||
private CheckBox restoreInsteadCheckBox;
|
||||
@FXML
|
||||
private Button forwardButton;
|
||||
|
||||
@Inject
|
||||
public ChooseMasterkeyFileController(@KeyLoading Stage window, @KeyLoading Vault vault, CompletableFuture<Path> result, ResourceBundle resourceBundle) {
|
||||
public ChooseMasterkeyFileController(@KeyLoading Stage window, //
|
||||
@KeyLoading Vault vault, //
|
||||
CompletableFuture<Path> result, //
|
||||
RecoveryKeyComponent.Factory recoveryKeyWindow, //
|
||||
ResourceBundle resourceBundle) {
|
||||
this.window = window;
|
||||
this.vault = vault;
|
||||
this.result = result;
|
||||
this.recoveryKeyWindow = recoveryKeyWindow;
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.window.setOnHiding(this::windowClosed);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void initialize() {
|
||||
restoreInsteadCheckBox.selectedProperty().addListener((_, _, newVal) -> {
|
||||
if (newVal) {
|
||||
forwardButton.setText(resourceBundle.getString("addvaultwizard.existing.restore"));
|
||||
forwardButton.setOnAction(_ -> restoreMasterkey());
|
||||
} else {
|
||||
forwardButton.setText(resourceBundle.getString("generic.button.choose"));
|
||||
forwardButton.setOnAction(_ -> proceed());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void cancel() {
|
||||
window.close();
|
||||
@@ -47,6 +75,13 @@ public class ChooseMasterkeyFileController implements FxController {
|
||||
result.cancel(true);
|
||||
}
|
||||
|
||||
@FXML
|
||||
void restoreMasterkey() {
|
||||
Stage ownerStage = (Stage) window.getOwner();
|
||||
window.close();
|
||||
recoveryKeyWindow.create(vault, ownerStage, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_MASTERKEY)).showOnboardingDialogWindow();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void proceed() {
|
||||
LOG.trace("proceed()");
|
||||
@@ -62,7 +97,7 @@ public class ChooseMasterkeyFileController implements FxController {
|
||||
|
||||
//--- Setter & Getter ---
|
||||
|
||||
public String getDisplayName(){
|
||||
public String getDisplayName() {
|
||||
return vault.getDisplayName();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.cryptomator.ui.error.ErrorComponent;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationTerminator;
|
||||
import org.cryptomator.ui.fxapp.PrimaryStage;
|
||||
import org.cryptomator.ui.migration.MigrationComponent;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||
import org.cryptomator.ui.stats.VaultStatisticsComponent;
|
||||
import org.cryptomator.ui.traymenu.TrayMenuComponent;
|
||||
import org.cryptomator.ui.wrongfilealert.WrongFileAlertComponent;
|
||||
@@ -32,7 +33,7 @@ import javafx.stage.Stage;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@Module(subcomponents = {AddVaultWizardComponent.class, MigrationComponent.class, VaultStatisticsComponent.class, WrongFileAlertComponent.class, ErrorComponent.class})
|
||||
@Module(subcomponents = {AddVaultWizardComponent.class, MigrationComponent.class, VaultStatisticsComponent.class, WrongFileAlertComponent.class, ErrorComponent.class, RecoveryKeyComponent.class})
|
||||
abstract class MainWindowModule {
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -52,7 +52,7 @@ public class VaultDetailController implements FxController {
|
||||
case LOCKED -> FontAwesome5Icon.LOCK;
|
||||
case PROCESSING -> FontAwesome5Icon.SPINNER;
|
||||
case UNLOCKED -> FontAwesome5Icon.LOCK_OPEN;
|
||||
case NEEDS_MIGRATION, MISSING, ERROR -> FontAwesome5Icon.EXCLAMATION_TRIANGLE;
|
||||
case NEEDS_MIGRATION, MISSING, VAULT_CONFIG_MISSING, ALL_MISSING, ERROR -> FontAwesome5Icon.EXCLAMATION_TRIANGLE;
|
||||
};
|
||||
} else {
|
||||
return FontAwesome5Icon.EXCLAMATION_TRIANGLE;
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
package org.cryptomator.ui.mainwindow;
|
||||
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultListManager;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.dialogs.Dialogs;
|
||||
import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB;
|
||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||
|
||||
@MainWindowScoped
|
||||
public class VaultDetailMissingVaultController implements FxController {
|
||||
@@ -23,6 +29,7 @@ public class VaultDetailMissingVaultController implements FxController {
|
||||
private final ObservableList<Vault> vaults;
|
||||
private final ResourceBundle resourceBundle;
|
||||
private final Stage window;
|
||||
private final RecoveryKeyComponent.Factory recoveryKeyWindow;
|
||||
private final Dialogs dialogs;
|
||||
|
||||
@Inject
|
||||
@@ -30,11 +37,13 @@ public class VaultDetailMissingVaultController implements FxController {
|
||||
ObservableList<Vault> vaults, //
|
||||
ResourceBundle resourceBundle, //
|
||||
@MainWindow Stage window, //
|
||||
Dialogs dialogs) {
|
||||
Dialogs dialogs, //
|
||||
RecoveryKeyComponent.Factory recoveryKeyWindow) {
|
||||
this.vault = vault;
|
||||
this.vaults = vaults;
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.window = window;
|
||||
this.recoveryKeyWindow = recoveryKeyWindow;
|
||||
this.dialogs = dialogs;
|
||||
}
|
||||
|
||||
@@ -48,6 +57,19 @@ public class VaultDetailMissingVaultController implements FxController {
|
||||
dialogs.prepareRemoveVaultDialog(window, vault.get(), vaults).build().showAndWait();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void restoreVaultConfig() {
|
||||
if(KeyLoadingStrategy.isHubVault(vault.get().getVaultSettings().lastKnownKeyLoader.get())){
|
||||
dialogs.prepareContactHubVaultOwner(window).build().showAndWait();
|
||||
}
|
||||
else if(Files.exists(vault.get().getPath().resolve(MASTERKEY_FILENAME))){
|
||||
recoveryKeyWindow.create(vault.get(), window, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_VAULT_CONFIG)).showOnboardingDialogWindow();
|
||||
}
|
||||
else {
|
||||
recoveryKeyWindow.create(vault.get(), window, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_ALL)).showOnboardingDialogWindow();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
void changeLocation() {
|
||||
// copied from ChooseExistingVaultController class
|
||||
|
||||
@@ -55,7 +55,7 @@ public class VaultListCellController implements FxController {
|
||||
case LOCKED -> FontAwesome5Icon.LOCK;
|
||||
case PROCESSING -> FontAwesome5Icon.SPINNER;
|
||||
case UNLOCKED -> FontAwesome5Icon.LOCK_OPEN;
|
||||
case NEEDS_MIGRATION, MISSING, ERROR -> FontAwesome5Icon.EXCLAMATION_TRIANGLE;
|
||||
case NEEDS_MIGRATION, MISSING, VAULT_CONFIG_MISSING, ALL_MISSING, ERROR -> FontAwesome5Icon.EXCLAMATION_TRIANGLE;
|
||||
};
|
||||
} else {
|
||||
return FontAwesome5Icon.EXCLAMATION_TRIANGLE;
|
||||
|
||||
@@ -20,11 +20,13 @@ import javafx.stage.Stage;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.ALL_MISSING;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.ERROR;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.LOCKED;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.MISSING;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.NEEDS_MIGRATION;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.UNLOCKED;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.VAULT_CONFIG_MISSING;
|
||||
|
||||
@MainWindowScoped
|
||||
public class VaultListContextMenuController implements FxController {
|
||||
@@ -63,7 +65,7 @@ public class VaultListContextMenuController implements FxController {
|
||||
|
||||
this.selectedVaultState = selectedVault.flatMap(Vault::stateProperty).orElse(null);
|
||||
this.selectedVaultPassphraseStored = selectedVault.map(this::isPasswordStored).orElse(false);
|
||||
this.selectedVaultRemovable = selectedVaultState.map(EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION)::contains).orElse(false);
|
||||
this.selectedVaultRemovable = selectedVaultState.map(EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION, ALL_MISSING, VAULT_CONFIG_MISSING)::contains).orElse(false);
|
||||
this.selectedVaultUnlockable = selectedVaultState.map(LOCKED::equals).orElse(false);
|
||||
this.selectedVaultLockable = selectedVaultState.map(UNLOCKED::equals).orElse(false);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package org.cryptomator.ui.mainwindow;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.recovery.VaultPreparator;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultComponent;
|
||||
import org.cryptomator.common.vaults.VaultListManager;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||
import org.cryptomator.cryptofs.DirStructure;
|
||||
import org.cryptomator.cryptofs.common.Constants;
|
||||
import org.cryptomator.integrations.mount.MountService;
|
||||
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.VaultService;
|
||||
@@ -13,6 +18,7 @@ import org.cryptomator.ui.dialogs.Dialogs;
|
||||
import org.cryptomator.ui.fxapp.FxFSEventList;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||
import org.cryptomator.ui.preferences.SelectedPreferencesTab;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -22,6 +28,7 @@ import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
@@ -37,11 +44,14 @@ import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.input.TransferMode;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.Stage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
@@ -50,10 +60,12 @@ import java.util.stream.Collectors;
|
||||
import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_EXT;
|
||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.ALL_MISSING;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.ERROR;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.LOCKED;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.MISSING;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.NEEDS_MIGRATION;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.VAULT_CONFIG_MISSING;
|
||||
|
||||
@MainWindowScoped
|
||||
public class VaultListController implements FxController {
|
||||
@@ -75,6 +87,10 @@ public class VaultListController implements FxController {
|
||||
private final ObservableValue<Double> cellSize;
|
||||
private final Dialogs dialogs;
|
||||
|
||||
private final VaultComponent.Factory vaultComponentFactory;
|
||||
private final RecoveryKeyComponent.Factory recoveryKeyWindow;
|
||||
private final List<MountService> mountServices;
|
||||
|
||||
public ListView<Vault> vaultList;
|
||||
public StackPane root;
|
||||
@FXML
|
||||
@@ -94,6 +110,9 @@ public class VaultListController implements FxController {
|
||||
FxApplicationWindows appWindows, //
|
||||
Settings settings, //
|
||||
Dialogs dialogs, //
|
||||
RecoveryKeyComponent.Factory recoveryKeyWindow, //
|
||||
VaultComponent.Factory vaultComponentFactory, //
|
||||
List<MountService> mountServices, //
|
||||
FxFSEventList fxFSEventList) {
|
||||
this.mainWindow = mainWindow;
|
||||
this.vaults = vaults;
|
||||
@@ -105,6 +124,9 @@ public class VaultListController implements FxController {
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.appWindows = appWindows;
|
||||
this.dialogs = dialogs;
|
||||
this.recoveryKeyWindow = recoveryKeyWindow;
|
||||
this.vaultComponentFactory = vaultComponentFactory;
|
||||
this.mountServices = mountServices;
|
||||
|
||||
this.emptyVaultList = Bindings.isEmpty(vaults);
|
||||
this.unreadEvents = fxFSEventList.unreadEventsProperty();
|
||||
@@ -204,6 +226,26 @@ public class VaultListController implements FxController {
|
||||
VaultListManager.redetermineVaultState(newValue);
|
||||
}
|
||||
|
||||
private Optional<Path> chooseValidVaultDirectory() {
|
||||
DirectoryChooser directoryChooser = new DirectoryChooser();
|
||||
File selectedDirectory;
|
||||
|
||||
do {
|
||||
selectedDirectory = directoryChooser.showDialog(mainWindow);
|
||||
if (selectedDirectory == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Path selectedPath = selectedDirectory.toPath();
|
||||
if (!Files.isDirectory(selectedPath.resolve(Constants.DATA_DIR_NAME))) {
|
||||
dialogs.prepareNoDDirectorySelectedDialog(mainWindow).build().showAndWait();
|
||||
selectedDirectory = null;
|
||||
}
|
||||
} while (selectedDirectory == null);
|
||||
|
||||
return Optional.of(selectedDirectory.toPath());
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void didClickAddNewVault() {
|
||||
addVaultWizard.build().showAddNewVaultWizard(resourceBundle);
|
||||
@@ -214,9 +256,40 @@ public class VaultListController implements FxController {
|
||||
addVaultWizard.build().showAddExistingVaultWizard(resourceBundle);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void didClickRecoverExistingVault() {
|
||||
Optional<Path> selectedDirectory = chooseValidVaultDirectory();
|
||||
if (selectedDirectory.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Path path = selectedDirectory.get();
|
||||
Optional<Vault> matchingVaultListEntry = vaultListManager.get(path);
|
||||
if (matchingVaultListEntry.isPresent()) {
|
||||
dialogs.prepareRecoveryVaultAlreadyExists(mainWindow, matchingVaultListEntry.get().getDisplayName()) //
|
||||
.setOkAction(Stage::close) //
|
||||
.build().showAndWait();
|
||||
return;
|
||||
}
|
||||
|
||||
Vault preparedVault = VaultPreparator.prepareVault(path, vaultComponentFactory, mountServices, resourceBundle);
|
||||
VaultListManager.redetermineVaultState(preparedVault);
|
||||
|
||||
switch (preparedVault.getState()) {
|
||||
case VAULT_CONFIG_MISSING -> recoveryKeyWindow.create(preparedVault, mainWindow, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_VAULT_CONFIG)).showOnboardingDialogWindow();
|
||||
case ALL_MISSING -> recoveryKeyWindow.create(preparedVault, mainWindow, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_ALL)).showOnboardingDialogWindow();
|
||||
case LOCKED, NEEDS_MIGRATION -> {
|
||||
vaultListManager.addVault(preparedVault);
|
||||
dialogs.prepareRecoveryVaultAdded(mainWindow, preparedVault.getDisplayName()).setOkAction(Stage::close).build().showAndWait();
|
||||
}
|
||||
default -> LOG.warn("Unhandled vault state during recovery: {}", preparedVault.getState());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void pressedShortcutToRemoveVault() {
|
||||
final var vault = selectedVault.get();
|
||||
if (vault != null && EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION).contains(vault.getState())) {
|
||||
if (vault != null && EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION, ALL_MISSING, VAULT_CONFIG_MISSING).contains(vault.getState())) {
|
||||
dialogs.prepareRemoveVaultDialog(mainWindow, vault, vaults).build().showAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,13 @@ package org.cryptomator.ui.recoverykey;
|
||||
import dagger.BindsInstance;
|
||||
import dagger.Lazy;
|
||||
import dagger.Subcomponent;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlScene;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
@@ -24,6 +26,9 @@ public interface RecoveryKeyComponent {
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_RECOVER)
|
||||
Lazy<Scene> recoverScene();
|
||||
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_ONBOARDING)
|
||||
Lazy<Scene> recoverOnboardingScene();
|
||||
|
||||
default void showRecoveryKeyCreationWindow() {
|
||||
Stage stage = window();
|
||||
stage.setScene(creationScene().get());
|
||||
@@ -38,11 +43,19 @@ public interface RecoveryKeyComponent {
|
||||
stage.show();
|
||||
}
|
||||
|
||||
default void showOnboardingDialogWindow() {
|
||||
Stage stage = window();
|
||||
stage.setScene(recoverOnboardingScene().get());
|
||||
stage.sizeToScene();
|
||||
stage.show();
|
||||
}
|
||||
|
||||
@Subcomponent.Factory
|
||||
interface Factory {
|
||||
|
||||
RecoveryKeyComponent create(@BindsInstance @RecoveryKeyWindow Vault vault, @BindsInstance @Named("keyRecoveryOwner") Stage owner);
|
||||
RecoveryKeyComponent create(@BindsInstance @RecoveryKeyWindow Vault vault, //
|
||||
@BindsInstance @Named("keyRecoveryOwner") Stage owner, //
|
||||
@BindsInstance @Named("recoverType") ObjectProperty<RecoveryActionType> recoverType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,28 +1,45 @@
|
||||
package org.cryptomator.ui.recoverykey;
|
||||
|
||||
import dagger.Lazy;
|
||||
import org.cryptomator.common.recovery.CryptoFsInitializer;
|
||||
import org.cryptomator.common.recovery.MasterkeyService;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.recovery.RecoveryDirectory;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultListManager;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
|
||||
import org.cryptomator.cryptolib.api.Masterkey;
|
||||
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||
import org.cryptomator.ui.common.Animations;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlScene;
|
||||
import org.cryptomator.ui.controls.FormattedLabel;
|
||||
import org.cryptomator.ui.controls.NiceSecurePasswordField;
|
||||
import org.cryptomator.ui.dialogs.Dialogs;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.stage.Stage;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
|
||||
|
||||
@RecoveryKeyScoped
|
||||
public class RecoveryKeyCreationController implements FxController {
|
||||
|
||||
@@ -30,23 +47,71 @@ public class RecoveryKeyCreationController implements FxController {
|
||||
|
||||
private final Stage window;
|
||||
private final Lazy<Scene> successScene;
|
||||
private final Lazy<Scene> recoverykeyExpertSettingsScene;
|
||||
private final MasterkeyFileAccess masterkeyFileAccess;
|
||||
private final Vault vault;
|
||||
private final ExecutorService executor;
|
||||
private final RecoveryKeyFactory recoveryKeyFactory;
|
||||
private final StringProperty recoveryKeyProperty;
|
||||
private final FxApplicationWindows appWindows;
|
||||
public NiceSecurePasswordField passwordField;
|
||||
private final IntegerProperty shorteningThreshold;
|
||||
private final ObjectProperty<RecoveryActionType> recoverType;
|
||||
private final ResourceBundle resourceBundle;
|
||||
public FormattedLabel descriptionLabel;
|
||||
public Button cancelButton;
|
||||
public Button nextButton;
|
||||
private final VaultListManager vaultListManager;
|
||||
private final Dialogs dialogs;
|
||||
|
||||
@Inject
|
||||
public RecoveryKeyCreationController(@RecoveryKeyWindow Stage window, @FxmlScene(FxmlFile.RECOVERYKEY_SUCCESS) Lazy<Scene> successScene, @RecoveryKeyWindow Vault vault, RecoveryKeyFactory recoveryKeyFactory, ExecutorService executor, @RecoveryKeyWindow StringProperty recoveryKey, FxApplicationWindows appWindows, ResourceBundle resourceBundle) {
|
||||
public RecoveryKeyCreationController(FxApplicationWindows appWindows, //
|
||||
@RecoveryKeyWindow Stage window, //
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_SUCCESS) Lazy<Scene> successScene, //
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_EXPERT_SETTINGS) Lazy<Scene> recoverykeyExpertSettingsScene, //
|
||||
@RecoveryKeyWindow Vault vault, //
|
||||
RecoveryKeyFactory recoveryKeyFactory, //
|
||||
MasterkeyFileAccess masterkeyFileAccess, //
|
||||
ExecutorService executor, //
|
||||
@RecoveryKeyWindow StringProperty recoveryKey, //
|
||||
@Named("shorteningThreshold") IntegerProperty shorteningThreshold, //
|
||||
@Named("recoverType") ObjectProperty<RecoveryActionType> recoverType, //
|
||||
VaultListManager vaultListManager, //
|
||||
ResourceBundle resourceBundle, //
|
||||
Dialogs dialogs) {
|
||||
this.window = window;
|
||||
window.setTitle(resourceBundle.getString("recoveryKey.display.title"));
|
||||
this.successScene = successScene;
|
||||
this.recoverykeyExpertSettingsScene = recoverykeyExpertSettingsScene;
|
||||
this.vault = vault;
|
||||
this.executor = executor;
|
||||
this.recoveryKeyFactory = recoveryKeyFactory;
|
||||
this.recoveryKeyProperty = recoveryKey;
|
||||
this.appWindows = appWindows;
|
||||
this.recoverType = recoverType;
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.masterkeyFileAccess = masterkeyFileAccess;
|
||||
this.shorteningThreshold = shorteningThreshold;
|
||||
this.vaultListManager = vaultListManager;
|
||||
this.dialogs = dialogs;
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
if (recoverType.get() == RecoveryActionType.SHOW_KEY) {
|
||||
window.setTitle(resourceBundle.getString("recoveryKey.display.title"));
|
||||
} else if (recoverType.get() == RecoveryActionType.RESTORE_VAULT_CONFIG) {
|
||||
window.setTitle(resourceBundle.getString("recover.recoverVaultConfig.title"));
|
||||
descriptionLabel.formatProperty().set(resourceBundle.getString("recoveryKey.recover.description"));
|
||||
cancelButton.setOnAction((_) -> back());
|
||||
cancelButton.setText(resourceBundle.getString("generic.button.back"));
|
||||
nextButton.setOnAction((_) -> restoreWithPassword());
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void back() {
|
||||
window.setScene(recoverykeyExpertSettingsScene.get());
|
||||
window.centerOnScreen();
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -71,6 +136,42 @@ public class RecoveryKeyCreationController implements FxController {
|
||||
executor.submit(task);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void restoreWithPassword() {
|
||||
|
||||
try (RecoveryDirectory recoveryDirectory = RecoveryDirectory.create(vault.getPath())) {
|
||||
Path recoveryPath = recoveryDirectory.getRecoveryPath();
|
||||
|
||||
Path masterkeyFilePath = vault.getPath().resolve(MASTERKEY_FILENAME);
|
||||
|
||||
try (Masterkey masterkey = MasterkeyService.load(masterkeyFileAccess, masterkeyFilePath, passwordField.getCharacters())) {
|
||||
var combo = MasterkeyService.detect(masterkey, vault.getPath())
|
||||
.orElseThrow(() -> new IllegalStateException("Could not detect combo for vault path: " + vault.getPath()));
|
||||
|
||||
CryptoFsInitializer.init(recoveryPath, masterkey, shorteningThreshold.get(), combo);
|
||||
}
|
||||
|
||||
recoveryDirectory.moveRecoveredFile(VAULTCONFIG_FILENAME);
|
||||
|
||||
if (!vaultListManager.isAlreadyAdded(vault.getPath())) {
|
||||
vaultListManager.add(vault.getPath());
|
||||
}
|
||||
window.close();
|
||||
dialogs.prepareRecoverPasswordSuccess((Stage)window.getOwner()) //
|
||||
.setTitleKey("recover.recoverVaultConfig.title") //
|
||||
.setMessageKey("recoveryKey.recover.resetVaultConfigSuccess.message") //
|
||||
.setDescriptionKey("recoveryKey.recover.resetMasterkeyFileSuccess.description")
|
||||
.build().showAndWait();
|
||||
|
||||
} catch (InvalidPassphraseException e) {
|
||||
LOG.info("Password invalid", e);
|
||||
Animations.createShakeWindowAnimation(window).play();
|
||||
} catch (IOException | CryptoException | IllegalStateException e) {
|
||||
LOG.error("Recovery process failed", e);
|
||||
appWindows.showErrorWindow(e, window, null);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void close() {
|
||||
window.close();
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
package org.cryptomator.ui.recoverykey;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javafx.application.Application;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import dagger.Lazy;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultState;
|
||||
import org.cryptomator.ui.addvaultwizard.CreateNewVaultExpertSettingsController;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlScene;
|
||||
import org.cryptomator.ui.controls.NumericTextField;
|
||||
|
||||
@RecoveryKeyScoped
|
||||
public class RecoveryKeyExpertSettingsController implements FxController {
|
||||
|
||||
public static final int MAX_SHORTENING_THRESHOLD = 220;
|
||||
public static final int MIN_SHORTENING_THRESHOLD = 36;
|
||||
private static final String DOCS_NAME_SHORTENING_URL = "https://docs.cryptomator.org/security/vault/#name-shortening";
|
||||
|
||||
private final Stage window;
|
||||
private final Lazy<Application> application;
|
||||
private final Vault vault;
|
||||
private final ObjectProperty<RecoveryActionType> recoverType;
|
||||
private final IntegerProperty shorteningThreshold;
|
||||
private final Lazy<Scene> resetPasswordScene;
|
||||
private final Lazy<Scene> createScene;
|
||||
private final Lazy<Scene> onBoardingScene;
|
||||
private final Lazy<Scene> recoverScene;
|
||||
private final BooleanBinding validShorteningThreshold;
|
||||
|
||||
@FXML
|
||||
public CheckBox expertSettingsCheckBox;
|
||||
@FXML
|
||||
public NumericTextField shorteningThresholdTextField;
|
||||
|
||||
@Inject
|
||||
public RecoveryKeyExpertSettingsController(@RecoveryKeyWindow Stage window, //
|
||||
Lazy<Application> application, //
|
||||
@RecoveryKeyWindow Vault vault, //
|
||||
@Named("recoverType") ObjectProperty<RecoveryActionType> recoverType, //
|
||||
@Named("shorteningThreshold") IntegerProperty shorteningThreshold, //
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD) Lazy<Scene> resetPasswordScene, //
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_CREATE) Lazy<Scene> createScene, //
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_ONBOARDING) Lazy<Scene> onBoardingScene, //
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_RECOVER) Lazy<Scene> recoverScene) {
|
||||
this.window = window;
|
||||
this.application = application;
|
||||
this.vault = vault;
|
||||
this.recoverType = recoverType;
|
||||
this.shorteningThreshold = shorteningThreshold;
|
||||
this.resetPasswordScene = resetPasswordScene;
|
||||
this.createScene = createScene;
|
||||
this.onBoardingScene = onBoardingScene;
|
||||
this.recoverScene = recoverScene;
|
||||
this.validShorteningThreshold = Bindings.createBooleanBinding(this::isValidShorteningThreshold, shorteningThreshold);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
shorteningThresholdTextField.setPromptText(MIN_SHORTENING_THRESHOLD + "-" + MAX_SHORTENING_THRESHOLD);
|
||||
shorteningThresholdTextField.setText(Integer.toString(MAX_SHORTENING_THRESHOLD));
|
||||
shorteningThresholdTextField.textProperty().addListener((_, _, newValue) -> {
|
||||
try {
|
||||
int intValue = Integer.parseInt(newValue);
|
||||
shorteningThreshold.set(intValue);
|
||||
} catch (NumberFormatException e) {
|
||||
shorteningThreshold.set(0); //the value is set to 0 to ensure that an invalid value assignment is detected during a NumberFormatException
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void toggleUseExpertSettings() {
|
||||
if (!expertSettingsCheckBox.isSelected()) {
|
||||
shorteningThresholdTextField.setText(Integer.toString(CreateNewVaultExpertSettingsController.MAX_SHORTENING_THRESHOLD));
|
||||
}
|
||||
}
|
||||
|
||||
public void openDocs() {
|
||||
application.get().getHostServices().showDocument(DOCS_NAME_SHORTENING_URL);
|
||||
}
|
||||
|
||||
public BooleanBinding validShorteningThresholdProperty() {
|
||||
return validShorteningThreshold;
|
||||
}
|
||||
|
||||
public boolean isValidShorteningThreshold() {
|
||||
var value = shorteningThreshold.get();
|
||||
return value >= MIN_SHORTENING_THRESHOLD && value <= MAX_SHORTENING_THRESHOLD;
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void back() {
|
||||
if (recoverType.get() == RecoveryActionType.RESTORE_ALL && vault.getState() == VaultState.Value.VAULT_CONFIG_MISSING) {
|
||||
window.setScene(recoverScene.get());
|
||||
} else if (recoverType.get() == RecoveryActionType.RESTORE_ALL && vault.getState() == VaultState.Value.ALL_MISSING) {
|
||||
window.setScene(recoverScene.get());
|
||||
} else if (recoverType.get() == RecoveryActionType.RESTORE_VAULT_CONFIG) {
|
||||
window.setScene(onBoardingScene.get());
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void next() {
|
||||
if (recoverType.get() == RecoveryActionType.RESTORE_VAULT_CONFIG) {
|
||||
window.setScene(createScene.get());
|
||||
} else {
|
||||
window.setScene(resetPasswordScene.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,12 @@ import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import dagger.multibindings.IntoMap;
|
||||
import org.cryptomator.common.Nullable;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.cryptofs.VaultConfig;
|
||||
import org.cryptomator.cryptolib.api.CryptorProvider;
|
||||
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||
import org.cryptomator.ui.addvaultwizard.CreateNewVaultExpertSettingsController;
|
||||
import org.cryptomator.ui.common.DefaultSceneFactory;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.FxControllerKey;
|
||||
@@ -19,6 +23,10 @@ import org.cryptomator.ui.common.StageFactory;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.scene.Scene;
|
||||
@@ -99,12 +107,18 @@ abstract class RecoveryKeyModule {
|
||||
}
|
||||
|
||||
@Provides
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD_SUCCESS)
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_ONBOARDING)
|
||||
@RecoveryKeyScoped
|
||||
static Scene provideRecoveryKeyResetPasswordSuccessScene(@RecoveryKeyWindow FxmlLoaderFactory fxmlLoaders) {
|
||||
return fxmlLoaders.createScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD_SUCCESS);
|
||||
static Scene provideRecoveryKeyOnboardingScene(@RecoveryKeyWindow FxmlLoaderFactory fxmlLoaders) {
|
||||
return fxmlLoaders.createScene(FxmlFile.RECOVERYKEY_ONBOARDING);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_EXPERT_SETTINGS)
|
||||
@RecoveryKeyScoped
|
||||
static Scene provideRecoveryKeyExpertSettingsScene(@RecoveryKeyWindow FxmlLoaderFactory fxmlLoaders) {
|
||||
return fxmlLoaders.createScene(FxmlFile.RECOVERYKEY_EXPERT_SETTINGS);
|
||||
}
|
||||
|
||||
// ------------------
|
||||
|
||||
@@ -120,6 +134,25 @@ abstract class RecoveryKeyModule {
|
||||
return new RecoveryKeyDisplayController(window, vault.getDisplayName(), recoveryKey.get(), localization);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("shorteningThreshold")
|
||||
@RecoveryKeyScoped
|
||||
static IntegerProperty provideShorteningThreshold() {
|
||||
return new SimpleIntegerProperty(CreateNewVaultExpertSettingsController.MAX_SHORTENING_THRESHOLD);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("cipherCombo")
|
||||
@RecoveryKeyScoped
|
||||
static ObjectProperty<CryptorProvider.Scheme> provideCipherCombo() {
|
||||
return new SimpleObjectProperty<>();
|
||||
}
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FxControllerKey(RecoveryKeyExpertSettingsController.class)
|
||||
abstract FxController provideRecoveryKeyExpertSettingsController(RecoveryKeyExpertSettingsController controller);
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FxControllerKey(RecoveryKeyRecoverController.class)
|
||||
@@ -137,14 +170,14 @@ abstract class RecoveryKeyModule {
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FxControllerKey(RecoveryKeyResetPasswordSuccessController.class)
|
||||
abstract FxController bindRecoveryKeyResetPasswordSuccessController(RecoveryKeyResetPasswordSuccessController controller);
|
||||
@FxControllerKey(RecoveryKeyOnboardingController.class)
|
||||
abstract FxController bindRecoveryKeyOnboardingController(RecoveryKeyOnboardingController 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);
|
||||
static FxController bindRecoveryKeyValidateController(@RecoveryKeyWindow Vault vault, @RecoveryKeyWindow @Nullable VaultConfig.UnverifiedVaultConfig vaultConfig, @RecoveryKeyWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, @Named("recoverType") ObjectProperty<RecoveryActionType> recoverType, @Named("cipherCombo") ObjectProperty<CryptorProvider.Scheme> cipherCombo, @Nullable MasterkeyFileAccess masterkeyFileAccess) {
|
||||
return new RecoveryKeyValidateController(vault, vaultConfig, recoveryKey, recoveryKeyFactory, masterkeyFileAccess, recoverType, cipherCombo);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
package org.cryptomator.ui.recoverykey;
|
||||
|
||||
import dagger.Lazy;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultState;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlScene;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.RadioButton;
|
||||
import javafx.scene.control.Toggle;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import static org.cryptomator.common.recovery.RecoveryActionType.RESTORE_ALL;
|
||||
import static org.cryptomator.common.recovery.RecoveryActionType.RESTORE_VAULT_CONFIG;
|
||||
|
||||
@RecoveryKeyScoped
|
||||
public class RecoveryKeyOnboardingController implements FxController {
|
||||
|
||||
private final Stage window;
|
||||
private final Vault vault;
|
||||
private final Lazy<Scene> recoverykeyRecoverScene;
|
||||
private final Lazy<Scene> recoverykeyExpertSettingsScene;
|
||||
private final ObjectProperty<RecoveryActionType> recoverType;
|
||||
private final ResourceBundle resourceBundle;
|
||||
|
||||
public Label titleLabel;
|
||||
public Label messageLabel;
|
||||
public Label pleaseConfirm;
|
||||
public Label secondTextDesc;
|
||||
|
||||
@FXML
|
||||
private CheckBox affirmationBox;
|
||||
@FXML
|
||||
private RadioButton recoveryKeyRadio;
|
||||
@FXML
|
||||
private RadioButton passwordRadio;
|
||||
@FXML
|
||||
private Button nextButton;
|
||||
@FXML
|
||||
private VBox chooseMethodeBox;
|
||||
@FXML
|
||||
private ToggleGroup methodToggleGroup = new ToggleGroup();
|
||||
@FXML
|
||||
private HBox hBox;
|
||||
|
||||
@Inject
|
||||
public RecoveryKeyOnboardingController(@RecoveryKeyWindow Stage window, //
|
||||
@RecoveryKeyWindow Vault vault, //
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_RECOVER) Lazy<Scene> recoverykeyRecoverScene, //
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_EXPERT_SETTINGS) Lazy<Scene> recoverykeyExpertSettingsScene, //
|
||||
@Named("recoverType") ObjectProperty<RecoveryActionType> recoverType, //
|
||||
ResourceBundle resourceBundle) {
|
||||
this.window = window;
|
||||
this.vault = vault;
|
||||
this.recoverykeyRecoverScene = recoverykeyRecoverScene;
|
||||
this.recoverykeyExpertSettingsScene = recoverykeyExpertSettingsScene;
|
||||
this.recoverType = recoverType;
|
||||
this.resourceBundle = resourceBundle;
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
recoveryKeyRadio.setToggleGroup(methodToggleGroup);
|
||||
passwordRadio.setToggleGroup(methodToggleGroup);
|
||||
|
||||
BooleanBinding showMethodSelection = Bindings.createBooleanBinding(
|
||||
() -> recoverType.get() == RecoveryActionType.RESTORE_VAULT_CONFIG, recoverType);
|
||||
chooseMethodeBox.visibleProperty().bind(showMethodSelection);
|
||||
chooseMethodeBox.managedProperty().bind(showMethodSelection);
|
||||
|
||||
nextButton.disableProperty().bind(
|
||||
affirmationBox.selectedProperty().not()
|
||||
.or(methodToggleGroup.selectedToggleProperty().isNull().and(showMethodSelection))
|
||||
);
|
||||
|
||||
switch (recoverType.get()) {
|
||||
case RESTORE_MASTERKEY -> {
|
||||
window.setTitle(resourceBundle.getString("recover.recoverMasterkey.title"));
|
||||
messageLabel.setVisible(false);
|
||||
messageLabel.setManaged(false);
|
||||
pleaseConfirm.setText(resourceBundle.getString("recover.onBoarding.pleaseConfirm"));
|
||||
}
|
||||
case RESTORE_ALL -> {
|
||||
window.setTitle(resourceBundle.getString("recover.recoverVaultConfig.title"));
|
||||
messageLabel.setVisible(true);
|
||||
messageLabel.setManaged(true);
|
||||
pleaseConfirm.setText(resourceBundle.getString("recover.onBoarding.otherwisePleaseConfirm"));
|
||||
}
|
||||
case RESTORE_VAULT_CONFIG -> {
|
||||
window.setTitle(resourceBundle.getString("recover.recoverVaultConfig.title"));
|
||||
messageLabel.setVisible(false);
|
||||
messageLabel.setManaged(false);
|
||||
pleaseConfirm.setText(resourceBundle.getString("recover.onBoarding.pleaseConfirm"));
|
||||
}
|
||||
default -> window.setTitle("");
|
||||
}
|
||||
|
||||
if (vault.getState() == VaultState.Value.ALL_MISSING) {
|
||||
messageLabel.setText(resourceBundle.getString("recover.onBoarding.allMissing.intro"));
|
||||
} else {
|
||||
messageLabel.setText(resourceBundle.getString("recover.onBoarding.intro"));
|
||||
}
|
||||
|
||||
titleLabel.textProperty().bind(Bindings.createStringBinding(() ->
|
||||
recoverType.get() == RecoveryActionType.RESTORE_MASTERKEY
|
||||
? resourceBundle.getString("recover.recoverMasterkey.title")
|
||||
: resourceBundle.getString("recover.recoverVaultConfig.title"), recoverType));
|
||||
|
||||
BooleanBinding isRestoreMasterkey = Bindings.createBooleanBinding(
|
||||
() -> recoverType.get() == RecoveryActionType.RESTORE_MASTERKEY, recoverType);
|
||||
hBox.minHeightProperty().bind(Bindings.when(isRestoreMasterkey).then(206.0).otherwise(Region.USE_COMPUTED_SIZE));
|
||||
|
||||
secondTextDesc.textProperty().bind(Bindings.createStringBinding(() -> {
|
||||
RecoveryActionType type = recoverType.get();
|
||||
Toggle sel = methodToggleGroup.getSelectedToggle();
|
||||
return switch (type) {
|
||||
case RESTORE_VAULT_CONFIG -> resourceBundle.getString(sel == passwordRadio
|
||||
? "recover.onBoarding.intro.password"
|
||||
: "recover.onBoarding.intro.recoveryKey");
|
||||
case RESTORE_MASTERKEY -> resourceBundle.getString("recover.onBoarding.intro.masterkey.recoveryKey");
|
||||
case RESTORE_ALL -> resourceBundle.getString("recover.onBoarding.intro.recoveryKey");
|
||||
default -> "";
|
||||
};
|
||||
}, recoverType, methodToggleGroup.selectedToggleProperty()));
|
||||
|
||||
showMethodSelection.addListener((_, _, nowShown) -> {
|
||||
if (nowShown && methodToggleGroup.getSelectedToggle() == null) {
|
||||
methodToggleGroup.selectToggle(recoveryKeyRadio);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void close() {
|
||||
window.close();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void next() {
|
||||
switch (recoverType.get()) {
|
||||
case RESTORE_VAULT_CONFIG, RESTORE_ALL -> {
|
||||
Object selectedToggle = methodToggleGroup.getSelectedToggle();
|
||||
if (selectedToggle == recoveryKeyRadio) {
|
||||
recoverType.set(RESTORE_ALL);
|
||||
window.setScene(recoverykeyRecoverScene.get());
|
||||
} else if (selectedToggle == passwordRadio) {
|
||||
recoverType.set(RESTORE_VAULT_CONFIG);
|
||||
window.setScene(recoverykeyExpertSettingsScene.get());
|
||||
} else {
|
||||
window.setScene(recoverykeyRecoverScene.get());
|
||||
}
|
||||
}
|
||||
case RESTORE_MASTERKEY -> window.setScene(recoverykeyRecoverScene.get());
|
||||
default -> window.setScene(recoverykeyRecoverScene.get()); // Fallback
|
||||
}
|
||||
window.centerOnScreen();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +1,105 @@
|
||||
package org.cryptomator.ui.recoverykey;
|
||||
|
||||
import dagger.Lazy;
|
||||
import org.cryptomator.common.Nullable;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.cryptofs.VaultConfig;
|
||||
import org.cryptomator.common.vaults.VaultState;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlScene;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javax.inject.Named;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.stage.Stage;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@RecoveryKeyScoped
|
||||
public class RecoveryKeyRecoverController implements FxController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RecoveryKeyCreationController.class);
|
||||
|
||||
private final Stage window;
|
||||
private final Lazy<Scene> resetPasswordScene;
|
||||
private final Vault vault;
|
||||
private final Lazy<Scene> nextScene;
|
||||
private final Lazy<Scene> onBoardingScene;
|
||||
private final ResourceBundle resourceBundle;
|
||||
public ObjectProperty<RecoveryActionType> recoverType;
|
||||
|
||||
@FXML
|
||||
private Button cancelButton;
|
||||
|
||||
@FXML
|
||||
RecoveryKeyValidateController recoveryKeyValidateController;
|
||||
|
||||
@Inject
|
||||
public RecoveryKeyRecoverController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, @RecoveryKeyWindow StringProperty recoveryKey, @FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD) Lazy<Scene> resetPasswordScene, ResourceBundle resourceBundle) {
|
||||
public RecoveryKeyRecoverController(@RecoveryKeyWindow Stage window, //
|
||||
@RecoveryKeyWindow Vault vault, //
|
||||
ResourceBundle resourceBundle, //
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD) Lazy<Scene> resetPasswordScene, //
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_EXPERT_SETTINGS) Lazy<Scene> expertSettingsScene, //
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_ONBOARDING) Lazy<Scene> onBoardingScene, //
|
||||
@Named("recoverType") ObjectProperty<RecoveryActionType> recoverType) {
|
||||
this.window = window;
|
||||
window.setTitle(resourceBundle.getString("recoveryKey.recover.title"));
|
||||
this.resetPasswordScene = resetPasswordScene;
|
||||
this.vault = vault;
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.onBoardingScene = onBoardingScene;
|
||||
this.recoverType = recoverType;
|
||||
this.nextScene = switch (recoverType.get()) {
|
||||
case RESTORE_ALL, RESTORE_VAULT_CONFIG -> {
|
||||
window.setTitle(resourceBundle.getString("recover.recoverVaultConfig.title"));
|
||||
yield expertSettingsScene;
|
||||
}
|
||||
case RESTORE_MASTERKEY -> {
|
||||
window.setTitle(resourceBundle.getString("recover.recoverMasterkey.title"));
|
||||
yield resetPasswordScene;
|
||||
}
|
||||
case RESET_PASSWORD -> {
|
||||
window.setTitle(resourceBundle.getString("recoveryKey.recover.title"));
|
||||
yield resetPasswordScene;
|
||||
}
|
||||
case SHOW_KEY -> {
|
||||
window.setTitle(resourceBundle.getString("recoveryKey.display.title"));
|
||||
yield resetPasswordScene;
|
||||
}
|
||||
default -> throw new IllegalArgumentException("Unexpected recovery action type: " + recoverType.get());
|
||||
};
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
if (recoverType.get() == RecoveryActionType.RESET_PASSWORD) {
|
||||
cancelButton.setText(resourceBundle.getString("generic.button.cancel"));
|
||||
} else {
|
||||
cancelButton.setText(resourceBundle.getString("generic.button.back"));
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void close() {
|
||||
window.close();
|
||||
public void closeOrReturn() {
|
||||
switch (recoverType.get()) {
|
||||
case RESET_PASSWORD -> window.close();
|
||||
case RESTORE_MASTERKEY -> {
|
||||
window.setScene(onBoardingScene.get());
|
||||
window.centerOnScreen();
|
||||
}
|
||||
default -> {
|
||||
if(vault.getState().equals(VaultState.Value.ALL_MISSING)){
|
||||
recoverType.set(RecoveryActionType.RESTORE_ALL);
|
||||
}
|
||||
else {
|
||||
recoverType.set(RecoveryActionType.RESTORE_VAULT_CONFIG);
|
||||
}
|
||||
window.setScene(onBoardingScene.get());
|
||||
window.centerOnScreen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void recover() {
|
||||
window.setScene(resetPasswordScene.get());
|
||||
window.setScene(nextScene.get());
|
||||
}
|
||||
|
||||
/* Getter/Setter */
|
||||
|
||||
@@ -1,25 +1,44 @@
|
||||
package org.cryptomator.ui.recoverykey;
|
||||
|
||||
import dagger.Lazy;
|
||||
import org.cryptomator.common.recovery.CryptoFsInitializer;
|
||||
import org.cryptomator.common.recovery.MasterkeyService;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.recovery.RecoveryDirectory;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultListManager;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.CryptorProvider;
|
||||
import org.cryptomator.cryptolib.api.Masterkey;
|
||||
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.changepassword.NewPasswordController;
|
||||
import org.cryptomator.ui.dialogs.Dialogs;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.stage.Stage;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
|
||||
|
||||
@RecoveryKeyScoped
|
||||
public class RecoveryKeyResetPasswordController implements FxController {
|
||||
|
||||
@@ -30,48 +49,140 @@ public class RecoveryKeyResetPasswordController implements FxController {
|
||||
private final RecoveryKeyFactory recoveryKeyFactory;
|
||||
private final ExecutorService executor;
|
||||
private final StringProperty recoveryKey;
|
||||
private final Lazy<Scene> recoverResetPasswordSuccessScene;
|
||||
private final Lazy<Scene> recoverExpertSettingsScene;
|
||||
private final Lazy<Scene> recoverykeyRecoverScene;
|
||||
private final FxApplicationWindows appWindows;
|
||||
private final MasterkeyFileAccess masterkeyFileAccess;
|
||||
private final VaultListManager vaultListManager;
|
||||
private final IntegerProperty shorteningThreshold;
|
||||
private final ObjectProperty<RecoveryActionType> recoverType;
|
||||
private final ObjectProperty<CryptorProvider.Scheme> cipherCombo;
|
||||
private final ResourceBundle resourceBundle;
|
||||
private final Dialogs dialogs;
|
||||
|
||||
public NewPasswordController newPasswordController;
|
||||
public Button nextButton;
|
||||
|
||||
@Inject
|
||||
public RecoveryKeyResetPasswordController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, RecoveryKeyFactory recoveryKeyFactory, ExecutorService executor, @RecoveryKeyWindow StringProperty recoveryKey, @FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD_SUCCESS) Lazy<Scene> recoverResetPasswordSuccessScene, FxApplicationWindows appWindows) {
|
||||
public RecoveryKeyResetPasswordController(@RecoveryKeyWindow Stage window, //
|
||||
@RecoveryKeyWindow Vault vault, //
|
||||
RecoveryKeyFactory recoveryKeyFactory, //
|
||||
ExecutorService executor, //
|
||||
@RecoveryKeyWindow StringProperty recoveryKey, //
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_EXPERT_SETTINGS) Lazy<Scene> recoverExpertSettingsScene, //
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_RECOVER) Lazy<Scene> recoverykeyRecoverScene, //
|
||||
FxApplicationWindows appWindows, //
|
||||
MasterkeyFileAccess masterkeyFileAccess, //
|
||||
VaultListManager vaultListManager, //
|
||||
@Named("shorteningThreshold") IntegerProperty shorteningThreshold, //
|
||||
@Named("recoverType") ObjectProperty<RecoveryActionType> recoverType, //
|
||||
@Named("cipherCombo") ObjectProperty<CryptorProvider.Scheme> cipherCombo, //
|
||||
ResourceBundle resourceBundle, //
|
||||
Dialogs dialogs) {
|
||||
this.window = window;
|
||||
this.vault = vault;
|
||||
this.recoveryKeyFactory = recoveryKeyFactory;
|
||||
this.executor = executor;
|
||||
this.recoveryKey = recoveryKey;
|
||||
this.recoverResetPasswordSuccessScene = recoverResetPasswordSuccessScene;
|
||||
this.recoverExpertSettingsScene = recoverExpertSettingsScene;
|
||||
this.recoverykeyRecoverScene = recoverykeyRecoverScene;
|
||||
this.appWindows = appWindows;
|
||||
this.masterkeyFileAccess = masterkeyFileAccess;
|
||||
this.vaultListManager = vaultListManager;
|
||||
this.shorteningThreshold = shorteningThreshold;
|
||||
this.cipherCombo = cipherCombo;
|
||||
this.recoverType = recoverType;
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.dialogs = dialogs;
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
switch (recoverType.get()) {
|
||||
case RESTORE_MASTERKEY, RESTORE_ALL -> nextButton.setText(resourceBundle.getString("recoveryKey.recover.recoverBtn"));
|
||||
case RESET_PASSWORD -> nextButton.setText(resourceBundle.getString("recoveryKey.recover.resetBtn"));
|
||||
default -> nextButton.setText(resourceBundle.getString("recoveryKey.recover.recoverBtn")); // Fallback
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void close() {
|
||||
window.close();
|
||||
switch (recoverType.get()) {
|
||||
case RESTORE_ALL -> window.setScene(recoverExpertSettingsScene.get());
|
||||
case RESTORE_MASTERKEY, RESET_PASSWORD -> window.setScene(recoverykeyRecoverScene.get());
|
||||
default -> window.close();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void next() {
|
||||
switch (recoverType.get()) {
|
||||
case RESTORE_ALL -> restorePassword();
|
||||
case RESTORE_MASTERKEY, RESET_PASSWORD -> resetPassword();
|
||||
default -> resetPassword(); // Fallback
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void restorePassword() {
|
||||
try (RecoveryDirectory recoveryDirectory = RecoveryDirectory.create(vault.getPath())) {
|
||||
Path recoveryPath = recoveryDirectory.getRecoveryPath();
|
||||
MasterkeyService.recoverFromRecoveryKey(recoveryKey.get(), recoveryKeyFactory, recoveryPath, newPasswordController.passwordField.getCharacters());
|
||||
|
||||
try (Masterkey masterkey = MasterkeyService.load(masterkeyFileAccess, recoveryPath.resolve(MASTERKEY_FILENAME), newPasswordController.passwordField.getCharacters())) {
|
||||
CryptoFsInitializer.init(recoveryPath, masterkey, shorteningThreshold.get(), cipherCombo.get());
|
||||
}
|
||||
|
||||
recoveryDirectory.moveRecoveredFile(MASTERKEY_FILENAME);
|
||||
recoveryDirectory.moveRecoveredFile(VAULTCONFIG_FILENAME);
|
||||
|
||||
if (!vaultListManager.isAlreadyAdded(vault.getPath())) {
|
||||
vaultListManager.add(vault.getPath());
|
||||
}
|
||||
window.close();
|
||||
dialogs.prepareRecoverPasswordSuccess((Stage)window.getOwner()) //
|
||||
.setTitleKey("recover.recoverVaultConfig.title") //
|
||||
.setMessageKey("recoveryKey.recover.resetVaultConfigSuccess.message") //
|
||||
.build().showAndWait();
|
||||
|
||||
} catch (IOException | CryptoException e) {
|
||||
LOG.error("Recovery process failed", e);
|
||||
appWindows.showErrorWindow(e, window, null);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void resetPassword() {
|
||||
Task<Void> task = new ResetPasswordTask();
|
||||
task.setOnScheduled(event -> {
|
||||
|
||||
task.setOnScheduled(_ -> {
|
||||
LOG.debug("Using recovery key to reset password for {}.", vault.getDisplayablePath());
|
||||
});
|
||||
task.setOnSucceeded(event -> {
|
||||
LOG.info("Used recovery key to reset password for {}.", vault.getDisplayablePath());
|
||||
window.setScene(recoverResetPasswordSuccessScene.get());
|
||||
|
||||
task.setOnSucceeded(_ -> {
|
||||
LOG.debug("Used recovery key to reset password for {}.", vault.getDisplayablePath());
|
||||
window.close();
|
||||
switch (recoverType.get()){
|
||||
case RESET_PASSWORD -> dialogs.prepareRecoverPasswordSuccess((Stage)window.getOwner()).build().showAndWait();
|
||||
case RESTORE_MASTERKEY -> dialogs.prepareRecoverPasswordSuccess((Stage)window.getOwner()).setTitleKey("recover.recoverMasterkey.title").setMessageKey("recoveryKey.recover.resetMasterkeyFileSuccess.message").build().showAndWait();
|
||||
default -> dialogs.prepareRecoverPasswordSuccess(window).build().showAndWait(); // Fallback
|
||||
}
|
||||
});
|
||||
task.setOnFailed(event -> {
|
||||
|
||||
task.setOnFailed(_ -> {
|
||||
LOG.error("Resetting password failed.", task.getException());
|
||||
appWindows.showErrorWindow(task.getException(), window, null);
|
||||
});
|
||||
|
||||
executor.submit(task);
|
||||
}
|
||||
|
||||
private class ResetPasswordTask extends Task<Void> {
|
||||
|
||||
private ResetPasswordTask() {
|
||||
setOnFailed(event -> LOG.error("Failed to reset password", getException()));
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ResetPasswordTask.class);
|
||||
|
||||
public ResetPasswordTask() {
|
||||
setOnFailed(_ -> LOG.error("Failed to reset password", getException()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,7 +190,6 @@ public class RecoveryKeyResetPasswordController implements FxController {
|
||||
recoveryKeyFactory.newMasterkeyFileWithPassphrase(vault.getPath(), recoveryKey.get(), newPasswordController.passwordField.getCharacters());
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Getter/Setter */
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package org.cryptomator.ui.recoverykey;
|
||||
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
@RecoveryKeyScoped
|
||||
public class RecoveryKeyResetPasswordSuccessController implements FxController {
|
||||
|
||||
private final Stage window;
|
||||
|
||||
@Inject
|
||||
public RecoveryKeyResetPasswordSuccessController(@RecoveryKeyWindow Stage window) {
|
||||
this.window = window;
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void close() {
|
||||
window.close();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +1,23 @@
|
||||
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.recovery.MasterkeyService;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.cryptofs.VaultConfig;
|
||||
import org.cryptomator.cryptofs.VaultConfigLoadException;
|
||||
import org.cryptomator.cryptofs.VaultKeyInvalidException;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.CryptorProvider;
|
||||
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
@@ -22,10 +27,12 @@ import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TextFormatter;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import java.io.IOException;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class RecoveryKeyValidateController implements FxController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RecoveryKeyCreationController.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RecoveryKeyValidateController.class);
|
||||
private static final CharMatcher ALLOWED_CHARS = CharMatcher.inRange('a', 'z').or(CharMatcher.is(' '));
|
||||
|
||||
private final Vault vault;
|
||||
@@ -36,13 +43,23 @@ public class RecoveryKeyValidateController implements FxController {
|
||||
private final ObservableValue<Boolean> recoveryKeyInvalid;
|
||||
private final RecoveryKeyFactory recoveryKeyFactory;
|
||||
private final ObjectProperty<RecoveryKeyState> recoveryKeyState;
|
||||
private final ObjectProperty<CryptorProvider.Scheme> cipherCombo;
|
||||
private final AutoCompleter autoCompleter;
|
||||
private final ObjectProperty<RecoveryActionType> recoverType;
|
||||
private final MasterkeyFileAccess masterkeyFileAccess;
|
||||
|
||||
private volatile boolean isWrongKey;
|
||||
|
||||
public TextArea textarea;
|
||||
|
||||
public RecoveryKeyValidateController(Vault vault, @Nullable VaultConfig.UnverifiedVaultConfig vaultConfig, StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory) {
|
||||
public RecoveryKeyValidateController(Vault vault, //
|
||||
@Nullable VaultConfig.UnverifiedVaultConfig vaultConfig, //
|
||||
StringProperty recoveryKey, //
|
||||
RecoveryKeyFactory recoveryKeyFactory, //
|
||||
MasterkeyFileAccess masterkeyFileAccess, //
|
||||
@Named("recoverType") ObjectProperty<RecoveryActionType> recoverType, //
|
||||
@Named("cipherCombo") ObjectProperty<CryptorProvider.Scheme> cipherCombo
|
||||
) {
|
||||
this.vault = vault;
|
||||
this.unverifiedVaultConfig = vaultConfig;
|
||||
this.recoveryKey = recoveryKey;
|
||||
@@ -52,6 +69,9 @@ public class RecoveryKeyValidateController implements FxController {
|
||||
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);
|
||||
this.recoverType = recoverType;
|
||||
this.cipherCombo = cipherCombo;
|
||||
this.masterkeyFileAccess = masterkeyFileAccess;
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -117,14 +137,37 @@ public class RecoveryKeyValidateController implements FxController {
|
||||
}
|
||||
|
||||
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);
|
||||
switch (recoverType.get()) {
|
||||
case RESTORE_ALL, RESTORE_VAULT_CONFIG -> {
|
||||
try {
|
||||
var scheme = MasterkeyService.validateRecoveryKeyAndDetectCombo(recoveryKeyFactory, vault, recoveryKey.get(), masterkeyFileAccess);
|
||||
cipherCombo.set(scheme);
|
||||
recoveryKeyState.set(RecoveryKeyState.CORRECT);
|
||||
} catch (CryptoException e) {
|
||||
LOG.info("Recovery key is valid but crypto scheme couldn't be determined", e);
|
||||
recoveryKeyState.set(RecoveryKeyState.WRONG);
|
||||
} catch (IllegalArgumentException e) {
|
||||
LOG.info("Recovery key is syntactically invalid", e);
|
||||
recoveryKeyState.set(RecoveryKeyState.INVALID);
|
||||
} catch (IOException e) {
|
||||
LOG.warn("IO error while validating recovery key", e);
|
||||
recoveryKeyState.set(RecoveryKeyState.INVALID);
|
||||
} catch (NoSuchElementException e) {
|
||||
LOG.warn("Could not determine scheme from masterkey during recovery key validation, because no valid *.c9r file is present in vault", e);
|
||||
recoveryKeyState.set(RecoveryKeyState.INVALID);
|
||||
}
|
||||
}
|
||||
case RESTORE_MASTERKEY, RESET_PASSWORD, SHOW_KEY, CONVERT_VAULT -> {
|
||||
isWrongKey = false;
|
||||
boolean 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,9 +58,15 @@ public class ShareVaultController implements FxController {
|
||||
|
||||
private static URI getHubUri(Vault vault) {
|
||||
try {
|
||||
var keyID = new URI(vault.getVaultConfigCache().get().getKeyId().toString());
|
||||
assert keyID.getScheme().startsWith(SCHEME_PREFIX);
|
||||
return new URI(keyID.getScheme().substring(SCHEME_PREFIX.length()) + "://" + keyID.getHost() + "/app/vaults");
|
||||
var keyId = new URI(vault.getVaultConfigCache().get().getKeyId().toString());
|
||||
assert keyId.getScheme().startsWith(SCHEME_PREFIX);
|
||||
var path = keyId.getPath();
|
||||
var apiIdx = path.indexOf("/api/");
|
||||
if (apiIdx < 0) {
|
||||
throw new IllegalArgumentException("Path does not contain /api/: " + path);
|
||||
}
|
||||
var appPath = path.substring(0, apiIdx) + "/app/vaults";
|
||||
return new URI(keyId.getScheme().substring(SCHEME_PREFIX.length()), keyId.getAuthority(), appPath, null, null);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
} catch (URISyntaxException e) {
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.cryptomator.ui.common.FxmlScene;
|
||||
import org.cryptomator.ui.common.StageFactory;
|
||||
import org.cryptomator.ui.keyloading.KeyLoadingComponent;
|
||||
import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.inject.Named;
|
||||
@@ -27,7 +28,7 @@ import javafx.stage.Stage;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@Module(subcomponents = {KeyLoadingComponent.class})
|
||||
@Module(subcomponents = {KeyLoadingComponent.class, RecoveryKeyComponent.class})
|
||||
abstract class UnlockModule {
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package org.cryptomator.ui.vaultoptions;
|
||||
|
||||
import org.cryptomator.common.keychain.KeychainManager;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
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.recoverykey.RecoveryKeyComponent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.stage.Stage;
|
||||
@@ -18,8 +18,6 @@ import javafx.stage.Stage;
|
||||
@VaultOptionsScoped
|
||||
public class MasterkeyOptionsController implements FxController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MasterkeyOptionsController.class);
|
||||
|
||||
private final Vault vault;
|
||||
private final Stage window;
|
||||
private final ChangePasswordComponent.Builder changePasswordWindow;
|
||||
@@ -51,12 +49,12 @@ public class MasterkeyOptionsController implements FxController {
|
||||
|
||||
@FXML
|
||||
public void showRecoveryKey() {
|
||||
recoveryKeyWindow.create(vault, window).showRecoveryKeyCreationWindow();
|
||||
recoveryKeyWindow.create(vault, window, new SimpleObjectProperty<>(RecoveryActionType.SHOW_KEY)).showRecoveryKeyCreationWindow();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void showRecoverVaultDialog() {
|
||||
recoveryKeyWindow.create(vault, window).showRecoveryKeyRecoverWindow();
|
||||
recoveryKeyWindow.create(vault, window, new SimpleObjectProperty<>(RecoveryActionType.RESET_PASSWORD)).showRecoveryKeyRecoverWindow();
|
||||
}
|
||||
|
||||
@FXML
|
||||
|
||||
@@ -6,7 +6,12 @@
|
||||
<?import javafx.scene.control.ButtonBar?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<?import javafx.scene.Group?>
|
||||
<HBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.convertvault.HubToPasswordConvertController"
|
||||
minWidth="400"
|
||||
@@ -17,7 +22,16 @@
|
||||
<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="KEY" glyphSize="24"/>
|
||||
</StackPane>
|
||||
</Group>
|
||||
<VBox spacing="12" HBox.hgrow="ALWAYS" alignment="TOP_CENTER">
|
||||
<fx:include fx:id="newPassword" source="new_password.fxml"/>
|
||||
|
||||
<Region VBox.vgrow="ALWAYS"/>
|
||||
@@ -26,7 +40,7 @@
|
||||
<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 -->
|
||||
<Button fx:id="convertBtn" ButtonBar.buttonData="FINISH" defaultButton="true" onAction="#convert">
|
||||
<graphic>
|
||||
<FontAwesome5Spinner glyphSize="12"/>
|
||||
</graphic>
|
||||
@@ -34,5 +48,5 @@
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
</VBox>
|
||||
</children>
|
||||
</VBox>
|
||||
</VBox>
|
||||
</HBox>
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.ButtonBar?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<?import javafx.scene.Group?>
|
||||
<HBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.convertvault.HubToPasswordStartController"
|
||||
minWidth="400"
|
||||
@@ -16,18 +19,26 @@
|
||||
<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="SYNC" glyphSize="24"/>
|
||||
</StackPane>
|
||||
</Group>
|
||||
|
||||
<VBox spacing="12" HBox.hgrow="ALWAYS" alignment="TOP_CENTER">
|
||||
<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>
|
||||
<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>
|
||||
</HBox>
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
<Insets bottom="6" top="6"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<FormattedLabel format="%recoveryKey.create.description" arg1="${controller.vault.displayName}" wrapText="true">
|
||||
<FormattedLabel fx:id="descriptionLabel" format="%recoveryKey.create.description" arg1="${controller.vault.displayName}" wrapText="true">
|
||||
<padding>
|
||||
<Insets bottom="6"/>
|
||||
</padding>
|
||||
@@ -49,8 +49,8 @@
|
||||
<Region VBox.vgrow="ALWAYS" minHeight="18"/>
|
||||
<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="#createRecoveryKey" disable="${passwordField.text.empty}"/>
|
||||
<Button fx:id="cancelButton" text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
|
||||
<Button fx:id="nextButton" text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#createRecoveryKey" disable="${passwordField.text.empty}"/>
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
</VBox>
|
||||
|
||||
86
src/main/resources/fxml/recoverykey_expert_settings.fxml
Normal file
86
src/main/resources/fxml/recoverykey_expert_settings.fxml
Normal file
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ButtonBar?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.control.Hyperlink?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.Tooltip?>
|
||||
<?import javafx.scene.Group?>
|
||||
<?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 org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||
<?import org.cryptomator.ui.controls.NumericTextField?>
|
||||
<HBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.recoverykey.RecoveryKeyExpertSettingsController"
|
||||
minWidth="400"
|
||||
maxWidth="400"
|
||||
minHeight="145"
|
||||
spacing="12"
|
||||
alignment="TOP_CENTER">
|
||||
<padding>
|
||||
<Insets topRightBottomLeft="12"/>
|
||||
</padding>
|
||||
<Group>
|
||||
<StackPane>
|
||||
<padding>
|
||||
<Insets topRightBottomLeft="6"/>
|
||||
</padding>
|
||||
<Circle styleClass="glyph-icon-primary" radius="24"/>
|
||||
<FontAwesome5IconView styleClass="glyph-icon-white" glyph="QUESTION" glyphSize="24"/>
|
||||
</StackPane>
|
||||
</Group>
|
||||
|
||||
<VBox HBox.hgrow="ALWAYS">
|
||||
<Label styleClass="label-large" text="Expert Settings" wrapText="true">
|
||||
<padding>
|
||||
<Insets bottom="6" top="6"/>
|
||||
</padding>
|
||||
</Label>
|
||||
|
||||
<CheckBox fx:id="expertSettingsCheckBox" text="%addvaultwizard.new.expertSettings.enableExpertSettingsCheckbox" onAction="#toggleUseExpertSettings"/>
|
||||
<VBox spacing="6" visible="${expertSettingsCheckBox.selected}">
|
||||
<HBox spacing="2" HBox.hgrow="NEVER">
|
||||
<Label text="%addvaultwizard.new.expertSettings.shorteningThreshold.title"/>
|
||||
<Region prefWidth="2"/>
|
||||
<Hyperlink contentDisplay="GRAPHIC_ONLY" onAction="#openDocs">
|
||||
<graphic>
|
||||
<FontAwesome5IconView glyph="QUESTION_CIRCLE" styleClass="glyph-icon-muted"/>
|
||||
</graphic>
|
||||
<tooltip>
|
||||
<Tooltip text="%addvaultwizard.new.expertSettings.shorteningThreshold.tooltip" showDelay="10ms"/>
|
||||
</tooltip>
|
||||
</Hyperlink>
|
||||
</HBox>
|
||||
<Label text="%recover.expertSettings.shorteningThreshold.title" wrapText="true"/>
|
||||
<NumericTextField fx:id="shorteningThresholdTextField"/>
|
||||
<HBox alignment="TOP_RIGHT">
|
||||
<Region minWidth="4" prefWidth="4" HBox.hgrow="NEVER"/>
|
||||
<StackPane>
|
||||
<Label styleClass="label-muted" text="%addvaultwizard.new.expertSettings.shorteningThreshold.invalid" textAlignment="RIGHT" alignment="CENTER_RIGHT" visible="${!controller.validShorteningThreshold}" managed="${!controller.validShorteningThreshold}" graphicTextGap="6">
|
||||
<graphic>
|
||||
<FontAwesome5IconView styleClass="glyph-icon-red" glyph="TIMES"/>
|
||||
</graphic>
|
||||
</Label>
|
||||
<Label styleClass="label-muted" text="%addvaultwizard.new.expertSettings.shorteningThreshold.valid" textAlignment="RIGHT" alignment="CENTER_RIGHT" visible="${controller.validShorteningThreshold}" managed="${controller.validShorteningThreshold}" graphicTextGap="6">
|
||||
<graphic>
|
||||
<FontAwesome5IconView styleClass="glyph-icon-primary" glyph="CHECK"/>
|
||||
</graphic>
|
||||
</Label>
|
||||
</StackPane>
|
||||
</HBox>
|
||||
</VBox>
|
||||
<Region VBox.vgrow="ALWAYS" minHeight="18"/>
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+C">
|
||||
<buttons>
|
||||
<Button text="%generic.button.back" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#back"/>
|
||||
<Button text="%generic.button.next" ButtonBar.buttonData="CANCEL_CLOSE" defaultButton="true" onAction="#next"/>
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
</VBox>
|
||||
</HBox>
|
||||
88
src/main/resources/fxml/recoverykey_onboarding.fxml
Normal file
88
src/main/resources/fxml/recoverykey_onboarding.fxml
Normal file
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ButtonBar?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.RadioButton?>
|
||||
<?import javafx.scene.control.ToggleGroup?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||
|
||||
<?import javafx.scene.Group?>
|
||||
<HBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:id="hBox"
|
||||
fx:controller="org.cryptomator.ui.recoverykey.RecoveryKeyOnboardingController"
|
||||
prefWidth="480"
|
||||
minHeight="242"
|
||||
spacing="12"
|
||||
VBox.vgrow="ALWAYS">
|
||||
<padding>
|
||||
<Insets topRightBottomLeft="12"/>
|
||||
</padding>
|
||||
<Group>
|
||||
<StackPane>
|
||||
<padding>
|
||||
<Insets topRightBottomLeft="6"/>
|
||||
</padding>
|
||||
<Circle styleClass="glyph-icon-primary" radius="24"/>
|
||||
<FontAwesome5IconView styleClass="glyph-icon-white" glyph="SYNC" glyphSize="24"/>
|
||||
</StackPane>
|
||||
</Group>
|
||||
<VBox HBox.hgrow="ALWAYS" spacing="12">
|
||||
<Label fx:id="titleLabel" text="%recover.recoverVaultConfig.title" styleClass="label-extra-large"/>
|
||||
<VBox spacing="6">
|
||||
<VBox fx:id="chooseMethodeBox" spacing="6">
|
||||
<Label text="%recover.onBoarding.chooseMethod"/>
|
||||
<RadioButton fx:id="recoveryKeyRadio" text="%recover.onBoarding.useRecoveryKey" selected="true">
|
||||
<toggleGroup>
|
||||
<ToggleGroup fx:id="methodToggleGroup"/>
|
||||
</toggleGroup>
|
||||
</RadioButton>
|
||||
<RadioButton fx:id="passwordRadio" text="%recover.onBoarding.usePassword"/>
|
||||
</VBox>
|
||||
|
||||
<Label fx:id="messageLabel" wrapText="true"/>
|
||||
<Label fx:id="pleaseConfirm" wrapText="true"/>
|
||||
<GridPane alignment="CENTER_LEFT">
|
||||
<padding>
|
||||
<Insets left="6"/>
|
||||
</padding>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints minWidth="20" halignment="LEFT"/>
|
||||
<ColumnConstraints />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints valignment="TOP"/>
|
||||
<RowConstraints valignment="TOP"/>
|
||||
<RowConstraints valignment="TOP"/>
|
||||
</rowConstraints>
|
||||
<Label text="1." GridPane.rowIndex="0" GridPane.columnIndex="0"/>
|
||||
<Label text="%recover.onBoarding.intro.ensure" wrapText="true" GridPane.rowIndex="0" GridPane.columnIndex="1"/>
|
||||
<Label text="2." GridPane.rowIndex="1" GridPane.columnIndex="0"/>
|
||||
<Label fx:id="secondTextDesc" text="%recover.onBoarding.intro.recoveryKey" wrapText="true" GridPane.rowIndex="1" GridPane.columnIndex="1"/>
|
||||
</GridPane>
|
||||
<CheckBox fx:id="affirmationBox" text="%recover.onBoarding.affirmation"/>
|
||||
</VBox>
|
||||
|
||||
<Region VBox.vgrow="ALWAYS"/>
|
||||
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+CX" VBox.vgrow="NEVER">
|
||||
<buttons>
|
||||
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
|
||||
<Button fx:id="nextButton" text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD"
|
||||
disable="${!affirmationBox.selected}" defaultButton="true" onAction="#next"/>
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
|
||||
</VBox>
|
||||
</HBox>
|
||||
@@ -3,32 +3,46 @@
|
||||
<?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?>
|
||||
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||
<?import javafx.scene.Group?>
|
||||
|
||||
<HBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.recoverykey.RecoveryKeyRecoverController"
|
||||
minWidth="400"
|
||||
maxWidth="400"
|
||||
minHeight="145"
|
||||
spacing="12"
|
||||
alignment="TOP_CENTER">
|
||||
spacing="12">
|
||||
<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="SYNC" glyphSize="24"/>
|
||||
</StackPane>
|
||||
</Group>
|
||||
|
||||
<fx:include fx:id="recoveryKeyValidate" source="recoverykey_validate.fxml"/>
|
||||
<VBox spacing="12" HBox.hgrow="ALWAYS" alignment="TOP_CENTER">
|
||||
<fx:include fx:id="recoveryKeyValidate" source="recoverykey_validate.fxml"/>
|
||||
|
||||
<Region VBox.vgrow="ALWAYS"/>
|
||||
<Region VBox.vgrow="ALWAYS"/>
|
||||
|
||||
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+CX">
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+BX">
|
||||
<buttons>
|
||||
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
|
||||
<Button fx:id="cancelButton" ButtonBar.buttonData="BACK_PREVIOUS" cancelButton="true" onAction="#closeOrReturn"/>
|
||||
<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#recover" disable="${!controller.validateController.recoveryKeyCorrect}"/>
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
</VBox>
|
||||
</children>
|
||||
</VBox>
|
||||
</HBox>
|
||||
|
||||
@@ -5,7 +5,12 @@
|
||||
<?import javafx.scene.control.ButtonBar?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<?import javafx.scene.Group?>
|
||||
<HBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.recoverykey.RecoveryKeyResetPasswordController"
|
||||
minWidth="400"
|
||||
@@ -17,17 +22,28 @@
|
||||
<Insets topRightBottomLeft="12"/>
|
||||
</padding>
|
||||
<children>
|
||||
<fx:include fx:id="newPassword" source="new_password.fxml"/>
|
||||
<Group>
|
||||
<StackPane>
|
||||
<padding>
|
||||
<Insets topRightBottomLeft="6"/>
|
||||
</padding>
|
||||
<Circle styleClass="glyph-icon-primary" radius="24"/>
|
||||
<FontAwesome5IconView styleClass="glyph-icon-white" glyph="KEY" glyphSize="24"/>
|
||||
</StackPane>
|
||||
</Group>
|
||||
<VBox spacing="12" HBox.hgrow="ALWAYS" alignment="TOP_CENTER">
|
||||
<fx:include fx:id="newPassword" source="new_password.fxml"/>
|
||||
|
||||
<Region VBox.vgrow="ALWAYS"/>
|
||||
<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 text="%recoveryKey.recover.resetBtn" ButtonBar.buttonData="FINISH" defaultButton="true" onAction="#resetPassword" disable="${!controller.passwordSufficientAndMatching}"/>
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+CI">
|
||||
<buttons>
|
||||
<Button text="%generic.button.back" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
|
||||
<Button fx:id="nextButton" ButtonBar.buttonData="FINISH" defaultButton="true" disable="${!controller.passwordSufficientAndMatching}" onAction="#next"/>
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
</VBox>
|
||||
</VBox>
|
||||
</children>
|
||||
</VBox>
|
||||
</HBox>
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
<?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.control.ButtonBar?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<?import javafx.scene.Group?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<HBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.recoverykey.RecoveryKeyResetPasswordSuccessController"
|
||||
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="%recoveryKey.recover.resetSuccess.message" wrapText="true" textAlignment="LEFT">
|
||||
<padding>
|
||||
<Insets bottom="6" top="6"/>
|
||||
</padding>
|
||||
</Label>
|
||||
|
||||
<Label text="%recoveryKey.recover.resetSuccess.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>
|
||||
@@ -2,48 +2,40 @@
|
||||
|
||||
<?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>
|
||||
spacing="12">
|
||||
<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">
|
||||
<VBox>
|
||||
<Label text="Just some Filler" visible="false" managed="${textarea.text.empty}" graphicTextGap="6">
|
||||
<graphic>
|
||||
<FontAwesome5IconView glyph="ANCHOR"/>
|
||||
</graphic>
|
||||
</Label>
|
||||
<Label text="%recoveryKey.recover.correctKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) && controller.recoveryKeyCorrect}">
|
||||
<Label text="%recoveryKey.recover.correctKey" graphicTextGap="6" visible="${(!textarea.text.empty) && controller.recoveryKeyCorrect}" managed="${(!textarea.text.empty) && controller.recoveryKeyCorrect}">
|
||||
<graphic>
|
||||
<FontAwesome5IconView glyph="CHECK"/>
|
||||
</graphic>
|
||||
</Label>
|
||||
<Label text="%recoveryKey.recover.wrongKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) && controller.recoveryKeyWrong}">
|
||||
<Label text="%recoveryKey.recover.wrongKey" graphicTextGap="6" visible="${(!textarea.text.empty) && controller.recoveryKeyWrong}" managed="${(!textarea.text.empty) && 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) && controller.recoveryKeyInvalid}">
|
||||
<Label text="%recoveryKey.recover.invalidKey" graphicTextGap="6" visible="${(!textarea.text.empty) && controller.recoveryKeyInvalid}" managed="${(!textarea.text.empty) && controller.recoveryKeyInvalid}">
|
||||
<graphic>
|
||||
<FontAwesome5IconView glyph="TIMES" styleClass="glyph-icon-red"/>
|
||||
</graphic>
|
||||
</Label>
|
||||
</StackPane>
|
||||
</VBox>
|
||||
</children>
|
||||
</VBox>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<?import javafx.scene.Group?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import org.cryptomator.ui.controls.FormattedLabel?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<HBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.keyloading.masterkeyfile.ChooseMasterkeyFileController"
|
||||
@@ -40,12 +41,13 @@
|
||||
</padding>
|
||||
</Label>
|
||||
<FormattedLabel format="%unlock.chooseMasterkey.description" arg1="${controller.displayName}" wrapText="true"/>
|
||||
<CheckBox fx:id="restoreInsteadCheckBox" text="%unlock.chooseMasterkey.restoreInstead" wrapText="true"/>
|
||||
|
||||
<Region VBox.vgrow="ALWAYS" minHeight="18"/>
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+CX">
|
||||
<buttons>
|
||||
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#cancel"/>
|
||||
<Button text="%generic.button.choose" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#proceed"/>
|
||||
<Button fx:id="forwardButton" text="%generic.button.choose" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#proceed"/>
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
</VBox>
|
||||
|
||||
@@ -53,5 +53,6 @@
|
||||
<fx:include VBox.vgrow="ALWAYS" source="vault_detail_missing.fxml" visible="${controller.vault.missing}" managed="${controller.vault.missing}"/>
|
||||
<fx:include VBox.vgrow="ALWAYS" source="vault_detail_needsmigration.fxml" visible="${controller.vault.needsMigration}" managed="${controller.vault.needsMigration}"/>
|
||||
<fx:include VBox.vgrow="ALWAYS" source="vault_detail_unknownerror.fxml" visible="${controller.vault.unknownError}" managed="${controller.vault.unknownError}"/>
|
||||
<fx:include VBox.vgrow="ALWAYS" source="vault_detail_missing_vault_config.fxml" visible="${controller.vault.missingVaultConfig}" managed="${controller.vault.missingVaultConfig}"/>
|
||||
</children>
|
||||
</VBox>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.mainwindow.VaultDetailMissingVaultController"
|
||||
alignment="TOP_CENTER"
|
||||
spacing="9">
|
||||
<VBox spacing="9" alignment="CENTER">
|
||||
<StackPane>
|
||||
<Circle styleClass="glyph-icon-primary" radius="48"/>
|
||||
<FontAwesome5IconView styleClass="glyph-icon-white" glyph="FILE" glyphSize="48"/>
|
||||
<FontAwesome5IconView styleClass="glyph-icon-primary" glyph="SEARCH" glyphSize="24">
|
||||
<StackPane.margin>
|
||||
<Insets top="12"/>
|
||||
</StackPane.margin>
|
||||
</FontAwesome5IconView>
|
||||
</StackPane>
|
||||
<Label text="%main.vaultDetail.missingVaultConfig.info" wrapText="true"/>
|
||||
</VBox>
|
||||
<VBox spacing="6" alignment="CENTER">
|
||||
<Button text="%main.vaultDetail.missing.recheck" minWidth="120" onAction="#recheck">
|
||||
<graphic>
|
||||
<FontAwesome5IconView glyph="REDO"/>
|
||||
</graphic>
|
||||
</Button>
|
||||
<Button text="%main.vaultDetail.missingVaultConfig.restore" minWidth="120" onAction="#restoreVaultConfig">
|
||||
<graphic>
|
||||
<FontAwesome5IconView glyph="MAGIC"/>
|
||||
</graphic>
|
||||
</Button>
|
||||
<Button text="%main.vaultDetail.missing.remove" minWidth="120" onAction="#didClickRemoveVault">
|
||||
<graphic>
|
||||
<FontAwesome5IconView glyph="TRASH"/>
|
||||
</graphic>
|
||||
</Button>
|
||||
</VBox>
|
||||
</VBox>
|
||||
@@ -13,8 +13,6 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.Arc?>
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.shape.Rectangle?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<StackPane xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
@@ -80,6 +78,11 @@
|
||||
<FontAwesome5IconView glyph="FOLDER_OPEN" textAlignment="CENTER" wrappingWidth="14"/>
|
||||
</graphic>
|
||||
</MenuItem>
|
||||
<MenuItem styleClass="dropdown-button-context-menu-item" text="%main.vaultlist.addVaultBtn.menuItemRecover" onAction="#didClickRecoverExistingVault">
|
||||
<graphic>
|
||||
<FontAwesome5IconView glyph="SYNC" textAlignment="CENTER" wrappingWidth="14"/>
|
||||
</graphic>
|
||||
</MenuItem>
|
||||
</items>
|
||||
</ContextMenu>
|
||||
</fx:define>
|
||||
|
||||
@@ -97,6 +97,7 @@ addvault.new.readme.accessLocation.4=Feel free to remove this file.
|
||||
## Existing
|
||||
addvaultwizard.existing.title=Add Existing Vault
|
||||
addvaultwizard.existing.instruction=Choose the "vault.cryptomator" file of your existing vault. If only a file named "masterkey.cryptomator" exists, select that instead.
|
||||
addvaultwizard.existing.restore=Restore…
|
||||
addvaultwizard.existing.chooseBtn=Choose…
|
||||
addvaultwizard.existing.filePickerTitle=Select Vault File
|
||||
addvaultwizard.existing.filePickerMimeDesc=Cryptomator Vault
|
||||
@@ -128,6 +129,7 @@ unlock.unlockBtn=Unlock
|
||||
## Select
|
||||
unlock.chooseMasterkey.message=Masterkey file not found
|
||||
unlock.chooseMasterkey.description=Cryptomator could not find the masterkey file for vault "%s". Please choose the key file manually.
|
||||
unlock.chooseMasterkey.restoreInstead=Restore the masterkey file instead
|
||||
unlock.chooseMasterkey.filePickerTitle=Select Masterkey File
|
||||
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator Masterkey
|
||||
## Success
|
||||
@@ -395,8 +397,9 @@ main.vaultlist.contextMenu.unlockNow=Unlock Now
|
||||
main.vaultlist.contextMenu.vaultoptions=Show Vault Options
|
||||
main.vaultlist.contextMenu.reveal=Reveal Drive
|
||||
main.vaultlist.contextMenu.share=Share…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Create New Vault...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Open Existing Vault...
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Create New Vault…
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Open Existing Vault…
|
||||
main.vaultlist.addVaultBtn.menuItemRecover=Recover Existing Vault…
|
||||
main.vaultlist.showEventsButton.tooltip=Open event view
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Update is available.
|
||||
@@ -434,6 +437,9 @@ main.vaultDetail.missing.info=Cryptomator could not find a vault at this path.
|
||||
main.vaultDetail.missing.recheck=Recheck
|
||||
main.vaultDetail.missing.remove=Remove from Vault List…
|
||||
main.vaultDetail.missing.changeLocation=Change Vault Location…
|
||||
### Missing Vault Config
|
||||
main.vaultDetail.missingVaultConfig.info=Vault config is missing.
|
||||
main.vaultDetail.missingVaultConfig.restore=Restore vault config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Upgrade Vault
|
||||
main.vaultDetail.migratePrompt=Your vault needs to be upgraded to a new format, before you can access it
|
||||
@@ -498,6 +504,7 @@ vaultOptions.hub.convertBtn=Convert to Password-Based Vault
|
||||
recoveryKey.display.title=Show Recovery Key
|
||||
recoveryKey.create.message=Password required
|
||||
recoveryKey.create.description=Enter the password for "%s" to show its recovery key.
|
||||
recoveryKey.recover.description=Enter the password for "%s" to recover the vault config.
|
||||
recoveryKey.display.description=The following recovery key can be used to restore access to "%s":
|
||||
recoveryKey.display.StorageHints=Keep it somewhere very secure, e.g.:\n • Store it using a password manager\n • Save it on a USB flash drive\n • Print it on paper
|
||||
## Reset Password
|
||||
@@ -510,9 +517,59 @@ recoveryKey.recover.invalidKey=This recovery key is not valid
|
||||
recoveryKey.printout.heading=Cryptomator Recovery Key\n"%s"\n
|
||||
### Reset Password
|
||||
recoveryKey.recover.resetBtn=Reset
|
||||
recoveryKey.recover.recoverBtn=Recover
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Password reset successful
|
||||
recoveryKey.recover.resetSuccess.description=You can unlock your vault with the new password.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
recoveryKey.recover.resetVaultConfigSuccess.message=Vault configuration recovered
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.message=Masterkey file recovered
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.description=You can unlock your vault with your password now.
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
recover.existing.title=Vault Added
|
||||
recover.existing.message=The vault was added successfully
|
||||
recover.existing.description=Your vault "%s" has been added to the vault list. No recovery process was necessary.
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
recover.alreadyExists.title=Vault Already Exists
|
||||
recover.alreadyExists.message=This vault has already been added
|
||||
recover.alreadyExists.description=Your vault "%s" is already present in your vault list and was therefore not added again.
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
recover.invalidSelection.title=Invalid Selection
|
||||
recover.invalidSelection.message=Your selection is not a vault
|
||||
recover.invalidSelection.description=The selected folder must be a valid Cryptomator vault.
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub Vault
|
||||
contactHubVaultOwner.message=This vault was created with Cryptomator Hub
|
||||
contactHubVaultOwner.description=Please reach out to the vault owner to restore the missing file. They can download the vault template from Cryptomator Hub.
|
||||
|
||||
##Dialog Title
|
||||
recover.recoverVaultConfig.title=Recover Vault Config
|
||||
recover.recoverMasterkey.title=Recover Masterkey
|
||||
|
||||
## OnBoarding
|
||||
recover.onBoarding.chooseMethod=Choose recovery method:
|
||||
recover.onBoarding.useRecoveryKey=Use Recovery Key
|
||||
recover.onBoarding.usePassword=Use Password
|
||||
recover.onBoarding.intro=Make sure to check the following:
|
||||
recover.onBoarding.pleaseConfirm=Before proceeding, please confirm that:
|
||||
recover.onBoarding.otherwisePleaseConfirm=Otherwise, please confirm that:
|
||||
recover.onBoarding.allMissing.intro=If this vault is managed by Cryptomator Hub, the vault owner must restore it for you.
|
||||
recover.onBoarding.intro.ensure=All files are fully synced.
|
||||
recover.onBoarding.affirmation=I have read and understood these requirements
|
||||
|
||||
###Vault Config Missing
|
||||
recover.onBoarding.intro.recoveryKey=You have the recovery key and know if expert settings were used.
|
||||
recover.onBoarding.intro.password=You have the vault password and know if expert settings were used.
|
||||
###Masterkey Missing
|
||||
recover.onBoarding.intro.masterkey.recoveryKey=You have the vault recovery key.
|
||||
|
||||
## Expert Settings
|
||||
recover.expertSettings.shorteningThreshold.title=This value must match the one used before recovery to ensure compatibility with previously encrypted data.
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Convert Vault
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
### Locked
|
||||
### Unlocked
|
||||
### Missing
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
### Error
|
||||
|
||||
@@ -105,6 +106,25 @@
|
||||
### Enter Recovery Key
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -394,8 +394,6 @@ main.vaultlist.contextMenu.unlockNow=افتح الان
|
||||
main.vaultlist.contextMenu.vaultoptions=إظهار خيارات المخزن
|
||||
main.vaultlist.contextMenu.reveal=اظهار القرص
|
||||
main.vaultlist.contextMenu.share=مشاركة…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=إنشاء مخزن جديد...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=افتح مخزن موجود...
|
||||
main.vaultlist.showEventsButton.tooltip=عرض الإشعارات
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=هناك تحديث متاح.
|
||||
@@ -433,6 +431,7 @@ main.vaultDetail.missing.info=لم يتمكن Cryptomator من العثور عل
|
||||
main.vaultDetail.missing.recheck=إعادة الفحص
|
||||
main.vaultDetail.missing.remove=حذف من قائمة الخزنات…
|
||||
main.vaultDetail.missing.changeLocation=تغيير موقع الخزنة…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=ترقية الحافظة
|
||||
main.vaultDetail.migratePrompt=يجب ترقية المخزن الخاص بك إلى تنسيق جديد، قبل أن تتمكن من الوصول إليه
|
||||
@@ -512,6 +511,26 @@ recoveryKey.recover.resetBtn=إعادة الضبط
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=تم إعادة تعيين كلمة المرور بنجاح
|
||||
recoveryKey.recover.resetSuccess.description=يمكنك فتح الخزانة الخاصة بك بكلمة المرور الجديدة.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=خزانة Hub
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=تحويل الخزانة
|
||||
|
||||
@@ -394,6 +394,7 @@ main.vaultDetail.missing.info=Cryptomator был юлдан һаҡлағыс т
|
||||
main.vaultDetail.missing.recheck=Яңынан тикшер
|
||||
main.vaultDetail.missing.remove=Һаҡлағыс исемлегенән алып ташла…
|
||||
main.vaultDetail.missing.changeLocation=Һаҡлағыс урынын үҙгәрт…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Һаҡлағысты яңыртыу
|
||||
main.vaultDetail.migratePrompt=Һаҡлағысҡа инер алдынан уны яңы форматҡа тиклем яңыртыу кәрәк
|
||||
@@ -472,6 +473,26 @@ recoveryKey.recover.resetBtn=Яңынан башла
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Серһүҙ яңыртыу уңышлы тамамланды
|
||||
recoveryKey.recover.resetSuccess.description=Яңы серһүҙ менән һаҡлағысты аса алаһығыҙ.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Һаҡлағыс хабы
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Һаҡлағысты үҙгәртеү
|
||||
|
||||
@@ -381,6 +381,7 @@ main.vaultDetail.missing.info=Cryptomator ня змог знайсці скар
|
||||
main.vaultDetail.missing.recheck=Пераправерыць
|
||||
main.vaultDetail.missing.remove=Выдаліць са спісу скарбніц…
|
||||
main.vaultDetail.missing.changeLocation=Змяніць месцазнаходжанне скарбніцы…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Абнавіць скарбніцу
|
||||
main.vaultDetail.migratePrompt=Тваю скарбніцу трэба сканвертаваць у новы фармат, перад тым як ты зможаш атрымаць доступ да яе
|
||||
@@ -454,6 +455,25 @@ recoveryKey.recover.resetBtn=Скінуць
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Пароль паспяхова скінуты
|
||||
recoveryKey.recover.resetSuccess.description=Ты можаш разамкнуць сваю скарбніцу з дапамогаю новага паролю.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Перабудаваць скарбніцу
|
||||
|
||||
@@ -395,6 +395,7 @@ main.vaultDetail.missing.info=Криптоматор не намира хран
|
||||
main.vaultDetail.missing.recheck=Повторен опит
|
||||
main.vaultDetail.missing.remove=Премахване от списъка с хранилищата…
|
||||
main.vaultDetail.missing.changeLocation=Смяна на мястото на хранилището…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Надграждане на хранилище
|
||||
main.vaultDetail.migratePrompt=Преди да можете да го достъпвате, хранилището трябва да бъде надградено до новия формат
|
||||
@@ -473,6 +474,26 @@ recoveryKey.recover.resetBtn=Нулиране
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Паролата е променена
|
||||
recoveryKey.recover.resetSuccess.description=Можете да отключите хранилището с новата парола.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Хранилище на Hub
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Преобразуване на хранилище
|
||||
|
||||
@@ -149,6 +149,7 @@ main.vaultlist.contextMenu.lock=লক করুন
|
||||
### Unlocked
|
||||
main.vaultDetail.lockBtn=লক করুন
|
||||
### Missing
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
### Error
|
||||
|
||||
@@ -169,6 +170,25 @@ vaultOptions.mount.mountPoint.directoryPickerButton=নির্বাচন ক
|
||||
### Enter Recovery Key
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -241,6 +241,7 @@ main.vaultDetail.missing.info=Cryptomator nije mogao pronaći disk na ovoj lokac
|
||||
main.vaultDetail.missing.recheck=Provjeri ponovo
|
||||
main.vaultDetail.missing.remove=Ukloni sa liste sefova…
|
||||
main.vaultDetail.missing.changeLocation=Promijeni lokaciju sefa…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Nadogradi sef
|
||||
main.vaultDetail.migratePrompt=Da biste mogli pristupiti svom sefu, morate ga nadograditi na novi format
|
||||
@@ -294,6 +295,25 @@ 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
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -394,8 +394,6 @@ main.vaultlist.contextMenu.unlockNow=Desbloqueja ara
|
||||
main.vaultlist.contextMenu.vaultoptions=Opcions de la caixa forta
|
||||
main.vaultlist.contextMenu.reveal=Mostra la unitat
|
||||
main.vaultlist.contextMenu.share=Compateix…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Crea una nova caixa forta…
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Obri una caixa forta existent...
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Hi ha una actualització disponible.
|
||||
main.notification.support=Doneu suport a Cryptomator.
|
||||
@@ -429,6 +427,7 @@ main.vaultDetail.missing.info=Cryptomator no ha trobat una caixa forta en aquest
|
||||
main.vaultDetail.missing.recheck=Torna a comprovar
|
||||
main.vaultDetail.missing.remove=Eliminar de la llista de la caixa forta…
|
||||
main.vaultDetail.missing.changeLocation=Canvia la localització de la caixa forta…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Actualitza la caixa forta
|
||||
main.vaultDetail.migratePrompt=Per accedir a la vostra caixa forta abans cal actualitzar-la al nou format
|
||||
@@ -508,6 +507,26 @@ recoveryKey.recover.resetBtn=Reinicia
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=S'ha modificat la contrasenya correctament
|
||||
recoveryKey.recover.resetSuccess.description=Pots desbloquejar la caixa forta amb la nova contrasenya.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Caixa forta de Hub
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Convertir la caixa forta
|
||||
|
||||
@@ -396,6 +396,7 @@ main.vaultDetail.missing.info=Cryptomator nemohl najít trezor na této cestě.
|
||||
main.vaultDetail.missing.recheck=Znovu zkontrolovat
|
||||
main.vaultDetail.missing.remove=Odebrat ze seznamu trezorů…
|
||||
main.vaultDetail.missing.changeLocation=Změnit umístění trezoru…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Upgrade trezoru
|
||||
main.vaultDetail.migratePrompt=Váš trezor musí být aktualizován na nový formát, než k němu budete mít přístup
|
||||
@@ -473,6 +474,26 @@ recoveryKey.recover.resetBtn=Resetovat
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Resetování hesla bylo úspěšné
|
||||
recoveryKey.recover.resetSuccess.description=Můžete odemknout váš trezor pomocí nového hesla.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub trezor
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Převést trezor
|
||||
|
||||
@@ -96,6 +96,7 @@ addvault.new.readme.accessLocation.4=Fjern denne fil hvis du har lyst.
|
||||
## Existing
|
||||
addvaultwizard.existing.title=Tilføj Eksisterende Boks
|
||||
addvaultwizard.existing.instruction=Vælgt filen "vault.cryptomator" i mappen med dine boks-filer. Hvis der kun findes en fil med navnet "masterkey.cryptomator", skal du vælge den i stedet.
|
||||
addvaultwizard.existing.restore=Gendan…
|
||||
addvaultwizard.existing.chooseBtn=Vælg…
|
||||
addvaultwizard.existing.filePickerTitle=Vælg boks-fil
|
||||
addvaultwizard.existing.filePickerMimeDesc=Cryptomator boks
|
||||
@@ -127,6 +128,7 @@ unlock.unlockBtn=Lås op
|
||||
## Select
|
||||
unlock.chooseMasterkey.message=Hovednøgle-fil ikke fundet
|
||||
unlock.chooseMasterkey.description=Cryptomator kunne ikke finde hovednøgle-filen for boksen "%s". Vælg venligst filen manuelt.
|
||||
unlock.chooseMasterkey.restoreInstead=Gendan i stedet masterkey-filen
|
||||
unlock.chooseMasterkey.filePickerTitle=Vælg hovednøgle-fil
|
||||
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator hovednøgle
|
||||
## Success
|
||||
@@ -394,8 +396,9 @@ main.vaultlist.contextMenu.unlockNow=Lås op nu
|
||||
main.vaultlist.contextMenu.vaultoptions=Vis boksindstillinger
|
||||
main.vaultlist.contextMenu.reveal=Vis drev
|
||||
main.vaultlist.contextMenu.share=Del…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Opret ny boks...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Åbn eksisterende boks...
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Opret ny boks…
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Åbn eksisterende boks…
|
||||
main.vaultlist.addVaultBtn.menuItemRecover=Genopret eksisterende boks…
|
||||
main.vaultlist.showEventsButton.tooltip=Åbn begivenhedsvisning
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Opdatering er tilgængelig.
|
||||
@@ -433,6 +436,9 @@ main.vaultDetail.missing.info=Cryptomator kunne ikke finde en boks på denne sti
|
||||
main.vaultDetail.missing.recheck=Kontrollér igen
|
||||
main.vaultDetail.missing.remove=Fjern fra listen over bokse…
|
||||
main.vaultDetail.missing.changeLocation=Skift placering for boks…
|
||||
### Missing Vault Config
|
||||
main.vaultDetail.missingVaultConfig.info=Bokskonfiguration mangler.
|
||||
main.vaultDetail.missingVaultConfig.restore=Gendan bokskonfiguration
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Opgradér boks
|
||||
main.vaultDetail.migratePrompt=Din boks skal opgraderes til et nyt format, før du kan tilgå den
|
||||
@@ -497,6 +503,7 @@ vaultOptions.hub.convertBtn=Konvertér til adgangskodebaseret boks
|
||||
recoveryKey.display.title=Vis gendannelsesnøgle
|
||||
recoveryKey.create.message=Adgangskode krævet
|
||||
recoveryKey.create.description=Indtast adgangskoden for "%s", for at vise gendannelsesnøglen.
|
||||
recoveryKey.recover.description=Indtast adgangskoden for "%s" for at gendanne bokskonfiguration.
|
||||
recoveryKey.display.description=Den følgende gendannelsesnøgle kan bruges til at genskabe adgang til "%s":
|
||||
recoveryKey.display.StorageHints=Opbevar den et meget sikkert sted, som fx:\n • Gem den i din adgangskode-manager\n • Gem den på et USB-drev\n • Print den ud på papir
|
||||
## Reset Password
|
||||
@@ -509,9 +516,57 @@ recoveryKey.recover.invalidKey=Denne gendannelsesnøgle er ikke gyldig
|
||||
recoveryKey.printout.heading=Cryptomator gendannelsesnøgle\n"%s"\n
|
||||
### Reset Password
|
||||
recoveryKey.recover.resetBtn=Nulstil
|
||||
recoveryKey.recover.recoverBtn=Gendan
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Adgangskod nulstillet
|
||||
recoveryKey.recover.resetSuccess.description=Du kan nu låse din boks op med den nye adgangskode.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.description=Du kan låse din boks op med din adgangskode nu.
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
recover.existing.title=Boks tilføjet
|
||||
recover.existing.message=Boksen blev tilføjet med succes
|
||||
recover.existing.description=Din boks "%s" er blevet tilføjet til bokslisten. Ingen genoprettelsesproces var nødvendig.
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
recover.alreadyExists.title=Boksen findes allerede
|
||||
recover.alreadyExists.message=Denne boks er allerede tilføjet
|
||||
recover.alreadyExists.description=Din boks "%s" er allerede til stede i din boksliste og blev derfor ikke tilføjet igen.
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
recover.invalidSelection.title=Ugyldigt valg
|
||||
recover.invalidSelection.message=Dit valg er ikke en boks
|
||||
recover.invalidSelection.description=Den valgte mappe skal være en gyldig Cryptomator boks.
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub Boks
|
||||
contactHubVaultOwner.message=Denne boks blev oprettet med Cryptomator Hub
|
||||
contactHubVaultOwner.description=Tag venligst kontakt til boksenejer for at gendanne den manglende fil. De kan downloade boksskabelon fra Cryptomator Hub.
|
||||
|
||||
##Dialog Title
|
||||
recover.recoverVaultConfig.title=Gendan bokskonfiguration
|
||||
recover.recoverMasterkey.title=Gendan Masterkey
|
||||
|
||||
## OnBoarding
|
||||
recover.onBoarding.chooseMethod=Vælg genoprettelsesmetode:
|
||||
recover.onBoarding.useRecoveryKey=Brug gendannelsesnøgle
|
||||
recover.onBoarding.usePassword=Brug adgangskode
|
||||
recover.onBoarding.intro=Sørg for at tjekke følgende:
|
||||
recover.onBoarding.pleaseConfirm=Før der fortsættes, bekræftes at:
|
||||
recover.onBoarding.otherwisePleaseConfirm=I modsat fald bekræftes følgende:
|
||||
recover.onBoarding.allMissing.intro=Hvis denne boks administreres af Cryptomator Hub, skal boksejer gendanne den for dig.
|
||||
recover.onBoarding.intro.ensure=Alle filer er fuldt synkroniserede.
|
||||
recover.onBoarding.affirmation=Jeg har læst og forstået disse krav
|
||||
|
||||
###Vault Config Missing
|
||||
recover.onBoarding.intro.recoveryKey=Du har gendannelsesnøglen og ved, om ekspertindstillinger blev brugt.
|
||||
recover.onBoarding.intro.password=Du har boksens adgangskode og ved, om ekspertindstillinger blev brugt.
|
||||
###Masterkey Missing
|
||||
recover.onBoarding.intro.masterkey.recoveryKey=Du har boksens gendannelsesnøgle.
|
||||
|
||||
## Expert Settings
|
||||
recover.expertSettings.shorteningThreshold.title=Denne værdi skal matche den, der blev brugt før gendannelse for at sikre kompatibilitet med tidligere krypterede data.
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Konvertér boks
|
||||
@@ -561,6 +616,7 @@ dokanySupportEnd.preferencesBtn=Åbn Indstillinger
|
||||
retryIfReadonly.title=Begrænset boksadgang
|
||||
retryIfReadonly.message=Ingen skriveadgang til boksens mappe
|
||||
retryIfReadonly.description=Cryptomator kan ikke skrive til boksens mappe. Du kan ændre boksen til at være skrivebeskyttet og prøve igen. Denne indstilling kan være deaktiveret i boksens indstillinger.
|
||||
retryIfReadonly.retry=Skift og prøv igen
|
||||
|
||||
# Share Vault
|
||||
shareVault.title=Del Boks
|
||||
@@ -584,10 +640,39 @@ shareVault.hub.openHub=Åben Cryptomator Hub
|
||||
|
||||
# Decrypt File Names
|
||||
decryptNames.title=Dekryptér Filnavne
|
||||
decryptNames.filePicker.title=Vælg krypteret fil
|
||||
decryptNames.filePicker.extensionDescription=Cryptomator krypteret fil
|
||||
decryptNames.copyTable.tooltip=Kopiér tabel
|
||||
decryptNames.clearTable.tooltip=Ryd tabel
|
||||
decryptNames.copyHint=Kopiér celleindhold med %s
|
||||
decryptNames.dropZone.message=Slip filer eller klik for at vælge
|
||||
decryptNames.dropZone.error.vaultInternalFiles=Boks interne filer med intet dekrypterbart navn valgt
|
||||
decryptNames.dropZone.error.foreignFiles=Filer hører ikke til boksen "%s"
|
||||
decryptNames.dropZone.error.noDirIdBackup=Mappe af valgte filer indeholder ikke dirId.c9r fil
|
||||
decryptNames.dropZone.error.generic=Kunne ikke dekryptere filnavne
|
||||
|
||||
|
||||
# Event View
|
||||
eventView.title=Begivenheder
|
||||
eventView.filter.allVaults=Alle
|
||||
eventView.clearListButton.tooltip=Ryd liste
|
||||
## event list entries
|
||||
eventView.entry.vaultLocked.description=Lås "%s" op for detaljer
|
||||
eventView.entry.conflictResolved.message=Løst konflikt
|
||||
eventView.entry.conflictResolved.showDecrypted=Vis dekrypteret fil
|
||||
eventView.entry.conflictResolved.copyDecrypted=Kopiér dekrypteret sti
|
||||
eventView.entry.conflict.message=Konfliktløsning mislykkedes
|
||||
eventView.entry.conflict.showDecrypted=Vis dekrypteret, original fil
|
||||
eventView.entry.conflict.copyDecrypted=Kopier dekrypteret, original sti
|
||||
eventView.entry.conflict.showEncrypted=Vis modstridende, krypteret fil
|
||||
eventView.entry.conflict.copyEncrypted=Kopier modstridende, krypteret sti
|
||||
eventView.entry.decryptionFailed.message=Dekryptering mislykkedes
|
||||
eventView.entry.decryptionFailed.showEncrypted=Vis krypteret fil
|
||||
eventView.entry.decryptionFailed.copyEncrypted=Kopiér krypteret sti
|
||||
eventView.entry.brokenDirFile.message=Brudt mappelink
|
||||
eventView.entry.brokenDirFile.showEncrypted=Vis brudt, krypteret link
|
||||
eventView.entry.brokenDirFile.copyEncrypted=Kopiér sti til brudt link
|
||||
eventView.entry.brokenFileNode.message=Brudt filsystem-node
|
||||
eventView.entry.brokenFileNode.showEncrypted=Vis brudt, krypteret node
|
||||
eventView.entry.brokenFileNode.copyEncrypted=Kopiér sti af brudt, krypteret node
|
||||
eventView.entry.brokenFileNode.copyDecrypted=Kopiér dekrypteret sti
|
||||
|
||||
@@ -96,6 +96,7 @@ addvault.new.readme.accessLocation.4=Du kannst diese Datei löschen.
|
||||
## Existing
|
||||
addvaultwizard.existing.title=Bestehenden Tresor hinzufügen
|
||||
addvaultwizard.existing.instruction=Wähle die Datei „vault.cryptomator“ deines bestehenden Tresors aus. Falls nur eine Datei mit der Bezeichnung „masterkey.cryptomator“ vorhanden ist, nutze stattdessen diese.
|
||||
addvaultwizard.existing.restore=Wiederherstellen…
|
||||
addvaultwizard.existing.chooseBtn=Durchsuchen …
|
||||
addvaultwizard.existing.filePickerTitle=Tresordatei auswählen
|
||||
addvaultwizard.existing.filePickerMimeDesc=Cryptomator-Tresor
|
||||
@@ -127,6 +128,7 @@ unlock.unlockBtn=Entsperren
|
||||
## Select
|
||||
unlock.chooseMasterkey.message=Masterkey-Datei nicht gefunden
|
||||
unlock.chooseMasterkey.description=Cryptomator konnte die Masterkey-Datei des Tresors „%s“ nicht finden. Bitte wähle die Datei manuell aus.
|
||||
unlock.chooseMasterkey.restoreInstead=Masterkey Datei wiederherstellen
|
||||
unlock.chooseMasterkey.filePickerTitle=Masterkey-Datei auswählen
|
||||
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator-Masterkey
|
||||
## Success
|
||||
@@ -394,8 +396,9 @@ main.vaultlist.contextMenu.unlockNow=Jetzt entsperren
|
||||
main.vaultlist.contextMenu.vaultoptions=Tresoroptionen anzeigen
|
||||
main.vaultlist.contextMenu.reveal=Laufwerk anzeigen
|
||||
main.vaultlist.contextMenu.share=Teilen …
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Neuen Tresor erstellen...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Bestehenden Tresor öffnen...
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Neuen Tresor erstellen…
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Bestehenden Tresor öffnen…
|
||||
main.vaultlist.addVaultBtn.menuItemRecover=Bestehenden Tresor wiederherstellen…
|
||||
main.vaultlist.showEventsButton.tooltip=Ereignis-Ansicht öffnen
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Eine neue Version ist verfügbar.
|
||||
@@ -433,6 +436,9 @@ main.vaultDetail.missing.info=Cryptomator konnte keinen Tresor mit diesem Pfad f
|
||||
main.vaultDetail.missing.recheck=Erneut prüfen
|
||||
main.vaultDetail.missing.remove=Aus Tresorliste entfernen …
|
||||
main.vaultDetail.missing.changeLocation=Speicherort des Tresors ändern …
|
||||
### Missing Vault Config
|
||||
main.vaultDetail.missingVaultConfig.info=Tresorkonfiguration fehlt.
|
||||
main.vaultDetail.missingVaultConfig.restore=Tresorkonfiguration wiederherstellen
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Tresor upgraden
|
||||
main.vaultDetail.migratePrompt=Dein Tresor muss in ein neues Format konvertiert werden, bevor du auf ihn zugreifen kannst
|
||||
@@ -497,6 +503,7 @@ vaultOptions.hub.convertBtn=In passwortgeschützten Tresor umwandeln
|
||||
recoveryKey.display.title=Wiederherstellungsschlüssel anzeigen
|
||||
recoveryKey.create.message=Passwort erforderlich
|
||||
recoveryKey.create.description=Gib das Passwort für „%s“ ein, um dessen Wiederherstellungsschlüssel anzuzeigen.
|
||||
recoveryKey.recover.description=Gib das Passwort für "%s" ein, um die Tresorkonfiguration wiederherzustellen.
|
||||
recoveryKey.display.description=Mit folgendem Wiederherstellungsschlüssel kannst du den Zugriff auf „%s“ wiederherstellen:
|
||||
recoveryKey.display.StorageHints=Bewahre ihn möglichst sicher auf, z. B.\n • in einem Passwortmanager\n • auf einem USB-Speicherstick\n • auf Papier ausgedruckt
|
||||
## Reset Password
|
||||
@@ -509,9 +516,59 @@ recoveryKey.recover.invalidKey=Dieser Wiederherstellungsschlüssel ist ungültig
|
||||
recoveryKey.printout.heading=Cryptomator-Wiederherstellungsschlüssel\n„%s“\n
|
||||
### Reset Password
|
||||
recoveryKey.recover.resetBtn=Zurücksetzen
|
||||
recoveryKey.recover.recoverBtn=Wiederherstellen
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Passwort erfolgreich zurückgesetzt
|
||||
recoveryKey.recover.resetSuccess.description=Du kannst deinen Tresor mit dem neuen Passwort entsperren.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
recoveryKey.recover.resetVaultConfigSuccess.message=Tresorkonfiguration wiederhergestellt
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.message=Masterkey-Datei wiederhergestellt
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.description=Du kannst deinen Tresor mit dem neuen Passwort jetzt entsperren.
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
recover.existing.title=Tresor hinzugefügt
|
||||
recover.existing.message=Der Tresor wurde erfolgreich hinzugefügt
|
||||
recover.existing.description=Dein Tresor "%s" wurde zur Tresorliste hinzugefügt. Es war kein Wiederherstellungsprozess nötig.
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
recover.alreadyExists.title=Tresor existiert bereits
|
||||
recover.alreadyExists.message=Dieser Tresor wurde bereits hinzugefügt
|
||||
recover.alreadyExists.description=Dein Tresor "%s" ist bereits in der Tresorliste vorhanden und wurde daher nicht erneut hinzugefügt.
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
recover.invalidSelection.title=Ungültige Auswahl
|
||||
recover.invalidSelection.message=Der ausgewählte Ordner ist kein Tresor
|
||||
recover.invalidSelection.description=Der ausgewählte Ordner muss ein gültiger Cryptomator-Tresor sein.
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hubtresor
|
||||
contactHubVaultOwner.message=Dieser Tresor wurde mit Cryptomator Hub erstellt
|
||||
contactHubVaultOwner.description=Bitte wenden dich an den Tresorbesitzer, um die fehlende Datei wiederherzustellen. Dieser kann die Tresorvorlage von Cryptomator Hub herunterladen.
|
||||
|
||||
##Dialog Title
|
||||
recover.recoverVaultConfig.title=Tresorkonfiguration wiederherstellen
|
||||
recover.recoverMasterkey.title=Masterkey wiederherstellen
|
||||
|
||||
## OnBoarding
|
||||
recover.onBoarding.chooseMethod=Wähle die Wiederherstellungsmethode:
|
||||
recover.onBoarding.useRecoveryKey=Wiederherstellungsschlüssel verwenden
|
||||
recover.onBoarding.usePassword=Passwort verwenden
|
||||
recover.onBoarding.intro=Stelle sicher, folgendes geprüft zu haben:
|
||||
recover.onBoarding.pleaseConfirm=Bevor es weiter geht, bestätige bitte:
|
||||
recover.onBoarding.otherwisePleaseConfirm=Andernfalls, bestätige bitte:
|
||||
recover.onBoarding.allMissing.intro=Wird der Tresor von Cryptomator Hub verwaltet, muss der Tresorbesitzer ihn für dich wiederherstellen.
|
||||
recover.onBoarding.intro.ensure=Alle Dateien sind vollständig synchronisiert.
|
||||
recover.onBoarding.affirmation=Ich habe die Anforderungen gelesen und verstanden
|
||||
|
||||
###Vault Config Missing
|
||||
recover.onBoarding.intro.recoveryKey=Du besitzt den Wiederherstellungsschlüssel und weißt, ob Experteneinstellungen verwendet wurden.
|
||||
recover.onBoarding.intro.password=Du besitzt das Tresorpasswort und weißt, ob Experteneinstellungen verwendet wurden.
|
||||
###Masterkey Missing
|
||||
recover.onBoarding.intro.masterkey.recoveryKey=Du besitzt den Wiederherstellungsschlüssel.
|
||||
|
||||
## Expert Settings
|
||||
recover.expertSettings.shorteningThreshold.title=Um Kompatibilität mit den verschlüsselten Dateien zu gewährleisten, muss der gleiche Wert wie zur Tresorerstellung verwendet werden.
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Tresor umwandeln
|
||||
|
||||
@@ -394,8 +394,6 @@ main.vaultlist.contextMenu.unlockNow=Ξεκλείδωμα τώρα
|
||||
main.vaultlist.contextMenu.vaultoptions=Εμφάνιση επιλογών Vault
|
||||
main.vaultlist.contextMenu.reveal=Αποκάλυψη εικονικού δίσκου
|
||||
main.vaultlist.contextMenu.share=Κοινοποίηση…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Δημιουργία Νέας Κρύπτης...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Άνοιγμα Υπάρχοντος Κρύπτης...
|
||||
main.vaultlist.showEventsButton.tooltip=Άνοιγμα προβολής συμβάντων
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Η ενημέρωση είναι διαθέσιμη.
|
||||
@@ -433,6 +431,7 @@ main.vaultDetail.missing.info=Cryptomator δεν βρήκε vault σε αυτό
|
||||
main.vaultDetail.missing.recheck=Επανέλεγχος
|
||||
main.vaultDetail.missing.remove=Κατάργηση από την λίστα των Vault…
|
||||
main.vaultDetail.missing.changeLocation=Αλλαγή τοποθεσίας Vault…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Αναβάθμιση Vault
|
||||
main.vaultDetail.migratePrompt=Το vault σας πρέπει να αναβαθμιστεί σε νέα μορφή, προτού να έχετε πρόσβαση σε αυτό
|
||||
@@ -512,6 +511,26 @@ recoveryKey.recover.resetBtn=Επαναφορά
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Επιτυχής επαναφορά κωδικού πρόσβασης
|
||||
recoveryKey.recover.resetSuccess.description=Μπορείτε να ξεκλειδώσετε την κρύπτη σας με το νέο κωδικό πρόσβασης.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Κρύπτη Hub
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Μετατροπή Θησαυ/κιου
|
||||
|
||||
@@ -96,6 +96,7 @@ addvault.new.readme.accessLocation.4=No dude en eliminar este archivo.
|
||||
## Existing
|
||||
addvaultwizard.existing.title=Añadir bóveda existente
|
||||
addvaultwizard.existing.instruction=Elija el archivo "vault.cryptomator" de su bóveda existente. Si solo existe un archivo llamado "masterkey.cryptomator", selecciónelo en su lugar.
|
||||
addvaultwizard.existing.restore=…
|
||||
addvaultwizard.existing.chooseBtn=Elegir…
|
||||
addvaultwizard.existing.filePickerTitle=Seleccionar archivo de bóveda
|
||||
addvaultwizard.existing.filePickerMimeDesc=Bóveda de Cryptomator
|
||||
@@ -127,6 +128,7 @@ unlock.unlockBtn=Desbloquear
|
||||
## Select
|
||||
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.restoreInstead=
|
||||
unlock.chooseMasterkey.filePickerTitle=Seleccione el archivo de la clave maestra
|
||||
unlock.chooseMasterkey.filePickerMimeDesc=Clave maestra de Cryptomator
|
||||
## Success
|
||||
@@ -394,8 +396,9 @@ main.vaultlist.contextMenu.unlockNow=Desbloquear ahora
|
||||
main.vaultlist.contextMenu.vaultoptions=Mostrar opciones de la bóveda
|
||||
main.vaultlist.contextMenu.reveal=Revelar unidad
|
||||
main.vaultlist.contextMenu.share=Compartir…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Crear Bóveda Nueva...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Abrir Bóveda Existente...
|
||||
main.vaultlist.addVaultBtn.menuItemNew=
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=
|
||||
main.vaultlist.addVaultBtn.menuItemRecover=
|
||||
main.vaultlist.showEventsButton.tooltip=Abrir vista de evento
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Existen actualizaciones disponibles.
|
||||
@@ -433,6 +436,9 @@ main.vaultDetail.missing.info=Cryptomator no pudo encontrar una bóveda en esta
|
||||
main.vaultDetail.missing.recheck=Volver a comprobar
|
||||
main.vaultDetail.missing.remove=Eliminar de la lista de bóveda…
|
||||
main.vaultDetail.missing.changeLocation=Cambiar ubicación de la bóveda…
|
||||
### Missing Vault Config
|
||||
main.vaultDetail.missingVaultConfig.info=Falta la configuración de la bóveda.
|
||||
main.vaultDetail.missingVaultConfig.restore=
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Actualizar bóveda
|
||||
main.vaultDetail.migratePrompt=Su bóveda necesita ser actualizada a un formato nuevo antes de poder acceder a ella
|
||||
@@ -497,6 +503,7 @@ vaultOptions.hub.convertBtn=Convertir a Bóveda con Contraseña
|
||||
recoveryKey.display.title=Mostrar clave de recuperación
|
||||
recoveryKey.create.message=Contraseña requerida
|
||||
recoveryKey.create.description=Ingresar la contraseña para mostrar la clave de recuperación para "%s":
|
||||
recoveryKey.recover.description=
|
||||
recoveryKey.display.description=La siguiente clave de recuperación puede usarse para restaurar el acceso a "%s":
|
||||
recoveryKey.display.StorageHints=Manténgala en algún lugar seguro, p.ej.:\n • Almacenarla en un administrador de contraseñas\n • Guardarla en una llave USB\n • Imprimirla en un papel
|
||||
## Reset Password
|
||||
@@ -512,6 +519,26 @@ recoveryKey.recover.resetBtn=## Reiniciar contraseña\nrecoveryKey.recover.reset
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Contraseña restablecida con éxito
|
||||
recoveryKey.recover.resetSuccess.description=Puede desbloquear su bóveda con la contraseña nueva.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Bóveda de Hub
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Convertir bóveda
|
||||
|
||||
@@ -183,6 +183,7 @@ main.vaultlist.contextMenu.reveal=نمایش درایو
|
||||
main.vaultDetail.revealBtn=نمایش درایو
|
||||
main.vaultDetail.lockBtn=قفل
|
||||
### Missing
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
### Error
|
||||
|
||||
@@ -204,6 +205,25 @@ vaultOptions.mount.mountPoint.directoryPickerButton=انتخاب کنید…
|
||||
### Enter Recovery Key
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -393,8 +393,6 @@ main.vaultlist.contextMenu.unlockNow=Avaa Nyt
|
||||
main.vaultlist.contextMenu.vaultoptions=Näytä holvin asetukset
|
||||
main.vaultlist.contextMenu.reveal=Paljasta Asema
|
||||
main.vaultlist.contextMenu.share=Jaa…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Luo uusi holvi...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Avaa olemassa oleva holvi...
|
||||
main.vaultlist.showEventsButton.tooltip=Avaa tapahtumanäkymä
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Päivitys on saatavilla.
|
||||
@@ -432,6 +430,7 @@ main.vaultDetail.missing.info=Cryptomator ei löytänyt täältä holvia.
|
||||
main.vaultDetail.missing.recheck=Tarkista uudelleen
|
||||
main.vaultDetail.missing.remove=Poista holvilistalta…
|
||||
main.vaultDetail.missing.changeLocation=Vaihda holvin sijaintia…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Päivitä Holvi
|
||||
main.vaultDetail.migratePrompt=Holvisi täytyy muuntaa uuteen muotoon ennen kuin voit avata sen
|
||||
@@ -511,6 +510,25 @@ recoveryKey.recover.resetBtn=Palauta
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Salasanan palautus onnistui
|
||||
recoveryKey.recover.resetSuccess.description=Voit avata holvin uudella salasanalla.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Muunna holvi
|
||||
|
||||
@@ -416,6 +416,7 @@ main.vaultDetail.missing.info=Hindi makahanap ng vault ang Cryptomator sa landas
|
||||
main.vaultDetail.missing.recheck=Suriin muli
|
||||
main.vaultDetail.missing.remove=Alisin sa Listahan ng Vault…
|
||||
main.vaultDetail.missing.changeLocation=Baguhin ang Lokasyon ng Vault…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=I-upgrade ang Vault
|
||||
main.vaultDetail.migratePrompt=Kailangang i-upgrade ang iyong vault sa bagong format, bago mo ito ma-access
|
||||
@@ -495,6 +496,26 @@ recoveryKey.recover.resetBtn=I-reset
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Matagumpay ang pag-reset ng password
|
||||
recoveryKey.recover.resetSuccess.description=Maaari mong i-unlock ang iyong vault gamit ang bagong password.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub Vault
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=I-convert ang Vault
|
||||
|
||||
@@ -96,6 +96,7 @@ addvault.new.readme.accessLocation.4=Vous pouvez supprimer ce fichier.
|
||||
## Existing
|
||||
addvaultwizard.existing.title=Ajouter un coffre existant
|
||||
addvaultwizard.existing.instruction=Choisissez le fichier « vault.cryptomator » de votre volume existant. Si seul le fichier « masterkey.cryptomator » est présent, sélectionnez celui-là.
|
||||
addvaultwizard.existing.restore=Restaurer…
|
||||
addvaultwizard.existing.chooseBtn=Choisir…
|
||||
addvaultwizard.existing.filePickerTitle=Sélectionnez le fichier correspondant au volume chiffré
|
||||
addvaultwizard.existing.filePickerMimeDesc=Coffre-fort Cryptomator
|
||||
@@ -127,6 +128,7 @@ unlock.unlockBtn=Déverrouiller
|
||||
## Select
|
||||
unlock.chooseMasterkey.message=Fichier Masterkey introuvable
|
||||
unlock.chooseMasterkey.description=Impossible de trouver le fichier clef à l'adresse attendue pour l'espace chiffré "%s". Veuillez sélectionner le fichier clef manuellement.
|
||||
unlock.chooseMasterkey.restoreInstead=Restaurez le fichier masterkey à la place
|
||||
unlock.chooseMasterkey.filePickerTitle=Sélectionner le fichier clef
|
||||
unlock.chooseMasterkey.filePickerMimeDesc=Clé principale Cryptomator
|
||||
## Success
|
||||
@@ -394,8 +396,9 @@ main.vaultlist.contextMenu.unlockNow=Déverrouiller maintenant
|
||||
main.vaultlist.contextMenu.vaultoptions=Afficher les options du volume chiffré
|
||||
main.vaultlist.contextMenu.reveal=Afficher le lecteur
|
||||
main.vaultlist.contextMenu.share=Partager…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Créer un nouveau coffre...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Ouvrir un coffre existant...
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Créer un nouveau coffre…
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Ouvrir le coffre existant…
|
||||
main.vaultlist.addVaultBtn.menuItemRecover=Restaurer le coffre existant…
|
||||
main.vaultlist.showEventsButton.tooltip=Ouvrir la vue Événements
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Mise à jour disponible.
|
||||
@@ -433,6 +436,9 @@ main.vaultDetail.missing.info=Cryptomator n'a pas pu trouver de volume chiffré
|
||||
main.vaultDetail.missing.recheck=Revérifier
|
||||
main.vaultDetail.missing.remove=Retirer de la liste des volumes…
|
||||
main.vaultDetail.missing.changeLocation=Changer l'emplacement du volume…
|
||||
### Missing Vault Config
|
||||
main.vaultDetail.missingVaultConfig.info=La configuration du coffre est manquante.
|
||||
main.vaultDetail.missingVaultConfig.restore=Restaurer la configuration du coffre
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Mettre le volume à jour
|
||||
main.vaultDetail.migratePrompt=Votre coffre doit être converti dans un nouveau format avant d'y accéder
|
||||
@@ -497,6 +503,7 @@ vaultOptions.hub.convertBtn=Convertir en coffre-fort basé sur mot de passe
|
||||
recoveryKey.display.title=Montrer la clé de récupération
|
||||
recoveryKey.create.message=Mot de passe requis
|
||||
recoveryKey.create.description=Entrez le mot de passe de "%s" pour afficher sa clé de récupération.
|
||||
recoveryKey.recover.description=Entrez le mot de passe pour "%s" pour restaurer la configuration du coffre.
|
||||
recoveryKey.display.description=La clé de récupération suivante peut être utilisée pour restaurer l'accès à "%s " :
|
||||
recoveryKey.display.StorageHints=Gardez-la dans un endroit sûr, par ex. :\n • Stockez-la en utilisant un gestionnaire de mots de passe\n • Enregistrez-la sur une clé USB\n • Imprimez-la
|
||||
## Reset Password
|
||||
@@ -509,9 +516,57 @@ recoveryKey.recover.invalidKey=Cette clé de récupération n'est pas valide
|
||||
recoveryKey.printout.heading=Clé de récupération Cryptomator "%s"\n
|
||||
### Reset Password
|
||||
recoveryKey.recover.resetBtn=Réinitialiser
|
||||
recoveryKey.recover.recoverBtn=Restaurer
|
||||
### Recovery Key Password Reset Success
|
||||
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.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.description=Vous pouvez maintenant déverrouiller votre coffre avec votre mot de passe.
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
recover.existing.title=Coffre ajouté
|
||||
recover.existing.message=Le coffre a été ajouté avec succès
|
||||
recover.existing.description=Votre coffre "%s" a été ajouté à la liste des coffres. Aucun processus de récupération n'a été nécessaire.
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
recover.alreadyExists.title=Le coffre-fort existe déjà
|
||||
recover.alreadyExists.message=Ce coffre a déjà été ajouté
|
||||
recover.alreadyExists.description=Votre coffre «%s» est déjà présent dans votre liste de coffres et n'a donc pas été ajouté à nouveau.
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
recover.invalidSelection.title=Sélection invalide
|
||||
recover.invalidSelection.message=Votre sélection n'est pas un coffre
|
||||
recover.invalidSelection.description=Le dossier sélectionné doit être un coffre Cryptomator valide.
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Coffre dans Hub
|
||||
contactHubVaultOwner.message=Ce coffre a été créé avec le Hub Cryptomator
|
||||
contactHubVaultOwner.description=.
|
||||
|
||||
##Dialog Title
|
||||
recover.recoverVaultConfig.title=Récupérer la configuration du coffre
|
||||
recover.recoverMasterkey.title=Récupérer la clé principale
|
||||
|
||||
## OnBoarding
|
||||
recover.onBoarding.chooseMethod=Choisissez la méthode de récupération :
|
||||
recover.onBoarding.useRecoveryKey=Utiliser la clé de récupération
|
||||
recover.onBoarding.usePassword=Utiliser mot de passe
|
||||
recover.onBoarding.intro=Assurez-vous de vérifier ce qui suit :
|
||||
recover.onBoarding.pleaseConfirm=Avant de procéder, veuillez confirmer ceci :
|
||||
recover.onBoarding.otherwisePleaseConfirm=Sinon, veuillez confirmer ceci:
|
||||
recover.onBoarding.allMissing.intro=Si ce coffre est géré par Cryptomator Hub, le propriétaire du coffre doit le restaurer pour vous.
|
||||
recover.onBoarding.intro.ensure=.
|
||||
recover.onBoarding.affirmation=J'ai lu et compris ces prérequis
|
||||
|
||||
###Vault Config Missing
|
||||
recover.onBoarding.intro.recoveryKey=Vous avez la clé de récupération et et savez si les paramètres experts ont été utilisés.
|
||||
recover.onBoarding.intro.password=Vous avez le mot de passe du coffre et savez si les paramètres experts ont été utilisés.
|
||||
###Masterkey Missing
|
||||
recover.onBoarding.intro.masterkey.recoveryKey=Vous avez la clé de récupération du coffre.
|
||||
|
||||
## Expert Settings
|
||||
recover.expertSettings.shorteningThreshold.title=
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Convertir le coffre
|
||||
|
||||
@@ -101,6 +101,7 @@ lock.forced.retryBtn=Tentar de novo
|
||||
### Locked
|
||||
### Unlocked
|
||||
### Missing
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
### Error
|
||||
|
||||
@@ -119,6 +120,25 @@ lock.forced.retryBtn=Tentar de novo
|
||||
### Enter Recovery Key
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -384,6 +384,7 @@ main.vaultDetail.missing.info=Cryptomator לא הצליח למצוא כספת ב
|
||||
main.vaultDetail.missing.recheck=בדיקה נוספת
|
||||
main.vaultDetail.missing.remove=הסר מרשימה הכספות…
|
||||
main.vaultDetail.missing.changeLocation=שנה את מיקום הכספת…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=שדרג הכספת
|
||||
main.vaultDetail.migratePrompt=צריך לשדרג את הכספת שלך לגרסה חדשה לפני שניתן לגשת אליה
|
||||
@@ -455,6 +456,25 @@ recoveryKey.recover.resetBtn=איפוס
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=איפוס סיסמה הצליח
|
||||
recoveryKey.recover.resetSuccess.description=ניתן לפתוח את הכספת עם הסיסמה החדשה.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.convert.convertBtn.before=להמיר
|
||||
|
||||
@@ -256,6 +256,7 @@ main.vaultDetail.lockBtn=लॉक करें
|
||||
main.vaultDetail.stats=वॉल्ट के आंकड़े
|
||||
### Missing
|
||||
main.vaultDetail.missing.remove=वॉल्ट की सूची से हटाए।
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=वाउल्ट को अपग्रेड करें
|
||||
### Error
|
||||
@@ -291,6 +292,25 @@ recoveryKey.create.description=रिकवरी-की दिखाने क
|
||||
### Enter Recovery Key
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -298,6 +298,7 @@ main.vaultDetail.missing.info=Cryptomator nije mogao pronaći trezor s ovom puta
|
||||
main.vaultDetail.missing.recheck=Ponovo provjeri
|
||||
main.vaultDetail.missing.remove=Ukloni iz liste trezora…
|
||||
main.vaultDetail.missing.changeLocation=Promijeni lokaciju trezora…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Nadogradi trezor
|
||||
main.vaultDetail.migratePrompt=Vaš trezor treba se nadograditi na novi format, prije nego mu možete pristupiti
|
||||
@@ -357,6 +358,25 @@ 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
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -394,8 +394,6 @@ main.vaultlist.contextMenu.unlockNow=Azonnali feloldás
|
||||
main.vaultlist.contextMenu.vaultoptions=Széf beállítások
|
||||
main.vaultlist.contextMenu.reveal=Széf megjelenítése
|
||||
main.vaultlist.contextMenu.share=Megosztás…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Új széf létrehozása...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Meglévő széf megnyitása...
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Frissítés elérhető.
|
||||
main.notification.support=Cryptomator támogatása.
|
||||
@@ -429,6 +427,7 @@ main.vaultDetail.missing.info=A Cryptomator nem talált széfet ezen az útvonal
|
||||
main.vaultDetail.missing.recheck=Ellenőrizze újra
|
||||
main.vaultDetail.missing.remove=A széf eltávolítása a listából…
|
||||
main.vaultDetail.missing.changeLocation=A széf helyének megváltoztatása…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Széf frissítése
|
||||
main.vaultDetail.migratePrompt=A széfet új formátumra kell frissíteni, mielőtt hozzáférhet
|
||||
@@ -508,6 +507,26 @@ recoveryKey.recover.resetBtn=Visszaállítás
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=A jelszó alaphelyzetbe állítása sikeresen megtörtént
|
||||
recoveryKey.recover.resetSuccess.description=Feloldhatja a széfet az új jelszóval.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub széf
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Széf átalakítása
|
||||
|
||||
@@ -394,8 +394,6 @@ main.vaultlist.contextMenu.unlockNow=Buka Kunci Sekarang
|
||||
main.vaultlist.contextMenu.vaultoptions=Tampilkan Opsi Vault
|
||||
main.vaultlist.contextMenu.reveal=Buka Drive
|
||||
main.vaultlist.contextMenu.share=Bagikan…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Buat Vault Baru...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Buka Vault yang Tersedia...
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Pembaruan tersedia.
|
||||
main.notification.support=Dukung Cryptomator.
|
||||
@@ -429,6 +427,7 @@ main.vaultDetail.missing.info=Cryptomator tidak dapat menemukan vault di path in
|
||||
main.vaultDetail.missing.recheck=Periksa kembali
|
||||
main.vaultDetail.missing.remove=Hapus dari Daftar Vault…
|
||||
main.vaultDetail.missing.changeLocation=Ganti Lokasi Vault…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Tingkatkan Vault
|
||||
main.vaultDetail.migratePrompt=Vault Anda perlu ditingkatkan ke format baru, sebelum Anda dapat mengaksesnya
|
||||
@@ -508,6 +507,26 @@ recoveryKey.recover.resetBtn=Atur ulang
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Atur ulang kata sandi berhasil
|
||||
recoveryKey.recover.resetSuccess.description=Anda dapat membuka kunci vault Anda dengan kata sandi baru.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub Vault
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Konversi Vault
|
||||
|
||||
@@ -96,6 +96,7 @@ addvault.new.readme.accessLocation.4=Sentiti libero di rimuovere questo file.
|
||||
## Existing
|
||||
addvaultwizard.existing.title=Aggiungi una Cassaforte Esistente
|
||||
addvaultwizard.existing.instruction=Scegliere il file "vault.cryptomator" della tua cassaforte. Se esiste solo un file chiamato "masterkey.cryptomator", allora scegli quello.
|
||||
addvaultwizard.existing.restore=Ripristina…
|
||||
addvaultwizard.existing.chooseBtn=Scegli…
|
||||
addvaultwizard.existing.filePickerTitle=Seleziona file cassaforte
|
||||
addvaultwizard.existing.filePickerMimeDesc=Cassaforte di Cryptomator
|
||||
@@ -127,6 +128,7 @@ unlock.unlockBtn=Sblocca
|
||||
## Select
|
||||
unlock.chooseMasterkey.message=File Masterkey non trovato
|
||||
unlock.chooseMasterkey.description=Impossibile trovare il file Masterkey per questa cassaforte alla sua posizione prevista. Sei pregato di sceglierlo manualmente.
|
||||
unlock.chooseMasterkey.restoreInstead=Ripristina invece il file con la chiave principale
|
||||
unlock.chooseMasterkey.filePickerTitle=Seleziona il File Masterkey
|
||||
unlock.chooseMasterkey.filePickerMimeDesc=Chiave principale di Cryptomator
|
||||
## Success
|
||||
@@ -394,8 +396,9 @@ main.vaultlist.contextMenu.unlockNow=Sblocca Ora
|
||||
main.vaultlist.contextMenu.vaultoptions=Mostra le Opzioni della Cassaforte
|
||||
main.vaultlist.contextMenu.reveal=Rivela Unità
|
||||
main.vaultlist.contextMenu.share=Condividi…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Crea una nuova cassaforte...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Apri una cassaforte esistente...
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Crea una nuova cassaforte…
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Apri una cassaforte esistente…
|
||||
main.vaultlist.addVaultBtn.menuItemRecover=Recupera una cassaforte esistente…
|
||||
main.vaultlist.showEventsButton.tooltip=Apri vista eventi
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Aggiornamento disponibile.
|
||||
@@ -433,6 +436,9 @@ main.vaultDetail.missing.info=Cryptomator non è riuscito a trovare una cassafor
|
||||
main.vaultDetail.missing.recheck=Ricontrolla
|
||||
main.vaultDetail.missing.remove=Rimuovi dall'elenco delle casseforti…
|
||||
main.vaultDetail.missing.changeLocation=Cambia la Posizione della Cassaforte…
|
||||
### Missing Vault Config
|
||||
main.vaultDetail.missingVaultConfig.info=Manca la configurazione della cassaforte.
|
||||
main.vaultDetail.missingVaultConfig.restore=Ripristina la configurazione della cassaforte
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Aggiorna la Cassaforte
|
||||
main.vaultDetail.migratePrompt=La tua cassaforte dev'esser aggiornata a un nuovo formato, prima di potervi accedere
|
||||
@@ -497,6 +503,7 @@ vaultOptions.hub.convertBtn=Converti in cassaforte basata su password
|
||||
recoveryKey.display.title=Mostra Chiave Di Recupero
|
||||
recoveryKey.create.message=Password richiesta
|
||||
recoveryKey.create.description=Inserisci la password per visualizzare la chiave di recupero per "%s":
|
||||
recoveryKey.recover.description=Inserisci la password di "%s" per recuperare la configurazione della cassaforte.
|
||||
recoveryKey.display.description=La seguente chiave di recupero può essere utilizzata per ripristinare l'accesso a %s":
|
||||
recoveryKey.display.StorageHints=Conservala da qualche parte in modo sicuro, es.\n • Archiviarla usando un gestore di password\n • Salvarla su un'unità flash USB\n • Stamparla su carta
|
||||
## Reset Password
|
||||
@@ -509,9 +516,57 @@ recoveryKey.recover.invalidKey=Questa chiave di recupero non é valida
|
||||
recoveryKey.printout.heading=Chiave di recupero Cryptomator\n"%s"\n
|
||||
### Reset Password
|
||||
recoveryKey.recover.resetBtn=Reimposta
|
||||
recoveryKey.recover.recoverBtn=Recupera
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Password reimpostata correttamente
|
||||
recoveryKey.recover.resetSuccess.description=Puoi sbloccare la tua cassaforte con la nuova password.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.description=Ora puoi sbloccare la cassaforte con la tua password.
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
recover.existing.title=Cassaforte aggiunta
|
||||
recover.existing.message=La cassaforte è stata aggiunta con successo
|
||||
recover.existing.description=La tua cassaforte "%s" è stata aggiunta alla lista. Non è stata necessaria alcuna azione di recupero.
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
recover.alreadyExists.title=La cassaforte esiste già
|
||||
recover.alreadyExists.message=Questa cassaforte è già stata aggiunta
|
||||
recover.alreadyExists.description=La tua cassaforte "%s" è già presente nella lista, quindi non è stata aggiunta di nuovo.
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
recover.invalidSelection.title=Selezione non valida
|
||||
recover.invalidSelection.message=Quello che hai selezionato non è una cassaforte
|
||||
recover.invalidSelection.description=La cartella selezionata deve essere una cassaforte Cryptomator.
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Centrale delle Casseforti
|
||||
contactHubVaultOwner.message=Questa cassaforte è stata creata con Cryptomator Hub
|
||||
contactHubVaultOwner.description=Contatta il proprietario della cassaforte per ripristinare il file mancante. Si può scaricare il modello di cassaforte da Cryptomator Hub.
|
||||
|
||||
##Dialog Title
|
||||
recover.recoverVaultConfig.title=Ripristina la configurazione della cassaforte
|
||||
recover.recoverMasterkey.title=Recupera il file con la chiave principale
|
||||
|
||||
## OnBoarding
|
||||
recover.onBoarding.chooseMethod=Scegli metodo di recupero:
|
||||
recover.onBoarding.useRecoveryKey=Usa la chiave di recupero
|
||||
recover.onBoarding.usePassword=Utilizza la password
|
||||
recover.onBoarding.intro=Assicurati di controllare quanto segue:
|
||||
recover.onBoarding.pleaseConfirm=Prima di procedere, conferma che:
|
||||
recover.onBoarding.otherwisePleaseConfirm=In caso contrario, conferma che:
|
||||
recover.onBoarding.allMissing.intro=Se questa cassaforte è gestita da Cryptomator Hub, è il proprietario della cassaforte che deve ripristinarla.
|
||||
recover.onBoarding.intro.ensure=Tutti i file sono completamente sincronizzati.
|
||||
recover.onBoarding.affirmation=Ho letto e compreso questi requisiti
|
||||
|
||||
###Vault Config Missing
|
||||
recover.onBoarding.intro.recoveryKey=Hai la chiave di recupero e sai se sono state utilizzate configurazioni avanzate.
|
||||
recover.onBoarding.intro.password=Hai la chiave di recupero e sai se sono state utilizzate configurazioni avanzate.
|
||||
###Masterkey Missing
|
||||
recover.onBoarding.intro.masterkey.recoveryKey=Hai la chiave di ripristino della cassaforte.
|
||||
|
||||
## Expert Settings
|
||||
recover.expertSettings.shorteningThreshold.title=Questo valore deve corrispondere a quello usato prima del recupero per garantire la compatibilità con i dati precedentemente crittografati.
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Convertire Cassaforte
|
||||
|
||||
@@ -391,8 +391,6 @@ main.vaultlist.contextMenu.unlockNow=今すぐ解錠
|
||||
main.vaultlist.contextMenu.vaultoptions=金庫のオプションを表示
|
||||
main.vaultlist.contextMenu.reveal=ドライブを表示
|
||||
main.vaultlist.contextMenu.share=共有…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=新しい金庫を作成…
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=既存の金庫を開く…
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=アップデートがあります。
|
||||
main.notification.support=Cryptomator を支援する。
|
||||
@@ -429,6 +427,7 @@ main.vaultDetail.missing.info=Cryptomator はこの場所に金庫を見つけ
|
||||
main.vaultDetail.missing.recheck=再確認
|
||||
main.vaultDetail.missing.remove=金庫のリストから削除...
|
||||
main.vaultDetail.missing.changeLocation=金庫の場所を変更...
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=金庫をアップグレード
|
||||
main.vaultDetail.migratePrompt=金庫にアクセスする前に、 金庫を新しい形式にアップグレードする必要があります
|
||||
@@ -508,6 +507,32 @@ recoveryKey.recover.resetBtn=リセット
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=パスワードをリセットしました
|
||||
recoveryKey.recover.resetSuccess.description=新しいパスワードで金庫の施錠ができます。
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
recover.invalidSelection.title=無効な選択
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
recover.onBoarding.useRecoveryKey=回復キーを利用
|
||||
recover.onBoarding.usePassword=パスワードを使用
|
||||
recover.onBoarding.pleaseConfirm=続行する前に、以下を確認してください:
|
||||
recover.onBoarding.intro.ensure=全てのファイルは完全に同期されています。
|
||||
recover.onBoarding.affirmation=私はこれらの要件を読み、理解しました
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=金庫を変換
|
||||
|
||||
@@ -394,8 +394,6 @@ main.vaultlist.contextMenu.unlockNow=지금 잠금 해제
|
||||
main.vaultlist.contextMenu.vaultoptions=Vault 옵션 보기
|
||||
main.vaultlist.contextMenu.reveal=드라이브 표시
|
||||
main.vaultlist.contextMenu.share=공유하기…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=새 Vault 생성...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=기존 Vault 열기...
|
||||
main.vaultlist.showEventsButton.tooltip=이벤트 뷰어 열기
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=업데이트가 있습니다.
|
||||
@@ -433,6 +431,7 @@ main.vaultDetail.missing.info=Cryptomator가 이 경로에 있는 Vault를 찾
|
||||
main.vaultDetail.missing.recheck=다시 시도
|
||||
main.vaultDetail.missing.remove=Vault 목록에서 제거...
|
||||
main.vaultDetail.missing.changeLocation=Vault 위치 변경
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Vault 업그레이드
|
||||
main.vaultDetail.migratePrompt=Vault에 접근하기 전, 새로운 포맷으로 업그레이드가 필요합니다.
|
||||
@@ -512,6 +511,26 @@ recoveryKey.recover.resetBtn=초기화
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=비밀번호 재설정 성공
|
||||
recoveryKey.recover.resetSuccess.description=이제 해당 vault를 새 비밀번호로 잠금 해제할 수 있습니다.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub Vault
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Vault 변환
|
||||
|
||||
@@ -96,6 +96,7 @@ addvault.new.readme.accessLocation.4=Šo datni var droši noņemt.
|
||||
## Existing
|
||||
addvaultwizard.existing.title=Pievienot esošu glabātavu
|
||||
addvaultwizard.existing.instruction=Jāizvēlas esošas glabātavas datne "vault.cryptomator". Ja pastāv tikai datne ar nosaukumu "masterkey.cryptomator", tad jāatlasā tā.
|
||||
addvaultwizard.existing.restore=Atjaunot…
|
||||
addvaultwizard.existing.chooseBtn=Izvēlēties…
|
||||
addvaultwizard.existing.filePickerTitle=Atlasīt glabātavas datni
|
||||
addvaultwizard.existing.filePickerMimeDesc=Cryptomator glabātava
|
||||
@@ -127,6 +128,7 @@ unlock.unlockBtn=Atslēgt
|
||||
## Select
|
||||
unlock.chooseMasterkey.message=Galvenās atslēgas datne nav atrasta
|
||||
unlock.chooseMasterkey.description=Cryptomator nevarēja atrast galvenās atslēgas datni glabātavai "%s". Lūgums pašrocīgi izvēlēties atslēgas datni.
|
||||
unlock.chooseMasterkey.restoreInstead=Tā vietā atjaunot galvenās atslēgas datni
|
||||
unlock.chooseMasterkey.filePickerTitle=Atlasīt galvenās atslēgas datni
|
||||
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator galvenā atslēga
|
||||
## Success
|
||||
@@ -394,8 +396,9 @@ main.vaultlist.contextMenu.unlockNow=Atslēgt tagad
|
||||
main.vaultlist.contextMenu.vaultoptions=Rādīt glabātavas iespējas
|
||||
main.vaultlist.contextMenu.reveal=Atklāt disku
|
||||
main.vaultlist.contextMenu.share=Kopīgot…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Izveidot jaunu glabātavu...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Atvērt esošu glabātavu...
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Izveidot jaunu glabātavu…
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Atvērt esošu glabātavu…
|
||||
main.vaultlist.addVaultBtn.menuItemRecover=Atjaunot esošu glabātavu…
|
||||
main.vaultlist.showEventsButton.tooltip=Atvērt notikumu skatu
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Ir pieejams atjauninājums.
|
||||
@@ -433,6 +436,9 @@ main.vaultDetail.missing.info=Cryptomator šajā ceļā nevarēja atrast glabāt
|
||||
main.vaultDetail.missing.recheck=Pārbaudīt atkārtoti
|
||||
main.vaultDetail.missing.remove=Noņemt no glabātavu saraksta…
|
||||
main.vaultDetail.missing.changeLocation=Mainīt glabātavas atrašanās vietu…
|
||||
### Missing Vault Config
|
||||
main.vaultDetail.missingVaultConfig.info=Trūkst glabātavas konfigurācijas.
|
||||
main.vaultDetail.missingVaultConfig.restore=Atjaunot glabātavas konfigurāciju
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Jaunināt glabātavu
|
||||
main.vaultDetail.migratePrompt=Glabātavu ir nepieciešams jaunināt uz jaunu veidolu, pirms tai varēs piekļūt
|
||||
@@ -497,6 +503,7 @@ vaultOptions.hub.convertBtn=Pārveidot par uz paroli balstītu glabātavu
|
||||
recoveryKey.display.title=Parādīt atkopes atslēgu
|
||||
recoveryKey.create.message=Nepieciešama parole
|
||||
recoveryKey.create.description=Jāievada "%s" parole, lai parādītu tās atkopes atslēgu.
|
||||
recoveryKey.recover.description=Jāievada “%s” parole, lai atkoptu glabātavas konfigurāciju.
|
||||
recoveryKey.display.description=Zemāk esošā atkopes atslēga var tikt izmantota, lai atjaunotu piekļuvi "%s":
|
||||
recoveryKey.display.StorageHints=Tā ir jātur ļoti drošā vietā, piemēram:\n • jāglabā paroļu pārvaldniekā;\n • jāsaglabā USB zibatmiņā;\n • jāizdrukā uz papīra.
|
||||
## Reset Password
|
||||
@@ -509,9 +516,57 @@ recoveryKey.recover.invalidKey=Šī atkopes atslēga nav derīga
|
||||
recoveryKey.printout.heading=Cryptomator atkopes atslēga\n"%s" \n
|
||||
### Reset Password
|
||||
recoveryKey.recover.resetBtn=Atiestatīt
|
||||
recoveryKey.recover.recoverBtn=Atkopt
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Paroles atiestatīšana sekmīga
|
||||
recoveryKey.recover.resetSuccess.description=Savu glabātavu var atslēgt ar jauno paroli.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.description=Savu glabātavu tagad var atslēgt ar jauno paroli.
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
recover.existing.title=Glabātava pievienota
|
||||
recover.existing.message=Glabātava tika sekmīgi pievienota
|
||||
recover.existing.description=Glabātava “%s” tika pievienota glabātavu sarakstam. Atkope nebija nepieciešama.
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
recover.alreadyExists.title=Glabātava jau pastāv
|
||||
recover.alreadyExists.message=Šī glabātava jau ir pievienota
|
||||
recover.alreadyExists.description=Glabātava “%s” jau ir glabātavu sarakstā, tādējādi tā netika pievienota vēlreiz.
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
recover.invalidSelection.title=Nederīga atlase
|
||||
recover.invalidSelection.message=Atlasītais nav glabātava
|
||||
recover.invalidSelection.description=Atlasītajai mapei jābūt derīgai Cryptomator glabātavai.
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub glabātava
|
||||
contactHubVaultOwner.message=Šī glabātava tika izveidota ar Cryptomator Hub
|
||||
contactHubVaultOwner.description=Lūgums vērsties pie glabātavas īpašnieka, lai atjaunotu trūkstošo datni. Glabātavas sagatavi var lejupielādēt no Cryptomator Hub.
|
||||
|
||||
##Dialog Title
|
||||
recover.recoverVaultConfig.title=Atkopt glabātavas konfigurāciju
|
||||
recover.recoverMasterkey.title=Atkopt galveno atslēgu
|
||||
|
||||
## OnBoarding
|
||||
recover.onBoarding.chooseMethod=Jāizvēlas atkopes veids:
|
||||
recover.onBoarding.useRecoveryKey=Izmantot atkopes atslēgu
|
||||
recover.onBoarding.usePassword=Izmantot paroli
|
||||
recover.onBoarding.intro=Jāpārliecinās, ka ir pārbaudīts šis:
|
||||
recover.onBoarding.pleaseConfirm=Pirms turpināšanas lūgums apstiprināt, ka:
|
||||
recover.onBoarding.otherwisePleaseConfirm=Pretējā gadījumā lūgums apstiprināt, ka:
|
||||
recover.onBoarding.allMissing.intro=Ja šo glabātavu pārvalda Cryptomator Hub, tā ir jāatjauno glabātavas īpašniekam.
|
||||
recover.onBoarding.intro.ensure=Visas datnes ir pilnībā sinhronizētas.
|
||||
recover.onBoarding.affirmation=Es izlasīju un saprotu šīs prasības
|
||||
|
||||
###Vault Config Missing
|
||||
recover.onBoarding.intro.recoveryKey=Tev ir atkopes atslēga, un Tu zini, vai tika izmantoti lietpratēju iestatījumi.
|
||||
recover.onBoarding.intro.password=Tev ir glabātavas atslēga, un Tu zini, vai tika izmantoti lietpratēju iestatījumi.
|
||||
###Masterkey Missing
|
||||
recover.onBoarding.intro.masterkey.recoveryKey=Tev ir glabātavas atkopes atslēga.
|
||||
|
||||
## Expert Settings
|
||||
recover.expertSettings.shorteningThreshold.title=Šai vērtībai ir jāatbilst tai, kas tika izmantota pirms atkopes, lai nodrošinatu saderību ar iepriekš šifrētajiem datiem.
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Pārveidot glabātavu
|
||||
|
||||
@@ -135,6 +135,7 @@ main.vaultlist.contextMenu.lock=Заклучи
|
||||
### Unlocked
|
||||
main.vaultDetail.lockBtn=Заклучи
|
||||
### Missing
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
### Error
|
||||
|
||||
@@ -155,6 +156,25 @@ vaultOptions.mount.mountPoint.directoryPickerButton=Избор…
|
||||
### Enter Recovery Key
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
### Locked
|
||||
### Unlocked
|
||||
### Missing
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
### Error
|
||||
|
||||
@@ -105,6 +106,25 @@
|
||||
### Enter Recovery Key
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -419,6 +419,7 @@ main.vaultDetail.missing.info=Cryptomator kunne ikke finne et hvelv på denne s
|
||||
main.vaultDetail.missing.recheck=Kontroller igjen
|
||||
main.vaultDetail.missing.remove=Fjern fra hvelvlisten…
|
||||
main.vaultDetail.missing.changeLocation=Endre hvelvplassering…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Oppgrader hvelv
|
||||
main.vaultDetail.migratePrompt=Hvelvet ditt må oppgraderes til et nytt format før du kan få tilgang til det
|
||||
@@ -498,6 +499,26 @@ recoveryKey.recover.resetBtn=Nullstill
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Passordnullstillingen vellykket
|
||||
recoveryKey.recover.resetSuccess.description=Du kan låse opp hvelvet med det nye passordet.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub hvelv
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Konverter hvelvet
|
||||
|
||||
@@ -96,6 +96,7 @@ addvault.new.readme.accessLocation.4=Voel je vrij om dit bestand te verwijderen.
|
||||
## Existing
|
||||
addvaultwizard.existing.title=Bestaande kluis toevoegen
|
||||
addvaultwizard.existing.instruction=Kies het "vault.cryptomator"-bestand van uw bestaande kluis. Indien er enkel een bestand genaamd "masterkey.cryptomator" anwezig is, kies deze dan in de plaats.
|
||||
addvaultwizard.existing.restore=Herstel…
|
||||
addvaultwizard.existing.chooseBtn=Kies…
|
||||
addvaultwizard.existing.filePickerTitle=Kies kluisbestand
|
||||
addvaultwizard.existing.filePickerMimeDesc=Cryptomator kluis
|
||||
@@ -127,6 +128,7 @@ unlock.unlockBtn=Ontgrendel
|
||||
## Select
|
||||
unlock.chooseMasterkey.message=Masterkey-bestand niet gevonden
|
||||
unlock.chooseMasterkey.description=Kon het sleutelbestand voor deze kluis niet vinden op de gewenste locatie. Kies het sleutelbestand handmatig.
|
||||
unlock.chooseMasterkey.restoreInstead=Herstel inplaats daarvan het hoofdsleutelbestand
|
||||
unlock.chooseMasterkey.filePickerTitle=Selecteer het Masterkey-bestand
|
||||
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator Masterkey
|
||||
## Success
|
||||
@@ -394,8 +396,9 @@ main.vaultlist.contextMenu.unlockNow=Nu Ontgrendelen
|
||||
main.vaultlist.contextMenu.vaultoptions=Laat kluisinstellingen zien
|
||||
main.vaultlist.contextMenu.reveal=Toon Schijf
|
||||
main.vaultlist.contextMenu.share=Delen…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Nieuwe Kluis Aanmaken...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Open Bestaande Kluis...
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Maak een nieuwe kluis aan…
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Open bestaande kluis…
|
||||
main.vaultlist.addVaultBtn.menuItemRecover=Herstel bestaande kluis…
|
||||
main.vaultlist.showEventsButton.tooltip=Afspraakweergave openen
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Update beschikbaar.
|
||||
@@ -433,6 +436,9 @@ main.vaultDetail.missing.info=Cryptomator kon op dit pad geen kluis vinden.
|
||||
main.vaultDetail.missing.recheck=Controleer nog eens
|
||||
main.vaultDetail.missing.remove=Verwijderen van kluislijst…
|
||||
main.vaultDetail.missing.changeLocation=Verander de locatie van de kluis…
|
||||
### Missing Vault Config
|
||||
main.vaultDetail.missingVaultConfig.info=Het configuratiebestand van de kluis ontbreekt.
|
||||
main.vaultDetail.missingVaultConfig.restore=Herstel het configuratiebestand van de kluis
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Kluis upgraden
|
||||
main.vaultDetail.migratePrompt=Uw kluis moet worden bijgewerkt naar een nieuw formaat, voordat u deze kunt openen
|
||||
@@ -497,6 +503,7 @@ vaultOptions.hub.convertBtn=Converteren naar Wachtwoord-gebaseerde kluis
|
||||
recoveryKey.display.title=Toon herstelsleutel
|
||||
recoveryKey.create.message=Wachtwoord vereist
|
||||
recoveryKey.create.description=Voer uw wachtwoord in om de herstelsleutel voor "%s" te tonen:
|
||||
recoveryKey.recover.description=Voer het wachtwoord voor "%s" in om de kluis te herstellen.
|
||||
recoveryKey.display.description=De volgende herstelsleutel kan worden gebruikt om "%s" te herstellen:
|
||||
recoveryKey.display.StorageHints=Bewaar het op een veilige plek, bv:\n • Bewaar het in een wachtwoordmanager\n • Sla het op op een USB-stick\n • Print het op papier
|
||||
## Reset Password
|
||||
@@ -509,9 +516,59 @@ recoveryKey.recover.invalidKey=Deze herstelsleutel is niet geldig
|
||||
recoveryKey.printout.heading=Cryptomator herstelsleutel\n"%s"\n
|
||||
### Reset Password
|
||||
recoveryKey.recover.resetBtn=Resetten
|
||||
recoveryKey.recover.recoverBtn=Herstellen
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Wachtwoord resetten geslaagd
|
||||
recoveryKey.recover.resetSuccess.description=Je kunt je kluis ontgrendelen met het nieuwe wachtwoord.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
recoveryKey.recover.resetVaultConfigSuccess.message=Kluis configuratie hersteld
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.message=Masterkey-bestand hersteld
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.description=Je kunt je kluis nu ontgrendelen met je wachtwoord.
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
recover.existing.title=Kluis toegevoegd
|
||||
recover.existing.message=De kluis is met succes toegevoegd
|
||||
recover.existing.description=Uw kluis "%s" is toegevoegd aan de lijst van kluizen. Er was geen herstelproces nodig.
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
recover.alreadyExists.title=Kluis bestaat al
|
||||
recover.alreadyExists.message=Deze kluis is al toegevoegd
|
||||
recover.alreadyExists.description=Je kluis "%s" is al aanwezig in je kluis lijst en is daarom niet meer toegevoegd.
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
recover.invalidSelection.title=Ongeldige selectie
|
||||
recover.invalidSelection.message=Jouw selectie is geen kluis
|
||||
recover.invalidSelection.description=De geselecteerde map moet een geldige Cryptomator kluis zijn.
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub Kluis
|
||||
contactHubVaultOwner.message=Deze kluis is gemaakt met Cryptomator Hub
|
||||
contactHubVaultOwner.description=Neem contact op met de eigenaar van de kluis om het ontbrekende bestand te herstellen. Ze kunnen de kluissjabloon downloaden van Cryptomator Hub.
|
||||
|
||||
##Dialog Title
|
||||
recover.recoverVaultConfig.title=Herstel het configuratiebestand van de kluis
|
||||
recover.recoverMasterkey.title=Masterkey herstellen
|
||||
|
||||
## OnBoarding
|
||||
recover.onBoarding.chooseMethod=Kies een herstelmethode:
|
||||
recover.onBoarding.useRecoveryKey=Herstelsleutel gebruiken
|
||||
recover.onBoarding.usePassword=Wachtwoord gebruiken
|
||||
recover.onBoarding.intro=Zorg ervoor dat je het volgende controleert:
|
||||
recover.onBoarding.pleaseConfirm=Vooraleer verder te gaan, bevestig dat:
|
||||
recover.onBoarding.otherwisePleaseConfirm=Anders bevestig dat:
|
||||
recover.onBoarding.allMissing.intro=Als deze kluis wordt beheerd door Cryptomator Hub, moet de eigenaar van de kluis deze voor je herstellen.
|
||||
recover.onBoarding.intro.ensure=Alle bestanden zijn volledig gesynchroniseerd.
|
||||
recover.onBoarding.affirmation=Ik heb deze vereisten gelezen en begrepen
|
||||
|
||||
###Vault Config Missing
|
||||
recover.onBoarding.intro.recoveryKey=Je beschikt over de herstelsleutel en weet of de geavanceerde instellingen zijn gebruikt.
|
||||
recover.onBoarding.intro.password=Je beschikt over de herstelsleutel en weet of de geavanceerde instellingen zijn gebruikt.
|
||||
###Masterkey Missing
|
||||
recover.onBoarding.intro.masterkey.recoveryKey=Je hebt de kluis herstelsleutel.
|
||||
|
||||
## Expert Settings
|
||||
recover.expertSettings.shorteningThreshold.title=Deze waarde moet overeenkomen met de waarde voor het herstel om de compatibiliteit met eerder versleutelde gegevens te waarborgen.
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Kluis converteren
|
||||
|
||||
@@ -202,6 +202,7 @@ main.vaultDetail.throughput.mbps=%.1f MiB/s
|
||||
### Missing
|
||||
main.vaultDetail.missing.info=Cryptomator kunne ikkje finna ein kvelv på denne søkastien.
|
||||
main.vaultDetail.missing.recheck=Kontroller igjen
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Oppgrader kvelv
|
||||
main.vaultDetail.migratePrompt=Kvelven din må oppgraderast til eit nytt format før du kan få tilgang til det
|
||||
@@ -254,6 +255,25 @@ recoveryKey.display.StorageHints=Ta vare på han ein veldig sikker stad, t.d. ve
|
||||
recoveryKey.printout.heading=Cryptomator-gjenopprettingsnøkkel\n"%s"\n
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
### Locked
|
||||
### Unlocked
|
||||
### Missing
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
### Error
|
||||
|
||||
@@ -105,6 +106,25 @@
|
||||
### Enter Recovery Key
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -329,8 +329,6 @@ main.vaultlist.contextMenu.unlockNow=ਹੁਣੇ ਅਣ-ਲਾਕ ਕਰੋ
|
||||
main.vaultlist.contextMenu.vaultoptions=ਵਾਲਟ ਚੋਣਾਂ ਨੂੰ ਵੇਖਾਓ
|
||||
main.vaultlist.contextMenu.reveal=ਡਰਾਇਵ ਦਿਖਾਓ
|
||||
main.vaultlist.contextMenu.share=…ਸਾਂਝਾ ਕਰੋ
|
||||
main.vaultlist.addVaultBtn.menuItemNew=...ਨਵਾਂ ਵਾਲਟ ਬਣਾਓ
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=...ਮੌਜੂਦਾ ਵਾਲਟ ਨੂੰ ਖੋਲ੍ਹੋ
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=ਅੱਪਡੇਟ ਮੌਜੂਦ ਹੈ।
|
||||
main.notification.support=Cryptomator ਲਈ ਸਹਿਯੋਗ।
|
||||
@@ -362,6 +360,7 @@ main.vaultDetail.missing.info=Cryptomator ਇਸ ਮਾਗਰ ਉੱਤੇ ਵ
|
||||
main.vaultDetail.missing.recheck=ਮੁੜ-ਜਾਂਚੋ
|
||||
main.vaultDetail.missing.remove=ਵਾਲਟ ਸੂਚੀ ਤੋਂ ਹਟਾਓ…
|
||||
main.vaultDetail.missing.changeLocation=ਵਾਲਟ ਟਿਕਾਣੇ ਨੂੰ ਬਦਲੋ…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=ਵਾਲਟ ਅੱਪਗਰੇਡ ਕਰੋ
|
||||
main.vaultDetail.migratePrompt=ਤੁਹਾਡੇ ਵਾਲਟ ਨੂੰ ਵਰਤੇ ਜਾਣ ਤੋਂ ਪਹਿਲਾਂ ਨਵੇਂ ਫਾਰਮੈਟ ਲਈ ਅੱਪਗਰੇਡ ਕਰਨ ਦੀ ਲੋੜ ਹੈ
|
||||
@@ -439,6 +438,26 @@ recoveryKey.recover.resetBtn=ਰੀਸੈੱਟ ਕਰੋ
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=ਪਾਸਵਰਡ ਨੂੰ ਕਾਮਯਾਬੀ ਨਾਲ ਮੁੜ-ਸੈੱਟ ਕੀਤਾ ਗਿਆ
|
||||
recoveryKey.recover.resetSuccess.description=ਤੁਸੀਂ ਆਪਣੇ ਵਾਲਟ ਨੂੰ ਨਵੇਂ ਪਾਸਵਰਡ ਨਾਲ ਖੋਲ੍ਹ ਸਕਦੇ ਹੋ
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub ਵਾਲਟ
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=ਵਾਲਟ ਨੂੰ ਬਦਲੋ
|
||||
|
||||
@@ -394,8 +394,6 @@ main.vaultlist.contextMenu.unlockNow=Odblokuj teraz
|
||||
main.vaultlist.contextMenu.vaultoptions=Pokaż opcje sejfu
|
||||
main.vaultlist.contextMenu.reveal=Otwórz lokalizację
|
||||
main.vaultlist.contextMenu.share=Udostępnij…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Utwórz Nowy Sejf...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Otwórz Istniejący Sejf...
|
||||
main.vaultlist.showEventsButton.tooltip=Otwórz widok wydarzeń
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Dostępna aktualizacja.
|
||||
@@ -433,6 +431,7 @@ main.vaultDetail.missing.info=Cryptomator nie mógł znaleźć sejfu w tej lokal
|
||||
main.vaultDetail.missing.recheck=Ponów próbę
|
||||
main.vaultDetail.missing.remove=Usuń z listy sejfów…
|
||||
main.vaultDetail.missing.changeLocation=Zmień lokalizację sejfu…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Aktualizuj sejf
|
||||
main.vaultDetail.migratePrompt=Twój sejf musi zostać zaktualizowany do nowego formatu, zanim będziesz mógł go używać
|
||||
@@ -512,6 +511,26 @@ recoveryKey.recover.resetBtn=Resetuj
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Hasło zostało zresetowane
|
||||
recoveryKey.recover.resetSuccess.description=Możesz odblokować sejf przy użyciu nowego hasła.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub sejfów
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Konwertuj sejf
|
||||
|
||||
@@ -96,6 +96,7 @@ addvault.new.readme.accessLocation.4=Sinta-se livre para remover este ficheiro.
|
||||
## Existing
|
||||
addvaultwizard.existing.title=Adicionar cofre existente
|
||||
addvaultwizard.existing.instruction=Escolha o ficheiro "vault.cryptomator" do seu cofre. Se encontrar unicamente o ficheiro "masterkey.cryptomator", selecione-o.
|
||||
addvaultwizard.existing.restore=Restaurar…
|
||||
addvaultwizard.existing.chooseBtn=Escolher…
|
||||
addvaultwizard.existing.filePickerTitle=Selecionar o ficheiro do cofre
|
||||
addvaultwizard.existing.filePickerMimeDesc=Cofre Cryptomator
|
||||
@@ -127,6 +128,7 @@ unlock.unlockBtn=Desbloquear
|
||||
## Select
|
||||
unlock.chooseMasterkey.message=Chave Mestra não encontrada
|
||||
unlock.chooseMasterkey.description=Não foi possível encontrar o ficheiro masterkey no local predefinido para este cofre. Por favor, escolha o ficheiro chave manualmente.
|
||||
unlock.chooseMasterkey.restoreInstead=Restaure o ficheiro da chave mestra
|
||||
unlock.chooseMasterkey.filePickerTitle=Selecionar ficheiro MasterKey
|
||||
unlock.chooseMasterkey.filePickerMimeDesc=Chave Mestra Cryptomator
|
||||
## Success
|
||||
@@ -394,8 +396,9 @@ main.vaultlist.contextMenu.unlockNow=Desbloquear agora
|
||||
main.vaultlist.contextMenu.vaultoptions=Mostrar opções do Cofre
|
||||
main.vaultlist.contextMenu.reveal=Revelar unidade
|
||||
main.vaultlist.contextMenu.share=Partilhar…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Criar novo cofre...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Abrir cofre existente...
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Criar novo cofre…
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Abrir cofre existente…
|
||||
main.vaultlist.addVaultBtn.menuItemRecover=Recuperar cofre existente…
|
||||
main.vaultlist.showEventsButton.tooltip=Abrir visualização do evento
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=A atualização está disponível.
|
||||
@@ -433,6 +436,9 @@ main.vaultDetail.missing.info=O Cryptomator não conseguiu encontrar um cofre ne
|
||||
main.vaultDetail.missing.recheck=Verificar novamente
|
||||
main.vaultDetail.missing.remove=Remover da Lista de Cofres…
|
||||
main.vaultDetail.missing.changeLocation=Mudar localização do Cofre…
|
||||
### Missing Vault Config
|
||||
main.vaultDetail.missingVaultConfig.info=A configuração do cofre está em falta.
|
||||
main.vaultDetail.missingVaultConfig.restore=Restaurar configuração do cofre
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Atualizar Cofre
|
||||
main.vaultDetail.migratePrompt=O cofre precisa de ser atualizado para um novo formato, antes que possa acessá-lo
|
||||
@@ -497,6 +503,7 @@ vaultOptions.hub.convertBtn=Converter para cofre baseado em palavras-passe
|
||||
recoveryKey.display.title=Mostrar chave de recuperação
|
||||
recoveryKey.create.message=Palavra-passe necessária
|
||||
recoveryKey.create.description=Inserir a palavra passe de "%s" para mostrar a chave de recuperação.
|
||||
recoveryKey.recover.description=Introduza a palavra-passe de "%s" para recuperar a configuração do cofre.
|
||||
recoveryKey.display.description=Esta chave de recuperação pode ser usada para restaurar acesso a "%s":
|
||||
recoveryKey.display.StorageHints=Guarde-a num lugar muito seguro, por exemplo:\n • Armazená-la usando um gerenciador de senhas\n • Guarde-a numa ‘pen’ USB\n • Imprima-a em papel
|
||||
## Reset Password
|
||||
@@ -509,9 +516,57 @@ recoveryKey.recover.invalidKey=Esta chave de recupreação não está certa
|
||||
recoveryKey.printout.heading=A chave de recuperação do Cryptomator \n"%s"\n
|
||||
### Reset Password
|
||||
recoveryKey.recover.resetBtn=Repor
|
||||
recoveryKey.recover.recoverBtn=Recuperar
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Palavra-passe redefinida com sucesso
|
||||
recoveryKey.recover.resetSuccess.description=Você pode desbloquear o seu cofre com a nova senha.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.description=Agora pode desbloquear o seu cofre com a sua palavra-passe.
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
recover.existing.title=Cofre adicionado
|
||||
recover.existing.message=O cofre foi adicionado com sucesso
|
||||
recover.existing.description=O seu cofre "%s" foi adicionado à lista de cofres. Nenhum processo de recuperação foi necessário.
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
recover.alreadyExists.title=O cofre já existe
|
||||
recover.alreadyExists.message=Este cofre já foi adicionado
|
||||
recover.alreadyExists.description=O seu cofre "%s" já está presente na lista de cofres, por isso, não foi adicionado novamente.
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
recover.invalidSelection.title=Seleção inválida
|
||||
recover.invalidSelection.message=A sua seleção não é um cofre
|
||||
recover.invalidSelection.description=A pasta selecionada precisa ser um cofre válido do Cryptomator.
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Cofre do Hub
|
||||
contactHubVaultOwner.message=Este cofre foi criado com o Cryptomator Hub
|
||||
contactHubVaultOwner.description=Contacte o proprietário do cofre para restaurar o ficheiro perdido. Pode descarregar o modelo do cofre no Cryptomator Hub.
|
||||
|
||||
##Dialog Title
|
||||
recover.recoverVaultConfig.title=Recuperar configuração do cofre
|
||||
recover.recoverMasterkey.title=Recuperar chave mestra
|
||||
|
||||
## OnBoarding
|
||||
recover.onBoarding.chooseMethod=Escolher método de recuperação:
|
||||
recover.onBoarding.useRecoveryKey=Usar chave de recuperação
|
||||
recover.onBoarding.usePassword=Usar palavra-passe
|
||||
recover.onBoarding.intro=Certifique-se de verificar o seguinte:
|
||||
recover.onBoarding.pleaseConfirm=Antes de prosseguir, por favor confirme que:
|
||||
recover.onBoarding.otherwisePleaseConfirm=Caso contrário, confirme que:
|
||||
recover.onBoarding.allMissing.intro=Se este cofre for gerido pelo Cryptomator Hub, o proprietário do cofre deverá restaurá-lo para si.
|
||||
recover.onBoarding.intro.ensure=Todos os ficheiros estão totalmente sincronizados.
|
||||
recover.onBoarding.affirmation=Li e compreendi estes requisitos
|
||||
|
||||
###Vault Config Missing
|
||||
recover.onBoarding.intro.recoveryKey=Tem a chave de recuperação e sabe se foram utilizadas as definições de especialista.
|
||||
recover.onBoarding.intro.password=Tem a palavra-passe do cofre e sabe se foram usadas configurações de especialista.
|
||||
###Masterkey Missing
|
||||
recover.onBoarding.intro.masterkey.recoveryKey=Você tem a chave de recuperação do cofre.
|
||||
|
||||
## Expert Settings
|
||||
recover.expertSettings.shorteningThreshold.title=Este valor deve corresponder ao utilizado antes da recuperação para garantir a compatibilidade com os dados previamente encriptados.
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Converter cofre
|
||||
|
||||
@@ -394,8 +394,6 @@ main.vaultlist.contextMenu.unlockNow=Desbloquear Agora
|
||||
main.vaultlist.contextMenu.vaultoptions=Exibir Opções de Cofre
|
||||
main.vaultlist.contextMenu.reveal=Revelar Volume
|
||||
main.vaultlist.contextMenu.share=Compartilhar…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Novo Cofre...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Abrir Cofre Existente...
|
||||
main.vaultlist.showEventsButton.tooltip=Abrir visualização de evento
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Atualização disponível.
|
||||
@@ -433,6 +431,7 @@ main.vaultDetail.missing.info=O Cryptomator não encontrou um cofre neste caminh
|
||||
main.vaultDetail.missing.recheck=Verificar novamente
|
||||
main.vaultDetail.missing.remove=Remover da lista de cofres…
|
||||
main.vaultDetail.missing.changeLocation=Alterar Localização do Cofre…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Atualizar Cofre
|
||||
main.vaultDetail.migratePrompt=Seu cofre precisa ser atualizado para um novo formato antes de poder acessá-lo
|
||||
@@ -512,6 +511,26 @@ recoveryKey.recover.resetBtn=Redefinir
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Senha redefinida com sucesso
|
||||
recoveryKey.recover.resetSuccess.description=Você pode desbloquear o seu cofre com a nova senha.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Cofre do Hub
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Converter Cofre
|
||||
|
||||
@@ -390,8 +390,6 @@ main.vaultlist.contextMenu.unlockNow=Deblochează acum
|
||||
main.vaultlist.contextMenu.vaultoptions=Arată opțiunile seifului
|
||||
main.vaultlist.contextMenu.reveal=Dezvăluie unitatea
|
||||
main.vaultlist.contextMenu.share=Distribuie…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Creare seif nou...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Deschide un seif existent...
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=O nouă versiune este valabilă.
|
||||
main.notification.support=Susține Cryptomator.
|
||||
@@ -425,6 +423,7 @@ main.vaultDetail.missing.info=Cryptomator nu a putut găsi un seif pe această c
|
||||
main.vaultDetail.missing.recheck=Verifică din nou
|
||||
main.vaultDetail.missing.remove=Eliminați din lista de seifuri…
|
||||
main.vaultDetail.missing.changeLocation=Schimbați locația seifului…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Îmbunătățește seiful
|
||||
main.vaultDetail.migratePrompt=Înainte de a-l putea accesa, seiful dumneavoastră trebuie actualizat la format nou
|
||||
@@ -504,6 +503,26 @@ recoveryKey.recover.resetBtn=Resetează
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Parola a fost resetată cu succes
|
||||
recoveryKey.recover.resetSuccess.description=Puteți debloca seiful cu parola noua.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Seif Hub
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Transformă seiful
|
||||
|
||||
@@ -96,6 +96,7 @@ addvault.new.readme.accessLocation.4=Этот файл можно удалить
|
||||
## Existing
|
||||
addvaultwizard.existing.title=Добавить имеющееся хранилище
|
||||
addvaultwizard.existing.instruction=Выберите файл "vault.cryptomator" существующего хранилища. Если имеется только файл "masterkey.cryptomator", выберите его.
|
||||
addvaultwizard.existing.restore=Восстановить…
|
||||
addvaultwizard.existing.chooseBtn=Выбрать…
|
||||
addvaultwizard.existing.filePickerTitle=Выберите файл хранилища
|
||||
addvaultwizard.existing.filePickerMimeDesc=Хранилище Cryptomator
|
||||
@@ -127,6 +128,7 @@ unlock.unlockBtn=Разблокировать
|
||||
## Select
|
||||
unlock.chooseMasterkey.message=Файл Masterkey не найден
|
||||
unlock.chooseMasterkey.description=Не удалось найти файл Masterkey для хранилища "%s". Выберите ключевой файл вручную.
|
||||
unlock.chooseMasterkey.restoreInstead=Восстановить файл Masterkey
|
||||
unlock.chooseMasterkey.filePickerTitle=Выберите файл MasterKey
|
||||
unlock.chooseMasterkey.filePickerMimeDesc=Мастер-ключ Cryptomator
|
||||
## Success
|
||||
@@ -394,8 +396,9 @@ main.vaultlist.contextMenu.unlockNow=Разблокировать
|
||||
main.vaultlist.contextMenu.vaultoptions=Параметры хранилища
|
||||
main.vaultlist.contextMenu.reveal=Показать диск
|
||||
main.vaultlist.contextMenu.share=Поделиться…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Создать хранилище...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Открыть имеющееся хранилище...
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Создать хранилище…
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Открыть имеющееся хранилище…
|
||||
main.vaultlist.addVaultBtn.menuItemRecover=Восстановить имеющееся хранилище…
|
||||
main.vaultlist.showEventsButton.tooltip=Открыть просмотр события
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Есть обновление.
|
||||
@@ -433,6 +436,9 @@ main.vaultDetail.missing.info=Cryptomator не смог найти хранил
|
||||
main.vaultDetail.missing.recheck=Перепроверить
|
||||
main.vaultDetail.missing.remove=Удалить из списка хранилищ…
|
||||
main.vaultDetail.missing.changeLocation=Изменить расположение хранилища…
|
||||
### Missing Vault Config
|
||||
main.vaultDetail.missingVaultConfig.info=Отсутствует конфигурация хранилища.
|
||||
main.vaultDetail.missingVaultConfig.restore=Восстановить настройки хранилища
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Обновить хранилище
|
||||
main.vaultDetail.migratePrompt=Чтобы получить доступ к хранилищу, его нужно преобразовать в новый формат
|
||||
@@ -497,6 +503,7 @@ vaultOptions.hub.convertBtn=Преобразовать в хранилище с
|
||||
recoveryKey.display.title=Показать ключ восстановления
|
||||
recoveryKey.create.message=Требуется пароль
|
||||
recoveryKey.create.description=Введите пароль для "%s", чтобы показать его ключ восстановления.
|
||||
recoveryKey.recover.description=Введите пароль для "%s", чтобы восстановить конфигурацию хранилища.
|
||||
recoveryKey.display.description=Ключ для восстановления доступа к "%s":
|
||||
recoveryKey.display.StorageHints=Храните его в надёжном месте, например:\n • в диспетчере паролей\n • на флеш-накопителе USB\n • распечатанным на бумаге
|
||||
## Reset Password
|
||||
@@ -509,9 +516,57 @@ recoveryKey.recover.invalidKey=Этот ключ восстановления н
|
||||
recoveryKey.printout.heading=Ключ восстановления Cryptomator\n"%s"\n
|
||||
### Reset Password
|
||||
recoveryKey.recover.resetBtn=Сброс
|
||||
recoveryKey.recover.recoverBtn=Восстановить
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Пароль успешно сброшен
|
||||
recoveryKey.recover.resetSuccess.description=Вы можете разблокировать хранилище новым паролем.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.description=Теперь вы можете разблокировать хранилище с помощью пароля.
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
recover.existing.title=Хранилище добавлено
|
||||
recover.existing.message=Хранилище успешно добавлено
|
||||
recover.existing.description=Хранилище "%s" добавлено в список. Восстановление не потребовалось.
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
recover.alreadyExists.title=Хранилище уже существует
|
||||
recover.alreadyExists.message=Это хранилище уже добавлено
|
||||
recover.alreadyExists.description=Хранилище "%s" уже есть в списке и поэтому не было добавлено снова.
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
recover.invalidSelection.title=Неверный выбор
|
||||
recover.invalidSelection.message=Выбрано не хранилище
|
||||
recover.invalidSelection.description=Выбранная папка должна быть корректным хранилищем Cryptomator.
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Хаб-хранилище
|
||||
contactHubVaultOwner.message=Это хранилище было создано с помощью хаба Cryptomator
|
||||
contactHubVaultOwner.description=Свяжитесь с владельцем хранилища для восстановления отсутствующего файла. Шаблон хранилища можно загрузить из хаба Cryptomator.
|
||||
|
||||
##Dialog Title
|
||||
recover.recoverVaultConfig.title=Восстановление конфигурации хранилища
|
||||
recover.recoverMasterkey.title=Восстановить Masterkey
|
||||
|
||||
## OnBoarding
|
||||
recover.onBoarding.chooseMethod=Выберите метод восстановления:
|
||||
recover.onBoarding.useRecoveryKey=Использовать ключ восстановления
|
||||
recover.onBoarding.usePassword=Использовать пароль
|
||||
recover.onBoarding.intro=Проверьте следующее:
|
||||
recover.onBoarding.pleaseConfirm=Прежде чем продолжить, подтвердите, что:
|
||||
recover.onBoarding.otherwisePleaseConfirm=В противном случае подтвердите, что:
|
||||
recover.onBoarding.allMissing.intro=Если это хранилище управляется хабом Cryptomator, владелец хранилища должен восстановить его для вас.
|
||||
recover.onBoarding.intro.ensure=Все файлы полностью синхронизированы.
|
||||
recover.onBoarding.affirmation=Требования прочитаны и понятны
|
||||
|
||||
###Vault Config Missing
|
||||
recover.onBoarding.intro.recoveryKey=У вас есть ключ восстановления и вы знаете, что были использованы экспертные настройки.
|
||||
recover.onBoarding.intro.password=У вас есть пароль хранилища и вы знаете, что были использованы экспертные настройки.
|
||||
###Masterkey Missing
|
||||
recover.onBoarding.intro.masterkey.recoveryKey=У вас есть ключ восстановления хранилища.
|
||||
|
||||
## Expert Settings
|
||||
recover.expertSettings.shorteningThreshold.title=Это значение должно соответствовать значению перед восстановлением, чтобы гарантировать совместимость с ранее зашифрованными данными.
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Преобразовать хранилище
|
||||
|
||||
@@ -104,6 +104,7 @@ hub.registerSuccess.unlockBtn=අගුළුහරින්න
|
||||
### Locked
|
||||
### Unlocked
|
||||
### Missing
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
### Error
|
||||
|
||||
@@ -122,6 +123,25 @@ hub.registerSuccess.unlockBtn=අගුළුහරින්න
|
||||
### Enter Recovery Key
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -96,6 +96,7 @@ addvault.new.readme.accessLocation.4=Tento súbor môžete kedykoľvek odstráni
|
||||
## Existing
|
||||
addvaultwizard.existing.title=Pridať existujúci trezor
|
||||
addvaultwizard.existing.instruction=Zvoľte "vault.cryptomator" súbor Vášho existujúceho trezora. Ak existuje iba súbor s menom "masterkey.cryptomator", vyberte ho namiesto.
|
||||
addvaultwizard.existing.restore=Obnoviť…
|
||||
addvaultwizard.existing.chooseBtn=Vybrať…
|
||||
addvaultwizard.existing.filePickerTitle=Zvoľte súbor trezora
|
||||
addvaultwizard.existing.filePickerMimeDesc=Trezor Cryptomátora
|
||||
@@ -388,7 +389,6 @@ main.vaultlist.contextMenu.vaultoptions=Ukáž možnosti trezora
|
||||
main.vaultlist.contextMenu.reveal=Odkry disk
|
||||
main.vaultlist.contextMenu.share=Zdieľať…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Vytvoriť Nový trezor…
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Otvoriť Existujúci trezor...
|
||||
main.vaultlist.showEventsButton.tooltip=Otvoriť zobrazenie udalosti
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Aktualizácia je k dispozícii.
|
||||
@@ -426,6 +426,7 @@ main.vaultDetail.missing.info=Cryptomator nevie nájsť trezor na tejto ceste.
|
||||
main.vaultDetail.missing.recheck=Prekontrolovať
|
||||
main.vaultDetail.missing.remove=Odstrániť zo zoznamu trezora…
|
||||
main.vaultDetail.missing.changeLocation=Zmeniť umiestnenie trezora…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Aktualizácia trezora
|
||||
main.vaultDetail.migratePrompt=Váš trezor vyžaduje aktualizáciu na nový formát predtým ako ho použijete
|
||||
@@ -501,9 +502,37 @@ recoveryKey.recover.invalidKey=Toto je neplatný kľúč obnovy
|
||||
recoveryKey.printout.heading=Kľúč obnovy Cryptomator-a\n "%s"\n
|
||||
### Reset Password
|
||||
recoveryKey.recover.resetBtn=Resetovať
|
||||
recoveryKey.recover.recoverBtn=Obnov
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Heslo úspešne zresetované
|
||||
recoveryKey.recover.resetSuccess.description=Môžte odomknúť trezor s novým heslom.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
recoveryKey.recover.resetVaultConfigSuccess.message=Konfigurácia peňaženky obnovená
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.message=Hlavný kľuč obnovený
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.description=Teraz môžte odomknúť Váš trezor s heslom.
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
recover.alreadyExists.title=Trezor už existuje
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
recover.invalidSelection.title=Neplatný výber
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub trezora
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
recover.onBoarding.usePassword=Použite heslo
|
||||
recover.onBoarding.intro.ensure=Všetky súbory sú plne synchronizované.
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Konvertovať trezor
|
||||
|
||||
@@ -143,6 +143,7 @@ main.vaultDetail.share=Deli…
|
||||
main.vaultDetail.lockBtn=Zakleni
|
||||
main.vaultDetail.locateEncryptedFileBtn=Poišči šifrirano datoteko
|
||||
### Missing
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
### Error
|
||||
|
||||
@@ -166,6 +167,26 @@ recoveryKey.recover.wrongKey=Ta obnovitveni ključ se ujema z drugim trezorjem
|
||||
recoveryKey.recover.invalidKey=Obnovitveni ključ ni pravilen
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub trezor
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -245,6 +245,7 @@ main.vaultDetail.missing.info=Cryptomator није пронашао сеф на
|
||||
main.vaultDetail.missing.recheck=Провери поново
|
||||
main.vaultDetail.missing.remove=Удаљи са листе сефова…
|
||||
main.vaultDetail.missing.changeLocation=Промени локацију сефа…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Nadogradi sef
|
||||
main.vaultDetail.migratePrompt=Да бисте приступили вашем сефу, он мора бити надограђен на нови формат
|
||||
@@ -298,6 +299,25 @@ recoveryKey.recover.correctKey=Ово је исправан резервни к
|
||||
recoveryKey.printout.heading=Cryptomator Резервни Кључ\n"%s"\n
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -204,6 +204,7 @@ main.vaultDetail.unlockNowBtn=Otključaj sada
|
||||
main.vaultDetail.revealBtn=Otvori disk
|
||||
main.vaultDetail.lockBtn=Zaključaj
|
||||
### Missing
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Nadogradi sef
|
||||
### Error
|
||||
@@ -228,6 +229,25 @@ vaultOptions.masterkey.changePasswordBtn=Promena lozinke
|
||||
### Enter Recovery Key
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -96,6 +96,7 @@ addvault.new.readme.accessLocation.4=Du kan ta bort denna fil.
|
||||
## Existing
|
||||
addvaultwizard.existing.title=Öppna befintligt valv
|
||||
addvaultwizard.existing.instruction=Välj filen "vault.cryptomator" i ditt befintliga valv. Om det endast finns en fil som heter "masterkey.cryptomator", välj den istället.
|
||||
addvaultwizard.existing.restore=Återställ…
|
||||
addvaultwizard.existing.chooseBtn=Välj…
|
||||
addvaultwizard.existing.filePickerTitle=Välj valvfil
|
||||
addvaultwizard.existing.filePickerMimeDesc=Cryptomator valv
|
||||
@@ -127,6 +128,7 @@ unlock.unlockBtn=Lås upp
|
||||
## Select
|
||||
unlock.chooseMasterkey.message=Filen med huvudnyckeln hittades inte
|
||||
unlock.chooseMasterkey.description=Kunde inte hitta Masterkey-filen för detta valv på förväntad plats. Välj filen manuellt.
|
||||
unlock.chooseMasterkey.restoreInstead=Återställ huvudnyckeln istället
|
||||
unlock.chooseMasterkey.filePickerTitle=Välj Masterkey-fil
|
||||
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator huvudnyckel
|
||||
## Success
|
||||
@@ -394,8 +396,9 @@ main.vaultlist.contextMenu.unlockNow=Lås upp nu
|
||||
main.vaultlist.contextMenu.vaultoptions=Visa inställningar för valv
|
||||
main.vaultlist.contextMenu.reveal=Visa enhet
|
||||
main.vaultlist.contextMenu.share=Dela…
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Skapa nytt valv...
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Öppna befintligt valv...
|
||||
main.vaultlist.addVaultBtn.menuItemNew=Skapa nytt valv…
|
||||
main.vaultlist.addVaultBtn.menuItemExisting=Öppna befintligt valv…
|
||||
main.vaultlist.addVaultBtn.menuItemRecover=Återställ befintligt valv…
|
||||
main.vaultlist.showEventsButton.tooltip=Öppna händelsevy
|
||||
##Notificaition
|
||||
main.notification.updateAvailable=Uppdatering tillgänglig.
|
||||
@@ -433,6 +436,9 @@ main.vaultDetail.missing.info=Cryptomator kunde inte hitta någt valv i denna s
|
||||
main.vaultDetail.missing.recheck=Kontrollera igen
|
||||
main.vaultDetail.missing.remove=Ta bort från listan…
|
||||
main.vaultDetail.missing.changeLocation=Ändra valvets plats…
|
||||
### Missing Vault Config
|
||||
main.vaultDetail.missingVaultConfig.info=Valvkonfigurationen saknas.
|
||||
main.vaultDetail.missingVaultConfig.restore=Återställ valvkonfiguration
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Uppgradera valv
|
||||
main.vaultDetail.migratePrompt=Ditt valv behöver uppgraderas till ett nytt format innan du kan använda det
|
||||
@@ -497,6 +503,7 @@ vaultOptions.hub.convertBtn=Konvertera till Lösenordsbaserat Valv
|
||||
recoveryKey.display.title=Visa återställningsnyckel
|
||||
recoveryKey.create.message=Lösenord krävs
|
||||
recoveryKey.create.description=Ange ditt lösenord för att visa återställningsnyckeln för "%s":
|
||||
recoveryKey.recover.description=Ange lösenordet för "%s" för att återställa valvkonfigurationen.
|
||||
recoveryKey.display.description=Använd denna återställningsnyckel för att återställa åtkomst till "%s":
|
||||
recoveryKey.display.StorageHints=Spara den på en säker plats, t.ex:\n • I en lösenordshanterare\n • På ett USB-minne (förvara säkert) \n • Skriv ut på ett papper (förvara säkert)
|
||||
## Reset Password
|
||||
@@ -509,9 +516,41 @@ recoveryKey.recover.invalidKey=Denna återställningsnyckel är ogiltig
|
||||
recoveryKey.printout.heading=Cryptomator återställningsnyckel\n"%s"\n
|
||||
### Reset Password
|
||||
recoveryKey.recover.resetBtn=Återställ
|
||||
recoveryKey.recover.recoverBtn=Återställ
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Lösenord återställt
|
||||
recoveryKey.recover.resetSuccess.description=Du kan låsa upp valvet med det nya lösenordet.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
recoveryKey.recover.resetMasterkeyFileSuccess.description=Nu kan du låsa upp valvet med lösenordet.
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
recover.existing.title=Valvet tillagt
|
||||
recover.existing.message=Valvet har lagts till
|
||||
recover.existing.description=Ditt valv "%s" har lagts till i valvlistan. Ingen återhämtningsprocess var nödvändig.
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
recover.alreadyExists.title=Valvet finns redan
|
||||
recover.alreadyExists.message=Detta valv har redan lagts till
|
||||
recover.alreadyExists.description=Ditt valv "%s" finns redan i din valvlista och lades därför inte till igen.
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
recover.invalidSelection.title=Ogiltigt val
|
||||
recover.invalidSelection.message=Ditt val är inte ett valv
|
||||
recover.invalidSelection.description=Den valda mappen måste vara ett giltigt Cryptomatorvalv.
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hubb valv
|
||||
contactHubVaultOwner.message=Detta valv skapades med Cryptomator Hub
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.title=Konvertera valv
|
||||
|
||||
@@ -365,6 +365,7 @@ main.vaultDetail.missing.info=Cryptomator haikuweza kupata kuba katika njia hii.
|
||||
main.vaultDetail.missing.recheck=Kagua upya
|
||||
main.vaultDetail.missing.remove=Ondoa kutoka kwenye Orodha ya Kuba…
|
||||
main.vaultDetail.missing.changeLocation=Badilisha Mahali pa Kuba…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=Pandisha daraja Kuba
|
||||
main.vaultDetail.migratePrompt=Kuba yako inahitaji kuboreshwa hadi umbizo jipya, kabla ya kuipata
|
||||
@@ -435,6 +436,25 @@ recoveryKey.recover.resetBtn=Weka upya
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=Kuweka upya nenosiri kumefaulu
|
||||
recoveryKey.recover.resetSuccess.description=Unaweza kufungua chumba chako kwa kutumia neno la siri jipya.
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -243,6 +243,7 @@ main.vaultDetail.unlockNowBtn=இப்போது திறக்கவும
|
||||
main.vaultDetail.revealBtn=இயக்ககத்தை வெளிப்படுத்து
|
||||
main.vaultDetail.lockBtn=பூட்டு
|
||||
### Missing
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=பெட்டகத்தை மேம்படுத்து
|
||||
### Error
|
||||
@@ -280,6 +281,25 @@ vaultOptions.masterkey.changePasswordBtn=கடவுச்சொல்லை
|
||||
### Enter Recovery Key
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ preferences.interface.theme.light=కాంతి
|
||||
### Locked
|
||||
### Unlocked
|
||||
### Missing
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
### Error
|
||||
|
||||
@@ -109,6 +110,25 @@ preferences.interface.theme.light=కాంతి
|
||||
### Enter Recovery Key
|
||||
### Reset Password
|
||||
### Recovery Key Password Reset Success
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
|
||||
|
||||
@@ -360,6 +360,7 @@ main.vaultDetail.stats=สถิติของ Vault
|
||||
main.vaultDetail.missing.recheck=ตรวจสอบอีกครั้ง
|
||||
main.vaultDetail.missing.remove=ลบออกจากรายชื่อ Vault…
|
||||
main.vaultDetail.missing.changeLocation=เปลี่ยนที่อยู่ vault…
|
||||
### Missing Vault Config
|
||||
### Needs Migration
|
||||
main.vaultDetail.migrateButton=อัปเกรด Vault
|
||||
### Error
|
||||
@@ -412,6 +413,26 @@ recoveryKey.recover.title=ตั้งรหัสผ่านใหม่
|
||||
recoveryKey.recover.resetBtn=รีเซ็ต
|
||||
### Recovery Key Password Reset Success
|
||||
recoveryKey.recover.resetSuccess.message=รีเซ็ตรหัสผ่านสำเร็จ
|
||||
### Recovery Key Vault Config Reset Success
|
||||
|
||||
# Recover Vault Config File and/or Masterkey
|
||||
##Add Existing Vault without recovery - Dialog
|
||||
|
||||
##Vault Already Exists - Dialog
|
||||
|
||||
##Invalid Selection - Dialog
|
||||
|
||||
## Contact Hub Vault Owner - Dialog
|
||||
contactHubVaultOwner.title=Hub Vault
|
||||
|
||||
##Dialog Title
|
||||
|
||||
## OnBoarding
|
||||
|
||||
###Vault Config Missing
|
||||
###Masterkey Missing
|
||||
|
||||
## Expert Settings
|
||||
|
||||
# Convert Vault
|
||||
convertVault.convert.convertBtn.before=แปลง
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user