v0.0.28: BotFather-only registration, per-instance bot toggle, docs update
Security: - Bot registration restricted to BotFather (requires botfather_token) - Direct POST /v1/bot/register without BotFather auth → rejected Deploy: - systemd service reads /home/warzone/server.env for EXTRA_ARGS - deploy/warzone-server.env.mequ: no bots (default) - deploy/warzone-server.env.kh3rad3ree: --enable-bots - setup.sh copies per-hostname env file Docs updated: - LLM_HELP.md: BotFather flow, plaintext bot messaging, E2E option, bridge - LLM_BOT_DEV.md: botfather_token requirement, E2E mode, bridge section - BOT_API.md: full BotFather flow, ownership, numeric IDs, webhook delivery - SERVER.md: --enable-bots flag, per-instance config, bot system section - USAGE.md: bot messaging, BotFather, bridge tool Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "warzone-protocol"
|
||||
version = "0.0.27"
|
||||
version = "0.0.28"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
description = "Core crypto & wire protocol for featherChat (Warzone messenger)"
|
||||
|
||||
@@ -236,6 +236,8 @@ struct RegisterBotRequest {
|
||||
e2e: Option<bool>, // true = E2E bot, false/None = plaintext bot
|
||||
#[serde(default)]
|
||||
owner: Option<String>, // fingerprint of the bot creator
|
||||
#[serde(default)]
|
||||
botfather_token: Option<String>,
|
||||
}
|
||||
|
||||
/// Register a bot and receive a token.
|
||||
@@ -249,12 +251,25 @@ async fn register_bot(
|
||||
State(state): State<AppState>,
|
||||
Json(req): Json<RegisterBotRequest>,
|
||||
) -> AppResult<Json<serde_json::Value>> {
|
||||
// TODO: In production, only @botfather should be able to register bots.
|
||||
// For v1, direct registration is allowed for development.
|
||||
if !state.bots_enabled {
|
||||
return Ok(Json(serde_json::json!({"ok": false, "description": "Bot API is disabled on this server. Use a server with --enable-bots"})));
|
||||
}
|
||||
|
||||
// Only BotFather can register bots
|
||||
// Require botfather_token field matching the stored BotFather token
|
||||
if let Some(ref bf_token) = req.botfather_token {
|
||||
let botfather_fp = "0000000000000000botfather00000000";
|
||||
let bf_key = format!("bot_fp:{}", botfather_fp);
|
||||
let stored_token = state.db.tokens.get(bf_key.as_bytes())
|
||||
.ok().flatten()
|
||||
.map(|v| String::from_utf8_lossy(&v).to_string());
|
||||
if stored_token.as_deref() != Some(bf_token.as_str()) {
|
||||
return Ok(Json(serde_json::json!({"ok": false, "description": "invalid BotFather token"})));
|
||||
}
|
||||
} else {
|
||||
return Ok(Json(serde_json::json!({"ok": false, "description": "bot registration requires BotFather authorization. Message @botfather to create a bot."})));
|
||||
}
|
||||
|
||||
let fp = req
|
||||
.fingerprint
|
||||
.chars()
|
||||
|
||||
@@ -50,7 +50,7 @@ async fn pwa_manifest() -> impl IntoResponse {
|
||||
|
||||
async fn service_worker() -> impl IntoResponse {
|
||||
([(header::CONTENT_TYPE, "application/javascript")], r##"
|
||||
const CACHE = 'wz-v9';
|
||||
const CACHE = 'wz-v10';
|
||||
const SHELL = ['/', '/wasm/warzone_wasm.js', '/wasm/warzone_wasm_bg.wasm', '/icon.svg', '/manifest.json'];
|
||||
|
||||
self.addEventListener('install', e => {
|
||||
@@ -241,7 +241,7 @@ let pollTimer = null;
|
||||
let ws = null; // WebSocket connection
|
||||
let wasmReady = false;
|
||||
|
||||
const VERSION = '0.0.27';
|
||||
const VERSION = '0.0.28';
|
||||
let DEBUG = true; // toggle with /debug command
|
||||
|
||||
// ── Receipt tracking ──
|
||||
|
||||
Reference in New Issue
Block a user