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:
@@ -0,0 +1,54 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from flask import Blueprint, jsonify, request
|
||||
|
||||
from . import auth
|
||||
from .config import Config
|
||||
|
||||
bp = Blueprint("auth", __name__)
|
||||
|
||||
|
||||
@bp.post("/login/start")
|
||||
def login_start():
|
||||
try:
|
||||
result = auth.start_login_flow()
|
||||
except Exception as exc: # noqa: BLE001
|
||||
return jsonify(error=f"could not start login: {exc}"), 502
|
||||
return jsonify(result)
|
||||
|
||||
|
||||
@bp.get("/login/poll")
|
||||
def login_poll():
|
||||
flow_id = request.args.get("flow_id", "")
|
||||
if not flow_id:
|
||||
return jsonify(error="flow_id is required"), 400
|
||||
|
||||
try:
|
||||
result = auth.poll_login_flow(flow_id)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
return jsonify(error=f"login poll failed: {exc}"), 502
|
||||
|
||||
if result["status"] != "done":
|
||||
return jsonify(status=result["status"])
|
||||
|
||||
resp = jsonify(status="done", nc_user_id=result["nc_user_id"])
|
||||
resp.set_cookie(
|
||||
Config.SESSION_COOKIE_NAME,
|
||||
result["session_id"],
|
||||
max_age=Config.SESSION_TTL_DAYS * 24 * 3600,
|
||||
httponly=True,
|
||||
secure=Config.SESSION_COOKIE_SECURE,
|
||||
samesite="Lax",
|
||||
path="/",
|
||||
)
|
||||
return resp
|
||||
|
||||
|
||||
@bp.post("/logout")
|
||||
def logout():
|
||||
session_id = request.cookies.get(Config.SESSION_COOKIE_NAME)
|
||||
if session_id:
|
||||
auth.destroy_session(session_id)
|
||||
resp = jsonify(status="ok")
|
||||
resp.delete_cookie(Config.SESSION_COOKIE_NAME, path="/")
|
||||
return resp
|
||||
Reference in New Issue
Block a user