settings: add nav visibility prefs and per-user Strava credentials
- user_prefs table in db.py with get/set helpers - GET/PUT /api/me/prefs endpoints for bulk pref management - GET/PUT/DELETE /api/me/strava-credentials; PUT preserves existing secret when client_secret field is left blank - _strava_creds() helper resolves per-user → instance fallback across all five Strava endpoints - Settings page: Navigation card (hide Feed/Community/About toggles) and Strava credentials card - Base.astro: ids on feed/community/about nav links; applies nav_hide_* prefs after login
This commit is contained in:
@@ -59,9 +59,17 @@ CREATE TABLE IF NOT EXISTS settings (
|
||||
value TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_prefs (
|
||||
handle TEXT NOT NULL REFERENCES users(handle) ON DELETE CASCADE,
|
||||
key TEXT NOT NULL,
|
||||
value TEXT NOT NULL,
|
||||
PRIMARY KEY (handle, key)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS sessions_handle ON sessions(handle);
|
||||
CREATE INDEX IF NOT EXISTS invites_created_by ON invites(created_by);
|
||||
CREATE INDEX IF NOT EXISTS reset_codes_handle ON reset_codes(handle);
|
||||
CREATE INDEX IF NOT EXISTS user_prefs_handle ON user_prefs(handle);
|
||||
"""
|
||||
|
||||
_SESSION_DAYS = 30
|
||||
@@ -361,6 +369,36 @@ def create_reset_code(db: sqlite3.Connection, handle: str, created_by: str) -> s
|
||||
return code
|
||||
|
||||
|
||||
# ── User preferences ─────────────────────────────────────────────────────────
|
||||
|
||||
def get_user_prefs(db: sqlite3.Connection, handle: str) -> dict[str, str]:
|
||||
"""Return all preferences for a user as a plain dict."""
|
||||
rows = db.execute(
|
||||
"SELECT key, value FROM user_prefs WHERE handle = ?", (handle,)
|
||||
).fetchall()
|
||||
return {r["key"]: r["value"] for r in rows}
|
||||
|
||||
|
||||
def set_user_pref(db: sqlite3.Connection, handle: str, key: str, value: str) -> None:
|
||||
db.execute(
|
||||
"INSERT INTO user_prefs (handle, key, value) VALUES (?, ?, ?) "
|
||||
"ON CONFLICT(handle, key) DO UPDATE SET value = excluded.value",
|
||||
(handle, key, value),
|
||||
)
|
||||
db.commit()
|
||||
|
||||
|
||||
def set_user_prefs(db: sqlite3.Connection, handle: str, prefs: dict[str, str]) -> None:
|
||||
"""Bulk-upsert multiple preferences for a user."""
|
||||
for key, value in prefs.items():
|
||||
db.execute(
|
||||
"INSERT INTO user_prefs (handle, key, value) VALUES (?, ?, ?) "
|
||||
"ON CONFLICT(handle, key) DO UPDATE SET value = excluded.value",
|
||||
(handle, key, value),
|
||||
)
|
||||
db.commit()
|
||||
|
||||
|
||||
def use_reset_code(db: sqlite3.Connection, code: str, handle: str) -> bool:
|
||||
"""Validate a reset code for the given handle and mark it used.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user