@zetagoaurum-socket/decagramton 3.2.5 → 3.2.7

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 (92) hide show
  1. package/README.md +91 -91
  2. package/WAProto/index.js +56886 -17506
  3. package/engine-requirements.js +91 -0
  4. package/lib/Defaults/index.js +47 -2
  5. package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
  6. package/lib/Signal/Group/ciphertext-message.js +15 -0
  7. package/lib/Signal/Group/group-session-builder.d.ts +14 -0
  8. package/lib/Signal/Group/group-session-builder.js +64 -0
  9. package/lib/Signal/Group/group_cipher.d.ts +17 -0
  10. package/lib/Signal/Group/group_cipher.js +96 -0
  11. package/lib/Signal/Group/index.d.ts +11 -0
  12. package/lib/Signal/Group/index.js +57 -0
  13. package/lib/Signal/Group/keyhelper.d.ts +10 -0
  14. package/lib/Signal/Group/keyhelper.js +55 -0
  15. package/lib/Signal/Group/queue-job.d.ts +1 -0
  16. package/lib/Signal/Group/queue-job.js +57 -0
  17. package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
  18. package/lib/Signal/Group/sender-chain-key.js +34 -0
  19. package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
  20. package/lib/Signal/Group/sender-key-distribution-message.js +66 -0
  21. package/lib/Signal/Group/sender-key-message.d.ts +18 -0
  22. package/lib/Signal/Group/sender-key-message.js +69 -0
  23. package/lib/Signal/Group/sender-key-name.d.ts +17 -0
  24. package/lib/Signal/Group/sender-key-name.js +51 -0
  25. package/lib/Signal/Group/sender-key-record.d.ts +30 -0
  26. package/lib/Signal/Group/sender-key-record.js +53 -0
  27. package/lib/Signal/Group/sender-key-state.d.ts +38 -0
  28. package/lib/Signal/Group/sender-key-state.js +99 -0
  29. package/lib/Signal/Group/sender-message-key.d.ts +11 -0
  30. package/{WASignalGroup/sender_message_key.js → lib/Signal/Group/sender-message-key.js} +6 -16
  31. package/lib/Signal/libsignal.js +51 -29
  32. package/lib/Socket/business.d.ts +3 -2
  33. package/lib/Socket/chats.d.ts +215 -28
  34. package/lib/Socket/chats.js +166 -70
  35. package/lib/Socket/dugong.d.ts +254 -0
  36. package/lib/Socket/dugong.js +432 -141
  37. package/lib/Socket/groups.js +20 -23
  38. package/lib/Socket/index.js +2 -15
  39. package/lib/Socket/messages-recv.d.ts +56 -55
  40. package/lib/Socket/messages-recv.js +367 -131
  41. package/lib/Socket/messages-send.d.ts +3 -2
  42. package/lib/Socket/messages-send.js +423 -380
  43. package/lib/Socket/newsletter.js +147 -21
  44. package/lib/Socket/socket.js +156 -148
  45. package/lib/Socket/usync.d.ts +3 -3
  46. package/lib/Types/GroupMetadata.d.ts +1 -0
  47. package/lib/Types/Newsletter.d.ts +97 -86
  48. package/lib/Types/Newsletter.js +38 -32
  49. package/lib/Types/USync.d.ts +25 -0
  50. package/lib/Types/USync.js +2 -0
  51. package/lib/Utils/anti-crash.js +31 -0
  52. package/lib/Utils/chat-utils.js +6 -1
  53. package/lib/Utils/generics.js +66 -34
  54. package/lib/Utils/history.js +6 -1
  55. package/lib/Utils/index.js +0 -1
  56. package/lib/Utils/link-preview.js +1 -1
  57. package/lib/Utils/messages-media.js +145 -57
  58. package/lib/Utils/messages.js +92 -306
  59. package/lib/Utils/signal.js +48 -46
  60. package/lib/Utils/use-multi-file-auth-state.js +45 -6
  61. package/lib/Utils/validate-connection.js +89 -65
  62. package/lib/WABinary/constants.d.ts +27 -24
  63. package/lib/WABinary/encode.js +160 -123
  64. package/lib/WABinary/generic-utils.d.ts +2 -0
  65. package/lib/WABinary/generic-utils.js +124 -36
  66. package/lib/WABinary/jid-utils.js +5 -26
  67. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -1
  68. package/lib/index.d.ts +1 -0
  69. package/lib/index.js +56 -0
  70. package/package.json +107 -101
  71. package/LICENSE +0 -21
  72. package/WAProto/GenerateStatics.sh +0 -4
  73. package/WAProto/WAProto.proto +0 -3344
  74. package/WAProto/index.d.ts +0 -37016
  75. package/WASignalGroup/GroupProtocol.js +0 -1697
  76. package/WASignalGroup/ciphertext_message.js +0 -16
  77. package/WASignalGroup/group_cipher.js +0 -120
  78. package/WASignalGroup/group_session_builder.js +0 -46
  79. package/WASignalGroup/index.js +0 -5
  80. package/WASignalGroup/keyhelper.js +0 -21
  81. package/WASignalGroup/protobufs.js +0 -3
  82. package/WASignalGroup/queue_job.js +0 -69
  83. package/WASignalGroup/sender_chain_key.js +0 -50
  84. package/WASignalGroup/sender_key_distribution_message.js +0 -78
  85. package/WASignalGroup/sender_key_message.js +0 -92
  86. package/WASignalGroup/sender_key_name.js +0 -70
  87. package/WASignalGroup/sender_key_record.js +0 -56
  88. package/WASignalGroup/sender_key_state.js +0 -129
  89. package/decagramton.jpg +0 -0
  90. package/lib/Utils/rate-limiter.js +0 -55
  91. package/lib/WAUSync/Fall +0 -1
  92. package/lib/WAUSync/Protocols/Fal +0 -1
@@ -188,68 +188,138 @@ const mediaMessageSHA256B64 = (message) => {
188
188
  };
189
189
  exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
190
190
  async function getAudioDuration(buffer) {
191
- const musicMetadata = await import('music-metadata');
192
- let metadata;
193
- if (Buffer.isBuffer(buffer)) {
194
- metadata = await musicMetadata.parseBuffer(buffer, undefined, { duration: true });
195
- }
196
- else if (typeof buffer === 'string') {
197
- const rStream = (0, fs_1.createReadStream)(buffer);
198
- try {
199
- metadata = await musicMetadata.parseStream(rStream, undefined, { duration: true });
200
- }
201
- finally {
202
- rStream.destroy();
191
+ try {
192
+ const { PassThrough } = require('stream');
193
+ const ff = require('fluent-ffmpeg');
194
+
195
+ return await new Promise((resolve, reject) => {
196
+ const inputStream = new PassThrough();
197
+ inputStream.end(buffer);
198
+
199
+ ff(inputStream)
200
+ .ffprobe((err, data) => {
201
+ if (err) reject(err);
202
+ else resolve(data.format.duration);
203
+ });
204
+ });
205
+ } catch (error) {
206
+ const musicMetadata = await import('music-metadata');
207
+ let metadata;
208
+ if (Buffer.isBuffer(buffer)) {
209
+ metadata = await musicMetadata.parseBuffer(buffer, undefined, {
210
+ duration: true
211
+ });
212
+ } else if (typeof buffer === 'string') {
213
+ const rStream = (0, fs_1.createReadStream)(buffer);
214
+ try {
215
+ metadata = await musicMetadata.parseStream(rStream, undefined, {
216
+ duration: true
217
+ });
218
+ } finally {
219
+ rStream.destroy();
220
+ }
221
+ } else {
222
+ metadata = await musicMetadata.parseStream(buffer, undefined, {
223
+ duration: true
224
+ });
203
225
  }
226
+ return metadata.format.duration;
204
227
  }
205
- else {
206
- metadata = await musicMetadata.parseStream(buffer, undefined, { duration: true });
207
- }
208
- return metadata.format.duration;
209
228
  }
210
229
  exports.getAudioDuration = getAudioDuration;
211
- /**
212
- referenced from and modifying https://github.com/wppconnect-team/wa-js/blob/main/src/chat/functions/prepareAudioWaveform.ts
213
- */
214
230
  async function getAudioWaveform(buffer, logger) {
215
231
  try {
216
- const audioDecode = (buffer) => import('audio-decode').then(({ default: audioDecode }) => audioDecode(buffer));
232
+ const { PassThrough } = require('stream');
233
+ const ff = require('fluent-ffmpeg');
234
+
217
235
  let audioData;
218
236
  if (Buffer.isBuffer(buffer)) {
219
237
  audioData = buffer;
238
+ } else if (typeof buffer === 'string') {
239
+ const rStream = require('fs').createReadStream(buffer);
240
+ audioData = await exports.toBuffer(rStream);
241
+ } else {
242
+ audioData = await exports.toBuffer(buffer);
220
243
  }
221
- else if (typeof buffer === 'string') {
222
- const rStream = (0, fs_1.createReadStream)(buffer);
223
- audioData = await (0, exports.toBuffer)(rStream);
224
- }
225
- else {
226
- audioData = await (0, exports.toBuffer)(buffer);
227
- }
228
- const audioBuffer = await audioDecode(audioData);
229
- const rawData = audioBuffer.getChannelData(0); // We only need to work with one channel of data
230
- const samples = 64; // Number of samples we want to have in our final data set
231
- const blockSize = Math.floor(rawData.length / samples); // the number of samples in each subdivision
232
- const filteredData = [];
233
- for (let i = 0; i < samples; i++) {
234
- const blockStart = blockSize * i; // the location of the first sample in the block
235
- let sum = 0;
236
- for (let j = 0; j < blockSize; j++) {
237
- sum = sum + Math.abs(rawData[blockStart + j]); // find the sum of all the samples in the block
238
- }
239
- filteredData.push(sum / blockSize); // divide the sum by the block size to get the average
240
- }
241
- // This guarantees that the largest data point will be set to 1, and the rest of the data will scale proportionally.
242
- const multiplier = Math.pow(Math.max(...filteredData), -1);
243
- const normalizedData = filteredData.map((n) => n * multiplier);
244
- // Generate waveform like WhatsApp
245
- const waveform = new Uint8Array(normalizedData.map((n) => Math.floor(100 * n)));
246
- return waveform;
247
- }
248
- catch (e) {
249
- logger === null || logger === void 0 ? void 0 : logger.debug('Failed to generate waveform: ' + e);
244
+
245
+ return await new Promise((resolve, reject) => {
246
+ const inputStream = new PassThrough();
247
+ inputStream.end(audioData);
248
+ const chunks = [];
249
+ const bars = 64;
250
+
251
+ ff(inputStream)
252
+ .audioChannels(1)
253
+ .audioFrequency(16000)
254
+ .format('s16le')
255
+ .on('error', reject)
256
+ .on('end', () => {
257
+ const rawData = Buffer.concat(chunks);
258
+ const samples = rawData.length / 2;
259
+ const amplitudes = [];
260
+
261
+ for (let i = 0; i < samples; i++) {
262
+ amplitudes.push(Math.abs(rawData.readInt16LE(i * 2)) / 32768);
263
+ }
264
+
265
+ const blockSize = Math.floor(amplitudes.length / bars);
266
+ const avg = [];
267
+ for (let i = 0; i < bars; i++) {
268
+ const block = amplitudes.slice(i * blockSize, (i + 1) * blockSize);
269
+ avg.push(block.reduce((a, b) => a + b, 0) / block.length);
270
+ }
271
+
272
+ const max = Math.max(...avg);
273
+ const normalized = avg.map(v => Math.floor((v / max) * 100));
274
+ resolve(new Uint8Array(normalized));
275
+ })
276
+ .pipe()
277
+ .on('data', chunk => chunks.push(chunk));
278
+ });
279
+ } catch (e) {
280
+ logger?.debug(e);
250
281
  }
251
282
  }
252
283
  exports.getAudioWaveform = getAudioWaveform;
284
+ async function convertToOpusBuffer(buffer, logger) {
285
+ try {
286
+ const { PassThrough } = require('stream');
287
+ const ff = require('fluent-ffmpeg');
288
+
289
+ return await new Promise((resolve, reject) => {
290
+ const inStream = new PassThrough();
291
+ const outStream = new PassThrough();
292
+ const chunks = [];
293
+ inStream.end(buffer);
294
+
295
+ ff(inStream)
296
+ .noVideo()
297
+ .audioCodec('libopus')
298
+ .format('ogg')
299
+ .audioBitrate('48k')
300
+ .audioChannels(1)
301
+ .audioFrequency(48000)
302
+ .outputOptions([
303
+ '-vn',
304
+ '-b:a 64k',
305
+ '-ac 2',
306
+ '-ar 48000',
307
+ '-map_metadata', '-1',
308
+ '-application', 'voip'
309
+ ])
310
+ .on('error', reject)
311
+ .on('end', () => resolve(Buffer.concat(chunks)))
312
+ .pipe(outStream, {
313
+ end: true
314
+ });
315
+ outStream.on('data', c => chunks.push(c));
316
+ });
317
+ } catch (e) {
318
+ logger?.debug(e);
319
+ throw e;
320
+ }
321
+ }
322
+ exports.convertToOpusBuffer = convertToOpusBuffer;
253
323
  const toReadable = (buffer) => {
254
324
  const readable = new stream_1.Readable({ read: () => { } });
255
325
  readable.push(buffer);
@@ -362,15 +432,28 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
362
432
  }
363
433
  };
364
434
  exports.prepareStream = prepareStream;
365
- const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
435
+ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts, isPtt, forceOpus } = {}) => {
366
436
  const { stream, type } = await (0, exports.getStream)(media, opts);
367
- logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
437
+
438
+ let finalStream = stream;
439
+ if (mediaType === 'audio' && (isPtt === true || forceOpus === true)) {
440
+ try {
441
+ const buffer = await (0, exports.toBuffer)(stream);
442
+ const opusBuffer = await exports.convertToOpusBuffer(buffer, logger);
443
+ finalStream = (0, exports.toReadable)(opusBuffer);
444
+ } catch (error) {
445
+ const { stream: newStream } = await (0, exports.getStream)(media, opts);
446
+ finalStream = newStream;
447
+ }
448
+ }
449
+
368
450
  const mediaKey = Crypto.randomBytes(32);
369
451
  const { cipherKey, iv, macKey } = getMediaKeys(mediaKey, mediaType);
370
452
  const encWriteStream = new stream_1.Readable({ read: () => { } });
371
453
  let bodyPath;
372
454
  let writeStream;
373
455
  let didSaveToTmpPath = false;
456
+
374
457
  if (type === 'file') {
375
458
  bodyPath = media.url;
376
459
  }
@@ -379,13 +462,15 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
379
462
  writeStream = (0, fs_1.createWriteStream)(bodyPath);
380
463
  didSaveToTmpPath = true;
381
464
  }
465
+
382
466
  let fileLength = 0;
383
467
  const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv);
384
468
  let hmac = Crypto.createHmac('sha256', macKey).update(iv);
385
469
  let sha256Plain = Crypto.createHash('sha256');
386
470
  let sha256Enc = Crypto.createHash('sha256');
471
+
387
472
  try {
388
- for await (const data of stream) {
473
+ for await (const data of finalStream) {
389
474
  fileLength += data.length;
390
475
  if (type === 'remote'
391
476
  && (opts === null || opts === void 0 ? void 0 : opts.maxContentLength)
@@ -394,6 +479,7 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
394
479
  data: { media, type }
395
480
  });
396
481
  }
482
+
397
483
  sha256Plain = sha256Plain.update(data);
398
484
  if (writeStream) {
399
485
  if (!writeStream.write(data)) {
@@ -402,16 +488,18 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
402
488
  }
403
489
  onChunk(aes.update(data));
404
490
  }
491
+
405
492
  onChunk(aes.final());
406
493
  const mac = hmac.digest().slice(0, 10);
407
494
  sha256Enc = sha256Enc.update(mac);
408
495
  const fileSha256 = sha256Plain.digest();
409
496
  const fileEncSha256 = sha256Enc.digest();
497
+
410
498
  encWriteStream.push(mac);
411
499
  encWriteStream.push(null);
412
500
  writeStream === null || writeStream === void 0 ? void 0 : writeStream.end();
413
- stream.destroy();
414
- logger === null || logger === void 0 ? void 0 : logger.debug('encrypted data successfully');
501
+ finalStream.destroy();
502
+
415
503
  return {
416
504
  mediaKey,
417
505
  encWriteStream,
@@ -424,24 +512,24 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
424
512
  };
425
513
  }
426
514
  catch (error) {
427
- // destroy all streams with error
428
515
  encWriteStream.destroy();
429
516
  writeStream === null || writeStream === void 0 ? void 0 : writeStream.destroy();
430
517
  aes.destroy();
431
518
  hmac.destroy();
432
519
  sha256Plain.destroy();
433
520
  sha256Enc.destroy();
434
- stream.destroy();
521
+ finalStream.destroy();
522
+
435
523
  if (didSaveToTmpPath) {
436
524
  try {
437
525
  await fs_1.promises.unlink(bodyPath);
438
526
  }
439
527
  catch (err) {
440
- logger === null || logger === void 0 ? void 0 : logger.error({ err }, 'failed to save to tmp path');
441
528
  }
442
529
  }
443
530
  throw error;
444
531
  }
532
+
445
533
  function onChunk(buff) {
446
534
  sha256Enc = sha256Enc.update(buff);
447
535
  hmac = hmac.update(buff);