@d0v3riz/baileys 6.7.18 → 6.7.19

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.
@@ -217,7 +217,7 @@ export type MiscMessageGenerationOptions = MinimalRelayOptions & {
217
217
  export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions & {
218
218
  userJid: string;
219
219
  };
220
- export type WAMediaUploadFunction = (readStream: Readable, opts: {
220
+ export type WAMediaUploadFunction = (encFilePath: string, opts: {
221
221
  fileEncSha256B64: string;
222
222
  mediaType: MediaType;
223
223
  timeoutMs?: number;
@@ -4,7 +4,11 @@ exports.uploadingNecessaryImages = exports.parseProductNode = exports.toProductN
4
4
  exports.uploadingNecessaryImagesOfProduct = uploadingNecessaryImagesOfProduct;
5
5
  const boom_1 = require("@hapi/boom");
6
6
  const crypto_1 = require("crypto");
7
+ const fs_1 = require("fs");
8
+ const os_1 = require("os");
9
+ const path_1 = require("path");
7
10
  const WABinary_1 = require("../WABinary");
11
+ const generics_1 = require("./generics");
8
12
  const messages_media_1 = require("./messages-media");
9
13
  const parseCatalogNode = (node) => {
10
14
  const catalogNode = (0, WABinary_1.getBinaryNodeChild)(node, 'product_catalog');
@@ -202,17 +206,21 @@ const uploadingNecessaryImages = async (images, waUploadToServer, timeoutMs = 30
202
206
  }
203
207
  const { stream } = await (0, messages_media_1.getStream)(img);
204
208
  const hasher = (0, crypto_1.createHash)('sha256');
205
- const contentBlocks = [];
209
+ const filePath = (0, path_1.join)((0, os_1.tmpdir)(), 'img' + (0, generics_1.generateMessageIDV2)());
210
+ const encFileWriteStream = (0, fs_1.createWriteStream)(filePath);
206
211
  for await (const block of stream) {
207
212
  hasher.update(block);
208
- contentBlocks.push(block);
213
+ encFileWriteStream.write(block);
209
214
  }
210
215
  const sha = hasher.digest('base64');
211
- const { directPath } = await waUploadToServer((0, messages_media_1.toReadable)(Buffer.concat(contentBlocks)), {
216
+ const { directPath } = await waUploadToServer(filePath, {
212
217
  mediaType: 'product-catalog-image',
213
218
  fileEncSha256B64: sha,
214
219
  timeoutMs
215
220
  });
221
+ await fs_1.promises
222
+ .unlink(filePath)
223
+ .catch(err => console.log('Error deleting temp file ', err));
216
224
  return { url: (0, messages_media_1.getUrlFromDirectPath)(directPath) };
217
225
  }));
218
226
  return results;
@@ -62,13 +62,12 @@ type EncryptedStreamOptions = {
62
62
  };
63
63
  export declare const encryptedStream: (media: WAMediaUpload, mediaType: MediaType, { logger, saveOriginalFileIfRequired, opts }?: EncryptedStreamOptions) => Promise<{
64
64
  mediaKey: Buffer<ArrayBufferLike>;
65
- encWriteStream: Readable;
66
- bodyPath: string | undefined;
65
+ originalFilePath: string | undefined;
66
+ encFilePath: string;
67
67
  mac: Buffer<ArrayBuffer>;
68
68
  fileEncSha256: Buffer<ArrayBufferLike>;
69
69
  fileSha256: Buffer<ArrayBufferLike>;
70
70
  fileLength: number;
71
- didSaveToTmpPath: boolean;
72
71
  }>;
73
72
  export type MediaDownloadOptions = {
74
73
  startByte?: number;
@@ -331,27 +331,29 @@ const getHttpStream = async (url, options = {}) => {
331
331
  };
332
332
  exports.getHttpStream = getHttpStream;
333
333
  const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
334
+ var _a, _b;
334
335
  const { stream, type } = await (0, exports.getStream)(media, opts);
335
336
  logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
336
337
  const mediaKey = Crypto.randomBytes(32);
337
338
  const { cipherKey, iv, macKey } = await getMediaKeys(mediaKey, mediaType);
338
- const encWriteStream = new stream_1.Readable({ read: () => { } });
339
- let bodyPath;
340
- let writeStream;
341
- let didSaveToTmpPath = false;
342
- if (type === 'file') {
343
- bodyPath = media.url.toString();
344
- }
345
- else if (saveOriginalFileIfRequired) {
346
- bodyPath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageIDV2)());
347
- writeStream = (0, fs_1.createWriteStream)(bodyPath);
348
- didSaveToTmpPath = true;
339
+ const encFilePath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageIDV2)() + '-enc');
340
+ const encFileWriteStream = (0, fs_1.createWriteStream)(encFilePath);
341
+ let originalFileStream;
342
+ let originalFilePath;
343
+ if (saveOriginalFileIfRequired) {
344
+ originalFilePath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageIDV2)() + '-original');
345
+ originalFileStream = (0, fs_1.createWriteStream)(originalFilePath);
349
346
  }
350
347
  let fileLength = 0;
351
348
  const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv);
352
- let hmac = Crypto.createHmac('sha256', macKey).update(iv);
353
- let sha256Plain = Crypto.createHash('sha256');
354
- let sha256Enc = Crypto.createHash('sha256');
349
+ const hmac = Crypto.createHmac('sha256', macKey).update(iv);
350
+ const sha256Plain = Crypto.createHash('sha256');
351
+ const sha256Enc = Crypto.createHash('sha256');
352
+ const onChunk = (buff) => {
353
+ sha256Enc.update(buff);
354
+ hmac.update(buff);
355
+ encFileWriteStream.write(buff);
356
+ };
355
357
  try {
356
358
  for await (const data of stream) {
357
359
  fileLength += data.length;
@@ -362,57 +364,54 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
362
364
  data: { media, type }
363
365
  });
364
366
  }
365
- sha256Plain = sha256Plain.update(data);
366
- if (writeStream && !writeStream.write(data)) {
367
- await (0, events_1.once)(writeStream, 'drain');
367
+ if (originalFileStream) {
368
+ if (!originalFileStream.write(data)) {
369
+ await (0, events_1.once)(originalFileStream, 'drain');
370
+ }
368
371
  }
372
+ sha256Plain.update(data);
369
373
  onChunk(aes.update(data));
370
374
  }
371
375
  onChunk(aes.final());
372
376
  const mac = hmac.digest().slice(0, 10);
373
- sha256Enc = sha256Enc.update(mac);
377
+ sha256Enc.update(mac);
374
378
  const fileSha256 = sha256Plain.digest();
375
379
  const fileEncSha256 = sha256Enc.digest();
376
- encWriteStream.push(mac);
377
- encWriteStream.push(null);
378
- writeStream === null || writeStream === void 0 ? void 0 : writeStream.end();
380
+ encFileWriteStream.write(mac);
381
+ encFileWriteStream.end();
382
+ (_a = originalFileStream === null || originalFileStream === void 0 ? void 0 : originalFileStream.end) === null || _a === void 0 ? void 0 : _a.call(originalFileStream);
379
383
  stream.destroy();
380
384
  logger === null || logger === void 0 ? void 0 : logger.debug('encrypted data successfully');
381
385
  return {
382
386
  mediaKey,
383
- encWriteStream,
384
- bodyPath,
387
+ originalFilePath,
388
+ encFilePath,
385
389
  mac,
386
390
  fileEncSha256,
387
391
  fileSha256,
388
- fileLength,
389
- didSaveToTmpPath
392
+ fileLength
390
393
  };
391
394
  }
392
395
  catch (error) {
393
396
  // destroy all streams with error
394
- encWriteStream.destroy();
395
- writeStream === null || writeStream === void 0 ? void 0 : writeStream.destroy();
397
+ encFileWriteStream.destroy();
398
+ (_b = originalFileStream === null || originalFileStream === void 0 ? void 0 : originalFileStream.destroy) === null || _b === void 0 ? void 0 : _b.call(originalFileStream);
396
399
  aes.destroy();
397
400
  hmac.destroy();
398
401
  sha256Plain.destroy();
399
402
  sha256Enc.destroy();
400
403
  stream.destroy();
401
- if (didSaveToTmpPath) {
402
- try {
403
- await fs_1.promises.unlink(bodyPath);
404
- }
405
- catch (err) {
406
- logger === null || logger === void 0 ? void 0 : logger.error({ err }, 'failed to save to tmp path');
404
+ try {
405
+ await fs_1.promises.unlink(encFilePath);
406
+ if (originalFilePath) {
407
+ await fs_1.promises.unlink(originalFilePath);
407
408
  }
408
409
  }
410
+ catch (err) {
411
+ logger === null || logger === void 0 ? void 0 : logger.error({ err }, 'failed deleting tmp files');
412
+ }
409
413
  throw error;
410
414
  }
411
- function onChunk(buff) {
412
- sha256Enc = sha256Enc.update(buff);
413
- hmac = hmac.update(buff);
414
- encWriteStream.push(buff);
415
- }
416
415
  };
417
416
  exports.encryptedStream = encryptedStream;
418
417
  const DEF_HOST = 'mmg.whatsapp.net';
@@ -532,7 +531,7 @@ function extensionForMediaMessage(message) {
532
531
  return extension;
533
532
  }
534
533
  const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
535
- return async (stream, { mediaType, fileEncSha256B64, timeoutMs }) => {
534
+ return async (filePath, { mediaType, fileEncSha256B64, timeoutMs }) => {
536
535
  var _a, _b;
537
536
  // send a query JSON to obtain the url & auth token to upload our media
538
537
  let uploadInfo = await refreshMediaConn(false);
@@ -546,8 +545,9 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
546
545
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
547
546
  let result;
548
547
  try {
549
- const body = await axios_1.default.post(url, stream, {
548
+ const body = await axios_1.default.post(url, (0, fs_1.createReadStream)(filePath), {
550
549
  ...options,
550
+ maxRedirects: 0,
551
551
  headers: {
552
552
  ...options.headers || {},
553
553
  'Content-Type': 'application/octet-stream',
@@ -111,7 +111,7 @@ const prepareWAMessageMedia = async (message, options) => {
111
111
  const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
112
112
  const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
113
113
  const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
114
- const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath } = await (0, messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
114
+ const { mediaKey, encFilePath, originalFilePath, fileEncSha256, fileSha256, fileLength } = await (0, messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
115
115
  logger,
116
116
  saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
117
117
  opts: options.options
@@ -120,14 +120,14 @@ const prepareWAMessageMedia = async (message, options) => {
120
120
  const fileEncSha256B64 = fileEncSha256.toString('base64');
121
121
  const [{ mediaUrl, directPath }] = await Promise.all([
122
122
  (async () => {
123
- const result = await options.upload(encWriteStream, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs });
123
+ const result = await options.upload(encFilePath, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs });
124
124
  logger === null || logger === void 0 ? void 0 : logger.debug({ mediaType, cacheableKey }, 'uploaded media');
125
125
  return result;
126
126
  })(),
127
127
  (async () => {
128
128
  try {
129
129
  if (requiresThumbnailComputation) {
130
- const { thumbnail, originalImageDimensions } = await (0, messages_media_1.generateThumbnail)(bodyPath, mediaType, options);
130
+ const { thumbnail, originalImageDimensions } = await (0, messages_media_1.generateThumbnail)(originalFilePath, mediaType, options);
131
131
  uploadData.jpegThumbnail = thumbnail;
132
132
  if (!uploadData.width && originalImageDimensions) {
133
133
  uploadData.width = originalImageDimensions.width;
@@ -137,11 +137,11 @@ const prepareWAMessageMedia = async (message, options) => {
137
137
  logger === null || logger === void 0 ? void 0 : logger.debug('generated thumbnail');
138
138
  }
139
139
  if (requiresDurationComputation) {
140
- uploadData.seconds = await (0, messages_media_1.getAudioDuration)(bodyPath);
140
+ uploadData.seconds = await (0, messages_media_1.getAudioDuration)(originalFilePath);
141
141
  logger === null || logger === void 0 ? void 0 : logger.debug('computed audio duration');
142
142
  }
143
143
  if (requiresWaveformProcessing) {
144
- uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(bodyPath, logger);
144
+ uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(originalFilePath, logger);
145
145
  logger === null || logger === void 0 ? void 0 : logger.debug('processed waveform');
146
146
  }
147
147
  if (requiresAudioBackground) {
@@ -155,17 +155,15 @@ const prepareWAMessageMedia = async (message, options) => {
155
155
  })(),
156
156
  ])
157
157
  .finally(async () => {
158
- encWriteStream.destroy();
159
- // remove tmp files
160
- if (didSaveToTmpPath && bodyPath) {
161
- try {
162
- await fs_1.promises.access(bodyPath);
163
- await fs_1.promises.unlink(bodyPath);
164
- logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp file');
165
- }
166
- catch (error) {
167
- logger === null || logger === void 0 ? void 0 : logger.warn('failed to remove tmp file');
158
+ try {
159
+ await fs_1.promises.unlink(encFilePath);
160
+ if (originalFilePath) {
161
+ await fs_1.promises.unlink(originalFilePath);
168
162
  }
163
+ logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp files');
164
+ }
165
+ catch (error) {
166
+ logger === null || logger === void 0 ? void 0 : logger.warn('failed to remove tmp file');
169
167
  }
170
168
  });
171
169
  const obj = Types_1.WAProto.Message.fromObject({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@d0v3riz/baileys",
3
- "version": "6.7.18",
3
+ "version": "6.7.19",
4
4
  "description": "A WebSockets library for interacting with WhatsApp Web",
5
5
  "keywords": [
6
6
  "whatsapp",