diff --git a/CLAUDE.md b/CLAUDE.md index 2d6eabc..5c0162b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -108,6 +108,7 @@ Without this, sessions and CSRF tokens are broken across the 4 Gunicorn workers. | `templates/login.html` | Standalone login page | Does NOT extend `base.html`; has its own `
` and no `app.js`; CSRF token must be a direct hidden input | | `templates/forgot_password.html` | Standalone forgot-password page | Same constraints as `login.html` — standalone, direct CSRF hidden input, no `app.js` | | `templates/reset_password.html` | Standalone reset-password page | Same constraints as `login.html` — standalone, direct CSRF hidden input, no `app.js` | +| `templates/profile.html` | User profile editor | Extends `base.html`; users can update `full_name` and `email`; username/role are read-only | --- @@ -121,6 +122,8 @@ Without this, sessions and CSRF tokens are broken across the 4 Gunicorn workers. - `@admin_required` — redirects to login or 403 if not admin - **Session fixation prevention** — `session.clear()` is called in `auth.login` immediately before setting `session["user"]` on successful authentication - **Keep-alive endpoint** — `GET /ping` (`routes/auth.py`, `@login_required`) touches `session.modified = True` and returns 204; called by the session-timeout warning in `app.js` +- **Password reset** — `POST /forgot-password` creates a 1-hour `password_reset_tokens` token and emails a link. `POST /reset-password/