show archived vault dialog on unlock when Hub returns 410

This commit is contained in:
Jan-Peter Klein
2025-12-17 09:56:56 +01:00
parent 1e861ac187
commit 760e260eba
6 changed files with 124 additions and 3 deletions

View File

@@ -18,6 +18,7 @@ public enum FxmlFile {
FORGET_PASSWORD("/fxml/forget_password.fxml"), //
HEALTH_START("/fxml/health_start.fxml"), //
HEALTH_CHECK_LIST("/fxml/health_check_list.fxml"), //
HUB_ARCHIVED_VAULT("/fxml/hub_archived_vault.fxml"), //
HUB_NO_KEYCHAIN("/fxml/hub_no_keychain.fxml"), //
HUB_AUTH_FLOW("/fxml/hub_auth_flow.fxml"), //
HUB_INVALID_LICENSE("/fxml/hub_invalid_license.fxml"), //

View File

@@ -0,0 +1,34 @@
package org.cryptomator.ui.keyloading.hub;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.keyloading.KeyLoading;
import org.cryptomator.ui.keyloading.KeyLoadingScoped;
import javax.inject.Inject;
import javafx.fxml.FXML;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import java.util.concurrent.CompletableFuture;
@KeyLoadingScoped
public class ArchivedVaultController implements FxController {
private final Stage window;
private final CompletableFuture<ReceivedKey> result;
@Inject
public ArchivedVaultController(@KeyLoading Stage window, CompletableFuture<ReceivedKey> result) {
this.window = window;
this.result = result;
this.window.addEventHandler(WindowEvent.WINDOW_HIDING, this::windowClosed);
}
@FXML
public void close() {
window.close();
}
private void windowClosed(WindowEvent windowEvent) {
result.cancel(true);
}
}

View File

@@ -161,6 +161,13 @@ public abstract class HubKeyLoadingModule {
return fxmlLoaders.createScene(FxmlFile.HUB_UNAUTHORIZED_DEVICE);
}
@Provides
@FxmlScene(FxmlFile.HUB_ARCHIVED_VAULT)
@KeyLoadingScoped
static Scene provideHubArchivedVaultScene(@KeyLoading FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.HUB_ARCHIVED_VAULT);
}
@Provides
@FxmlScene(FxmlFile.HUB_REQUIRE_ACCOUNT_INIT)
@KeyLoadingScoped
@@ -213,6 +220,11 @@ public abstract class HubKeyLoadingModule {
@FxControllerKey(RegisterFailedController.class)
abstract FxController bindRegisterFailedController(RegisterFailedController controller);
@Binds
@IntoMap
@FxControllerKey(ArchivedVaultController.class)
abstract FxController bindArchivedVaultController(ArchivedVaultController controller);
@Binds
@IntoMap
@FxControllerKey(UnauthorizedDeviceController.class)

View File

@@ -54,12 +54,25 @@ public class ReceiveKeyController implements FxController {
private final Lazy<Scene> registerDeviceScene;
private final Lazy<Scene> legacyRegisterDeviceScene;
private final Lazy<Scene> unauthorizedScene;
private final Lazy<Scene> archivedVaultScene;
private final Lazy<Scene> accountInitializationScene;
private final Lazy<Scene> invalidLicenseScene;
private final HttpClient httpClient;
@Inject
public ReceiveKeyController(@KeyLoading Vault vault, ExecutorService executor, @KeyLoading Stage window, HubConfig hubConfig, @Named("deviceId") String deviceId, @Named("bearerToken") AtomicReference<String> tokenRef, CompletableFuture<ReceivedKey> result, @FxmlScene(FxmlFile.HUB_REGISTER_DEVICE) Lazy<Scene> registerDeviceScene, @FxmlScene(FxmlFile.HUB_LEGACY_REGISTER_DEVICE) Lazy<Scene> legacyRegisterDeviceScene, @FxmlScene(FxmlFile.HUB_UNAUTHORIZED_DEVICE) Lazy<Scene> unauthorizedScene, @FxmlScene(FxmlFile.HUB_REQUIRE_ACCOUNT_INIT) Lazy<Scene> accountInitializationScene, @FxmlScene(FxmlFile.HUB_INVALID_LICENSE) Lazy<Scene> invalidLicenseScene) {
public ReceiveKeyController(@KeyLoading Vault vault,
ExecutorService executor,
@KeyLoading Stage window,
HubConfig hubConfig,
@Named("deviceId") String deviceId,
@Named("bearerToken") AtomicReference<String> tokenRef,
CompletableFuture<ReceivedKey> result,
@FxmlScene(FxmlFile.HUB_REGISTER_DEVICE) Lazy<Scene> registerDeviceScene,
@FxmlScene(FxmlFile.HUB_LEGACY_REGISTER_DEVICE) Lazy<Scene> legacyRegisterDeviceScene,
@FxmlScene(FxmlFile.HUB_ARCHIVED_VAULT) Lazy<Scene> archivedVaultScene,
@FxmlScene(FxmlFile.HUB_UNAUTHORIZED_DEVICE) Lazy<Scene> unauthorizedScene,
@FxmlScene(FxmlFile.HUB_REQUIRE_ACCOUNT_INIT) Lazy<Scene> accountInitializationScene,
@FxmlScene(FxmlFile.HUB_INVALID_LICENSE) Lazy<Scene> invalidLicenseScene) {
this.window = window;
this.hubConfig = hubConfig;
this.vaultId = extractVaultId(vault.getVaultConfigCache().getUnchecked().getKeyId()); // TODO: access vault config's JTI directly (requires changes in cryptofs)
@@ -69,6 +82,7 @@ public class ReceiveKeyController implements FxController {
this.registerDeviceScene = registerDeviceScene;
this.legacyRegisterDeviceScene = legacyRegisterDeviceScene;
this.unauthorizedScene = unauthorizedScene;
this.archivedVaultScene = archivedVaultScene;
this.accountInitializationScene = accountInitializationScene;
this.invalidLicenseScene = invalidLicenseScene;
this.window.addEventHandler(WindowEvent.WINDOW_HIDING, this::windowClosed);
@@ -184,7 +198,8 @@ public class ReceiveKeyController implements FxController {
switch (response.statusCode()) {
case 200 -> receivedBothEncryptedKeys(response.body(), encryptedUserKey);
case 402 -> licenseExceeded();
case 403, 410 -> accessNotGranted(); // or vault has been archived, effectively disallowing access - TODO: add specific dialog?
case 403 -> accessNotGranted();
case 410 -> accessGoneVaultArchived();
case 449 -> accountInitializationRequired();
default -> throw new IllegalStateException("Unexpected response " + response.statusCode());
}
@@ -228,7 +243,8 @@ public class ReceiveKeyController implements FxController {
switch (response.statusCode()) {
case 200 -> receivedLegacyAccessTokenSuccess(response.body());
case 402 -> licenseExceeded();
case 403, 410 -> accessNotGranted(); // or vault has been archived, effectively disallowing access
case 403 -> accessNotGranted();
case 410 -> accessGoneVaultArchived();
case 404 -> needsLegacyDeviceRegistration();
default -> throw new IOException("Unexpected response " + response.statusCode());
}
@@ -261,6 +277,10 @@ public class ReceiveKeyController implements FxController {
window.setScene(unauthorizedScene.get());
}
private void accessGoneVaultArchived() {
window.setScene(archivedVaultScene.get());
}
private void accountInitializationRequired() {
window.setScene(accountInitializationScene.get());
}