V0.1.1 release, close to actual release. Bug & security fixes/improvements.

This commit is contained in:
unknown
2026-05-24 19:29:41 +02:00
parent a7b44af91a
commit b004e15948
38 changed files with 3145 additions and 137 deletions

102
AI_MASTER_PLAN.md Normal file
View File

@@ -0,0 +1,102 @@
# AI Master Plan — cg.cx Refinement Pass
## 1. Current Repo Understanding
### Architecture
- **10-crate Rust workspace** (`cgcx-core`, `cgcx-config`, `cgcx-crypto`, `cgcx-db`, `cgcx-storage`, `cgcx-content-typing`, `cgcx-file-pipeline`, `cgcx-moderation`, `cgcx-bot`, `cgcx-server`)
- **SQLite** database with WAL mode, 7 migrations already applied (`001_init` through `007_hash_blacklist`)
- **Svelte 5** SPA frontend (`frontend/`), Vite build, served as static files by Axum fallback
- **Teloxide** bot (standalone binary) + **Axum** server (standalone binary), both share DB and config
- Content encrypted with XChaCha20-Poly1305, per-file CEKs wrapped with AES-KW under a master key
- BLAKE3 plaintext hashes stored for deduplication and hash-blacklist enforcement
### Already Implemented (verified in code)
| Task | Status | Location |
|------|--------|----------|
| D — GLOBAL_BAN config | ✅ | `config/default.toml` `[groups] global_ban`; `propagate_punishment()` in bot |
| F — Approval message with media batches | ✅ | `handle_forward_callback` "approve" — decrypts files, batches up to 10, appends caption to last batch |
| G — Review group media | ✅ | `finalize_upload` — decrypts and sends media batches to review group, appends review text to last batch |
| H — Review buttons (Ban, Blackl., Ban/BL u.) | ✅ | Inline keyboard in `finalize_upload` and handlers in `handle_forward_callback` |
| K — Show/Hide Author toggle | ✅ | `UploadOptions.show_author`, `toggle_author` callback, `show_author` DB column (migration 005) |
| L — File list metadata | ✅ | `ViewContent.svelte` shows `created_at`, `total_size`, `author` (username hyperlink + ID) |
| M — Deduplication | ✅ | `FilePipeline::ingest_file` checks `find_active_by_plaintext_hash`, increments `ref_count` |
| N — Hash blacklist | ✅ | `HashBlacklistRepo`, migration 007, blocked-hash rejection in pipeline |
| O — Username change tracking | ✅ | `UserRepo::ensure_exists` logs changes to `data/uname_changes.json` (configurable path in config) |
| Partial A — Misc report UI | ✅ | `Home.svelte` already has "Report Content via Telegram" link + "Report Content directly" input/button |
| Partial Q — Homepage bot link | ✅ | `Home.svelte` already has `t.me/{BOT_USERNAME}` link, but in wrong DOM order and styling needs tweak |
### Actual Bugs / Gaps to Fix
| Task | Root Cause | Fix Strategy |
|------|-----------|--------------|
| **B — /get_id** | Admin commands gated behind `msg.chat.is_group() \|\| msg.chat.is_supergroup()`, **excluding channels**. Also, HTML parse errors in logs come from unescaped `<arg>` tokens in `/help`, but `/get_id` must also be hardened for channels where `msg.from` / admin visibility differs. | Add `msg.chat.is_channel()` to admin command scope. Ensure `handle_get_id_search` gracefully handles channels (`get_chat_administrators` works in channels too if bot is admin). |
| **C — /help** | `help_text` raw string contains literal `<ID>`, `<@username>`, `<displayname>`, `<user_id>`, `<dur>`, `<unit>`. Telegram HTML parse mode rejects unsupported tags like `<id>`. | Escape all argument placeholders: replace `<arg>` with `&lt;arg&gt;` or `[arg]`. Minimally invasive: keep the rest of the formatting intact. |
| **E — blacklist_uid / whitelist_uid** | Commands are technically restricted to `admin_group_ids` inside the handler, but the outer command dispatch allows them in any group for admins, producing a confusing "only available in admin group" message. Missing-parameter handling exists but UX is inconsistent with other admin commands. | Move the admin-group check into the command dispatch so non-admin-group chats get a clear "Unauthorized" response. Ensure missing-parameter usage info is returned **before** the admin-group gate when possible, so users in the admin group see usage info immediately. |
| **I — Password + auto-destroy 410** | `serve_file` increments `view_count` for **HEAD requests** because `is_conditional` only checks `If-None-Match`, not request method. Some browsers/proxies/link previews issue HEAD before GET, consuming the view and causing the subsequent GET to hit `view_count >= max_views` → 410. | Add `Method` extractor to `serve_file` and skip view increment when `method == Method::HEAD`. Also skip increment for any non-GET method as defense-in-depth. |
| **J — Password field UX** | `Home.svelte` `submit()` calls `fetchMetadata(cxid)` **without password first**. For password-protected content this returns 401, throws, and the catch block sets a raw JSON error string. `needsPassword` is **never set to true**, so the password field never appears on the home page. Users cannot access password content from the home page at all. | Restructure `submit()`: on 401 from `fetchMetadata`, explicitly check if the error is auth-related and set `needsPassword = true` instead of treating it as a generic error. Ensure password verification only runs on explicit submit/Enter, not on keystrokes. |
| **A — Misc report (complete)** | Frontend UI exists but the "direct" report still opens a Telegram deep link instead of submitting via the web backend. The hardcoded `harmfulmeowbot` username is wrong; should use `BOT_USERNAME` from `api.js`. | Add `POST /api/report` endpoint to the server (it has access to `config.telegram.bot_token`). Server inserts report into DB and forwards a notification to configured review groups via direct Bot API HTTP calls. Update frontend to call the API instead of opening Telegram. |
| **Q — Homepage bot link** | Bot link is present in `Home.svelte` but **DOM order is wrong** (currently above Content ID label; should be between Content ID field and "-- cannibal girls --"). Styling says underline + very dark green/blackish green; current color is `var(--retro-green)` which may need to be `var(--retro-accent)` or a darker custom value. | Reorder elements in `Home.svelte`. Adjust CSS to match spec. Keep `BOT_USERNAME` dynamic import. |
## 2. Locked Implementation Rules
- **No broad rewrites.** Fix only the targeted bugs and gaps.
- **No redesign of working flows.** The upload pipeline, encryption, submission forward system, and moderation engine are working — do not touch them except where task I requires the HEAD-request guard.
- **Preserve existing frontend style and behavior.** Keep retro theme, fonts, colors, and animations. Only adjust the specific elements requested in A, J, Q.
- **No cleanup-only changes.** Do not refactor unrelated code, rename variables, or change formatting.
- **4-agent cycle mandatory** for implementation batches.
- **SQLite schema is frozen** except if a new migration is absolutely required. Tasks AQ do not need new DB tables (report endpoint can reuse existing `reports` table with `reporter_user_id = 0` for web reports).
## 3. Exact Batch Order for This Refinement Pass
### Batch 1: Security + Stability (Agent 1)
- **B** — /get_id channel support and robustness
- **C** — /help HTML escaping fix
- **E** — blacklist_uid/whitelist_uid command behavior refinement
- **I** — HEAD request view-count bugfix in `serve_file`
### Batch 2: Telegram Bot + Permissions (Agent 2)
- Verify Batch 1 bot changes compile and pass basic smoke tests
- **A** backend — Add `POST /api/report` endpoint to server (reuse `reports` table, forward to Telegram review groups via reqwest HTTP call to Bot API)
- **O** verification — Confirm username tracking writes correctly in channels/groups
- **D** verification — Confirm global_ban propagation logic works with recent schema
### Batch 3: Content Delivery + Rendering (Agent 3)
- **A** frontend — Wire "Report Content directly" to call `POST /api/report` instead of Telegram deep link
- **J** — Fix home page password flow (needsPassword trigger on 401)
- **Q** — Reorder bot link, adjust underline/dark-green styling
- **L** verification — Ensure metadata bar renders correctly after Batch 1 server changes
### Batch 4: Docs + QA + Regression (Agent 4)
- **P** — Update `docs/COMMANDS.md`, `docs/API.md`, `docs/MODERATION.md`, `README.md` to reflect all changes
- Regression test checklist: /get_id in group + channel, /help output, blacklist_uid usage, password+auto-destroy content loads on first GET, home page password flow, report submission API, bot link styling
- Run `cargo check --workspace` and `cargo test --workspace`
- Run frontend build (`cd frontend && npm run build`) and verify no new warnings
## 4. Key Risks
| Risk | Mitigation |
|------|-----------|
| Adding `Method` extractor to `serve_file` changes its signature and could break route registration if not matched exactly. | Use `extract::Method` in the handler signature; Axum `get()` accepts handlers with extra extractors. |
| `POST /api/report` needs to send Telegram messages from the server, which currently has no Telegram client. | Use `reqwest` (already transitive via Axum) to make direct HTTPS POSTs to `https://api.telegram.org/bot<token>/sendMessage`. Add `reqwest` explicitly to `cgcx-server/Cargo.toml`. |
| Channel admin command handling may behave differently because `msg.from` in channels can be the channel itself or anonymous. | Use `msg.sender_chat` or check `msg.from` carefully; `is_admin` still works with the bot's own admin check. |
| Frontend `fetchMetadata` 401 handling change in J must not break non-password flows. | Only set `needsPassword = true` when `err.status === 401`. Keep existing catch behavior for other errors. |
## 5. Exact 4-Agent Loop
```
Batch N assigned to 4 subagents -> execute in parallel -> wait for all 4 ->
brief review -> update AI_CHECKPOINT.md -> continue to Batch N+1
```
Agent definitions (always use these exact names):
1. **Security + Stability** — Server-side hardening, HTML escaping, view-count logic, command permission gates
2. **Telegram Bot + Permissions** — Bot command behavior, channel support, global_ban, backend API wiring
3. **Content Delivery + Rendering** — Frontend UX, Svelte components, API integration, styling
4. **Docs + QA + Regression** — Documentation updates, end-to-end verification, build checks, regression checklist
## 6. Resume Rules
- On any resume, **read this file first**, then `AI_CHECKPOINT.md`, then `AI_RESUME_PROMPT.md`.
- Do not skip batches. Do not merge batches.
- If a batch fails review, re-run that batch before advancing.
- Update `AI_CHECKPOINT.md` after every batch completes.
- Preserve all existing working behavior not explicitly listed for change.