# E1.5 proxy: TLS, the origins, and the forward_auth subrequest to web.
# The authorization DECISION behind /internal/authz/app is web's (E2). The share origins
# live in share.caddy, which entrypoint.sh appends only when AGENTO_SHARE_HOST is set (E6).
# No route here ever targets the toolbox, so a `?cap=` token never reaches this proxy.
{
	admin off
	auto_https disable_redirects
	log default {
		output stdout
		format json
		exclude http.log.error
	}
	# Caddy's error logger writes the raw request URI; the per-site access-log
	# filter does not cover it, so it gets the same redaction here.
	log redacted_errors {
		output stdout
		include http.log.error
		format filter {
			wrap json
			fields {
				request>uri query {
					replace cap REDACTED
					replace code REDACTED
				}
				request>headers>Cookie delete
				request>headers>Authorization delete
			}
		}
	}
}

(access_log) {
	log {
		output stdout
		format filter {
			wrap json
			fields {
				request>uri query {
					replace cap REDACTED
					replace code REDACTED
				}
				request>headers>Cookie delete
				request>headers>Authorization delete
			}
		}
	}
}

# Every caller-supplied identity header is dropped before any upstream or subrequest
# sees it. X-Agento-* is the proxy's own namespace; only forward_auth sets one.
# Caddy sorts directives: request_header runs before handle, but forward_auth at site
# level would run BEFORE request_header, and uri before forward_auth. So every
# forward_auth sits in a route (written order kept) inside a handle.
(strip_identity) {
	request_header -X-Agento-*
	request_header -X-Forwarded-User
	request_header -X-Remote-User
	request_header -Remote-User
}

{$AGENTO_PANEL_HOST} {
	tls internal
	import access_log
	import strip_identity
	handle /internal/* {
		respond 404
	}
	handle /api/* {
		reverse_proxy web:8000
	}
	handle /health {
		reverse_proxy web:8000
	}
	# The built panel (PRD E8 §11): static files, no server-side render. Hashed assets are
	# immutable; the shell is never cached, so a deploy is seen on the next load. A path
	# with no file is a client route and gets the shell.
	# `route` keeps the written order: a missing file answers 404 before any cache header.
	handle /assets/* {
		route {
			root * /srv/panel
			@missing not file
			respond @missing 404
			header Cache-Control "public, max-age=31536000, immutable"
			file_server
		}
	}
	handle {
		root * /srv/panel
		header Cache-Control "no-store"
		try_files {path} /index.html
		file_server
	}
}

# Only the immutable /a/<code>/v/<id>/ shape is served (PRD E6 §6.2): no `current`
# route and no index. web parses the RAW path (X-Forwarded-Uri) once, decides on it, and
# returns the canonical path in X-Agento-Upstream-Path; exactly that path is fetched, so
# the decision and the file lookup cannot parse the request two ways.
{$AGENTO_APPS_HOST} {
	tls internal
	import access_log
	import strip_identity
	# The launch exchange (PRD E2 §4.3): the panel page POSTs a form here. POST only, so a
	# prefetch or a scanner cannot consume the one-time code; the code is never in the URL.
	@redeem {
		method POST
		path /launch
	}
	handle @redeem {
		rewrite * /internal/launch/redeem
		reverse_proxy web:8000
	}
	# The miniapp kit (PRD E8 §10): /_ui/<version>/ is immutable, never behind forward_auth;
	# it holds no data, only the shared CSS, the custom elements, the bridge and the font.
	handle_path /_ui/* {
		route {
			root * /srv/miniapp-ui
			@missing not file
			respond @missing 404
			header Cache-Control "public, max-age=31536000, immutable"
			file_server
		}
	}
	handle /a/* {
		route {
			forward_auth web:8000 {
				uri /internal/authz/app
				header_up X-Agento-Proxy-Auth {$AGENTO_PROXY_SECRET}
				copy_headers X-Agento-Upstream-Path
			}
			rewrite * {http.request.header.X-Agento-Upstream-Path}
			request_header -X-Agento-Upstream-Path
			reverse_proxy artifacts:8080
		}
	}
	handle {
		respond 404
	}
}
