From 24bdd3c8adb7b9ecd3adb1f600d84066901942a3 Mon Sep 17 00:00:00 2001 From: Zitao Xiong Date: Wed, 6 May 2026 07:56:32 -0400 Subject: [PATCH] fix(relay): use TLS for any port-443 relay endpoint (#774) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(relay): use TLS for any port-443 relay endpoint `shouldUseTlsForDefaultHostedRelay` only returned true for `relay.paseo.sh:443`. Self-hosted relays on port 443 connected via `ws://` instead of `wss://`, causing HTTP 400 from the TLS server. Port-based detection: port 443 → wss, everything else → ws. * Test port-based hosted relay TLS detection Cover the new behavior: any port-443 endpoint (hosted Paseo or self-hosted) and IPv6 hosts return true, non-443 ports and malformed input return false. --------- Co-authored-by: Mohamed Boudra --- .../src/shared/daemon-endpoints.test.ts | 23 +++++++++++++++++++ .../server/src/shared/daemon-endpoints.ts | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/server/src/shared/daemon-endpoints.test.ts b/packages/server/src/shared/daemon-endpoints.test.ts index 34522ff49..7f131eec0 100644 --- a/packages/server/src/shared/daemon-endpoints.test.ts +++ b/packages/server/src/shared/daemon-endpoints.test.ts @@ -9,6 +9,7 @@ import { parseConnectionUri, serializeConnectionUri, serializeConnectionUriForStorage, + shouldUseTlsForDefaultHostedRelay, } from "./daemon-endpoints.js"; describe("connection URI parsing", () => { @@ -188,3 +189,25 @@ describe("relay websocket URLs", () => { expect(extractHostPortFromWebSocketUrl(wsUrl)).toBe("[::1]:443"); }); }); + +describe("shouldUseTlsForDefaultHostedRelay", () => { + test("returns true for the hosted Paseo relay on port 443", () => { + expect(shouldUseTlsForDefaultHostedRelay("relay.paseo.sh:443")).toBe(true); + }); + + test("returns true for any self-hosted relay on port 443", () => { + expect(shouldUseTlsForDefaultHostedRelay("relay.example.com:443")).toBe(true); + }); + + test("returns true for an IPv6 relay on port 443", () => { + expect(shouldUseTlsForDefaultHostedRelay("[::1]:443")).toBe(true); + }); + + test("returns false for a relay on a non-443 port", () => { + expect(shouldUseTlsForDefaultHostedRelay("relay.example.com:8080")).toBe(false); + }); + + test("returns false for malformed endpoints", () => { + expect(shouldUseTlsForDefaultHostedRelay("not-an-endpoint")).toBe(false); + }); +}); diff --git a/packages/server/src/shared/daemon-endpoints.ts b/packages/server/src/shared/daemon-endpoints.ts index da98944a5..299abcab3 100644 --- a/packages/server/src/shared/daemon-endpoints.ts +++ b/packages/server/src/shared/daemon-endpoints.ts @@ -204,7 +204,8 @@ export function buildRelayWebSocketUrl(params: { */ export function shouldUseTlsForDefaultHostedRelay(endpoint: string): boolean { try { - return normalizeHostPort(endpoint) === DEFAULT_RELAY_ENDPOINT; + const { port } = parseHostPort(endpoint); + return port === 443; } catch { return false; }