# psplayhosted - Caddy buendelt alles unter EINER HTTPS-Adresse.
#
# Statisch: alle Werte kommen als Umgebungsvariablen aus der .env
# (docker-compose.yml reicht sie an den Container durch, Caddy ersetzt
# {$NAME} beim Laden). Der Installer schreibt nur die .env.
#
# Warum HTTPS Pflicht ist: Browser geben Gamepad-API und WebHID nur in
# sicheren Kontexten frei, und ein gemeinsamer Ursprung fuer Panel und
# Stream laesst das Sitzungscookie fuer beides gelten.
#
# Wo und wie Caddy lauscht, legt WEB_MODE fest (caddy/site/<modus>.caddy):
#   direct  Port 80/443 dieses Servers, eigenes Zertifikat (Standard)
#   sni     wie direct, ein Reverse-Proxy davor reicht TLS nur durch
#   port    eigener HTTPS-Port (WEB_HTTPS_PORT), Zertifikat ueber Port 80 des
#           anderen Dienstes (Weiterleitung an WEB_HTTP_PORT) oder per DNS-01
#   proxy   ein Reverse-Proxy davor macht HTTPS und leitet auf
#           WEB_PROXY_PORT (HTTP) weiter
# Die Routen darunter sind fuer alle Modi gleich.

{
	email {$ACME_EMAIL}
	admin {$CADDY_ADMIN:localhost:2019}
	import {$CADDY_SITE_DIR:/etc/caddy/site}/{$WEB_MODE:direct}-global.caddy
}

(psplay) {
	# Eine vom Client mitgeschickte Upstream-Angabe nie durchreichen - die
	# setzt allein das Panel (forward_auth -> copy_headers). Laeuft auf
	# Site-Ebene und damit vor den handle-Bloecken unten.
	request_header -X-Bridge-Upstream

	# Nur fuer die Bridges auf diesem Server (direkt ueber 127.0.0.1).
	handle /internal/* {
		respond 404
	}

	# Die REST-Schnittstellen der Bridges spricht nur das Panel an.
	handle /bridge/* {
		respond 404
	}

	# Signaling + Stream (/ws) und reine Eingabe-Verbindungen fuer ein
	# Zweitgeraet (/ws-input), jeweils mit ?site=<id>. Das Panel prueft
	# Anmeldung UND Zugriff auf diese Site und nennt die Bridge der Site;
	# Caddy prueft vor dem WebSocket-Upgrade.
	handle /ws* {
		forward_auth 127.0.0.1:{$PANEL_PORT} {
			uri /api/auth-check/bridge
			copy_headers X-Bridge-Upstream
			# Die Pruefanfrage ist eine normale GET-Anfrage: ohne das wuerden
			# die Upgrade-Header des Originals mitgeschickt und uvicorn
			# behandelte sie als WebSocket-Aufbau.
			header_up -Upgrade
			header_up -Connection
		}
		reverse_proxy {http.request.header.X-Bridge-Upstream}
	}

	# Panel: Anmeldung, Heimnetze, Seiten
	handle {
		reverse_proxy 127.0.0.1:{$PANEL_PORT} {
			# Echte Herkunftsadresse durchreichen (Sperre nach Fehlversuchen,
			# Schutz von /internal/* im Panel). {client_ip} ist die Adresse des
			# Browsers - hinter einem Reverse-Proxy (WEB_MODE=proxy) die aus
			# dessen X-Forwarded-For, aber nur von WEB_TRUSTED_PROXIES.
			header_up X-Forwarded-For {client_ip}
		}
	}

	encode zstd gzip

	header {
		X-Frame-Options DENY
		X-Content-Type-Options nosniff
		Referrer-Policy no-referrer
	}

	log {
		output file {$CADDY_LOG_DIR:/var/log/caddy}/access.log {
			roll_size 10MiB
			roll_keep 3
		}
	}
}

# Browser merken sich: diese Domain nur per HTTPS (alle Modi ausser port,
# siehe caddy/site/port.caddy)
(hsts) {
	header Strict-Transport-Security "max-age=31536000"
}

import {$CADDY_SITE_DIR:/etc/caddy/site}/{$WEB_MODE:direct}.caddy
