diff --git a/web/app/servers/[id]/console/page.tsx b/web/app/servers/[id]/console/page.tsx index 6b8c5be..d261f95 100644 --- a/web/app/servers/[id]/console/page.tsx +++ b/web/app/servers/[id]/console/page.tsx @@ -85,10 +85,11 @@ export default function ServerConsolePage() { const { token, ws_path } = await api.connectConsole(body); const wsProto = location.protocol === "https:" ? "wss" : "ws"; - const wsUrl = `${wsProto}://${location.host}${ws_path}?token=${encodeURIComponent(token)}`; + const wsUrl = `${wsProto}://${location.host}${ws_path}`; + const connectData = `token=${encodeURIComponent(token)}`; if (containerRef.current) { - const conn = openConsole(containerRef.current, wsUrl); + const conn = openConsole(containerRef.current, wsUrl, connectData); connectionRef.current = conn; setConnected(true); } diff --git a/web/lib/guacConsole.ts b/web/lib/guacConsole.ts index fee85fa..b01b69d 100644 --- a/web/lib/guacConsole.ts +++ b/web/lib/guacConsole.ts @@ -2,14 +2,16 @@ // The library attaches a global `Guacamole` object when loaded. declare const Guacamole: any; -export function openConsole(container: HTMLElement, wsUrl: string): { disconnect: () => void } { +export function openConsole(container: HTMLElement, wsUrl: string, connectData = ""): { disconnect: () => void } { + // Guacamole's WebSocketTunnel builds the socket URL as `wsUrl + "?" + data`, + // so wsUrl must NOT already contain a query string — pass params via connectData. const tunnel = new Guacamole.WebSocketTunnel(wsUrl); const client = new Guacamole.Client(tunnel); container.innerHTML = ""; container.appendChild(client.getDisplay().getElement()); - client.connect(""); + client.connect(connectData); // Wire keyboard + mouse. const mouse = new Guacamole.Mouse(client.getDisplay().getElement());