From 32fbcdc4a86e74955d1c58573a7302ac3ab77e08 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Mon, 19 Oct 2026 08:37:15 +0200 Subject: [PATCH] fix(hosts): validate safe targets and verify encrypted relay routes --- docs/connected-hosts.md | 1 + .../e2e/support/helpers/connected-hosts.ts | 3 + packages/app/src/connected-hosts/index.tsx | 26 ++- packages/cli/src/utils/client.ts | 6 +- packages/cli/src/utils/daemon-target.test.ts | 18 +- packages/cli/src/utils/daemon-target.ts | 10 +- packages/protocol/src/host-target.test.ts | 42 +++- packages/protocol/src/host-target.ts | 24 +- packages/protocol/src/messages.ts | 51 ++-- packages/server/package.json | 2 +- .../server/connected-hosts/hosts.e2e.test.ts | 27 +++ .../daemon-e2e/relay-transport.e2e.test.ts | 219 +++++++++++++++++- packages/server/src/server/session.ts | 10 +- .../websocket-server.relay-reconnect.test.ts | 28 ++- .../server/src/server/websocket-server.ts | 2 +- 15 files changed, 412 insertions(+), 57 deletions(-) diff --git a/docs/connected-hosts.md b/docs/connected-hosts.md index f30e81dca4..b4b99f6616 100644 --- a/docs/connected-hosts.md +++ b/docs/connected-hosts.md @@ -25,6 +25,7 @@ permissions closes existing routes. A routed API cannot select a second hop. A producer that registers a host through a routed API is qualified on B as `route:::`, with each component percent-encoded. This namespace belongs to the authenticated link principal. An ordinary direct B consumer does not become that producer by supplying a source key. +The optional `server_info.sourceId` reports this producer identity for source-owner controls; it does not describe the authenticated admission principal. Trusted server plugins retain the authority of their runtime; they are not sandboxed by this feature. ## Connections and recovery diff --git a/packages/app/e2e/support/helpers/connected-hosts.ts b/packages/app/e2e/support/helpers/connected-hosts.ts index d57a5a0498..70c288e4c4 100644 --- a/packages/app/e2e/support/helpers/connected-hosts.ts +++ b/packages/app/e2e/support/helpers/connected-hosts.ts @@ -28,6 +28,9 @@ export async function correctConnection(page: Page, value: string) { await saveConnectedHost(page); } export async function inspectConnectedHost(page: Page, label: string) { + await expect( + page.getByText(/^(connecting|offline|error|online|disabled) · (Enabled|Disabled) · User$/), + ).toBeVisible(); await page.getByRole("button", { name: `Details for ${label}`, exact: true }).click(); await expect(page.getByText("Connected host details", { exact: true })).toBeVisible(); } diff --git a/packages/app/src/connected-hosts/index.tsx b/packages/app/src/connected-hosts/index.tsx index 2dbdff5e8d..e1966f1508 100644 --- a/packages/app/src/connected-hosts/index.tsx +++ b/packages/app/src/connected-hosts/index.tsx @@ -85,7 +85,7 @@ function ConnectedHosts({ client, connected }: { client: DaemonClient; connected model={model} canManage={canManage} manageSources={info?.permissions?.includes("access.manage") === true} - sourceId={info?.principalId} + sourceId={info?.sourceId} pending={state.pending !== null} /> ) : null} @@ -151,7 +151,7 @@ function HostRow({ return (