fix: Go E2EE security hardening — key holder tracking, base64 loose validation, rate limits, test schema

- I-1: Add key holder election in Hub (lowest userID per channel); reject
  non-key-holder voice_e2ee_offer with NOT_KEY_HOLDER error
- I-2: Accept raw (unpadded) base64 in E2EE announce/offer handlers via
  decodeBase64Loose fallback
- I-6: Copy E2EE public key value while h.mu.RLock is held in getClientE2EEPubKey
- I-7: Lower loginRateLimitPerMinute from 60 to 5
- C-1: TOCTOU fix — target channel check held under same lock as client lookup
- C-2: Include is_key_holder bool in voice_token payload so client knows
  whether to initiate key distribution
- M-5/M-6: Add ErrCodeBadPayload/ErrCodeNotKeyHolder error constants
- Fix pre-existing api build errors: block_handler.go getUserFromContext,
  router.go RequirePermission arg count
- Add user_blocks table to all test DB schemas (ws, api DM)
- Add voice_e2ee_test.go and constants_test.go covering all fixes
This commit is contained in:
J3vb
2026-04-04 23:16:31 +02:00
parent 774a7bcce9
commit 3d18ce4f99
16 changed files with 650 additions and 42 deletions
+8
View File
@@ -109,6 +109,14 @@ CREATE TABLE IF NOT EXISTS read_states (
mention_count INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (user_id, channel_id)
);
CREATE TABLE IF NOT EXISTS user_blocks (
blocker_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
blocked_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
PRIMARY KEY (blocker_id, blocked_id),
CHECK (blocker_id != blocked_id)
);
`)
// ─── helpers ────────────────────────────────────────────────────────────────