Expand README: Home Assistant guide, OIDC/backup status, troubleshooting
This commit is contained in:
1 parent
38c24fc9dc
commit
a82c29a69d
1 file changed
+87
-13
@@ -27,9 +27,12 @@ below for where things stand against the original 22 criteria.
|
|||||||
Set via `AUTH_MODE` (`.env` / `docker-compose.yml` environment): `disabled`,
|
Set via `AUTH_MODE` (`.env` / `docker-compose.yml` environment): `disabled`,
|
||||||
`proxy`, or `oidc` — see [docs/phase1/02-threat-model.md](docs/phase1/02-threat-model.md).
|
`proxy`, or `oidc` — see [docs/phase1/02-threat-model.md](docs/phase1/02-threat-model.md).
|
||||||
`disabled` refuses to start when `NODE_ENV=production` (it grants every
|
`disabled` refuses to start when `NODE_ENV=production` (it grants every
|
||||||
request implicit admin access — dev/test only). `oidc` is implemented
|
request implicit admin access — dev/test only). `oidc` is confirmed working
|
||||||
against the `openid-client` v5 API but hasn't been run against a real IdP
|
end-to-end against a real Pocket ID instance (Authorization Code + PKCE via
|
||||||
yet; test it once Pocket ID (or similar) is configured.
|
`openid-client` v5). Once `AUTH_MODE=oidc` is set and the server restarted,
|
||||||
|
the actual provider details (issuer URL, client ID/secret, redirect URL,
|
||||||
|
scopes) are editable any time from **Admin → Auth** — no further env file
|
||||||
|
edits or restarts needed for those.
|
||||||
|
|
||||||
All mutating requests on the web listener (`POST`/`PUT`/`PATCH`/`DELETE`
|
All mutating requests on the web listener (`POST`/`PUT`/`PATCH`/`DELETE`
|
||||||
under `/api/`) require a `X-Requested-With: notizarr` header — this is the
|
under `/api/`) require a `X-Requested-With: notizarr` header — this is the
|
||||||
@@ -150,6 +153,12 @@ push subscriptions, the VAPID keypair, the session secret — lives in
|
|||||||
Postgres (see [docs/phase1/06-docker-unraid-design.md](docs/phase1/06-docker-unraid-design.md#backup--restore)),
|
Postgres (see [docs/phase1/06-docker-unraid-design.md](docs/phase1/06-docker-unraid-design.md#backup--restore)),
|
||||||
so backing up the database is a complete backup.
|
so backing up the database is a complete backup.
|
||||||
|
|
||||||
|
**Automatic (no setup needed):** the app backs itself up once a day and
|
||||||
|
keeps the last 14, no Unraid User Scripts cron entry required. Trigger one
|
||||||
|
manually or download an existing one from **Admin → Backups**.
|
||||||
|
|
||||||
|
**Manual / scripted**, e.g. for an off-box copy:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /mnt/tank/appdata/notizarr
|
cd /mnt/tank/appdata/notizarr
|
||||||
./scripts/backup.sh
|
./scripts/backup.sh
|
||||||
@@ -158,24 +167,78 @@ cd /mnt/tank/appdata/notizarr
|
|||||||
Writes a timestamped, gzipped `pg_dump` plus a copy of the compose file
|
Writes a timestamped, gzipped `pg_dump` plus a copy of the compose file
|
||||||
(env vars, including the DB password and OIDC client secret, are inline
|
(env vars, including the DB password and OIDC client secret, are inline
|
||||||
there rather than in a separate `.env` — keep `backups/` off shared or
|
there rather than in a separate `.env` — keep `backups/` off shared or
|
||||||
public storage) into `backups/`, keeping the last 14 of each. Restore
|
public storage) into `backups/`, keeping the last 14 of each — the same
|
||||||
with:
|
directory and naming the in-app job uses, so both coexist. Restore with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./scripts/restore.sh backups/notizarr-db-<timestamp>.sql.gz
|
./scripts/restore.sh backups/notizarr-db-<timestamp>.sql.gz
|
||||||
```
|
```
|
||||||
|
|
||||||
This is destructive (replaces all current data) and asks for confirmation.
|
This is destructive (replaces all current data) and asks for confirmation.
|
||||||
Consider scheduling `backup.sh` via an Unraid User Scripts cron entry for
|
|
||||||
regular backups.
|
|
||||||
|
|
||||||
## Migrating from ntfy / integrating other services
|
## Home Assistant
|
||||||
|
|
||||||
- [docs/migration-ntfy.md](docs/migration-ntfy.md) — endpoint mapping,
|
Add a `rest_command` pointing at the LAN ingestion listener (`:8081`, never
|
||||||
before/after examples, what's intentionally not replicated
|
the public URL):
|
||||||
- [docs/home-assistant.md](docs/home-assistant.md) — `rest_command` example
|
|
||||||
replacing `ntfy.publish`, plus Seerr, Uptime Kuma, and generic webhook
|
```yaml
|
||||||
configuration
|
# configuration.yaml
|
||||||
|
rest_command:
|
||||||
|
notizarr:
|
||||||
|
url: "http://<lan-ip>:8081/api/v1/notifications"
|
||||||
|
method: POST
|
||||||
|
headers:
|
||||||
|
Authorization: !secret notizarr_token
|
||||||
|
Content-Type: "application/json"
|
||||||
|
payload: >
|
||||||
|
{
|
||||||
|
"topic": "{{ topic }}",
|
||||||
|
"title": "{{ title }}",
|
||||||
|
"message": "{{ message }}",
|
||||||
|
"source": "{{ source | default('home-assistant') }}",
|
||||||
|
"priority": "{{ priority | default('default') }}",
|
||||||
|
"image_url": "{{ image_url | default('') }}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# secrets.yaml — the value is the FULL header including "Bearer ", since a
|
||||||
|
# YAML !secret must be a key's entire value, not embedded in a larger string
|
||||||
|
notizarr_token: "Bearer nzr_your_token_here"
|
||||||
|
```
|
||||||
|
|
||||||
|
Then call it from any automation:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
action: rest_command.notizarr
|
||||||
|
data:
|
||||||
|
topic: homeassistant
|
||||||
|
title: "🏠 Home"
|
||||||
|
message: "Office window is open, don't forget to close it"
|
||||||
|
```
|
||||||
|
|
||||||
|
Get the token from **Admin → API Tokens → Create token**. Two extras worth
|
||||||
|
knowing:
|
||||||
|
|
||||||
|
- **`priority: min`** stores and shows the notification as usual but skips
|
||||||
|
the push — useful for automations that should log something without
|
||||||
|
buzzing anyone's phone, without needing a separate "quiet" topic.
|
||||||
|
- **Quiet hours** (Admin → System) and **per-topic snooze** (the alarm-clock
|
||||||
|
icon on any topic page) both suppress push independently of what any
|
||||||
|
individual automation sends, if you'd rather configure "don't wake me
|
||||||
|
up" once instead of per-automation.
|
||||||
|
|
||||||
|
Full field reference, dedup keys, and examples for Seerr/Uptime
|
||||||
|
Kuma/generic webhooks: [docs/home-assistant.md](docs/home-assistant.md).
|
||||||
|
|
||||||
|
## Migrating from ntfy
|
||||||
|
|
||||||
|
[docs/migration-ntfy.md](docs/migration-ntfy.md) — endpoint mapping,
|
||||||
|
before/after examples, what's intentionally not replicated. Short version:
|
||||||
|
point existing `ntfy.sh/<topic>` publishers at
|
||||||
|
`http://<lan-ip>:8081/<topic>` with an `Authorization: Bearer nzr_...`
|
||||||
|
header instead — headers, JSON body, and query-param publishing all still
|
||||||
|
work the same way.
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
@@ -208,6 +271,17 @@ regular backups.
|
|||||||
non-admin user was created first (e.g. during testing), promote them
|
non-admin user was created first (e.g. during testing), promote them
|
||||||
manually via Settings → Admin → Users using an existing admin account, or
|
manually via Settings → Admin → Users using an existing admin account, or
|
||||||
directly in Postgres if none exists yet.
|
directly in Postgres if none exists yet.
|
||||||
|
- **A third-party app's built-in "Ntfy" notification type won't send
|
||||||
|
("test failed", 404).** Sonarr/Radarr/Prowlarr-style apps typically
|
||||||
|
append each topic in their own "Topics" field to the Server URL
|
||||||
|
(`{Server URL}/{topic}`), so the topic must **not** already be in the
|
||||||
|
Server URL — just the bare host+port. Overseerr/Jellyseerr-style apps do
|
||||||
|
the opposite: they expect the topic already in the Server URL and don't
|
||||||
|
append anything, so putting a topic in a separate "Topic" field there is
|
||||||
|
redundant but harmless. When in doubt, `curl` the ingestion listener
|
||||||
|
directly with the same topic path the app would use — Notizarr always
|
||||||
|
expects exactly one path segment (`POST /:topic`), and comparing that
|
||||||
|
against what actually gets sent explains almost every case of this.
|
||||||
|
|
||||||
## MVP acceptance status
|
## MVP acceptance status
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user