From 39c543d7ff8dc4c77ff425cc3a333347549d6740 Mon Sep 17 00:00:00 2001 From: crschnick Date: Mon, 16 Mar 2026 04:13:40 +0000 Subject: [PATCH] Rework --- .../PasswordManagerInPlaceKeyStrategy.java | 92 +++++++++++++++++++ .../xpipe/app/cred/SshIdentityStrategy.java | 20 +++- .../app/pwman/PasswordManagerKeyStrategy.java | 24 +++++ dist/changelog/22.0.md | 2 +- .../base/identity/IdentityChoiceBuilder.java | 2 +- lang/strings/translations_en.properties | 5 +- 6 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/io/xpipe/app/cred/PasswordManagerInPlaceKeyStrategy.java diff --git a/app/src/main/java/io/xpipe/app/cred/PasswordManagerInPlaceKeyStrategy.java b/app/src/main/java/io/xpipe/app/cred/PasswordManagerInPlaceKeyStrategy.java new file mode 100644 index 000000000..d18117b21 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/cred/PasswordManagerInPlaceKeyStrategy.java @@ -0,0 +1,92 @@ +package io.xpipe.app.cred; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.comp.base.*; +import io.xpipe.app.core.App; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.ValidationException; +import io.xpipe.app.platform.OptionsBuilder; +import io.xpipe.app.prefs.AppPrefs; +import io.xpipe.app.process.CommandBuilder; +import io.xpipe.app.process.ShellControl; +import io.xpipe.app.pwman.PasswordManagerKeyConfiguration; +import io.xpipe.app.secret.SecretPasswordManagerStrategy; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.util.Validators; +import io.xpipe.core.FilePath; +import io.xpipe.core.KeyValue; +import javafx.beans.binding.Bindings; +import javafx.beans.property.Property; +import javafx.beans.property.SimpleStringProperty; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import lombok.Builder; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; +import org.kordamp.ikonli.javafx.FontIcon; + +import java.util.List; + +@JsonTypeName("passwordManagerInPlaceKey") +@Value +@Jacksonized +@Builder +public class PasswordManagerInPlaceKeyStrategy implements SshIdentityAgentStrategy { + + @SuppressWarnings("unused") + public static OptionsBuilder createOptions( + Property p, SshIdentityStrategyChoiceConfig config) { + var options = new OptionsBuilder(); + var prefs = AppPrefs.get(); + var keyProperty = options.map(p, PasswordManagerInPlaceKeyStrategy::getKey); + var field = new TextFieldComp(keyProperty).apply(struc -> struc.promptTextProperty() + .bind(Bindings.createStringBinding( + () -> { + return prefs.passwordManager().getValue() != null + ? prefs.passwordManager().getValue().getKeyPlaceholder() + : "?"; + }, + prefs.passwordManager()))); + var button = new ButtonComp(null, new FontIcon("mdomz-settings"), () -> { + AppPrefs.get().selectCategory("passwordManager"); + App.getApp().getStage().requestFocus(); + }); + var content = new InputGroupComp(List.of(field, button)); + content.setMainReference(field); + return options.nameAndDescription("passwordManagerInPlaceKeyKey") + .addComp(content, keyProperty) + .nonNull() + .bind( + () -> { + return PasswordManagerInPlaceKeyStrategy.builder().key(keyProperty.get()).build(); + }, + p); + } + + String key; + + @Override + public void prepareParent(ShellControl parent) throws Exception { + + } + + @Override + public void buildCommand(CommandBuilder builder) { + + } + + @Override + public List configOptions(ShellControl sc) throws Exception { + return List.of(); + } + + @Override + public PublicKeyStrategy getPublicKeyStrategy() { + return null; + } + + @Override + public FilePath determinetAgentSocketLocation(ShellControl parent) throws Exception { + return null; + } +} diff --git a/app/src/main/java/io/xpipe/app/cred/SshIdentityStrategy.java b/app/src/main/java/io/xpipe/app/cred/SshIdentityStrategy.java index d9c51256b..05f48db76 100644 --- a/app/src/main/java/io/xpipe/app/cred/SshIdentityStrategy.java +++ b/app/src/main/java/io/xpipe/app/cred/SshIdentityStrategy.java @@ -20,7 +20,7 @@ import java.util.Optional; @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") public interface SshIdentityStrategy { - static List> getClasses() { + static List> getAvailable() { var l = new ArrayList>(); l.add(NoIdentityStrategy.class); l.add(InPlaceKeyStrategy.class); @@ -43,6 +43,24 @@ public interface SshIdentityStrategy { return l; } + static List> getClasses() { + var l = new ArrayList>(); + l.add(NoIdentityStrategy.class); + l.add(InPlaceKeyStrategy.class); + l.add(KeyFileStrategy.class); + l.add(OpenSshAgentStrategy.class); + l.add(PasswordManagerAgentStrategy.class); + l.add(PasswordManagerInPlaceKeyStrategy.class); + l.add(CustomAgentStrategy.class); + l.add(GpgAgentStrategy.class); + l.add(PageantStrategy.class); + l.add(YubikeyPivStrategy.class); + l.add(CustomPkcs11LibraryStrategy.class); + l.add(OtherExternalAgentStrategy.class); + + return l; + } + static Optional getPublicKeyPath(ShellControl sc, String publicKey) throws Exception { if (publicKey == null || publicKey.isBlank()) { return Optional.empty(); diff --git a/app/src/main/java/io/xpipe/app/pwman/PasswordManagerKeyStrategy.java b/app/src/main/java/io/xpipe/app/pwman/PasswordManagerKeyStrategy.java index 9cfd7b302..dc4eef1de 100644 --- a/app/src/main/java/io/xpipe/app/pwman/PasswordManagerKeyStrategy.java +++ b/app/src/main/java/io/xpipe/app/pwman/PasswordManagerKeyStrategy.java @@ -57,6 +57,29 @@ public interface PasswordManagerKeyStrategy { } } + + @JsonTypeName("inlineSeparate") + @Value + @Jacksonized + @Builder + class InlineSeparate implements PasswordManagerKeyStrategy { + + @SuppressWarnings("unused") + public static String getOptionsNameKey() { + return "inlineKey"; + } + + @Override + public boolean useAgent() { + return false; + } + + @Override + public SshIdentityAgentStrategy getSshIdentityStrategy(String publicKey, boolean forward) { + return null; + } + } + @JsonTypeName("agent") @Value @Jacksonized @@ -218,6 +241,7 @@ public interface PasswordManagerKeyStrategy { l.add(KeePassXcOpenSshAgent.class); l.add(KeePassXcPageant.class); l.add(Inline.class); + l.add(InlineSeparate.class); return l; } } diff --git a/dist/changelog/22.0.md b/dist/changelog/22.0.md index f1596151b..82580abb2 100644 --- a/dist/changelog/22.0.md +++ b/dist/changelog/22.0.md @@ -51,4 +51,4 @@ Furthermore, the container restart action will now properly restart any systemd - Fix Keeper SMS handling when CLI had a different login duration configured - Add support for multiple 1password accounts - Add support for Bitwarden flatpak and macOS App Store installations -- +- Add support for KeePassXC flatpak diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentityChoiceBuilder.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentityChoiceBuilder.java index 246b68cc6..2d9fa27e4 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentityChoiceBuilder.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentityChoiceBuilder.java @@ -85,7 +85,7 @@ public class IdentityChoiceBuilder { .allowNull(false) .property(identity) .customConfiguration(config) - .available(SshIdentityStrategy.getClasses()) + .available(SshIdentityStrategy.getAvailable()) .transformer(entryComboBox -> { var button = new ButtonComp(null, new LabelGraphic.IconGraphic("mdi2k-key-plus"), () -> { ProcessControlProvider.get().showSshKeygenDialog(null, identity); diff --git a/lang/strings/translations_en.properties b/lang/strings/translations_en.properties index 4f7f2b39d..3baf1e3e6 100644 --- a/lang/strings/translations_en.properties +++ b/lang/strings/translations_en.properties @@ -1459,6 +1459,8 @@ passwordManagerKey=Password manager key #force passwordManagerKeyDescription=The password manager identifier of the credentials entry passwordManagerAgent=Password manager agent +passwordManagerInPlaceKey=Password manager +passwordManagerInPlaceKeyKey=Password manager identifier for the SSH key entry dockerComposeProject.displayName=Docker compose project dockerComposeProject.displayDescription=Group containers of a compose project together sshVerboseOutput=Enable verbose SSH output @@ -1997,7 +1999,8 @@ prefsRestartTitle=Restart required prefsRestartContent=Some options you changed require an application restart to apply. Do you want to restart XPipe now? bashShell=Bash shell sshKey=SSH key -inlineKey=Retrieve directly from CLI +inlineKey=Retrieve directly +inlineSeparateKey=Retrieve additional key keyAgent=Use agent integration passwordManagerKeyStrategy=SSH key retrieval method passwordManagerKeyStrategyDescription=How to retrieve SSH keys stored in the password manager. When disabled, no keys can be retrieved. When an SSH agent is configured, the agent must be properly started in the password manager.