Compare commits

...
Author SHA1 Message Date
Sebastian Stenzel 845189c638 experimental smooth I/O charts 2021-03-30 11:58:31 +02:00
Armin Schrenk 61b7a39aad change level of a log message from warn to debug
[ci skip]
2021-03-29 10:53:48 +02:00
Tobias HagemannandGitHub 16bd84ee62 Update README.md
[ci skip]
2021-03-26 10:46:49 +01:00
Tobias HagemannandGitHub 3d0a97fcdf Update README.md
[ci skip]
2021-03-25 17:06:15 +01:00
Armin Schrenk b199b65e38 closes #176 2021-03-22 12:51:07 +01:00
Tobias HagemannandGitHub 999abf3c13 Update README.md
[ci skip]
2021-03-22 12:24:54 +01:00
Sebastian StenzelandGitHub 31e938de6a Merge pull request #1587 from cryptomator/feature/jdk-16
Update to JDK 16
2021-03-17 12:29:29 +01:00
Sebastian Stenzel 4c10ab764a updated README 2021-03-17 09:33:43 +01:00
Sebastian Stenzel 4e075ab0ca using pattern-matching instanceof where applicable 2021-03-17 09:22:16 +01:00
Sebastian Stenzel f73ae9759f use new Stream.toList() where applicable 2021-03-17 09:16:44 +01:00
Sebastian Stenzel f6283b2f7e using text blocks where applicable 2021-03-17 09:12:54 +01:00
Sebastian Stenzel b23d2e4def allow use of reflection in codacy coverage reporter 2021-03-17 08:19:58 +01:00
Sebastian Stenzel 91a2943599 update to JDK 16 2021-03-17 08:16:26 +01:00
Sebastian Stenzel e083fd0bcc skip certain steps on forks 2021-03-02 11:55:20 +01:00
ff687f1bae fix: main/pom.xml to reduce vulnerabilities (#1569)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JAVA-ORGECLIPSEJETTY-1080611

Co-authored-by: snyk-bot <snyk-bot@snyk.io>
2021-03-02 08:43:10 +01:00
Sebastian Stenzel 84d2644f19 fix wrong versions that have been merged from main branch 2021-02-26 10:05:26 +01:00
Armin Schrenk f9a9d7b870 Merge tag '1.5.13' into develop
1.5.13
2021-02-24 16:21:07 +01:00
26 changed files with 182 additions and 70 deletions
+7 -6
View File
@@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-java@v1 - uses: actions/setup-java@v1
with: with:
java-version: 14 java-version: 16
- uses: actions/cache@v1 - uses: actions/cache@v1
with: with:
path: ~/.m2/repository path: ~/.m2/repository
@@ -25,12 +25,13 @@ jobs:
- name: Build and Test - name: Build and Test
run: mvn -B install --file main/pom.xml -Pcoverage run: mvn -B install --file main/pom.xml -Pcoverage
- name: Run Codacy Coverage Reporter - name: Run Codacy Coverage Reporter
if: github.repository == 'cryptomator/cryptomator'
run: | run: |
curl -o ~/codacy-coverage-reporter.jar https://repo.maven.apache.org/maven2/com/codacy/codacy-coverage-reporter/7.1.0/codacy-coverage-reporter-7.1.0-assembly.jar curl -o ~/codacy-coverage-reporter.jar https://repo.maven.apache.org/maven2/com/codacy/codacy-coverage-reporter/7.1.0/codacy-coverage-reporter-7.1.0-assembly.jar
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/commons/target/site/jacoco/jacoco.xml --partial $JAVA_HOME/bin/java --illegal-access=permit -jar ~/codacy-coverage-reporter.jar report -l Java -r main/commons/target/site/jacoco/jacoco.xml --partial
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/ui/target/site/jacoco/jacoco.xml --partial $JAVA_HOME/bin/java --illegal-access=permit -jar ~/codacy-coverage-reporter.jar report -l Java -r main/ui/target/site/jacoco/jacoco.xml --partial
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/launcher/target/site/jacoco/jacoco.xml --partial $JAVA_HOME/bin/java --illegal-access=permit -jar ~/codacy-coverage-reporter.jar report -l Java -r main/launcher/target/site/jacoco/jacoco.xml --partial
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar final $JAVA_HOME/bin/java --illegal-access=permit -jar ~/codacy-coverage-reporter.jar final
env: env:
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
- name: Assemble buildkit-linux.zip - name: Assemble buildkit-linux.zip
@@ -59,7 +60,7 @@ jobs:
name: Draft a Release on GitHub Releases name: Draft a Release on GitHub Releases
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/') && github.repository == 'cryptomator/cryptomator'
steps: steps:
- name: Download buildkit-linux.zip - name: Download buildkit-linux.zip
uses: actions/download-artifact@v1 uses: actions/download-artifact@v1
+1 -1
View File
@@ -8,7 +8,7 @@
</list> </list>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_14" default="false" project-jdk-name="14" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_16" project-jdk-name="16" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>
+19 -4
View File
@@ -2,7 +2,7 @@
[![Build](https://github.com/cryptomator/cryptomator/workflows/Build/badge.svg)](https://github.com/cryptomator/cryptomator/actions?query=workflow%3ABuild) [![Build](https://github.com/cryptomator/cryptomator/workflows/Build/badge.svg)](https://github.com/cryptomator/cryptomator/actions?query=workflow%3ABuild)
[![Known Vulnerabilities](https://snyk.io/test/github/cryptomator/cryptomator/badge.svg?targetFile=main%2Fpom.xml)](https://snyk.io/test/github/cryptomator/cryptomator?targetFile=main%2Fpom.xml) [![Known Vulnerabilities](https://snyk.io/test/github/cryptomator/cryptomator/badge.svg?targetFile=main%2Fpom.xml)](https://snyk.io/test/github/cryptomator/cryptomator?targetFile=main%2Fpom.xml)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/2a0adf3cec6a4143b91035d3924178f1)](https://www.codacy.com/app/cryptomator/cryptomator?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cryptomator/cryptomator&amp;utm_campaign=Badge_Grade) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/2a0adf3cec6a4143b91035d3924178f1)](https://www.codacy.com/gh/cryptomator/cryptomator/dashboard)
[![Twitter](https://img.shields.io/badge/twitter-@Cryptomator-blue.svg?style=flat)](http://twitter.com/Cryptomator) [![Twitter](https://img.shields.io/badge/twitter-@Cryptomator-blue.svg?style=flat)](http://twitter.com/Cryptomator)
[![Crowdin](https://badges.crowdin.net/cryptomator/localized.svg)](https://translate.cryptomator.org/) [![Crowdin](https://badges.crowdin.net/cryptomator/localized.svg)](https://translate.cryptomator.org/)
[![Latest Release](https://img.shields.io/github/release/cryptomator/cryptomator.svg)](https://github.com/cryptomator/cryptomator/releases/latest) [![Latest Release](https://img.shields.io/github/release/cryptomator/cryptomator.svg)](https://github.com/cryptomator/cryptomator/releases/latest)
@@ -17,11 +17,26 @@ Cryptomator is provided free of charge as an open-source project despite the hig
### Gold Sponsors ### Gold Sponsors
[<img src="https://cryptomator.org/img/sponsors/geewhiz.svg" alt="gee-whiz" height="96">](https://www.gee-whiz.de/) <table>
<tbody>
<tr>
<td><a href="https://www.gee-whiz.de/"><img src="https://cryptomator.org/img/sponsors/geewhiz.svg" alt="gee-whiz" height="80"></a></td>
<td><a href="https://proxy-hub.com/"><img src="https://cryptomator.org/img/sponsors/proxyhub.svg" alt="Proxy-Hub" height="80"></a></td>
</tr>
</tbody>
</table>
### Silver Sponsors ### Silver Sponsors
[![TheBestVPN](https://cryptomator.org/img/sponsors/thebestvpn.png)](https://thebestvpn.com/) <table>
<tbody>
<tr>
<td><a href="https://thebestvpn.com/"><img src="https://cryptomator.org/img/sponsors/thebestvpn@2x.png" alt="TheBestVPN" height="64"></a></td>
</tr>
</tbody>
</table>
- [Jameson Lopp](https://www.lopp.net/)
--- ---
@@ -65,7 +80,7 @@ For more information on the security details visit [cryptomator.org](https://doc
### Dependencies ### Dependencies
* JDK 14 (e.g. adoptopenjdk) * JDK 16 (e.g. adoptopenjdk)
* Maven 3 * Maven 3
* Optional: OS-dependent build tools for native packaging (see [Windows](https://github.com/cryptomator/cryptomator-win), [OS X](https://github.com/cryptomator/cryptomator-osx), [Linux](https://github.com/cryptomator/builder-containers)) * Optional: OS-dependent build tools for native packaging (see [Windows](https://github.com/cryptomator/cryptomator-win), [OS X](https://github.com/cryptomator/cryptomator-osx), [Linux](https://github.com/cryptomator/builder-containers))
+1 -1
View File
@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.5.13</version> <version>1.6.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>buildkit</artifactId> <artifactId>buildkit</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.5.13</version> <version>1.6.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>commons</artifactId> <artifactId>commons</artifactId>
<name>Cryptomator Commons</name> <name>Cryptomator Commons</name>
@@ -47,10 +47,12 @@ public abstract class CommonsModule {
@Named("licensePublicKey") @Named("licensePublicKey")
static String provideLicensePublicKey() { static String provideLicensePublicKey() {
// in PEM format without the dash-escaped begin/end lines // in PEM format without the dash-escaped begin/end lines
return "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQB7NfnqiZbg2KTmoflmZ71PbXru7oW" // return """
+ "fmnV2yv3eDjlDfGruBrqz9TtXBZV/eYWt31xu1osIqaT12lKBvZ511aaAkIBeOEV" // MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQB7NfnqiZbg2KTmoflmZ71PbXru7oW\
+ "gwcBIlJr6kUw7NKzeJt7r2rrsOyQoOG2nWc/Of/NBqA3mIZRHk5Aq1YupFdD26QE" // fmnV2yv3eDjlDfGruBrqz9TtXBZV/eYWt31xu1osIqaT12lKBvZ511aaAkIBeOEV\
+ "r0DzRyj4ixPIt38CQB8="; gwcBIlJr6kUw7NKzeJt7r2rrsOyQoOG2nWc/Of/NBqA3mIZRHk5Aq1YupFdD26QE\
r0DzRyj4ixPIt38CQB8=\
""";
} }
@Provides @Provides
@@ -33,8 +33,8 @@ class LicenseChecker {
try { try {
byte[] keyBytes = BaseEncoding.base64().decode(pemEncodedPublicKey); byte[] keyBytes = BaseEncoding.base64().decode(pemEncodedPublicKey);
PublicKey key = KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(keyBytes)); PublicKey key = KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(keyBytes));
if (key instanceof ECPublicKey) { if (key instanceof ECPublicKey k) {
return (ECPublicKey) key; return k;
} else { } else {
throw new IllegalStateException("Key not an EC public key."); throw new IllegalStateException("Key not an EC public key.");
} }
@@ -173,8 +173,7 @@ public class VaultSettings {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj instanceof VaultSettings && obj.getClass().equals(this.getClass())) { if (obj instanceof VaultSettings other && obj.getClass().equals(this.getClass())) {
VaultSettings other = (VaultSettings) obj;
return Objects.equals(this.id, other.id); return Objects.equals(this.id, other.id);
} else { } else {
return false; return false;
@@ -355,8 +355,7 @@ public class Vault {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj instanceof Vault && obj.getClass().equals(this.getClass())) { if (obj instanceof Vault other && obj.getClass().equals(this.getClass())) {
final Vault other = (Vault) obj;
return Objects.equals(this.vaultSettings, other.vaultSettings); return Objects.equals(this.vaultSettings, other.vaultSettings);
} else { } else {
return false; return false;
@@ -22,10 +22,10 @@ class VaultListChangeListener implements ListChangeListener<Vault> {
public void onChanged(Change<? extends Vault> c) { public void onChanged(Change<? extends Vault> c) {
while (c.next()) { while (c.next()) {
if (c.wasAdded()) { if (c.wasAdded()) {
List<VaultSettings> addedSettings = c.getAddedSubList().stream().map(Vault::getVaultSettings).collect(Collectors.toList()); List<VaultSettings> addedSettings = c.getAddedSubList().stream().map(Vault::getVaultSettings).toList();
vaultSettingsList.addAll(c.getFrom(), addedSettings); vaultSettingsList.addAll(c.getFrom(), addedSettings);
} else if (c.wasRemoved()) { } else if (c.wasRemoved()) {
List<VaultSettings> removedSettings = c.getRemoved().stream().map(Vault::getVaultSettings).collect(Collectors.toList()); List<VaultSettings> removedSettings = c.getRemoved().stream().map(Vault::getVaultSettings).toList();
vaultSettingsList.removeAll(removedSettings); vaultSettingsList.removeAll(removedSettings);
} }
} }
@@ -79,7 +79,7 @@ public class VaultListManager {
} }
private void addAll(Collection<VaultSettings> vaultSettings) { private void addAll(Collection<VaultSettings> vaultSettings) {
Collection<Vault> vaults = vaultSettings.stream().map(this::create).collect(Collectors.toList()); Collection<Vault> vaults = vaultSettings.stream().map(this::create).toList();
vaultList.addAll(vaults); vaultList.addAll(vaults);
} }
@@ -32,7 +32,7 @@ class EnvironmentTest {
public void testSettingsPath() { public void testSettingsPath() {
System.setProperty("cryptomator.settingsPath", "~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json"); System.setProperty("cryptomator.settingsPath", "~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json");
List<Path> result = env.getSettingsPath().collect(Collectors.toList()); List<Path> result = env.getSettingsPath().toList();
MatcherAssert.assertThat(result, Matchers.hasSize(2)); MatcherAssert.assertThat(result, Matchers.hasSize(2));
MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/.config/Cryptomator/settings.json"), // MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/.config/Cryptomator/settings.json"), //
Paths.get("/home/testuser/.Cryptomator/settings.json"))); Paths.get("/home/testuser/.Cryptomator/settings.json")));
@@ -43,7 +43,7 @@ class EnvironmentTest {
public void testIpcPortPath() { public void testIpcPortPath() {
System.setProperty("cryptomator.ipcPortPath", "~/.config/Cryptomator/ipcPort.bin:~/.Cryptomator/ipcPort.bin"); System.setProperty("cryptomator.ipcPortPath", "~/.config/Cryptomator/ipcPort.bin:~/.Cryptomator/ipcPort.bin");
List<Path> result = env.getIpcPortPath().collect(Collectors.toList()); List<Path> result = env.getIpcPortPath().toList();
MatcherAssert.assertThat(result, Matchers.hasSize(2)); MatcherAssert.assertThat(result, Matchers.hasSize(2));
MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/.config/Cryptomator/ipcPort.bin"), // MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/.config/Cryptomator/ipcPort.bin"), //
Paths.get("/home/testuser/.Cryptomator/ipcPort.bin"))); Paths.get("/home/testuser/.Cryptomator/ipcPort.bin")));
@@ -54,7 +54,7 @@ class EnvironmentTest {
public void testKeychainPath() { public void testKeychainPath() {
System.setProperty("cryptomator.keychainPath", "~/AppData/Roaming/Cryptomator/keychain.json"); System.setProperty("cryptomator.keychainPath", "~/AppData/Roaming/Cryptomator/keychain.json");
List<Path> result = env.getKeychainPath().collect(Collectors.toList()); List<Path> result = env.getKeychainPath().toList();
MatcherAssert.assertThat(result, Matchers.hasSize(1)); MatcherAssert.assertThat(result, Matchers.hasSize(1));
MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/AppData/Roaming/Cryptomator/keychain.json"))); MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/AppData/Roaming/Cryptomator/keychain.json")));
} }
@@ -88,7 +88,7 @@ class EnvironmentTest {
@DisplayName("test.path.property=") @DisplayName("test.path.property=")
public void testEmptyList() { public void testEmptyList() {
System.setProperty("test.path.property", ""); System.setProperty("test.path.property", "");
List<Path> result = env.getPaths("test.path.property").collect(Collectors.toList()); List<Path> result = env.getPaths("test.path.property").toList();
MatcherAssert.assertThat(result, Matchers.hasSize(0)); MatcherAssert.assertThat(result, Matchers.hasSize(0));
} }
@@ -97,7 +97,7 @@ class EnvironmentTest {
@DisplayName("test.path.property=/foo/bar/test") @DisplayName("test.path.property=/foo/bar/test")
public void testSingleAbsolutePath() { public void testSingleAbsolutePath() {
System.setProperty("test.path.property", "/foo/bar/test"); System.setProperty("test.path.property", "/foo/bar/test");
List<Path> result = env.getPaths("test.path.property").collect(Collectors.toList()); List<Path> result = env.getPaths("test.path.property").toList();
MatcherAssert.assertThat(result, Matchers.hasSize(1)); MatcherAssert.assertThat(result, Matchers.hasSize(1));
MatcherAssert.assertThat(result, Matchers.hasItem(Paths.get("/foo/bar/test"))); MatcherAssert.assertThat(result, Matchers.hasItem(Paths.get("/foo/bar/test")));
@@ -107,7 +107,7 @@ class EnvironmentTest {
@DisplayName("test.path.property=~/test") @DisplayName("test.path.property=~/test")
public void testSingleHomeRelativePath() { public void testSingleHomeRelativePath() {
System.setProperty("test.path.property", "~/test"); System.setProperty("test.path.property", "~/test");
List<Path> result = env.getPaths("test.path.property").collect(Collectors.toList()); List<Path> result = env.getPaths("test.path.property").toList();
MatcherAssert.assertThat(result, Matchers.hasSize(1)); MatcherAssert.assertThat(result, Matchers.hasSize(1));
MatcherAssert.assertThat(result, Matchers.hasItem(Paths.get("/home/testuser/test"))); MatcherAssert.assertThat(result, Matchers.hasItem(Paths.get("/home/testuser/test")));
@@ -117,7 +117,7 @@ class EnvironmentTest {
@DisplayName("test.path.property=~/test:~/test2:/foo/bar/test") @DisplayName("test.path.property=~/test:~/test2:/foo/bar/test")
public void testMultiplePaths() { public void testMultiplePaths() {
System.setProperty("test.path.property", "~/test:~/test2:/foo/bar/test"); System.setProperty("test.path.property", "~/test:~/test2:/foo/bar/test");
List<Path> result = env.getPaths("test.path.property").collect(Collectors.toList()); List<Path> result = env.getPaths("test.path.property").toList();
MatcherAssert.assertThat(result, Matchers.hasSize(3)); MatcherAssert.assertThat(result, Matchers.hasSize(3));
MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/test"), // MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/test"), //
@@ -9,10 +9,12 @@ import java.util.Optional;
class LicenseCheckerTest { class LicenseCheckerTest {
private static final String PUBLIC_KEY = "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBgc4HZz+/fBbC7lmEww0AO3NK9wVZ" // private static final String PUBLIC_KEY = """
+ "PDZ0VEnsaUFLEYpTzb90nITtJUcPUbvOsdZIZ1Q8fnbquAYgxXL5UgHMoywAib47" // MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBgc4HZz+/fBbC7lmEww0AO3NK9wVZ\
+ "6MkyyYgPk0BXZq3mq4zImTRNuaU9slj9TVJ3ScT3L1bXwVuPJDzpr5GOFpaj+WwM" // PDZ0VEnsaUFLEYpTzb90nITtJUcPUbvOsdZIZ1Q8fnbquAYgxXL5UgHMoywAib47\
+ "Al8G7CqwoJOsW7Kddns="; 6MkyyYgPk0BXZq3mq4zImTRNuaU9slj9TVJ3ScT3L1bXwVuPJDzpr5GOFpaj+WwM\
Al8G7CqwoJOsW7Kddns=\
""";
private LicenseChecker licenseChecker; private LicenseChecker licenseChecker;
@@ -21,13 +21,18 @@ public class SettingsJsonAdapterTest {
@Test @Test
public void testDeserialize() throws IOException { public void testDeserialize() throws IOException {
String vault1Json = "{\"id\": \"1\", \"path\": \"/vault1\", \"mountName\": \"vault1\", \"winDriveLetter\": \"X\"}"; String json = """
String vault2Json = "{\"id\": \"2\", \"path\": \"/vault2\", \"mountName\": \"vault2\", \"winDriveLetter\": \"Y\"}"; {
String json = "{\"directories\": [" + vault1Json + "," + vault2Json + "]," // "directories": [
+ "\"checkForUpdatesEnabled\": true,"// {"id": "1", "path": "/vault1", "mountName": "vault1", "winDriveLetter": "X"},
+ "\"port\": 8080,"// {"id": "2", "path": "/vault2", "mountName": "vault2", "winDriveLetter": "Y"}
+ "\"numTrayNotifications\": 42,"// ],
+ "\"preferredVolumeImpl\": \"FUSE\"}"; "checkForUpdatesEnabled": true,
"port": 8080,
"numTrayNotifications": 42,
"preferredVolumeImpl": "FUSE"
}
""";
Settings settings = adapter.fromJson(json); Settings settings = adapter.fromJson(json);
+1 -1
View File
@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.5.13</version> <version>1.6.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>launcher</artifactId> <artifactId>launcher</artifactId>
<name>Cryptomator Launcher</name> <name>Cryptomator Launcher</name>
@@ -41,7 +41,7 @@ class FileOpenRequestHandler {
} }
private void openFiles(OpenFilesEvent evt) { private void openFiles(OpenFilesEvent evt) {
Collection<Path> pathsToOpen = evt.getFiles().stream().map(File::toPath).collect(Collectors.toList()); Collection<Path> pathsToOpen = evt.getFiles().stream().map(File::toPath).toList();
AppLaunchEvent launchEvent = new AppLaunchEvent(AppLaunchEvent.EventType.OPEN_FILE, pathsToOpen); AppLaunchEvent launchEvent = new AppLaunchEvent(AppLaunchEvent.EventType.OPEN_FILE, pathsToOpen);
tryToEnqueueFileOpenRequest(launchEvent); tryToEnqueueFileOpenRequest(launchEvent);
} }
@@ -59,7 +59,7 @@ class FileOpenRequestHandler {
LOG.trace("Argument not a valid path: {}", str); LOG.trace("Argument not a valid path: {}", str);
return null; return null;
} }
}).filter(Objects::nonNull).collect(Collectors.toList()); }).filter(Objects::nonNull).toList();
if (!pathsToOpen.isEmpty()) { if (!pathsToOpen.isEmpty()) {
AppLaunchEvent launchEvent = new AppLaunchEvent(AppLaunchEvent.EventType.OPEN_FILE, pathsToOpen); AppLaunchEvent launchEvent = new AppLaunchEvent(AppLaunchEvent.EventType.OPEN_FILE, pathsToOpen);
tryToEnqueueFileOpenRequest(launchEvent); tryToEnqueueFileOpenRequest(launchEvent);
@@ -47,8 +47,8 @@ public class LoggerModule {
@Singleton @Singleton
static LoggerContext provideLoggerContext() { static LoggerContext provideLoggerContext() {
ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory(); ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
if (loggerFactory instanceof LoggerContext) { if (loggerFactory instanceof LoggerContext context) {
return (LoggerContext) loggerFactory; return context;
} else { } else {
throw new IllegalStateException("SLF4J not bound to Logback."); throw new IllegalStateException("SLF4J not bound to Logback.");
} }
+3 -3
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.5.13</version> <version>1.6.0-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Cryptomator</name> <name>Cryptomator</name>
@@ -22,7 +22,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.jdk.version>14</project.jdk.version> <project.jdk.version>16</project.jdk.version>
<!-- cryptomator dependencies --> <!-- cryptomator dependencies -->
<cryptomator.cryptofs.version>1.9.14</cryptomator.cryptofs.version> <cryptomator.cryptofs.version>1.9.14</cryptomator.cryptofs.version>
@@ -32,7 +32,7 @@
<cryptomator.integrations.linux.version>1.0.0-beta1</cryptomator.integrations.linux.version> <cryptomator.integrations.linux.version>1.0.0-beta1</cryptomator.integrations.linux.version>
<cryptomator.fuse.version>1.2.9</cryptomator.fuse.version> <cryptomator.fuse.version>1.2.9</cryptomator.fuse.version>
<cryptomator.dokany.version>1.2.4</cryptomator.dokany.version> <cryptomator.dokany.version>1.2.4</cryptomator.dokany.version>
<cryptomator.webdav.version>1.1.3</cryptomator.webdav.version> <cryptomator.webdav.version>1.1.4</cryptomator.webdav.version>
<!-- 3rd party dependencies --> <!-- 3rd party dependencies -->
<javafx.version>15</javafx.version> <javafx.version>15</javafx.version>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.5.13</version> <version>1.6.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>ui</artifactId> <artifactId>ui</artifactId>
<name>Cryptomator GUI</name> <name>Cryptomator GUI</name>
@@ -42,8 +42,8 @@ public class DefaultSceneFactory implements Function<Parent, Scene> {
protected void configureScene(Scene scene) { protected void configureScene(Scene scene) {
scene.windowProperty().addListener(observable -> { scene.windowProperty().addListener(observable -> {
Window window = scene.getWindow(); Window window = scene.getWindow();
if (window instanceof Stage) { if (window instanceof Stage s) {
setupDefaultAccelerators(scene, (Stage) window); setupDefaultAccelerators(scene, s);
} }
}); });
} }
@@ -86,7 +86,7 @@ public class FxApplication extends Application {
} }
private void hasVisibleStagesChanged(@SuppressWarnings("unused") ObservableValue<? extends Boolean> observableValue, @SuppressWarnings("unused") boolean oldValue, boolean newValue) { private void hasVisibleStagesChanged(@SuppressWarnings("unused") ObservableValue<? extends Boolean> observableValue, @SuppressWarnings("unused") boolean oldValue, boolean newValue) {
LOG.warn("has visible stages: {}", newValue); LOG.debug("has visible stages: {}", newValue);
if (newValue) { if (newValue) {
trayIntegration.ifPresent(TrayIntegrationProvider::restoredFromTray); trayIntegration.ifPresent(TrayIntegrationProvider::restoredFromTray);
} else { } else {
@@ -1,5 +1,6 @@
package org.cryptomator.ui.launcher; package org.cryptomator.ui.launcher;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.ui.fxapp.FxApplication; import org.cryptomator.ui.fxapp.FxApplication;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -55,7 +56,7 @@ class AppLaunchEventHandler {
case REVEAL_APP -> fxApplicationStarter.get().thenAccept(FxApplication::showMainWindow); case REVEAL_APP -> fxApplicationStarter.get().thenAccept(FxApplication::showMainWindow);
case OPEN_FILE -> fxApplicationStarter.get().thenRun(() -> { case OPEN_FILE -> fxApplicationStarter.get().thenRun(() -> {
Platform.runLater(() -> { Platform.runLater(() -> {
event.getPathsToOpen().forEach(this::addVault); event.getPathsToOpen().forEach(this::addOrRevealVault);
}); });
}); });
default -> LOG.warn("Unsupported event type: {}", event.getType()); default -> LOG.warn("Unsupported event type: {}", event.getType());
@@ -63,13 +64,18 @@ class AppLaunchEventHandler {
} }
// TODO dedup MainWindowController... // TODO dedup MainWindowController...
private void addVault(Path potentialVaultPath) { private void addOrRevealVault(Path potentialVaultPath) {
assert Platform.isFxApplicationThread(); assert Platform.isFxApplicationThread();
try { try {
final Vault v;
if (potentialVaultPath.getFileName().toString().equals(MASTERKEY_FILENAME)) { if (potentialVaultPath.getFileName().toString().equals(MASTERKEY_FILENAME)) {
vaultListManager.add(potentialVaultPath.getParent()); v = vaultListManager.add(potentialVaultPath.getParent());
} else { } else {
vaultListManager.add(potentialVaultPath); v = vaultListManager.add(potentialVaultPath);
}
if (v.isUnlocked()) {
fxApplicationStarter.get().thenAccept(app -> app.getVaultService().reveal(v));
} }
LOG.debug("Added vault {}", potentialVaultPath); LOG.debug("Added vault {}", potentialVaultPath);
} catch (NoSuchFileException e) { } catch (NoSuchFileException e) {
@@ -0,0 +1,78 @@
package org.cryptomator.ui.stats;
import javafx.beans.NamedArg;
import javafx.collections.ObservableList;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.Axis;
import javafx.scene.shape.ClosePath;
import javafx.scene.shape.CubicCurveTo;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.PathElement;
// inspired by http://fxexperience.com/2012/01/curve-fitting-and-styling-areachart/
public class SmoothAreaChart extends AreaChart<Number, Number> {
public SmoothAreaChart(@NamedArg("xAxis") Axis<Number> xAxis, @NamedArg("yAxis") Axis<Number> yAxis) {
super(xAxis, yAxis);
}
@Override
protected void layoutPlotChildren() {
super.layoutPlotChildren();
var iter = getDisplayedSeriesIterator();
while (iter.hasNext()) {
var series = iter.next();
final Path seriesLine = (Path)((Group)series.getNode()).getChildren().get(1);
final Path fillPath = (Path)((Group)series.getNode()).getChildren().get(0);
var dx = getXAxis().getWidth() / series.getData().size();
smooth(seriesLine.getElements(), fillPath.getElements(), dx);
}
}
private static void smooth(ObservableList<PathElement> strokeElements, ObservableList<PathElement> fillElements, double dx) {
// as we do not have direct access to the data, first recreate the list of all the data points we have
final Point2D[] dataPoints = new Point2D[strokeElements.size()];
for (int i = 0; i < strokeElements.size(); i++) {
final PathElement element = strokeElements.get(i);
if (element instanceof MoveTo) {
final MoveTo move = (MoveTo)element;
dataPoints[i] = new Point2D(move.getX(), move.getY());
} else if (element instanceof LineTo) {
final LineTo line = (LineTo)element;
final double x = line.getX(), y = line.getY();
dataPoints[i] = new Point2D(x, y);
}
}
// next we need to know the zero Y value
final double zeroY = ((MoveTo) fillElements.get(0)).getY();
final double dx2 = dx / 2.0;
// now clear and rebuild elements
strokeElements.clear();
fillElements.clear();
// start both paths
strokeElements.add(new MoveTo(dataPoints[0].getX(),dataPoints[0].getY()));
fillElements.add(new MoveTo(dataPoints[0].getX(),zeroY));
fillElements.add(new LineTo(dataPoints[0].getX(),dataPoints[0].getY()));
// add curves
for (int i = 1; i < dataPoints.length; i++) {
final int ci = i-1;
strokeElements.add(new CubicCurveTo(
dataPoints[ci].getX() + dx2, dataPoints[ci].getY(),
dataPoints[i].getX() - dx2, dataPoints[i].getY(),
dataPoints[i].getX(), dataPoints[i].getY()));
fillElements.add(new CubicCurveTo(
dataPoints[ci].getX() + dx2, dataPoints[ci].getY(),
dataPoints[i].getX() - dx2, dataPoints[i].getY(),
dataPoints[i].getX(),dataPoints[i].getY()));
}
// end the paths
fillElements.add(new LineTo(dataPoints[dataPoints.length-1].getX(),zeroY));
fillElements.add(new ClosePath());
}
}
@@ -76,8 +76,8 @@ public class UnlockWorkflow extends Task<Boolean> {
setOnFailed(event -> { setOnFailed(event -> {
Throwable throwable = event.getSource().getException(); Throwable throwable = event.getSource().getException();
if (throwable instanceof InvalidMountPointException) { if (throwable instanceof InvalidMountPointException e) {
handleInvalidMountPoint((InvalidMountPointException) throwable); handleInvalidMountPoint(e);
} else { } else {
handleGenericError(throwable); handleGenericError(throwable);
} }
+3 -2
View File
@@ -13,6 +13,7 @@
<?import javafx.scene.layout.StackPane?> <?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Arc?> <?import javafx.scene.shape.Arc?>
<?import org.cryptomator.ui.stats.SmoothAreaChart?>
<HBox xmlns="http://javafx.com/javafx" <HBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml" xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.stats.VaultStatisticsController" fx:controller="org.cryptomator.ui.stats.VaultStatisticsController"
@@ -38,7 +39,7 @@
<!-- Read --> <!-- Read -->
<VBox prefWidth="300" prefHeight="300" spacing="6" alignment="CENTER"> <VBox prefWidth="300" prefHeight="300" spacing="6" alignment="CENTER">
<ThrougputLabel styleClass="label-large" idleFormat="%stats.read.throughput.idle" kibsFormat="%stats.read.throughput.kibs" mibsFormat="%stats.read.throughput.mibs" bytesPerSecond="${controller.bpsRead}"/> <ThrougputLabel styleClass="label-large" idleFormat="%stats.read.throughput.idle" kibsFormat="%stats.read.throughput.kibs" mibsFormat="%stats.read.throughput.mibs" bytesPerSecond="${controller.bpsRead}"/>
<AreaChart fx:id="readChart" styleClass="io-stats" createSymbols="false" animated="false"> <SmoothAreaChart fx:id="readChart" styleClass="io-stats" createSymbols="false" animated="false">
<xAxis> <xAxis>
<NumberAxis fx:id="readChartXAxis" styleClass="io-stats" autoRanging="false" forceZeroInRange="false" side="BOTTOM"/> <NumberAxis fx:id="readChartXAxis" styleClass="io-stats" autoRanging="false" forceZeroInRange="false" side="BOTTOM"/>
</xAxis> </xAxis>
@@ -48,7 +49,7 @@
<cursor> <cursor>
<Cursor fx:constant="DEFAULT"/> <Cursor fx:constant="DEFAULT"/>
</cursor> </cursor>
</AreaChart> </SmoothAreaChart>
<DataLabel byteFormat="%stats.read.total.data.none" kibFormat="%stats.read.total.data.kib" mibFormat="%stats.read.total.data.mib" gibFormat="%stats.read.total.data.gib" dataInBytes="${controller.totalBytesRead}"/> <DataLabel byteFormat="%stats.read.total.data.none" kibFormat="%stats.read.total.data.kib" mibFormat="%stats.read.total.data.mib" gibFormat="%stats.read.total.data.gib" dataInBytes="${controller.totalBytesRead}"/>
<DataLabel byteFormat="%stats.decr.total.data.none" kibFormat="%stats.decr.total.data.kib" mibFormat="%stats.decr.total.data.mib" gibFormat="%stats.decr.total.data.gib" dataInBytes="${controller.totalBytesDecrypted}"/> <DataLabel byteFormat="%stats.decr.total.data.none" kibFormat="%stats.decr.total.data.kib" mibFormat="%stats.decr.total.data.mib" gibFormat="%stats.decr.total.data.gib" dataInBytes="${controller.totalBytesDecrypted}"/>
<FormattedLabel format="%stats.read.accessCount" arg1="${controller.filesRead}"/> <FormattedLabel format="%stats.read.accessCount" arg1="${controller.filesRead}"/>
@@ -48,18 +48,22 @@ class RecoveryKeyFactoryTest {
@Test @Test
@DisplayName("validateRecoveryKey() with invalid checksum") @DisplayName("validateRecoveryKey() with invalid checksum")
public void testValidateValidateRecoveryKeyWithInvalidCrc() { public void testValidateValidateRecoveryKeyWithInvalidCrc() {
boolean result = inTest.validateRecoveryKey("pathway lift abuse plenty export texture gentleman landscape beyond ceiling around leaf cafe" // boolean result = inTest.validateRecoveryKey("""
+ " charity border breakdown victory surely computer cat linger restrict infer crowd live computer true written amazed investor boot" // pathway lift abuse plenty export texture gentleman landscape beyond ceiling around leaf cafe charity \
+ " depth left theory snow whereby terminal weekly reject happiness circuit partial cup wrong"); border breakdown victory surely computer cat linger restrict infer crowd live computer true written amazed \
investor boot depth left theory snow whereby terminal weekly reject happiness circuit partial cup wrong \
""");
Assertions.assertFalse(result); Assertions.assertFalse(result);
} }
@Test @Test
@DisplayName("validateRecoveryKey() with valid input") @DisplayName("validateRecoveryKey() with valid input")
public void testValidateValidateRecoveryKeyWithValidKey() { public void testValidateValidateRecoveryKeyWithValidKey() {
boolean result = inTest.validateRecoveryKey("pathway lift abuse plenty export texture gentleman landscape beyond ceiling around leaf cafe" // boolean result = inTest.validateRecoveryKey("""
+ " charity border breakdown victory surely computer cat linger restrict infer crowd live computer true written amazed investor boot" // pathway lift abuse plenty export texture gentleman landscape beyond ceiling around leaf cafe charity \
+ " depth left theory snow whereby terminal weekly reject happiness circuit partial cup ad"); border breakdown victory surely computer cat linger restrict infer crowd live computer true written amazed \
investor boot depth left theory snow whereby terminal weekly reject happiness circuit partial cup ad \
""");
Assertions.assertTrue(result); Assertions.assertTrue(result);
} }