# retoor from fastapi import APIRouter, Request from molodetz.database import create_session, end_session, get_int_setting, get_user_by_email, get_user_by_username from molodetz.dependencies import json_or_form from molodetz.models import LoginForm from molodetz.responses import action_result, json_error, respond, wants_json from molodetz.schemas.account import LoginPageOut from molodetz.seo import base_seo_context from molodetz.templating import templates from molodetz.utils.audit import record from molodetz.utils.auth import get_current_user, invalidate_user_cache, is_account_active, verify_password_async from molodetz.utils.request_meta import is_secure_request, safe_next router = APIRouter() def _seo(request): return base_seo_context(request, "Inloggen", robots="noindex,nofollow") @router.get("/login") async def login_page(request: Request): next_url = safe_next(request.query_params.get("next"), "/admin") return respond(request, "auth/login.html", {"errors": [], "form": {}, "next": next_url, "seo": _seo(request)}, model=LoginPageOut) @router.post("/login") async def login_submit(request: Request): data = await json_or_form(request, LoginForm) user = get_user_by_username(data.username) or get_user_by_email(data.username.lower()) valid = user is not None and is_account_active(user) and await verify_password_async(data.password, user.get("password_hash")) if not valid: record(request, "auth.login.failed", result="denied", payload={"username": data.username[:64]}) ctx = { "errors": ["Onbekende combinatie van naam en wachtwoord."], "form": {"username": data.username}, "next": data.next, "seo": _seo(request), } if wants_json(request): return json_error(401, "Invalid credentials") return templates.TemplateResponse(request, "auth/login.html", ctx, status_code=400) days = get_int_setting("session_remember_days", 30) if data.remember else get_int_setting("session_max_age_days", 7) max_age = max(1, days) * 86400 token = create_session(user["uid"], max_age) record(request, "auth.login", targets=[("user", user["uid"])], user=user) response = action_result(request, safe_next(data.next, "/admin")) response.set_cookie( key="session", value=token, max_age=max_age, httponly=True, samesite="lax", secure=is_secure_request(request), ) return response @router.post("/logout") async def logout(request: Request): user = get_current_user(request) token = request.cookies.get("session") if token: end_session(token, user["uid"] if user else "guest") invalidate_user_cache(propagate=True) record(request, "auth.logout", user=user) response = action_result(request, "/") response.delete_cookie("session") return response