| author | |
| committer | |
| log | 69e5ad88462f9f58dacaee9ca926dea8a658378b |
| tree | 714b59c34d5cc1c17c3f7be4ced2cb1835dbff74 |
| parent | a9cd94eb935fed8e73b0d88e599c27048f2939c3 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Simone <185146821+Lucenx9@users.noreply.github.com>2 files changed, 24 insertions(+), 2 deletions(-)
apps/web/src/environments/primary/bootstrap.test.ts+18| ... | @@ -155,6 +155,24 @@ describe("environmentBootstrap", () => { | ... | @@ -155,6 +155,24 @@ describe("environmentBootstrap", () => { |
| 155 | }); | 155 | }); |
| 156 | }); | 156 | }); |
| 157 | 157 | ||
| 158 | it("keeps an uppercase wss scheme secure when deriving the http url", () => { | ||
| 159 | vi.stubEnv("VITE_WS_URL", "WSS://remote.example.com"); | ||
| 160 | |||
| 161 | expect(readPrimaryEnvironmentTarget().target).toEqual({ | ||
| 162 | httpBaseUrl: "https://remote.example.com/", | ||
| 163 | wsBaseUrl: "wss://remote.example.com/", | ||
| 164 | }); | ||
| 165 | }); | ||
| 166 | |||
| 167 | it("keeps an uppercase https scheme secure when deriving the websocket url", () => { | ||
| 168 | vi.stubEnv("VITE_HTTP_URL", "HTTPS://remote.example.com"); | ||
| 169 | |||
| 170 | expect(readPrimaryEnvironmentTarget().target).toEqual({ | ||
| 171 | httpBaseUrl: "https://remote.example.com/", | ||
| 172 | wsBaseUrl: "wss://remote.example.com/", | ||
| 173 | }); | ||
| 174 | }); | ||
| 175 | |||
| 158 | it("uses the current origin as the descriptor base for local dev environments", async () => { | 176 | it("uses the current origin as the descriptor base for local dev environments", async () => { |
| 159 | installTestBrowser("http://localhost:5735/"); | 177 | installTestBrowser("http://localhost:5735/"); |
| 160 | await installDescriptorApi(); | 178 | await installDescriptorApi(); |
apps/web/src/environments/primary/target.ts+6-2| ... | @@ -189,14 +189,18 @@ function resolveConfiguredPrimaryTarget(): PrimaryEnvironmentTarget | null { | ... | @@ -189,14 +189,18 @@ function resolveConfiguredPrimaryTarget(): PrimaryEnvironmentTarget | null { |
| 189 | return null; | 189 | return null; |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | // Scheme checks run on the raw configured string, while the URL parser | ||
| 193 | // folds schemes to lowercase ("WSS://host" parses fine). Without the | ||
| 194 | // case folding an uppercase scheme would be classified as plaintext and | ||
| 195 | // swapped to http/ws, silently downgrading TLS. | ||
| 192 | const resolvedHttpBaseUrl = | 196 | const resolvedHttpBaseUrl = |
| 193 | configuredHttpBaseUrl ?? | 197 | configuredHttpBaseUrl ?? |
| 194 | (configuredWsBaseUrl?.startsWith("wss:") | 198 | (configuredWsBaseUrl?.toLowerCase().startsWith("wss:") |
| 195 | ? swapBaseUrlProtocol(configuredWsBaseUrl, "https:", "websocket-base-url") | 199 | ? swapBaseUrlProtocol(configuredWsBaseUrl, "https:", "websocket-base-url") |
| 196 | : swapBaseUrlProtocol(configuredWsBaseUrl!, "http:", "websocket-base-url")); | 200 | : swapBaseUrlProtocol(configuredWsBaseUrl!, "http:", "websocket-base-url")); |
| 197 | const resolvedWsBaseUrl = | 201 | const resolvedWsBaseUrl = |
| 198 | configuredWsBaseUrl ?? | 202 | configuredWsBaseUrl ?? |
| 199 | (configuredHttpBaseUrl?.startsWith("https:") | 203 | (configuredHttpBaseUrl?.toLowerCase().startsWith("https:") |
| 200 | ? swapBaseUrlProtocol(configuredHttpBaseUrl, "wss:", "http-base-url") | 204 | ? swapBaseUrlProtocol(configuredHttpBaseUrl, "wss:", "http-base-url") |
| 201 | : swapBaseUrlProtocol(configuredHttpBaseUrl!, "ws:", "http-base-url")); | 205 | : swapBaseUrlProtocol(configuredHttpBaseUrl!, "ws:", "http-base-url")); |
| 202 | 206 |