amiudmodz 5.0.1 → 5.0.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.
@@ -402,9 +402,11 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
402
402
  let didSaveToTmpPath = false;
403
403
  let fileLength = 0;
404
404
  const sha256 = Crypto.createHash('sha256');
405
- const encWriteStream = new stream_1.PassThrough();
406
405
 
407
- // if it's already a file, we can use its path
406
+ // Always save prepared data to a temp file for large files support and retries
407
+ const preparedPath = (0, path_1.join)(getTmpFilesDirectory(), `prepared-${mediaType}-${(0, generics_1.generateMessageID)()}`);
408
+ const preparedWriteStream = (0, fs_1.createWriteStream)(preparedPath);
409
+
408
410
  if (type === 'file') {
409
411
  bodyPath = media.url;
410
412
  } else if (saveOriginalFileIfRequired) {
@@ -423,10 +425,12 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
423
425
  await (0, events_1.once)(writeStream, 'drain');
424
426
  }
425
427
  }
426
- encWriteStream.write(chunk);
428
+ if (!preparedWriteStream.write(chunk)) {
429
+ await (0, events_1.once)(preparedWriteStream, 'drain');
430
+ }
427
431
  }
428
432
 
429
- encWriteStream.end();
433
+ preparedWriteStream.end();
430
434
  writeStream?.end();
431
435
 
432
436
  const fileSha256 = sha256.digest();
@@ -434,18 +438,22 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
434
438
 
435
439
  return {
436
440
  mediaKey: undefined,
437
- encWriteStream, // Now a stream, not a buffer
441
+ encWriteStream: (0, fs_1.createReadStream)(preparedPath),
438
442
  fileLength,
439
443
  fileSha256,
440
444
  fileEncSha256: undefined,
441
445
  bodyPath,
446
+ streamPath: preparedPath,
442
447
  didSaveToTmpPath
443
448
  };
444
449
  }
445
450
  catch (error) {
446
451
  stream.destroy();
447
- encWriteStream.destroy();
452
+ preparedWriteStream.destroy();
448
453
  writeStream?.destroy();
454
+ try {
455
+ await fs_1.promises.unlink(preparedPath);
456
+ } catch {}
449
457
  if (didSaveToTmpPath) {
450
458
  try {
451
459
  await fs_1.promises.unlink(bodyPath);
@@ -460,7 +468,6 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
460
468
  exports.prepareStream = prepareStream;
461
469
  const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts, isPtt, forceOpus } = {}) => {
462
470
  const { stream, type } = await (0, exports.getStream)(media, opts);
463
-
464
471
  let finalStream = stream;
465
472
  let opusConverted = false;
466
473
  if (mediaType === 'audio' && (isPtt === true || forceOpus === true)) {
@@ -469,19 +476,22 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
469
476
  const opusBuffer = await exports.convertToOpusBuffer(buffer, logger);
470
477
  finalStream = (0, exports.toReadable)(opusBuffer);
471
478
  opusConverted = true;
472
- } catch (error) {
479
+ }
480
+ catch (error) {
473
481
  const { stream: newStream } = await (0, exports.getStream)(media, opts);
474
482
  finalStream = newStream;
475
483
  }
476
484
  }
477
-
478
485
  const mediaKey = Crypto.randomBytes(32);
479
486
  const { cipherKey, iv, macKey } = getMediaKeys(mediaKey, mediaType);
480
- const encWriteStream = new stream_1.Readable({ read: () => { } });
487
+
488
+ // Always save encrypted data to a temp file for 2GB support and retries
489
+ const encPath = (0, path_1.join)(getTmpFilesDirectory(), `enc-${mediaType}-${(0, generics_1.generateMessageID)()}`);
490
+ const encTempWriteStream = (0, fs_1.createWriteStream)(encPath);
491
+
481
492
  let bodyPath;
482
493
  let writeStream;
483
494
  let didSaveToTmpPath = false;
484
-
485
495
  if (type === 'file') {
486
496
  bodyPath = media.url;
487
497
  }
@@ -490,13 +500,11 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
490
500
  writeStream = (0, fs_1.createWriteStream)(bodyPath);
491
501
  didSaveToTmpPath = true;
492
502
  }
493
-
494
503
  let fileLength = 0;
495
504
  const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv);
496
505
  let hmac = Crypto.createHmac('sha256', macKey).update(iv);
497
506
  let sha256Plain = Crypto.createHash('sha256');
498
507
  let sha256Enc = Crypto.createHash('sha256');
499
-
500
508
  try {
501
509
  for await (const data of finalStream) {
502
510
  fileLength += data.length;
@@ -507,31 +515,44 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
507
515
  data: { media, type }
508
516
  });
509
517
  }
510
-
511
518
  sha256Plain = sha256Plain.update(data);
512
519
  if (writeStream) {
513
520
  if (!writeStream.write(data)) {
514
521
  await (0, events_1.once)(writeStream, 'drain');
515
522
  }
516
523
  }
517
- onChunk(aes.update(data));
524
+ const encrypted = aes.update(data);
525
+ sha256Enc = sha256Enc.update(encrypted);
526
+ hmac = hmac.update(encrypted);
527
+ if (!encTempWriteStream.write(encrypted)) {
528
+ await (0, events_1.once)(encTempWriteStream, 'drain');
529
+ }
530
+ }
531
+ const finalEnc = aes.final();
532
+ sha256Enc = sha256Enc.update(finalEnc);
533
+ hmac = hmac.update(finalEnc);
534
+ if (!encTempWriteStream.write(finalEnc)) {
535
+ await (0, events_1.once)(encTempWriteStream, 'drain');
518
536
  }
519
537
 
520
- onChunk(aes.final());
521
538
  const mac = hmac.digest().slice(0, 10);
522
539
  sha256Enc = sha256Enc.update(mac);
540
+ if (!encTempWriteStream.write(mac)) {
541
+ await (0, events_1.once)(encTempWriteStream, 'drain');
542
+ }
543
+
523
544
  const fileSha256 = sha256Plain.digest();
524
545
  const fileEncSha256 = sha256Enc.digest();
525
-
526
- encWriteStream.push(mac);
527
- encWriteStream.push(null);
546
+
547
+ encTempWriteStream.end();
528
548
  writeStream === null || writeStream === void 0 ? void 0 : writeStream.end();
529
549
  finalStream.destroy();
530
550
 
531
551
  return {
532
552
  mediaKey,
533
- encWriteStream,
553
+ encWriteStream: (0, fs_1.createReadStream)(encPath),
534
554
  bodyPath,
555
+ streamPath: encPath,
535
556
  mac,
536
557
  fileEncSha256,
537
558
  fileSha256,
@@ -541,14 +562,16 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
541
562
  };
542
563
  }
543
564
  catch (error) {
544
- encWriteStream.destroy();
565
+ encTempWriteStream.destroy();
545
566
  writeStream === null || writeStream === void 0 ? void 0 : writeStream.destroy();
546
567
  aes.destroy();
547
568
  hmac.destroy();
548
569
  sha256Plain.destroy();
549
570
  sha256Enc.destroy();
550
571
  finalStream.destroy();
551
-
572
+ try {
573
+ await fs_1.promises.unlink(encPath);
574
+ } catch {}
552
575
  if (didSaveToTmpPath) {
553
576
  try {
554
577
  await fs_1.promises.unlink(bodyPath);
@@ -558,12 +581,6 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
558
581
  }
559
582
  throw error;
560
583
  }
561
-
562
- function onChunk(buff) {
563
- sha256Enc = sha256Enc.update(buff);
564
- hmac = hmac.update(buff);
565
- encWriteStream.push(buff);
566
- }
567
584
  };
568
585
  exports.encryptedStream = encryptedStream;
569
586
  const DEF_HOST = 'mmg.whatsapp.net';
@@ -684,14 +701,14 @@ function extensionForMediaMessage(message) {
684
701
  }
685
702
  exports.extensionForMediaMessage = extensionForMediaMessage;
686
703
  const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
687
- return async (stream, { mediaType, fileEncSha256B64, newsletter, timeoutMs, fileLength }) => {
704
+ return async (stream, { mediaType, fileEncSha256B64, newsletter, timeoutMs, fileLength, streamPath }) => {
688
705
  var _a, _b;
689
706
  const { default: axios } = await import('axios');
707
+ const { createReadStream } = await import('fs');
690
708
 
691
709
  let uploadInfo = await refreshMediaConn(false);
692
710
  let urls;
693
711
  const hosts = [...customUploadHosts, ...uploadInfo.hosts];
694
- const reqBody = stream;
695
712
  fileEncSha256B64 = (0, exports.encodeBase64EncodedStringForUpload)(fileEncSha256B64);
696
713
  let media = Defaults_1.MEDIA_PATH_MAP[mediaType];
697
714
  if (newsletter) {
@@ -701,6 +718,11 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
701
718
  logger.debug(`uploading to "${hostname}"`);
702
719
  const auth = encodeURIComponent(uploadInfo.auth);
703
720
  const url = `https://${hostname}${media}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
721
+
722
+ // Re-create stream if retrying and we have a path
723
+ // This is essential for large files (2GB) as the first stream will be consumed
724
+ const reqBody = streamPath ? createReadStream(streamPath) : stream;
725
+
704
726
  let result;
705
727
  try {
706
728
  const bodyLength = fileLength || (Buffer.isBuffer(reqBody) ? reqBody.length : 0);
@@ -149,7 +149,7 @@ const prepareWAMessageMedia = async (message, options) => {
149
149
  const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
150
150
  const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
151
151
 
152
- const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, opusConverted } = await (options.newsletter ? messages_media_1.prepareStream : messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
152
+ const { mediaKey, encWriteStream, bodyPath, streamPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, opusConverted } = await (options.newsletter ? messages_media_1.prepareStream : messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
153
153
  logger,
154
154
  saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
155
155
  opts: options.options,
@@ -165,7 +165,7 @@ const prepareWAMessageMedia = async (message, options) => {
165
165
 
166
166
  const [{ mediaUrl, directPath, handle }] = await Promise.all([
167
167
  (async () => {
168
- const result = await options.upload(encWriteStream, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs, fileLength });
168
+ const result = await options.upload(encWriteStream, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs, fileLength, streamPath });
169
169
  logger === null || logger === void 0 ? void 0 : logger.debug({ mediaType, cacheableKey }, 'uploaded media');
170
170
  return result;
171
171
  })(),
@@ -205,9 +205,12 @@ const prepareWAMessageMedia = async (message, options) => {
205
205
  }
206
206
 
207
207
  if (didSaveToTmpPath && bodyPath) {
208
- await fs_1.promises.unlink(bodyPath);
209
- logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp files');
208
+ await fs_1.promises.unlink(bodyPath).catch(() => { });
210
209
  }
210
+ if (streamPath) {
211
+ await fs_1.promises.unlink(streamPath).catch(() => { });
212
+ }
213
+ logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp files');
211
214
  });
212
215
 
213
216
  const obj = Types_1.WAProto.Message.fromObject({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amiudmodz",
3
- "version": "5.0.1",
3
+ "version": "5.0.2",
4
4
  "description": "WhatsApp Baileys mod Powered by UDMODZ",
5
5
  "keywords": [
6
6
  "whatsapp",