mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-21 15:10:23 +00:00
Various fixes
This commit is contained in:
parent
2d67443f22
commit
4f3f2bbfd2
16 changed files with 41 additions and 84 deletions
|
@ -51,7 +51,7 @@ dependencies {
|
|||
api files("$rootDir/gradle/gradle_scripts/markdowngenerator-1.3.1.1.jar")
|
||||
api files("$rootDir/gradle/gradle_scripts/vernacular-1.16.jar")
|
||||
api 'info.picocli:picocli:4.7.6'
|
||||
api ('org.kohsuke:github-api:1.321') {
|
||||
api ('org.kohsuke:github-api:1.322') {
|
||||
exclude group: 'org.apache.commons', module: 'commons-lang3'
|
||||
}
|
||||
api 'org.apache.commons:commons-lang3:3.14.0'
|
||||
|
|
|
@ -41,7 +41,7 @@ public class ListBoxViewComp<T> extends Comp<CompStructure<ScrollPane>> {
|
|||
Map<T, Region> cache = new IdentityHashMap<>();
|
||||
|
||||
VBox vbox = new VBox();
|
||||
vbox.getStyleClass().add("content");
|
||||
vbox.getStyleClass().add("list-box-content");
|
||||
vbox.setFocusTraversable(false);
|
||||
|
||||
refresh(vbox, shown, all, cache, false);
|
||||
|
|
|
@ -34,7 +34,7 @@ public class ListSelectorComp<T> extends SimpleComp {
|
|||
protected Region createSimple() {
|
||||
var vbox = new VBox();
|
||||
vbox.setSpacing(8);
|
||||
vbox.getStyleClass().add("content");
|
||||
vbox.getStyleClass().add("list-content");
|
||||
var cbs = new ArrayList<CheckBox>();
|
||||
for (var v : values) {
|
||||
var cb = new CheckBox(null);
|
||||
|
|
|
@ -151,7 +151,7 @@ public class StoreSectionComp extends Comp<CompStructure<VBox>> {
|
|||
topEntryList,
|
||||
Comp.separator().hide(expanded.not()),
|
||||
new HorizontalComp(List.of(content))
|
||||
.styleClass("content")
|
||||
.styleClass("children-content")
|
||||
.apply(struc -> struc.get().setFillHeight(true))
|
||||
.hide(Bindings.or(
|
||||
Bindings.not(section.getWrapper().getExpanded()),
|
||||
|
|
|
@ -46,6 +46,7 @@ public class AppExtensionManager {
|
|||
INSTANCE.determineExtensionDirectories();
|
||||
INSTANCE.loadBaseExtension();
|
||||
INSTANCE.loadAllExtensions();
|
||||
INSTANCE.loadUaccExtension();
|
||||
}
|
||||
|
||||
if (load) {
|
||||
|
@ -139,7 +140,7 @@ public class AppExtensionManager {
|
|||
}
|
||||
|
||||
private void loadAllExtensions() {
|
||||
for (var ext : List.of("jdbc", "proc", "uacc")) {
|
||||
for (var ext : List.of("jdbc", "proc")) {
|
||||
var extension = findAndParseExtension(ext, baseLayer)
|
||||
.orElseThrow(() -> ExtensionException.corrupt("Missing module " + ext));
|
||||
loadedExtensions.add(extension);
|
||||
|
@ -154,6 +155,21 @@ public class AppExtensionManager {
|
|||
.layer();
|
||||
}
|
||||
|
||||
|
||||
private void loadUaccExtension() {
|
||||
var extension = findAndParseExtension("uacc", extendedLayer)
|
||||
.orElseThrow(() -> ExtensionException.corrupt("Missing module uacc"));
|
||||
loadedExtensions.add(extension);
|
||||
leafModuleLayers.add(extension.getModule().getLayer());
|
||||
|
||||
var scl = ClassLoader.getSystemClassLoader();
|
||||
var cfs = leafModuleLayers.stream().map(ModuleLayer::configuration).toList();
|
||||
var finder = ModuleFinder.ofSystem();
|
||||
var cf = Configuration.resolve(finder, cfs, finder, List.of());
|
||||
extendedLayer = ModuleLayer.defineModulesWithOneLoader(cf, leafModuleLayers, scl)
|
||||
.layer();
|
||||
}
|
||||
|
||||
private Optional<Extension> findAndParseExtension(String name, ModuleLayer parent) {
|
||||
var inModulePath = ModuleLayer.boot().findModule("io.xpipe.ext." + name);
|
||||
if (inModulePath.isPresent()) {
|
||||
|
|
|
@ -106,6 +106,7 @@ public class UserReportComp extends SimpleComp {
|
|||
layout.setCenter(reportSection);
|
||||
layout.setBottom(buttons);
|
||||
layout.getStyleClass().add("error-report");
|
||||
layout.getStyleClass().add("background");
|
||||
layout.setPrefWidth(600);
|
||||
layout.setPrefHeight(550);
|
||||
return layout;
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
|
||||
public abstract class LicenseConnectionLimit {
|
||||
|
||||
private final int limit;
|
||||
private final LicensedFeature feature;
|
||||
|
||||
public LicenseConnectionLimit(int limit, LicensedFeature feature) {
|
||||
this.limit = limit;
|
||||
this.feature = feature;
|
||||
}
|
||||
|
||||
protected abstract boolean matches(DataStore store);
|
||||
|
||||
public void checkLimit() {
|
||||
if (feature.isSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var found = DataStorage.get().getStoreEntries().stream()
|
||||
.filter(entry -> entry.getValidity().isUsable() && matches(entry.getStore()))
|
||||
.toList();
|
||||
if (found.size() > limit) {
|
||||
throw new LicenseRequiredException(feature, limit);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,9 +26,5 @@ public interface LicensedFeature {
|
|||
|
||||
boolean isPreviewSupported();
|
||||
|
||||
default void throwIfUnsupported() throws LicenseRequiredException {
|
||||
if (!isSupported()) {
|
||||
throw new LicenseRequiredException(this);
|
||||
}
|
||||
}
|
||||
void throwIfUnsupported() throws LicenseRequiredException;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,8 @@ Prior to sending requests to the API, you first have to establish a new API sess
|
|||
In the response you will receive a session token that you can use to authenticate during this session.
|
||||
|
||||
This is done so that the daemon knows what kind of clients are connected and can manage individual capabilities for clients.
|
||||
If your client is running on the same system as the daemon, you can choose the local authentication method to avoid having to deal with API keys.
|
||||
If your client does not have file system access, e.g. if it is running remotely, then you have to use an API key.
|
||||
|
||||
Note that for development you can also turn off the required authentication in the XPipe settings menu, allowing you to send unauthenticated requests.
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
-fx-spacing: 0.3em;
|
||||
}
|
||||
|
||||
.error-report .attachments .attachment-list .content {
|
||||
.error-report .attachments .attachment-list .list-box-content {
|
||||
-fx-padding: 0.5em 1em;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@
|
|||
-fx-border-insets: 0px;
|
||||
}
|
||||
|
||||
.store-entry-section-comp > .content {
|
||||
.store-entry-section-comp > .children-content {
|
||||
-fx-padding: 5px 0 5px 25px;
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@
|
|||
-fx-background-radius: 0;
|
||||
}
|
||||
|
||||
.store-entry-section-comp .list-box-view-comp .content {
|
||||
.store-entry-section-comp .list-box-view-comp .list-box-content {
|
||||
-fx-spacing: 0.2em;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
.store-mini-list-comp > * > * > .children-content {
|
||||
-fx-spacing: 0.5em;
|
||||
}
|
||||
|
||||
.store-mini-list-comp:root {
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-color: transparent;
|
||||
|
@ -118,7 +114,7 @@
|
|||
-fx-border-color: -color-border-default;
|
||||
}
|
||||
|
||||
.store-section-mini-comp .list-box-view-comp .children-content {
|
||||
.store-section-mini-comp:root .list-box-view-comp .list-box-content {
|
||||
-fx-spacing: 0.4em;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,14 @@
|
|||
-fx-background-color: derive(-color-bg-default, -9%);
|
||||
}
|
||||
|
||||
.root:dark.background {
|
||||
-fx-background-color: derive(-color-bg-default, 1%);
|
||||
}
|
||||
|
||||
.root:light.background {
|
||||
-fx-background-color: derive(-color-bg-default, -9%);
|
||||
}
|
||||
|
||||
.root:seamless-frame.layout > .background {
|
||||
-fx-background-insets: 5 0 0 0;
|
||||
-fx-border-insets: 5 0 0 0;
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.xpipe.ext.base.service;
|
|||
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.HostHelper;
|
||||
import io.xpipe.app.util.LicenseProvider;
|
||||
import io.xpipe.app.util.Validators;
|
||||
import io.xpipe.core.store.*;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
|
@ -32,7 +33,7 @@ public abstract class AbstractServiceStore extends JacksonizedValue
|
|||
|
||||
@Override
|
||||
public NetworkTunnelSession newSession() throws Exception {
|
||||
ServiceLicenseCheck.check();
|
||||
LicenseProvider.get().getFeature("services").throwIfUnsupported();
|
||||
var l = localPort != null ? localPort : HostHelper.findRandomOpenPortOnAllLocalInterfaces();
|
||||
return getHost().getStore().sessionChain(l, remotePort);
|
||||
}
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
package io.xpipe.ext.base.service;
|
||||
|
||||
import io.xpipe.app.util.LicenseConnectionLimit;
|
||||
import io.xpipe.app.util.LicenseProvider;
|
||||
import io.xpipe.app.util.LicensedFeature;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
|
||||
public class ServiceLicenseCheck {
|
||||
|
||||
public static LicensedFeature getFeature() {
|
||||
return LicenseProvider.get().getFeature("services");
|
||||
}
|
||||
|
||||
public static void check() {
|
||||
if (getFeature().isSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var limit = getConnectionLimit();
|
||||
limit.checkLimit();
|
||||
}
|
||||
|
||||
public static LicenseConnectionLimit getConnectionLimit() {
|
||||
// We check before starting a new service
|
||||
return new LicenseConnectionLimit(0, getFeature()) {
|
||||
|
||||
@Override
|
||||
protected boolean matches(DataStore store) {
|
||||
return store instanceof AbstractServiceStore abstractServiceStore
|
||||
&& abstractServiceStore.requiresTunnel()
|
||||
&& abstractServiceStore.isSessionRunning();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -39,6 +39,8 @@ paths:
|
|||
In the response you will receive a session token that you can use to authenticate during this session.
|
||||
|
||||
This is done so that the daemon knows what kind of clients are connected and can manage individual capabilities for clients.
|
||||
If your client is running on the same system as the daemon, you can choose the local authentication method to avoid having to deal with API keys.
|
||||
If your client does not have file system access, e.g. if it is running remotely, then you have to use an API key.
|
||||
|
||||
Note that for development you can also turn off the required authentication in the XPipe settings menu, allowing you to send unauthenticated requests.
|
||||
operationId: handshake
|
||||
|
|
Loading…
Reference in a new issue