Commit Graph

10 Commits

Author SHA1 Message Date
Claude c3a44783bd fix(pr-77): apply Copilot/Codex review corrections with Protocol de Blindagem
Applies all 9 critical issues identified by Copilot/Codex reviewers on PR #77.
All fixes follow Protocol de Blindagem methodology:
- Boundary Analysis
- Invariant Verification
- Data Flow Tracking
- Edge Mitigation
- Semantic Distrust

## CRITICAL FIXES

### 1. Auto-Reconnect Implementation BROKEN (socket.ts:1369-1409)
**Issue:** Using `await end()` + `await connect()` breaks recovery.
**Root Cause:**
- `end()` sets `closed = true` permanently
- `connect()` function does not exist in makeSocket() return
- Pattern: consumers call `makeWASocket()` to recreate socket

**Fix:**
- Removed internal reconnect logic
- Emit `connection.update` with `isSessionError: true` flag
- Consumer detects and recreates socket with makeWASocket()
- Added `isSessionError` to ConnectionState type (State.ts)

**Invariants Verified:**
 Socket cannot reconnect itself (must be recreated)
 Consumer pattern: makeWASocket() on close event
 Example.ts shows correct pattern (line 84)

### 2. Memory Leak - PreKey Auto-Sync Listener (socket.ts:774-787)
**Issue:** Event listener never removed, memory leak on repeated socket creation.
**Fix:**
- Store listener reference in `connectionHandler`
- Return cleanup function from `startPreKeyAutoSync()`
- Call `cleanupPreKeyAutoSync()` in `end()` function
- Cleanup both listener AND timer

**Invariants Verified:**
 Listener removed via `ev.off()`
 Timer cleared via `clearTimeout()`
 Called in end() before ws listeners removed

### 3. Memory Leak - Session TTL Listener (socket.ts:813-848)
**Issue:** Event listener never removed, memory leak on repeated socket creation.
**Fix:**
- Store listener reference in `connectionHandler`
- Return cleanup function from `startSessionTTL()`
- Call `cleanupSessionTTL()` in `end()` function
- Cleanup listener AND both timers (ttl + grace)

**Invariants Verified:**
 Listener removed via `ev.off()`
 Both timers cleared (ttlTimer + ttlGraceTimer)
 Called in end() after transaction cleanup

### 4. Race Condition - TTL Grace Timeout (socket.ts:831-834)
**Issue:** Nested grace period timeout never cleared, fires after close.
**Fix:**
- Added `ttlGraceTimer` variable
- Store timeout reference
- Clear in close handler AND cleanup function
- Prevents `end()` call on already-closed socket

**Invariants Verified:**
 Grace timer cleared on disconnect
 No orphan timeouts
 Double-cleanup safe (idempotent)

### 5. Timer Accumulation in syncLoop (socket.ts:768-773)
**Issue:** Recursive setTimeout could accumulate if completion happens after close.
**Fix:**
- Check `!closed && ws.isOpen` BEFORE rescheduling
- Only schedule next sync if connection still open
- Prevents unbounded timer growth

**Invariants Verified:**
 Max 1 timer at a time
 No scheduling after close
 Cleanup always happens

### 6. TypeScript Compilation Error - Missing Event (Events.ts)
**Issue:** 'session.ttl-expired' not in BaileysEventMap.
**Fix:**
- Added event to BaileysEventMap (Events.ts:162-167)
- Full JSDoc documentation
- Type-safe event payload

**Invariants Verified:**
 TypeScript compilation succeeds
 Type-safe ev.emit() and ev.on()

### 7. Unbounded Queue - event-buffer.ts (Line 423-451)
**Issue:** If import() fails, metricsQueue grows unbounded.
**Fix:**
- Added `metricsImportFailed` flag
- Added `MAX_METRICS_QUEUE_SIZE = 1000` cap
- Clear queue on import failure
- Check both conditions before push

**Invariants Verified:**
 Queue never exceeds 1000 items
 Queue cleared on import failure
 Silently drops metrics (acceptable for observability)
 Applied to ALL 7 metric call sites

### 8. Empty Callback - lid-mapping.ts (Line 984-986)
**Issue:** Buffered callback empty, does nothing when module loads.
**Fix:**
- Removed metrics buffering entirely
- Changed to no-op with comment
- Actual metrics implementation pending

**Invariants Verified:**
 No memory leak from queue growth
 No false promises (code matches reality)
 Clear TODO for future implementation

### 9. Renumbered Protections (socket.ts comments)
**Fix:**
- PreKey Auto-Sync: PROTECTION 1-6 (sequential)
- Session TTL: PROTECTION 1-5 (sequential)
- Documentation matches implementation

## 🛡️ VERIFICAÇÕES DE ROBUSTEZ

### Boundary Analysis Applied:
 Verified `end()` sets `closed = true` (socket.ts:927)
 Verified `connect()` does NOT exist in return type
 Verified makeWASocket() pattern in Example.ts
 Verified ConnectionState type structure (State.ts:17-49)
 Verified import() failure path in event-buffer.ts

### Invariant Verification:
 Socket lifecycle: create → use → end → recreate (not reconnect)
 Event listeners: added → used → removed in cleanup
 Timers: created → referenced → cleared on cleanup
 Queue bounds: capped at 1000, cleared on failure
 Cleanup idempotence: safe to call multiple times

### Data Flow Tracking:
 end() → cleanupPreKeyAutoSync() → ev.off() → listener removed
 end() → cleanupSessionTTL() → ev.off() + clearTimeout() → cleanup
 import() fail → metricsImportFailed = true → queue stops growing
 session error → emit close → consumer creates new socket

### Edge Mitigation:
 TTL expires during message send: 5s grace period >> message time
 Connection closes during sync: checked before reschedule
 Import fails: queue capped and cleared
 Multiple end() calls: guards prevent double cleanup

### Semantic Distrust:
 Did NOT assume connect() exists (verified absence)
 Did NOT trust empty callback would work (removed)
 Did NOT assume cleanup happens automatically (explicit)
 Did NOT trust queue would self-limit (added cap)

## FILES MODIFIED
- src/Socket/socket.ts (auto-reconnect fix, listener cleanup, timer fixes)
- src/Types/Events.ts (session.ttl-expired event)
- src/Types/State.ts (isSessionError flag)
- src/Utils/event-buffer.ts (unbounded queue fix)
- src/Signal/lid-mapping.ts (empty callback removal)

## ZERO BREAKING CHANGES
 No impact on message delivery
 No impact on connection stability
 No impact on interactive messages
 Type-safe (TypeScript compiles)
 Consumer pattern unchanged

https://claude.ai/code/session_33db9e93-e4c3-4859-9ff3-96d8864af1c4
2026-02-03 23:13:36 +00:00
João Lucas de Oliveira Lopes 812e53e4eb Refactor: Fix Event Buffer Deadlock with State Machine (#1633)
* feat: implement state machine for chat synchronization and buffer management

* test: Add Jest configuration and tests for connection deadlock handling

- Created a Jest configuration file to set up testing environment.
- Implemented utility functions for creating isolated authentication sessions and mocking WebSocket connections.
- Added a test case to ensure that the connection does not deadlock when history sync is disabled, verifying the correct handling of message events.

* feat: add GitHub Actions workflow for running tests

* chore: sort import lint

* fix: implement timeout handling for AwaitingInitialSync state in chat socket, maybe fix memory leak

* feat: enhance chat synchronization by refining AwaitingInitialSync handling and adding history sync checks
2025-08-07 01:15:41 +03:00
Rajeh Taher 787aed88b8 project: Move to ESM Modules 2025-07-17 13:54:17 +03:00
canove fa706d0b50 chore: format everything 2025-05-06 12:10:19 -03:00
Adhiraj Singh 40a1e268aa feat: add "strictNullChecks" 2022-07-09 10:20:07 +05:30
Adhiraj Singh 6824a203d0 feat: correctly handle presence being offline for receipts
When sendPresenceUpdate('unavailable') is called, it should allow notifications to be received on the phone
2022-06-01 13:20:21 +05:30
Adhiraj Singh de7d1002a9 lint: stricter linting rules 2022-03-01 16:32:14 +05:30
Adhiraj Singh 8f11f0be76 chore: add linting 2022-01-19 15:54:02 +05:30
Adhiraj Singh 19a9980492 feat: add legacy connection 2021-12-17 19:27:04 +05:30
Adhiraj Singh f267f27ada finalize multi-device 2021-09-22 22:19:53 +05:30