diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 6627f5528..fe1da0f3e 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -45,6 +45,7 @@ module org.cryptomator.desktop { exports org.cryptomator.ui.keyloading.hub to com.fasterxml.jackson.databind; opens org.cryptomator.common.settings to com.google.gson; + opens org.cryptomator.ui.keyloading.hub to com.google.gson, javafx.fxml; opens org.cryptomator.common to javafx.fxml; opens org.cryptomator.common.vaults to javafx.fxml; @@ -55,7 +56,6 @@ module org.cryptomator.desktop { opens org.cryptomator.ui.forgetPassword to javafx.fxml; opens org.cryptomator.ui.fxapp to javafx.fxml; opens org.cryptomator.ui.health to javafx.fxml; - opens org.cryptomator.ui.keyloading.hub to javafx.fxml; opens org.cryptomator.ui.keyloading.masterkeyfile to javafx.fxml; opens org.cryptomator.ui.lock to javafx.fxml; opens org.cryptomator.ui.mainwindow to javafx.fxml; diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/AuthFlowController.java b/src/main/java/org/cryptomator/ui/keyloading/hub/AuthFlowController.java index 65c9a0df7..339030cf2 100644 --- a/src/main/java/org/cryptomator/ui/keyloading/hub/AuthFlowController.java +++ b/src/main/java/org/cryptomator/ui/keyloading/hub/AuthFlowController.java @@ -1,15 +1,12 @@ package org.cryptomator.ui.keyloading.hub; +import com.nimbusds.jose.JWEObject; import dagger.Lazy; -import org.cryptomator.ui.common.ErrorComponent; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; -import org.cryptomator.ui.common.UserInteractionLock; import org.cryptomator.ui.keyloading.KeyLoading; import org.cryptomator.ui.keyloading.KeyLoadingScoped; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.inject.Named; @@ -24,29 +21,27 @@ import javafx.scene.Scene; import javafx.stage.Stage; import javafx.stage.WindowEvent; import java.net.URI; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; @KeyLoadingScoped public class AuthFlowController implements FxController { - private static final Logger LOG = LoggerFactory.getLogger(AuthFlowController.class); - private final Application application; private final Stage window; private final ExecutorService executor; private final String deviceId; private final HubConfig hubConfig; private final AtomicReference tokenRef; - private final UserInteractionLock result; + private final CompletableFuture result; private final Lazy receiveKeyScene; - private final ErrorComponent.Builder errorComponent; private final ObjectProperty authUri; private final StringBinding authHost; private AuthFlowTask task; @Inject - public AuthFlowController(Application application, @KeyLoading Stage window, ExecutorService executor, @Named("deviceId") String deviceId, HubConfig hubConfig, @Named("bearerToken") AtomicReference tokenRef, UserInteractionLock result, @FxmlScene(FxmlFile.HUB_RECEIVE_KEY) Lazy receiveKeyScene, ErrorComponent.Builder errorComponent) { + public AuthFlowController(Application application, @KeyLoading Stage window, ExecutorService executor, @Named("deviceId") String deviceId, HubConfig hubConfig, @Named("bearerToken") AtomicReference tokenRef, CompletableFuture result, @FxmlScene(FxmlFile.HUB_RECEIVE_KEY) Lazy receiveKeyScene) { this.application = application; this.window = window; this.executor = executor; @@ -55,7 +50,6 @@ public class AuthFlowController implements FxController { this.tokenRef = tokenRef; this.result = result; this.receiveKeyScene = receiveKeyScene; - this.errorComponent = errorComponent; this.authUri = new SimpleObjectProperty<>(); this.authHost = Bindings.createStringBinding(this::getAuthHost, authUri); this.window.addEventHandler(WindowEvent.WINDOW_HIDING, this::windowClosed); @@ -64,7 +58,7 @@ public class AuthFlowController implements FxController { @FXML public void initialize() { assert task == null; - task = new AuthFlowTask(hubConfig, new AuthFlowContext(deviceId), this::setAuthUri);; + task = new AuthFlowTask(hubConfig, new AuthFlowContext(deviceId), this::setAuthUri); task.setOnFailed(this::authFailed); task.setOnSucceeded(this::authSucceeded); executor.submit(task); @@ -88,11 +82,7 @@ public class AuthFlowController implements FxController { private void windowClosed(WindowEvent windowEvent) { // stop server, if it is still running task.cancel(); - // if not already interacted, mark this workflow as cancelled: - if (result.awaitingInteraction().get()) { - LOG.debug("Authorization cancelled by user."); - result.interacted(HubKeyLoadingModule.HubLoadingResult.CANCELLED); - } + result.cancel(true); } private void authSucceeded(WorkerStateEvent workerStateEvent) { @@ -102,11 +92,9 @@ public class AuthFlowController implements FxController { } private void authFailed(WorkerStateEvent workerStateEvent) { - result.interacted(HubKeyLoadingModule.HubLoadingResult.FAILED); window.requestFocus(); var exception = workerStateEvent.getSource().getException(); - LOG.error("Authentication failed", exception); - errorComponent.cause(exception).window(window).build().showErrorScene(); + result.completeExceptionally(exception); } /* Getter/Setter */ diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/CreateDeviceDto.java b/src/main/java/org/cryptomator/ui/keyloading/hub/CreateDeviceDto.java new file mode 100644 index 000000000..71377a318 --- /dev/null +++ b/src/main/java/org/cryptomator/ui/keyloading/hub/CreateDeviceDto.java @@ -0,0 +1,9 @@ +package org.cryptomator.ui.keyloading.hub; + +class CreateDeviceDto { + + public String id; + public String name; + public String publicKey; + +} diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/HubKeyLoadingModule.java b/src/main/java/org/cryptomator/ui/keyloading/hub/HubKeyLoadingModule.java index 04faa1493..4d4d810a3 100644 --- a/src/main/java/org/cryptomator/ui/keyloading/hub/HubKeyLoadingModule.java +++ b/src/main/java/org/cryptomator/ui/keyloading/hub/HubKeyLoadingModule.java @@ -17,7 +17,6 @@ import org.cryptomator.ui.common.FxmlLoaderFactory; import org.cryptomator.ui.common.FxmlScene; import org.cryptomator.ui.common.NewPasswordController; import org.cryptomator.ui.common.PasswordStrengthUtil; -import org.cryptomator.ui.common.UserInteractionLock; import org.cryptomator.ui.keyloading.KeyLoading; import org.cryptomator.ui.keyloading.KeyLoadingScoped; import org.cryptomator.ui.keyloading.KeyLoadingStrategy; @@ -28,17 +27,12 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.util.Objects; import java.util.ResourceBundle; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicReference; @Module public abstract class HubKeyLoadingModule { - public enum HubLoadingResult { - SUCCESS, - FAILED, - CANCELLED - } - @Provides @KeyLoadingScoped static HubConfig provideHubConfig(@KeyLoading Vault vault) { @@ -67,14 +61,8 @@ public abstract class HubKeyLoadingModule { @Provides @KeyLoadingScoped - static AtomicReference provideJweRef() { - return new AtomicReference<>(); - } - - @Provides - @KeyLoadingScoped - static UserInteractionLock provideResultLock() { - return new UserInteractionLock<>(null); + static CompletableFuture provideResult() { + return new CompletableFuture<>(); } @Binds diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/HubKeyLoadingStrategy.java b/src/main/java/org/cryptomator/ui/keyloading/hub/HubKeyLoadingStrategy.java index 2aadfb1d0..10d1399e2 100644 --- a/src/main/java/org/cryptomator/ui/keyloading/hub/HubKeyLoadingStrategy.java +++ b/src/main/java/org/cryptomator/ui/keyloading/hub/HubKeyLoadingStrategy.java @@ -8,7 +8,6 @@ import org.cryptomator.cryptolib.api.Masterkey; import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; -import org.cryptomator.ui.common.UserInteractionLock; import org.cryptomator.ui.keyloading.KeyLoading; import org.cryptomator.ui.keyloading.KeyLoadingStrategy; import org.cryptomator.ui.unlock.UnlockCancelledException; @@ -19,7 +18,9 @@ import javafx.scene.Scene; import javafx.stage.Stage; import javafx.stage.Window; import java.net.URI; -import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; @KeyLoading public class HubKeyLoadingStrategy implements KeyLoadingStrategy { @@ -30,37 +31,37 @@ public class HubKeyLoadingStrategy implements KeyLoadingStrategy { private final Stage window; private final Lazy authFlowScene; - private final UserInteractionLock userInteraction; + private final CompletableFuture result; private final DeviceKey deviceKey; - private final AtomicReference jweRef; @Inject - public HubKeyLoadingStrategy(@KeyLoading Stage window, @FxmlScene(FxmlFile.HUB_AUTH_FLOW) Lazy authFlowScene, UserInteractionLock userInteraction, DeviceKey deviceKey, AtomicReference jweRef) { + public HubKeyLoadingStrategy(@KeyLoading Stage window, @FxmlScene(FxmlFile.HUB_AUTH_FLOW) Lazy authFlowScene, CompletableFuture result, DeviceKey deviceKey) { this.window = window; this.authFlowScene = authFlowScene; - this.userInteraction = userInteraction; + this.result = result; this.deviceKey = deviceKey; - this.jweRef = jweRef; } @Override public Masterkey loadKey(URI keyId) throws MasterkeyLoadingFailedException { Preconditions.checkArgument(keyId.getScheme().startsWith(SCHEME_PREFIX)); try { - return switch (auth()) { - case SUCCESS -> JWEHelper.decrypt(jweRef.get(), deviceKey.get().getPrivate()); - case FAILED -> throw new MasterkeyLoadingFailedException("failed to load keypair"); - case CANCELLED -> throw new UnlockCancelledException("User cancelled auth workflow"); - }; + startAuthFlow(); + var jwe = result.get(); + return JWEHelper.decrypt(jwe, deviceKey.get().getPrivate()); } catch (DeviceKey.DeviceKeyRetrievalException e) { - throw new MasterkeyLoadingFailedException("Failed to create or load device key pair", e); + throw new MasterkeyLoadingFailedException("Failed to load keypair", e); + } catch (CancellationException e) { + throw new UnlockCancelledException("User cancelled auth workflow", e); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new UnlockCancelledException("Loading interrupted", e); + } catch (ExecutionException e) { + throw new MasterkeyLoadingFailedException("Failed to retrieve key", e); } } - private HubKeyLoadingModule.HubLoadingResult auth() throws InterruptedException { + private void startAuthFlow() { Platform.runLater(() -> { window.setScene(authFlowScene.get()); window.show(); @@ -72,7 +73,6 @@ public class HubKeyLoadingStrategy implements KeyLoadingStrategy { window.centerOnScreen(); } }); - return userInteraction.awaitInteraction(); } } diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java b/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java index 90efc6abc..be4c3b791 100644 --- a/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java +++ b/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java @@ -3,13 +3,12 @@ package org.cryptomator.ui.keyloading.hub; import com.nimbusds.jose.JWEObject; import dagger.Lazy; import org.cryptomator.common.vaults.Vault; -import org.cryptomator.ui.common.ErrorComponent; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; -import org.cryptomator.ui.common.UserInteractionLock; import org.cryptomator.ui.keyloading.KeyLoading; import org.cryptomator.ui.keyloading.KeyLoadingScoped; +import org.eclipse.jetty.io.RuntimeIOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,6 +29,7 @@ import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.text.ParseException; import java.util.Objects; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; @@ -42,24 +42,20 @@ public class ReceiveKeyController implements FxController { private final Stage window; private final String deviceId; private final String bearerToken; - private final AtomicReference jweRef; - private final UserInteractionLock result; + private final CompletableFuture result; private final Lazy registerDeviceScene; private final Lazy unauthorizedScene; - private final ErrorComponent.Builder errorComponent; private final URI vaultBaseUri; private final HttpClient httpClient; @Inject - public ReceiveKeyController(@KeyLoading Vault vault, ExecutorService executor, @KeyLoading Stage window, @Named("deviceId") String deviceId, @Named("bearerToken") AtomicReference tokenRef, AtomicReference jweRef, UserInteractionLock result, @FxmlScene(FxmlFile.HUB_REGISTER_DEVICE) Lazy registerDeviceScene, @FxmlScene(FxmlFile.HUB_UNAUTHORIZED_DEVICE) Lazy unauthorizedScene, ErrorComponent.Builder errorComponent) { + public ReceiveKeyController(@KeyLoading Vault vault, ExecutorService executor, @KeyLoading Stage window, @Named("deviceId") String deviceId, @Named("bearerToken") AtomicReference tokenRef, CompletableFuture result, @FxmlScene(FxmlFile.HUB_REGISTER_DEVICE) Lazy registerDeviceScene, @FxmlScene(FxmlFile.HUB_UNAUTHORIZED_DEVICE) Lazy unauthorizedScene) { this.window = window; this.deviceId = deviceId; this.bearerToken = Objects.requireNonNull(tokenRef.get()); - this.jweRef = jweRef; this.result = result; this.registerDeviceScene = registerDeviceScene; this.unauthorizedScene = unauthorizedScene; - this.errorComponent = errorComponent; this.vaultBaseUri = getVaultBaseUri(vault); this.window.addEventHandler(WindowEvent.WINDOW_HIDING, this::windowClosed); this.httpClient = HttpClient.newBuilder().executor(executor).build(); @@ -73,30 +69,30 @@ public class ReceiveKeyController implements FxController { .GET() // .build(); httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream()) // - .whenCompleteAsync(this::loadedExistingKey, Platform::runLater); + .thenAcceptAsync(this::loadedExistingKey, Platform::runLater) // + .exceptionally(this::retrievalFailed); } - private void loadedExistingKey(HttpResponse response, Throwable error) { - if (error != null) { - retrievalFailed(error); - } else { + private void loadedExistingKey(HttpResponse response) { + try { switch (response.statusCode()) { case 200 -> retrievalSucceeded(response); case 403 -> accessNotGranted(); case 404 -> needsDeviceRegistration(); - default -> retrievalFailed(new IOException("Unexpected response " + response.statusCode())); + default -> throw new IOException("Unexpected response " + response.statusCode()); } + } catch (IOException e) { + throw new RuntimeIOException(e); } } - private void retrievalSucceeded(HttpResponse response) { + private void retrievalSucceeded(HttpResponse response) throws IOException { try { var string = HttpHelper.readBody(response); - jweRef.set(JWEObject.parse(string)); - result.interacted(HubKeyLoadingModule.HubLoadingResult.SUCCESS); + result.complete(JWEObject.parse(string)); window.close(); - } catch (ParseException | IOException e) { - retrievalFailed(e); + } catch (ParseException e) { + throw new IOException("Failed to parse JWE", e); } } @@ -108,10 +104,9 @@ public class ReceiveKeyController implements FxController { window.setScene(unauthorizedScene.get()); } - private void retrievalFailed(Throwable cause) { - result.interacted(HubKeyLoadingModule.HubLoadingResult.FAILED); - LOG.error("Key retrieval failed", cause); - errorComponent.cause(cause).window(window).build().showErrorScene(); + private Void retrievalFailed(Throwable cause) { + result.completeExceptionally(cause); + return null; } @FXML @@ -120,11 +115,7 @@ public class ReceiveKeyController implements FxController { } private void windowClosed(WindowEvent windowEvent) { - // if not already interacted, mark this workflow as cancelled: - if (result.awaitingInteraction().get()) { - LOG.debug("Authorization cancelled by user."); - result.interacted(HubKeyLoadingModule.HubLoadingResult.CANCELLED); - } + result.cancel(true); } private static URI appendPath(URI base, String path) { diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java b/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java index 46349280b..d50b565b5 100644 --- a/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java +++ b/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java @@ -1,57 +1,92 @@ package org.cryptomator.ui.keyloading.hub; +import com.auth0.jwt.JWT; +import com.auth0.jwt.interfaces.DecodedJWT; import com.google.common.io.BaseEncoding; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.nimbusds.jose.JWEObject; import org.cryptomator.common.settings.DeviceKey; -import org.cryptomator.cryptolib.common.MessageDigestSupplier; import org.cryptomator.cryptolib.common.P384KeyPair; import org.cryptomator.ui.common.FxController; -import org.cryptomator.ui.common.UserInteractionLock; import org.cryptomator.ui.keyloading.KeyLoading; import org.cryptomator.ui.keyloading.KeyLoadingScoped; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.inject.Inject; -import javafx.application.Application; +import javax.inject.Named; +import javafx.application.Platform; import javafx.fxml.FXML; +import javafx.scene.control.TextField; import javafx.stage.Stage; import javafx.stage.WindowEvent; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; -import java.security.KeyPair; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; @KeyLoadingScoped public class RegisterDeviceController implements FxController { - private final Application application; + private static final Logger LOG = LoggerFactory.getLogger(RegisterDeviceController.class); + private static final Gson GSON = new GsonBuilder().setLenient().create(); + private final Stage window; private final HubConfig hubConfig; + private final String bearerToken; + private final String deviceId; private final P384KeyPair keyPair; - private final UserInteractionLock result; - private final String verificationCode; + private final CompletableFuture result; + private final DecodedJWT jwt; + private final HttpClient httpClient; + + public TextField deviceNameField; @Inject - public RegisterDeviceController(Application application, SecureRandom csprng, @KeyLoading Stage window, HubConfig hubConfig, DeviceKey deviceKey, UserInteractionLock result) { - this.application = application; + public RegisterDeviceController(@KeyLoading Stage window, ExecutorService executor, HubConfig hubConfig, @Named("deviceId") String deviceId, DeviceKey deviceKey, CompletableFuture result, @Named("bearerToken") AtomicReference bearerToken) { this.window = window; this.hubConfig = hubConfig; + this.deviceId = deviceId; this.keyPair = Objects.requireNonNull(deviceKey.get()); this.result = result; + this.bearerToken = Objects.requireNonNull(bearerToken.get()); + this.jwt = JWT.decode(this.bearerToken); this.window.addEventHandler(WindowEvent.WINDOW_HIDING, this::windowClosed); - this.verificationCode = String.format("%06d", csprng.nextInt(1_000_000)); + this.httpClient = HttpClient.newBuilder().executor(executor).build(); } @FXML - public void browse() { + public void register() { + var keyUri = URI.create("http://localhost:9090/devices/" + deviceId); // TODO lol hubConfig.deviceRegistrationUrl var deviceKey = keyPair.getPublic().getEncoded(); - var encodedKey = BaseEncoding.base64Url().omitPadding().encode(deviceKey); - var hashedKey = MessageDigestSupplier.SHA256.get().digest(deviceKey); - var deviceId = BaseEncoding.base16().encode(hashedKey); - var hash = computeVerificationHash(deviceId + encodedKey + verificationCode); - var url = hubConfig.deviceRegistrationUrl + "&device_key=" + encodedKey + "&device_id=" + deviceId + "&verification_hash=" + hash; - application.getHostServices().showDocument(url); + var dto = new CreateDeviceDto(); + dto.id = deviceId; + dto.name = deviceNameField.getText(); + dto.publicKey = BaseEncoding.base64Url().omitPadding().encode(deviceKey); + var json = GSON.toJson(dto); // TODO: do we want to keep GSON? doesn't support records -.- + var request = HttpRequest.newBuilder(keyUri) // + .header("Authorization", "Bearer " + bearerToken) // + .header("Content-Type", "application/json").PUT(HttpRequest.BodyPublishers.ofString(json, StandardCharsets.UTF_8)) // + .build(); + httpClient.sendAsync(request, HttpResponse.BodyHandlers.discarding()) // + .thenAcceptAsync(this::registrationSucceeded, Platform::runLater) // + .exceptionally(this::registrationFailed); + } + + private void registrationSucceeded(HttpResponse voidHttpResponse) { + LOG.info("Registered!"); + window.close(); // TODO: show visual feedback "please wait for device authorization" + } + + private Void registrationFailed(Throwable cause) { + result.completeExceptionally(cause); + return null; } @FXML @@ -60,26 +95,14 @@ public class RegisterDeviceController implements FxController { } private void windowClosed(WindowEvent windowEvent) { - // if not already interacted, mark this workflow as cancelled: - if (result.awaitingInteraction().get()) { - result.interacted(HubKeyLoadingModule.HubLoadingResult.CANCELLED); - } - } - - private static String computeVerificationHash(String input) { - try { - var digest = MessageDigest.getInstance("SHA-256"); - digest.update(StandardCharsets.UTF_8.encode(input)); - return BaseEncoding.base64Url().omitPadding().encode(digest.digest()); - } catch (NoSuchAlgorithmException e) { - throw new IllegalStateException("Every implementation of the Java platform is required to support SHA-256."); - } + result.cancel(true); } /* Getter */ - public String getVerificationCode() { - return verificationCode; + public String getUserName() { + return jwt.getClaim("email").asString(); } + } diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/UnauthorizedDeviceController.java b/src/main/java/org/cryptomator/ui/keyloading/hub/UnauthorizedDeviceController.java index a915f4016..1a7cbab02 100644 --- a/src/main/java/org/cryptomator/ui/keyloading/hub/UnauthorizedDeviceController.java +++ b/src/main/java/org/cryptomator/ui/keyloading/hub/UnauthorizedDeviceController.java @@ -1,27 +1,24 @@ package org.cryptomator.ui.keyloading.hub; +import com.nimbusds.jose.JWEObject; import org.cryptomator.ui.common.FxController; -import org.cryptomator.ui.common.UserInteractionLock; import org.cryptomator.ui.keyloading.KeyLoading; import org.cryptomator.ui.keyloading.KeyLoadingScoped; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.fxml.FXML; import javafx.stage.Stage; import javafx.stage.WindowEvent; +import java.util.concurrent.CompletableFuture; @KeyLoadingScoped public class UnauthorizedDeviceController implements FxController { - private static final Logger LOG = LoggerFactory.getLogger(UnauthorizedDeviceController.class); - private final Stage window; - private final UserInteractionLock result; + private final CompletableFuture result; @Inject - public UnauthorizedDeviceController(@KeyLoading Stage window, UserInteractionLock result) { + public UnauthorizedDeviceController(@KeyLoading Stage window, CompletableFuture result) { this.window = window; this.result = result; this.window.addEventHandler(WindowEvent.WINDOW_HIDING, this::windowClosed); @@ -33,10 +30,6 @@ public class UnauthorizedDeviceController implements FxController { } private void windowClosed(WindowEvent windowEvent) { - // if not already interacted, mark this workflow as cancelled: - if (result.awaitingInteraction().get()) { - LOG.debug("Authorization cancelled. Device not authorized."); - result.interacted(HubKeyLoadingModule.HubLoadingResult.CANCELLED); - } + result.cancel(true); } } diff --git a/src/main/resources/fxml/hub_register_device.fxml b/src/main/resources/fxml/hub_register_device.fxml index edf7249e6..2fd5ceaa5 100644 --- a/src/main/resources/fxml/hub_register_device.fxml +++ b/src/main/resources/fxml/hub_register_device.fxml @@ -1,16 +1,15 @@ - + + - - - @@ -42,11 +44,7 @@ +