Commit Graph
771 Commits
Author SHA1 Message Date
mrhid6 28b813ba64 feat: sell status pages as a per-instance licence feature 2026-08-25 09:25:05 +00:00
mrhid6 68160dc681 docs: correct the status page URL for self-hosted, trim to what ships
- The status page URL was given only as `<instance>.vantage.<tld>`, which a
  self-hosted install does not serve. Both deployments are now described.
- The banner is documented as one notice: the editor exposes no level picker
  and the view renders every level identically.
- `pending` added to the component states, which a monitor with no result yet
  renders.
- Delete page documented alongside un-publish.
- `TRUSTED_PROXIES` names the LAN case: with the RFC1918 default, a client on a
  private range reaching the server directly is itself trusted and can spoof
  `X-Forwarded-For` — and now `X-Forwarded-Host`. Narrow it to the proxy.
- CLAUDE.md: scopes are nine resources, not eight; `status-pages` added to the
  REST route table; the host-resolution rules recorded under Status pages.
2026-08-25 09:05:06 +00:00
mrhid6 32e7420d89 fix: wire status page and incident delete, stop promising a name we do not publish
- The display-name placeholder showed the monitor's own name, reading as "leave
  this blank and we will use it". The server deliberately does the opposite: a
  blank `display_name` publishes the raw monitor id, because publishing an
  internal name has to be a decision. The placeholder now says "Public name
  (required)" and Save is refused until every component has one, so nobody adds
  five monitors and discovers five UUIDs on their public page. The server
  fallback is unchanged.
- `deleteStatusPage` and `deleteStatusIncident` existed in the api client and
  were wired to nothing, and the page address is immutable — delete was the
  only correction for a typo and there was no way to reach it. The editor
  header gains a typed-confirmation Delete page, and each incident row a
  confirmed delete, both on the existing ConfirmDialog.
- The create modal's address hint had lost its em dash and read as a broken
  sentence.
2026-08-25 09:05:06 +00:00
mrhid6 7e1d67dba4 fix: file live outages as active, refuse "operational" over zero components
- A derived monitor outage with no `resolved_at` went to `History`, so an
  ongoing disruption was listed under "Past incidents" while the component pill
  beside it read Down. Unresolved now goes to `ActiveIncidents`.
- `overallState` returned `up` when nothing was counted: "all systems
  operational" claimed from no evidence at all. A page with no components now
  reports `no_data`, which the view already renders as "Status unknown".
- `EnsureStatusPageIndexes` returned on the first failure, so a transient
  failure on the `status_pages` index left `status_incidents` with no unique
  `(instance_id, incident_id)` index — a correctness property, not a scan
  optimisation. All three are attempted and the failures joined.
2026-08-25 09:04:54 +00:00
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
mrhid6 72c9492223 docs: status pages 2026-08-25 08:44:38 +00:00
mrhid6 fa67d839cd fix: status page editor error handling, maintenance validation and UTC display 2026-08-25 08:40:05 +00:00
mrhid6 1452928b75 feat: status page authoring UI 2026-08-25 08:32:43 +00:00
mrhid6 bf10023f35 fix: empty slices rather than null on the unavailable status snapshot 2026-08-24 19:42:16 +00:00
mrhid6 f4f41e400b feat: public status page 2026-08-24 14:53:42 +00:00
mrhid6 3abbdc41d6 feat: status page authoring API
Adds owner|admin routes under /api/status-pages for authoring status pages
and their incidents/maintenance windows, gated by the status_pages licence
feature. Adds the "status" token scope resource and the ten route-scope
entries, and regenerates the committed OpenAPI document.

Also types ErrPageInvalid as a sentinel for status page/incident validation
failures (previously bare errors), so statusPageError maps them to 400
instead of 500, and createStatusIncident/updateStatusIncident route through
the shared error mapper rather than hand-rolling a 400 for any service error.
2026-08-24 14:43:17 +00:00
mrhid6 6ba54f690c fix: default TRUSTED_PROXIES in shipped deployments and route /public/ through ingress 2026-08-24 14:35:29 +00:00
mrhid6 a3c6b2a305 feat: public status page endpoint with per-address rate limit 2026-08-24 14:29:24 +00:00
mrhid6 21a2d077d8 feat: cached public status snapshot with licence gate 2026-08-24 14:24:07 +00:00
mrhid6 6263c7e16f fix: clear resolved_at when reopening a status incident via appended update 2026-08-24 14:21:26 +00:00
mrhid6 161835802d feat: authored status incidents and maintenance windows 2026-08-24 14:18:06 +00:00
mrhid6 6f998ff506 feat: status page CRUD and cache invalidation 2026-08-24 14:15:25 +00:00
mrhid6 d192589790 fix: maintenance repaint no longer zeroes no_data uptime; strengthen redaction test 2026-08-24 14:12:38 +00:00
mrhid6 21c2bb2646 feat: public status snapshot assembly and redaction boundary 2026-08-24 14:07:10 +00:00
mrhid6 9c0bbd13dd feat: status page id validation and cache key 2026-08-24 14:02:46 +00:00
mrhid6 1c15961309 feat: status page schema, licence feature and indexes 2026-08-24 14:00:00 +00:00
mrhid6 383b763a66 docs: attach approved status page mockup to the implementation plan 2026-08-24 13:52:07 +00:00
mrhid6 3e99a9df33 docs: public status pages implementation plan 2026-08-24 13:42:44 +00:00
mrhid6 f1b6f90345 docs: public status pages design spec 2026-08-24 13:32:24 +00:00
mrhid6 2a660697c5 docs: Updated troubleshotting doc 2026-08-24 12:50:44 +00:00
mrhid6 0c08dda635 feat: Useragent 2026-08-24 12:17:46 +00:00
mrhid6 22b99ff895 feat: Monitor grath zoom 2026-08-24 10:58:50 +00:00
mrhid6 2fab784ba7 feat: Monitor groups and chart information 2026-08-24 10:30:23 +00:00
mrhid6 83cdf92575 feat: Updated edit monitor page 2026-08-24 09:25:43 +00:00
mrhid6 aa1c8e4aa1 feat: Hide secrets on api and channels 2026-08-14 12:23:36 +00:00
mrhid6 ac61015cc0 fix: Fixed incorrect openapi doc 2026-08-13 13:04:44 +00:00
mrhid6 a0fbf5b9ba fix: Word and colour Windows workloads correctly across the UI 2026-08-13 12:57:37 +00:00
mrhid6 ddf0814803 docs: Fix Windows package-inventory and poll-loop claims in CLAUDE.md 2026-08-13 12:28:51 +00:00
mrhid6 2bc15648b7 docs: Describe the Windows agent's update and workload support 2026-08-13 12:23:34 +00:00
mrhid6 7f348b7b2b fix: Follow Windows Th/Td labels through the updates table 2026-08-13 12:19:47 +00:00
mrhid6 a71fd9a9f4 fix: Fixed docs entitlement 2026-08-13 12:18:21 +00:00
mrhid6 36848a519a feat: Word the workload and update panels for Windows servers 2026-08-13 12:16:10 +00:00
mrhid6 ea6d0b969c fix: Trim Windows event log after SCM filtering, not before 2026-08-13 12:12:11 +00:00
mrhid6 4ba9983cf8 feat: Control Windows services and read their event log as workloads 2026-08-13 12:04:49 +00:00
mrhid6 8caaa4540f fix: Respect .exe word boundary and unterminated quotes in servicePath 2026-08-13 12:00:59 +00:00
mrhid6 42f0cb67cb feat: Collect Windows services as workloads 2026-08-13 11:52:08 +00:00
mrhid6 1dfb3cc28c refactor: Split the agent workloads package by build tag 2026-08-13 10:49:24 +00:00
mrhid6 b51e87477e feat: Report whether a managed host is waiting on a reboot 2026-08-13 10:39:27 +00:00
mrhid6 05c0ad43d2 feat: Check and apply Windows updates through the Windows Update COM API 2026-08-13 10:36:22 +00:00
mrhid6 4a07af049c refactor: Split the agent updates package by build tag 2026-08-13 10:33:35 +00:00
mrhid6 057c193e26 feat: Add winexec helper for running PowerShell from the agent 2026-08-13 10:26:31 +00:00
mrhid6 38a731f269 docs: Add implementation plan for Windows agent parity 2026-08-13 10:21:04 +00:00
mrhid6 06d69590fc docs: Design for Windows agent parity on updates and workloads 2026-08-13 10:08:25 +00:00
mrhid6 6adee810dc feat: Cleanup old docs 2026-08-13 09:41:32 +00:00
mrhid6 00d4307346 fix: Fixed chart for ingress 2026-08-13 09:29:01 +00:00