feat: implement periodic session cleanup for inactive/orphaned sessions

Implements automatic cleanup of Signal sessions to prevent database growth:

**Configuration (environment variables):**
- BAILEYS_SESSION_CLEANUP_ENABLED=true (default: true)
- BAILEYS_SESSION_CLEANUP_INTERVAL=86400000 (24h default)
- BAILEYS_SESSION_CLEANUP_HOUR=3 (3am default)
- BAILEYS_SESSION_SECONDARY_INACTIVE_DAYS=15
- BAILEYS_SESSION_PRIMARY_INACTIVE_DAYS=30
- BAILEYS_SESSION_LID_ORPHAN_HOURS=24

**Cleanup rules:**
1. Secondary devices (Web, Desktop): inactive > 15 days
2. Primary devices: inactive > 30 days
3. LID orphans (no PN mapping): > 24 hours

**Safety guarantees:**
- Does NOT affect WebSocket connections
- Does NOT cause message loss (Signal Protocol auto-recreates sessions)
- Runs in low-traffic hours (3am default, configurable)
- Atomic transactions (all-or-nothing)
- Comprehensive logging and statistics

**Implementation:**
- src/Signal/session-cleanup.ts: Core cleanup logic
- src/Defaults/index.ts: Configuration defaults
- src/Socket/socket.ts: Integration and lifecycle management

**Note:** Activity tracking not yet implemented (required for time-based cleanup).
Current implementation only cleans LID orphans (sessions without PN mapping).

https://claude.ai/code/session_01SoNUGBEWbJwWWws3F2fuzh
This commit is contained in:
Claude
2026-02-10 03:44:42 +00:00
parent 846ec76b29
commit a4a0272ccc
3 changed files with 444 additions and 0 deletions
+17
View File
@@ -6,12 +6,14 @@ import { proto } from '../../WAProto/index.js'
import {
DEF_CALLBACK_PREFIX,
DEF_TAG_PREFIX,
DEFAULT_SESSION_CLEANUP_CONFIG,
INITIAL_PREKEY_COUNT,
MIN_PREKEY_COUNT,
MIN_UPLOAD_INTERVAL,
NOISE_WA_HEADER,
UPLOAD_TIMEOUT
} from '../Defaults'
import { makeSessionCleanup } from '../Signal/session-cleanup'
import type { ConnectionState, LIDMapping, SocketConfig } from '../Types'
import { DisconnectReason } from '../Types'
import {
@@ -499,6 +501,14 @@ export const makeSocket = (config: SocketConfig) => {
const keys = addTransactionCapability(authState.keys, logger, transactionOpts)
const signalRepository = makeSignalRepository({ creds, keys }, logger, pnFromLIDUSync)
// Session cleanup manager - removes inactive/orphaned sessions
const sessionCleanup = makeSessionCleanup(
keys,
signalRepository.lidMapping,
logger,
DEFAULT_SESSION_CLEANUP_CONFIG
)
let lastDateRecv: Date
let epoch = 1
let keepAliveReq: NodeJS.Timeout
@@ -1079,6 +1089,9 @@ export const makeSocket = (config: SocketConfig) => {
clearInterval(keepAliveReq)
clearTimeout(qrTimer)
// Stop session cleanup scheduler
sessionCleanup.stop()
// Clean up unified session manager
unifiedSessionManager?.destroy()
@@ -1448,6 +1461,9 @@ export const makeSocket = (config: SocketConfig) => {
recordConnectionAttempt('success')
incrementActiveConnections()
// Start session cleanup scheduler
sessionCleanup.start()
// Update server time offset from success node
const serverTime = extractServerTime(node)
if (serverTime) {
@@ -1572,6 +1588,7 @@ export const makeSocket = (config: SocketConfig) => {
ev,
authState: { creds, keys },
signalRepository,
sessionCleanup,
get user() {
return authState.creds.me
},