docs: release notes for v3.14.0 (#2143)

Release notes and the CHANGELOG entry for v3.14.0. The release workflow
reads `docs/release-notes/v3.14.0.md` from the tagged commit as the
release body, so this lands before the tag.

23 commits since v3.13.1: 13 fix, 8 feat, 1 ci, and this docs commit.
The headline is optional user accounts (#2128). "Read this before
upgrading" covers the new limits on unauthenticated endpoints, the
`traffic_share_score` drop (#2117), the region filter window (#2114) and
the config file mode (#2126).

After merge: tag this commit as `v3.14.0` once its `:edge` image is
built, then dispatch the CI/CD pipeline on the tag.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
efiten
2026-10-08 23:19:04 +02:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 57395e2b28
commit 9dbc287579
2 changed files with 129 additions and 0 deletions
+12
View File
@@ -2,6 +2,18 @@
## [Unreleased]
## [3.14.0] - 2026-10-08
See [docs/release-notes/v3.14.0.md](docs/release-notes/v3.14.0.md) for the full notes. 23 commits since v3.13.1: 13 fix, 8 feat, 1 ci, 1 docs.
### Highlights
- **Optional user accounts, off by default** (#2129, #2130, #2138 to #2141) - accounts and roles, settings sync across devices, an admin area with an audit log, hashtag channel proposals with admin approval, mail notifications for watched nodes, data export and daily `users.db` backups. Setup: `docs/user-guide/accounts.md`.
- **New limits on unauthenticated endpoints** (#2119, #2120, #2122, #2123, #2127) - requests above them now get 400 or 429 instead of an answer. **Operator awareness required** for API clients that send long `nodes=` lists.
- **`traffic_share_score` drops after the upgrade and no longer drifts with uptime** (#2117).
- **Regional `/api/nodes` queries no longer exhaust the database pool** (#2114, #2115) - 154.8 s to 37 ms for an uncached region set.
No manual migration step. With user management off, no new file or table is created.
## [3.13.1] - 2026-10-04
See [docs/release-notes/v3.13.1.md](docs/release-notes/v3.13.1.md) for the full notes. 1 commit since v3.13.0: 1 fix.
+117
View File
@@ -0,0 +1,117 @@
# v3.14.0
23 commits since v3.13.1: 13 fix, 8 feat, 1 ci, 1 docs (these notes). Eight feats and no breaking change, so minor.
The headline is optional user accounts (#2128). They are off by default: without a
`userManagement` block in `config.json`, nothing in this section changes anything.
## Read this before upgrading
These change what a running instance does without being asked.
- **Limits on unauthenticated endpoints.** Requests above them now get an error instead
of an answer:
- `GET /api/packets?nodes=` takes at most 50 entries and answers 400 above that
(#2120). 12,000 entries took 1.3 s per request under the store's read lock.
- `POST /api/decode` and `POST /api/packets/observations` cap the request body
(#2119). One 100 MB request raised the process's memory on a test instance.
- `GET /api/nodes/{pubkey}/reach` runs at most 2 cold scans at once and answers 429
with `Retry-After: 5` beyond that (#2127). Cached answers are not affected.
- The ingestor truncates observer ids, names and other status fields to 128
characters and IATA codes to 16, and strips control characters (#2123). The
`/neighbors` report only accepts 64-hex pubkeys and a scope list of up to 256
bytes (#2122).
- **`traffic_share_score` drops after the upgrade** (#2117). The score counted a
transmission once per observation through a relay, so it grew with uptime until many
relays sat at 1.0. It now counts distinct transmissions. Expect lower values; they no
longer drift.
- **The `/api/nodes` region filter covers the packet store's window** (#2114), the same
window the rest of the UI shows, instead of all database history. A node heard in a
region only before that window no longer matches.
- **The geo-filter save keeps `config.json`'s file mode** (#2126). A 0600 config stayed
0600 only until the first save; now it stays 0600.
## Optional user accounts
Turn them on with a `userManagement` block. Setup and every option are in
[`docs/user-guide/accounts.md`](https://github.com/Kpa-clawbot/CoreScope/blob/master/docs/user-guide/accounts.md).
Accounts live in a separate `users.db`; the server still opens the analyzer database
read-only.
- **Accounts and roles** (#2129). Register with an email address, activate through a
mailed link that also sets the password, log in. Roles `user` and `admin`. Admins
manage users and use the operator actions (geo-filter, backup, perf reset) without
the shared API key. Mail goes through Brevo, with delivery status.
- **Settings sync** (#2130). A logged-in user's own nodes, favorites, theme,
customizer settings and filters follow them to every device. Private channel keys
and decrypted messages are never synced.
- **Admin area** (#2138). `#/admin` with an overview of what needs attention (stuck
activations, bouncing mail, password guessing, a dropped MQTT source), the user
table, and an audit log that now records logins.
- **Hashtag channel proposals** (#2139, closes #2092). Logged-in users propose a
channel; after an admin approves it, the ingestor decrypts it without a restart and
it is listed for everyone. Opt in with `userManagement.channelProposals`. Every
approved key is tried on each GRP_TXT no key opens: 204 to 216 µs per packet with
320 keys, 272 to 320 µs with 128 approved keys added.
- **Mail notifications for watched nodes** (#2140). "Notify me" on a node page sends
one mail when that node goes offline, comes back or reports a low battery, using the
thresholds the node page uses. Admins can add new foreign nodes and observers going
offline. Bundled per user, 20 mails per user and 100 per instance per rolling 24
hours, one-click unsubscribe. Opt in with `userManagement.notifications`.
- **Data export and users.db backup** (#2141). "Download my data" gives a user one
JSON file with everything stored about their account, credentials excluded. The
server keeps daily `users.db` snapshots (7 by default) and admins can download one.
## Fixes
- **Regional `/api/nodes` queries no longer exhaust the database pool** (#2114, closes
#2101). A regional node count took 154.8 s on a 10.3 GB database and tied up the
readers. The region set now comes from the packet store: 37 ms uncached in the
benchmark, then cached for 30 s. A follow-up matches observers by id, so a changed
observer region applies at once (#2115).
- **Escaping**: observer IATA, name and id and node names in eight render sinks
(#2118), and the route string on the unknown-route page (#2124).
- **CDN scripts are pinned with integrity hashes** (#2121): `chart.js@4.5.1`,
`leaflet.heat@0.2.0`, `swagger-ui-dist@5.33.1`.
## Interface
- **Path hash size on each channel message** (#2089): `1-byte`, `2-bytes` or `3-bytes`
before the scope chip.
- **RF noise-floor layer on the Mobile RX coverage page** (#2113), for instances with
`clientRfSamples` enabled.
- **Node details explain the packet and observation counts** (#2132, closes #2131).
## CI
- **Tests and the image build run side by side** (#2135, closes #2134). Only the GHCR
push waits for all of them, and E2E runs in 3 shards.
## Issues closed
- #2092 Feature proposal: user-suggested shared hashtag channels with admin approval and revoke
- #2101 bug: Regional /api/nodes queries exhaust the SQLite connection pool
- #2128 No user accounts: settings are tied to one browser and operator actions to a shared API key
- #2131 ui(nodes): explain transmission and observation counts in node details
- #2134 CI takes ~30 min because every job waits for the previous one
#2092 and #2128 were closed by hand after their pull requests merged; the others
through the pull request.
## Contributors
Pull request authors: @efiten (11), @nullrouten0 (9), @dborup (1), @n30nex (1),
@sylr (1).
Issue reporters: @efiten (2), @dborup (1), @mannkind (1), @n30nex (1).
No co-authors other than tooling are credited in the commits.
## Upgrade notes
- No manual migration step. With user management off, no new file or table is created.
- With user management on, `users.db` is created next to the analyzer database (or at
`userManagement.dbPath`) and migrated at startup; `backups/` is created next to it.
- `channelProposals` and `notifications` are opt-in under `userManagement`; the backup
is on by default when user management is on and can be turned off with
`userManagement.backup.enabled: false`.