Add curator authentication with audit logging and fix empty 3D gallery sessions.
Introduce session-based curator login, gate debug/checkup routes, log mutations to curator_audit_log, and keep guest hall preload public. Fix gallery view mounting so WebGL halls render reliably after navigation.
This commit is contained in:
+69
-2
@@ -26,6 +26,66 @@ curl.exe -sk https://devgallery.mysuperlab.netcraze.pro/api/bounds
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
Anonymous visitors have implicit role **`user`** (browse only). **Curator** accounts unlock debug mode, the Checkup page, and all mutating audit routes.
|
||||
|
||||
Sessions use an HTTP-only cookie (`gallery.sid`). The client sends `credentials: 'include'` on API requests.
|
||||
|
||||
### `GET /api/auth/me`
|
||||
|
||||
**Response (anonymous)**
|
||||
|
||||
```json
|
||||
{ "role": "user" }
|
||||
```
|
||||
|
||||
**Response (curator session)**
|
||||
|
||||
```json
|
||||
{ "role": "curator", "username": "curator" }
|
||||
```
|
||||
|
||||
### `POST /api/auth/login`
|
||||
|
||||
**Body:** `{ "username": "curator", "password": "…" }`
|
||||
|
||||
**Response:** `{ "role": "curator", "username": "curator" }`
|
||||
|
||||
**Errors:** `401` invalid credentials, `400` missing fields.
|
||||
|
||||
### `POST /api/auth/logout`
|
||||
|
||||
Destroys the session cookie.
|
||||
|
||||
**Response:** `{ "ok": true }`
|
||||
|
||||
### Curator-only routes
|
||||
|
||||
These return **`401`** with `{ "error": "Curator login required" }` without a valid curator session:
|
||||
|
||||
| Route | Audit action (mutations only) |
|
||||
|-------|-------------------------------|
|
||||
| `GET /api/paintings/checkup` | — (read) |
|
||||
| `GET /api/paintings/:id/debug-image-search` (+ `/more`) | — |
|
||||
| `GET /api/artists/:id/debug-portrait-search` (+ `/more`) | — |
|
||||
| `GET /api/debug/image-proxy` | — |
|
||||
| `PATCH /api/paintings/:id/checkup-flags` | `painting.checkup_flags` |
|
||||
| `PATCH /api/artists/:id/checkup-flags` | `artist.checkup_flags` |
|
||||
| `POST /api/paintings/:id/fix-image` | `painting.fix_image` |
|
||||
| `POST /api/paintings/:id/clear-image` | `painting.clear_image` |
|
||||
| `POST /api/paintings/:id/upload-image` | `painting.upload_image` |
|
||||
| `DELETE /api/paintings/:id` | `painting.delete` |
|
||||
| `POST /api/artists/:id/fix-portrait` | `artist.fix_portrait` |
|
||||
| `POST /api/artists/:id/clear-portrait` | `artist.clear_portrait` |
|
||||
| `POST /api/artists/:id/upload-portrait` | `artist.upload_portrait` |
|
||||
|
||||
**Public** (no login): all catalog `GET` routes, `POST /api/artists/:id/preload-images` (local file linking for 3D halls), `/images`, SPA static.
|
||||
|
||||
Curator mutations are recorded in `curator_audit_log` (see [DB_structure.md](DB_structure.md)).
|
||||
|
||||
---
|
||||
|
||||
## `GET /api/bounds`
|
||||
|
||||
Returns the overall timeline year range used to initialise the zoomable timeline.
|
||||
@@ -316,7 +376,9 @@ Both lists are grouped by art movement and exclude the current artist. Each arti
|
||||
|
||||
## `POST /api/artists/:id/preload-images`
|
||||
|
||||
Fast local scan: links paintings to files already on disk. Does **not** download from the internet (safe to call before opening the 3D gallery).
|
||||
**Public** — no curator login required.
|
||||
|
||||
Fast local scan: links paintings to files already on disk. Does **not** download from the internet. The 3D client calls this automatically when entering an **artist** hall.
|
||||
|
||||
**Response**
|
||||
|
||||
@@ -398,6 +460,8 @@ Returns the image bytes with `Cache-Control: public, max-age=86400`, or `404` if
|
||||
|
||||
## Developer image audit
|
||||
|
||||
**Curator login required** for every route in this section. See [Authentication](#authentication) above.
|
||||
|
||||
Routes for the **Checkup** page and **Debug mode** on painting detail and artist bio. Register `GET /api/paintings/checkup` **before** `GET /api/paintings/:id` so `"checkup"` is not parsed as a painting id.
|
||||
|
||||
### `GET /api/paintings/checkup`
|
||||
@@ -590,10 +654,13 @@ Returns image bytes with appropriate `Content-Type`.
|
||||
|
||||
## Frontend helpers
|
||||
|
||||
The React client wraps these endpoints in `client/src/api/client.ts`:
|
||||
The React client wraps these endpoints in `client/src/api/client.ts`. All requests send `credentials: 'include'` for session cookies.
|
||||
|
||||
| Function | Maps to |
|
||||
|----------|---------|
|
||||
| `getAuthMe()` | `GET /api/auth/me` |
|
||||
| `loginCurator(user, pass)` | `POST /api/auth/login` |
|
||||
| `logoutCurator()` | `POST /api/auth/logout` |
|
||||
| `api.getBounds()` | `GET /api/bounds` |
|
||||
| `api.getTimeline(start, end)` | `GET /api/timeline` |
|
||||
| `api.getArtists(...)` | `GET /api/artists` |
|
||||
|
||||
Reference in New Issue
Block a user