authorgravatar for technocratix902@gmail.comKriday Dave <technocratix902@gmail.com> 2026-07-17 22:29:42+05:30
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-07-17 18:59:42+02:00
logc49d424e3aa2f5993e756a2b8f19b9b5da6f0cc5
tree52c206632def650e4e07d3c34c7d4e6a17be5c2c
parent4804a9824fa86f4b8974f449194619c955d03624
signature Signed by PGP key B5690EEEBB952194

Normalize protocol-relative remote host input as https (#3971)


2 files changed, 68 insertions(+), 4 deletions(-)

packages/shared/src/remote.test.ts+64
......@@ -59,6 +59,70 @@ describe("remote", () => {
5959 });
6060 });
6161
62 it("treats a protocol-relative host as https", () => {
63 expect(
64 resolveRemotePairingTarget({
65 host: "//remote.example.com",
66 pairingCode: "pairing-token",
67 }),
68 ).toEqual({
69 credential: "pairing-token",
70 httpBaseUrl: "https://remote.example.com/",
71 wsBaseUrl: "wss://remote.example.com/",
72 });
73 });
74
75 it("preserves the port when normalizing a protocol-relative host", () => {
76 expect(
77 resolveRemotePairingTarget({
78 host: "//remote.example.com:3000",
79 pairingCode: "pairing-token",
80 }),
81 ).toEqual({
82 credential: "pairing-token",
83 httpBaseUrl: "https://remote.example.com:3000/",
84 wsBaseUrl: "wss://remote.example.com:3000/",
85 });
86 });
87
88 it("normalizes a protocol-relative host from a hosted pairing link", () => {
89 expect(
90 resolveRemotePairingTarget({
91 pairingUrl: "https://app.t3.codes/pair?host=%2F%2Fremote.example.com#token=pairing-token",
92 }),
93 ).toEqual({
94 credential: "pairing-token",
95 httpBaseUrl: "https://remote.example.com/",
96 wsBaseUrl: "wss://remote.example.com/",
97 });
98 });
99
100 it("collapses extra leading slashes instead of producing an empty host", () => {
101 expect(
102 resolveRemotePairingTarget({
103 host: "///example.com",
104 pairingCode: "pairing-token",
105 }),
106 ).toEqual({
107 credential: "pairing-token",
108 httpBaseUrl: "https://example.com/",
109 wsBaseUrl: "wss://example.com/",
110 });
111 });
112
113 it("does not double-prepend https when the host already carries a scheme", () => {
114 expect(
115 resolveRemotePairingTarget({
116 host: "//https://example.com",
117 pairingCode: "pairing-token",
118 }),
119 ).toEqual({
120 credential: "pairing-token",
121 httpBaseUrl: "https://example.com/",
122 wsBaseUrl: "wss://example.com/",
123 });
124 });
125
62126 it("preserves host ports when normalizing a bare host input", () => {
63127 expect(
64128 resolveRemotePairingTarget({
packages/shared/src/remote.ts+4-4
......@@ -81,10 +81,10 @@ const normalizeRemoteBaseUrl = (
8181 throw new RemoteBackendUrlMissingError();
8282 }
8383
84 const normalizedInput =
85 /^[a-zA-Z][a-zA-Z\d+-]*:\/\//.test(trimmed) || trimmed.startsWith("//")
86 ? trimmed
87 : `https://${trimmed}`;
84 const withoutLeadingSlashes = trimmed.replace(/^\/+/, "");
85 const normalizedInput = /^[a-zA-Z][a-zA-Z\d+-]*:\/\//.test(withoutLeadingSlashes)
86 ? withoutLeadingSlashes
87 : `https://${withoutLeadingSlashes}`;
8888 let url: URL;
8989 try {
9090 url = new URL(normalizedInput);