# ==============================================================
# Verumind Hub — Caddy Reverse-Proxy
#
# Caddy holt automatisch ein Let's-Encrypt-Zertifikat für die Domain
# und terminiert HTTPS. Die Domain wird NICHT hier hart eingetragen,
# sondern über die Umgebungsvariable DOMAIN aus der .env gesteuert
# (siehe docker-compose.yml → Service "caddy").
#
# Pro Kunde muss also nur DOMAIN, ACME_EMAIL (und optional ACME_CA zum
# Testen) in der .env getauscht werden — diese Datei bleibt unverändert.
# ==============================================================
{
	# E-Mail für Let's Encrypt (Ablauf-/Sicherheitsbenachrichtigungen).
	email {$ACME_EMAIL}

	# ACME-Endpoint. Standard = Let's-Encrypt-PRODUKTION.
	# Zum gefahrlosen Testen ACME_CA in der .env auf den Staging-Endpoint
	# setzen — Staging-Zertifikate sind im Browser "nicht vertrauenswürdig"
	# (das ist erwartet), unterliegen aber keinem strengen Ratenlimit.
	acme_ca {$ACME_CA:https://acme-v02.api.letsencrypt.org/directory}
}

# Die öffentliche Domain kommt aus der Umgebungsvariable DOMAIN.
{$DOMAIN} {
	# Antworten komprimieren.
	encode zstd gzip

	# Sicherheits-Header für alle Antworten.
	header {
		# HTTPS für 1 Jahr erzwingen (Caddy terminiert TLS ohnehin).
		Strict-Transport-Security "max-age=31536000; includeSubDomains"
		# MIME-Sniffing unterbinden.
		X-Content-Type-Options "nosniff"
		# Einbettung in fremde Seiten verbieten (Clickjacking).
		X-Frame-Options "DENY"
		# Keine Referrer-Weitergabe an fremde Origins.
		Referrer-Policy "strict-origin-when-cross-origin"
		# Sensible Browser-APIs nicht freigeben.
		Permissions-Policy "camera=(), microphone=(), geolocation=()"

		# ── Content-Security-Policy (OPL #42) — SCHARF (blockierend) ─────────
		# Seit 23.07. scharf: der Browser BLOCKIERT jetzt Fremdinhalte, statt sie nur
		# zu melden. Das ist der eigentliche Schutz gegen eingeschleusten Fremdcode
		# (XSS). Der beobachtende Report-Only-Betrieb davor zeigte keine störenden
		# Verstöße; die einzige externe Ressource ist die OpenStreetMap-Karte im
		# Sourcing — deren Kacheln sind Bilder und über `img-src ... https:` erlaubt.
		#
		# ZURÜCKSCHALTEN bei Problemen: Header-Namen wieder auf
		# "Content-Security-Policy-Report-Only" ändern (blockiert dann nichts mehr).
		#
		# Die Direktiven im Einzelnen:
		# - 'unsafe-inline'/'unsafe-eval' für Skripte: BEWUSST — Next.js liefert den
		#   Hydration-Zustand als Inline-Skript. Ein Nonce-Verfahren wäre sauberer,
		#   braucht aber eine Frontend-Middleware (eigener Schritt).
		# - img-src ... https:  → erlaubt die OpenStreetMap-Kartenkacheln (Leaflet)
		#   UND data:/blob: (Next.js-Bilder). Bewusst breit für Bilder, weil Kacheln
		#   von wechselnden Tile-Servern kommen.
		# - font-src 'self' data:  → Inter-Schrift wird von next/font SELBST gehostet
		#   (zur Build-Zeit heruntergeladen, liegt unter .next/static/media).
		# - connect-src 'self'  → genügt, weil ALLE fremden Aufrufe (n8n, Salesforce,
		#   Apify) serverseitig laufen; der Browser spricht nur mit der eigenen Domain.
		Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'"
	}

	# Alle Anfragen gehen an das Frontend (Next.js, intern Port 3001).
	# Das Frontend leitet /backend/* (API) und /api/auth/* (Token-Cookies)
	# serverseitig intern an das Backend weiter — daher ist hier KEIN
	# separater Backend-Pfad nötig und die Backend-Domain bleibt privat.
	reverse_proxy frontend:3001
}
