Add auto-recovery from stuck WhatsApp sessions

Fixes issue where unauthorized messages from +212652169245 (5elements spa)
triggered Bad MAC errors and silently killed the event emitter, preventing
all future message processing.

Changes:
1. Early allowFrom filtering in inbound.ts - blocks unauthorized senders
   before they trigger encryption errors
2. Message timeout watchdog - auto-restarts connection if no messages
   received for 10 minutes
3. Health monitoring in heartbeat - warns if >30 min without messages
4. Mock loadConfig in tests to handle new dependency

Root cause: Event emitter stopped firing after Bad MAC errors from
decryption attempts on messages from unauthorized senders. Connection
stayed alive but all subsequent messages.upsert events silently failed.
This commit is contained in:
Peter Steinberger
2025-11-30 17:53:32 +00:00
parent 37d8e55991
commit 69319a0569
4 changed files with 83 additions and 12 deletions

View File

@@ -8,10 +8,11 @@ import {
downloadMediaMessage,
} from "@whiskeysockets/baileys";
import { loadConfig } from "../config/config.js";
import { isVerbose, logVerbose } from "../globals.js";
import { getChildLogger } from "../logging.js";
import { saveMediaBuffer } from "../media/store.js";
import { jidToE164 } from "../utils.js";
import { jidToE164, normalizeE164 } from "../utils.js";
import {
createWaSocket,
getStatusCode,
@@ -94,6 +95,20 @@ export async function monitorWebInbox(options: {
}
const from = jidToE164(remoteJid);
if (!from) continue;
// Filter unauthorized senders early to prevent wasted processing
// and potential session corruption from Bad MAC errors
const cfg = loadConfig();
const allowFrom = cfg.inbound?.allowFrom;
const isSamePhone = from === selfE164;
if (!isSamePhone && Array.isArray(allowFrom) && allowFrom.length > 0) {
if (!allowFrom.includes("*") && !allowFrom.map(normalizeE164).includes(from)) {
logVerbose(`Blocked unauthorized sender ${from} (not in allowFrom list)`);
continue; // Skip processing entirely
}
}
let body = extractText(msg.message ?? undefined);
if (!body) {
body = extractMediaPlaceholder(msg.message ?? undefined);