Files
vantage/web/app
mrhid6 da1dc90ac5 fix: resolve the public status page's tenant from a trusted X-Forwarded-Host
The SSR fetch set `Host` to the visitor's hostname. `Host` is a forbidden
header name and undici discards it silently, so the Go server saw
`server:8080`, `hostSlug` returned "", `InstanceFromHost` returned false and
every public status page 404'd on every deployment. The feature did not work.

- `web/` now forwards the visitor's host as `X-Forwarded-Host`, and their
  address on `X-Forwarded-For` — without the latter gin sees a request from the
  Next pod with no XFF and every visitor of every page shares one 120/min
  bucket, tripped by exactly the traffic an outage produces.
- `publicStatusInstance` honours `X-Forwarded-Host` only when `c.RemoteIP()` is
  in `TRUSTED_PROXIES`. It is a tenant selector, so an untrusted peer must not
  be able to name one; `RemoteIP()` rather than `ClientIP()` because the latter
  is reconstructed from the very headers being judged. `TrustedProxies()` moves
  from main.go into the api package so the variable keeps one parser.
- A host naming no slug on a non-cloud deployment resolves the sole instance,
  the way bootstrap does. A self-hosted install at vantage.acme.com or an IP
  has no slug and could never serve a status page; more than one instance is a
  404 rather than a guess, and an unknown-but-well-formed slug stays a 404.
- `InstanceFromHost` gains an explicit-host variant rather than a second copy
  of the slug rules, and now caches negative lookups: an unknown host cost a
  Mongo query per anonymous request, which is also a timing oracle separating
  "no such instance" from "instance exists, page does not".
- The handler's `@Router` annotation is dropped. openapi.json declares one
  server of `/api`, so it published `/api/public/status/{pageId}` — a path that
  does not exist. The real address is described in prose instead.
2026-08-25 09:04:47 +00:00
..
2026-07-28 12:46:28 +01:00
2026-07-28 12:46:28 +01:00