Skip to content

bug(frontend): mixed-content WebSocket — LiveEventService connects to ws:// from HTTPS page, browser blocks it #6642

Closed

Description

@mrveiss

Summary

Page is served over HTTPS (`https://172.16.168.20\`), but the LiveEventService WebSocket tries to connect to `ws://...` (insecure). Chrome blocks mixed-content WS, the connection times out, and the user sees an endless loading spinner.

```
Mixed Content: The page at 'https://172.16.168.20/...' was loaded over HTTPS,
but attempted to connect to the insecure WebSocket endpoint
'ws://172.16.168.20/api/ws/live'. This endpoint should be available via WSS.

[ERROR] [LiveEventService] Connection timeout
[ERROR] [LiveEventService] Initial LiveEventService connection failed
[WARN] [UnifiedLoadingView] Loading timed out after 15000ms
```

Root cause

`config/ssot-config.ts:424` reads the protocol from a build-time env var:
```ts
const httpProtocol = getEnv('VITE_HTTP_PROTOCOL', 'http');
```

`config/ssot-config.ts:456-461` then drives the WebSocket scheme off this:
```ts
get websocketUrl(): string {
if (httpProtocol === 'https') {
return `wss://${vm.main}/api/ws`;
}
return `ws://${vm.main}:${port.backend}/api/ws`;
}
```

`VITE_HTTP_PROTOCOL` was not set at build time on this deploy, so it defaulted to `http` and `websocketUrl` returned `ws://...` — even though the user loaded the page over HTTPS.

The same module already gets this right elsewhere — `getBackendWsUrl()` detects the protocol at runtime from `window.location.protocol`. The `websocketUrl` getter should use the same pattern.

Fix

Replace the build-time env-var check in the `websocketUrl` getter with a runtime check against `window.location.protocol`. Same machinery as the existing `getBackendWsUrl` helper. When HTTPS, use `wss://{host}/api/ws` (no port — nginx terminates TLS on 443).

This is robust: works for both Vite dev server and any production deploy without needing the env var to be set correctly.

Acceptance Criteria

  • On HTTPS-served frontend: `config.websocketUrl` returns `wss://{host}/api/ws`
  • On HTTP dev server: `config.websocketUrl` returns `ws://{vm.main}:{port.backend}/api/ws` (current behaviour preserved)
  • LiveEventService connects without mixed-content browser block
  • No regression for existing `getBackendWsUrl` callers (different helper)

Related

Out of scope (file separately if relevant)

The console also showed: `Service Worker registration failed: SecurityError: SSL certificate error` — expected for self-signed certs in dev, not critical, but worth a follow-up to either skip SW registration on HTTPS-with-self-signed or fix the cert chain.

Activity

  1. mrveiss commented on Apr 30, 2026

    @mrveiss
    OwnerAuthor

    ✅ Merged via PR #6643 (commit 0430b0de4).

    config/ssot-config.ts:websocketUrl now uses window.location.protocol at runtime instead of the build-time env var. Same pattern as getBackendWsUrl. ws:// is now only used on the HTTP dev server.

    Pending Ansible deploy + browser verification: console should no longer show the Mixed Content warnings or LiveEventService Connection timeout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions