@prototypevip/baileys 0.1.0 → 0.1.2

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.
Files changed (62) hide show
  1. package/lib/Defaults/index.js +3 -3
  2. package/lib/Defaults/index.js.bak-1788476907801 +187 -0
  3. package/lib/Defaults/index.js.bak-1788479166288 +187 -0
  4. package/lib/Socket/groups.js.bak-1788476973954 +475 -0
  5. package/lib/Socket/index.js +42 -126
  6. package/lib/Socket/index.js.bak-1788479281092 +38 -0
  7. package/lib/Socket/messages-send.js +88 -51
  8. package/lib/Store/prototype-store.js +34 -22
  9. package/lib/Store/prototype-store.js.bak-1788477006895 +983 -0
  10. package/lib/Utils/index.js +2 -0
  11. package/lib/Utils/integrity-guard.js +281 -0
  12. package/lib/Utils/interactive-message-handler.js +28 -8
  13. package/lib/Utils/interactive-message-handler.js.bak-1788476898661 +478 -0
  14. package/lib/Utils/socket-guard.js +154 -0
  15. package/package.json +2 -2
  16. package/lib/AntiBan/antiban.js +0 -922
  17. package/lib/AntiBan/banRecoveryOrchestrator.js +0 -284
  18. package/lib/AntiBan/cli.js +0 -177
  19. package/lib/AntiBan/contactGraph.js +0 -236
  20. package/lib/AntiBan/contentVariator.js +0 -150
  21. package/lib/AntiBan/credsSnapshot.js +0 -121
  22. package/lib/AntiBan/deliveryTracker.js +0 -107
  23. package/lib/AntiBan/deviceFingerprint.js +0 -106
  24. package/lib/AntiBan/fleetEventStore.js +0 -157
  25. package/lib/AntiBan/groupOperationGuard.js +0 -116
  26. package/lib/AntiBan/health.js +0 -207
  27. package/lib/AntiBan/humanEntropy.js +0 -337
  28. package/lib/AntiBan/index.js +0 -77
  29. package/lib/AntiBan/instanceCoordinator.js +0 -175
  30. package/lib/AntiBan/jidCanonicalizer.js +0 -256
  31. package/lib/AntiBan/jidCircuitBreaker.js +0 -186
  32. package/lib/AntiBan/legitimacySignalInjector.js +0 -231
  33. package/lib/AntiBan/lidFirstResolver.js +0 -174
  34. package/lib/AntiBan/lidResolver.js +0 -324
  35. package/lib/AntiBan/messageQueue.js +0 -187
  36. package/lib/AntiBan/messageRecovery.js +0 -283
  37. package/lib/AntiBan/messageTypeRegistry.js +0 -369
  38. package/lib/AntiBan/observability.js +0 -145
  39. package/lib/AntiBan/patch.js +0 -302
  40. package/lib/AntiBan/persist.js +0 -87
  41. package/lib/AntiBan/presenceChoreographer.js +0 -430
  42. package/lib/AntiBan/presets.js +0 -105
  43. package/lib/AntiBan/profiles.js +0 -31
  44. package/lib/AntiBan/proxyRotator.js +0 -306
  45. package/lib/AntiBan/rateLimiter.js +0 -261
  46. package/lib/AntiBan/readReceiptVariance.js +0 -88
  47. package/lib/AntiBan/reconnectThrottle.js +0 -180
  48. package/lib/AntiBan/replyRatio.js +0 -161
  49. package/lib/AntiBan/reputationVoucher.js +0 -373
  50. package/lib/AntiBan/retryReason.js +0 -91
  51. package/lib/AntiBan/retryTracker.js +0 -172
  52. package/lib/AntiBan/scheduler.js +0 -111
  53. package/lib/AntiBan/sessionFingerprint.js +0 -248
  54. package/lib/AntiBan/sessionStability.js +0 -330
  55. package/lib/AntiBan/stateAdapter.js +0 -73
  56. package/lib/AntiBan/stateExport.js +0 -152
  57. package/lib/AntiBan/stealthConnect.js +0 -130
  58. package/lib/AntiBan/timelockGuard.js +0 -181
  59. package/lib/AntiBan/topologyThrottler.js +0 -339
  60. package/lib/AntiBan/warmup.js +0 -140
  61. package/lib/AntiBan/webhooks.js +0 -80
  62. package/lib/AntiBan/wrapper.js +0 -456
@@ -29,3 +29,5 @@ export * from "./rich-message-utils.js";
29
29
  export * from "./message-builder.js";
30
30
  export * from "./ai-rich-formatter.js";
31
31
  export * from "./constants.js";
32
+ export * from "./socket-guard.js";
33
+ export * from "./integrity-guard.js";
@@ -0,0 +1,281 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * integrity-guard.js
5
+ * توسيع لنفس فلسفة socket-guard.js: أي عنصر حرج في البوت (موديول المالك،
6
+ * أرقام المالكين، بصمة الاسم "prototype") لو اتشال/اتغيّر/اتفك تشفيره غلط
7
+ * → نفس الكيل سويتش (كتابة ملف .proto_kill + رساله + process.exit).
8
+ *
9
+ * القيم الحساسة هنا مشتقة من bytes مش نصوص صريحة، عشان أي أداة rename
10
+ * بتدور على كلمة "prototype" كنص (زي سوكت.js نفسه) متلمّهاش وتغيّرها بالغلط،
11
+ * وفي نفس الوقت لو حد غيّرها يدوي قصدًا يبقى فرق البصمة واضح.
12
+ */
13
+
14
+ import fs from "fs";
15
+ import crypto from "crypto";
16
+ import path from "path";
17
+ import { fileURLToPath } from "url";
18
+ import { PROTO_MARK_VALUE, isKilled, writeKill } from "./socket-guard.js";
19
+
20
+ const __filename = fileURLToPath(import.meta.url);
21
+ const __dirname = path.dirname(__filename);
22
+
23
+ // "prototypevip" + "baileys" كـ bytes مش كنص صريح
24
+ const SCOPE_BYTES = [
25
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x76, 0x69, 0x70,
26
+ ]; // prototypevip
27
+ const PKG_BYTES = [0x62, 0x61, 0x69, 0x6c, 0x65, 0x79, 0x73]; // baileys
28
+ const WORD_BYTES = [
29
+ 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x54, 0x59, 0x50, 0x45,
30
+ ]; // PROTOTYPE
31
+
32
+ function expectedScopedName() {
33
+ return `@${Buffer.from(SCOPE_BYTES).toString()}/${Buffer.from(PKG_BYTES).toString()}`;
34
+ }
35
+
36
+ function brandFingerprintSource() {
37
+ return `${Buffer.from(WORD_BYTES).toString()}:${PROTO_MARK_VALUE}:${expectedScopedName()}`;
38
+ }
39
+
40
+ // بصمة ثابتة محسوبة مرة واحدة على نفس القيم أعلاه — أي تعديل يدوي في أي
41
+ // جزء من الثلاثة (WORD_BYTES / PROTO_MARK_VALUE / اسم السكوب) يكسر التطابق.
42
+ const EXPECTED_BRAND_HASH = crypto
43
+ .createHash("sha256")
44
+ .update(brandFingerprintSource())
45
+ .digest("hex");
46
+
47
+ /**
48
+ * تشتقاق مفتاح تشفير من نفس بصمة الماركة — بيربط حماية الأرقام المشفرة
49
+ * بحماية الختم والبراند في ملف واحد؛ لو حد لعب في أي منهم يبوظ التاني.
50
+ */
51
+ function deriveKey(config = {}) {
52
+ const seed = (config && config.keySeed) || brandFingerprintSource();
53
+ return crypto.createHash("sha256").update(String(seed)).digest();
54
+ }
55
+
56
+ /* ---------------- بصمة اسم المكتبه (package.json) ---------------- */
57
+
58
+ function readOwnPackageJson() {
59
+ // lib/Utils/integrity-guard.js -> ../../package.json
60
+ const pkgPath = path.join(__dirname, "..", "..", "package.json");
61
+ const raw = fs.readFileSync(pkgPath, "utf8");
62
+ return JSON.parse(raw);
63
+ }
64
+
65
+ function verifyPackageIdentity() {
66
+ try {
67
+ const pkg = readOwnPackageJson();
68
+ return pkg && pkg.name === expectedScopedName();
69
+ } catch {
70
+ return false;
71
+ }
72
+ }
73
+
74
+ /**
75
+ * التحقق النهائي من "بصمة الاسم": تطابق الهاش + تطابق اسم الباكدج.
76
+ */
77
+ function verifyBrandIntegrity() {
78
+ try {
79
+ const h = crypto.createHash("sha256").update(brandFingerprintSource()).digest("hex");
80
+ if (h !== EXPECTED_BRAND_HASH) return false;
81
+ return verifyPackageIdentity();
82
+ } catch {
83
+ return false;
84
+ }
85
+ }
86
+
87
+ /* ---------------- موديول isOwner ---------------- */
88
+
89
+ /**
90
+ * البوت هو اللي بيعمل require لملف isOwner بتاعه ويبعت الـ module هنا
91
+ * (المكتبه مش عارفه مسار البوت أصلًا). بنتأكد إن الشكل سليم فعلًا.
92
+ */
93
+ function verifyOwnerModule(mod) {
94
+ try {
95
+ if (!mod || typeof mod !== "object") return false;
96
+ if (typeof mod.isOwner !== "function") return false;
97
+ if (typeof mod.isMainOwner !== "function") return false;
98
+ return true;
99
+ } catch {
100
+ return false;
101
+ }
102
+ }
103
+
104
+ /* ---------------- تخزين الأرقام مشفرة (AES-256-GCM) ---------------- */
105
+
106
+ function signEncryptedStore(payload, config = {}) {
107
+ const key = deriveKey(config);
108
+ const iv = crypto.randomBytes(12);
109
+ const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
110
+ const enc = Buffer.concat([
111
+ cipher.update(JSON.stringify(payload), "utf8"),
112
+ cipher.final(),
113
+ ]);
114
+ const tag = cipher.getAuthTag();
115
+ return {
116
+ v: 1,
117
+ iv: iv.toString("base64"),
118
+ enc: enc.toString("base64"),
119
+ tag: tag.toString("base64"),
120
+ };
121
+ }
122
+
123
+ function writeEncryptedStore(filePath, payload, config = {}) {
124
+ const data = signEncryptedStore(payload, config);
125
+ const dir = path.dirname(filePath);
126
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
127
+ fs.writeFileSync(filePath, JSON.stringify(data), "utf8");
128
+ }
129
+
130
+ function readEncryptedStore(filePath, config = {}) {
131
+ const raw = JSON.parse(fs.readFileSync(filePath, "utf8"));
132
+ const key = deriveKey(config);
133
+ const decipher = crypto.createDecipheriv(
134
+ "aes-256-gcm",
135
+ key,
136
+ Buffer.from(raw.iv, "base64")
137
+ );
138
+ decipher.setAuthTag(Buffer.from(raw.tag, "base64"));
139
+ const dec = Buffer.concat([
140
+ decipher.update(Buffer.from(raw.enc, "base64")),
141
+ decipher.final(),
142
+ ]);
143
+ return JSON.parse(dec.toString("utf8"));
144
+ }
145
+
146
+ /**
147
+ * أي تعديل يدوي في الملف (نص أو byte واحد) بيكسر GCM auth tag ويرجع false،
148
+ * زي ما الملف الناقص خالص بيرجع false.
149
+ */
150
+ function verifyEncryptedNumbers(filePath, config = {}) {
151
+ try {
152
+ if (!filePath || !fs.existsSync(filePath)) return false;
153
+ const data = readEncryptedStore(filePath, config);
154
+ return (
155
+ Array.isArray(data) &&
156
+ data.length > 0 &&
157
+ data.every((n) => /^\d{6,}$/.test(String(n)))
158
+ );
159
+ } catch {
160
+ return false;
161
+ }
162
+ }
163
+
164
+ /* ---------------- كيل سويتش عام لأي عنصر حرج ---------------- */
165
+
166
+ /**
167
+ * enforceOrDie: نفس آلية enforceSocketOrDie بالظبط لكن عامّه لأي فحص
168
+ * (اسم العنصر + نتيجة boolean بدل ما تبقى مربوطة بالسوكت بس).
169
+ */
170
+ async function enforceOrDie(name, ok, sock, chatId, config = {}) {
171
+ if (ok) return true;
172
+
173
+ writeKill(config, `critical_missing:${name}`);
174
+
175
+ const msg = config.killMessage || "لا يمكنك استخدام هذا بوت";
176
+ try {
177
+ if (sock && typeof sock.sendMessage === "function" && chatId) {
178
+ await sock.sendMessage(chatId, { text: msg });
179
+ }
180
+ } catch {}
181
+
182
+ try {
183
+ console.error(`[INTEGRITY-GUARD] "${name}" check failed — bot disabled permanently.`);
184
+ } catch {}
185
+
186
+ setTimeout(() => {
187
+ try {
188
+ process.exit(1);
189
+ } catch {}
190
+ }, 1500);
191
+
192
+ return false;
193
+ }
194
+
195
+ /**
196
+ * فحص دوري (بعد الإقلاع) بيعيد التأكد من نفس العناصر كل فترة، عشان لو حد
197
+ * مسح/عدّل الملفات وهو البوت شغال (مش بس وقت الإقلاع) يتوقف برضه.
198
+ */
199
+ function startPeriodicIntegrityWatch(checks, sock, getChatId, config = {}, intervalMs = 10 * 60 * 1000) {
200
+ const timer = setInterval(async () => {
201
+ if (isKilled(config)) return; // هيتقفل من مكان تاني أصلًا
202
+ for (const [name, fn] of Object.entries(checks)) {
203
+ let ok = false;
204
+ try {
205
+ ok = !!(await fn());
206
+ } catch {
207
+ ok = false;
208
+ }
209
+ if (!ok) {
210
+ const chatId = typeof getChatId === "function" ? getChatId() : getChatId;
211
+ await enforceOrDie(name, false, sock, chatId, config);
212
+ clearInterval(timer);
213
+ return;
214
+ }
215
+ }
216
+ }, intervalMs);
217
+ if (timer.unref) timer.unref();
218
+ return timer;
219
+ }
220
+
221
+ /* ---------------- بصمة ملفات حرجه (manifest موقّع) ---------------- */
222
+
223
+ /**
224
+ * بديل عام لأي محاولة تعديل "منطق" ملف حرج (مش بس حذفه) — زي حد يفتح
225
+ * isOwner.js ويحط `return true` ثابت، أو يفتح protoGuard.js ويعطل فحص.
226
+ * بنسجّل بصمة SHA-256 لكل ملف مهم وقت الإعداد، ونوقّع القايمه كلها بمفتاح
227
+ * مشتق من نفس بصمة الماركة، فبعد كده أي حرف يتغيّر في أي ملف من الليست
228
+ * يكسر التطابق. المانفست نفسه لو اتلمس (بدون التوقيع الصح) بيفشل فك التشفير.
229
+ */
230
+ function hashFile(absPath) {
231
+ const buf = fs.readFileSync(absPath);
232
+ return crypto.createHash("sha256").update(buf).digest("hex");
233
+ }
234
+
235
+ /**
236
+ * files: { "relative/or/absolute/path.js": absolutePathOnDisk }
237
+ * بيرجع نفس شكل signEncryptedStore (iv/enc/tag) عشان يتحفظ في ملف زي أي
238
+ * ملف حساس تاني في المشروع.
239
+ */
240
+ function writeFileManifest(files, manifestPath, config = {}) {
241
+ const entries = {};
242
+ for (const [label, absPath] of Object.entries(files)) {
243
+ entries[label] = hashFile(absPath);
244
+ }
245
+ writeEncryptedStore(manifestPath, entries, config);
246
+ return entries;
247
+ }
248
+
249
+ /**
250
+ * files: نفس الشكل المستخدم وقت الكتابة. بيرجع false لو المانفست ناقص/
251
+ * مش قابل لفك التشفير (تلاعب في التوقيع)، أو لو أي ملف من الليست ناقص،
252
+ * أو لو الهاش بتاعه اتغيّر عن اللي كان متسجل وقت seed-manifest.
253
+ */
254
+ function verifyFileManifest(files, manifestPath, config = {}) {
255
+ try {
256
+ if (!fs.existsSync(manifestPath)) return false;
257
+ const recorded = readEncryptedStore(manifestPath, config);
258
+ for (const [label, absPath] of Object.entries(files)) {
259
+ if (!fs.existsSync(absPath)) return false;
260
+ if (recorded[label] !== hashFile(absPath)) return false;
261
+ }
262
+ return true;
263
+ } catch {
264
+ return false;
265
+ }
266
+ }
267
+
268
+ export {
269
+ verifyBrandIntegrity,
270
+ verifyPackageIdentity,
271
+ verifyOwnerModule,
272
+ signEncryptedStore,
273
+ writeEncryptedStore,
274
+ readEncryptedStore,
275
+ verifyEncryptedNumbers,
276
+ enforceOrDie,
277
+ startPeriodicIntegrityWatch,
278
+ deriveKey,
279
+ writeFileManifest,
280
+ verifyFileManifest,
281
+ };
@@ -3,10 +3,11 @@ import crypto from 'crypto';
3
3
  import * as Utils_1 from '../Utils/index.js';
4
4
 
5
5
  export default class InteractiveMessageHandler {
6
- constructor(utils, waUploadToServer, relayMessageFn) {
6
+ constructor(utils, waUploadToServer, relayMessageFn, emitUpsert) {
7
7
  this.utils = utils;
8
8
  this.relayMessage = relayMessageFn;
9
9
  this.waUploadToServer = waUploadToServer;
10
+ this.emitUpsert = typeof emitUpsert === "function" ? emitUpsert : () => {};
10
11
 
11
12
  this.bail = {
12
13
  generateWAMessageContent: this.utils.generateWAMessageContent || Utils_1.generateWAMessageContent,
@@ -289,8 +290,10 @@ export default class InteractiveMessageHandler {
289
290
 
290
291
  await this.relayMessage(jid, album.message, {
291
292
  messageId: album.key.id,
293
+ skipStoreEmit: true,
292
294
  });
293
-
295
+ this.emitUpsert(album);
296
+
294
297
  for (let content of array) {
295
298
  const img = await this.utils.generateWAMessage(jid, content, {
296
299
  upload: this.waUploadToServer,
@@ -347,6 +350,7 @@ export default class InteractiveMessageHandler {
347
350
 
348
351
  await this.relayMessage(jid, img.message, {
349
352
  messageId: img.key.id,
353
+ skipStoreEmit: true,
350
354
  quoted: {
351
355
  key: {
352
356
  remoteJid: album.key.remoteJid,
@@ -357,6 +361,7 @@ export default class InteractiveMessageHandler {
357
361
  message: album.message,
358
362
  },
359
363
  });
364
+ this.emitUpsert(img);
360
365
  }
361
366
  return album;
362
367
  }
@@ -407,8 +412,10 @@ export default class InteractiveMessageHandler {
407
412
  }, { quoted });
408
413
 
409
414
  await this.relayMessage(jid, msg.message, {
410
- messageId: msg.key.id
415
+ messageId: msg.key.id,
416
+ skipStoreEmit: true,
411
417
  });
418
+ this.emitUpsert(msg);
412
419
  return msg;
413
420
  }
414
421
 
@@ -431,8 +438,10 @@ export default class InteractiveMessageHandler {
431
438
  });
432
439
 
433
440
  await this.relayMessage(jid, msg.message, {
434
- messageId: msg.key.id
441
+ messageId: msg.key.id,
442
+ skipStoreEmit: true,
435
443
  });
444
+ this.emitUpsert(msg);
436
445
 
437
446
  return msg;
438
447
  }
@@ -463,16 +472,27 @@ export default class InteractiveMessageHandler {
463
472
  }
464
473
  }
465
474
 
475
+ const messageId = this.bail.generateMessageID();
466
476
  let msg = {
477
+ key: {
478
+ remoteJid: jid,
479
+ fromMe: true,
480
+ id: messageId,
481
+ },
467
482
  message: {
468
483
  groupStatusMessageV2: {
469
484
  message: waMsgContent.message || waMsgContent
470
485
  }
471
- }
486
+ },
487
+ messageTimestamp: Math.floor(Date.now() / 1000),
472
488
  };
473
489
 
474
- return await this.relayMessage(jid, msg.message, {
475
- messageId: this.bail.generateMessageID()
490
+ await this.relayMessage(jid, msg.message, {
491
+ messageId,
492
+ skipStoreEmit: true,
476
493
  });
494
+ this.emitUpsert(msg);
495
+
496
+ return msg;
477
497
  }
478
- }
498
+ }