{
	auto_https off
	admin off
}

:{$PORT} {
	root * {$MESSAGES_FRONTEND_ROOT:/app}

	# Security headers for everything this site serves (SPA shell, static
	# assets, and proxied API/admin — `header` replaces, so it does not
	# duplicate Django's own X-Frame-Options).
	header {
		-Server
		# Clickjacking: the webmail UI must never be framable. frame-ancestors
		# is the modern control; X-Frame-Options covers older browsers.
		X-Frame-Options "DENY"
		Content-Security-Policy "frame-ancestors 'none'; base-uri 'self'; object-src 'none'"
		X-Content-Type-Options "nosniff"
		Referrer-Policy "same-origin"
	}

	route {
		# Health checks
		respond /__lbheartbeat__ 200
		respond /__lbheartbeat__/ 200

		reverse_proxy /__heartbeat__/* {$MESSAGES_FRONTEND_BACKEND_SERVER:localhost:8000} {
			header_up X-Forwarded-Proto https
			header_up X-Forwarded-For {remote_host}
		}

		# Django backend proxy
		reverse_proxy /api/* {$MESSAGES_FRONTEND_BACKEND_SERVER:localhost:8000} {
			header_up X-Forwarded-Proto https
			header_up X-Forwarded-For {remote_host}
		}

		redir /{$DJANGO_ADMIN_URL:admin} /{$DJANGO_ADMIN_URL:admin}/ 301

		reverse_proxy /{$DJANGO_ADMIN_URL:admin}/* {$MESSAGES_FRONTEND_BACKEND_SERVER:localhost:8000} {
			header_up X-Forwarded-Proto https
			header_up X-Forwarded-For {remote_host}
		}

		reverse_proxy /static/* {$MESSAGES_FRONTEND_BACKEND_SERVER:localhost:8000} {
			header_up X-Forwarded-Proto https
			header_up X-Forwarded-For {remote_host}
		}

		# --- Cache policy for the static SPA output ---
		# Vite fingerprints everything under /assets, so a given URL's bytes
		# never change: cache it forever. A new deploy emits new hashed URLs.
		@immutable path /assets/*
		header @immutable Cache-Control "public, max-age=31536000, immutable"
		# The SPA shell and other non-fingerprinted files (index.html, the
		# /locales JSON, images) must revalidate every load, or a deploy's new
		# asset hashes / translations only show up after a manual hard refresh.
		@revalidate not path /assets/*
		header @revalidate Cache-Control "no-cache"

		# SPA fallback: any unmatched request returns index.html so the
		# client-side router can resolve the path.
		try_files {path} /index.html
		file_server
	}

	handle_errors {
		@spa_404 expression `{err.status_code} == 404`
		handle @spa_404 {
			rewrite * /index.html
			file_server
		}
	}
}
