Fix ntfy bearer token usage
This commit is contained in:
parent
a7ab445281
commit
0c2cc6b081
4 changed files with 9 additions and 20 deletions
|
|
@ -37,7 +37,7 @@ A web app that visualizes DMR repeaters on an interactive map. Filter by band an
|
|||
| [BrandMeister WebSocket](https://wiki.brandmeister.network/index.php/API/Last_Heard) | Real-time Last Heard feed for heatmap via socket.io | None |
|
||||
| [Nominatim](https://nominatim.openstreetmap.org) | Address geocoding and autocomplete (client-side) | None |
|
||||
| [OSRM](https://project-osrm.org) | Driving route calculation (client-side) | None |
|
||||
| [ntfy](https://ntfy.sh) | Push notification when a user report is submitted (optional) | Access token (bearer or basic auth) |
|
||||
| [ntfy](https://ntfy.sh) | Push notification when a user report is submitted (optional) | Access token (bearer) |
|
||||
|
||||
The BrandMeister talk group registry is fetched once at Docker build time and bundled as `frontend/static/talkgroups.json`. It is used for talk group name resolution and autocomplete in CPS Studio.
|
||||
|
||||
|
|
@ -79,8 +79,7 @@ docker compose -f compose.test.yml run --rm test
|
|||
| `ADMIN_TOKEN` | *(disabled)* | Set to enable the admin interface at `/admin/` |
|
||||
| `NTFY_URL` | *(disabled)* | ntfy server base URL (e.g. `https://ntfy.example.com`). Together with `NTFY_TOPIC` it enables push notifications for new user reports |
|
||||
| `NTFY_TOPIC` | *(disabled)* | ntfy topic that report notifications are published to |
|
||||
| `NTFY_USER` | *(none)* | ntfy username. When set, the token is sent as HTTP basic auth (`user:token`) |
|
||||
| `NTFY_TOKEN` | *(none)* | ntfy access token. Sent as `Authorization: Bearer` when no username is set |
|
||||
| `NTFY_TOKEN` | *(none)* | ntfy access token, sent as `Authorization: Bearer`. Required for protected topics |
|
||||
| `PUBLIC_BASE_URL` | *(none)* | Public base URL of the site (e.g. `https://dmrmap.de`). Used to add a click-through link to the admin view in ntfy notifications |
|
||||
|
||||
Both `NTFY_URL` and `NTFY_TOPIC` must be set for notifications; otherwise reports are stored but nothing is pushed. On startup the app logs either `ntfy notifications enabled: <topic URL> (auth: ...)` or `ntfy notifications disabled`. The **Test push** button in the admin Reports view publishes a test notification and shows the upstream error if it fails.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
|
|
@ -14,14 +13,13 @@ import (
|
|||
// required environment variables are not set, in which case notify is a no-op.
|
||||
type ntfyNotifier struct {
|
||||
url string // full topic URL, e.g. https://ntfy.example.com/dmrmap
|
||||
user string
|
||||
token string
|
||||
clickBase string
|
||||
httpClient *http.Client
|
||||
}
|
||||
|
||||
// newNtfyNotifierFromEnv builds a notifier from NTFY_URL / NTFY_TOPIC /
|
||||
// NTFY_USER / NTFY_TOKEN. Returns nil when notifications are not configured.
|
||||
// NTFY_TOKEN. Returns nil when notifications are not configured.
|
||||
func newNtfyNotifierFromEnv() *ntfyNotifier {
|
||||
base := strings.TrimSpace(os.Getenv("NTFY_URL"))
|
||||
topic := strings.TrimSpace(os.Getenv("NTFY_TOPIC"))
|
||||
|
|
@ -32,17 +30,14 @@ func newNtfyNotifierFromEnv() *ntfyNotifier {
|
|||
|
||||
n := &ntfyNotifier{
|
||||
url: strings.TrimRight(base, "/") + "/" + strings.TrimLeft(topic, "/"),
|
||||
user: strings.TrimSpace(os.Getenv("NTFY_USER")),
|
||||
token: strings.TrimSpace(os.Getenv("NTFY_TOKEN")),
|
||||
clickBase: strings.TrimRight(strings.TrimSpace(os.Getenv("PUBLIC_BASE_URL")), "/"),
|
||||
httpClient: &http.Client{Timeout: 10 * time.Second},
|
||||
}
|
||||
|
||||
auth := "none"
|
||||
if n.user != "" && n.token != "" {
|
||||
auth = "basic (" + n.user + ")"
|
||||
} else if n.token != "" {
|
||||
auth = "bearer token"
|
||||
if n.token != "" {
|
||||
auth = "access token"
|
||||
}
|
||||
log.Printf("ntfy notifications enabled: %s (auth: %s)", n.url, auth)
|
||||
|
||||
|
|
@ -110,14 +105,11 @@ func (n *ntfyNotifier) send(rep UserReport) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// setAuth uses basic auth when a username is configured (ntfy accepts an
|
||||
// access token as the password), and bearer auth for a token on its own.
|
||||
// setAuth applies the ntfy access token. It is a bearer credential: ntfy does
|
||||
// NOT accept it as the password half of a username:password pair (that yields
|
||||
// HTTP 401), only as a bearer token or as basic auth with an empty username.
|
||||
func (n *ntfyNotifier) setAuth(req *http.Request) {
|
||||
switch {
|
||||
case n.user != "" && n.token != "":
|
||||
creds := base64.StdEncoding.EncodeToString([]byte(n.user + ":" + n.token))
|
||||
req.Header.Set("Authorization", "Basic "+creds)
|
||||
case n.token != "":
|
||||
if n.token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+n.token)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ services:
|
|||
- MIGRATIONS_DIR=/app/backend/migrations
|
||||
- NTFY_URL=${NTFY_URL:-}
|
||||
- NTFY_TOPIC=${NTFY_TOPIC:-}
|
||||
- NTFY_USER=${NTFY_USER:-}
|
||||
- NTFY_TOKEN=${NTFY_TOKEN:-}
|
||||
- PUBLIC_BASE_URL=${PUBLIC_BASE_URL:-http://localhost:8080}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ services:
|
|||
- ADMIN_TOKEN=${ADMIN_TOKEN:-}
|
||||
- NTFY_URL=${NTFY_URL:-}
|
||||
- NTFY_TOPIC=${NTFY_TOPIC:-}
|
||||
- NTFY_USER=${NTFY_USER:-}
|
||||
- NTFY_TOKEN=${NTFY_TOKEN:-}
|
||||
- PUBLIC_BASE_URL=${PUBLIC_BASE_URL:-}
|
||||
restart: unless-stopped
|
||||
|
|
|
|||
Loading…
Reference in a new issue