diff --git a/frontend/index.html b/frontend/index.html index b2faf53..608c1ec 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -11,6 +11,7 @@ ` diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 48bf50e..e13e454 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,6 +1,6 @@ import { useCallback, useEffect, useReducer, useState } from "react"; import { Navbar, Form, Offcanvas, Container } from "react-bootstrap"; -import { authority, socket } from "./socket"; +import { authority, socket, forwardedProto } from "./socket"; import "./App.css"; import { Notifications, @@ -68,12 +68,12 @@ const App = () => { useEffect(() => { // Allow the user to add a custom css file - fetch(`http://${authority}/custom.css`, { credentials: "include" }) + fetch(`${forwardedProto}://${authority}/custom.css`, { credentials: "include" }) .then((response) => { if (response.ok) { // If the file exists, create a link element for the custom CSS const link = document.createElement("link"); - link.href = `http://${authority}/custom.css`; + link.href = `${forwardedProto}://${authority}/custom.css`; link.type = "text/css"; link.rel = "stylesheet"; document.head.appendChild(link); @@ -83,7 +83,9 @@ const App = () => { socket.on("connect", () => { // Fetch data from the API when the client connects - fetch(`http://${authority}/service-properties`, { credentials: "include" }) + fetch(`${forwardedProto}://${authority}/service-properties`, { + credentials: "include", + }) .then((response) => response.json()) .then((data: State) => { dispatch({ type: "SET_DATA", data }); @@ -91,7 +93,7 @@ const App = () => { document.title = data.name; // Setting browser tab title }); - fetch(`http://${authority}/web-settings`, { credentials: "include" }) + fetch(`${forwardedProto}://${authority}/web-settings`, { credentials: "include" }) .then((response) => response.json()) .then((data: Record) => setWebSettings(data)); setConnectionStatus("connected"); diff --git a/frontend/src/socket.ts b/frontend/src/socket.ts index f0d6544..71d3402 100644 --- a/frontend/src/socket.ts +++ b/frontend/src/socket.ts @@ -10,10 +10,16 @@ const port = process.env.NODE_ENV === "development" ? 8001 : window.location.por export const forwardedPrefix: string = (window as any) /* eslint-disable-line @typescript-eslint/no-explicit-any */ .__FORWARDED_PREFIX__ || ""; +// Get the forwarded protocol type from the global variable +export const forwardedProto: string = + (window as any) /* eslint-disable-line @typescript-eslint/no-explicit-any */ + .__FORWARDED_PROTO__ || "http"; export const authority = `${hostname}:${port}${forwardedPrefix}`; -const URL = `ws://${hostname}:${port}/`; +const wsProto = forwardedProto === "http" ? "ws" : "wss"; + +const URL = `${wsProto}://${hostname}:${port}/`; console.debug("Websocket: ", URL); export const socket = io(URL, { path: `${forwardedPrefix}/ws/socket.io`, diff --git a/src/pydase/server/web_server/web_server.py b/src/pydase/server/web_server/web_server.py index 3e3b75b..b886f1c 100644 --- a/src/pydase/server/web_server/web_server.py +++ b/src/pydase/server/web_server/web_server.py @@ -104,6 +104,21 @@ class WebServer: async def index( request: aiohttp.web.Request, ) -> aiohttp.web.Response | aiohttp.web.FileResponse: + forwarded_proto = request.headers["X-Forwarded-Proto"] + escaped_proto = html.escape(forwarded_proto) + + # Read the index.html file + index_file_path = self.frontend_src / "index.html" + + async with await anyio.open_file(index_file_path) as f: + html_content = await f.read() + + # Inject the escaped forwarded protocol into the HTML + modified_html = html_content.replace( + 'window.__FORWARDED_PROTO__ = "";', + f'window.__FORWARDED_PROTO__ = "{escaped_proto}";', + ) + # Read the X-Forwarded-Prefix header from the request forwarded_prefix = request.headers.get("X-Forwarded-Prefix", "") @@ -111,14 +126,8 @@ class WebServer: # Escape the forwarded prefix to prevent XSS escaped_prefix = html.escape(forwarded_prefix) - # Read the index.html file - index_file_path = self.frontend_src / "index.html" - - async with await anyio.open_file(index_file_path) as f: - html_content = await f.read() - # Inject the escaped forwarded prefix into the HTML - modified_html = html_content.replace( + modified_html = modified_html.replace( 'window.__FORWARDED_PREFIX__ = "";', f'window.__FORWARDED_PREFIX__ = "{escaped_prefix}";', )