Enhance API documentation and improve marker functionality

- Updated API documentation for clarity and consistency, including detailed descriptions of authentication and user account endpoints.
- Added a new cave marker image to enhance visual representation in the frontend.
- Implemented normalization for cave marker images during upload to ensure consistent storage format.
- Expanded test coverage for client services, including new tests for marker uploads and image normalization.
This commit is contained in:
2026-03-04 16:57:43 +03:00
parent 40945c818b
commit 3968bdc76f
5 changed files with 883 additions and 846 deletions

View File

@@ -1,79 +1,79 @@
# HTTP API
The API is available under the `/map/api/` prefix. Requests requiring authentication use a `session` cookie (set on login).
## Authentication
- **POST /map/api/login** — sign in. Body: `{"user":"...","pass":"..."}`. On success returns JSON with user data and sets a session cookie. On first run, bootstrap is available: logging in as `admin` with the password from `HNHMAP_BOOTSTRAP_PASSWORD` creates the first admin user. For users created via OAuth (no password), returns 401 with `{"error":"Use OAuth to sign in"}`.
- **GET /map/api/me** — current user (by session). Response: `username`, `auths`, and optionally `tokens`, `prefix`, `email` (string, optional — for Gravatar and display).
- **POST /map/api/logout** — sign out (invalidates the session).
- **GET /map/api/setup** — check if initial setup is needed. Response: `{"setupRequired": true|false}`.
### OAuth
- **GET /map/api/oauth/providers** — list of configured OAuth providers. Response: `["google", ...]`.
- **GET /map/api/oauth/{provider}/login** — redirect to the provider's authorization page. Query: `redirect` — path to redirect to after successful login (e.g. `/profile`).
- **GET /map/api/oauth/{provider}/callback** — callback from the provider (called automatically). Exchanges the `code` for tokens, creates or finds the user, creates a session, and redirects to `/profile` or the `redirect` from state.
## User account
- **PATCH /map/api/me** — update current user. Body: `{"email": "..."}`. Used to set or change the user's email (for Gravatar and profile display). Requires a valid session.
- **POST /map/api/me/tokens** — generate a new upload token (requires `upload` permission). Response: `{"tokens": ["...", ...]}`.
- **POST /map/api/me/password** — change password. Body: `{"pass":"..."}`.
## Map data
- **GET /map/api/config** — client configuration (title, auths). Requires a session.
- **GET /map/api/v1/characters** — list of characters on the map (requires `map` permission; `markers` permission needed to see data). Each character object includes `ownedByMe` (boolean), which is true when the character was last updated by one of the current user's upload tokens.
- **GET /map/api/v1/markers** — markers (requires `map` permission; `markers` permission needed to see data).
- **GET /map/api/maps** — list of maps (filtered by permissions and hidden status). For non-admin users hidden maps are excluded; for admin, the response may include hidden maps (client should hide them in map selector if needed).
## Admin (all endpoints below require `admin` permission)
- **GET /map/api/admin/users** — list of usernames.
- **POST /map/api/admin/users** — create or update a user. Body: `{"user":"...","pass":"...","auths":["admin","map",...]}`.
- **GET /map/api/admin/users/:name** — user data.
- **DELETE /map/api/admin/users/:name** — delete a user.
- **GET /map/api/admin/settings** — settings (prefix, defaultHide, title).
- **POST /map/api/admin/settings** — save settings. Body: `{"prefix":"...","defaultHide":true|false,"title":"..."}` (all fields optional).
- **GET /map/api/admin/maps** — list of maps for the admin panel.
- **POST /map/api/admin/maps/:id** — update a map (name, hidden, priority).
- **POST /map/api/admin/maps/:id/toggle-hidden** — toggle map visibility.
- **POST /map/api/admin/wipe** — wipe grids, markers, tiles, and maps from the database.
- **POST /map/api/admin/rebuildZooms** — start rebuilding tile zoom levels from base tiles in the background. Returns **202 Accepted** immediately; the operation can take minutes when there are many grids. The client may poll **GET /map/api/admin/rebuildZooms/status** until `{"running": false}` and then refresh the map.
- **GET /map/api/admin/rebuildZooms/status** — returns `{"running": true|false}` indicating whether a rebuild started via POST rebuildZooms is still in progress.
- **GET /map/api/admin/export** — download data export (ZIP).
- **POST /map/api/admin/merge** — upload and apply a merge (ZIP with grids and markers).
- **GET /map/api/admin/wipeTile** — delete a tile. Query: `map`, `x`, `y`.
- **GET /map/api/admin/setCoords** — shift grid coordinates. Query: `map`, `fx`, `fy`, `tx`, `ty`.
- **GET /map/api/admin/hideMarker** — hide a marker. Query: `id`.
## Game client
The game client (e.g. Purus Pasta) communicates via `/client/{token}/...` endpoints using token-based authentication.
- **GET /client/{token}/checkVersion** — check client protocol version. Query: `version`. Returns 200 if matching, 400 otherwise.
- **GET /client/{token}/locate** — get grid coordinates. Query: `gridID`. Response: `mapid;x;y`.
- **POST /client/{token}/gridUpdate** — report visible grids and receive upload requests.
- **POST /client/{token}/gridUpload** — upload a tile image (multipart).
- **POST /client/{token}/positionUpdate** — update character positions.
- **POST /client/{token}/markerUpdate** — upload markers.
## SSE (Server-Sent Events)
- **GET /map/updates** — real-time tile and merge updates. Requires a session with `map` permission. Sends an initial `data:` message with an empty tile cache array `[]`, then incremental `data:` messages with tile cache updates and `event: merge` messages for map merges. The client requests tiles with `cache=0` when not yet in cache.
## Tile images
- **GET /map/grids/{mapid}/{zoom}/{x}_{y}.png** — tile image. Requires a session with `map` permission. Returns the tile image or a transparent 1×1 PNG if the tile does not exist.
## Response codes
- **200** — success.
- **400** — bad request (wrong method, body, or parameters).
- **401** — unauthorized (missing or invalid session).
- **403** — forbidden (insufficient permissions).
- **404** — not found.
- **500** — internal error.
Error format: JSON body `{"error": "message", "code": "CODE"}`.
# HTTP API
The API is available under the `/map/api/` prefix. Requests requiring authentication use a `session` cookie (set on login).
## Authentication
- **POST /map/api/login** — sign in. Body: `{"user":"...","pass":"..."}`. On success returns JSON with user data and sets a session cookie. On first run, bootstrap is available: logging in as `admin` with the password from `HNHMAP_BOOTSTRAP_PASSWORD` creates the first admin user. For users created via OAuth (no password), returns 401 with `{"error":"Use OAuth to sign in"}`.
- **GET /map/api/me** — current user (by session). Response: `username`, `auths`, and optionally `tokens`, `prefix`, `email` (string, optional — for Gravatar and display).
- **POST /map/api/logout** — sign out (invalidates the session).
- **GET /map/api/setup** — check if initial setup is needed. Response: `{"setupRequired": true|false}`.
### OAuth
- **GET /map/api/oauth/providers** — list of configured OAuth providers. Response: `["google", ...]`.
- **GET /map/api/oauth/{provider}/login** — redirect to the provider's authorization page. Query: `redirect` — path to redirect to after successful login (e.g. `/profile`).
- **GET /map/api/oauth/{provider}/callback** — callback from the provider (called automatically). Exchanges the `code` for tokens, creates or finds the user, creates a session, and redirects to `/profile` or the `redirect` from state.
## User account
- **PATCH /map/api/me** — update current user. Body: `{"email": "..."}`. Used to set or change the user's email (for Gravatar and profile display). Requires a valid session.
- **POST /map/api/me/tokens** — generate a new upload token (requires `upload` permission). Response: `{"tokens": ["...", ...]}`.
- **POST /map/api/me/password** — change password. Body: `{"pass":"..."}`.
## Map data
- **GET /map/api/config** — client configuration (title, auths). Requires a session.
- **GET /map/api/v1/characters** — list of characters on the map (requires `map` permission; `markers` permission needed to see data). Each character object includes `ownedByMe` (boolean), which is true when the character was last updated by one of the current user's upload tokens.
- **GET /map/api/v1/markers** — markers (requires `map` permission; `markers` permission needed to see data).
- **GET /map/api/maps** — list of maps (filtered by permissions and hidden status). For non-admin users hidden maps are excluded; for admin, the response may include hidden maps (client should hide them in map selector if needed).
## Admin (all endpoints below require `admin` permission)
- **GET /map/api/admin/users** — list of usernames.
- **POST /map/api/admin/users** — create or update a user. Body: `{"user":"...","pass":"...","auths":["admin","map",...]}`.
- **GET /map/api/admin/users/:name** — user data.
- **DELETE /map/api/admin/users/:name** — delete a user.
- **GET /map/api/admin/settings** — settings (prefix, defaultHide, title).
- **POST /map/api/admin/settings** — save settings. Body: `{"prefix":"...","defaultHide":true|false,"title":"..."}` (all fields optional).
- **GET /map/api/admin/maps** — list of maps for the admin panel.
- **POST /map/api/admin/maps/:id** — update a map (name, hidden, priority).
- **POST /map/api/admin/maps/:id/toggle-hidden** — toggle map visibility.
- **POST /map/api/admin/wipe** — wipe grids, markers, tiles, and maps from the database.
- **POST /map/api/admin/rebuildZooms** — start rebuilding tile zoom levels from base tiles in the background. Returns **202 Accepted** immediately; the operation can take minutes when there are many grids. The client may poll **GET /map/api/admin/rebuildZooms/status** until `{"running": false}` and then refresh the map.
- **GET /map/api/admin/rebuildZooms/status** — returns `{"running": true|false}` indicating whether a rebuild started via POST rebuildZooms is still in progress.
- **GET /map/api/admin/export** — download data export (ZIP).
- **POST /map/api/admin/merge** — upload and apply a merge (ZIP with grids and markers).
- **GET /map/api/admin/wipeTile** — delete a tile. Query: `map`, `x`, `y`.
- **GET /map/api/admin/setCoords** — shift grid coordinates. Query: `map`, `fx`, `fy`, `tx`, `ty`.
- **GET /map/api/admin/hideMarker** — hide a marker. Query: `id`.
## Game client
The game client (e.g. Purus Pasta) communicates via `/client/{token}/...` endpoints using token-based authentication.
- **GET /client/{token}/checkVersion** — check client protocol version. Query: `version`. Returns 200 if matching, 400 otherwise.
- **GET /client/{token}/locate** — get grid coordinates. Query: `gridID`. Response: `mapid;x;y`.
- **POST /client/{token}/gridUpdate** — report visible grids and receive upload requests.
- **POST /client/{token}/gridUpload** — upload a tile image (multipart).
- **POST /client/{token}/positionUpdate** — update character positions.
- **POST /client/{token}/markerUpdate** — upload markers.
## SSE (Server-Sent Events)
- **GET /map/updates** — real-time tile and merge updates. Requires a session with `map` permission. Sends an initial `data:` message with an empty tile cache array `[]`, then incremental `data:` messages with tile cache updates and `event: merge` messages for map merges. The client requests tiles with `cache=0` when not yet in cache.
## Tile images
- **GET /map/grids/{mapid}/{zoom}/{x}_{y}.png** — tile image. Requires a session with `map` permission. Returns the tile image or a transparent 1×1 PNG if the tile does not exist.
## Response codes
- **200** — success.
- **400** — bad request (wrong method, body, or parameters).
- **401** — unauthorized (missing or invalid session).
- **403** — forbidden (insufficient permissions).
- **404** — not found.
- **500** — internal error.
Error format: JSON body `{"error": "message", "code": "CODE"}`.