Files
cg_api_secure-webshare/docs/API.md

142 lines
6.4 KiB
Markdown

# HTTP API Reference
## Endpoints
### GET /api/health
- **Description:** Health check endpoint.
- **Auth:** None
- **Query params:** None
- **Response:** `{"status":"ok"}`
---
### GET /api/content/:cxid
- **Description:** Get content metadata (files, view limits, password status, etc.).
- **Auth:**
- None if the content has no password.
- Password required if the content has a password. Provide via query param `sc` **or** cookie `cgcx_pw`.
- **Path params:**
- `cxid` — Content ID string.
- **Query params:**
- `sc` (optional) — Password as a query string parameter.
- **Response formats:**
- `200 OK` — JSON metadata object:
```json
{
"cxid": "string",
"files": [
{
"idx": 0,
"name": "string",
"mime": "string",
"size": 12345,
"render_flags": 0
}
],
"has_password": true,
"max_views": 10,
"current_views": 3,
"allow_download": true,
"created_at": "2024-01-01T00:00:00+00:00",
"total_size": 1234567,
"author": {
"username": "@example",
"user_id": 123456789
}
}
```
- `401 Unauthorized` — Password required but missing or invalid.
- `404 Not Found` — Content does not exist or has been deleted/blacklisted.
- `410 Gone` — Content has reached its maximum view count.
- **Notes:**
- `total_size` is the sum of all file sizes in bytes.
- `author` is gated by the content's `show_author` flag. It is `null` when `show_author = false`, when the uploader's user record is missing, or when the user has no Telegram username (`username` may be `null` even when `user_id` is present).
- If authentication succeeds via the `sc` query parameter, the server sets an HMAC-signed `cgcx_pw` cookie on the response (`Max-Age=3600; SameSite=Strict; HttpOnly; Path=/`).
---
### GET /api/content/:cxid/file/:file_idx
- **Description:** Serve a decrypted file. Supports HTTP Range requests for video/audio streaming. Returns the file with `Content-Disposition: inline` by default, or `attachment` when downloading.
- **Auth:**
- None if the content has no password.
- Password required if the content has a password. Provide via query param `sc` **or** cookie `cgcx_pw`.
- **Path params:**
- `cxid` — Content ID string.
- `file_idx` — Zero-based file index within the content bundle.
- **Query params:**
- `sc` (optional) — Password as a query string parameter.
- `download` (optional) — If truthy (`1`, `true`, `yes`), requests a download (`Content-Disposition: attachment`). Ignored if `allow_download` is `false` for the content.
- **Response formats:**
- `200 OK` — File stream with appropriate `Content-Type`.
- `206 Partial Content` — Byte-range response (if `Range` header is present and valid).
- `401 Unauthorized` — Password required but missing or invalid.
- `403 Forbidden` — Download requested but not allowed, or path traversal blocked.
- `404 Not Found` — Content or file index does not exist, or content deleted/blacklisted.
- `410 Gone` — Content has reached its maximum view count.
- `416 Range Not Satisfiable` — Invalid `Range` header.
- **Notes:**
- The server increments the view counter on successful full-file responses. Range requests and `If-None-Match` (ETag) matches do **not** increment the counter.
- If the incremented view count reaches `max_views`, the server may delete content files (depending on `keep_content` config) and mark the content as `Deleted`, returning `410 Gone`.
- `Accept-Ranges: bytes` is included for `video/*` and `audio/*` MIME types.
- Cache-Control is `private, max-age=60` for unprotected content and `private, no-store, max-age=0` for password-protected content.
- If authentication succeeds via the `sc` query parameter, the server sets an HMAC-signed `cgcx_pw` cookie on the response.
---
### GET /api/content/:cxid/file/:file_idx/raw
- **Description:** Serve the fully decrypted file as raw plain text (`text/plain; charset=utf-8`). The entire file is decrypted into memory before being returned. No Range support.
- **Auth:**
- None if the content has no password.
- Password required if the content has a password. Provide via query param `sc` **or** cookie `cgcx_pw`.
- **Path params:**
- `cxid` — Content ID string.
- `file_idx` — Zero-based file index within the content bundle.
- **Query params:**
- `sc` (optional) — Password as a query string parameter.
- **Response formats:**
- `200 OK` — Plain text body.
- `401 Unauthorized` — Password required but missing or invalid.
- `403 Forbidden` — Path traversal blocked.
- `404 Not Found` — Content or file index does not exist, or content deleted/blacklisted.
- `410 Gone` — Content has reached its maximum view count.
- **Notes:**
- The server performs BLAKE3 integrity verification after full decryption.
- If authentication succeeds via the `sc` query parameter, the server sets an HMAC-signed `cgcx_pw` cookie on the response.
---
### POST /api/content/:cxid/verify-password
- **Description:** Explicitly verify a password for password-protected content and receive an authentication cookie.
- **Auth:** None (this is the endpoint used to *obtain* auth).
- **Path params:**
- `cxid` — Content ID string.
- **Body:** JSON object:
```json
{
"password": "string"
}
```
- **Response formats:**
- `204 No Content` — Password is correct. The response includes a `Set-Cookie` header with `cgcx_pw`.
- `401 Unauthorized` — Password is incorrect.
- `404 Not Found` — Content does not exist.
- **Notes:**
- If the content has no password, the endpoint returns `204 No Content` without setting a cookie.
- This endpoint has a separate, stricter rate limit than the general API.
---
## General Behavior
### CORS
The server allows cross-origin requests from its configured `base_url` and common local development origins (`http://127.0.0.1:5173`, `http://localhost:5173`, `http://127.0.0.1:8090`, `http://localhost:8090`).
### Rate Limiting
- General API routes (`/api/health`, `/api/content/...`) share a per-IP rate limit configured by `requests_per_minute` and `burst`.
- `POST /api/content/:cxid/verify-password` has its own rate limit with a burst of 3 and a separate `password_attempts_per_minute` setting.
### Fallback / Static Assets
- `/assets/*` — Serves static files from `frontend/dist/assets`.
- All other non-`/api` paths — Serves `frontend/dist/index.html` (SPA fallback).
- `/api/*` paths with no matching route — Return `404 Not Found` JSON.