adds support for X-Forwarded-Proto

This commit is contained in:
Mose Müller 2024-11-21 14:30:33 +01:00
parent 0e9ec7a66a
commit 5827cda316
4 changed files with 31 additions and 13 deletions

View File

@ -11,6 +11,7 @@
<script>
// this will be set by the python backend if the service is behind a proxy which strips a prefix. The frontend can use this to build the paths to the resources.
window.__FORWARDED_PREFIX__ = "";
window.__FORWARDED_PROTO__ = "";
</script>`
<body>

View File

@ -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<string, WebSetting>) => setWebSettings(data));
setConnectionStatus("connected");

View File

@ -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`,

View File

@ -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}";',
)