diff --git a/docs/api/reference.md b/docs/api/reference.md index b154655f..8a9b88c4 100644 --- a/docs/api/reference.md +++ b/docs/api/reference.md @@ -49,7 +49,7 @@ The remaining codes are specific to a route and are listed with it. Most are upp Three answers are not JSON: -- A route the server did not register (a feature that is not wired, such as the outbound heartbeats in demo mode) and a wrong method on a known path answer the plain-text `404` and `405` of the Go router. +- A route the server did not register (a feature that is not wired) and a wrong method on a known path answer the plain-text `404` and `405` of the Go router. - A request still running after 10 seconds is cut with `503` and the plain-text body `request timeout`. Streams are exempt. The work the request started can still finish, for example a synchronous certificate scan. - The OAuth routes answer with the RFC 6749 shape (`{"error": "...", "error_description": "..."}`). @@ -90,7 +90,7 @@ The API refuses a browser write that comes from another origin, unless that orig ### Demo mode -A demo build of maintenant is read-only. Every request other than `GET`, `HEAD` and `OPTIONS` answers `403 DEMO_MODE` (only `POST /api/v1/escalation-policies/overlap-probe`, which changes nothing, is let through). `/ping/`, `/mcp`, `/oauth/` and `/.well-known/oauth-*` answer `403 DEMO_MODE` for every method, and the outbound heartbeat routes are not registered. A request carrying the `X-Maintenant-Demo-Token` header with the value of `MAINTENANT_DEMO_TOKEN` bypasses the guard. `GET /api/v1/edition` reports `"demo": true`. +A demo build of maintenant is read-only. Every request other than `GET`, `HEAD` and `OPTIONS` answers `403 DEMO_MODE` (only `POST /api/v1/escalation-policies/overlap-probe`, which changes nothing, is let through). `/ping/`, `/mcp`, `/oauth/` and `/.well-known/oauth-*` answer `403 DEMO_MODE` for every method. Outbound heartbeats are never sent. A request carrying the `X-Maintenant-Demo-Token` header with the value of `MAINTENANT_DEMO_TOKEN` bypasses the guard. `GET /api/v1/edition` reports `"demo": true`. --- @@ -271,7 +271,7 @@ These routes need no credentials: the UUID of the heartbeat is the secret. They ### Outbound heartbeats -Outbound heartbeats make this instance ping an external URL so another system notices when it stops. The routes are not registered in demo mode. All are open in every edition. See [Outbound Heartbeats](../features/heartbeats.md#outbound-heartbeats). +Outbound heartbeats make this instance ping an external URL so another system notices when it stops. In demo mode they are read-only like every other route and no ping is sent. All are open in every edition. See [Outbound Heartbeats](../features/heartbeats.md#outbound-heartbeats). | Method | Endpoint | Description | |--------|----------|-------------| diff --git a/docs/features/heartbeats.md b/docs/features/heartbeats.md index e1061119..80d70fbc 100644 --- a/docs/features/heartbeats.md +++ b/docs/features/heartbeats.md @@ -193,7 +193,7 @@ The first send happens within seconds of creating the target. Two instances can - A 2xx response counts as a success. Any other status, or a network error, is recorded as the target's last error and logged as a warning. - A disabled target keeps its settings but is no longer called. - An extra root CA set with `MAINTENANT_CA_CERT` applies, so the other instance may use an internal PKI. -- The page is not available in demo mode. +- In demo mode the page is read-only and no ping is sent. !!! note "HTTPS and public addresses only" Targets must use `https://` and resolve to a public address. Loopback, private, diff --git a/frontend/src/layouts/DefaultLayout.vue b/frontend/src/layouts/DefaultLayout.vue index f7fd2b3d..028c5ed4 100644 --- a/frontend/src/layouts/DefaultLayout.vue +++ b/frontend/src/layouts/DefaultLayout.vue @@ -62,7 +62,6 @@ const router = useRouter() const { version } = useAppVersion() const { isCommunity, - isDemo, editionName, hasFeature, licenseMessage, @@ -164,7 +163,7 @@ const allNav: NavItem[] = [ { type: 'separator' }, { type: 'item', to: '/status-admin', label: 'Status Pages', icon: Activity }, { type: 'item', to: '/agents', label: 'Agents', icon: MonitorDot }, - { type: 'item', to: '/outbound-heartbeats', label: 'Outbound heartbeats', icon: RadioTower, hideInDemo: true }, + { type: 'item', to: '/outbound-heartbeats', label: 'Outbound heartbeats', icon: RadioTower }, ] const mainNav = computed(() => @@ -172,7 +171,6 @@ const mainNav = computed(() => isNavItemVisible(item, { hasFeature, availableRuntimes: availableRuntimes.value, - isDemo: isDemo.value, }), ), ) diff --git a/frontend/src/pages/OutboundHeartbeatsPage.vue b/frontend/src/pages/OutboundHeartbeatsPage.vue index ee30e059..bfdb6e5b 100644 --- a/frontend/src/pages/OutboundHeartbeatsPage.vue +++ b/frontend/src/pages/OutboundHeartbeatsPage.vue @@ -5,15 +5,10 @@ @@ -28,31 +23,22 @@ const showCreateForm = ref(false) Ping other Maintenant instances so they alert if this one goes down
-/ping/{uuid})
- as a target here. This instance pings it on the interval you choose — if this instance goes down, the other one raises the alert.
- /ping/{uuid})
+ as a target here. This instance pings it on the interval you choose — if this instance goes down, the other one raises the alert.
+