SurfSense/surfsense_backend/app/auth/session_cookies.py
2026-06-23 12:49:22 +05:30

89 lines
2.4 KiB
Python

"""Centralized session-cookie I/O for web authentication."""
from __future__ import annotations
from datetime import UTC, datetime, timedelta
from typing import Any
from fastapi import Request, Response
from app.config import config
def _cookie_secure(request: Request | None = None) -> bool:
policy = config.SESSION_COOKIE_SECURE_POLICY
if policy == "always":
return True
if policy == "never":
return False
if request is not None:
proto = request.headers.get("x-forwarded-proto")
if proto:
return proto.split(",", 1)[0].strip().lower() == "https"
return request.url.scheme == "https"
return bool(config.BACKEND_URL and config.BACKEND_URL.startswith("https://"))
def _set_persistent_cookie(
response: Response,
*,
key: str,
value: str,
max_age: int,
request: Request | None,
) -> None:
expires = datetime.now(UTC) + timedelta(seconds=max_age)
response.set_cookie(
key=key,
value=value,
max_age=max_age,
expires=expires,
httponly=True,
secure=_cookie_secure(request),
samesite=config.SESSION_COOKIE_SAMESITE,
domain=config.COOKIE_DOMAIN,
path="/",
)
def write_session(
response: Response,
access: str,
refresh: str,
request: Request | None = None,
) -> None:
_set_persistent_cookie(
response,
key=config.SESSION_COOKIE_NAME,
value=access,
max_age=config.ACCESS_TOKEN_LIFETIME_SECONDS,
request=request,
)
_set_persistent_cookie(
response,
key=config.REFRESH_COOKIE_NAME,
value=refresh,
max_age=config.REFRESH_TOKEN_LIFETIME_SECONDS,
request=request,
)
def clear_session(response: Response, request: Request | None = None) -> None:
for key in (config.SESSION_COOKIE_NAME, config.REFRESH_COOKIE_NAME):
response.delete_cookie(
key=key,
path="/",
domain=config.COOKIE_DOMAIN,
secure=_cookie_secure(request),
samesite=config.SESSION_COOKIE_SAMESITE,
httponly=True,
)
def read_refresh(request: Request, body: Any | None = None) -> str | None:
cookie = request.cookies.get(config.REFRESH_COOKIE_NAME)
if cookie:
return cookie
if body is None:
return None
return getattr(body, "refresh_token", None)