Compare commits

..

37 Commits
1.2.0 ... 1.2.5

Author SHA1 Message Date
Sebastian Stenzel
6932fe4ab4 preparing hotfix 1.2.5 2017-06-23 13:38:09 +02:00
Sebastian Stenzel
332890d92b fixes #523 2017-06-23 13:37:45 +02:00
Tobias Hagemann
0c0fb1c4c5 Merge branch 'release/1.2.4' 2017-01-27 11:22:14 +01:00
Tobias Hagemann
ab39bd1667 updated to version 1.2.4 2017-01-27 11:12:45 +01:00
Tobias Hagemann
b41636a208 added japanese localization, updated other localizations 2017-01-26 16:01:49 +01:00
Tobias Hagemann
0902de821a fixed unit test 2017-01-25 17:32:50 +01:00
Tobias Hagemann
8a6265658e fixed range requests 2017-01-25 15:48:21 +01:00
Sebastian Stenzel
28fedafb59 added linux-launcher-* to RPM [ci skip] 2016-12-12 11:39:23 +01:00
Tobias Hagemann
d9bff68555 updated localization stuff
- added title text to upgrade strategy
- added texts for upgrade 4 to 5
- changed most texts to title style capitalization
2016-11-30 17:22:29 +01:00
Tobias Hagemann
cef3a5fc77 Merge branch 'release/1.2.3'
# Conflicts:
#	main/ant-kit/pom.xml
#	main/commons-test/pom.xml
#	main/commons/pom.xml
#	main/filesystem-api/pom.xml
#	main/filesystem-charsets/pom.xml
#	main/filesystem-crypto-integration-tests/pom.xml
#	main/filesystem-crypto/pom.xml
#	main/filesystem-inmemory/pom.xml
#	main/filesystem-invariants-tests/pom.xml
#	main/filesystem-nameshortening/pom.xml
#	main/filesystem-nio/pom.xml
#	main/filesystem-stats/pom.xml
#	main/frontend-api/pom.xml
#	main/frontend-webdav/pom.xml
#	main/jacoco-report/pom.xml
#	main/keychain/pom.xml
#	main/pom.xml
#	main/uber-jar/pom.xml
#	main/ui/pom.xml
2016-11-29 23:03:26 +01:00
Tobias Hagemann
9956f43fd9 updated to version 1.2.3 2016-11-29 22:24:26 +01:00
Tobias Hagemann
2b84593bde updated localization 2016-11-29 22:16:46 +01:00
Markus Kreusch
4e728fd387 Merge branch 'feature/issue-363' into develop 2016-11-29 15:21:48 +01:00
Tobias Hagemann
438ade1106 fixes #382 2016-11-27 14:28:44 +01:00
Sebastian Stenzel
fe54f4ec66 Update README.md
As suggested by @tallesh in #135
2016-11-27 10:14:34 +01:00
Markus Kreusch
fe86b4c593 Implemented #363 2016-11-14 22:26:55 +01:00
Markus Kreusch
a583afeb60 Merge branch 'feature/issue-393' into develop 2016-11-14 15:08:31 +01:00
Sebastian Stenzel
a585d3cf16 cherry picked from bac1d6f [ci skip] 2016-11-12 17:04:58 +01:00
Sebastian Stenzel
3db757193e Merge branch 'hotfix/1.2.2' 2016-11-12 17:02:04 +01:00
Sebastian Stenzel
bac1d6fd83 Updated siv-mode to 1.2.0 to be consistent with CryptoLib 2016-11-12 16:41:26 +01:00
Sebastian Stenzel
39ee8a9cde coverity issue 151831 2016-11-11 17:11:21 +01:00
Markus Kreusch
1263b3af81 fixed 'a' really bad thing in the last commit 2016-11-11 09:56:45 +01:00
Markus Kreusch
dafa29d8a3 Implemented #393 2016-11-10 22:58:45 +01:00
Sebastian Stenzel
2bc6fe89ad Merge branch 'release/1.2.1' 2016-11-10 15:23:11 +01:00
Sebastian Stenzel
8439216233 Updated version to 1.2.1 2016-11-10 15:13:28 +01:00
Sebastian Stenzel
aab616d184 Updated CryptoLib, hopefully fixes #373 2016-11-10 15:11:04 +01:00
Sebastian Stenzel
70c3a38c49 invoking UI methods on UI thread, might solve #351 2016-11-10 14:07:37 +01:00
Sebastian Stenzel
c64294ac3e Added chinese localizations, updated dutch localization 2016-11-10 13:41:09 +01:00
Markus Kreusch
82330db871 Additional logging for vault version upgrade 2016-11-09 15:54:10 +01:00
Sebastian Stenzel
c54a721f9a Merge pull request #385 from IAMtheIAM/patch-1
Update README.md
2016-11-06 21:59:16 +01:00
Sebastian Stenzel
355bbb5459 Merge branch 'develop' into patch-1 2016-11-06 21:53:28 +01:00
IAMtheIAM
63daa0f121 Update README.md
Update Readme with accurate info regarding v1.2.0
2016-11-06 03:56:56 -07:00
IAMtheIAM
50885d5c7c Update README.md 2016-11-05 16:51:16 -07:00
IAMtheIAM
4d68818ec5 Update README.md
Update features
2016-11-05 14:00:32 -07:00
IAMtheIAM
6fb20dd509 Update README.md
Added info about obfuscating file size and folder structure (two very important features that should be known!)
2016-11-05 13:54:39 -07:00
Sebastian Stenzel
2bb87dfa96 Merge branch 'release/1.2.0' into develop
# Conflicts:
#	main/ant-kit/pom.xml
#	main/commons-test/pom.xml
#	main/commons/pom.xml
#	main/filesystem-api/pom.xml
#	main/filesystem-charsets/pom.xml
#	main/filesystem-crypto-integration-tests/pom.xml
#	main/filesystem-crypto/pom.xml
#	main/filesystem-inmemory/pom.xml
#	main/filesystem-invariants-tests/pom.xml
#	main/filesystem-nameshortening/pom.xml
#	main/filesystem-nio/pom.xml
#	main/filesystem-stats/pom.xml
#	main/frontend-api/pom.xml
#	main/frontend-webdav/pom.xml
#	main/jacoco-report/pom.xml
#	main/keychain/pom.xml
#	main/pom.xml
#	main/uber-jar/pom.xml
#	main/ui/pom.xml
2016-09-19 15:12:24 +02:00
Sebastian Stenzel
2fa04d7b7c increased version to 1.3.0-SNAPSHOT
[ci skip]
2016-09-15 13:35:22 +02:00
75 changed files with 1229 additions and 430 deletions

View File

@@ -19,7 +19,8 @@ Download native binaries of Cryptomator on [cryptomator.org](https://cryptomator
- Client-side: No accounts, no data shared with any online service
- Totally transparent: Just work on the virtual drive as if it were a USB flash drive
- AES encryption with 256-bit key length
- Filenames get encrypted, too
- File names get encrypted
- Folder structure gets obfuscated
- Use as many vaults in your Dropbox as you want, each having individual passwords
### Privacy
@@ -52,9 +53,11 @@ For more information on the security details visit [cryptomator.org](https://cry
```
cd main
mvn clean install
mvn clean install -Prelease
```
An executable jar file will be created inside `main/uber-jar/target`.
## Contributing to Cryptomator
Please read our [contribution guide](https://github.com/cryptomator/cryptomator/blob/master/CONTRIBUTING.md), if you would like to report a bug, ask a question or help us with coding.

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>ant-kit</artifactId>
<packaging>pom</packaging>

View File

@@ -32,6 +32,7 @@
<fx:property name="cryptomator.logPath" value="~/.Cryptomator/cryptomator.log" />
<fx:property name="cryptomator.upgradeLogPath" value="~/.Cryptomator/upgrade.log" />
<fx:property name="cryptomator.settingsPath" value="~/.Cryptomator/settings.json" />
<fx:jvmarg value="-Xss2m"/>
<fx:jvmarg value="-Xmx512m"/>
</fx:platform>
<fx:resources>
@@ -55,11 +56,13 @@
<fx:property name="cryptomator.logPath" value="~/.Cryptomator/cryptomator.log" />
<fx:property name="cryptomator.upgradeLogPath" value="~/.Cryptomator/upgrade.log" />
<fx:property name="cryptomator.settingsPath" value="~/.Cryptomator/settings.json" />
<fx:jvmarg value="-Xss2m"/>
<fx:jvmarg value="-Xmx512m"/>
</fx:platform>
<fx:resources>
<fx:fileset dir="antbuild" type="jar" includes="Cryptomator-${project.version}.jar" />
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="ui-${project.version}.jar"/>
<fx:fileset dir="fixed-binaries" type="data" includes="linux-launcher-*" arch=""/>
</fx:resources>
<fx:permissions elevated="false" />
<fx:preferences install="true" />

View File

@@ -10,7 +10,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>commons-test</artifactId>
<name>Cryptomator common test dependencies</name>

View File

@@ -10,7 +10,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>commons</artifactId>
<name>Cryptomator common</name>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>filesystem-api</artifactId>
<name>Cryptomator filesystem: API</name>

View File

@@ -12,7 +12,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>filesystem-charsets</artifactId>
<name>Cryptomator filesystem: Charset compatibility layer</name>

View File

@@ -40,9 +40,9 @@ class NormalizedNameFolder extends DelegatingFolder<NormalizedNameFolder, Normal
NormalizedNameFile nfcFile = super.file(nfcName);
NormalizedNameFile nfdFile = super.file(nfdName);
if (!nfcName.equals(nfdName) && nfcFile.exists() && nfdFile.exists()) {
LOG.warn("Ambiguous file names \"" + nfcName + "\" (NFC) vs. \"" + nfdName + "\" (NFD). Both files exist. Using \"" + nfcName + "\" (NFC).");
LOG.debug("Ambiguous file names \"" + nfcName + "\" (NFC) vs. \"" + nfdName + "\" (NFD). Both files exist. Using \"" + nfcName + "\" (NFC).");
} else if (!nfcName.equals(nfdName) && !nfcFile.exists() && nfdFile.exists()) {
LOG.info("Moving file from \"" + nfcName + "\" (NFD) to \"" + nfdName + "\" (NFC).");
LOG.debug("Moving file from \"" + nfcName + "\" (NFD) to \"" + nfdName + "\" (NFC).");
nfdFile.moveTo(nfcFile);
}
return nfcFile;
@@ -60,9 +60,9 @@ class NormalizedNameFolder extends DelegatingFolder<NormalizedNameFolder, Normal
NormalizedNameFolder nfcFolder = super.folder(nfcName);
NormalizedNameFolder nfdFolder = super.folder(nfdName);
if (!nfcName.equals(nfdName) && nfcFolder.exists() && nfdFolder.exists()) {
LOG.warn("Ambiguous folder names \"" + nfcName + "\" (NFC) vs. \"" + nfdName + "\" (NFD). Both files exist. Using \"" + nfcName + "\" (NFC).");
LOG.debug("Ambiguous folder names \"" + nfcName + "\" (NFC) vs. \"" + nfdName + "\" (NFD). Both files exist. Using \"" + nfcName + "\" (NFC).");
} else if (!nfcName.equals(nfdName) && !nfcFolder.exists() && nfdFolder.exists()) {
LOG.info("Moving folder from \"" + nfcName + "\" (NFD) to \"" + nfdName + "\" (NFC).");
LOG.debug("Moving folder from \"" + nfcName + "\" (NFD) to \"" + nfdName + "\" (NFC).");
nfdFolder.moveTo(nfcFolder);
}
return nfcFolder;

View File

@@ -12,7 +12,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>filesystem-crypto-integration-tests</artifactId>
<name>Cryptomator filesystem: Encryption layer tests</name>

View File

@@ -12,14 +12,14 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>filesystem-crypto</artifactId>
<name>Cryptomator filesystem: Encryption layer</name>
<properties>
<bouncycastle.version>1.51</bouncycastle.version>
<sivmode.version>1.0.8</sivmode.version>
<sivmode.version>1.2.0</sivmode.version>
</properties>
<dependencies>

View File

@@ -14,7 +14,6 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.regex.Pattern;
import javax.crypto.AEADBadTagException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
@@ -23,6 +22,7 @@ import org.apache.commons.codec.binary.BaseNCodec;
import org.cryptomator.crypto.engine.AuthenticationFailedException;
import org.cryptomator.crypto.engine.FilenameCryptor;
import org.cryptomator.siv.SivMode;
import org.cryptomator.siv.UnauthenticCiphertextException;
class FilenameCryptorImpl implements FilenameCryptor {
@@ -71,7 +71,7 @@ class FilenameCryptorImpl implements FilenameCryptor {
try {
final byte[] cleartextBytes = AES_SIV.get().decrypt(encryptionKey, macKey, encryptedBytes, associatedData);
return new String(cleartextBytes, UTF_8);
} catch (AEADBadTagException | IllegalBlockSizeException e) {
} catch (UnauthenticCiphertextException | IllegalBlockSizeException e) {
throw new AuthenticationFailedException("Invalid ciphertext.", e);
}
}

View File

@@ -68,7 +68,7 @@ final class ConflictResolver {
String alternativeCiphertext = nameEncryptor.apply(alternativeCleartext).get();
alternativeFile = folder.file(isDirectory ? DIR_PREFIX + alternativeCiphertext : alternativeCiphertext);
} while (alternativeFile.exists());
LOG.info("Detected conflict {}:\n{}\n{}", conflictId, canonicalFile, conflictingFile);
LOG.debug("Detected conflict {}:\n{}\n{}", conflictId, canonicalFile, conflictingFile);
conflictingFile.moveTo(alternativeFile);
return alternativeFile;
}

View File

@@ -12,7 +12,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>filesystem-inmemory</artifactId>
<name>Cryptomator filesystem: In-memory mock</name>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>filesystem-invariants-tests</artifactId>
<name>Cryptomator filesystem: Invariants tests</name>

View File

@@ -12,7 +12,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>filesystem-nameshortening</artifactId>
<name>Cryptomator filesystem: Name shortening layer</name>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>filesystem-nio</artifactId>
<name>Cryptomator filesystem: NIO-based physical layer</name>

View File

@@ -12,7 +12,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>filesystem-stats</artifactId>
<name>Cryptomator filesystem: Throughput statistics</name>

View File

@@ -12,7 +12,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>frontend-api</artifactId>
<name>Cryptomator frontend: API</name>

View File

@@ -12,7 +12,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>frontend-webdav</artifactId>
<name>Cryptomator frontend: WebDAV frontend</name>

View File

@@ -18,6 +18,10 @@ class ContextPaths {
return format("/%s/%s", id, name);
}
public static String removeFrontendId(String path) {
return path.replaceAll("/" + FRONTEND_ID_PATTERN + "/", "/[...]/");
}
public static Optional<FrontendId> extractFrontendId(String path) {
Matcher matcher = SERVLET_PATH_WITH_FRONTEND_ID_PATTERN.matcher(path);
if (matcher.matches()) {

View File

@@ -0,0 +1,17 @@
package org.cryptomator.frontend.webdav;
import org.eclipse.jetty.server.HandlerContainer;
import org.eclipse.jetty.servlet.ServletContextHandler;
class FontendIdHidingServletContextHandler extends ServletContextHandler {
public FontendIdHidingServletContextHandler(HandlerContainer parent, String contextPath, int options) {
super(parent, contextPath, options);
}
@Override
public String toString() {
return ContextPaths.removeFrontendId(super.toString());
}
}

View File

@@ -8,8 +8,6 @@
*******************************************************************************/
package org.cryptomator.frontend.webdav;
import static java.lang.String.format;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
@@ -110,7 +108,7 @@ public class WebDavServer implements FrontendFactory {
@Override
public Frontend create(Folder root, FrontendId id, String name) throws FrontendCreationFailedException {
String contextPath = format("/%s/%s", id, name);
String contextPath = ContextPaths.from(id, name);
final URI uri;
try {
uri = new URI("http", null, "localhost", getPort(), contextPath, null, null);
@@ -118,10 +116,10 @@ public class WebDavServer implements FrontendFactory {
throw new IllegalStateException(e);
}
final ServletContextHandler handler = addServlet(root, uri);
LOG.info("Servlet available under " + uri);
LOG.info("Servlet available under " + ContextPaths.removeFrontendId(uri.toString()));
return new WebDavFrontend(webdavMounterProvider, handler, uri);
}
public void setValidFrontendIds(Collection<FrontendId> validFrontendIds) {
tarpit.setValidFrontendIds(validFrontendIds);
}

View File

@@ -35,9 +35,10 @@ import org.eclipse.jetty.servlet.ServletHolder;
class WebDavServletContextFactory {
private static final String WILDCARD = "/*";
@Inject
public WebDavServletContextFactory() {}
public WebDavServletContextFactory() {
}
/**
* Creates a new Jetty ServletContextHandler, that can be be added to a servletCollection as follows:
@@ -63,7 +64,7 @@ class WebDavServletContextFactory {
}
};
final String contextPath = StringUtils.removeEnd(contextRoot.getPath(), "/");
final ServletContextHandler servletContext = new ServletContextHandler(null, contextPath, ServletContextHandler.SESSIONS);
final ServletContextHandler servletContext = new FontendIdHidingServletContextHandler(null, contextPath, ServletContextHandler.SESSIONS);
final ServletHolder servletHolder = new ServletHolder(contextPath, new WebDavServlet(contextRoot, root));
servletContext.addServlet(servletHolder, WILDCARD);
servletContext.addFilter(LoopbackFilter.class, WILDCARD, EnumSet.of(DispatcherType.REQUEST));

View File

@@ -16,7 +16,6 @@ import java.util.Objects;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavServletResponse;
import org.apache.jackrabbit.webdav.DavSession;
import org.apache.jackrabbit.webdav.io.OutputContext;
@@ -36,7 +35,7 @@ class DavFileWithRange extends DavFile {
private final Pair<String, String> requestRange;
public DavFileWithRange(FilesystemResourceFactory factory, LockManager lockManager, DavSession session, FileLocator node, Pair<String, String> requestRange) throws DavException {
public DavFileWithRange(FilesystemResourceFactory factory, LockManager lockManager, DavSession session, FileLocator node, Pair<String, String> requestRange) {
super(factory, lockManager, session, node);
this.requestRange = Objects.requireNonNull(requestRange);
}
@@ -48,18 +47,18 @@ class DavFileWithRange extends DavFile {
return;
}
final long contentLength = node.size();
final Pair<Long, Long> range = getEffectiveRange(contentLength);
if (range.getLeft() < 0 || range.getLeft() > range.getRight() || range.getRight() > contentLength) {
outputContext.setProperty(HttpHeader.CONTENT_RANGE.asString(), "bytes */" + contentLength);
throw new UncheckedDavException(DavServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE, "Valid Range would be in [0, " + contentLength + "]");
}
final Long rangeLength = range.getRight() - range.getLeft() + 1;
outputContext.setContentLength(rangeLength);
outputContext.setProperty(HttpHeader.CONTENT_RANGE.asString(), contentRangeResponseHeader(range.getLeft(), range.getRight(), contentLength));
outputContext.setContentType(CONTENT_TYPE_VALUE);
outputContext.setProperty(CONTENT_DISPOSITION_HEADER, CONTENT_DISPOSITION_VALUE);
outputContext.setProperty(X_CONTENT_TYPE_OPTIONS_HEADER, X_CONTENT_TYPE_OPTIONS_VALUE);
try (ReadableFile src = node.openReadable(); OutputStream out = outputContext.getOutputStream()) {
final Pair<Long, Long> range = getEffectiveRange(contentLength);
if (range.getLeft() < 0 || range.getLeft() > range.getRight() || range.getRight() > contentLength) {
outputContext.setProperty(HttpHeader.CONTENT_RANGE.asString(), "bytes */" + contentLength);
throw new UncheckedDavException(DavServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE, "Valid Range would be in [0, " + contentLength + "]");
}
final Long rangeLength = range.getRight() - range.getLeft() + 1;
outputContext.setContentLength(rangeLength);
outputContext.setProperty(HttpHeader.CONTENT_RANGE.asString(), contentRangeResponseHeader(range.getLeft(), range.getRight(), contentLength));
outputContext.setContentType(CONTENT_TYPE_VALUE);
outputContext.setProperty(CONTENT_DISPOSITION_HEADER, CONTENT_DISPOSITION_VALUE);
outputContext.setProperty(X_CONTENT_TYPE_OPTIONS_HEADER, X_CONTENT_TYPE_OPTIONS_VALUE);
src.position(range.getLeft());
InputStream limitedIn = ByteStreams.limit(Channels.newInputStream(src), rangeLength);
ByteStreams.copy(limitedIn, out);

View File

@@ -1,50 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 Sebastian Stenzel and others.
* This file is licensed under the terms of the MIT license.
* See the LICENSE.txt file for more info.
*
* Contributors:
* Sebastian Stenzel - initial API and implementation
*******************************************************************************/
package org.cryptomator.frontend.webdav.jackrabbitservlet;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.channels.Channels;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavSession;
import org.apache.jackrabbit.webdav.io.OutputContext;
import org.apache.jackrabbit.webdav.lock.LockManager;
import org.cryptomator.filesystem.ReadableFile;
import org.cryptomator.filesystem.jackrabbit.FileLocator;
import org.eclipse.jetty.http.HttpHeader;
import com.google.common.io.ByteStreams;
/**
* Sends the full file in reaction to an unsatisfiable range.
*
* @see {@link https://tools.ietf.org/html/rfc7233#section-4.2}
*/
class DavFileWithUnsatisfiableRange extends DavFile {
public DavFileWithUnsatisfiableRange(FilesystemResourceFactory factory, LockManager lockManager, DavSession session, FileLocator node) throws DavException {
super(factory, lockManager, session, node);
}
@Override
public void spool(OutputContext outputContext) throws IOException {
outputContext.setModificationTime(node.lastModified().toEpochMilli());
if (!outputContext.hasStream()) {
return;
}
final long contentLength = node.size();
outputContext.setContentLength(contentLength);
outputContext.setProperty(HttpHeader.CONTENT_RANGE.asString(), "bytes */" + contentLength);
try (ReadableFile src = node.openReadable(); OutputStream out = outputContext.getOutputStream()) {
ByteStreams.copy(src, Channels.newChannel(out));
}
}
}

View File

@@ -85,17 +85,11 @@ class FilesystemResourceFactory implements DavResourceFactory {
final String rangeHeader = request.getHeader(HttpHeader.RANGE.asString());
try {
// 206 for ranged resources:
final Pair<String, String> parsedRange = parseRangeRequestHeader(rangeHeader);
final Pair<String, String> parsedRange = parseSingleByteRange(rangeHeader);
response.setStatus(DavServletResponse.SC_PARTIAL_CONTENT);
return new DavFileWithRange(this, lockManager, session, file, parsedRange);
} catch (DavException ex) {
if (ex.getErrorCode() == DavServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE) {
// 416 for unsatisfiable ranges:
response.setStatus(DavServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return new DavFileWithUnsatisfiableRange(this, lockManager, session, file);
} else {
throw new DavException(ex.getErrorCode(), ex);
}
} catch (NotASingleByteRangeException ex) {
return createFile(file, session);
}
}
@@ -108,17 +102,18 @@ class FilesystemResourceFactory implements DavResourceFactory {
* </code>
*
* @return Tuple of lower and upper range.
* @throws DavException HTTP statuscode 400 for malformed requests. 416 if requested range is not supported.
* @throws DavException HTTP statuscode 400 for malformed requests.
* @throws NotASingleByteRangeException Indicating a range that is not supported by this server, i.e. range header should be ignored.
*/
private Pair<String, String> parseRangeRequestHeader(String rangeHeader) throws DavException {
private Pair<String, String> parseSingleByteRange(String rangeHeader) throws DavException, NotASingleByteRangeException {
assert rangeHeader != null;
if (!rangeHeader.startsWith(RANGE_BYTE_PREFIX)) {
throw new DavException(DavServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
throw new NotASingleByteRangeException();
}
final String byteRangeSet = StringUtils.removeStartIgnoreCase(rangeHeader, RANGE_BYTE_PREFIX);
final String[] byteRanges = StringUtils.split(byteRangeSet, RANGE_SET_SEP);
if (byteRanges.length != 1) {
throw new DavException(DavServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
throw new NotASingleByteRangeException();
}
final String byteRange = byteRanges[0];
final String[] bytePos = StringUtils.splitPreserveAllTokens(byteRange, RANGE_SEP);
@@ -146,4 +141,7 @@ class FilesystemResourceFactory implements DavResourceFactory {
}
}
private static class NotASingleByteRangeException extends Exception {
}
}

View File

@@ -376,7 +376,7 @@ public class WebDavServerTest {
final HttpMethod getMethod = new GetMethod(servletRoot + "/foo.txt");
getMethod.addRequestHeader("Range", "chunks=1-2");
final int statusCode = client.executeMethod(getMethod);
Assert.assertEquals(416, statusCode);
Assert.assertEquals(200, statusCode);
Assert.assertArrayEquals(testContent, getMethod.getResponseBody());
getMethod.releaseConnection();
}

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>jacoco-report</artifactId>
<name>Cryptomator Code Coverage Report</name>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>keychain</artifactId>
<name>System Keychain Access</name>

View File

@@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
<packaging>pom</packaging>
<name>Cryptomator</name>
@@ -27,7 +27,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- dependency versions -->
<cryptomator.cryptolib.version>1.0.2</cryptomator.cryptolib.version>
<cryptomator.cryptolib.version>1.0.7</cryptomator.cryptolib.version>
<cryptomator.jni.version>1.0.0</cryptomator.jni.version>
<log4j.version>2.1</log4j.version>
<slf4j.version>1.7.7</slf4j.version>

View File

@@ -12,7 +12,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>uber-jar</artifactId>
<packaging>pom</packaging>

View File

@@ -12,7 +12,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.2.0</version>
<version>1.2.5</version>
</parent>
<artifactId>ui</artifactId>
<name>Cryptomator GUI</name>

View File

@@ -20,6 +20,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.ui.util.ApplicationVersion;
import org.cryptomator.ui.util.SingleInstanceManager;
import org.cryptomator.ui.util.SingleInstanceManager.RemoteInstance;
import org.eclipse.jetty.util.ConcurrentHashSet;
@@ -33,63 +34,62 @@ public class Cryptomator {
public static final CompletableFuture<Consumer<File>> OPEN_FILE_HANDLER = new CompletableFuture<>();
private static final Logger LOG = LoggerFactory.getLogger(Cryptomator.class);
private static final Set<Runnable> SHUTDOWN_TASKS = new ConcurrentHashSet<>();
private static final CleanShutdownPerformer CLEAN_SHUTDOWN_PERFORMER = new CleanShutdownPerformer();
public static void main(String[] args) {
String cryptomatorVersion = Optional.ofNullable(Cryptomator.class.getPackage().getImplementationVersion()).orElse("SNAPSHOT");
LOG.info("Starting Cryptomator {} on {} {} ({})", cryptomatorVersion, SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
LOG.info("Starting Cryptomator {} on {} {} ({})", ApplicationVersion.orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
if (SystemUtils.IS_OS_MAC_OSX) {
/*
* On OSX we're in an awkward position. We need to register a handler in the main thread of this application. However, we can't
* even pass objects to the application, so we're forced to use a static CompletableFuture for the handler, which actually opens
* the file in the application.
*
* Code taken from https://github.com/axet/desktop/blob/master/src/main/java/com/github/axet/desktop/os/mac/AppleHandlers.java
*/
try {
final Class<?> applicationClass = Class.forName("com.apple.eawt.Application");
final Class<?> openFilesHandlerClass = Class.forName("com.apple.eawt.OpenFilesHandler");
final Method getApplication = applicationClass.getMethod("getApplication");
final Object application = getApplication.invoke(null);
final Method setOpenFileHandler = applicationClass.getMethod("setOpenFileHandler", openFilesHandlerClass);
final ClassLoader openFilesHandlerClassLoader = openFilesHandlerClass.getClassLoader();
final OpenFilesHandlerClassHandler openFilesHandlerHandler = new OpenFilesHandlerClassHandler();
final Object openFilesHandlerObject = Proxy.newProxyInstance(openFilesHandlerClassLoader, new Class<?>[] {openFilesHandlerClass}, openFilesHandlerHandler);
setOpenFileHandler.invoke(application, openFilesHandlerObject);
} catch (ReflectiveOperationException | RuntimeException e) {
// Since we're trying to call OS-specific code, we'll just have
// to hope for the best.
LOG.error("exception adding OSX file open handler", e);
}
addOsxFileOpenHandler();
}
/*
* Perform certain things on VM termination.
*/
Runtime.getRuntime().addShutdownHook(CLEAN_SHUTDOWN_PERFORMER);
new CleanShutdownPerformer().registerShutdownHook();
/*
* Before starting the application, we check if there is already an instance running on this computer. If so, we send our command
* line arguments to that instance and quit.
*/
final Optional<RemoteInstance> remoteInstance = SingleInstanceManager.getRemoteInstance(MainApplication.APPLICATION_KEY);
if (remoteInstance.isPresent()) {
try (RemoteInstance instance = remoteInstance.get()) {
LOG.info("An instance of Cryptomator is already running at {}.", instance.getRemotePort());
for (int i = 0; i < args.length; i++) {
remoteInstance.get().sendMessage(args[i], 100);
}
} catch (Exception e) {
LOG.error("Error forwarding arguments to remote instance", e);
}
final Optional<RemoteInstance> runningInstance = SingleInstanceManager.getRemoteInstance(MainApplication.APPLICATION_KEY);
if (runningInstance.isPresent()) {
sendArgsToRunningInstance(args, runningInstance);
} else {
Application.launch(MainApplication.class, args);
}
}
private static void addOsxFileOpenHandler() {
/*
* On OSX we're in an awkward position. We need to register a handler in the main thread of this application. However, we can't
* even pass objects to the application, so we're forced to use a static CompletableFuture for the handler, which actually opens
* the file in the application.
*
* Code taken from https://github.com/axet/desktop/blob/master/src/main/java/com/github/axet/desktop/os/mac/AppleHandlers.java
*/
try {
final Class<?> applicationClass = Class.forName("com.apple.eawt.Application");
final Class<?> openFilesHandlerClass = Class.forName("com.apple.eawt.OpenFilesHandler");
final Method getApplication = applicationClass.getMethod("getApplication");
final Object application = getApplication.invoke(null);
final Method setOpenFileHandler = applicationClass.getMethod("setOpenFileHandler", openFilesHandlerClass);
final ClassLoader openFilesHandlerClassLoader = openFilesHandlerClass.getClassLoader();
final OpenFilesHandlerClassHandler openFilesHandlerHandler = new OpenFilesHandlerClassHandler();
final Object openFilesHandlerObject = Proxy.newProxyInstance(openFilesHandlerClassLoader, new Class<?>[] {openFilesHandlerClass}, openFilesHandlerHandler);
setOpenFileHandler.invoke(application, openFilesHandlerObject);
} catch (ReflectiveOperationException | RuntimeException e) {
// Since we're trying to call OS-specific code, we'll just have
// to hope for the best.
LOG.error("exception adding OSX file open handler", e);
}
}
private static void sendArgsToRunningInstance(String[] args, final Optional<RemoteInstance> remoteInstance) {
try (RemoteInstance instance = remoteInstance.get()) {
LOG.info("An instance of Cryptomator is already running at {}.", instance.getRemotePort());
for (int i = 0; i < args.length; i++) {
remoteInstance.get().sendMessage(args[i], 100);
}
} catch (Exception e) {
LOG.error("Error forwarding arguments to remote instance", e);
}
}
public static void addShutdownTask(Runnable r) {
SHUTDOWN_TASKS.add(r);
}
@@ -111,6 +111,10 @@ public class Cryptomator {
});
SHUTDOWN_TASKS.clear();
}
public void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook(this);
}
}
private static void handleOpenFileRequest(File file) {

View File

@@ -37,6 +37,8 @@ interface CryptomatorComponent {
ExitUtil exitUtil();
DebugMode debugMode();
Optional<MacFunctions> nativeMacFunctions();
}

View File

@@ -0,0 +1,75 @@
package org.cryptomator.ui;
import static java.util.Arrays.asList;
import static org.apache.logging.log4j.LogManager.ROOT_LOGGER_NAME;
import java.util.Collection;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.cryptomator.ui.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class DebugMode {
private static final Logger LOG = LoggerFactory.getLogger(DebugMode.class);
private static final Collection<LoggerUpgrade> LOGGER_UPGRADES = asList( //
loggerUpgrade(ROOT_LOGGER_NAME, Level.INFO), //
loggerUpgrade("org.cryptomator", Level.TRACE), //
loggerUpgrade("org.eclipse.jetty.server.Server", Level.DEBUG) //
);
private final Settings settings;
@Inject
public DebugMode(Settings settings) {
this.settings = settings;
}
public void initialize() {
if (settings.getDebugMode()) {
enable();
LOG.debug("Debug mode initialized");
}
}
private void enable() {
LoggerContext context = (LoggerContext) LogManager.getContext(false);
Configuration config = context.getConfiguration();
LOGGER_UPGRADES.forEach(loggerUpgrade -> loggerUpgrade.execute(config));
context.updateLoggers();
}
private static LoggerUpgrade loggerUpgrade(String loggerName, Level minLevel) {
return new LoggerUpgrade(loggerName, minLevel);
}
private static class LoggerUpgrade {
private final Level level;
private final String loggerName;
public LoggerUpgrade(String loggerName, Level minLevel) {
this.loggerName = loggerName;
this.level = minLevel;
}
public void execute(Configuration config) {
LoggerConfig loggerConfig = config.getLoggerConfig(loggerName);
if (loggerConfig.getLevel().isMoreSpecificThan(level)) {
loggerConfig.setLevel(level);
}
}
}
}

View File

@@ -43,18 +43,46 @@ public class MainApplication extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
LOG.info("JavaFX application started");
final CryptomatorComponent comp;
CryptomatorComponent comp = createCryptomatorComponent(primaryStage);
MainController mainCtrl = comp.mainController();
closer = comp.deferredCloser();
comp.debugMode().initialize();
setupFXMLClassLoader();
setupStylesheets();
initializeStage(primaryStage, mainCtrl);
showWindow(primaryStage);
registerExitHandler(comp);
openFilesRequestedDuringStartup(primaryStage, mainCtrl);
registerApplicationToProcessOpenFileRequests(primaryStage, comp, mainCtrl);
}
@Override
public void stop() {
try {
comp = DaggerCryptomatorComponent.builder() //
closer.close();
} catch (ExecutionException e) {
LOG.error("Error closing ressources", e);
}
}
private CryptomatorComponent createCryptomatorComponent(Stage primaryStage) {
try {
return DaggerCryptomatorComponent.builder() //
.cryptomatorModule(new CryptomatorModule(this, primaryStage)) //
.secureRandomModule(new SecureRandomModule(SecureRandom.getInstanceStrong())) //
.build();
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("Every implementation of the Java platform is required to support at least one strong SecureRandom implementation.", e);
}
final MainController mainCtrl = comp.mainController();
closer = comp.deferredCloser();
}
private void setupFXMLClassLoader() {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
FXMLLoader.setDefaultClassLoader(contextClassLoader);
Platform.runLater(() -> {
@@ -66,35 +94,55 @@ public class MainApplication extends Application {
Thread.currentThread().setContextClassLoader(contextClassLoader);
}
});
}
// Set stylesheets and initialize stage:
private void setupStylesheets() {
Font.loadFont(getClass().getResourceAsStream("/css/ionicons.ttf"), 12.0);
chooseNativeStylesheet();
}
private void initializeStage(Stage primaryStage, MainController mainCtrl) {
mainCtrl.initStage(primaryStage);
primaryStage.titleProperty().bind(mainCtrl.windowTitle());
primaryStage.setResizable(false);
if (SystemUtils.IS_OS_WINDOWS) {
primaryStage.getIcons().add(new Image(MainApplication.class.getResourceAsStream("/window_icon.png")));
}
}
// show window and start observing its focus:
private void showWindow(Stage primaryStage) {
primaryStage.show();
ActiveWindowStyleSupport.startObservingFocus(primaryStage);
comp.exitUtil().initExitHandler(this::quit);
}
// open files, if requested during startup:
private void registerExitHandler(CryptomatorComponent comp) {
comp.exitUtil().initExitHandler(this::quit);
}
private void openFilesRequestedDuringStartup(Stage primaryStage, final MainController mainCtrl) {
for (String arg : getParameters().getUnnamed()) {
handleCommandLineArg(arg, primaryStage, mainCtrl);
}
if (SystemUtils.IS_OS_MAC_OSX) {
Cryptomator.OPEN_FILE_HANDLER.complete(file -> handleCommandLineArg(file.getAbsolutePath(), primaryStage, mainCtrl));
}
}
// register this application instance as primary application, that other instances can send open file requests to:
private void registerApplicationToProcessOpenFileRequests(Stage primaryStage, final CryptomatorComponent comp, final MainController mainCtrl) throws IOException {
LocalInstance cryptomatorGuiInstance = closer.closeLater(SingleInstanceManager.startLocalInstance(APPLICATION_KEY, comp.executorService()), LocalInstance::close).get().get();
cryptomatorGuiInstance.registerListener(arg -> handleCommandLineArg(arg, primaryStage, mainCtrl));
}
private void chooseNativeStylesheet() {
if (SystemUtils.IS_OS_MAC_OSX) {
setUserAgentStylesheet(getClass().getResource("/css/mac_theme.css").toString());
} else if (SystemUtils.IS_OS_LINUX) {
setUserAgentStylesheet(getClass().getResource("/css/linux_theme.css").toString());
} else if (SystemUtils.IS_OS_WINDOWS) {
setUserAgentStylesheet(getClass().getResource("/css/win_theme.css").toString());
}
}
private void handleCommandLineArg(String arg, Stage primaryStage, MainController mainCtrl) {
// find correct location:
final Path path = FileSystems.getDefault().getPath(arg);
@@ -118,16 +166,6 @@ public class MainApplication extends Application {
});
}
private void chooseNativeStylesheet() {
if (SystemUtils.IS_OS_MAC_OSX) {
setUserAgentStylesheet(getClass().getResource("/css/mac_theme.css").toString());
} else if (SystemUtils.IS_OS_LINUX) {
setUserAgentStylesheet(getClass().getResource("/css/linux_theme.css").toString());
} else if (SystemUtils.IS_OS_WINDOWS) {
setUserAgentStylesheet(getClass().getResource("/css/win_theme.css").toString());
}
}
private void quit() {
Platform.runLater(() -> {
stop();
@@ -136,13 +174,4 @@ public class MainApplication extends Application {
});
}
@Override
public void stop() {
try {
closer.close();
} catch (ExecutionException e) {
LOG.error("Error closing ressources", e);
}
}
}

View File

@@ -59,6 +59,9 @@ public class SettingsController extends LocalizedFXMLViewController {
@FXML
private ChoiceBox<String> prefGvfsScheme;
@FXML
private CheckBox debugModeCheckbox;
@Override
public void initialize() {
checkForUpdatesCheckbox.setDisable(areUpdatesManagedExternally());
@@ -74,11 +77,13 @@ public class SettingsController extends LocalizedFXMLViewController {
prefGvfsScheme.getItems().add("dav");
prefGvfsScheme.getItems().add("webdav");
prefGvfsScheme.setValue(settings.getPreferredGvfsScheme());
debugModeCheckbox.setSelected(settings.getDebugMode());
EasyBind.subscribe(checkForUpdatesCheckbox.selectedProperty(), this::checkForUpdateDidChange);
EasyBind.subscribe(portField.textProperty(), this::portDidChange);
EasyBind.subscribe(useIpv6Checkbox.selectedProperty(), this::useIpv6DidChange);
EasyBind.subscribe(prefGvfsScheme.valueProperty(), this::prefGvfsSchemeDidChange);
EasyBind.subscribe(debugModeCheckbox.selectedProperty(), this::debugModeDidChange);
}
@Override
@@ -114,6 +119,11 @@ public class SettingsController extends LocalizedFXMLViewController {
settings.save();
}
private void debugModeDidChange(Boolean newValue) {
settings.setDebugMode(newValue);
settings.save();
}
private void prefGvfsSchemeDidChange(String newValue) {
settings.setPreferredGvfsScheme(newValue);
settings.save();

View File

@@ -30,6 +30,7 @@ import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.settings.Localization;
import org.cryptomator.ui.settings.Settings;
import org.cryptomator.ui.util.AsyncTaskService;
import org.cryptomator.ui.util.DialogBuilderUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,7 +41,9 @@ import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Hyperlink;
@@ -276,6 +279,37 @@ public class UnlockController extends LocalizedFXMLViewController {
}
}
// ****************************************
// Save password checkbox
// ****************************************
@FXML
private void didClickSavePasswordCheckbox(ActionEvent event) {
if (!savePassword.isSelected() && hasStoredPassword()) {
Alert confirmDialog = DialogBuilderUtil.buildConfirmationDialog( //
localization.getString("unlock.savePassword.delete.confirmation.title"), //
localization.getString("unlock.savePassword.delete.confirmation.header"), //
localization.getString("unlock.savePassword.delete.confirmation.content"), //
SystemUtils.IS_OS_MAC_OSX ? ButtonType.CANCEL : ButtonType.OK);
Optional<ButtonType> choice = confirmDialog.showAndWait();
if (ButtonType.OK.equals(choice.get())) {
keychainAccess.get().deletePassphrase(vault.getId());
} else if (ButtonType.CANCEL.equals(choice.get())) {
savePassword.setSelected(true);
}
}
}
private boolean hasStoredPassword() {
char[] storedPw = keychainAccess.get().loadPassphrase(vault.getId());
boolean hasPw = (storedPw != null);
if (storedPw != null) {
Arrays.fill(storedPw, ' ');
}
return hasPw;
}
// ****************************************
// Unlock button
// ****************************************
@@ -301,7 +335,7 @@ public class UnlockController extends LocalizedFXMLViewController {
if (keychainAccess.isPresent() && savePassword.isSelected()) {
keychainAccess.get().storePassphrase(vault.getId(), password);
} else {
passwordField.swipe();
Platform.runLater(passwordField::swipe);
}
} catch (InvalidPassphraseException e) {
Platform.runLater(() -> {

View File

@@ -38,6 +38,7 @@ import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ToggleButton;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
@@ -57,15 +58,6 @@ public class UnlockedController extends LocalizedFXMLViewController {
private Optional<LockListener> listener = Optional.empty();
private Timeline ioAnimation;
@Inject
public UnlockedController(Localization localization, Provider<MacWarningsController> macWarningsControllerProvider, AsyncTaskService asyncTaskService) {
super(localization);
this.macWarningsController = macWarningsControllerProvider.get();
this.asyncTaskService = asyncTaskService;
macWarningsController.vault.bind(this.vault);
}
@FXML
private Label messageLabel;
@@ -81,11 +73,25 @@ public class UnlockedController extends LocalizedFXMLViewController {
@FXML
private ContextMenu moreOptionsMenu;
@FXML
private MenuItem revealVaultMenuItem;
@Inject
public UnlockedController(Localization localization, Provider<MacWarningsController> macWarningsControllerProvider, AsyncTaskService asyncTaskService) {
super(localization);
this.macWarningsController = macWarningsControllerProvider.get();
this.asyncTaskService = asyncTaskService;
macWarningsController.vault.bind(this.vault);
}
@Override
public void initialize() {
macWarningsController.initStage(macWarningsWindow);
ActiveWindowStyleSupport.startObservingFocus(macWarningsWindow);
revealVaultMenuItem.disableProperty().bind(EasyBind.map(vault, vault -> vault != null && !vault.isMounted()));
EasyBind.subscribe(vault, this::vaultChanged);
EasyBind.subscribe(moreOptionsMenu.showingProperty(), moreOptionsButton::setSelected);
}
@@ -109,6 +115,11 @@ public class UnlockedController extends LocalizedFXMLViewController {
}
});
if (!vault.get().isMounted()) {
// TODO Markus Kreusch #393: hyperlink auf FAQ oder sowas?
messageLabel.setText(localization.getString("unlocked.label.mountFailed"));
}
// (re)start throughput statistics:
stopIoSampling();
startIoSampling();

View File

@@ -41,7 +41,10 @@ public class UpgradeController extends LocalizedFXMLViewController {
}
@FXML
private Label upgradeLabel;
private Label upgradeTitleLabel;
@FXML
private Label upgradeMsgLabel;
@FXML
private SecPasswordField passwordField;
@@ -60,8 +63,11 @@ public class UpgradeController extends LocalizedFXMLViewController {
@Override
protected void initialize() {
upgradeLabel.textProperty().bind(EasyBind.monadic(strategy).map(instruction -> {
return instruction.map(this::upgradeNotification).orElse("");
upgradeTitleLabel.textProperty().bind(EasyBind.monadic(strategy).map(instruction -> {
return instruction.map(this::upgradeTitle).orElse("");
}).orElse(""));
upgradeMsgLabel.textProperty().bind(EasyBind.monadic(strategy).map(instruction -> {
return instruction.map(this::upgradeMessage).orElse("");
}).orElse(""));
BooleanExpression passwordProvided = passwordField.textProperty().isNotEmpty().and(passwordField.disabledProperty().not());
@@ -87,8 +93,12 @@ public class UpgradeController extends LocalizedFXMLViewController {
// Upgrade label
// ****************************************
private String upgradeNotification(UpgradeStrategy instruction) {
return instruction.getNotification(vault);
private String upgradeTitle(UpgradeStrategy instruction) {
return instruction.getTitle(vault);
}
private String upgradeMessage(UpgradeStrategy instruction) {
return instruction.getMessage(vault);
}
// ****************************************

View File

@@ -13,7 +13,6 @@ import java.net.URL;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import javax.inject.Inject;
import javax.inject.Named;
@@ -29,6 +28,7 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.ui.settings.Localization;
import org.cryptomator.ui.settings.Settings;
import org.cryptomator.ui.util.ApplicationVersion;
import org.cryptomator.ui.util.AsyncTaskService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -104,7 +104,7 @@ public class WelcomeController extends LocalizedFXMLViewController {
asyncTaskService.asyncTaskOf(() -> {
final HttpClient client = new HttpClient();
final HttpMethod method = new GetMethod("https://cryptomator.org/downloads/latestVersion.json");
client.getParams().setParameter(HttpClientParams.USER_AGENT, "Cryptomator VersionChecker/" + applicationVersion().orElse("SNAPSHOT"));
client.getParams().setParameter(HttpClientParams.USER_AGENT, "Cryptomator VersionChecker/" + ApplicationVersion.orElse("SNAPSHOT"));
client.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
client.getParams().setConnectionManagerTimeout(5000);
client.executeMethod(method);
@@ -124,10 +124,6 @@ public class WelcomeController extends LocalizedFXMLViewController {
}).run();
}
private Optional<String> applicationVersion() {
return Optional.ofNullable(getClass().getPackage().getImplementationVersion());
}
private void compareVersions(final Map<String, String> latestVersions) {
final String latestVersion;
if (SystemUtils.IS_OS_MAC_OSX) {
@@ -140,7 +136,7 @@ public class WelcomeController extends LocalizedFXMLViewController {
// no version check possible on unsupported OS
return;
}
final String currentVersion = applicationVersion().orElse(null);
final String currentVersion = ApplicationVersion.orElse(null);
LOG.debug("Current version: {}, lastest version: {}", currentVersion, latestVersion);
if (currentVersion != null && semVerComparator.compare(currentVersion, latestVersion) < 0) {
final String msg = String.format(localization.getString("welcome.newVersionMessage"), latestVersion, currentVersion);

View File

@@ -33,14 +33,20 @@ public abstract class UpgradeStrategy {
}
/**
* @return Localized string to display to the user when an upgrade is needed.
* @return Localized title string to display to the user when an upgrade is needed.
*/
public abstract String getNotification(Vault vault);
public abstract String getTitle(Vault vault);
/**
* @return Localized message string to display to the user when an upgrade is needed.
*/
public abstract String getMessage(Vault vault);
/**
* Upgrades a vault. Might take a moment, should be run in a background thread.
*/
public void upgrade(Vault vault, CharSequence passphrase) throws UpgradeFailedException {
LOG.info("Upgrading {} from {} to {}.", vault.path().getValue(), vaultVersionBeforeUpgrade, vaultVersionAfterUpgrade);
Cryptor cryptor = null;
try {
final Path masterkeyFile = vault.path().getValue().resolve(Constants.MASTERKEY_FILENAME);
@@ -49,12 +55,14 @@ public abstract class UpgradeStrategy {
// create backup, as soon as we know the password was correct:
final Path masterkeyBackupFile = vault.path().getValue().resolve(Constants.MASTERKEY_BACKUP_FILENAME);
Files.copy(masterkeyFile, masterkeyBackupFile, StandardCopyOption.REPLACE_EXISTING);
LOG.info("Backuped masterkey.");
// do stuff:
upgrade(vault, cryptor);
// write updated masterkey file:
final byte[] upgradedMasterkeyFileContents = cryptor.writeKeysToMasterkeyFile(passphrase, vaultVersionAfterUpgrade).serialize();
final Path masterkeyFileAfterUpgrade = vault.path().getValue().resolve(Constants.MASTERKEY_FILENAME); // path may have changed
Files.write(masterkeyFileAfterUpgrade, upgradedMasterkeyFileContents, StandardOpenOption.TRUNCATE_EXISTING);
LOG.info("Updated masterkey.");
} catch (InvalidPassphraseException e) {
throw new UpgradeFailedException(localization.getString("unlock.errorMessage.wrongPassword"));
} catch (UnsupportedVaultFormatException e) {

View File

@@ -32,7 +32,12 @@ class UpgradeVersion3DropBundleExtension extends UpgradeStrategy {
}
@Override
public String getNotification(Vault vault) {
public String getTitle(Vault vault) {
return localization.getString("upgrade.version3dropBundleExtension.title");
}
@Override
public String getMessage(Vault vault) {
String fmt = localization.getString("upgrade.version3dropBundleExtension.msg");
Path path = vault.path().getValue();
String oldVaultName = path.getFileName().toString();

View File

@@ -50,7 +50,12 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
}
@Override
public String getNotification(Vault vault) {
public String getTitle(Vault vault) {
return localization.getString("upgrade.version3to4.title");
}
@Override
public String getMessage(Vault vault) {
return localization.getString("upgrade.version3to4.msg");
}

View File

@@ -40,8 +40,13 @@ class UpgradeVersion4to5 extends UpgradeStrategy {
}
@Override
public String getNotification(Vault vault) {
return localization.getString("upgrade.version3to4.msg");
public String getTitle(Vault vault) {
return localization.getString("upgrade.version4to5.title");
}
@Override
public String getMessage(Vault vault) {
return localization.getString("upgrade.version4to5.msg");
}
@Override
@@ -57,6 +62,8 @@ class UpgradeVersion4to5 extends UpgradeStrategy {
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (BASE32_PATTERN.matcher(file.getFileName().toString()).find() && attrs.size() > cryptor.fileHeaderCryptor().headerSize()) {
migrate(file, attrs, cryptor);
} else {
LOG.info("Skipping irrelevant file {}.", file);
}
return FileVisitResult.CONTINUE;
}
@@ -64,24 +71,26 @@ class UpgradeVersion4to5 extends UpgradeStrategy {
});
} catch (IOException e) {
LOG.error("Migration failed.", e);
throw new UpgradeFailedException(localization.getString("upgrade.version3to4.err.io"));
throw new UpgradeFailedException(localization.getString("upgrade.version4to5.err.io"));
}
LOG.info("Migration finished.");
}
private void migrate(Path file, BasicFileAttributes attrs, Cryptor cryptor) throws IOException {
LOG.info("Starting migration of {}...", file);
try (FileChannel ch = FileChannel.open(file, StandardOpenOption.READ, StandardOpenOption.WRITE)) {
// read header:
ByteBuffer headerBuf = ByteBuffer.allocate(cryptor.fileHeaderCryptor().headerSize());
ch.read(headerBuf);
headerBuf.flip();
LOG.info("\tHeader read");
FileHeader header = cryptor.fileHeaderCryptor().decryptHeader(headerBuf);
long cleartextSize = header.getFilesize();
if (cleartextSize < 0) {
LOG.info("Skipping already migrated file {}.", file);
LOG.info("\tSkipping already migrated file");
return;
} else if (cleartextSize > attrs.size()) {
LOG.warn("Skipping file {} with invalid file size {}/{}", file, cleartextSize, attrs.size());
LOG.warn("\tSkipping file with invalid file size {}/{}", cleartextSize, attrs.size());
return;
}
int headerSize = cryptor.fileHeaderCryptor().headerSize();
@@ -93,12 +102,13 @@ class UpgradeVersion4to5 extends UpgradeStrategy {
long newAdditionalCiphertextBytes = newCiphertextSize % ciphertextChunkSize;
if (newAdditionalCiphertextBytes == 0) {
// (new) last block is already correct. just truncate:
LOG.info("Migrating {} of cleartext size {}: Truncating to new ciphertext size: {}", file, cleartextSize, newEOF);
LOG.info("\tMigrating cleartext size {}: Truncating to new ciphertext size: {}", cleartextSize, newEOF);
ch.truncate(newEOF);
LOG.info("\tFile truncated");
} else {
// last block may contain padding and needs to be re-encrypted:
long lastChunkIdx = newFullChunks;
LOG.info("Migrating {} of cleartext size {}: Re-encrypting chunk {}. New ciphertext size: {}", file, cleartextSize, lastChunkIdx, newEOF);
LOG.info("\tMigrating cleartext size {}: Re-encrypting chunk {}. New ciphertext size: {}", cleartextSize, lastChunkIdx, newEOF);
long beginOfLastChunk = headerSize + lastChunkIdx * ciphertextChunkSize;
assert beginOfLastChunk < newEOF;
int lastCleartextChunkLength = (int) (cleartextSize % cleartextChunkSize);
@@ -116,15 +126,18 @@ class UpgradeVersion4to5 extends UpgradeStrategy {
ch.truncate(beginOfLastChunk);
ch.write(newLastChunkCiphertext);
} else {
LOG.error("Reached EOF at position {}/{}", beginOfLastChunk, newEOF);
LOG.error("\tReached EOF at position {}/{}", beginOfLastChunk, newEOF);
return; // must exit method before changing header!
}
LOG.info("\tReencrypted last block");
}
header.setFilesize(-1l);
ByteBuffer newHeaderBuf = cryptor.fileHeaderCryptor().encryptHeader(header);
ch.position(0);
ch.write(newHeaderBuf);
LOG.info("\tUpdated header");
}
LOG.info("Finished migration of {}.", file);
}
}

View File

@@ -50,6 +50,8 @@ import org.cryptomator.ui.util.DeferredClosable;
import org.cryptomator.ui.util.DeferredCloser;
import org.cryptomator.ui.util.FXThreads;
import org.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableMap;
@@ -65,6 +67,8 @@ import javafx.collections.ObservableList;
public class Vault implements CryptoFileSystemDelegate {
private static final Logger LOG = LoggerFactory.getLogger(CryptoFileSystemDelegate.class);
public static final String VAULT_FILE_EXTENSION = ".cryptomator";
private final ObjectProperty<Path> path;
@@ -72,6 +76,7 @@ public class Vault implements CryptoFileSystemDelegate {
private final CryptoFileSystemFactory cryptoFileSystemFactory;
private final DeferredCloser closer;
private final BooleanProperty unlocked = new SimpleBooleanProperty();
private final BooleanProperty mounted = new SimpleBooleanProperty();
private final ObservableList<String> namesOfResourcesWithInvalidMac = FXThreads.observableListOnMainThread(FXCollections.observableArrayList());
private final Set<String> whitelistedResourcesWithInvalidMac = new HashSet<>();
private final AtomicReference<FileSystem> nioFileSystem = new AtomicReference<>();
@@ -131,7 +136,8 @@ public class Vault implements CryptoFileSystemDelegate {
}
public synchronized void activateFrontend(FrontendFactory frontendFactory, Settings settings, CharSequence passphrase) throws FrontendCreationFailedException {
boolean success = false;
boolean launchSuccess = false;
boolean mountSuccess = false;
try {
FileSystem fs = getNioFileSystem();
FileSystem shorteningFs = shorteningFileSystemFactory.get(fs);
@@ -140,22 +146,32 @@ public class Vault implements CryptoFileSystemDelegate {
StatsFileSystem statsFs = new StatsFileSystem(normalizingFs);
statsFileSystem = Optional.of(statsFs);
Frontend frontend = frontendFactory.create(statsFs, FrontendId.from(id), stripStart(mountName, "/"));
launchSuccess = true;
filesystemFrontend = closer.closeLater(frontend);
frontend.mount(getMountParams(settings));
success = true;
} catch (UncheckedIOException | CommandFailedException e) {
mountSuccess = true;
} catch (UncheckedIOException e) {
throw new FrontendCreationFailedException(e);
} catch (CommandFailedException e) {
LOG.error("Failed to mount vault " + mountName, e);
} finally {
// unlocked is a observable property and should only be changed by the FX application thread
final boolean finalSuccess = success;
Platform.runLater(() -> unlocked.set(finalSuccess));
boolean finalLaunchSuccess = launchSuccess;
boolean finalMountSuccess = mountSuccess;
Platform.runLater(() -> {
unlocked.set(finalLaunchSuccess);
mounted.set(finalMountSuccess);
});
}
}
public synchronized void deactivateFrontend() throws Exception {
filesystemFrontend.close();
statsFileSystem = Optional.empty();
Platform.runLater(() -> unlocked.set(false));
Platform.runLater(() -> {
mounted.set(false);
unlocked.set(false);
});
}
private Map<MountParam, Optional<String>> getMountParams(Settings settings) {
@@ -239,10 +255,18 @@ public class Vault implements CryptoFileSystemDelegate {
return unlocked;
}
public BooleanProperty mountedProperty() {
return mounted;
}
public boolean isUnlocked() {
return unlocked.get();
}
public boolean isMounted() {
return mounted.get();
}
public ObservableList<String> getNamesOfResourcesWithInvalidMac() {
return namesOfResourcesWithInvalidMac;
}

View File

@@ -18,6 +18,7 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,31 +29,50 @@ public class Localization extends ResourceBundle {
private static final String LOCALIZATION_DEFAULT_FILE = "/localization/en.txt";
private static final String LOCALIZATION_FILENAME_FMT = "/localization/%s.txt";
private static final String LOCALIZATION_FILE = String.format(LOCALIZATION_FILENAME_FMT, Locale.getDefault().getLanguage());
private final ResourceBundle fallback;
private final ResourceBundle localized;
@Inject
public Localization() {
try (InputStream in = getClass().getResourceAsStream(LOCALIZATION_DEFAULT_FILE)) {
Objects.requireNonNull(in);
Reader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
this.fallback = new PropertyResourceBundle(reader);
LOG.info("Loaded localization from bundle:{}", LOCALIZATION_FILE);
try {
this.fallback = Objects.requireNonNull(loadLocalizationFile(LOCALIZATION_DEFAULT_FILE));
LOG.debug("Loaded localization default file: {}", LOCALIZATION_DEFAULT_FILE);
String language = Locale.getDefault().getLanguage();
String region = Locale.getDefault().getCountry();
LOG.info("Detected language \"{}\" and region \"{}\"", language, region);
ResourceBundle localizationBundle = null;
if (StringUtils.isNotEmpty(language) && StringUtils.isNotEmpty(region)) {
String file = String.format(LOCALIZATION_FILENAME_FMT, language + "_" + region);
LOG.info("Attempting to load localization from: {}", file);
localizationBundle = loadLocalizationFile(file);
}
if (StringUtils.isNotEmpty(language) && localizationBundle == null) {
String file = String.format(LOCALIZATION_FILENAME_FMT, language);
LOG.info("Attempting to load localization from: {}", file);
localizationBundle = loadLocalizationFile(file);
}
if (localizationBundle == null) {
LOG.info("No localization found. Falling back to default language.");
localizationBundle = this.fallback;
}
this.localized = Objects.requireNonNull(localizationBundle);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
try (InputStream in = getClass().getResourceAsStream(LOCALIZATION_FILE)) {
// returns null if no resource for given path
private ResourceBundle loadLocalizationFile(String resourcePath) throws IOException {
try (InputStream in = getClass().getResourceAsStream(resourcePath)) {
if (in != null) {
Reader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
this.localized = new PropertyResourceBundle(reader);
return new PropertyResourceBundle(reader);
} else {
this.localized = this.fallback;
return null;
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

View File

@@ -28,6 +28,7 @@ public class Settings implements Serializable {
public static final boolean DEFAULT_USE_IPV6 = false;
public static final Integer DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
public static final String DEFAULT_GVFS_SCHEME = "dav";
public static final boolean DEFAULT_DEBUG_MODE = false;
private final Consumer<Settings> saveCmd;
@@ -49,6 +50,9 @@ public class Settings implements Serializable {
@JsonProperty("preferredGvfsScheme")
private String preferredGvfsScheme;
@JsonProperty("debugMode")
private Boolean debugMode;
/**
* Package-private constructor; use {@link SettingsProvider}.
*/
@@ -125,4 +129,12 @@ public class Settings implements Serializable {
this.preferredGvfsScheme = preferredGvfsScheme;
}
public boolean getDebugMode() {
return debugMode == null ? DEFAULT_DEBUG_MODE : debugMode;
}
public void setDebugMode(boolean debugMode) {
this.debugMode = debugMode;
}
}

View File

@@ -0,0 +1,17 @@
package org.cryptomator.ui.util;
import java.util.Optional;
import org.cryptomator.ui.Cryptomator;
public class ApplicationVersion {
public static String orElse(String other) {
return get().orElse(other);
}
public static Optional<String> get() {
return Optional.ofNullable(Cryptomator.class.getPackage().getImplementationVersion());
}
}

View File

@@ -85,7 +85,7 @@ public class SingleInstanceManager {
return true;
}
return !buf.hasRemaining();
} , timeout, 10);
}, timeout, 10);
return !buf.hasRemaining();
}
@@ -117,13 +117,14 @@ public class SingleInstanceManager {
final String applicationKey;
final ServerSocketChannel channel;
final Selector selector;
int port = 0;
final int port;
public LocalInstance(String applicationKey, ServerSocketChannel channel, Selector selector) {
public LocalInstance(String applicationKey, ServerSocketChannel channel, Selector selector, int port) {
Objects.requireNonNull(applicationKey);
this.applicationKey = applicationKey;
this.channel = channel;
this.selector = selector;
this.port = port;
}
/**
@@ -317,28 +318,27 @@ public class SingleInstanceManager {
*/
public static LocalInstance startLocalInstance(String applicationKey, ExecutorService exec) throws IOException {
final ServerSocketChannel channel = ServerSocketChannel.open();
channel.configureBlocking(false);
channel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
boolean success = false;
try {
channel.configureBlocking(false);
channel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
final int port = ((InetSocketAddress) channel.getLocalAddress()).getPort();
Preferences.userNodeForPackage(Cryptomator.class).putInt(applicationKey, port);
LOG.debug("InstanceManager bound to port {}", port);
final int port = ((InetSocketAddress) channel.getLocalAddress()).getPort();
Preferences.userNodeForPackage(Cryptomator.class).putInt(applicationKey, port);
LOG.debug("InstanceManager bound to port {}", port);
Selector selector = Selector.open();
channel.register(selector, SelectionKey.OP_ACCEPT);
LocalInstance instance = new LocalInstance(applicationKey, channel, selector);
exec.submit(() -> {
try {
instance.port = ((InetSocketAddress) channel.getLocalAddress()).getPort();
} catch (IOException e) {
Selector selector = Selector.open();
channel.register(selector, SelectionKey.OP_ACCEPT);
LocalInstance instance = new LocalInstance(applicationKey, channel, selector, port);
exec.submit(instance::selectionLoop);
success = true;
return instance;
} finally {
if (!success) {
channel.close();
}
instance.selectionLoop();
});
return instance;
}
}
/**
@@ -368,7 +368,7 @@ public class SingleInstanceManager {
}
}
return !buf.hasRemaining();
} , timeout, 1);
}, timeout, 1);
}
}
}

View File

@@ -46,6 +46,10 @@
<Label GridPane.rowIndex="3" GridPane.columnIndex="0" fx:id="prefGvfsSchemeLabel" text="%settings.prefGvfsScheme.label" cacheShape="true" cache="true" />
<ChoiceBox GridPane.rowIndex="3" GridPane.columnIndex="1" fx:id="prefGvfsScheme" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
<!-- Row 4 -->
<Label GridPane.rowIndex="4" GridPane.columnIndex="0" fx:id="debugModeLabel" text="%settings.debugMode.label" cacheShape="true" cache="true" />
<CheckBox GridPane.rowIndex="4" GridPane.columnIndex="1" fx:id="debugModeCheckbox" cacheShape="true" cache="true" />
</children>
</GridPane>
<Label VBox.vgrow="NEVER" text="%settings.requiresRestartLabel" alignment="CENTER" cacheShape="true" cache="true" />

View File

@@ -69,7 +69,7 @@
<!-- Row 3.1 -->
<Label GridPane.rowIndex="1" GridPane.columnIndex="0" text="%unlock.label.savePassword" cacheShape="true" cache="true" />
<CheckBox GridPane.rowIndex="1" GridPane.columnIndex="1" fx:id="savePassword" cacheShape="true" cache="true" />
<CheckBox GridPane.rowIndex="1" GridPane.columnIndex="1" fx:id="savePassword" onAction="#didClickSavePasswordCheckbox" cacheShape="true" cache="true" />
<!-- Row 3.2 -->
<Label GridPane.rowIndex="2" GridPane.columnIndex="0" text="%unlock.label.mountName" cacheShape="true" cache="true" />

View File

@@ -28,7 +28,7 @@
<fx:define>
<ContextMenu fx:id="moreOptionsMenu">
<items>
<MenuItem text="%unlocked.moreOptions.reveal" onAction="#didClickRevealVault">
<MenuItem fx:id="revealVaultMenuItem" text="%unlocked.moreOptions.reveal" onAction="#didClickRevealVault">
<graphic><Label text="&#xf133;" styleClass="ionicons"/></graphic>
</MenuItem>
<MenuItem text="%unlocked.moreOptions.copyUrl" onAction="#didClickCopyUrl">

View File

@@ -31,22 +31,24 @@
</columnConstraints>
<children>
<Label fx:id="upgradeLabel" wrapText="true" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" />
<Label fx:id="upgradeTitleLabel" wrapText="true" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" />
<Label fx:id="upgradeMsgLabel" wrapText="true" GridPane.rowIndex="1" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" />
<Pane prefHeight="12.0" GridPane.rowIndex="1" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true">
<Pane prefHeight="12.0" GridPane.rowIndex="2" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true">
</Pane>
<Label text="%unlock.label.password" GridPane.rowIndex="2" GridPane.columnIndex="0" cacheShape="true" cache="true" />
<SecPasswordField fx:id="passwordField" GridPane.rowIndex="2" GridPane.columnIndex="1" cacheShape="true" cache="true" />
<Label text="%unlock.label.password" GridPane.rowIndex="3" GridPane.columnIndex="0" cacheShape="true" cache="true" />
<SecPasswordField fx:id="passwordField" GridPane.rowIndex="3" GridPane.columnIndex="1" cacheShape="true" cache="true" />
<CheckBox fx:id="confirmationCheckbox" text="%upgrade.confirmation.label" wrapText="true" GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" />
<CheckBox fx:id="confirmationCheckbox" text="%upgrade.confirmation.label" wrapText="true" GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" />
<HBox alignment="CENTER_RIGHT" GridPane.hgrow="ALWAYS" GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true">
<HBox alignment="CENTER_RIGHT" GridPane.hgrow="ALWAYS" GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true">
<Button fx:id="upgradeButton" text="%upgrade.button" prefWidth="150.0" onAction="#didClickUpgradeButton" cacheShape="true" cache="true" />
</HBox>
<ProgressIndicator progress="-1" fx:id="progressIndicator" visible="false" GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" cacheHint="SPEED" />
<ProgressIndicator progress="-1" fx:id="progressIndicator" visible="false" GridPane.rowIndex="6" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" cacheHint="SPEED" />
<Label fx:id="errorLabel" wrapText="true" GridPane.rowIndex="6" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" />
<Label fx:id="errorLabel" wrapText="true" GridPane.rowIndex="7" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" />
</children>
</GridPane>

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Alle Cryptomator Versionen
changePassword.button.change = Passwort ändern
changePassword.errorMessage.wrongPassword = Falsches Passwort
changePassword.errorMessage.decryptionFailed = Entschlüsselung fehlgeschlagen
changePassword.infoMessage.success = Passwort geändert
# unlocked.fxml
unlocked.button.lock = Tresor sperren
unlocked.moreOptions.reveal = Laufwerk anzeigen
@@ -88,4 +87,14 @@ settings.prefGvfsScheme.label = WebDAV Schema
upgrade.confirmation.label = Ja, die Synchronisation ist abgeschlossen
initialize.messageLabel.notEmpty = Tresor ist nicht leer
unlock.label.savePassword = Passwort speichern
unlock.errorMessage.unauthenticVersionMac = Versions-MAC konnte nicht authentifiziert werden.
unlock.errorMessage.unauthenticVersionMac = Versions-MAC konnte nicht authentifiziert werden.
unlocked.label.mountFailed = Verbinden des Laufwerks fehlgeschlagen
unlock.savePassword.delete.confirmation.title = Gespeichertes Passwort löschen
unlock.savePassword.delete.confirmation.header = Möchten Sie das gespeicherte Passwort von diesem Tresor wirklich löschen?
unlock.savePassword.delete.confirmation.content = Das gespeicherte Passwort von diesem Tresor wird sofort aus Ihrem System-Schlüsselbund gelöscht. Falls Sie das Passwort erneut speichern möchten, müssen Sie den Tresor entsperren und dabei die "Passwort speichern"-Option aktiviert haben.
settings.debugMode.label = Debug-Modus *
upgrade.version3dropBundleExtension.title = Upgrade Tresor-Version 3 (Entfall der Bundle-Extension)
upgrade.version3to4.title = Upgrade Tresor-Version 3 zu 4
upgrade.version4to5.title = Upgrade Tresor-Version 4 zu 5
upgrade.version4to5.msg = Dieser Tresor muss auf ein neueres Format aktualisiert werden.\nVerschlüsselte Dateien werden dabei aktualisiert.\nStellen Sie bitte sicher, dass derzeit keine Synchronisation stattfindet.\n\nHinweis\: Beim Upgrade wird das Änderungsdatum aller Dateien auf das aktuelle Datum geändert.
upgrade.version4to5.err.io = Migration aufgrund eines I/O-Fehlers fehlgeschlagen.\nWeitere Informationen in der Log-Datei.

View File

@@ -9,10 +9,10 @@ app.name=Cryptomator
# main.fxml
main.emptyListInstructions=Click here to add a vault
main.directoryList.contextMenu.remove=Remove from list
main.directoryList.contextMenu.changePassword=Change password
main.addDirectory.contextMenu.new=Create new vault
main.addDirectory.contextMenu.open=Open existing vault
main.directoryList.contextMenu.remove=Remove from List
main.directoryList.contextMenu.changePassword=Change Password
main.addDirectory.contextMenu.new=Create New Vault
main.addDirectory.contextMenu.open=Open Existing Vault
main.directoryList.remove.confirmation.title=Remove Vault
main.directoryList.remove.confirmation.header=Do you really want to remove this vault?
main.directoryList.remove.confirmation.content=The vault will only be removed from the list. To permanently delete it, please delete the files from your filesystem.
@@ -23,8 +23,8 @@ welcome.newVersionMessage=Version %1$s can be downloaded.\nThis is %2$s.
# initialize.fxml
initialize.label.password=Password
initialize.label.retypePassword=Retype password
initialize.button.ok=Create vault
initialize.label.retypePassword=Retype Password
initialize.button.ok=Create Vault
initialize.messageLabel.alreadyInitialized=Vault already initialized
initialize.messageLabel.notEmpty=Vault not empty
initialize.messageLabel.initializationFailed=Could not initialize vault. See log file for details.
@@ -40,24 +40,33 @@ notfound.label=Vault couldn't be found. Has it been moved?
# upgrade.fxml
upgrade.confirmation.label=Yes, I've made sure that synchronization has finished
upgrade.button=Upgrade vault
upgrade.button=Upgrade Vault
upgrade.version3dropBundleExtension.title=Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3dropBundleExtension.msg=This vault needs to be migrated to a newer format.\n"%1$s" will be renamed to "%2$s".\nPlease make sure synchronization has finished before proceeding.
upgrade.version3dropBundleExtension.err.alreadyExists=Automatic migration failed.\n"%s" already exists.
upgrade.version3to4.title=Vault Version 3 to 4 Upgrade
upgrade.version3to4.msg=This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
upgrade.version3to4.err.io=Migration failed due to an I/O Exception. See log file for details.
upgrade.version4to5.title=Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg=This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io=Migration failed due to an I/O Exception. See log file for details.
# unlock.fxml
unlock.label.password=Password
unlock.label.savePassword=Save password
unlock.label.mountName=Drive name
unlock.label.winDriveLetter=Drive letter
unlock.label.savePassword=Save Password
unlock.label.mountName=Drive Name
unlock.label.winDriveLetter=Drive Letter
unlock.label.downloadsPageLink=All Cryptomator versions
unlock.label.advancedHeading=Advanced options
unlock.button.unlock=Unlock vault
unlock.button.advancedOptions.show=More options
unlock.button.advancedOptions.hide=Less options
unlock.label.advancedHeading=Advanced Options
unlock.button.unlock=Unlock Vault
unlock.button.advancedOptions.show=More Options
unlock.button.advancedOptions.hide=Less Options
unlock.savePassword.delete.confirmation.title=Delete Saved Password
unlock.savePassword.delete.confirmation.header=Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content=The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
unlock.choicebox.winDriveLetter.auto=Assign automatically
unlock.errorMessage.wrongPassword=Wrong password
unlock.errorMessage.mountingFailed=Mounting failed. See log file for details.
@@ -67,18 +76,19 @@ unlock.errorMessage.unauthenticVersionMac=Could not authenticate version MAC.
unlock.messageLabel.startServerFailed=Starting WebDAV server failed.
# change_password.fxml
changePassword.label.oldPassword=Old password
changePassword.label.newPassword=New password
changePassword.label.retypePassword=Retype password
changePassword.label.oldPassword=Old Password
changePassword.label.newPassword=New Nassword
changePassword.label.retypePassword=Retype Password
changePassword.label.downloadsPageLink=All Cryptomator versions
changePassword.button.change=Change password
changePassword.button.change=Change Password
changePassword.errorMessage.wrongPassword=Wrong password
changePassword.errorMessage.decryptionFailed=Decryption failed
# unlocked.fxml
unlocked.button.lock=Lock vault
unlocked.moreOptions.reveal=Reveal drive
unlocked.button.lock=Lock Vault
unlocked.moreOptions.reveal=Reveal Drive
unlocked.moreOptions.copyUrl=Copy WebDAV URL
unlocked.label.mountFailed=Connecting drive failed
unlocked.label.revealFailed=Command failed
unlocked.label.unmountFailed=Ejecting drive failed
unlocked.label.statsEncrypted=encrypted
@@ -88,21 +98,22 @@ unlocked.ioGraph.yAxis.label=Throughput (MiB/s)
# mac_warnings.fxml
macWarnings.windowTitle=Danger - Corrupted file in %s
macWarnings.message=Cryptomator detected potentially malicious corruptions in the following files:
macWarnings.moreInformationButton=Learn more
macWarnings.whitelistButton=Decrypt selected anyway
macWarnings.moreInformationButton=Learn More
macWarnings.whitelistButton=Decrypt Selected Anyway
# settings.fxml
settings.version.label=Version %s
settings.checkForUpdates.label=Check for updates
settings.checkForUpdates.label=Check for Updates
settings.port.label=WebDAV Port *
settings.port.prompt=0 = Choose automatically
settings.useipv6.label=Use IPv6 literal
settings.prefGvfsScheme.label=WebDAV scheme
settings.useipv6.label=Use IPv6 Literal
settings.prefGvfsScheme.label=WebDAV Scheme
settings.debugMode.label=Debug Mode *
settings.requiresRestartLabel=* Cryptomator needs to restart
# tray icon
tray.menu.open=Open
tray.menu.quit=Quit
tray.infoMsg.title=Still running
tray.infoMsg.title=Still Running
tray.infoMsg.msg=Cryptomator is still alive. Quit it from the tray icon.
tray.infoMsg.msg.osx=Cryptomator is still alive. Quit it from the menu bar icon.

View File

@@ -1,6 +1,6 @@
app.name = Cryptomator
# main.fxml
main.emptyListInstructions = Click aquí para añadir una caja fuerte
main.emptyListInstructions = Clic aquí para añadir una caja fuerte
# should it be imperative?
main.directoryList.contextMenu.remove = Eliminar de la lista
main.directoryList.contextMenu.changePassword = Cambiar la contraseña
@@ -45,7 +45,6 @@ changePassword.label.downloadsPageLink = Todas las versiones de Cryptomator
changePassword.button.change = Cambiar contraseña
changePassword.errorMessage.wrongPassword = Contraseña incorrecta
changePassword.errorMessage.decryptionFailed = Decifración ha fallado
changePassword.infoMessage.success = Contraseña se ha cambiado
# unlocked.fxml
unlocked.button.lock = Encerrar caja fuerte
unlocked.moreOptions.reveal = Mostrar disco
@@ -78,15 +77,26 @@ initialize.messageLabel.passwordStrength.1 = débil
initialize.messageLabel.passwordStrength.2 = suficiente
initialize.messageLabel.passwordStrength.3 = fuerte
initialize.messageLabel.passwordStrength.4 = muy fuerte
initialize.label.doNotForget = IMPORTANTE\: Si olivdes tú contraseña no hay ninguna manera de recuperar tus datos.
initialize.label.doNotForget = IMPORTANTE\: Si olivdes tú contraseña, no hay ninguna manera de recuperar tus datos.
main.directoryList.remove.confirmation.title = Borrar caja fuerte
main.directoryList.remove.confirmation.header = ¿Quieres de verdad borrar este caja fuerte?
main.directoryList.remove.confirmation.content = La caja fuerte solo se borra de la lista. Para eliminarla permanente por favor elimina los datos de tú sistema de archivos.
upgrade.version3to4.msg = Este caja fuerte se debe migrar a un formato más reciente.\nLos nombres de las carpetas cifradas se actualizan.\nPor favor asegurarse de que la sincronización ha terminado antes de seguir.
upgrade.version3to4.err.io = Migración ha fallado por causa de una excepción I/O. Para detalles revisa el archivo de registro.
settings.prefGvfsScheme.label = WebDAV scheme
# or esequema WEBDAV but I think sistema sounds better
settings.prefGvfsScheme.label = sistema WebDAV
# upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
upgrade.confirmation.label = Sí, me he asegurado de que la sincronización ha terminado
initialize.messageLabel.notEmpty = Caja fuerte no está vacio
unlock.label.savePassword = Contraseña segura
unlock.errorMessage.unauthenticVersionMac = No se pudo autentificar la version de MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -15,7 +15,7 @@ initialize.button.ok = Créer le coffre
initialize.messageLabel.alreadyInitialized = Coffre déjà initialisé
initialize.messageLabel.initializationFailed = Impossible d'initialiser le coffre. Voir le fichier de log pour plus de détails.
# notfound.fxml
notfound.label = Coffre introuvable. A t'il été déplacé?
notfound.label = Coffre introuvable. A-t-il été déplacé?
# upgrade.fxml
upgrade.button = Mettre à niveau
upgrade.version3dropBundleExtension.msg = Ce coffre doit être converti dans un format plus récent.\n"%1$s" sera renommé en "%2$s".\nAssurez-vous que la synchronisation est terminée avant de continuer.
@@ -44,7 +44,6 @@ changePassword.button.change = Modification du mot de masse
changePassword.errorMessage.wrongPassword = Mot de passe incorrect
# En français, on dit déchiffrement lorsque la clé est connue
changePassword.errorMessage.decryptionFailed = Echec du déchiffrement
changePassword.infoMessage.success = Mot de passe modifié
# unlocked.fxml
unlocked.button.lock = Verrouiller le coffre
unlocked.moreOptions.reveal = Voir le lecteur
@@ -58,7 +57,7 @@ unlocked.label.statsDecrypted = déchiffré
unlocked.ioGraph.yAxis.label = Débit (MiB/s)
# mac_warnings.fxml
macWarnings.windowTitle = Attention - Fichier corrompu dans %s
macWarnings.message = Cryptomator a détecté des corruptions de données dans les fichiers suivants\:
macWarnings.message = Cryptomator a détecté des corruptions de données dans les fichiers suivants \:
macWarnings.moreInformationButton = En savoir plus
macWarnings.whitelistButton = Déchiffrer tout de même
# settings.fxml
@@ -82,12 +81,22 @@ initialize.messageLabel.passwordStrength.4 = Très fort
initialize.label.doNotForget = ATTENTION \: Si vous oubliez votre mot de passe, il n'y aura aucun moyen de récupérer vos données.
main.directoryList.remove.confirmation.title = Retirer un coffre
main.directoryList.remove.confirmation.header = Voulez-vous vraiment retirer ce coffre ?
main.directoryList.remove.confirmation.content = Le coffre sera simplement retiré de la liste. Pour le supprimer complètement, supprimez les fichiers depuis votre système de fichiers.
main.directoryList.remove.confirmation.content = Le coffre sera seulement retiré de la liste. Pour le supprimer complètement, supprimez les fichiers depuis votre système de fichiers.
upgrade.version3to4.msg = Ce coffre doit être converti dans un nouveau format. Les noms de dossiers chiffrés seront mis à jour.\nMerci de vous assurer que la procédure de synchronisation est terminée avant de continuer.
upgrade.version3to4.err.io = La migration a échoué à cause d'une erreur d'entrée/sortie. Référez-vous au fichier log pour plus de détails.
settings.prefGvfsScheme.label = Schéma d'URI WebDAV
# upgrade.fxml
upgrade.confirmation.label = Oui, je suis certain que la synchronisation est finie
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
upgrade.confirmation.label = Oui, je suis certain que la synchronisation est terminée
initialize.messageLabel.notEmpty = Le coffre n'est pas vide
unlock.label.savePassword = Se souvenir du mot de passe
unlock.errorMessage.unauthenticVersionMac = Impossible d'authentifier la version MAC
unlocked.label.mountFailed = Echec de connexion au lecteur
unlock.savePassword.delete.confirmation.title = supprimer le mot de passe sauvegardé
unlock.savePassword.delete.confirmation.header = voulez vous vraiment supprimer le mot de pase sauvegardé de ce compte ?
unlock.savePassword.delete.confirmation.content = Le mot de passe de ce coffre sera supprimé immédiatement du trousseau.Si vous voulez le sauvegarder à nouveau, vous devrez cocher la case "retenir le mot de passe" lors du déverrouillage du coffre.
settings.debugMode.label = mode debuggage*
upgrade.version3dropBundleExtension.title = mise à jour vers la version 3 du coffre (extension "drop bundle")
upgrade.version3to4.title = metre à jour le coffre de la version 3 à la version 4
upgrade.version4to5.title = metre à jour le coffre de la version 4 à la version 5
upgrade.version4to5.msg = ce coffre doit être mis à jour vers un format plus récent.\nles fichiés chiffrés seront mis à jour.\nVeuillez vérifier que la synchronisation est terminée avant de commencer.\n\nNote \: la date de modification des fichiers sera mise à jour avec la date courante.
upgrade.version4to5.err.io = Migration échouée due à une erreur de lecture. Lisez les logs pour plus de détails.

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Összes Cryptomator verzió
changePassword.button.change = Jelszó megváltoztatása
changePassword.errorMessage.wrongPassword = Hibás jelszó
changePassword.errorMessage.decryptionFailed = A titkosítás feloldása meghíusúlt
changePassword.infoMessage.success = Jelszó megváltoztatva
# unlocked.fxml
unlocked.button.lock = Széf lezárása
unlocked.moreOptions.reveal = Meghajtó felfedése
@@ -84,7 +83,17 @@ upgrade.version3to4.msg = Ennek a széfnek egy újabb formátumra való migráci
upgrade.version3to4.err.io = Migráció meghíusúlt egy I/O kivétel miatt. Kérlek nézd meg a naplófájlt a további részletekért.
settings.prefGvfsScheme.label = WebDAV séma
# upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
upgrade.confirmation.label = Igen, meggyőződtem a szinkronizáció befejeztéről
initialize.messageLabel.notEmpty = A széf nem üres
unlock.label.savePassword = Jelszó mentése
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Meghajtó csatlakoztatása sikertelen
unlock.savePassword.delete.confirmation.title = Mentett jelszó törlése
unlock.savePassword.delete.confirmation.header = Biztosan el akarod távolítani a széfhez tartozó mentett jelszót?
unlock.savePassword.delete.confirmation.content = A széf mentett jelszava rögtön törlése kerül. Ha újra el szeretnéd menteni a jelszavad, a széfet a "Jelszó mentése" opció engedélyezése mellett kell feloldani.
settings.debugMode.label = Hibakeresési mód *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Széf verziófrissítése 3-ról 4-re
upgrade.version4to5.title = Széf verziófrissítése 4-ről 5-re
upgrade.version4to5.msg = Ennek a széfnek egy újabb formátumra való migrációja szükséges. A titkosított könyvtárnevek frissítve lesznek. Kérlek, győződj meg a szinkronizáció befejeztéről mielőtt továbblépnél.\n\nMegjegyzés\: A összes fájl módosításának dátuma az aktuális időre fog módosulni
upgrade.version4to5.err.io = Migráció meghíusúlt egy I/O kivétel miatt. Kérlek nézd meg a naplófájlt a további részletekért.

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Tutte le versioni di Cryptomator
changePassword.button.change = Cambia la password
changePassword.errorMessage.wrongPassword = Password errata
changePassword.errorMessage.decryptionFailed = Decriptaggio fallito
changePassword.infoMessage.success = Password cambiata
# unlocked.fxml
unlocked.button.lock = Blocca vault
unlocked.moreOptions.reveal = Apri il disco
@@ -82,9 +81,19 @@ main.directoryList.remove.confirmation.header = Vuoi davvero rimuovere questo va
main.directoryList.remove.confirmation.content = Il vault sarà rimosso solo dalla lista. Per eliminarlo definitivamente, elimina per favore i file dal tuo hard disk.
upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.prefGvfsScheme.label = WebDAV scheme
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlock.label.savePassword = Save Password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -0,0 +1,99 @@
app.name = Cryptomator
# main.fxml
main.emptyListInstructions = ここをクリックして金庫を追加する
main.directoryList.contextMenu.remove = リストから削除する
main.directoryList.contextMenu.changePassword = パスワード変更
main.addDirectory.contextMenu.new = 新しい金庫を作成する
main.addDirectory.contextMenu.open = 既存の金庫を開く
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = アップデートを確認中...
welcome.newVersionMessage = バージョン%1$sがダウンロードできます。\n現在のバージョンは%2$sです。
# initialize.fxml
initialize.label.password = パスワード
initialize.label.retypePassword = パスワード再入力
initialize.button.ok = 金庫を作成
initialize.messageLabel.alreadyInitialized = 金庫がすでに初期化されています。
initialize.messageLabel.initializationFailed = 金庫の初期化ができませんでした。詳細はログファイルをご覧ください。
# notfound.fxml
notfound.label = 金庫が見つかりませんでした。動かされたのですか?
# upgrade.fxml
upgrade.button = 金庫をアップグレードする
upgrade.version3dropBundleExtension.msg = この金庫を新しい形式に移行する必要があります。\n"%1$s"は"%2$s"に変更されます。\n続行する前に同期が完了していることをご確認ください。
upgrade.version3dropBundleExtension.err.alreadyExists = 自動移行が失敗しました。\n"%s"はすでに存在します。
# unlock.fxml
unlock.label.password = パスワード
unlock.label.mountName = ドライブ名
unlock.label.winDriveLetter = ドライブ文字
unlock.label.downloadsPageLink = 全てのCryptomatorバージョン
unlock.label.advancedHeading = 詳細オプション
unlock.button.unlock = 金庫を解除する
unlock.button.advancedOptions.show = その他のオプション
unlock.button.advancedOptions.hide = 基本オプション
unlock.choicebox.winDriveLetter.auto = 自動に割り当てる
unlock.errorMessage.wrongPassword = 間違ったパスワード
unlock.errorMessage.mountingFailed = 取り付けに失敗しました。詳細はログファイルをご覧ください。
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = サポートされていない金庫です。この金庫は古いバージョンのCryptomatorから作成されました。
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = サポートされていない金庫です。この金庫は新しいバージョンのCryptomatorから作成されました。
unlock.messageLabel.startServerFailed = WebDAVサーバーの起動失敗
# change_password.fxml
changePassword.label.oldPassword = 古いパスワード
changePassword.label.newPassword = 新しいパスワード
changePassword.label.retypePassword = 二回目のパスワード(確認用)
changePassword.label.downloadsPageLink = 全てのCryptomatorのバージョン
changePassword.button.change = パスワードの変更
changePassword.errorMessage.wrongPassword = 違うパスワード
changePassword.errorMessage.decryptionFailed = 解読不可
# unlocked.fxml
unlocked.button.lock = 金庫の施錠
unlocked.moreOptions.reveal = 金庫ドライブの表示
unlocked.moreOptions.copyUrl = WebDAVのURLのコピー
unlocked.label.revealFailed = 入力エラー
unlocked.label.unmountFailed = 外部出力の排出エラー
unlocked.label.statsEncrypted = 暗号化
unlocked.label.statsDecrypted = 解読
unlocked.ioGraph.yAxis.label = 情報処理量
# mac_warnings.fxml
macWarnings.windowTitle = 危険-有害でフォルダの%s
macWarnings.message = Cryptomatorは、以下のファイルで潜在的に悪意のある改悪されたものを見つけました
macWarnings.moreInformationButton = より習得する
macWarnings.whitelistButton = フォルダを選択、解読してください
# settings.fxml
settings.version.label = バージョンの%s
settings.checkForUpdates.label = 最新版のチェック
settings.port.label = WebDAVの移動
settings.port.prompt = 0自動的に選択します
settings.useipv6.label = IPv6をそのまま使用してください
settings.requiresRestartLabel = Cryptomatorの再起動が必要です
# tray icon
tray.menu.open = 開く
tray.menu.quit = 閉じる
tray.infoMsg.title = バックグラウンドで稼働中
tray.infoMsg.msg = Cryptomatorはまだ稼働しています。終了はトレイアイコンからしてください。
tray.infoMsg.msg.osx = Cryptomatorはまだ稼働しています。終了はメヌーバーアイコンからしてください。
initialize.messageLabel.passwordStrength.0 = 非常に弱い
initialize.messageLabel.passwordStrength.1 = 弱い
initialize.messageLabel.passwordStrength.2 = 普通
initialize.messageLabel.passwordStrength.3 = 強い
initialize.messageLabel.passwordStrength.4 = 非常に強い
initialize.label.doNotForget = 重要:パスワードを忘れましたら、あなたのデータは復旧できません。
main.directoryList.remove.confirmation.title = 金庫の削除
main.directoryList.remove.confirmation.header = 本当にこの金庫を取り除きたいですか?
main.directoryList.remove.confirmation.content = 金庫はリストのみで削除されます。永久に削除するなら、ファイルシステムからファイルを削除してください。
upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save Password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -15,7 +15,7 @@ initialize.button.ok = 보관함 만들기
initialize.messageLabel.alreadyInitialized = 이미 보관함이 초기화되었습니다.
initialize.messageLabel.initializationFailed = 보관함을 초기화할 수 없습니다. 자세한 사항은 로그 파일을 참조하세요.
# notfound.fxml
notfound.label = 보관함을 찾을 수 없습니다. 옮겨진 것은 아닌가요?
notfound.label = 보관함을 찾을 수 없습니다. 옮겨졌는지 확인해 주세요.
# upgrade.fxml
upgrade.button = 보관함 업그레이드
upgrade.version3dropBundleExtension.msg = 이 보관함은 새로운 형식으로 다시 바뀔 필요가 있습니다. "%1$s"의 이름은 "%2$s"로 바뀔 것입니다. 진행하기 전에 동기화가 완료되었는지 다시 한 번 확인해주시기 바랍니다.
@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = 모든 Cryptomator 버전
changePassword.button.change = 비밀번호 변경
changePassword.errorMessage.wrongPassword = 틀린 비밀번호
changePassword.errorMessage.decryptionFailed = 복호화 실패
changePassword.infoMessage.success = 비밀번호 변경
# unlocked.fxml
unlocked.button.lock = 보관함 잠그기
unlocked.moreOptions.reveal = 드라이브 표시
@@ -85,6 +84,16 @@ upgrade.version3to4.err.io = 입출력 예외 문제로 마이그레이션이
settings.prefGvfsScheme.label = WebDAV sceme
# upgrade.fxml
upgrade.confirmation.label = 네. 동기화가 완료되었음을 확인하였습니다.
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
initialize.messageLabel.notEmpty = 보관함이 비어있지 않음
unlock.label.savePassword = 비밀번호 저장
unlock.errorMessage.unauthenticVersionMac = 인증할 수 없는 버전의 맥입니다
unlocked.label.mountFailed = 드라이브 연결 실패
unlock.savePassword.delete.confirmation.title = 저장된 비밀번호 삭제
unlock.savePassword.delete.confirmation.header = 정말로 이 보관함의 저장된 비밀번호를 지우시겠습니까?
unlock.savePassword.delete.confirmation.content = 이 보관함의 저장된 비밀번호는 당신의 시스템 키체인에서 즉시 삭제될 것입니다. 다시 비밀번호를 저장하고 싶으시다면, 보관함을 열 때 "비밀번호 저장" 옵션을 활성화해야 합니다
settings.debugMode.label = 디버그 모드
upgrade.version3dropBundleExtension.title = 버전 3 보관함 업그레이드 (Drop Bundle Extension)
upgrade.version3to4.title = 보관함 버전 3에서 4로 업그레이드
upgrade.version4to5.title = 보관함 버전 4에서 5로 업그레이드
upgrade.version4to5.msg = 이 보관함은 새로운 포맷으로 이전되어야 합니다.\n암호화된 파일들은 업데이트 될 것입니다.\n진행하기 전에 동기화가 완료되었는지 확인해주세요.\n\n참고\: 모든 파일의 수정 날짜는 과정 진행 중에 현재 날짜/시간으로 바뀔 것입니다.
upgrade.version4to5.err.io = I/O 예외에 의해 마이그레이션 실패. 자세한 사항은 로그 파일을 참조하세요.

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Visas Cryptomator versijas
changePassword.button.change = Mainīt paroli
changePassword.errorMessage.wrongPassword = Nepareiza parole
changePassword.errorMessage.decryptionFailed = Atšifrēšana neizdevās
changePassword.infoMessage.success = Parole nomainīta
# unlocked.fxml
unlocked.button.lock = Aizslēgt glabātuvi
unlocked.moreOptions.reveal = Atklāt disku
@@ -87,5 +86,15 @@ settings.prefGvfsScheme.label = WebDAV shēma
# upgrade.fxml
upgrade.confirmation.label = Jā, esmu pārliecinājies, ka sinhronizācija ir pabeigta.
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlock.label.savePassword = Save Password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -2,22 +2,24 @@ app.name = Cryptomator
# main.fxml
main.emptyListInstructions = Klik hier om een kluis toe te voegen
main.directoryList.contextMenu.remove = Verwijder van lijst
main.directoryList.contextMenu.changePassword = Verander wachtwoord
main.addDirectory.contextMenu.new = Creeer nieuwe kluis
main.addDirectory.contextMenu.open = Open bestaande kluis
# The current Dutch translation of this string (and other, similar contexts) is not in accordance with Windows convention, which is to translate options like this with infinitivies and not imperatives, so "Wachtwoord wijzigen," not "Wijzig wachtwoord." MacOS uses imperatives in Dutch, not Windows.
main.directoryList.contextMenu.changePassword = Verander Wachtwoord
main.addDirectory.contextMenu.new = Maak Nieuwe Kluis
main.addDirectory.contextMenu.open = Open Bestaande Kluis
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Controleren op Updates...
welcome.checkForUpdates.label.currentlyChecking = Controleren op updates...
welcome.newVersionMessage = Versie %1$s kan worden gedownload.\nDit is %2$s.
# initialize.fxml
initialize.label.password = Wachtwoord
initialize.label.retypePassword = Voer wachtwoord opnieuw in
# This is not in accordance with Dutch conventions. Not only does it use an imperative, but 'create' is generally translated as 'maken' or 'aanmaken', not 'creëren'. So "Kluis maken."
initialize.button.ok = Creëer kluis
initialize.messageLabel.alreadyInitialized = Kluis reeds geïnitialiseerd
initialize.messageLabel.initializationFailed = Kon kluis niet initialiseren. Zie logbestand voor details.
# notfound.fxml
notfound.label = Kluis kon niet gevonden worden. Is de kluis wellicht verplaatst?
notfound.label = Kluis kon niet gevonden worden. Is hij verplaatst?
# upgrade.fxml
upgrade.button = Upgrade kluis
upgrade.button = Upgrade Kluis
upgrade.version3dropBundleExtension.msg = Deze kluis dient te worden gemigreerd naar een nieuwer type.\n"%1$s" zal worden hernoemd naar "%2$s".\nZorg ervoor dat de synchronisatie voltooid is alvorens door te gaan.
upgrade.version3dropBundleExtension.err.alreadyExists = Automatische migratie mislukt.\n"%s" bestaat al.
# unlock.fxml
@@ -25,30 +27,29 @@ unlock.label.password = Wachtwoord
unlock.label.mountName = Schijfnaam
unlock.label.winDriveLetter = Schijfletter
unlock.label.downloadsPageLink = Alle Cryptomator versies
unlock.label.advancedHeading = Geavanceerde opties
unlock.button.unlock = Ontgrendel kluis
unlock.button.advancedOptions.show = Meer opties
unlock.button.advancedOptions.hide = Minder opties
unlock.label.advancedHeading = Geavanceerde Opties
unlock.button.unlock = Ontgrendel Kluis
unlock.button.advancedOptions.show = Meer Opties
unlock.button.advancedOptions.hide = Minder Opties
unlock.choicebox.winDriveLetter.auto = Automatisch toekennen
unlock.errorMessage.wrongPassword = Verkeerd wachtwoord
unlock.errorMessage.mountingFailed = Mounten mislukt. Zie logbestand voor details.
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Niet ondersteunde kluis. Deze kluis is gecreëerd met een oudere versie van Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Niet ondersteunde kluis. Deze kluis is gecreëerd met een nieuwere versie van Cryptomator.
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Niet ondersteunde kluis. Deze kluis is gemaakt met een nieuwere versie van Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Niet ondersteunde kluis. Deze kluis is gemaakt met een nieuwere versie van Cryptomator.
unlock.messageLabel.startServerFailed = WebDAV server starten mislukt.
# change_password.fxml
changePassword.label.oldPassword = Huidig wachtwoord
changePassword.label.newPassword = Nieuw wachtwoord
changePassword.label.retypePassword = Herhaal wachtwoord
changePassword.label.oldPassword = Huidig Wachtwoord
changePassword.label.newPassword = Nieuw Wachtwoord
changePassword.label.retypePassword = Herhaal Wachtwoord
changePassword.label.downloadsPageLink = Alle Cryptomator versies
changePassword.button.change = Verander wachtwoord
changePassword.button.change = Verander Wachtwoord
changePassword.errorMessage.wrongPassword = Alle Cryptomator versies
changePassword.errorMessage.decryptionFailed = Decoderen mislukt
changePassword.infoMessage.success = Wachtwoord verandert
# unlocked.fxml
unlocked.button.lock = Vergrendel kluis
unlocked.moreOptions.reveal = Maak schijf zichtbaar
unlocked.moreOptions.copyUrl = Kopieer WebDAV URL
unlocked.label.revealFailed = Commando mislukt
unlocked.label.revealFailed = Opdracht mislukt
unlocked.label.unmountFailed = Uitwerpen schijf mislukt
unlocked.label.statsEncrypted = versleuteld
unlocked.label.statsDecrypted = gedecodeerd
@@ -57,7 +58,7 @@ unlocked.ioGraph.yAxis.label = Doorvoer (MiB/s)
macWarnings.windowTitle = Pas op - Corrupt bestand in %s
macWarnings.message = Cryptomator heeft mogelijk kwaadwillende corrupte items aangetroffen in de volgende bestanden\:
macWarnings.moreInformationButton = Leer meer
macWarnings.whitelistButton = Doorgaan met decoderen van selectie
macWarnings.whitelistButton = Geselecteerde toch Decoderen
# settings.fxml
settings.version.label = Versie %s
settings.checkForUpdates.label = Controleer op updates
@@ -68,9 +69,9 @@ settings.requiresRestartLabel = * Cryptomator dient te worden herstart
# tray icon
tray.menu.open = Open
tray.menu.quit = Afsluiten
tray.infoMsg.title = Nog steeds actief
tray.infoMsg.msg = Cryptomator is nog steeds actief. Sluit het af via het icon in het systeemvak.
tray.infoMsg.msg.osx = Cryptomator is nog steeds actief. Sluit het af via het icon op de menubalk.
tray.infoMsg.title = Nog Steeds Actief
tray.infoMsg.msg = Cryptomator is nog steeds actief. Sluit af via het icoon in het systeemvak.
tray.infoMsg.msg.osx = Cryptomator is nog steeds actief. Sluit af via het icoon op de menubalk.
initialize.messageLabel.passwordStrength.0 = Zeer zwak
initialize.messageLabel.passwordStrength.1 = Zwak
initialize.messageLabel.passwordStrength.2 = Redelijk
@@ -81,10 +82,20 @@ main.directoryList.remove.confirmation.title = Verwijder Kluis
main.directoryList.remove.confirmation.header = Weet je zeker dat je deze kluis wilt verwijderen?
main.directoryList.remove.confirmation.content = De kluis zal alleen van de lijst worden verwijdert. Verwijder de bestanden van het bestandssysteem voor permanente verwijdering.
upgrade.version3to4.msg = Deze kluis dient gemigreerd te worden naar een nieuwer type. \nVersleutelde mapnamen zullen worden geüpdatet. \nZorg ervoor dat de synchronisatie voltooid is alvorens door te gaan.
upgrade.version3to4.err.io = Migratie mislukt door een I/O Exception. Zie logbestand voor details.
settings.prefGvfsScheme.label = WebDAV scheme
upgrade.version3to4.err.io = I/O Exception\: migratie mislukt. Zie logbestand voor details.
settings.prefGvfsScheme.label = WebDAV schema
# upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
upgrade.confirmation.label = Ja, ik heb geverifieerd dat de synchronisatie voltooid is
initialize.messageLabel.notEmpty = Kluis niet leeg
unlock.label.savePassword = Wachtwoord Opslaan
unlock.errorMessage.unauthenticVersionMac = MAC authenticatie mislukt
unlocked.label.mountFailed = Verbinden van schijf mislukt
unlock.savePassword.delete.confirmation.title = Verwijder Opgeslagen Wachtwoord
unlock.savePassword.delete.confirmation.header = Ben je zeker dat je het opgeslagen wachtwoord van deze kluis wilt verwijderen?
unlock.savePassword.delete.confirmation.content = Het opgeslagen wachtwoord van deze kluis zal onmiddellijk verwijderd worden van je systeem sleutelhanger. Als je opnieuw je wachtwoord wilt opslaan, zal je je kluis moeten ontgrendelen met de optie "Sla wachtwoord op" aan.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Kluis Versie 3 Upgrade (Drop Bundel Extensie)
upgrade.version3to4.title = Kluis Versie 3 naar 4 Upgrade
upgrade.version4to5.title = Kluis Versie 4 naar 5 Upgrade
upgrade.version4to5.msg = Deze kluis moet gemigreerd worden naar een nieuw formaat.\nVersleutelde bestanden zullen bijgewerkt worden.\nZorg ervoor dat synchronisatie voltooid is alvorens verder te gaan.\n\nLet op\: Tijdens dit proces zal de wijzigingsdatum van alle bestanden gewijzigd worden naar de huidige datum/tijd.
upgrade.version4to5.err.io = Migratie mislukt door een I/O Exception. Bekijk log file voor details.

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Wszystkie wersje Cryptomatora
changePassword.button.change = Zmień hasło
changePassword.errorMessage.wrongPassword = Złe hasło
changePassword.errorMessage.decryptionFailed = Błąd deszyfracji
changePassword.infoMessage.success = Hasło zmienione
# unlocked.fxml
unlocked.button.lock = Zablokuj kryptę
unlocked.moreOptions.reveal = Zwolnij napęd
@@ -85,6 +84,16 @@ upgrade.version3to4.err.io = Błąd migracji I/O Exception. Sprawdź logi
settings.prefGvfsScheme.label = Schemat WebDAV
# upgrade.fxml
upgrade.confirmation.label = Tak, jestem pewien, że zakończyłem synchronizacje
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
initialize.messageLabel.notEmpty = Krypta pusta
unlock.label.savePassword = Zapisz hasło
unlock.errorMessage.unauthenticVersionMac = Nie udało się uwierzytelnić wersji MAC
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -1,24 +1,24 @@
app.name = Cryptomator
# main.fxml
main.emptyListInstructions = Clique aqui para adicionar uma caixa-forte
main.emptyListInstructions = Clique aqui para adicionar um cofre
main.directoryList.contextMenu.remove = Remover da lista
main.directoryList.contextMenu.changePassword = Alterar senha
main.addDirectory.contextMenu.new = Criar nova caixa-forte
main.addDirectory.contextMenu.open = Abrir caixa-forte existente
main.addDirectory.contextMenu.new = Criar um novo cofre
main.addDirectory.contextMenu.open = Abrir um cofre já existente
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Buscando por atualizações...
welcome.newVersionMessage = Versão %1$s pode ser abaixada. Esta é a versão %2$s.
welcome.newVersionMessage = Versão %1$s pode ser baixada. Esta é a versão %2$s.
# initialize.fxml
initialize.label.password = Senha
initialize.label.retypePassword = Redigitar senha
initialize.button.ok = Criar caixa-forte
initialize.messageLabel.alreadyInitialized = Caixa-forte já inicializada
initialize.messageLabel.initializationFailed = Não pôde inicializar a caixa-forte. Ver arquivo de log para mais detalhes.
initialize.label.retypePassword = Redigite a senha
initialize.button.ok = Criar cofre
initialize.messageLabel.alreadyInitialized = Cofre já inicializado
initialize.messageLabel.initializationFailed = Não pôde inicializar o cofre. Veja o arquivo de log para mais detalhes.
# notfound.fxml
notfound.label = A caixa-forte não pode ser encontrada. Ela foi movida?
notfound.label = O cofre não pode ser encontrado. Pode ter sido movido?
# upgrade.fxml
upgrade.button = Atualizar caixa-forte
upgrade.version3dropBundleExtension.msg = Esta caixa-forte tem que ser a migrada a um novo formato. "%1$s" será renomeada para "%2$s". Por favor assegure-se de que a sincronização foi finalizada antes de proceder com a migração.
upgrade.button = Atualizar cofre
upgrade.version3dropBundleExtension.msg = Esse cofre tem que ser migrado paraa um novo formato. "%1$s" será renomeada para "%2$s". Por favor assegure-se de que a sincronização foi finalizada antes de proceder com a migração.
upgrade.version3dropBundleExtension.err.alreadyExists = A migração automática falhou. "%s" já existe.
# unlock.fxml
unlock.label.password = Senha
@@ -26,45 +26,46 @@ unlock.label.mountName = Nome do drive
unlock.label.winDriveLetter = Letra do drive
unlock.label.downloadsPageLink = Todas as versões do Cryptomator
unlock.label.advancedHeading = Opções avançadas
unlock.button.unlock = Abrir caixa-forte
unlock.button.unlock = Abrir cofre
unlock.button.advancedOptions.show = Mais opções
unlock.button.advancedOptions.hide = Menos opções
unlock.choicebox.winDriveLetter.auto = Atribuir automaticamente
unlock.errorMessage.wrongPassword = Senha errada
unlock.errorMessage.mountingFailed = Falha ao montar. Ver arquivo de log para mais detalhes.
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Caixa-forte não suportada. Esta caixa-forte foi criada por uma versão antiga do Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Caixa-forte não suportada. Esta caixa-forte foi criada por uma versão mais nova do Cryptomator.
unlock.errorMessage.mountingFailed = Falha ao montar. Veja o arquivo de log para mais detalhes.
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Cofre não suportado. Esse cofre foi criado por uma versão antiga do Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Cofre não suportado. Esse cofre foi criado por uma versão mais nova do Cryptomator.
unlock.messageLabel.startServerFailed = Falha ao iniciar servidor WebDAV.
# change_password.fxml
changePassword.label.oldPassword = Senha anterior
changePassword.label.oldPassword = Senha atual
changePassword.label.newPassword = Nova senha
changePassword.label.retypePassword = Re-digitar senha
changePassword.label.downloadsPageLink = Todas as versões do Cryptomator
changePassword.button.change = Alterar senha
changePassword.errorMessage.wrongPassword = Senha incorreta
changePassword.errorMessage.decryptionFailed = Falha ao desencriptar
changePassword.infoMessage.success = Senha alterada
# unlocked.fxml
unlocked.button.lock = Fechar caixa-forte
unlocked.button.lock = Fechar cofre
unlocked.moreOptions.reveal = Mostrar drive
unlocked.moreOptions.copyUrl = Copiar URL WebDAV
unlocked.label.revealFailed = Falha ao mostrar drive
unlocked.label.unmountFailed = Falha ao ejetar drive
unlocked.label.statsEncrypted = encriptado
unlocked.label.statsDecrypted = desencriptado
unlocked.label.statsEncrypted = Encriptado
unlocked.label.statsDecrypted = Desencriptado
unlocked.ioGraph.yAxis.label = Taxa de transferência (MiB/s)
# mac_warnings.fxml
macWarnings.windowTitle = Perigo - Arquivo corrompido na %s
# Fuzzy
macWarnings.message = Cryptomator detectou potenciais corrupções maliciosas nos seguintes arquivos\:
macWarnings.moreInformationButton = Saiba mais
# Fuzzy
macWarnings.whitelistButton = Desencriptar selecionado de qualquer modo
# settings.fxml
settings.version.label = Versão %s
settings.checkForUpdates.label = Verificar por atualizações
settings.port.label = Port WebDAV *
settings.port.label = Porta WebDAV *
settings.port.prompt = 0 \= Escolher automaticamente
settings.useipv6.label = Usar IPv6 literal
settings.requiresRestartLabel = * Cryptomator necessita ser reiniciado
settings.requiresRestartLabel = * Cryptomator precisa ser reiniciado
# tray icon
tray.menu.open = Abrir
tray.menu.quit = Sair
@@ -77,14 +78,24 @@ initialize.messageLabel.passwordStrength.2 = Razoável
initialize.messageLabel.passwordStrength.3 = Forte
initialize.messageLabel.passwordStrength.4 = Muito forte
initialize.label.doNotForget = IMPORTANTE\: se você esquecer a sua senha, não haverá como recuperar os seus dados.
main.directoryList.remove.confirmation.title = Remover caixa-forte
main.directoryList.remove.confirmation.header = Você realmente quer remover esta caixa-forte?
main.directoryList.remove.confirmation.content = A caixa-forte somente será removida da lista. Para apagá-la permanentemente, por favor apagar os arquivos do seu sistema de arquivos.
upgrade.version3to4.msg = Esta caixa-forte tem que ser migrada a um novo formato. Os nomes das pastas encriptadas serão atualizados. Por favor assegure-se de que a sincronização foi finalizada antes de proceder com a migração.
upgrade.version3to4.err.io = Falha na migração devido a um erro de E/S. Ver arquivo de log para mais detalhes.
settings.prefGvfsScheme.label = WebDAV scheme
main.directoryList.remove.confirmation.title = Remover cofre
main.directoryList.remove.confirmation.header = Você realmente quer remover esse cofre?
main.directoryList.remove.confirmation.content = O cofre somente será removido da lista. Para apagá-lo permanentemente, por favor apagar os arquivos do seu sistema de arquivos.
upgrade.version3to4.msg = Esse cofre tem que ser migrado a um novo formato. Os nomes das pastas encriptadas serão atualizados. Por favor, assegure-se de que a sincronização do cofre foi finalizada antes de proceder com a sua migração.
upgrade.version3to4.err.io = Falha na migração devido a um erro de E/S. Veja o arquivo de log para mais detalhes.
settings.prefGvfsScheme.label = Esquema WebDAV
# upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
upgrade.confirmation.label = Sim, tenho certeza de que a sincronização foi concluída
initialize.messageLabel.notEmpty = Cofre não vazio
unlock.label.savePassword = Armazenar senha
unlock.errorMessage.unauthenticVersionMac = Não foi possível autenticar a versão do MAC.
unlocked.label.mountFailed = Falha ao conectar o drive
unlock.savePassword.delete.confirmation.title = Apagar a senha armazenada
unlock.savePassword.delete.confirmation.header = Você realmente quer apagar a senha armazenada deste cofre?
unlock.savePassword.delete.confirmation.content = A senha deste cofre que se encontra armazenada será imediatamente apagada do gestor de senhas do seu sistema. Se você quiser armazenar a sua senha novamente, você terá que abrir o seu cofre com a opção "Armazenar Senha" habilitada.
settings.debugMode.label = Modo de Debug *
upgrade.version3dropBundleExtension.title = Atualização para a versão 3 do cofre (Drop Bundle Extension)
upgrade.version3to4.title = Atualização do cofre da versão 3 para 4
upgrade.version4to5.title = Atualização do cofre da versão 4 para 5
upgrade.version4to5.msg = Este cofre precisa ser migrado a um novo formato.\nOs arquivos encriptados serão atualizados.\nPor favor, assegure-se de que a sincronização do cofre foi finalizada antes de proceder com a sua migração.\n\nNota\: A data de modificação de todos os arquivos do cofre será alterada durante o processo para a data e hora corrente.
upgrade.version4to5.err.io = A migração falhou devido a uma exceção de I/O. Ver arquivo de log para mais detalhes.

View File

@@ -44,7 +44,6 @@ changePassword.label.downloadsPageLink = Все версии Cryptomator
changePassword.button.change = Сменить пароль
changePassword.errorMessage.wrongPassword = Неверный пароль
changePassword.errorMessage.decryptionFailed = Ошибка дешифрования
changePassword.infoMessage.success = Пароль изменён
# unlocked.fxml
unlocked.button.lock = Заблокировать хранилище
# Does it mean "open" drive?
@@ -87,6 +86,16 @@ upgrade.version3to4.err.io = Преобразование не выполнен
settings.prefGvfsScheme.label = Схема WebDAV
# upgrade.fxml
upgrade.confirmation.label = Да, синхронизация точно завершена
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
initialize.messageLabel.notEmpty = Хранилище не пусто
unlock.label.savePassword = Сохранить пароль
unlock.errorMessage.unauthenticVersionMac = Не удалось идентифицировать версию MAC.
unlocked.label.mountFailed = Ошибка подключения к диску
unlock.savePassword.delete.confirmation.title = Удалить сохранённый пароль
unlock.savePassword.delete.confirmation.header = Вы действительно хотите удалить сохранённый пароль для этого хранилища?
unlock.savePassword.delete.confirmation.content = Сохранённый пароль от этого хранилища будет немедленно удалён из системной связки ключей. Если вы снова захотите сохранить пароль, вам придётся разблокировать хранилище с включённой опцией "Сохранить пароль".
settings.debugMode.label = Режим отладки *
upgrade.version3dropBundleExtension.title = Обновление хранилища версии 3 (Drop Bundle Extension)
upgrade.version3to4.title = Обновление хранилища с версии 3 на 4
upgrade.version4to5.title = Обновление хранилища с версии 4 на 5
upgrade.version4to5.msg = Это хранилище нужно преобразовать в более новый формат.\nЗашифрованные файлы будут обновлены.\nПрежде чем продолжить, убедитесь, что завершена синхронизация.\n\nПримечание\: даты изменения всех файлов будут изменены на текущие дату и время на момент обработки.
upgrade.version4to5.err.io = Преобразование не выполнено из-за исключения ввода-вывода. См. подробности в отчёте.

View File

@@ -46,7 +46,6 @@ changePassword.label.downloadsPageLink = Všetky verzie Cryptomatoru.
changePassword.button.change = Zmeniť heslo
changePassword.errorMessage.wrongPassword = Nesprávne heslo
changePassword.errorMessage.decryptionFailed = Dešifrovanie zlyhalo.
changePassword.infoMessage.success = Heslo zmenené
# unlocked.fxml
unlocked.button.lock = Zamknúť trezor
unlocked.moreOptions.reveal = Odhaliť jednotku
@@ -74,20 +73,30 @@ tray.menu.quit = Vypnúť
tray.infoMsg.title = Stále beží
tray.infoMsg.msg = Cryptomator je stále spustený. Vypnite ho pomocou ikony v systémovej lište.
tray.infoMsg.msg.osx = Cryptomator je stále sputený. Ukončite ho pomocou ikony v menu.
initialize.messageLabel.passwordStrength.0 = Very weak
initialize.messageLabel.passwordStrength.1 = Weak
initialize.messageLabel.passwordStrength.2 = Fair
initialize.messageLabel.passwordStrength.3 = Strong
initialize.messageLabel.passwordStrength.4 = Very strong
initialize.label.doNotForget = IMPORTANT\: If you forget your password, there is no way to recover your data.
main.directoryList.remove.confirmation.title = Remove Vault
main.directoryList.remove.confirmation.header = Do you really want to remove this vault?
main.directoryList.remove.confirmation.content = The vault will only be removed from the list. To permanently delete it, please delete the files from your filesystem.
initialize.messageLabel.passwordStrength.0 = Veľmi slabé
initialize.messageLabel.passwordStrength.1 = Slabé
initialize.messageLabel.passwordStrength.2 = Dobré
initialize.messageLabel.passwordStrength.3 = Silné
initialize.messageLabel.passwordStrength.4 = Veľmi silné
initialize.label.doNotForget = DÔLEŽITÉ\: Ak zabudnete heslo, nie je možné získať späť vaše dáta.
main.directoryList.remove.confirmation.title = Odstrániť trezor
main.directoryList.remove.confirmation.header = Skutočne chcete odstrániť tento trezor?
main.directoryList.remove.confirmation.content = Trezor bude odstránení zo zoznamu. Pre úplné zmazanie vymažte súbor s trezorom.
upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.prefGvfsScheme.label = WebDAV scheme
upgrade.version3to4.err.io = Migrácia zlyhala kvôli I/O Exception. Skontrolujte log pre viac detailov
settings.prefGvfsScheme.label = WebDAV Schéma
# upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
upgrade.confirmation.label = Áno, som si istý že synchronizácia je hotová
initialize.messageLabel.notEmpty = Trezor nie je prázdny
unlock.label.savePassword = Uložiť heslo
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Zmazať uložené heslo
unlock.savePassword.delete.confirmation.header = Naozaj chcete zmazať uložené heslo pre tento trezor?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Tüm Cryptomator sürümleri
changePassword.button.change = Şifreyi değiştir
changePassword.errorMessage.wrongPassword = Yanlış şifre
changePassword.errorMessage.decryptionFailed = Şifre çözme başarısız
changePassword.infoMessage.success = Şifre değiştirildi.
# unlocked.fxml
unlocked.button.lock = Kasayı kilitle
unlocked.moreOptions.reveal = Sürücüyü göster
@@ -82,9 +81,19 @@ main.directoryList.remove.confirmation.header = Kasayı silmek istediğinize emi
main.directoryList.remove.confirmation.content = Kasa yalnızca listeden silinecek. Tamamen silmek için dosya sisteminizden dosyaları elle siliniz.
upgrade.version3to4.msg = Bu kasanın yeni formata geçirilmesi gerekmekte. Şifreli klasör isimleri güncellenecek. Devam etmeden önce senkronizasyonun bittiğine emin olun.
upgrade.version3to4.err.io = Format değiştirme işlemi I/O Hatası dolayısı ile başarısız oldu. Detaylar için log dosyasına bakın
settings.prefGvfsScheme.label = WebDAV scheme
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlock.label.savePassword = Save Password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Всі версії Cryptomator
changePassword.button.change = Змінити пароль
changePassword.errorMessage.wrongPassword = Пароль невірний
changePassword.errorMessage.decryptionFailed = Розшифрування невдале
changePassword.infoMessage.success = Пароль змінений
# unlocked.fxml
unlocked.button.lock = Заблокувати сховище
unlocked.moreOptions.reveal = Відкрити накопичувач
@@ -82,9 +81,19 @@ main.directoryList.remove.confirmation.header = Ви дійсно хочете
main.directoryList.remove.confirmation.content = Сховище буде видалене тільки зі списку. Щоб стерти його остаточно, видаліть файли із файлової системи.
upgrade.version3to4.msg = Це сховище необхідно перетворити в новий формат. Зашифровані імена папок будуть оновлені. Перш ніж продовжити, виконайте синхронізацію.
upgrade.version3to4.err.io = Перетворення невдале через помилку введення-виведення. Дивіться деталі в файлі-звіті.
settings.prefGvfsScheme.label = WebDAV scheme
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlock.label.savePassword = Save Password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -0,0 +1,101 @@
app.name = Cryptomator
# main.fxml
main.emptyListInstructions = 单击此处添加保管库
main.directoryList.contextMenu.remove = 从列表中删除
main.directoryList.contextMenu.changePassword = 更改密码
main.addDirectory.contextMenu.new = 创建新保管库
main.addDirectory.contextMenu.open = 打开现有保管库
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = 正在检查更新……
welcome.newVersionMessage = 发现新版本版本%1$s\n当前版本%2$s
# initialize.fxml
initialize.label.password = 密码
initialize.label.retypePassword = 确认密码
initialize.button.ok = 创建保管库
initialize.messageLabel.alreadyInitialized = 保管库已初始化
initialize.messageLabel.initializationFailed = 无法初始化保管库。 有关详情,请参阅日志文件。
# notfound.fxml
notfound.label = 找不到保险柜。 是否已被移动?
# upgrade.fxml
upgrade.button = 升级保险柜
upgrade.version3dropBundleExtension.msg = 此保管库需要迁移到较新的格式。\n"%1$s"将重命名为"%2$s"。\n请确保同步已完成然后再继续。
upgrade.version3dropBundleExtension.err.alreadyExists = 自动迁移失败。\n"%s"已存在
# unlock.fxml
unlock.label.password = 密码
unlock.label.mountName = 驱动器名称
unlock.label.winDriveLetter = 驱动器号
unlock.label.downloadsPageLink = 所有Cryptomator版本
unlock.label.advancedHeading = 高级选项
unlock.button.unlock = 保险柜解锁
unlock.button.advancedOptions.show = 更多选项
unlock.button.advancedOptions.hide = 更少选项
unlock.choicebox.winDriveLetter.auto = 自动分配
unlock.errorMessage.wrongPassword = 密码错误
unlock.errorMessage.mountingFailed = 挂载失败。有关详情,请参阅日志文件。
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = 不支持的保管库。 此保管库由旧版本的Cryptomator创建。
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = 不支持的保管库。 此保管库由较新版本的Cryptomator创建。
unlock.messageLabel.startServerFailed = 启动WebDAV服务器失败。
# change_password.fxml
changePassword.label.oldPassword = 旧密码
changePassword.label.newPassword = 新密码
changePassword.label.retypePassword = 确认新密码
changePassword.label.downloadsPageLink = 所有Cryptomator版本
changePassword.button.change = 更改密码
changePassword.errorMessage.wrongPassword = 密码错误
changePassword.errorMessage.decryptionFailed = 解密失败
# unlocked.fxml
unlocked.button.lock = 保险柜上锁
unlocked.moreOptions.reveal = 显示驱动器
unlocked.moreOptions.copyUrl = 复制WebDAV地址(URL)
unlocked.label.revealFailed = 命令失败
unlocked.label.unmountFailed = 弹出驱动器失败
unlocked.label.statsEncrypted = 加密
unlocked.label.statsDecrypted = 解密
unlocked.ioGraph.yAxis.label = 吞吐量(Mib/s)
# mac_warnings.fxml
macWarnings.windowTitle = 危险 - 在%s有文件损坏
macWarnings.message = Cryptomator检测到以下文件中的潜在恶意损坏
macWarnings.moreInformationButton = 了解更多
macWarnings.whitelistButton = 任然解密选择项
# settings.fxml
settings.version.label = 版本%s
settings.checkForUpdates.label = 检查更新
# What's the "*" mean?
settings.port.label = WebDAV 端口 *
settings.port.prompt = 0 \=自动选择
settings.useipv6.label = 使用IPv6
settings.requiresRestartLabel = * Cryptomator需要重新启动
# tray icon
tray.menu.open = 打开
tray.menu.quit = 退出
tray.infoMsg.title = 仍在运行
tray.infoMsg.msg = Cryptomator仍在运行。 从托盘图标中退出。
tray.infoMsg.msg.osx = Cryptomator仍在运行。 从菜单栏图标中退出。
initialize.messageLabel.passwordStrength.0 = 非常简单
initialize.messageLabel.passwordStrength.1 = 简单
initialize.messageLabel.passwordStrength.2 = 平均水平
initialize.messageLabel.passwordStrength.3 = 强壮
initialize.messageLabel.passwordStrength.4 = 非常强壮
initialize.label.doNotForget = 重要信息:如果您忘记了密码,将无法恢复您的数据。
main.directoryList.remove.confirmation.title = 移除保险柜
main.directoryList.remove.confirmation.header = 您确定要删除此保管库吗?
main.directoryList.remove.confirmation.content = 文件库将仅从列表中删除。 要永久删除它,请从文件系统中删除这些文件。
upgrade.version3to4.msg = 此保管库需要迁移到较新的格式。\n加密的文件夹名称将更新。\n请确保同步已完成然后再继续。
upgrade.version3to4.err.io = 由于I/O异常迁移失败。有关详情请参阅日志文件。
settings.prefGvfsScheme.label = WebDAV方案
# upgrade.fxml
upgrade.confirmation.label = 是的,我确保同步已完成
initialize.messageLabel.notEmpty = 保险柜非空
unlock.label.savePassword = 保存密码
# This Mac means Mac(Apple) or Mac address?
unlock.errorMessage.unauthenticVersionMac = 无法验证消息验证代码的版本。
unlocked.label.mountFailed = 连接设备失败
unlock.savePassword.delete.confirmation.title = 删除已保存的密码
unlock.savePassword.delete.confirmation.header = 您真的要删除此密码库已保存的密码吗?
unlock.savePassword.delete.confirmation.content = 此密码库保存的密码将立即从系统钥匙串中删除。如果您想再次保存密码,则必须通过启用“保存密码”选项启用您的密码库。
settings.debugMode.label = 调试模式 *
upgrade.version3dropBundleExtension.title = 升级Vault版本3Drop Bundle Extension
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -0,0 +1,99 @@
app.name = Cryptomator
# main.fxml
main.emptyListInstructions = 按這裡新增檔案庫
main.directoryList.contextMenu.remove = 從清單移除
main.directoryList.contextMenu.changePassword = 變更密碼
main.addDirectory.contextMenu.new = 建立新的檔案庫
main.addDirectory.contextMenu.open = 打開現有的檔案庫
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = 檢查更新...
welcome.newVersionMessage = 版本%1$s可下載。這是%2$s。
# initialize.fxml
initialize.label.password = 密碼
initialize.label.retypePassword = 重新輸入密碼
initialize.button.ok = 建立檔案庫
initialize.messageLabel.alreadyInitialized = 已初始化檔案庫
initialize.messageLabel.initializationFailed = 無法初始化檔案庫。取得詳細資訊,請查看紀錄。
# notfound.fxml
notfound.label = 無法找到檔案庫。已經移置別的地方?
# upgrade.fxml
upgrade.button = 升級檔案庫
upgrade.version3dropBundleExtension.msg = 這個檔案庫需要被轉移到新的格式。\n"%1$s"將會重新命名為"%2$s"。\n在進行之前請確認同步已完成。
upgrade.version3dropBundleExtension.err.alreadyExists = 自動轉移失敗。\n"%s"已存在。
# unlock.fxml
unlock.label.password = 密碼
unlock.label.mountName = 磁碟名稱
unlock.label.winDriveLetter = 磁碟代號
unlock.label.downloadsPageLink = 所有的Cryptomator版本
unlock.label.advancedHeading = 進階選項
unlock.button.unlock = 解鎖檔案庫
unlock.button.advancedOptions.show = 更多選項
unlock.button.advancedOptions.hide = 更少選項
unlock.choicebox.winDriveLetter.auto = 自動指定
unlock.errorMessage.wrongPassword = 錯誤的密碼
unlock.errorMessage.mountingFailed = 掛載失敗。取得詳細資訊,請查看紀錄。
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = 不支援的檔案庫。這個檔案庫是由舊版本的Cryptomator所建立的。
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = 不支援的檔案庫。這個檔案庫是由新版本的Cryptomator所建立的。
unlock.messageLabel.startServerFailed = 啟動WebDAV的伺服器失敗。
# change_password.fxml
changePassword.label.oldPassword = 舊密碼
changePassword.label.newPassword = 新密碼
changePassword.label.retypePassword = 重新輸入密碼
changePassword.label.downloadsPageLink = 所有的Cryptomator版本
changePassword.button.change = 變更密碼
changePassword.errorMessage.wrongPassword = 錯誤的密碼
changePassword.errorMessage.decryptionFailed = 解密失敗
# unlocked.fxml
unlocked.button.lock = 鎖住檔案庫
unlocked.moreOptions.reveal = 打開磁碟
unlocked.moreOptions.copyUrl = 複製WebDAV的網址
unlocked.label.revealFailed = 指令錯誤
unlocked.label.unmountFailed = 插入磁碟錯誤
unlocked.label.statsEncrypted = 加密的
unlocked.label.statsDecrypted = 解密的
unlocked.ioGraph.yAxis.label = 傳輸量MIB / S
# mac_warnings.fxml
macWarnings.windowTitle = 危險 - 損壞的檔案在%s
macWarnings.message = Cryptomator在下列檔案中偵測到潛在的損壞威脅
macWarnings.moreInformationButton = 取得更多
macWarnings.whitelistButton = 總是解密所選的
# settings.fxml
settings.version.label = 版本%s
settings.checkForUpdates.label = 檢查更新
settings.port.label = WebDAV的埠號*
settings.port.prompt = 0 \=自動選擇
settings.useipv6.label = 使用IPv6
settings.requiresRestartLabel = * Cryptomator需要更新
# tray icon
tray.menu.open = 打開
tray.menu.quit = 離開
tray.infoMsg.title = 仍然在執行
tray.infoMsg.msg = Cryptomator仍然在運作。從工具列的圖示點選離開。
tray.infoMsg.msg.osx = Cryptomator仍然在運作。從選單列上點選離開。
initialize.messageLabel.passwordStrength.0 = 非常弱的
initialize.messageLabel.passwordStrength.1 = 弱的
initialize.messageLabel.passwordStrength.2 = 正常的
initialize.messageLabel.passwordStrength.3 = 強的
initialize.messageLabel.passwordStrength.4 = 非常強的
initialize.label.doNotForget = 重要:如果你忘記的密碼,就無法還原你的資料。
main.directoryList.remove.confirmation.title = 移除檔案庫
main.directoryList.remove.confirmation.header = 你真的想要移除這個檔案庫?
main.directoryList.remove.confirmation.content = 這個檔案庫只會從清單中移除。如果要永久刪除,請從檔案系統中刪除。
upgrade.version3to4.msg = 這個檔案庫需要被轉移到新的格式。\n加密的資料夾名稱將會被更新。\n在進行之前請確認同步已完成。
upgrade.version3to4.err.io = 由於I/O的例外轉移失敗。取得詳細資訊請查看紀錄。
settings.prefGvfsScheme.label = WebDAV的格式
# upgrade.fxml
upgrade.confirmation.label = 是的,請確認同步已完成。
initialize.messageLabel.notEmpty = 檔案庫不是空的
unlock.label.savePassword = 儲存密碼
unlock.errorMessage.unauthenticVersionMac = 無法認證消息驗證碼版本。
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -0,0 +1,99 @@
app.name = Cryptomator
# main.fxml
main.emptyListInstructions = 按這裡新增檔案庫
main.directoryList.contextMenu.remove = 從清單移除
main.directoryList.contextMenu.changePassword = 變更密碼
main.addDirectory.contextMenu.new = 建立新的檔案庫
main.addDirectory.contextMenu.open = 打開現有的檔案庫
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = 檢查更新...
welcome.newVersionMessage = 版本 %1$s 可下載。這是 %2$s 。
# initialize.fxml
initialize.label.password = 密碼
initialize.label.retypePassword = 重新輸入密碼
initialize.button.ok = 建立檔案庫
initialize.messageLabel.alreadyInitialized = 已初始化檔案庫
initialize.messageLabel.initializationFailed = 無法初始化檔案庫。取得詳細資訊,請查看紀錄。
# notfound.fxml
notfound.label = 無法找到檔案庫。已經移置別的地方?
# upgrade.fxml
upgrade.button = 升級檔案庫
upgrade.version3dropBundleExtension.msg = 這個檔案庫需要被轉移到新的格式。\n"%1$s" 將會重新命名為 "%2$s"。\n在進行之前請確認同步已完成。
upgrade.version3dropBundleExtension.err.alreadyExists = 自動轉移失敗。\n"%s" 已存在。
# unlock.fxml
unlock.label.password = 密碼
unlock.label.mountName = 磁碟名稱
unlock.label.winDriveLetter = 磁碟代號
unlock.label.downloadsPageLink = 所有的 Cryptomator 版本
unlock.label.advancedHeading = 進階選項
unlock.button.unlock = 解鎖檔案庫
unlock.button.advancedOptions.show = 更多選項
unlock.button.advancedOptions.hide = 更少選項
unlock.choicebox.winDriveLetter.auto = 自動指定
unlock.errorMessage.wrongPassword = 錯誤的密碼
unlock.errorMessage.mountingFailed = 掛載失敗。取得詳細資訊,請查看紀錄。
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = 不支援的檔案庫。這個檔案庫是由舊版本的 Cryptomator 所建立的。
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = 不支援的檔案庫。這個檔案庫是由新版本的 Cryptomator 所建立的。
unlock.messageLabel.startServerFailed = 啟動 WebDAV 伺服器失敗。
# change_password.fxml
changePassword.label.oldPassword = 舊密碼
changePassword.label.newPassword = 新密碼
changePassword.label.retypePassword = 重新輸入密碼
changePassword.label.downloadsPageLink = 所有的 Cryptomator 版本
changePassword.button.change = 變更密碼
changePassword.errorMessage.wrongPassword = 錯誤的密碼
changePassword.errorMessage.decryptionFailed = 解密失敗
# unlocked.fxml
unlocked.button.lock = 鎖住檔案庫
unlocked.moreOptions.reveal = 打開磁碟
unlocked.moreOptions.copyUrl = 複製 WebDAV 網址
unlocked.label.revealFailed = 指令錯誤
unlocked.label.unmountFailed = 插入磁碟錯誤
unlocked.label.statsEncrypted = 加密的
unlocked.label.statsDecrypted = 解密的
unlocked.ioGraph.yAxis.label = 傳輸量 (MiB/s)
# mac_warnings.fxml
macWarnings.windowTitle = 危險 - 損壞的檔案在 %s
macWarnings.message = Cryptomator 在下列檔案中,偵測到潛在的損壞威脅:
macWarnings.moreInformationButton = 取得更多
macWarnings.whitelistButton = 總是解密所選的
# settings.fxml
settings.version.label = 版本 %s
settings.checkForUpdates.label = 檢查更新
settings.port.label = WebDAV 埠號 *
settings.port.prompt = 0 \= 自動選擇
settings.useipv6.label = 使用 IPv6 literal
settings.requiresRestartLabel = * Cryptomator 需要更新
# tray icon
tray.menu.open = 打開
tray.menu.quit = 離開
tray.infoMsg.title = 仍然在執行
tray.infoMsg.msg = Cryptomator 仍然在運作。從工具列的圖示點選離開。
tray.infoMsg.msg.osx = Cryptomator 仍然在運作。從選單列上點選離開。
initialize.messageLabel.passwordStrength.0 = 非常弱的
initialize.messageLabel.passwordStrength.1 = 弱的
initialize.messageLabel.passwordStrength.2 = 正常的
initialize.messageLabel.passwordStrength.3 = 強的
initialize.messageLabel.passwordStrength.4 = 非常強的
initialize.label.doNotForget = 重要:如果你忘記的密碼,就無法還原你的資料。
main.directoryList.remove.confirmation.title = 移除檔案庫
main.directoryList.remove.confirmation.header = 你真的想要移除這個檔案庫?
main.directoryList.remove.confirmation.content = 這個檔案庫只會從清單中移除。如果要永久刪除,請從檔案系統中刪除。
upgrade.version3to4.msg = 這個檔案庫需要被轉移到新的格式。\n加密的資料夾名稱將會被更新。\n在進行之前請確認同步已完成。
upgrade.version3to4.err.io = 由於 I/O 的例外,轉移失敗。取得詳細資訊,請查看紀錄。
settings.prefGvfsScheme.label = WebDAV 格式
# upgrade.fxml
upgrade.confirmation.label = 是的,請確認同步已完成。
initialize.messageLabel.notEmpty = 檔案庫不是空的
unlock.label.savePassword = 儲存密碼
unlock.errorMessage.unauthenticVersionMac = 無法認證消息驗證碼版本。
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -27,9 +27,13 @@
</Appenders>
<Loggers>
<!-- package-specific config: -->
<Logger name="org.cryptomator" level="DEBUG" />
<Logger name="org.eclipse.jetty.server.Server" level="DEBUG" />
<!--
= NOTE =
All loggers below are set to info.
This is required to allow changing the levels of the loggers programmatically.
-->
<Logger name="org.cryptomator" level="INFO" />
<Logger name="org.eclipse.jetty.server.Server" level="INFO" />
<Logger name="org.cryptomator.ui.model" level="INFO">
<AppenderRef ref="UpgradeLog" />
</Logger>

View File

@@ -6,7 +6,7 @@
* Contributors:
* Sebastian Stenzel - initial API and implementation
*******************************************************************************/
package org.cryptomator.ui;
package org.cryptomator.ui.settings;
import java.io.IOException;
import java.io.InputStream;
@@ -31,7 +31,8 @@ public class LocalizationTest {
private static final Logger LOG = LoggerFactory.getLogger(LocalizationTest.class);
private static final String RESOURCE_FOLDER_PATH = "/localization/";
private static final String REF_FILE_NAME = "en.txt";
private static final String[] LANG_FILE_NAMES = {"de.txt", "es.txt", "fr.txt", "hu.txt", "it.txt", "kr.txt", "lv.txt", "nl.txt", "pl.txt", "pt.txt", "ru.txt", "sk.txt", "tr.txt", "uk.txt"};
private static final String[] LANG_FILE_NAMES = {"de.txt", "es.txt", "fr.txt", "hu.txt", "it.txt", "ja.txt", "kr.txt", "lv.txt", "nl.txt", "pl.txt", "pt.txt", "ru.txt", "sk.txt", "tr.txt", "uk.txt", "zh_HK.txt",
"zh_TW.txt", "zh.txt"};
/*
* @see Formatter