Merge branch 'develop' into feature/app-update

# Conflicts:
#	.github/workflows/appimage.yml
#	.github/workflows/check-jdk-updates.yml
#	.github/workflows/debian.yml
#	.github/workflows/mac-dmg-x64.yml
#	.github/workflows/mac-dmg.yml
#	.github/workflows/win-exe.yml
This commit is contained in:
Sebastian Stenzel
2025-11-12 11:50:21 +01:00
72 changed files with 1816 additions and 103 deletions

View File

@@ -20,7 +20,6 @@ import java.util.ResourceBundle;
public class PasswordStrengthUtil {
private static final int PW_TRUNC_LEN = 100; // truncate very long passwords, since zxcvbn memory and runtime depends vastly on the length
private static final String RESSOURCE_PREFIX = "passwordStrength.messageLabel.";
private static final List<String> SANITIZED_INPUTS = List.of("cryptomator");
private final ResourceBundle resourceBundle;
@@ -48,13 +47,15 @@ public class PasswordStrengthUtil {
}
public String getStrengthDescription(Number score) {
if (score.intValue() == -1) {
return String.format(resourceBundle.getString(RESSOURCE_PREFIX + "tooShort"), minPwLength);
} else if (resourceBundle.containsKey(RESSOURCE_PREFIX + score.intValue())) {
return resourceBundle.getString(RESSOURCE_PREFIX + score.intValue());
} else {
return "";
}
return switch (score.intValue()) {
case -1 -> String.format(resourceBundle.getString("passwordStrength.messageLabel.tooShort"), minPwLength);
case 0 -> resourceBundle.getString("passwordStrength.messageLabel.0");
case 1 -> resourceBundle.getString("passwordStrength.messageLabel.1");
case 2 -> resourceBundle.getString("passwordStrength.messageLabel.2");
case 3 -> resourceBundle.getString("passwordStrength.messageLabel.3");
case 4 -> resourceBundle.getString("passwordStrength.messageLabel.4");
default -> "";
};
}
}

View File

@@ -194,7 +194,7 @@ public class DecryptFileNamesViewController implements FxController {
}
}
//obvservable getter
//observable getter
public ObservableValue<String> dropZoneTextProperty() {
return dropZoneText;

View File

@@ -2,6 +2,7 @@ package org.cryptomator.ui.dialogs;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.StageFactory;
import org.cryptomator.ui.controls.FontAwesome5Icon;
import org.cryptomator.ui.fxapp.FxApplicationScoped;
@@ -19,19 +20,21 @@ public class Dialogs {
private final ResourceBundle resourceBundle;
private final StageFactory stageFactory;
private final DefaultSceneFactory sceneFactory;
private static final String BUTTON_KEY_CLOSE = "generic.button.close";
@Inject
public Dialogs(ResourceBundle resourceBundle, StageFactory stageFactory) {
public Dialogs(ResourceBundle resourceBundle, StageFactory stageFactory, DefaultSceneFactory sceneFactory) {
this.resourceBundle = resourceBundle;
this.stageFactory = stageFactory;
this.sceneFactory = sceneFactory;
}
private static final Logger LOG = LoggerFactory.getLogger(Dialogs.class);
private SimpleDialog.Builder createDialogBuilder() {
return new SimpleDialog.Builder(resourceBundle, stageFactory);
return new SimpleDialog.Builder(resourceBundle, stageFactory, sceneFactory);
}
public SimpleDialog.Builder prepareRemoveVaultDialog(Stage window, Vault vault, ObservableList<Vault> vaults) {

View File

@@ -1,5 +1,6 @@
package org.cryptomator.ui.dialogs;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.StageFactory;
@@ -36,9 +37,9 @@ public class SimpleDialog {
builder.cancelButtonKey != null ? resolveText(builder.cancelButtonKey, null) : null, //
() -> builder.okAction.accept(dialogStage), //
() -> builder.cancelAction.accept(dialogStage)), //
Scene::new, builder.resourceBundle);
builder.sceneFactory, builder.resourceBundle);
dialogStage.setScene(new Scene(loaderFactory.load(FxmlFile.SIMPLE_DIALOG.getRessourcePathString()).getRoot()));
dialogStage.setScene(loaderFactory.createScene(FxmlFile.SIMPLE_DIALOG));
}
public void showAndWait() {
@@ -62,6 +63,7 @@ public class SimpleDialog {
private Stage owner;
private final ResourceBundle resourceBundle;
private final StageFactory stageFactory;
private final DefaultSceneFactory sceneFactory;
private String titleKey;
private String[] titleArgs;
private String messageKey;
@@ -73,9 +75,10 @@ public class SimpleDialog {
private Consumer<Stage> okAction = Stage::close;
private Consumer<Stage> cancelAction = Stage::close;
public Builder(ResourceBundle resourceBundle, StageFactory stageFactory) {
public Builder(ResourceBundle resourceBundle, StageFactory stageFactory, DefaultSceneFactory sceneFactory) {
this.resourceBundle = resourceBundle;
this.stageFactory = stageFactory;
this.sceneFactory = sceneFactory;
}
public Builder setOwner(Stage owner) {

View File

@@ -58,9 +58,15 @@ public class ShareVaultController implements FxController {
private static URI getHubUri(Vault vault) {
try {
var keyID = new URI(vault.getVaultConfigCache().get().getKeyId().toString());
assert keyID.getScheme().startsWith(SCHEME_PREFIX);
return new URI(keyID.getScheme().substring(SCHEME_PREFIX.length()) + "://" + keyID.getHost() + "/app/vaults");
var keyId = new URI(vault.getVaultConfigCache().get().getKeyId().toString());
assert keyId.getScheme().startsWith(SCHEME_PREFIX);
var path = keyId.getPath();
var apiIdx = path.indexOf("/api/");
if (apiIdx < 0) {
throw new IllegalArgumentException("Path does not contain /api/: " + path);
}
var appPath = path.substring(0, apiIdx) + "/app/vaults";
return new URI(keyId.getScheme().substring(SCHEME_PREFIX.length()), keyId.getAuthority(), appPath, null, null);
} catch (IOException e) {
throw new UncheckedIOException(e);
} catch (URISyntaxException e) {