baileys-antiban 3.8.10 → 3.8.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/antiban.js CHANGED
@@ -79,6 +79,15 @@ function mapLegacyToFlat(legacy) {
79
79
  flat.identicalMessageWindowMs = legacyAsFlat.identicalMessageWindowMs;
80
80
  if (flat.burstAllowance === undefined && typeof legacyAsFlat.burstAllowance === 'number')
81
81
  flat.burstAllowance = legacyAsFlat.burstAllowance;
82
+ // v3 fields that may coexist with legacy nested keys
83
+ if (flat.autoPauseAt === undefined && typeof legacyAsFlat.autoPauseAt === 'string')
84
+ flat.autoPauseAt = legacyAsFlat.autoPauseAt;
85
+ if (flat.groupMultiplier === undefined && typeof legacyAsFlat.groupMultiplier === 'number')
86
+ flat.groupMultiplier = legacyAsFlat.groupMultiplier;
87
+ if (flat.groupProfiles === undefined && typeof legacyAsFlat.groupProfiles === 'boolean')
88
+ flat.groupProfiles = legacyAsFlat.groupProfiles;
89
+ if (flat.persist === undefined && typeof legacyAsFlat.persist === 'string')
90
+ flat.persist = legacyAsFlat.persist;
82
91
  return flat;
83
92
  }
84
93
  export class AntiBan {
@@ -82,6 +82,15 @@ function mapLegacyToFlat(legacy) {
82
82
  flat.identicalMessageWindowMs = legacyAsFlat.identicalMessageWindowMs;
83
83
  if (flat.burstAllowance === undefined && typeof legacyAsFlat.burstAllowance === 'number')
84
84
  flat.burstAllowance = legacyAsFlat.burstAllowance;
85
+ // v3 fields that may coexist with legacy nested keys
86
+ if (flat.autoPauseAt === undefined && typeof legacyAsFlat.autoPauseAt === 'string')
87
+ flat.autoPauseAt = legacyAsFlat.autoPauseAt;
88
+ if (flat.groupMultiplier === undefined && typeof legacyAsFlat.groupMultiplier === 'number')
89
+ flat.groupMultiplier = legacyAsFlat.groupMultiplier;
90
+ if (flat.groupProfiles === undefined && typeof legacyAsFlat.groupProfiles === 'boolean')
91
+ flat.groupProfiles = legacyAsFlat.groupProfiles;
92
+ if (flat.persist === undefined && typeof legacyAsFlat.persist === 'string')
93
+ flat.persist = legacyAsFlat.persist;
85
94
  return flat;
86
95
  }
87
96
  class AntiBan {
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.StateManager = void 0;
37
37
  const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
38
39
  const KNOWN_CHATS_MAX = 1000;
39
40
  const DEBOUNCE_MS = 5000;
40
41
  /**
@@ -48,13 +49,20 @@ class StateManager {
48
49
  path;
49
50
  debounceTimer = null;
50
51
  constructor(filePath) {
51
- this.path = filePath;
52
+ // Resolve to absolute path and reject null bytes to prevent path injection
53
+ if (filePath.includes('\0'))
54
+ throw new Error('[baileys-antiban] Invalid state file path: null byte');
55
+ this.path = path.resolve(filePath);
52
56
  }
53
57
  load() {
54
58
  try {
55
59
  const raw = fs.readFileSync(this.path, 'utf-8');
56
60
  const parsed = JSON.parse(raw);
57
- if (parsed.version !== 3) {
61
+ // Strict shape validation before trusting file content
62
+ if (typeof parsed !== 'object' || parsed === null ||
63
+ parsed.version !== 3 ||
64
+ typeof parsed.savedAt !== 'number' ||
65
+ !Array.isArray(parsed.knownChats)) {
58
66
  console.warn('[baileys-antiban] WARN: corrupt state file or version mismatch, starting fresh');
59
67
  return null;
60
68
  }
@@ -19,20 +19,19 @@
19
19
  */
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
21
  exports.proxyRotator = proxyRotator;
22
- // Create require function for loading optional peer dependencies
23
- // This function works in both ESM and CJS contexts
22
+ // Load optional peer dependencies synchronously in both ESM and CJS builds.
23
+ // CJS: native require is available. ESM: new Function() reads import.meta.url
24
+ // without causing TypeScript parse errors in CJS compilation. The string passed
25
+ // to new Function is a static literal — not user-controlled.
24
26
  function lazyRequire(moduleName) {
25
- // In CJS: use native require
26
27
  if (typeof require !== 'undefined') {
27
28
  return require(moduleName);
28
29
  }
29
- // In ESM: use createRequire with import.meta.url
30
- // We use indirect eval to get import.meta.url to avoid parse errors in CJS
31
- // @ts-ignore - ESM-only code path
32
- const { createRequire } = (0, eval)('require')('node:module');
33
- // @ts-ignore - ESM-only code path
34
- const dynamicRequire = createRequire((0, eval)('import.meta.url'));
35
- return dynamicRequire(moduleName);
30
+ // ESM path: new Function with static literal string avoids TS CJS-parse error on import.meta.
31
+ // Not user-controlled both strings are compile-time constants.
32
+ const { createRequire } = (new Function('return require')())('node:module');
33
+ const metaUrl = new Function('return import.meta.url')();
34
+ return createRequire(metaUrl)(moduleName);
36
35
  }
37
36
  const NoopLogger = {
38
37
  info: () => { },
@@ -177,6 +177,15 @@ class RateLimiter {
177
177
  this.identicalCount.delete(hash);
178
178
  }
179
179
  }
180
+ // LRU size cap — prevents unbounded growth when sending many unique messages.
181
+ // Evict oldest-by-lastSeen entries when map exceeds 10,000 entries.
182
+ const IDENTICAL_COUNT_MAX = 10_000;
183
+ if (this.identicalCount.size > IDENTICAL_COUNT_MAX) {
184
+ const sorted = [...this.identicalCount.entries()].sort(([, a], [, b]) => a.lastSeen - b.lastSeen);
185
+ const excess = this.identicalCount.size - IDENTICAL_COUNT_MAX;
186
+ for (let i = 0; i < excess; i++)
187
+ this.identicalCount.delete(sorted[i][0]);
188
+ }
180
189
  }
181
190
  /** Random delay between min and max (gaussian-ish distribution) */
182
191
  jitter(min, max) {
package/dist/persist.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as fs from 'fs';
2
+ import * as path from 'path';
2
3
  const KNOWN_CHATS_MAX = 1000;
3
4
  const DEBOUNCE_MS = 5000;
4
5
  /**
@@ -12,13 +13,20 @@ export class StateManager {
12
13
  path;
13
14
  debounceTimer = null;
14
15
  constructor(filePath) {
15
- this.path = filePath;
16
+ // Resolve to absolute path and reject null bytes to prevent path injection
17
+ if (filePath.includes('\0'))
18
+ throw new Error('[baileys-antiban] Invalid state file path: null byte');
19
+ this.path = path.resolve(filePath);
16
20
  }
17
21
  load() {
18
22
  try {
19
23
  const raw = fs.readFileSync(this.path, 'utf-8');
20
24
  const parsed = JSON.parse(raw);
21
- if (parsed.version !== 3) {
25
+ // Strict shape validation before trusting file content
26
+ if (typeof parsed !== 'object' || parsed === null ||
27
+ parsed.version !== 3 ||
28
+ typeof parsed.savedAt !== 'number' ||
29
+ !Array.isArray(parsed.knownChats)) {
22
30
  console.warn('[baileys-antiban] WARN: corrupt state file or version mismatch, starting fresh');
23
31
  return null;
24
32
  }
@@ -16,20 +16,19 @@
16
16
  * @author Kobus Wentzel <kobie@pop.co.za>
17
17
  * @license MIT
18
18
  */
19
- // Create require function for loading optional peer dependencies
20
- // This function works in both ESM and CJS contexts
19
+ // Load optional peer dependencies synchronously in both ESM and CJS builds.
20
+ // CJS: native require is available. ESM: new Function() reads import.meta.url
21
+ // without causing TypeScript parse errors in CJS compilation. The string passed
22
+ // to new Function is a static literal — not user-controlled.
21
23
  function lazyRequire(moduleName) {
22
- // In CJS: use native require
23
24
  if (typeof require !== 'undefined') {
24
25
  return require(moduleName);
25
26
  }
26
- // In ESM: use createRequire with import.meta.url
27
- // We use indirect eval to get import.meta.url to avoid parse errors in CJS
28
- // @ts-ignore - ESM-only code path
29
- const { createRequire } = (0, eval)('require')('node:module');
30
- // @ts-ignore - ESM-only code path
31
- const dynamicRequire = createRequire((0, eval)('import.meta.url'));
32
- return dynamicRequire(moduleName);
27
+ // ESM path: new Function with static literal string avoids TS CJS-parse error on import.meta.
28
+ // Not user-controlled both strings are compile-time constants.
29
+ const { createRequire } = (new Function('return require')())('node:module');
30
+ const metaUrl = new Function('return import.meta.url')();
31
+ return createRequire(metaUrl)(moduleName);
33
32
  }
34
33
  const NoopLogger = {
35
34
  info: () => { },
@@ -174,6 +174,15 @@ export class RateLimiter {
174
174
  this.identicalCount.delete(hash);
175
175
  }
176
176
  }
177
+ // LRU size cap — prevents unbounded growth when sending many unique messages.
178
+ // Evict oldest-by-lastSeen entries when map exceeds 10,000 entries.
179
+ const IDENTICAL_COUNT_MAX = 10_000;
180
+ if (this.identicalCount.size > IDENTICAL_COUNT_MAX) {
181
+ const sorted = [...this.identicalCount.entries()].sort(([, a], [, b]) => a.lastSeen - b.lastSeen);
182
+ const excess = this.identicalCount.size - IDENTICAL_COUNT_MAX;
183
+ for (let i = 0; i < excess; i++)
184
+ this.identicalCount.delete(sorted[i][0]);
185
+ }
177
186
  }
178
187
  /** Random delay between min and max (gaussian-ish distribution) */
179
188
  jitter(min, max) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baileys-antiban",
3
- "version": "3.8.10",
3
+ "version": "3.8.11",
4
4
  "description": "Anti-ban middleware for Baileys WhatsApp bots. Rate limiting, warmup, health monitor, LID resolver, disconnect classifier. Free Whapi.Cloud alternative.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "types": "dist/index.d.ts",