Allow self-hosted relays to opt into wss:// (#767)
* Add relay TLS schema fields * Wire relay TLS into websocket URLs * Propagate relay TLS from pairing offers * Expose relay TLS opt-in * Mark relay TLS fallback for removal * Preserve explicit relay TLS false * Align relay TLS defaults outside config loader
This commit is contained in:
@@ -77,4 +77,23 @@ describe("local daemon launch supervision", () => {
|
||||
expectSupervisorLaunch(argv);
|
||||
expect(argv).toContain("--no-mcp");
|
||||
});
|
||||
|
||||
test("relay TLS flag is passed to the supervised daemon", async () => {
|
||||
mocks.spawnSync.mockReturnValue({ status: 0, error: undefined });
|
||||
|
||||
const { startLocalDaemonForeground } = await import("./local-daemon.js");
|
||||
const status = startLocalDaemonForeground({
|
||||
home: "/tmp/paseo-test",
|
||||
relayUseTls: true,
|
||||
});
|
||||
|
||||
expect(status).toBe(0);
|
||||
const [, argv, options] = mocks.spawnSync.mock.calls[0] as [
|
||||
string,
|
||||
string[],
|
||||
{ env?: NodeJS.ProcessEnv },
|
||||
];
|
||||
expect(argv).toContain("--relay-use-tls");
|
||||
expect(options.env?.PASEO_RELAY_USE_TLS).toBe("true");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface DaemonStartOptions {
|
||||
home?: string;
|
||||
foreground?: boolean;
|
||||
relay?: boolean;
|
||||
relayUseTls?: boolean;
|
||||
mcp?: boolean;
|
||||
injectMcp?: boolean;
|
||||
hostnames?: string;
|
||||
@@ -28,6 +29,9 @@ export interface LocalDaemonPidInfo {
|
||||
export interface LocalDaemonState {
|
||||
home: string;
|
||||
listen: string;
|
||||
relayEnabled: boolean;
|
||||
relayEndpoint: string;
|
||||
relayUseTls: boolean;
|
||||
logPath: string;
|
||||
pidPath: string;
|
||||
pidInfo: LocalDaemonPidInfo | null;
|
||||
@@ -93,6 +97,9 @@ function buildRunnerArgs(options: DaemonStartOptions): string[] {
|
||||
if (options.relay === false) {
|
||||
args.push("--no-relay");
|
||||
}
|
||||
if (options.relayUseTls === true) {
|
||||
args.push("--relay-use-tls");
|
||||
}
|
||||
|
||||
if (options.mcp === false) {
|
||||
args.push("--no-mcp");
|
||||
@@ -117,6 +124,9 @@ function buildChildEnv(options: DaemonStartOptions): NodeJS.ProcessEnv {
|
||||
if (options.hostnames) {
|
||||
childEnv.PASEO_HOSTNAMES = options.hostnames;
|
||||
}
|
||||
if (options.relayUseTls === true) {
|
||||
childEnv.PASEO_RELAY_USE_TLS = "true";
|
||||
}
|
||||
return childEnv;
|
||||
}
|
||||
|
||||
@@ -353,6 +363,9 @@ export function resolveLocalDaemonState(options: { home?: string } = {}): LocalD
|
||||
return {
|
||||
home,
|
||||
listen,
|
||||
relayEnabled: config.relayEnabled ?? true,
|
||||
relayEndpoint: config.relayPublicEndpoint ?? config.relayEndpoint ?? "relay.paseo.sh:443",
|
||||
relayUseTls: config.relayUseTls ?? false,
|
||||
logPath,
|
||||
pidPath,
|
||||
pidInfo,
|
||||
|
||||
@@ -28,6 +28,7 @@ export async function runPairCommand(options: PairOptions): Promise<void> {
|
||||
relayEnabled: config.relayEnabled,
|
||||
relayEndpoint: config.relayEndpoint,
|
||||
relayPublicEndpoint: config.relayPublicEndpoint,
|
||||
relayUseTls: config.relayUseTls,
|
||||
appBaseUrl: config.appBaseUrl,
|
||||
includeQr: true,
|
||||
});
|
||||
|
||||
@@ -21,6 +21,7 @@ export function startCommand(): Command {
|
||||
.option("--home <path>", "Paseo home directory (default: ~/.paseo)")
|
||||
.option("--foreground", "Run in foreground (don't daemonize)")
|
||||
.option("--no-relay", "Disable relay connection")
|
||||
.option("--relay-use-tls", "Use wss:// for the relay connection and pairing offers")
|
||||
.option("--no-mcp", "Disable the Agent MCP HTTP endpoint")
|
||||
.option("--no-inject-mcp", "Disable auto-injecting the Paseo MCP into created agents")
|
||||
.option(
|
||||
|
||||
@@ -18,6 +18,7 @@ interface DaemonStatus {
|
||||
connectedDaemon: "reachable" | "unreachable" | "not_probed";
|
||||
home: string;
|
||||
listen: string;
|
||||
relay: string;
|
||||
hostname: string | null;
|
||||
pid: number | null;
|
||||
startedAt: string | null;
|
||||
@@ -117,6 +118,7 @@ function toStatusRows(status: DaemonStatus): StatusRow[] {
|
||||
{ key: "Connected Daemon", value: status.connectedDaemon },
|
||||
{ key: "Home", value: status.home },
|
||||
{ key: "Listen", value: status.listen },
|
||||
{ key: "Relay", value: status.relay },
|
||||
{ key: "Hostname", value: status.hostname ?? "-" },
|
||||
{ key: "PID", value: status.pid === null ? "-" : String(status.pid) },
|
||||
{ key: "Started", value: status.startedAt ?? "-" },
|
||||
@@ -312,6 +314,12 @@ async function resolveDaemonNodeLabel(
|
||||
return fromPid.nodePath ?? `unknown (${fromPid.error ?? "could not resolve from PID"})`;
|
||||
}
|
||||
|
||||
function formatRelayStatus(state: ReturnType<typeof resolveLocalDaemonState>): string {
|
||||
if (!state.relayEnabled) return "disabled";
|
||||
const scheme = state.relayUseTls ? "wss" : "ws";
|
||||
return `${scheme}://${state.relayEndpoint}`;
|
||||
}
|
||||
|
||||
export type StatusResult = ListResult<StatusRow>;
|
||||
|
||||
export async function runStatusCommand(
|
||||
@@ -370,6 +378,7 @@ export async function runStatusCommand(
|
||||
connectedDaemon,
|
||||
home: state.home,
|
||||
listen: state.listen,
|
||||
relay: formatRelayStatus(state),
|
||||
hostname: state.pidInfo?.hostname ?? null,
|
||||
pid: state.pidInfo?.pid ?? null,
|
||||
startedAt: state.pidInfo?.startedAt ?? null,
|
||||
|
||||
@@ -491,6 +491,7 @@ export async function runOnboard(options: OnboardOptions): Promise<void> {
|
||||
relayEnabled: config.relayEnabled,
|
||||
relayEndpoint: config.relayEndpoint,
|
||||
relayPublicEndpoint: config.relayPublicEndpoint,
|
||||
relayUseTls: config.relayUseTls,
|
||||
appBaseUrl: config.appBaseUrl,
|
||||
includeQr: true,
|
||||
});
|
||||
|
||||
@@ -286,7 +286,7 @@ async function connectViaRelayOffer(
|
||||
endpoint: offer.relay.endpoint,
|
||||
serverId: offer.serverId,
|
||||
role: "client",
|
||||
useTls: shouldUseTlsForDefaultHostedRelay(offer.relay.endpoint),
|
||||
useTls: offer.relay.useTls ?? shouldUseTlsForDefaultHostedRelay(offer.relay.endpoint),
|
||||
});
|
||||
|
||||
const client = new DaemonClient({
|
||||
|
||||
Reference in New Issue
Block a user