docs: update notification channel and API docs for form-based management
- NOTIFICATIONS.md: document owner/private fields, channel visibility rules, and user-created channels; add troubleshooting note for private channel visibility - HTTP_API.md: add notification channel API endpoints table and full endpoint reference (GET types, GET/POST/PUT/DELETE channels) - USERS.md: add missing PUT /api/0/users/me endpoint documentation with all three update modes (identity, channels, password) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,17 @@ See [User Management](USERS.md) for full authentication documentation.
|
|||||||
|--------|------|-------------|------|
|
|--------|------|-------------|------|
|
||||||
| `GET` | `/api/0/users` | List all users | Admin |
|
| `GET` | `/api/0/users` | List all users | Admin |
|
||||||
| `GET` | `/api/0/users/me` | Own profile | Authenticated |
|
| `GET` | `/api/0/users/me` | Own profile | Authenticated |
|
||||||
|
| `PUT` | `/api/0/users/me` | Update own profile | Authenticated |
|
||||||
|
|
||||||
|
### Notification Channels
|
||||||
|
|
||||||
|
| Method | Path | Description | Role |
|
||||||
|
|--------|------|-------------|------|
|
||||||
|
| `GET` | `/api/0/notification_channel_types` | Channel type schemas | Authenticated |
|
||||||
|
| `GET` | `/api/0/notification_channels` | List visible channels | Authenticated |
|
||||||
|
| `POST` | `/api/0/notification_channels` | Create a channel | Authenticated |
|
||||||
|
| `PUT` | `/api/0/notification_channels/{name}` | Update a channel | Owner or Admin |
|
||||||
|
| `DELETE` | `/api/0/notification_channels/{name}` | Delete a channel | Owner or Admin |
|
||||||
|
|
||||||
### Host Management
|
### Host Management
|
||||||
|
|
||||||
@@ -203,6 +214,101 @@ Changes take effect immediately but are not written back to the config file. Upd
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Notification Channel Endpoints
|
||||||
|
|
||||||
|
Channels are visible to all users by default. Channels marked `private: true` are only visible to their owner. Admins see all channels.
|
||||||
|
|
||||||
|
#### GET /api/0/notification_channel_types
|
||||||
|
Return the schema for every supported notifier type. Used by the web UI to dynamically render the channel creation form.
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"pushover": {
|
||||||
|
"label": "Pushover",
|
||||||
|
"fields": [
|
||||||
|
{"key": "token", "label": "App token", "type": "secret", "required": true},
|
||||||
|
{"key": "user", "label": "User key", "type": "secret", "required": true},
|
||||||
|
{"key": "sound", "label": "Sound", "type": "text", "required": false}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"email": { "label": "E-mail", "fields": [ ... ] },
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### GET /api/0/notification_channels
|
||||||
|
List channels visible to the current user (public channels + own private channels). Admins receive all channels.
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "pushover_ops",
|
||||||
|
"type": "pushover",
|
||||||
|
"type_label": "Pushover",
|
||||||
|
"owner": null,
|
||||||
|
"private": false,
|
||||||
|
"min_level": "WARNING",
|
||||||
|
"fields": [
|
||||||
|
{"key": "token", "label": "App token", "value": "•••", "sensitive": true},
|
||||||
|
{"key": "user", "label": "User key", "value": "•••", "sensitive": true}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Sensitive fields (`type: "secret"`) are always returned as `"•••"`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### POST /api/0/notification_channels
|
||||||
|
Create a new channel. The creating user becomes the channel's `owner`.
|
||||||
|
|
||||||
|
**Request body:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "my_pushover",
|
||||||
|
"type": "pushover",
|
||||||
|
"token": "app-token",
|
||||||
|
"user": "user-key",
|
||||||
|
"min_level": "WARNING",
|
||||||
|
"private": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:** `{"ok": true, "name": "my_pushover"}`
|
||||||
|
|
||||||
|
**Status codes:** `200 OK`, `400` (missing required field or unknown type), `409` (name already exists)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### PUT /api/0/notification_channels/{name}
|
||||||
|
Update an existing channel. Only the channel owner or an admin may update it.
|
||||||
|
|
||||||
|
Secret fields sent as `"•••"` are preserved from the existing config (same pattern as OAuth secrets in the admin config editor).
|
||||||
|
|
||||||
|
**Request body:** same shape as POST, `name` ignored (taken from URL).
|
||||||
|
|
||||||
|
**Response:** `{"ok": true}`
|
||||||
|
|
||||||
|
**Status codes:** `200 OK`, `403 Forbidden`, `404 Not Found`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### DELETE /api/0/notification_channels/{name}
|
||||||
|
Delete a channel. Only the channel owner or an admin may delete it.
|
||||||
|
|
||||||
|
**Response:** `{"ok": true}`
|
||||||
|
|
||||||
|
**Status codes:** `200 OK`, `403 Forbidden`, `404 Not Found`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Alert Endpoints
|
### Alert Endpoints
|
||||||
|
|
||||||
#### GET /api/0/hosts/{hostname}/alerts
|
#### GET /api/0/hosts/{hostname}/alerts
|
||||||
|
|||||||
+37
-7
@@ -30,9 +30,17 @@ Set `base_url` so notification links point to your hbd instance:
|
|||||||
base_url: https://hbd.example.com
|
base_url: https://hbd.example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
### Global channel definitions
|
### Channel definitions
|
||||||
|
|
||||||
Define channels once; reference them by name from user configs:
|
Channels are defined under `notification_channels`. Each entry specifies a delivery type and its credentials. Two optional metadata fields control visibility:
|
||||||
|
|
||||||
|
| Field | Default | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `owner` | *(absent)* | Username who created/owns this channel. Absent = admin-created. |
|
||||||
|
| `private` | `false` | When `true`, only the owner can see and select this channel. |
|
||||||
|
| `min_level` | `WARNING` | Minimum alert level this channel receives. |
|
||||||
|
|
||||||
|
**Admin-created channels** (set in the config file or via the admin settings UI) are public by default — all users can select them:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
notification_channels:
|
notification_channels:
|
||||||
@@ -41,7 +49,7 @@ notification_channels:
|
|||||||
type: pushover
|
type: pushover
|
||||||
token: your-app-token
|
token: your-app-token
|
||||||
user: your-user-key
|
user: your-user-key
|
||||||
min_level: WARNING # optional, default: WARNING
|
min_level: WARNING
|
||||||
|
|
||||||
email_ops:
|
email_ops:
|
||||||
type: email
|
type: email
|
||||||
@@ -58,14 +66,14 @@ notification_channels:
|
|||||||
homeserver: https://matrix.example.org
|
homeserver: https://matrix.example.org
|
||||||
access_token: syt_xxx
|
access_token: syt_xxx
|
||||||
room_id: "!abc:matrix.example.org"
|
room_id: "!abc:matrix.example.org"
|
||||||
min_level: CRITICAL # only send critical alerts to this room
|
min_level: CRITICAL
|
||||||
|
|
||||||
sms_oncall:
|
sms_oncall:
|
||||||
type: sms_voipms
|
type: sms_voipms
|
||||||
api_user: me@example.com
|
api_user: me@example.com
|
||||||
api_password: secret
|
api_password: secret
|
||||||
did: "5551234567" # your voip.ms DID number
|
did: "5551234567"
|
||||||
dst: "5559876543" # destination number
|
dst: "5559876543"
|
||||||
min_level: CRITICAL
|
min_level: CRITICAL
|
||||||
|
|
||||||
signal_ops:
|
signal_ops:
|
||||||
@@ -82,9 +90,30 @@ notification_channels:
|
|||||||
username: heartbeat-bot
|
username: heartbeat-bot
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**User-created channels** are written by authenticated users through the API or their profile page. They carry an `owner` field and optionally `private: true`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
notification_channels:
|
||||||
|
|
||||||
|
alice_personal:
|
||||||
|
type: pushover
|
||||||
|
token: personal-token
|
||||||
|
user: personal-key
|
||||||
|
owner: alice # created by alice
|
||||||
|
private: true # only alice can see this channel
|
||||||
|
```
|
||||||
|
|
||||||
|
### Channel visibility
|
||||||
|
|
||||||
|
| Channel | Who can see / select it |
|
||||||
|
|---|---|
|
||||||
|
| No `private` field (or `private: false`) | All users |
|
||||||
|
| `private: true` | Only the `owner` |
|
||||||
|
| Any channel | Admins always see everything |
|
||||||
|
|
||||||
### Users with notification channels
|
### Users with notification channels
|
||||||
|
|
||||||
Each user lists which global channels they receive notifications on:
|
Each user lists which channels they receive notifications on. Users can manage their own selection from the profile page:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
users:
|
users:
|
||||||
@@ -270,6 +299,7 @@ Called once at startup from `main.py`. Pass the running asyncio event loop so Ma
|
|||||||
- Check that the host has an `owner` or `managers` set
|
- Check that the host has an `owner` or `managers` set
|
||||||
- Check that users have `notification_channels` listed
|
- Check that users have `notification_channels` listed
|
||||||
- Check that the channel names in user config match keys under `notification_channels:`
|
- Check that the channel names in user config match keys under `notification_channels:`
|
||||||
|
- If a user can't select a channel, check whether it is `private: true` and owned by someone else
|
||||||
|
|
||||||
**min_level filtering too aggressive:**
|
**min_level filtering too aggressive:**
|
||||||
- Default is `WARNING` — both WARNING and CRITICAL are sent
|
- Default is `WARNING` — both WARNING and CRITICAL are sent
|
||||||
|
|||||||
+27
-1
@@ -36,7 +36,7 @@ users:
|
|||||||
bob:
|
bob:
|
||||||
full_name: Bob Smith
|
full_name: Bob Smith
|
||||||
password: pbkdf2:sha256:...
|
password: pbkdf2:sha256:...
|
||||||
notification_channels: [pushover_standard]
|
notification_channels: [pushover_standard] # channels bob has selected
|
||||||
|
|
||||||
carol:
|
carol:
|
||||||
full_name: Carol Jones
|
full_name: Carol Jones
|
||||||
@@ -188,6 +188,32 @@ Return the currently authenticated user's profile.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
#### PUT /api/0/users/me
|
||||||
|
Update the current user's profile. All fields are optional — send only what you want to change.
|
||||||
|
|
||||||
|
**Update display name and avatar:**
|
||||||
|
```json
|
||||||
|
{ "full_name": "Carol Jones", "avatar": "/avatars/carol.png" }
|
||||||
|
```
|
||||||
|
|
||||||
|
**Change notification channel selection:**
|
||||||
|
```json
|
||||||
|
{ "notification_channels": ["pushover_ops", "email_ops"] }
|
||||||
|
```
|
||||||
|
Only channels visible to the user (public + own private) are accepted; others are silently dropped.
|
||||||
|
|
||||||
|
**Change password:**
|
||||||
|
```json
|
||||||
|
{ "password": { "current": "oldpass", "new": "newpass" } }
|
||||||
|
```
|
||||||
|
Requires the correct current password. New password is hashed before storage.
|
||||||
|
|
||||||
|
**Response:** `{"ok": true}`
|
||||||
|
|
||||||
|
**Status codes:** `200 OK`, `400` (missing/invalid field), `401` (unauthenticated), `403` (wrong current password)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Host Access
|
### Host Access
|
||||||
|
|
||||||
#### GET /api/0/hosts/{hostname}/access
|
#### GET /api/0/hosts/{hostname}/access
|
||||||
|
|||||||
Reference in New Issue
Block a user