mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-09-23 08:55:41 +00:00
Rework
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
package io.xpipe.app.ext;
|
||||
|
||||
import io.xpipe.app.browser.BrowserAbstractSessionModel;
|
||||
import io.xpipe.app.browser.BrowserFullSessionModel;
|
||||
import io.xpipe.app.browser.BrowserStoreSessionTab;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.vnc.VncBaseStore;
|
||||
import io.xpipe.core.process.*;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
|
||||
@@ -16,6 +20,7 @@ public abstract class ProcessControlProvider {
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
}
|
||||
public abstract BrowserStoreSessionTab<?> createVncSession(BrowserFullSessionModel model, DataStoreEntryRef<VncBaseStore> ref);
|
||||
|
||||
public static ProcessControlProvider get() {
|
||||
return INSTANCE;
|
||||
|
||||
@@ -17,6 +17,9 @@ import io.xpipe.app.update.AppDistributionType;
|
||||
import io.xpipe.app.util.OptionsBuilder;
|
||||
import io.xpipe.app.util.PlatformState;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.vnc.ExternalVncClient;
|
||||
import io.xpipe.app.vnc.InternalVncClient;
|
||||
import io.xpipe.app.vnc.VncCategory;
|
||||
import io.xpipe.core.process.ShellScript;
|
||||
|
||||
import javafx.beans.property.*;
|
||||
@@ -101,6 +104,11 @@ public class AppPrefs {
|
||||
mapVaultShared(new SimpleObjectProperty<>(false), "alwaysConfirmElevation", Boolean.class, false);
|
||||
public final BooleanProperty dontCachePasswords =
|
||||
mapVaultShared(new SimpleBooleanProperty(false), "dontCachePasswords", Boolean.class, false);
|
||||
public final Property<ExternalVncClient> vncClient = map(Mapping.builder()
|
||||
.property(new SimpleObjectProperty<>(InternalVncClient.builder().build()))
|
||||
.key("vncClient")
|
||||
.valueClass(ExternalVncClient.class)
|
||||
.build());
|
||||
final Property<PasswordManager> passwordManager = map(Mapping.builder()
|
||||
.property(new SimpleObjectProperty<>())
|
||||
.key("passwordManager")
|
||||
@@ -141,8 +149,6 @@ public class AppPrefs {
|
||||
return terminalAlwaysPauseOnExit;
|
||||
}
|
||||
|
||||
public final StringProperty passwordManagerCommand =
|
||||
mapLocal(new SimpleStringProperty(null), "passwordManagerCommand", String.class, false);
|
||||
final ObjectProperty<StartupBehaviour> startupBehaviour = mapLocal(
|
||||
new SimpleObjectProperty<>(StartupBehaviour.GUI), "startupBehaviour", StartupBehaviour.class, true);
|
||||
public final BooleanProperty enableGitStorage =
|
||||
@@ -305,6 +311,7 @@ public class AppPrefs {
|
||||
new LoggingCategory(),
|
||||
new EditorCategory(),
|
||||
new RdpCategory(),
|
||||
new VncCategory(),
|
||||
new SshCategory(),
|
||||
new ConnectionHubCategory(),
|
||||
new FileBrowserCategory(),
|
||||
@@ -589,15 +596,6 @@ public class AppPrefs {
|
||||
var f = PlatformState.determineDefaultScalingFactor();
|
||||
uiScale.setValue(f.isPresent() ? f.getAsInt() : null);
|
||||
}
|
||||
|
||||
// Migrate legacy password manager
|
||||
if (passwordManagerCommand.get() != null
|
||||
&& !passwordManagerCommand.get().isBlank()
|
||||
&& passwordManager.getValue() == null) {
|
||||
passwordManager.setValue(PasswordManagerCommand.builder()
|
||||
.script(new ShellScript(passwordManagerCommand.get()))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSharedRemote() {
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.xpipe.app.storage.*;
|
||||
import io.xpipe.app.terminal.ExternalTerminalType;
|
||||
import io.xpipe.app.terminal.TerminalMultiplexer;
|
||||
import io.xpipe.app.terminal.TerminalPrompt;
|
||||
import io.xpipe.app.vnc.ExternalVncClient;
|
||||
import io.xpipe.core.util.InPlaceSecretValue;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
|
||||
@@ -47,6 +48,7 @@ public class AppJacksonModule extends SimpleModule {
|
||||
context.registerSubtypes(PasswordManager.getClasses());
|
||||
context.registerSubtypes(TerminalMultiplexer.getClasses());
|
||||
context.registerSubtypes(TerminalPrompt.getClasses());
|
||||
context.registerSubtypes(ExternalVncClient.getClasses());
|
||||
|
||||
context.addSerializers(_serializers);
|
||||
context.addDeserializers(_deserializers);
|
||||
|
||||
@@ -2,7 +2,10 @@ package io.xpipe.app.vnc;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import io.xpipe.app.pwman.*;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.util.SecretValue;
|
||||
import lombok.Value;
|
||||
|
||||
@@ -14,20 +17,8 @@ public interface ExternalVncClient {
|
||||
|
||||
static List<Class<?>> getClasses() {
|
||||
var l = new ArrayList<Class<?>>();
|
||||
l.add(OnePasswordManager.class);
|
||||
l.add(KeePassXcPasswordManager.class);
|
||||
l.add(BitwardenPasswordManager.class);
|
||||
l.add(DashlanePasswordManager.class);
|
||||
if (OsType.getLocal() != OsType.WINDOWS) {
|
||||
l.add(LastpassPasswordManager.class);
|
||||
l.add(EnpassPasswordManager.class);
|
||||
}
|
||||
l.add(KeeperPasswordManager.class);
|
||||
l.add(PsonoPasswordManager.class);
|
||||
if (OsType.getLocal() == OsType.WINDOWS) {
|
||||
l.add(WindowsCredentialManager.class);
|
||||
}
|
||||
l.add(PasswordManagerCommand.class);
|
||||
l.add(InternalVncClient.class);
|
||||
l.add(TightVncClient.class);
|
||||
return l;
|
||||
}
|
||||
|
||||
@@ -36,11 +27,10 @@ public interface ExternalVncClient {
|
||||
String title;
|
||||
String host;
|
||||
int port;
|
||||
SecretValue password;
|
||||
DataStoreEntryRef<VncBaseStore> entry;
|
||||
}
|
||||
|
||||
boolean isAvailable();
|
||||
|
||||
void launch(LaunchConfiguration configuration) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package io.xpipe.app.vnc;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.app.browser.BrowserFullSessionModel;
|
||||
import io.xpipe.app.browser.BrowserStoreSessionTab;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.prefs.ExternalApplicationType;
|
||||
import io.xpipe.app.util.LocalShell;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import lombok.Builder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
@Builder
|
||||
@Jacksonized
|
||||
@JsonTypeName("xpipe")
|
||||
public class InternalVncClient implements ExternalVncClient {
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void launch(LaunchConfiguration configuration) throws Exception {
|
||||
var open = BrowserFullSessionModel.DEFAULT.getSessionEntriesSnapshot().stream()
|
||||
.filter(browserSessionTab -> browserSessionTab instanceof BrowserStoreSessionTab<?> st
|
||||
&& st.getEntry().get().equals(configuration.getEntry().get()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (open != null) {
|
||||
AppLayoutModel.get().selectBrowser();
|
||||
BrowserFullSessionModel.DEFAULT.getSelectedEntry().setValue(open);
|
||||
return;
|
||||
}
|
||||
|
||||
BrowserFullSessionModel.DEFAULT.openSync(ProcessControlProvider.get().createVncSession(BrowserFullSessionModel.DEFAULT, configuration.getEntry()), null);
|
||||
AppLayoutModel.get().selectBrowser();
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,11 @@ public class TightVncClient implements ExternalApplicationType.WindowsType, Exte
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExecutable() {
|
||||
return "tvnviewer.exe";
|
||||
@@ -36,12 +41,7 @@ public class TightVncClient implements ExternalApplicationType.WindowsType, Exte
|
||||
|
||||
@Override
|
||||
public void launch(LaunchConfiguration configuration) throws Exception {
|
||||
var command = CommandBuilder.of().addFile(findExecutable()).add("-host").addLiteral(configuration.getHost()).add("-port").add("" + configuration.getPort());
|
||||
var command = CommandBuilder.of().addFile(findExecutable()).addQuoted(configuration.getHost() + "::" + configuration.getPort());
|
||||
LocalShell.getShell().command(command).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package io.xpipe.app.vnc;
|
||||
|
||||
import io.xpipe.app.util.SecretRetrievalStrategy;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface VncBaseStore extends DataStore {
|
||||
|
||||
String getEffectiveHost();
|
||||
|
||||
int getEffectivePort();
|
||||
|
||||
String getUser();
|
||||
|
||||
SecretRetrievalStrategy getPassword();
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package io.xpipe.app.vnc;
|
||||
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.base.ButtonComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.prefs.AppPrefsCategory;
|
||||
import io.xpipe.app.pwman.PasswordManager;
|
||||
import io.xpipe.app.util.*;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
public class VncCategory extends AppPrefsCategory {
|
||||
|
||||
@Override
|
||||
protected String getId() {
|
||||
return "vnc";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Comp<?> create() {
|
||||
var prefs = AppPrefs.get();
|
||||
var choiceBuilder = OptionsChoiceBuilder.builder()
|
||||
.property(prefs.vncClient)
|
||||
.subclasses(ExternalVncClient.getClasses())
|
||||
.allowNull(false)
|
||||
.transformer(entryComboBox -> {
|
||||
var docsLinkButton = new ButtonComp(
|
||||
AppI18n.observable("docs"), new FontIcon("mdi2h-help-circle-outline"), () -> {
|
||||
Hyperlinks.open(DocumentationLink.PASSWORD_MANAGER.getLink());
|
||||
});
|
||||
docsLinkButton.minWidth(Region.USE_PREF_SIZE);
|
||||
|
||||
var hbox = new HBox(entryComboBox, docsLinkButton.createRegion());
|
||||
HBox.setHgrow(entryComboBox, Priority.ALWAYS);
|
||||
hbox.setSpacing(10);
|
||||
hbox.setMaxWidth(getCompWidth());
|
||||
return hbox;
|
||||
})
|
||||
.build();
|
||||
prefs.vncClient.addListener((observable, oldValue, newValue) -> {
|
||||
int a = 0;
|
||||
});
|
||||
var choice = choiceBuilder.build().buildComp();
|
||||
return new OptionsBuilder()
|
||||
.addTitle("vncClient")
|
||||
.sub(new OptionsBuilder()
|
||||
.pref(prefs.vncClient)
|
||||
.addComp(choice)
|
||||
)
|
||||
.buildComp();
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,7 @@ open module io.xpipe.app {
|
||||
exports io.xpipe.app.icon;
|
||||
exports io.xpipe.app.pwman;
|
||||
exports io.xpipe.app.rdp;
|
||||
exports io.xpipe.app.vnc;
|
||||
|
||||
requires com.sun.jna;
|
||||
requires com.sun.jna.platform;
|
||||
|
||||
Reference in New Issue
Block a user