update
This commit is contained in:
@@ -46,6 +46,7 @@ Created idempotently at boot in `getDb()` (no migration framework; keep it so).
|
||||
| `users` | `id, username UNIQUE, display_name, avatar_url, theme, email, key_hash, created_at`. The `admin` row is bootstrapped (its `key_hash` is unused — admin auth goes through `APP_PASSWORD`). |
|
||||
| `sessions` | `token_hash PK, user_id, created_at, expires_at`. Bearer tokens, 256-bit, hashed with sha256. Expired rows are purged lazily on access. |
|
||||
| `resets` | `token_hash PK, user_id, created_at, expires_at`. One-time key-recovery tokens (single use, consumed on POST). |
|
||||
| `settings` | `key PK, value, updated_at`. Admin-controlled feature flags (`registration_enabled` default off, `tools_ocr_enabled` default on). |
|
||||
| `conversations` | `id, user_id, title, topic, model, created_at, updated_at`. |
|
||||
| `messages` | `id AUTOINCREMENT, conv_id → conversations ON DELETE CASCADE, role, content, created_at`. |
|
||||
| `shares` | `conv_id PK → conversations ON DELETE CASCADE, public_id UNIQUE, created_at`. |
|
||||
@@ -58,6 +59,10 @@ conversations → sessions → user) inside a transaction.
|
||||
- `POST /api/auth/login { username, key }`, sliding-window rate limit per IP
|
||||
(`RATE_LIMIT_MAX` / `RATE_LIMIT_WINDOW_MIN`, default 5 per 10 min) + 400 ms
|
||||
delay on failure. Success clears the IP counter and issues a fresh token.
|
||||
- `POST /api/auth/register { username, displayName?, email? }` — public
|
||||
self-registration, guarded by the `registration_enabled` setting (403 when
|
||||
off), same rate limit and validation as admin creation. Returns `{user, key}`
|
||||
with the key shown once.
|
||||
- `admin` is authenticated against `APP_PASSWORD` (timing-safe); users against
|
||||
their `ka_…` access key (timing-safe against the stored hash).
|
||||
- Keys are generated with `crypto.randomBytes` (`ka_` + 24 bytes base64url) and
|
||||
@@ -93,7 +98,7 @@ only ever sees reviewed text blocks, never raw files.
|
||||
|
||||
## Drivers`src/drivers/`: `LLMDriver` interface (`listModels`, `chat`, `chatStream`),
|
||||
`DriverRegistry` with global priority
|
||||
`ollama → mistral → puppeteer-openai (stub) → deepseek → anthropic → openai`.
|
||||
`ollama → mistral → glm → puppeteer-openai (stub) → deepseek → anthropic → openai`.
|
||||
Models are addressed as `"driver:model"` (split on the first `:`).
|
||||
|
||||
- `OllamaDriver`: model discovery via `GET {OLLAMA_HOST}/api/tags`, chat via
|
||||
|
||||
+6
-1
@@ -43,7 +43,12 @@ read-only `SharePage` (no auth), everything else renders the authenticated app.
|
||||
copy, unshare), `SettingsModal` (display name, avatar upload box with
|
||||
drag & drop, avatar URL, theme).
|
||||
- `AdminPanel.tsx` — No-KYC account management: create (key shown once),
|
||||
regenerate (revokes sessions), edit, delete with confirm.
|
||||
regenerate (revokes sessions), edit, delete with confirm. Renders bare
|
||||
(no modal shell) when embedded in the Admin Center page.
|
||||
- `AdminCenter.tsx` — `/admin` route (admin gate + locked screen otherwise):
|
||||
tabbed hub (Accounts / Features / Mail) reusing `AdminPanel`, server
|
||||
feature `Switch`es (`registrationEnabled`, `ocrEnabled` via
|
||||
`/api/admin/settings`), SMTP status card. Follows the platform theme.
|
||||
- `SharePage.tsx` — public read-only view, fetches `/api/share/:id` unauthenticated.
|
||||
- `Markdown.tsx` — `react-markdown` + GFM; code blocks get a language label and
|
||||
a copy button.
|
||||
|
||||
+17
-1
@@ -24,7 +24,8 @@ Copy `.env.example` to `.env`. Full list:
|
||||
| `RESET_TTL_MIN` | `60` | reset-link lifetime (single use) |
|
||||
| `RATE_LIMIT_MAX` / `RATE_LIMIT_WINDOW_MIN` | `5` / `10` | login rate limit per IP |
|
||||
| `OLLAMA_HOST` / `OLLAMA_ENABLED` | `http://10.66.66.4:11434` / `true` | local-model driver |
|
||||
| `MISTRAL_*`, `DEEPSEEK_*`, `ANTHROPIC_*`, `OPENAI_*` | disabled | API drivers: set `*_ENABLED=true` **and** `*_API_KEY` |
|
||||
| `MISTRAL_*`, `GLM_*`, `DEEPSEEK_*`, `ANTHROPIC_*`, `OPENAI_*` | disabled | API drivers: set `*_ENABLED=true` **and** `*_API_KEY` |
|
||||
| `GLM_BASE_URL` | `https://api.z.ai/api/paas/v4` | Zhipu platform override (mainland China: `https://open.bigmodel.cn/api/paas/v4`) |
|
||||
|
||||
## Local development
|
||||
|
||||
@@ -51,6 +52,21 @@ unshare. See `AGENTS.md`.
|
||||
5. Rotate a compromised key with the regenerate button (old sessions die);
|
||||
delete removes the account with all its chats and shares.
|
||||
|
||||
## Admin Center (`/admin`) & self-registration
|
||||
|
||||
The sidebar **Admin Center** button (admin only) opens the `/admin` page with
|
||||
three tabs: **Accounts** (same manager as before, incl. the Ollama model
|
||||
catalog), **Features** (server-side switches), **Mail** (SMTP status).
|
||||
|
||||
- `registration_enabled` (default off): when on, the login page shows a
|
||||
working **Register** button — anyone can create an account (key shown once)
|
||||
via `POST /api/auth/register`. When off, the button is greyed with the
|
||||
tooltip *"Registration currently disabled on this platform"* and the
|
||||
endpoint answers 403. Flipped live, no restart.
|
||||
- `tools_ocr_enabled` (default on): admin kill-switch for the OCR tool.
|
||||
- Flags live in the `settings` SQLite table, edited via
|
||||
`GET/PATCH /api/admin/settings` (admin Bearer only).
|
||||
|
||||
## Key recovery via email (optional)
|
||||
|
||||
Set the `SMTP_*` vars (and the real public `APP_URL`) to enable it; otherwise
|
||||
|
||||
Reference in New Issue
Block a user