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>
65 lines
3.1 KiB
C
65 lines
3.1 KiB
C
/* webui_store.h — SQLite-backed persistence for all web-UI-owned state:
|
|
* accounts, the category/tag taxonomy, and RSS feeds/rules/indexers.
|
|
*
|
|
* Owned entirely by the webui plugin (the daemon persists none of this).
|
|
* Account passwords are PBKDF2-HMAC-SHA256 with a per-user random salt. All
|
|
* calls are thread-safe (the store serializes access to its SQLite handle). */
|
|
#ifndef NAUT_WEBUI_STORE_H
|
|
#define NAUT_WEBUI_STORE_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <jansson.h>
|
|
|
|
typedef struct webui_store webui_store;
|
|
|
|
/* Open (creating if needed) the account database at `path`. Returns NULL on
|
|
* failure. The schema is created/migrated on open. */
|
|
webui_store *webui_store_open(const char *path);
|
|
void webui_store_close(webui_store *s);
|
|
|
|
/* Number of accounts, or -1 on error. */
|
|
int webui_store_user_count(webui_store *s);
|
|
/* Number of admin accounts, or -1 on error. */
|
|
int webui_store_admin_count(webui_store *s);
|
|
bool webui_store_user_exists(webui_store *s, const char *username);
|
|
|
|
/* Verify a username/password pair (constant-time). On success, copies the
|
|
* account's role ("admin"/"user") into role_out. */
|
|
bool webui_store_verify(webui_store *s, const char *username,
|
|
const char *password, char *role_out, size_t role_sz);
|
|
|
|
/* Create an account. `role` must be "admin" or "user" (defaults to "user" if
|
|
* NULL/invalid). Returns false if the username already exists or on error. */
|
|
bool webui_store_create_user(webui_store *s, const char *username,
|
|
const char *password, const char *role);
|
|
|
|
bool webui_store_set_password(webui_store *s, const char *username,
|
|
const char *password);
|
|
/* Change an account's role ("admin"/"user"). */
|
|
bool webui_store_set_role(webui_store *s, const char *username, const char *role);
|
|
bool webui_store_delete_user(webui_store *s, const char *username);
|
|
|
|
/* Append {username, role, createdAt} objects (sorted by username) to the
|
|
* json array `out`. Returns false on error. */
|
|
bool webui_store_list_users(webui_store *s, json_t *out);
|
|
|
|
/* --- category / tag taxonomy (web-UI organization, owned here) ------------- *
|
|
* The save_* calls replace the whole list atomically; the load_* calls append
|
|
* to the (array) `out`. Categories are {name, savePath}; tags are strings. */
|
|
bool webui_store_save_categories(webui_store *s, json_t *cats);
|
|
bool webui_store_load_categories(webui_store *s, json_t *out);
|
|
bool webui_store_save_tags(webui_store *s, json_t *tags);
|
|
bool webui_store_load_tags(webui_store *s, json_t *out);
|
|
|
|
/* --- RSS: feeds, auto-download rules, Torznab indexers (owned here) -------- *
|
|
* save_* replace the whole list atomically; load_* append to the array `out`,
|
|
* rebuilding the exact JSON shapes the web layer/UI use. */
|
|
bool webui_store_save_feeds(webui_store *s, json_t *feeds);
|
|
bool webui_store_load_feeds(webui_store *s, json_t *out);
|
|
bool webui_store_save_rules(webui_store *s, json_t *rules);
|
|
bool webui_store_load_rules(webui_store *s, json_t *out);
|
|
bool webui_store_save_indexers(webui_store *s, json_t *indexers);
|
|
bool webui_store_load_indexers(webui_store *s, json_t *out);
|
|
|
|
#endif /* NAUT_WEBUI_STORE_H */
|