|
|
|
|
@@ -169,9 +169,12 @@ none (keeps §11's zero-interaction promise).
|
|
|
|
|
registration and every publish validate it is HTTPS and its origin is in the shard's ntfy
|
|
|
|
|
allow-set (`NTFY_BASE_URL` / `NTFY_ALLOWED_ORIGINS`), rejecting loopback/private hosts.
|
|
|
|
|
- **ntfy** added to `website/docker-compose.yml` as a pinned upstream image with a committed
|
|
|
|
|
declarative `./ntfy/server.yml` and named volume, **no published host port** (reached via the
|
|
|
|
|
reverse proxy; internal-only for the publisher), anonymous read-write to unguessable topics (no
|
|
|
|
|
per-user accounts — safe because tickles are content-free).
|
|
|
|
|
declarative `./ntfy/server.yml` and named volume, **published on a host port** (`NTFY_HOST_PORT`,
|
|
|
|
|
default `2586` → container `:80`) so the public reverse proxy — which runs *outside* the compose
|
|
|
|
|
network — can forward the notification subdomain to it, anonymous read-write to unguessable topics
|
|
|
|
|
(no per-user accounts — safe because tickles are content-free). Both the app (SSE subscribe) and the
|
|
|
|
|
backend (POSTing tickles to registered device endpoints) reach ntfy on that public origin, so all
|
|
|
|
|
ntfy traffic transits the proxy — there is no separate internal publish port.
|
|
|
|
|
|
|
|
|
|
**Part 2 — the Android app — ✅ LANDED** (2026-07-20, `RunicGateway/Android-app#15` + a small
|
|
|
|
|
`RunicGateway/website#79` settings addition + this docs PR). Built exactly to the plan below, with
|
|
|
|
|
@@ -911,8 +914,11 @@ first release. Users **opt in per stream**: nothing is pushed unless subscribed.
|
|
|
|
|
path/tag at implementation.
|
|
|
|
|
- **All config is declarative** — a committed `ntfy` config file and/or `NTFY_*` env vars baked into
|
|
|
|
|
compose. No `docker exec`, no interactive `ntfy user add`, no post-deploy manual steps. Bringing the
|
|
|
|
|
stack up provisions a working push relay. Reachable to devices via the existing reverse proxy on its
|
|
|
|
|
own hostname/path; internal-only for the backend publisher.
|
|
|
|
|
stack up provisions a working push relay. Reachable via the existing reverse proxy on its own
|
|
|
|
|
hostname/path — the container publishes `:80` on a host port (`NTFY_HOST_PORT`, default `2586`)
|
|
|
|
|
because the proxy runs *outside* the compose network and can only reach a service through a
|
|
|
|
|
published host port (the same reason `app` publishes `3000`). Both devices and the backend publisher
|
|
|
|
|
reach ntfy on that public origin.
|
|
|
|
|
- **No per-user ntfy accounts to administer.** The security model (below) removes the need for ntfy ACL
|
|
|
|
|
provisioning, which is exactly what keeps setup interaction-free. ntfy topics are the random,
|
|
|
|
|
unguessable endpoints UnifiedPush hands out; the backend treats ntfy as an **untrusted relay**.
|
|
|
|
|
@@ -1002,8 +1008,10 @@ it is a UX convenience, not a v1 requirement — deferred at M3, descoped at M6;
|
|
|
|
|
See [`APP_LINKS.md`](./APP_LINKS.md).
|
|
|
|
|
- ntfy: exact upstream image + pinned tag (Part-1 landed the compose service — confirm the tag), and
|
|
|
|
|
its reverse-proxy hostname/path. The hostname must land in `NTFY_ALLOWED_ORIGINS` before M7 Part 2 is
|
|
|
|
|
end-to-end testable (the app registers an endpoint on that origin; the SSRF guard rejects others). No
|
|
|
|
|
backend publish token — **decided** (the content-free-tickle design does not require one; optional
|
|
|
|
|
end-to-end testable (the app registers an endpoint on that origin; the SSRF guard rejects others). The
|
|
|
|
|
reverse proxy forwards that hostname to the ntfy container's published host port (`NTFY_HOST_PORT`,
|
|
|
|
|
default `2586`) — the container publishes `:80` because the proxy runs outside the compose network.
|
|
|
|
|
No backend publish token — **decided** (the content-free-tickle design does not require one; optional
|
|
|
|
|
`NTFY_PUBLISH_TOKEN` is honored if ever set).
|
|
|
|
|
- FCM flavor: build it for the Play release or ship Play on UnifiedPush too? Decide at M8. (The M7
|
|
|
|
|
Part 2 `PushTransport` seam keeps this swap cheap.)
|
|
|
|
|
|