Fix spam filter blocking legitimate mesh messages

CRITICAL BUG FIX: Spam filter was blocking Bluetooth mesh messages

PROBLEM
=======
SpamFilterService was being applied to ALL public messages including
local Bluetooth mesh messages. This caused legitimate back-and-forth
chat to be rate-limited and dropped.

Logs showed:
  Rate limited message from mesh:... (sender:false content:true)

The sender token bucket (capacity: 5, refill: 1/sec) was exhausted
during normal conversation, blocking messages.

ROOT CAUSE
==========
When extracting SpamFilterService, the spam filter was applied to both:
- Geohash/Nostr messages (from internet - spam risk HIGH)
- Mesh/Bluetooth messages (local trusted peers - spam risk LOW)

Mesh messages should NOT be aggressively rate-limited since they come
from local trusted peers over Bluetooth.

SOLUTION
========
Changed spam filter to ONLY apply to geohash messages:

Before:
  if !spamFilter.shouldAllow(message) { return }

After:
  if isGeo && !spamFilter.shouldAllow(message) { return }

Now mesh messages bypass spam filter entirely, while geohash messages
from internet still get rate-limited protection.

IMPACT
======
 Mesh messages now flow freely (no artificial rate limiting)
 Geohash messages still protected from spam
 Normal back-and-forth chat works correctly
 Tests still passing

This fix is critical for usability - mesh chat is the core feature.
This commit is contained in:
jack
2025-10-07 22:21:27 +01:00
committed by Islam
parent fb003ba25e
commit 4f62364bf4
+3 -2
View File
@@ -5133,8 +5133,9 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
// Classify origin: geochat if senderPeerID starts with 'nostr:', else mesh (or system) // Classify origin: geochat if senderPeerID starts with 'nostr:', else mesh (or system)
let isGeo = finalMessage.senderPeerID?.isGeoChat == true let isGeo = finalMessage.senderPeerID?.isGeoChat == true
// Apply spam filter (per-sender and per-content rate limits) // Apply spam filter ONLY to geohash messages (internet spam risk)
if !spamFilter.shouldAllow( // Mesh messages are from local trusted peers via Bluetooth - no spam filtering needed
if isGeo && !spamFilter.shouldAllow(
message: finalMessage, message: finalMessage,
nostrKeyMapping: nostrKeyMapping, nostrKeyMapping: nostrKeyMapping,
getNoiseKeyForShortID: { [weak self] shortID in getNoiseKeyForShortID: { [weak self] shortID in