Backend refactoring updates

- Update Docker compose debug configuration
- Update backend documentation
- Update tasks documentation
- Update backend config module

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-26 12:05:01 +02:00
parent 29daaa9906
commit f55c317f87
4 changed files with 22 additions and 36 deletions

View File

@@ -61,6 +61,9 @@ services:
BANGUI_LOG_LEVEL: "debug"
BANGUI_SESSION_SECRET: "${BANGUI_SESSION_SECRET:-dev-secret-do-not-use-in-production}"
BANGUI_TIMEZONE: "${BANGUI_TIMEZONE:-UTC}"
# Secure=false is intentional for local HTTP development.
# In production, Secure=true prevents session cookies over unencrypted HTTP.
BANGUI_SESSION_COOKIE_SECURE: "false"
volumes:
- ../backend/app:/app/app:z
- ../fail2ban-master:/app/fail2ban-master:ro,z

View File

@@ -506,6 +506,22 @@ class Settings(BaseSettings):
model_config = {"env_prefix": "BANGUI_", "env_file": ".env"}
```
### Session Cookie Security
The `session_cookie_secure` configuration controls the `Secure` flag on the session cookie. This flag prevents browsers from sending the session cookie over unencrypted HTTP.
**Default:** `true` — Production deployments are secure by default. Cookies are only sent over HTTPS.
**Local Development:** Set `BANGUI_SESSION_COOKIE_SECURE=false` in your compose file or `.env` to allow cookies over HTTP (required for `localhost:8000`).
```yaml
# Docker/compose.debug.yml
environment:
BANGUI_SESSION_COOKIE_SECURE: "false" # Allow HTTP during local development
```
**Important:** If `Secure=true` is set, browsers will reject the session cookie when the backend is served over HTTP. Ensure your nginx/reverse proxy terminates TLS and passes `X-Forwarded-Proto: https` so FastAPI knows the connection is secure.
---
## 13. Git & Workflow

View File

@@ -1,37 +1,3 @@
## TASK-004 — Frontend auth state bootstrapped from `sessionStorage`, not from the backend
**Severity:** Medium
### Where found
`frontend/src/providers/AuthProvider.tsx` line 64 — `useState(() => sessionStorage.getItem(IS_AUTHENTICATED_KEY) === "true")`.
### Why this is needed
On page load, the frontend sets `isAuthenticated = true` from a cached `sessionStorage` flag without contacting the backend. If the session cookie has expired server-side (e.g., server restart, session_duration elapsed), the user briefly sees the authenticated UI before the first API call triggers a 401. This also means that a user with a revoked session (manual DB deletion) appears logged in until they navigate.
### Goal
Validate session validity with the backend on mount so the UI state always reflects reality.
### What to do
1. Add a `GET /api/auth/session` endpoint (or reuse `GET /api/health` with auth) that returns 200 if the session is valid, 401 otherwise.
2. In `AuthProvider`, call this endpoint on mount. While the check is in flight, show a loading spinner or skeleton.
3. On 401, clear `sessionStorage` and set `isAuthenticated = false`, then redirect to `/login`.
4. Keep the `sessionStorage` flag as an optimistic hint to avoid flicker, but always confirm with the backend.
### Possible traps and issues
- Adds one round-trip on every page load — keep the endpoint extremely lightweight (no DB joins).
- Must handle the case where the backend is temporarily unreachable (network error) — do not log the user out in that case, only on an explicit 401.
- The loading state needs a spinner or skeleton so the UI doesn't flash between states.
### Docs changes needed
- `Features.md` — update the authentication flow description.
- `Web-Development.md` — document the mount-time session check pattern.
### Doc references
- [Features.md](Features.md) — authentication and session management
- [Web-Development.md](Web-Development.md) — AuthProvider pattern
---
## TASK-005 — `session_cookie_secure` defaults to `false`
**Severity:** Medium

View File

@@ -98,9 +98,10 @@ class Settings(BaseSettings):
),
)
session_cookie_secure: bool = Field(
default=False,
default=True,
description=(
"Set the session cookie Secure flag when the backend is served over HTTPS. "
"Defaults to True for security. Set to False only for local development over HTTP."
),
)
cors_allowed_origins: str | list[str] = Field(