diff --git a/main/commons/pom.xml b/main/commons/pom.xml
index 261ab2ee8..f16aaccfc 100644
--- a/main/commons/pom.xml
+++ b/main/commons/pom.xml
@@ -48,6 +48,12 @@
easybind
+
+
+ com.auth0
+ java-jwt
+
+
com.google.guava
diff --git a/main/commons/src/main/java/org/cryptomator/common/CommonsModule.java b/main/commons/src/main/java/org/cryptomator/common/CommonsModule.java
index 5d86ca6ce..81bc5f01e 100644
--- a/main/commons/src/main/java/org/cryptomator/common/CommonsModule.java
+++ b/main/commons/src/main/java/org/cryptomator/common/CommonsModule.java
@@ -35,6 +35,17 @@ public abstract class CommonsModule {
private static final int NUM_SCHEDULER_THREADS = 4;
+ @Provides
+ @Singleton
+ @Named("licensePublicKey")
+ static String provideLicensePublicKey() {
+ // TODO replace
+ return "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBgc4HZz+/fBbC7lmEww0AO3NK9wVZ" //
+ + "PDZ0VEnsaUFLEYpTzb90nITtJUcPUbvOsdZIZ1Q8fnbquAYgxXL5UgHMoywAib47" //
+ + "6MkyyYgPk0BXZq3mq4zImTRNuaU9slj9TVJ3ScT3L1bXwVuPJDzpr5GOFpaj+WwM" //
+ + "Al8G7CqwoJOsW7Kddns=";
+ }
+
@Provides
@Singleton
@Named("SemVer")
diff --git a/main/ui/src/main/java/org/cryptomator/ui/preferences/LicenseChecker.java b/main/commons/src/main/java/org/cryptomator/common/LicenseChecker.java
similarity index 95%
rename from main/ui/src/main/java/org/cryptomator/ui/preferences/LicenseChecker.java
rename to main/commons/src/main/java/org/cryptomator/common/LicenseChecker.java
index e99a1bb03..82134f77f 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/preferences/LicenseChecker.java
+++ b/main/commons/src/main/java/org/cryptomator/common/LicenseChecker.java
@@ -1,4 +1,4 @@
-package org.cryptomator.ui.preferences;
+package org.cryptomator.common;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
@@ -9,6 +9,7 @@ import com.google.common.io.BaseEncoding;
import javax.inject.Inject;
import javax.inject.Named;
+import javax.inject.Singleton;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
@@ -17,6 +18,7 @@ import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Optional;
+@Singleton
public class LicenseChecker {
private final JWTVerifier verifier;
diff --git a/main/commons/src/main/java/org/cryptomator/common/Optionals.java b/main/commons/src/main/java/org/cryptomator/common/Optionals.java
deleted file mode 100644
index 4ccea7d8b..000000000
--- a/main/commons/src/main/java/org/cryptomator/common/Optionals.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the accompanying LICENSE file.
- *******************************************************************************/
-package org.cryptomator.common;
-
-import java.util.Optional;
-import java.util.function.Function;
-
-public final class Optionals {
-
- private Optionals() {
- }
-
- /**
- * Returns a function that is equivalent to the input function but immediately gets the value of the returned optional when invoked.
- *
- * @param the type of the input to the function
- * @param the type of the result of the function
- * @param function An {@code Optional}-bearing input function {@code Function>}
- * @return A {@code Function}, that may throw a NoSuchElementException, if the original function returns an empty optional.
- */
- public static Function unwrap(Function> function) {
- return t -> function.apply(t).get();
- }
-
-}
diff --git a/main/commons/src/main/java/org/cryptomator/common/settings/Settings.java b/main/commons/src/main/java/org/cryptomator/common/settings/Settings.java
index ff5613f1e..863e359e2 100644
--- a/main/commons/src/main/java/org/cryptomator/common/settings/Settings.java
+++ b/main/commons/src/main/java/org/cryptomator/common/settings/Settings.java
@@ -15,6 +15,8 @@ import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.NodeOrientation;
@@ -35,6 +37,7 @@ public class Settings {
public static final VolumeImpl DEFAULT_PREFERRED_VOLUME_IMPL = System.getProperty("os.name").toLowerCase().contains("windows") ? VolumeImpl.DOKANY : VolumeImpl.FUSE;
public static final UiTheme DEFAULT_THEME = UiTheme.LIGHT;
public static final NodeOrientation DEFAULT_USER_INTERFACE_ORIENTATION = NodeOrientation.LEFT_TO_RIGHT;
+ private static final String DEFAULT_LICENSE_KEY = "";
private final ObservableList directories = FXCollections.observableArrayList(VaultSettings::observables);
private final BooleanProperty askedForUpdateCheck = new SimpleBooleanProperty(DEFAULT_ASKED_FOR_UPDATE_CHECK);
@@ -47,6 +50,7 @@ public class Settings {
private final ObjectProperty preferredVolumeImpl = new SimpleObjectProperty<>(DEFAULT_PREFERRED_VOLUME_IMPL);
private final ObjectProperty theme = new SimpleObjectProperty<>(DEFAULT_THEME);
private final ObjectProperty userInterfaceOrientation = new SimpleObjectProperty<>(DEFAULT_USER_INTERFACE_ORIENTATION);
+ private final StringProperty licenseKey = new SimpleStringProperty(DEFAULT_LICENSE_KEY);
private Consumer saveCmd;
@@ -126,4 +130,8 @@ public class Settings {
public ObjectProperty userInterfaceOrientation() {
return userInterfaceOrientation;
}
+
+ public StringProperty licenseKey() {
+ return licenseKey;
+ }
}
diff --git a/main/ui/src/test/java/org/cryptomator/ui/preferences/LicenseCheckerTest.java b/main/commons/src/test/java/org/cryptomator/common/LicenseCheckerTest.java
similarity index 97%
rename from main/ui/src/test/java/org/cryptomator/ui/preferences/LicenseCheckerTest.java
rename to main/commons/src/test/java/org/cryptomator/common/LicenseCheckerTest.java
index ebf40d018..5ae8f0fb9 100644
--- a/main/ui/src/test/java/org/cryptomator/ui/preferences/LicenseCheckerTest.java
+++ b/main/commons/src/test/java/org/cryptomator/common/LicenseCheckerTest.java
@@ -1,6 +1,7 @@
-package org.cryptomator.ui.preferences;
+package org.cryptomator.common;
import com.auth0.jwt.interfaces.DecodedJWT;
+import org.cryptomator.common.LicenseChecker;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
diff --git a/main/ui/pom.xml b/main/ui/pom.xml
index cf253cce6..514288e89 100644
--- a/main/ui/pom.xml
+++ b/main/ui/pom.xml
@@ -38,12 +38,6 @@
org.fxmisc.easybind
easybind
-
-
-
- com.auth0
- java-jwt
-
diff --git a/main/ui/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java b/main/ui/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java
index f5b62ae2b..41f8b80e2 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java
@@ -15,17 +15,18 @@ public enum FontAwesome5Icon {
EYE_SLASH("\uF070"), //
FILE_IMPORT("\uF56F"), //
FOLDER_OPEN("\uF07C"), //
+ HEART("\uF004"), //
HDD("\uF0A0"), //
KEY("\uF084"), //
LOCK_ALT("\uF30D"), //
LOCK_OPEN_ALT("\uF3C2"), //
- MINUS("\uF068"), //
PLUS("\uF067"), //
QUESTION("\uF128"), //
SPARKLES("\uF890"), //
SPINNER("\uF110"), //
SYNC("\uF021"), //
TIMES("\uF00D"), //
+ USER_CHECK("\uf4fc"), //
WRENCH("\uF0AD"), //
;
diff --git a/main/ui/src/main/java/org/cryptomator/ui/preferences/PreferencesController.java b/main/ui/src/main/java/org/cryptomator/ui/preferences/PreferencesController.java
index e63505e4b..7ce4793cc 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/preferences/PreferencesController.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/preferences/PreferencesController.java
@@ -17,7 +17,6 @@ public class PreferencesController implements FxController {
private final Stage window;
private final BooleanBinding updateAvailable;
public TabPane tabPane;
- public Tab generalTab;
public Tab updatesTab;
@Inject
diff --git a/main/ui/src/main/java/org/cryptomator/ui/preferences/PreferencesModule.java b/main/ui/src/main/java/org/cryptomator/ui/preferences/PreferencesModule.java
index ae4233cb8..793617352 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/preferences/PreferencesModule.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/preferences/PreferencesModule.java
@@ -70,4 +70,9 @@ abstract class PreferencesModule {
@FxControllerKey(VolumePreferencesController.class)
abstract FxController bindVolumePreferencesController(VolumePreferencesController controller);
+ @Binds
+ @IntoMap
+ @FxControllerKey(RegistrationPreferencesController.class)
+ abstract FxController bindRegistrationPreferencesController(RegistrationPreferencesController controller);
+
}
diff --git a/main/ui/src/main/java/org/cryptomator/ui/preferences/RegistrationPreferencesController.java b/main/ui/src/main/java/org/cryptomator/ui/preferences/RegistrationPreferencesController.java
new file mode 100644
index 000000000..64de38d63
--- /dev/null
+++ b/main/ui/src/main/java/org/cryptomator/ui/preferences/RegistrationPreferencesController.java
@@ -0,0 +1,77 @@
+package org.cryptomator.ui.preferences;
+
+import com.auth0.jwt.interfaces.DecodedJWT;
+import javafx.beans.binding.Bindings;
+import javafx.beans.binding.BooleanBinding;
+import javafx.beans.binding.StringBinding;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.fxml.FXML;
+import javafx.scene.control.TextArea;
+import org.cryptomator.common.LicenseChecker;
+import org.cryptomator.common.settings.Settings;
+import org.cryptomator.ui.common.FxController;
+
+import javax.inject.Inject;
+import java.util.Optional;
+
+@PreferencesScoped
+public class RegistrationPreferencesController implements FxController {
+
+ private final Settings settings;
+ private final LicenseChecker licenseChecker;
+ private final ObjectProperty validJwtClaims;
+ private final StringBinding licenseSubject;
+ private final BooleanBinding registeredProperty;
+ public TextArea registrationKeyField;
+
+ @Inject
+ RegistrationPreferencesController(Settings settings, LicenseChecker licenseChecker) {
+ this.settings = settings;
+ this.licenseChecker = licenseChecker;
+ this.validJwtClaims = new SimpleObjectProperty<>();
+ this.licenseSubject = Bindings.createStringBinding(this::getLicenseSubject, validJwtClaims);
+ this.registeredProperty = validJwtClaims.isNotNull();
+
+ Optional claims = licenseChecker.check(settings.licenseKey().get());
+ validJwtClaims.set(claims.orElse(null));
+ }
+
+ @FXML
+ public void initialize() {
+ registrationKeyField.textProperty().addListener(this::registrationKeyChanged);
+ }
+
+ private void registrationKeyChanged(@SuppressWarnings("unused") ObservableValue extends String> observable, @SuppressWarnings("unused") String oldValue, String newValue) {
+ Optional claims = licenseChecker.check(newValue);
+ validJwtClaims.set(claims.orElse(null));
+ if (claims.isPresent()) {
+ settings.licenseKey().set(newValue);
+ }
+ }
+
+ /* Observable Properties */
+
+ public StringBinding licenseSubjectProperty() {
+ return licenseSubject;
+ }
+
+ public String getLicenseSubject() {
+ DecodedJWT claims = validJwtClaims.get();
+ if (claims != null) {
+ return claims.getSubject();
+ } else {
+ return null;
+ }
+ }
+
+ public BooleanBinding registeredProperty() {
+ return registeredProperty;
+ }
+
+ public boolean isRegistered() {
+ return registeredProperty.get();
+ }
+
+}
diff --git a/main/ui/src/main/resources/fxml/preferences.fxml b/main/ui/src/main/resources/fxml/preferences.fxml
index 34ea44235..4a5363883 100644
--- a/main/ui/src/main/resources/fxml/preferences.fxml
+++ b/main/ui/src/main/resources/fxml/preferences.fxml
@@ -35,5 +35,13 @@
+
+
+
+
+
+
+
+
diff --git a/main/ui/src/main/resources/fxml/preferences_registration.fxml b/main/ui/src/main/resources/fxml/preferences_registration.fxml
new file mode 100644
index 000000000..0620ad9ed
--- /dev/null
+++ b/main/ui/src/main/resources/fxml/preferences_registration.fxml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/main/ui/src/main/resources/i18n/strings.properties b/main/ui/src/main/resources/i18n/strings.properties
index 2d7a4d21c..d61d3eb74 100644
--- a/main/ui/src/main/resources/i18n/strings.properties
+++ b/main/ui/src/main/resources/i18n/strings.properties
@@ -123,6 +123,9 @@ preferences.updates.currentVersion=Current Version: %s
preferences.updates.autoUpdateCheck=Check for updates automatically
preferences.updates.checkNowBtn=Check Now
preferences.updates.updateAvailable=Update to version %s available.
+## Registration
+preferences.registration=Registration
+preferences.registration.registeredFor=Registered for %s
# Main Window
main.closeBtn.tooltip=Close