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

View File

@@ -21,12 +21,13 @@ cg.cx lets Telegram users upload media, documents, or plain text and receive a s
| **Auto-Destruct** | Uploaders can set a max view count; content self-destructs once the limit is reached. |
| **Password Protection** | Optional per-content passwords with Argon2id-hashed verification and HMAC-SHA256 session cookies. |
| **Admin Moderation** | Blacklist / whitelist user IDs, delete content, review reports via Telegram admin groups. |
| **Reporting** | Users can report content via the homepage Misc section or the Telegram bot; reports are routed to review groups with inline admin actions. |
| **Reporting** | Users can report content directly via the web (`POST /api/content/:cxid/report`) or through the Telegram bot; reports are routed to review groups with inline admin actions (delete, blacklist, ban, ignore). |
| **Author Visibility** | Uploaders can toggle whether their Telegram username/ID is shown on the share page. |
| **Username Tracking** | Username changes are logged to a JSON file for audit and moderation purposes. |
| **Global Ban Config** | Optional `global_ban` flag propagates punishments across all configured admin groups, review groups, and active forward chats. |
| **Content Deduplication** | BLAKE3 plaintext hashing enables automatic reuse of existing encrypted files when identical content is re-uploaded. |
| **Hash Blacklist** | Moderators can block re-uploads of known-banned content by its plaintext hash at ingestion time. |
| **Native Media Batching** | Review and forward batches use native Telegram photo, video, audio, and document types with automatic caption truncation to 1,024 chars. |
| **Streaming Decryption** | Large encrypted files are decrypted and streamed chunk-by-chunk without loading into memory. |
| **Content Typing & Safety** | Automatic MIME detection and render flags flag dangerous/executable files for safe handling. |
@@ -131,6 +132,7 @@ cg.cx is organized as a **Rust workspace** with 10 focused crates. This modular
| **Backend** | Rust (edition 2021), Tokio async runtime |
| **Web Server** | Axum 0.7, Tower HTTP middleware |
| **Telegram Bot** | Teloxide 0.13 |
| **HTTP Client** | reqwest 0.12 (server-side report forwarding) |
| **Frontend** | Svelte 5, Vite 5 |
| **Database** | SQLite 3 (WAL mode), `rusqlite` + `rusqlite_migration` |
| **Cryptography** | libsodium (via `sodiumoxide`), `aes-kw`, `blake3`, `argon2`, `hmac`, `sha2` |
@@ -233,11 +235,13 @@ cargo run -p cgcx-server
The server binds to `127.0.0.1:8080` by default and serves:
- `/` - Svelte frontend
- `/` - Svelte frontend (includes dynamic bot username link and direct web reporting)
- `/api/health` - health check
- `/api/content/:cxid` - metadata JSON
- `/api/content/:cxid/verify-password` - password verification
- `/api/content/:cxid/file/:file_idx` - streamed decrypted file
- `/api/content/:cxid/file/:file_idx/raw` - streamed decrypted file (raw text)
- `/api/content/:cxid/report` - submit a direct web report
- `/assets/*` - static frontend assets
### Run the Telegram Bot
@@ -369,20 +373,54 @@ Use Let's Encrypt (certbot) or a managed TLS terminator. The `__Host-pw` cookie
Admin commands are restricted to users in configured `admin_group_ids` who also have the `admin` role in the database.
| Command | Usage | Description |
| ---------------- | -------------------------- | ---------------------------------------------------------------------------------------------- |
| `/reload` | `/reload` | Reloads moderation lists from disk (`data/blacklisted_ids.json`, `data/whitelisted_ids.json`). |
| `/blacklist_uid` | `/blacklist_uid <user_id>` | Blacklists a Telegram user ID globally and sets their role to `banned`. Shows usage info if the ID is missing. |
| `/whitelist_uid` | `/whitelist_uid <user_id>` | Removes a user from the global blacklist and restores their role to `user`. Shows usage info if the ID is missing. |
| Command | Usage | Description |
| ---------------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------- |
| `/reload` | `/reload` | Reloads moderation lists from disk (`data/blacklisted_ids.json`, `data/whitelisted_ids.json`). |
| `/blacklist_uid` | `/blacklist_uid <user_id>` | Blacklists a Telegram user ID globally and sets their role to `banned`. **Restricted to configured admin groups.** Shows usage info if the ID is missing. |
| `/whitelist_uid` | `/whitelist_uid <user_id>` | Removes a user from the global blacklist and restores their role to `user`. **Restricted to configured admin groups.** Shows usage info if the ID is missing. |
| `/help` | `/help` | Shows all admin commands with usage info. Uses HTML parse mode with proper escaping. |
| `/get_id` | `/get_id` | Returns the current chat ID. Works in groups, supergroups, and channels (admin-only). |
| `/get_id` | `/get_id @username` | Searches administrators by username (admin-only). |
| `/get_id` | `/get_id displayname` | Searches members in this chat by display name (admin-only). |
| `/create_submit_forward` | `/create_submit_forward <dest> <review> [msg]` | Creates a submission forward link. Bot must be admin in both destination and review groups. |
| `/show_c_forward` | `/show_c_forward [page]` | Lists active forward links with revoke buttons. |
| `/add_blacklist` | `/add_blacklist <user_id>` | Blacklists a user in all active forwards for this chat. |
| `/rm_blacklist` | `/rm_blacklist <user_id>` | Removes a user from blacklist in all active forwards for this chat. |
| `/sban` | `/sban @user <dur> <unit> [reason]` | Bans a user for a duration (e.g., `1 h`, `3 d`). Propagates if `global_ban` is enabled. |
| `/smute` | `/smute @user <dur> <unit> [reason]` | Mutes a user for a duration. Propagates if `global_ban` is enabled. |
| `/mute` | `/mute @user [reason]` | Mutes a user indefinitely. Propagates if `global_ban` is enabled. |
| `/pban` | `/pban @user [reason]` | Permanently bans a user. Propagates if `global_ban` is enabled. |
| `/kick` | `/kick @user [reason]` | Kicks a user from the group. Propagates if `global_ban` is enabled. |
| `/rmute` | `/rmute @user` | Revokes an active mute. |
| `/rban` | `/rban @user` | Revokes an active ban. |
### Review Groups
Reports submitted by users are forwarded to all configured `review_group_ids` with an inline keyboard:
Reports submitted via the Telegram bot or the web frontend are forwarded to all configured `review_group_ids` with an inline keyboard:
- **🗑⛔ Rmv + Ban** - Deletes the reported content and blacklists the uploader.
- **🗑 Delete Only** - Deletes the reported content.
- ** Blacklist Only** - Blacklists the uploader and sets their role to `banned`.
- **📝 Ignore** - Dismisses the report.
- **[ Rmv + Ban ]** - Deletes the reported content and blacklists the uploader.
- **[ Delete Only ]** - Deletes the reported content.
- **[ Blacklist Only ]** - Blacklists the uploader and sets their role to `banned`.
- **[ Ignore ]** - Dismisses the report.
Web reports are submitted via `POST /api/content/:cxid/report` and include a default reason of `"Direct web report"`. The server forwards the report to all review groups using the Telegram Bot API directly.
### Submission Forward System
The bot supports a submission-forward workflow for moderated content distribution:
1. Admins create a forward definition with `/create_submit_forward <destination_chat_id> <review_group_id> [message]`.
2. Users submit content through a private-link start parameter (`?start=submitfwdid<code>`).
3. Submissions are sent to the review group with action buttons: **Approve**, **Ignore**, **Blacklist**, **Ban**, **Ban+Blacklist**.
4. On approval, decrypted media is batched and forwarded to the destination chat.
5. Media is correctly typed as photo, video, audio, or document; captions are truncated to Telegram's 1,024-character limit.
6. The submitter receives a DM with the posted link.
### Auto-Destruct & Password Protection Fixes
- **HEAD request safety**: `HEAD` requests to content endpoints no longer consume a view count. Range requests and conditional (`If-None-Match`) requests also skip the increment.
- **serve_raw_file parity**: The raw text endpoint (`/api/content/:cxid/file/:file_idx/raw`) now mirrors `serve_file` view-increment behavior, including the 30-second delayed cleanup when `max_views` is reached.
- **Homepage password UX**: The frontend now shows a password field when the server returns `401`, and displays `"Incorrect password."` on verification failure.
### Moderation Modes