Sessions lived in an in-memory array, so every daemon restart wiped them
and forced a re-login. Move them into the webui DB:
- New sessions table storing a SHA-256 of the bearer token (never the
raw token, so a DB read can't be replayed), the user, role, and an
absolute expiry.
- create/lookup/touch/delete + per-user delete + prune in webui_store.
- Login persists the session; auth checks validate against the DB with a
throttled sliding expiry (re-extended at most hourly to avoid a write
per request); logout and admin reset/delete drop the rows. Expired
rows are reaped lazily on lookup and pruned at startup.
- TTL is configurable via NAUT_SESSION_TTL (default 7 days) and drives
the cookie Max-Age. Removes the in-memory session array + auth_lock.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the JSON-blob columns (feeds.articles, rules.affected_feeds)
with proper relational tables:
- articles(feed,key,…,is_read,grabbed) with UNIQUE(feed,key) and indexes,
so dedup and grabbed become INSERT OR IGNORE / WHERE-key queries and a
poll inserts only new rows instead of rewriting the whole feed blob.
- rule_feeds(rule,feed) join table for a rule's feed scope.
The webui RSS engine now operates on rows via a row-level store API
(feed/article/rule/indexer upsert/list/etc.) instead of holding the
feeds/rules/indexers in memory and saving whole lists; the in-memory
copies and rss_save/rss_load are gone. The poller, the auto-download
rules, force-run, manual download, refresh and search all read/write the
DB directly. A one-time migration upgrades an existing webui.db in place
(moving the old JSON blobs into the new tables, preserving article
read/grabbed flags and rule scoping, then dropping the legacy columns).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move RSS persistence out of the daemon blob store and into the webui's
own SQLite DB (feeds, rules, indexers tables; articles + affectedFeeds
held as JSON columns). Remove the now-unused daemon blob store
(set/get_webui_blob, blob_lock, data_dir).
With this, all webui-owned state — accounts, taxonomy, RSS — lives in
the webui DB; the daemon only keeps naut's own data (per-torrent labels
still flow through set_labels for Lua).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the category + tag lists out of the daemon (labels.json + the
get/set_label_taxonomy RPCs) and into the webui's own SQLite DB
(categories, tags tables). The daemon no longer persists webui taxonomy;
per-torrent labels still flow through set_labels for Lua.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The plugin's SQLite store will own more than accounts (taxonomy, RSS),
so give it a general name. Mechanical rename of files + symbols; default
DB filename is now webui.db. No behavior change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>