Commit Graph

6 Commits

Author SHA1 Message Date
Siavash Sameni
210fbbb35b feat: bot alias reservation + BOT_API.md documentation
- Aliases ending with Bot/bot/_bot reserved for registered bots only
- Non-bot users get clear error directing to /v1/bot/register
- Bot registration auto-creates alias (@name_bot suffix)
- BOT_API.md: full developer guide with endpoints, examples, echo bot
- LLM_HELP.md: expanded bot section with update types + Python example

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 07:34:45 +04:00
Siavash Sameni
dbf5d136cf fix: WASM double-X3DH bug, federated aliases, deploy tooling
WASM fix (critical):
- encrypt_key_exchange_with_id was calling x3dh::initiate a second time,
  generating a new ephemeral key that didn't match the ratchet — receiver
  always failed to decrypt. Now stores X3DH result from initiate() and
  reuses it. Added 2 protocol tests confirming the fix + the bug.
- Bumped service worker cache to wz-v2 to force browsers to re-fetch.
- Disabled wasm-opt for Hetzner builds (libc compat issue).

Federation — alias support:
- resolve_alias falls back to federation peer if not found locally
- register_alias checks peer server before allowing — globally unique aliases
- Added resolve_remote_alias() and is_alias_taken_remote() to FederationHandle

Federation — key proxy fix:
- Remote bundles no longer cached locally (stale cache caused decrypt failures)
- Local vs remote determined by device: prefix in keys DB

Client fixes:
- Self-messaging blocked ("Cannot send messages to yourself")
- /peer <self> blocked
- last_dm_peer never set to self
- /r <message> sends reply inline (switches peer + sends in one command)

Deploy tooling:
- scripts/build-linux.sh with --ship (build + deploy + destroy)
- --update-all, --status, --logs commands
- WASM rebuilt on Hetzner VM before server binary
- deploy/ directory: systemd service, federation configs, setup script
- Journald log cap (50MB, 7-day retention)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 22:59:19 +04:00
Siavash Sameni
3e0889e5dc v0.0.21: TUI overhaul, WZP call infrastructure, security hardening, federation
TUI:
- Split 1,756-line app.rs monolith into 7 modules (types, draw, commands, input, file_transfer, network, mod)
- Message timestamps [HH:MM], scrolling (PageUp/Down/arrows), connection status dot, unread badge
- /help command, terminal bell on incoming DM, /devices + /kick commands
- 44 unit tests (types, input, draw with TestBackend)

Server — WZP Call Infrastructure (FC-2/3/5/6/7/10):
- Call state management (CallState, CallStatus, active_calls, calls + missed_calls sled trees)
- WS call signal awareness (Offer/Answer/Hangup update state, missed call on offline)
- Group call endpoint (POST /groups/:name/call with SHA-256 room ID, fan-out)
- Presence API (GET /presence/:fp, POST /presence/batch)
- Missed call flush on WS reconnect
- WZP relay config + CORS

Server — Security (FC-P1):
- Auth enforcement middleware (AuthFingerprint extractor on 13 write handlers)
- Session auto-recovery (delete corrupted ratchet, show [session reset])
- WS connection cap (5/fingerprint) + global concurrency limit (200)
- Device management (GET /devices, POST /devices/:id/kick, POST /devices/revoke-all)

Server — Federation:
- Two-server federation via JSON config (--federation flag)
- Periodic presence sync (every 5s, full-state, self-healing)
- Message forwarding via HTTP POST with SHA-256(secret||body) auth
- Graceful degradation (peer down = queue locally)
- deliver_or_queue() replaces push-or-queue in ws.rs + messages.rs

Client — Group Messaging:
- SenderKeyDistribution storage + GroupSenderKey decryption in TUI
- sender_keys sled tree in LocalDb

WASM:
- All 8 WireMessage variants handled (no more "unsupported")
- decrypt_group_message() + create_sender_key_from_distribution() exports
- CallSignal parsing with signal_type mapping

Docs:
- ARCHITECTURE.md rewritten with Mermaid diagrams
- README.md created
- TASK_PLAN.md with FC-P{phase}-T{task} naming
- PROGRESS.md updated to v0.0.21

WZP submodule updated to 6f4e8eb (IAX2 trunking, adaptive quality, metrics, all S-tasks done)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:45:58 +04:00
Siavash Sameni
9c70e02eba v0.0.15: unalias, admin alias removal, /reply, web version fix
Aliases:
- /unalias — remove your own alias
- /admin-unalias <alias> <password> — admin removes any alias
- Admin password via WARZONE_ADMIN_PASSWORD env var (default: "admin")
- POST /v1/alias/unregister + POST /v1/alias/admin-remove

Reply:
- /r or /reply — switches peer to whoever last DM'd you
- lastDmPeer tracked on both web and TUI
- Then type normally to reply

Web:
- Version bumped to 0.0.15 (was stuck at 0.0.10)
- WASM rebuilt with latest protocol

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:12:33 +04:00
Siavash Sameni
bf67566b0c Alias TTL, recovery keys, and reclamation
Aliases now have a lifecycle:
- 365-day TTL from last activity (send/receive/renew)
- 30-day grace period after expiry (only recovery key can reclaim)
- After grace: anyone can register the alias
- Recovery key generated on first registration, rotated on recovery
- Auto-renew on activity via POST /v1/alias/renew

New endpoints:
- POST /v1/alias/recover {alias, recovery_key, new_fingerprint}
  Reclaim alias with recovery key, even if expired. Works across
  identity changes (new seed → new fingerprint, same alias).
  Recovery key is rotated on each recovery.
- POST /v1/alias/renew {fingerprint}
  Heartbeat — resets TTL. Returns days until expiry.

Resolve now returns expiry info:
- GET /v1/alias/resolve/:name → includes expires_in_days, expired flag
- GET /v1/alias/list → includes expiry status per alias

Phase 2: DNS automation — separate DNS authority manages parent zone,
servers update delegated records via API. Recovery key maps to DNS
record ownership for out-of-band reclamation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 07:18:10 +04:00
Siavash Sameni
29c059cebf Aliases: human-readable names mapped to fingerprints
Server:
- POST /v1/alias/register — claim an alias (one per fingerprint)
- GET /v1/alias/resolve/:name — alias → fingerprint
- GET /v1/alias/whois/:fingerprint — fingerprint → alias (reverse)
- GET /v1/alias/list — list all aliases
- Bidirectional mapping in sled (a:name→fp, fp:fp→name)
- One alias per person, re-registering replaces old alias

Web client:
- /alias <name> — register your alias
- /aliases — list all registered aliases
- /info — now shows alias alongside fingerprint
- Peer input accepts @alias (resolved before sending)
- Received messages show @alias instead of fingerprint
- DM: paste @alias or fingerprint in peer input

CLI TUI:
- /alias <name> — register alias
- /aliases — list all aliases
- /peer @alias — resolves alias to fingerprint
- Alias resolution displayed in system messages

Addressing model:
- @manwe (local) → server resolves → fingerprint
- @manwe.b1.example.com (federated) → DNS resolve (Phase 3)
- Raw fingerprint → always works, no resolution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 07:01:35 +04:00