Per-user auth via Nextcloud Login Flow v2, Tailwind UI rewrite
- auth.py/auth_routes.py: Login Flow v2 (verified against real NC source/docs) - no OAuth2 client registration needed, backend polls server-side so no CORS issues. Sessions are hashed-token cookies; NC app passwords encrypted at rest (Fernet). Every /api/* route guarded by a blueprint-wide before_request, not per-route decorators, so future routes are protected by default. - receipts/groups scoped per owner_nc_user_id; cross-user access 404s. - nc_client/cospend_client take (username, app_password) per call instead of one shared global credential - each user's uploads/shares/ bills now happen as themselves. - Frontend: LoginGate component drives the login flow (open NC login in a new tab, poll our backend, done). - Merged the old separate review step into the split screen, redesigned with Tailwind (was unstyled/broken), default-excluded-per-item splitting with one-click "include everyone" fixed, DD.MM.YYYY date field, receipt-icon branding. - Dropped LLM bounding-box highlighting - unreliable on real receipts, plain photo upload instead. - Only mention who a bill is split with in its title when there's more than one bill off the same receipt to disambiguate.
This commit is contained in:
+20
-1
@@ -1,5 +1,25 @@
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
nc_user_id TEXT PRIMARY KEY,
|
||||
-- Fernet-encrypted NC app password obtained via Login Flow v2. Never
|
||||
-- returned by any API response.
|
||||
nc_app_password_encrypted BLOB NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
last_login_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
-- SHA-256 hex digest of the actual session cookie value - never the raw
|
||||
-- token, so a DB read alone can't yield a usable session (same
|
||||
-- principle as password hashing).
|
||||
session_id_hash TEXT PRIMARY KEY,
|
||||
nc_user_id TEXT NOT NULL REFERENCES users(nc_user_id) ON DELETE CASCADE,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
expires_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS receipts (
|
||||
id TEXT PRIMARY KEY,
|
||||
owner_nc_user_id TEXT NOT NULL REFERENCES users(nc_user_id) ON DELETE CASCADE,
|
||||
image_path TEXT NOT NULL,
|
||||
image_width INTEGER,
|
||||
image_height INTEGER,
|
||||
@@ -14,7 +34,6 @@ CREATE TABLE IF NOT EXISTS receipts (
|
||||
CREATE TABLE IF NOT EXISTS groups (
|
||||
id TEXT PRIMARY KEY,
|
||||
receipt_id TEXT NOT NULL REFERENCES receipts(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
cospend_project_id TEXT NOT NULL,
|
||||
payer_member_id TEXT NOT NULL,
|
||||
member_ids_json TEXT NOT NULL, -- json list of cospend member ids (owers)
|
||||
|
||||
Reference in New Issue
Block a user