@baileys-md/baileys 11.0.3 → 11.1.0

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 (122) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/WAProto/index.js +4182 -13516
  4. package/WASignalGroup/GroupProtocol.js +1697 -0
  5. package/WASignalGroup/ciphertext_message.js +16 -0
  6. package/WASignalGroup/group_cipher.js +120 -0
  7. package/WASignalGroup/group_session_builder.js +46 -0
  8. package/WASignalGroup/index.js +5 -0
  9. package/WASignalGroup/keyhelper.js +21 -0
  10. package/WASignalGroup/protobufs.js +3 -0
  11. package/WASignalGroup/queue_job.js +69 -0
  12. package/WASignalGroup/sender_chain_key.js +50 -0
  13. package/WASignalGroup/sender_key_distribution_message.js +78 -0
  14. package/WASignalGroup/sender_key_message.js +92 -0
  15. package/WASignalGroup/sender_key_name.js +70 -0
  16. package/WASignalGroup/sender_key_record.js +56 -0
  17. package/WASignalGroup/sender_key_state.js +129 -0
  18. package/{lib/Signal/Group/sender-message-key.js → WASignalGroup/sender_message_key.js} +16 -4
  19. package/lib/Defaults/baileys-version.json +3 -0
  20. package/lib/Defaults/index.js +71 -52
  21. package/lib/Defaults/{phonenumber-mcc.js → phonenumber-mcc.json} +1 -1
  22. package/lib/Signal/libsignal.js +61 -41
  23. package/lib/Socket/Client/abstract-socket-client.js +13 -0
  24. package/lib/Socket/Client/index.js +19 -3
  25. package/lib/Socket/Client/mobile-socket-client.js +65 -0
  26. package/lib/Socket/Client/web-socket-client.js +62 -0
  27. package/lib/Socket/business.js +42 -37
  28. package/lib/Socket/chats.js +187 -194
  29. package/lib/Socket/groups.js +90 -87
  30. package/lib/Socket/index.js +8 -7
  31. package/lib/Socket/messages-recv.js +335 -360
  32. package/lib/Socket/messages-send.js +279 -156
  33. package/lib/Socket/newsletter.js +213 -144
  34. package/lib/Socket/registration.js +166 -0
  35. package/lib/Socket/socket.js +161 -128
  36. package/lib/Socket/usync.js +26 -19
  37. package/lib/Store/index.js +8 -0
  38. package/lib/Store/make-cache-manager-store.js +83 -0
  39. package/lib/{Utils → Store}/make-in-memory-store.js +27 -19
  40. package/lib/Store/make-mongo-store.js +567 -0
  41. package/lib/{Utils → Store}/make-ordered-dictionary.js +5 -2
  42. package/lib/{Utils → Store}/object-repository.js +4 -1
  43. package/lib/Types/Auth.js +2 -2
  44. package/lib/Types/Call.js +2 -2
  45. package/lib/Types/Chat.js +4 -8
  46. package/lib/Types/Contact.js +2 -2
  47. package/lib/Types/Events.js +2 -2
  48. package/lib/Types/GroupMetadata.js +2 -2
  49. package/lib/Types/Label.js +5 -3
  50. package/lib/Types/LabelAssociation.js +5 -3
  51. package/lib/Types/Message.js +7 -7
  52. package/lib/Types/Newsletter.js +17 -30
  53. package/lib/Types/Product.js +2 -2
  54. package/lib/Types/Signal.js +2 -2
  55. package/lib/Types/Socket.js +2 -3
  56. package/lib/Types/State.js +2 -2
  57. package/lib/Types/USync.js +2 -2
  58. package/lib/Types/index.js +31 -15
  59. package/lib/Utils/auth-utils.js +47 -31
  60. package/lib/Utils/baileys-event-stream.js +22 -15
  61. package/lib/Utils/business.js +69 -66
  62. package/lib/Utils/chat-utils.js +195 -200
  63. package/lib/Utils/crypto.js +85 -70
  64. package/lib/Utils/decode-wa-message.js +51 -46
  65. package/lib/Utils/event-buffer.js +46 -36
  66. package/lib/Utils/generics.js +188 -116
  67. package/lib/Utils/history.js +46 -37
  68. package/lib/Utils/index.js +33 -19
  69. package/lib/Utils/link-preview.js +55 -14
  70. package/lib/Utils/logger.js +7 -3
  71. package/lib/Utils/lt-hash.js +26 -23
  72. package/lib/Utils/make-mutex.js +10 -7
  73. package/lib/Utils/messages-media.js +368 -239
  74. package/lib/Utils/messages.js +510 -278
  75. package/lib/Utils/noise-handler.js +31 -22
  76. package/lib/Utils/process-message.js +148 -144
  77. package/lib/Utils/signal.js +64 -71
  78. package/lib/Utils/use-multi-file-auth-state.js +32 -14
  79. package/lib/Utils/validate-connection.js +115 -72
  80. package/lib/WABinary/constants.js +20 -1281
  81. package/lib/WABinary/decode.js +52 -15
  82. package/lib/WABinary/encode.js +48 -14
  83. package/lib/WABinary/generic-utils.js +39 -31
  84. package/lib/WABinary/index.js +21 -6
  85. package/lib/WABinary/jid-utils.js +40 -23
  86. package/lib/WABinary/types.js +2 -2
  87. package/lib/WAM/BinaryInfo.js +5 -2
  88. package/lib/WAM/constants.js +2366 -2257
  89. package/lib/WAM/encode.js +21 -17
  90. package/lib/WAM/index.js +19 -4
  91. package/lib/WAUSync/Protocols/USyncContactProtocol.js +11 -8
  92. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +14 -11
  93. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +12 -9
  94. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +13 -9
  95. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +22 -20
  96. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +6 -3
  97. package/lib/WAUSync/Protocols/index.js +20 -5
  98. package/lib/WAUSync/USyncQuery.js +32 -34
  99. package/lib/WAUSync/USyncUser.js +5 -2
  100. package/lib/WAUSync/index.js +19 -4
  101. package/lib/index.js +33 -11
  102. package/package.json +61 -21
  103. package/WAProto/GenerateStatics.sh +0 -3
  104. package/WAProto/WAProto.proto +0 -4633
  105. package/WAProto/fix-imports.js +0 -29
  106. package/lib/Defaults/baileys-version.js +0 -1
  107. package/lib/Signal/Group/ciphertext-message.js +0 -12
  108. package/lib/Signal/Group/group-session-builder.js +0 -30
  109. package/lib/Signal/Group/group_cipher.js +0 -94
  110. package/lib/Signal/Group/index.js +0 -12
  111. package/lib/Signal/Group/keyhelper.js +0 -19
  112. package/lib/Signal/Group/queue-job.js +0 -54
  113. package/lib/Signal/Group/sender-chain-key.js +0 -32
  114. package/lib/Signal/Group/sender-key-distribution-message.js +0 -63
  115. package/lib/Signal/Group/sender-key-message.js +0 -67
  116. package/lib/Signal/Group/sender-key-name.js +0 -48
  117. package/lib/Signal/Group/sender-key-record.js +0 -50
  118. package/lib/Signal/Group/sender-key-state.js +0 -96
  119. package/lib/Socket/Client/types.js +0 -11
  120. package/lib/Socket/Client/websocket.js +0 -50
  121. package/lib/Socket/communities.js +0 -351
  122. package/lib/Socket/mex.js +0 -42
@@ -1,81 +1,108 @@
1
- import { Boom } from '@hapi/boom';
2
- import axios, {} from 'axios';
3
- import { exec } from 'child_process';
4
- import * as Crypto from 'crypto';
5
- import { once } from 'events';
6
- import { createReadStream, createWriteStream, promises as fs, WriteStream } from 'fs';
7
- import { tmpdir } from 'os';
8
- import { join } from 'path';
9
- import { Readable, Transform } from 'stream';
10
- import { URL } from 'url';
11
- import { proto } from '../../WAProto/index.js';
12
- import { DEFAULT_ORIGIN, MEDIA_HKDF_KEY_MAPPING, MEDIA_PATH_MAP } from '../Defaults/index.js';
13
- import { getBinaryNodeChild, getBinaryNodeChildBuffer, jidNormalizedUser } from '../WABinary/index.js';
14
- import { aesDecryptGCM, aesEncryptGCM, hkdf } from './crypto.js';
15
- import { generateMessageIDV2 } from './generics.js';
16
- const getTmpFilesDirectory = () => tmpdir();
17
- export const hkdfInfoKey = (type) => {
18
- const hkdfInfo = MEDIA_HKDF_KEY_MAPPING[type];
19
- return `WhatsApp ${hkdfInfo} Keys`;
20
- };
21
- export const getRawMediaUploadData = async (media, mediaType, logger) => {
22
- const { stream } = await getStream(media);
23
- logger?.debug('got stream for raw upload');
24
- const hasher = Crypto.createHash('sha256');
25
- const filePath = join(tmpdir(), mediaType + generateMessageIDV2());
26
- const fileWriteStream = createWriteStream(filePath);
27
- let fileLength = 0;
28
- try {
29
- for await (const data of stream) {
30
- fileLength += data.length;
31
- hasher.update(data);
32
- if (!fileWriteStream.write(data)) {
33
- await once(fileWriteStream, 'drain');
34
- }
35
- }
36
- fileWriteStream.end();
37
- await once(fileWriteStream, 'finish');
38
- stream.destroy();
39
- const fileSha256 = hasher.digest();
40
- logger?.debug('hashed data for raw upload');
41
- return {
42
- filePath: filePath,
43
- fileSha256,
44
- fileLength
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
45
24
  };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.getStatusCodeForMediaRetry = exports.decryptMediaRetryData = exports.decodeMediaRetryNode = exports.encryptMediaRetryRequest = exports.getWAUploadToServer = exports.downloadEncryptedContent = exports.downloadContentFromMessage = exports.getUrlFromDirectPath = exports.encryptedStream = exports.prepareStream = exports.getHttpStream = exports.getStream = exports.toBuffer = exports.toReadable = exports.mediaMessageSHA256B64 = exports.generateProfilePicture = exports.encodeBase64EncodedStringForUpload = exports.extractImageThumb = exports.hkdfInfoKey = void 0;
40
+ exports.getMediaKeys = getMediaKeys;
41
+ exports.getAudioDuration = getAudioDuration;
42
+ exports.getAudioWaveform = getAudioWaveform;
43
+ exports.generateThumbnail = generateThumbnail;
44
+ exports.extensionForMediaMessage = extensionForMediaMessage;
45
+ const boom_1 = require("@hapi/boom");
46
+ const axios_1 = __importDefault(require("axios"));
47
+ const child_process_1 = require("child_process");
48
+ const Crypto = __importStar(require("crypto"));
49
+ const events_1 = require("events");
50
+ const fs_1 = require("fs");
51
+ const os_1 = require("os");
52
+ const path_1 = require("path");
53
+ const jimp_1 = __importDefault(require("jimp"));
54
+ const stream_1 = require("stream");
55
+ const WAProto_1 = require("../../WAProto");
56
+ const Defaults_1 = require("../Defaults");
57
+ const WABinary_1 = require("../WABinary");
58
+ const crypto_1 = require("./crypto");
59
+ const generics_1 = require("./generics");
60
+ const getTmpFilesDirectory = () => (0, os_1.tmpdir)();
61
+ const getImageProcessingLibrary = async () => {
62
+ const [_jimp, sharp] = await Promise.all([
63
+ (async () => {
64
+ const jimp = await (Promise.resolve().then(() => __importStar(require('jimp'))).catch(() => { }));
65
+ return jimp;
66
+ })(),
67
+ (async () => {
68
+ const sharp = await (Promise.resolve().then(() => __importStar(require('sharp'))).catch(() => { }));
69
+ return sharp;
70
+ })()
71
+ ]);
72
+ if (sharp) {
73
+ return { sharp };
46
74
  }
47
- catch (error) {
48
- fileWriteStream.destroy();
49
- stream.destroy();
50
- try {
51
- await fs.unlink(filePath);
52
- }
53
- catch {
54
- //
55
- }
56
- throw error;
75
+ const jimp = (_jimp === null || _jimp === void 0 ? void 0 : _jimp.default) || _jimp;
76
+ if (jimp) {
77
+ return { jimp };
57
78
  }
79
+ throw new boom_1.Boom('No image processing library available');
58
80
  };
81
+ const hkdfInfoKey = (type) => {
82
+ const hkdfInfo = Defaults_1.MEDIA_HKDF_KEY_MAPPING[type];
83
+ return `WhatsApp ${hkdfInfo} Keys`;
84
+ };
85
+ exports.hkdfInfoKey = hkdfInfoKey;
59
86
  /** generates all the keys required to encrypt/decrypt & sign a media message */
60
- export async function getMediaKeys(buffer, mediaType) {
87
+ async function getMediaKeys(buffer, mediaType) {
61
88
  if (!buffer) {
62
- throw new Boom('Cannot derive from empty media key');
89
+ throw new boom_1.Boom('Cannot derive from empty media key');
63
90
  }
64
91
  if (typeof buffer === 'string') {
65
92
  buffer = Buffer.from(buffer.replace('data:;base64,', ''), 'base64');
66
93
  }
67
94
  // expand using HKDF to 112 bytes, also pass in the relevant app info
68
- const expandedMediaKey = await hkdf(buffer, 112, { info: hkdfInfoKey(mediaType) });
95
+ const expandedMediaKey = await (0, crypto_1.hkdf)(buffer, 112, { info: (0, exports.hkdfInfoKey)(mediaType) });
69
96
  return {
70
97
  iv: expandedMediaKey.slice(0, 16),
71
98
  cipherKey: expandedMediaKey.slice(16, 48),
72
- macKey: expandedMediaKey.slice(48, 80)
99
+ macKey: expandedMediaKey.slice(48, 80),
73
100
  };
74
101
  }
75
102
  /** Extracts video thumb using FFMPEG */
76
103
  const extractVideoThumb = async (path, destPath, time, size) => new Promise((resolve, reject) => {
77
104
  const cmd = `ffmpeg -ss ${time} -i ${path} -y -vf scale=${size.width}:-1 -vframes 1 -f image2 ${destPath}`;
78
- exec(cmd, err => {
105
+ (0, child_process_1.exec)(cmd, (err) => {
79
106
  if (err) {
80
107
  reject(err);
81
108
  }
@@ -84,86 +111,117 @@ const extractVideoThumb = async (path, destPath, time, size) => new Promise((res
84
111
  }
85
112
  });
86
113
  });
87
- export const extractImageThumb = async (bufferOrFilePath, width = 32) => {
88
- // TODO: Move entirely to sharp, removing jimp as it supports readable streams
89
- // This will have positive speed and performance impacts as well as minimizing RAM usage.
90
- if (bufferOrFilePath instanceof Readable) {
91
- bufferOrFilePath = await toBuffer(bufferOrFilePath);
92
- }
93
- const Jimp = await (await import('jimp')).default
94
- const { read, MIME_JPEG, RESIZE_BILINEAR, AUTO } = Jimp
95
- const jimp = await read(bufferOrFilePath);
96
- const dimensions = {
97
- width: jimp.getWidth(),
98
- height: jimp.getHeight()
99
- };
100
- const buffer = await jimp
101
- .quality(50)
102
- .resize(width, AUTO, RESIZE_BILINEAR)
103
- .getBufferAsync(MIME_JPEG);
104
- return {
105
- buffer,
106
- original: dimensions
107
- };
114
+ const extractImageThumb = async (bufferOrFilePath, width = 32) => {
115
+ var _a, _b;
116
+ if (bufferOrFilePath instanceof stream_1.Readable) {
117
+ bufferOrFilePath = await (0, exports.toBuffer)(bufferOrFilePath);
118
+ }
119
+ const lib = await getImageProcessingLibrary();
120
+ if ('sharp' in lib && typeof ((_a = lib.sharp) === null || _a === void 0 ? void 0 : _a.default) === 'function') {
121
+ const img = lib.sharp.default(bufferOrFilePath);
122
+ const dimensions = await img.metadata();
123
+ const buffer = await img
124
+ .resize(width)
125
+ .jpeg({ quality: 50 })
126
+ .toBuffer();
127
+ return {
128
+ buffer,
129
+ original: {
130
+ width: dimensions.width,
131
+ height: dimensions.height,
132
+ },
133
+ };
134
+ }
135
+ else if ('jimp' in lib && typeof ((_b = lib.jimp) === null || _b === void 0 ? void 0 : _b.read) === 'function') {
136
+ const { read, MIME_JPEG, RESIZE_BILINEAR, AUTO } = lib.jimp;
137
+ const jimp = await read(bufferOrFilePath);
138
+ const dimensions = {
139
+ width: jimp.getWidth(),
140
+ height: jimp.getHeight()
141
+ };
142
+ const buffer = await jimp
143
+ .quality(50)
144
+ .resize(width, AUTO, RESIZE_BILINEAR)
145
+ .getBufferAsync(MIME_JPEG);
146
+ return {
147
+ buffer,
148
+ original: dimensions
149
+ };
150
+ }
151
+ else {
152
+ throw new boom_1.Boom('No image processing library available');
153
+ }
108
154
  };
109
- /**/
110
- export const encodeBase64EncodedStringForUpload = (b64) => encodeURIComponent(b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, ''));
111
- export const generateProfilePicture = async (mediaUpload) => {
112
- let buffer;
155
+ exports.extractImageThumb = extractImageThumb;
156
+ const encodeBase64EncodedStringForUpload = (b64) => (encodeURIComponent(b64
157
+ .replace(/\+/g, '-')
158
+ .replace(/\//g, '_')
159
+ .replace(/\=+$/, '')));
160
+ exports.encodeBase64EncodedStringForUpload = encodeBase64EncodedStringForUpload;
161
+ const generateProfilePicture = async (mediaUpload) => {
162
+ let bufferOrFilePath;
163
+ let img;
113
164
  if (Buffer.isBuffer(mediaUpload)) {
114
- buffer = mediaUpload;
115
- } else {
116
- const { stream } = await getStream(mediaUpload);
117
- buffer = await toBuffer(stream);
118
- }
119
- const Jimp = (await import('jimp')).default;
120
- const jimp = await Jimp.read(mediaUpload);
121
- const min = await jimp.getWidth();
122
- const max = await jimp.getHeight();
123
- const cropped = await jimp.crop(0, 0, min, max);
165
+ bufferOrFilePath = mediaUpload;
166
+ }
167
+ else if ('url' in mediaUpload) {
168
+ bufferOrFilePath = mediaUpload.url.toString();
169
+ }
170
+ else {
171
+ bufferOrFilePath = await (0, exports.toBuffer)(mediaUpload.stream);
172
+ }
173
+ const jimp = await jimp_1.default.read(bufferOrFilePath);
174
+ const cropped = jimp.getWidth() > jimp.getHeight() ? jimp.resize(550, -1) : jimp.resize(-1, 650);
175
+ img = cropped
176
+ .quality(100)
177
+ .getBufferAsync(jimp_1.default.MIME_JPEG);
124
178
  return {
125
- img: await cropped.scaleToFit(720, 720).getBufferAsync(Jimp.MIME_JPEG),
179
+ img: await img,
126
180
  };
127
181
  };
182
+ exports.generateProfilePicture = generateProfilePicture;
128
183
  /** gets the SHA256 of the given media message */
129
- export const mediaMessageSHA256B64 = (message) => {
184
+ const mediaMessageSHA256B64 = (message) => {
130
185
  const media = Object.values(message)[0];
131
- return media?.fileSha256 && Buffer.from(media.fileSha256).toString('base64');
186
+ return (media === null || media === void 0 ? void 0 : media.fileSha256) && Buffer.from(media.fileSha256).toString('base64');
132
187
  };
133
- export async function getAudioDuration(buffer) {
134
- const musicMetadata = await import('music-metadata');
188
+ exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
189
+ async function getAudioDuration(buffer) {
190
+ const musicMetadata = await Promise.resolve().then(() => __importStar(require('music-metadata')));
135
191
  let metadata;
136
- const options = {
137
- duration: true
138
- };
139
192
  if (Buffer.isBuffer(buffer)) {
140
- metadata = await musicMetadata.parseBuffer(buffer, undefined, options);
193
+ metadata = await musicMetadata.parseBuffer(buffer, undefined, { duration: true });
141
194
  }
142
195
  else if (typeof buffer === 'string') {
143
- metadata = await musicMetadata.parseFile(buffer, options);
196
+ const rStream = (0, fs_1.createReadStream)(buffer);
197
+ try {
198
+ metadata = await musicMetadata.parseStream(rStream, undefined, { duration: true });
199
+ }
200
+ finally {
201
+ rStream.destroy();
202
+ }
144
203
  }
145
204
  else {
146
- metadata = await musicMetadata.parseStream(buffer, undefined, options);
205
+ metadata = await musicMetadata.parseStream(buffer, undefined, { duration: true });
147
206
  }
148
207
  return metadata.format.duration;
149
208
  }
150
209
  /**
151
210
  referenced from and modifying https://github.com/wppconnect-team/wa-js/blob/main/src/chat/functions/prepareAudioWaveform.ts
152
211
  */
153
- export async function getAudioWaveform(buffer, logger) {
212
+ async function getAudioWaveform(buffer, logger) {
154
213
  try {
155
- // @ts-ignore
156
- const { default: decoder } = await import('audio-decode');
214
+ const { default: decoder } = await eval('import(\'audio-decode\')');
157
215
  let audioData;
158
216
  if (Buffer.isBuffer(buffer)) {
159
217
  audioData = buffer;
160
218
  }
161
219
  else if (typeof buffer === 'string') {
162
- const rStream = createReadStream(buffer);
163
- audioData = await toBuffer(rStream);
220
+ const rStream = (0, fs_1.createReadStream)(buffer);
221
+ audioData = await (0, exports.toBuffer)(rStream);
164
222
  }
165
223
  else {
166
- audioData = await toBuffer(buffer);
224
+ audioData = await (0, exports.toBuffer)(buffer);
167
225
  }
168
226
  const audioBuffer = await decoder(audioData);
169
227
  const rawData = audioBuffer.getChannelData(0); // We only need to work with one channel of data
@@ -180,22 +238,23 @@ export async function getAudioWaveform(buffer, logger) {
180
238
  }
181
239
  // This guarantees that the largest data point will be set to 1, and the rest of the data will scale proportionally.
182
240
  const multiplier = Math.pow(Math.max(...filteredData), -1);
183
- const normalizedData = filteredData.map(n => n * multiplier);
241
+ const normalizedData = filteredData.map((n) => n * multiplier);
184
242
  // Generate waveform like WhatsApp
185
- const waveform = new Uint8Array(normalizedData.map(n => Math.floor(100 * n)));
243
+ const waveform = new Uint8Array(normalizedData.map((n) => Math.floor(100 * n)));
186
244
  return waveform;
187
245
  }
188
246
  catch (e) {
189
- logger?.debug('Failed to generate waveform: ' + e);
247
+ logger === null || logger === void 0 ? void 0 : logger.debug('Failed to generate waveform: ' + e);
190
248
  }
191
249
  }
192
- export const toReadable = (buffer) => {
193
- const readable = new Readable({ read: () => { } });
250
+ const toReadable = (buffer) => {
251
+ const readable = new stream_1.Readable({ read: () => { } });
194
252
  readable.push(buffer);
195
253
  readable.push(null);
196
254
  return readable;
197
255
  };
198
- export const toBuffer = async (stream) => {
256
+ exports.toReadable = toReadable;
257
+ const toBuffer = async (stream) => {
199
258
  const chunks = [];
200
259
  for await (const chunk of stream) {
201
260
  chunks.push(chunk);
@@ -203,47 +262,45 @@ export const toBuffer = async (stream) => {
203
262
  stream.destroy();
204
263
  return Buffer.concat(chunks);
205
264
  };
206
- export const getStream = async (item, opts) => {
265
+ exports.toBuffer = toBuffer;
266
+ const getStream = async (item, opts) => {
207
267
  if (Buffer.isBuffer(item)) {
208
- return { stream: toReadable(item), type: 'buffer' };
268
+ return { stream: (0, exports.toReadable)(item), type: 'buffer' };
209
269
  }
210
270
  if ('stream' in item) {
211
271
  return { stream: item.stream, type: 'readable' };
212
272
  }
213
- const urlStr = item.url.toString();
214
- if (urlStr.startsWith('data:')) {
215
- const buffer = Buffer.from(urlStr.split(',')[1], 'base64');
216
- return { stream: toReadable(buffer), type: 'buffer' };
217
- }
218
- if (urlStr.startsWith('http://') || urlStr.startsWith('https://')) {
219
- return { stream: await getHttpStream(item.url, opts), type: 'remote' };
273
+ if (item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')) {
274
+ return { stream: await (0, exports.getHttpStream)(item.url, opts), type: 'remote' };
220
275
  }
221
- return { stream: createReadStream(item.url), type: 'file' };
276
+ return { stream: (0, fs_1.createReadStream)(item.url), type: 'file' };
222
277
  };
278
+ exports.getStream = getStream;
223
279
  /** generates a thumbnail for a given media, if required */
224
- export async function generateThumbnail(file, mediaType, options) {
280
+ async function generateThumbnail(file, mediaType, options) {
281
+ var _a;
225
282
  let thumbnail;
226
283
  let originalImageDimensions;
227
284
  if (mediaType === 'image') {
228
- const { buffer, original } = await extractImageThumb(file);
285
+ const { buffer, original } = await (0, exports.extractImageThumb)(file);
229
286
  thumbnail = buffer.toString('base64');
230
287
  if (original.width && original.height) {
231
288
  originalImageDimensions = {
232
289
  width: original.width,
233
- height: original.height
290
+ height: original.height,
234
291
  };
235
292
  }
236
293
  }
237
294
  else if (mediaType === 'video') {
238
- const imgFilename = join(getTmpFilesDirectory(), generateMessageIDV2() + '.jpg');
295
+ const imgFilename = (0, path_1.join)(getTmpFilesDirectory(), (0, generics_1.generateMessageIDV2)() + '.jpg');
239
296
  try {
240
297
  await extractVideoThumb(file, imgFilename, '00:00:00', { width: 32, height: 32 });
241
- const buff = await fs.readFile(imgFilename);
298
+ const buff = await fs_1.promises.readFile(imgFilename);
242
299
  thumbnail = buff.toString('base64');
243
- await fs.unlink(imgFilename);
300
+ await fs_1.promises.unlink(imgFilename);
244
301
  }
245
302
  catch (err) {
246
- options.logger?.debug('could not generate video thumb: ' + err);
303
+ (_a = options.logger) === null || _a === void 0 ? void 0 : _a.debug('could not generate video thumb: ' + err);
247
304
  }
248
305
  }
249
306
  return {
@@ -251,110 +308,160 @@ export async function generateThumbnail(file, mediaType, options) {
251
308
  originalImageDimensions
252
309
  };
253
310
  }
254
- export const getHttpStream = async (url, options = {}) => {
255
- const fetched = await axios.get(url.toString(), { ...options, responseType: 'stream' });
311
+ const getHttpStream = async (url, options = {}) => {
312
+ const fetched = await axios_1.default.get(url.toString(), { ...options, responseType: 'stream' });
256
313
  return fetched.data;
257
314
  };
258
- export const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
259
- const { stream, type } = await getStream(media, opts);
260
- logger?.debug('fetched media stream');
315
+ exports.getHttpStream = getHttpStream;
316
+ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
317
+ const { stream, type } = await (0, exports.getStream)(media, opts);
318
+ logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
319
+ let bodyPath;
320
+ let didSaveToTmpPath = false;
321
+ try {
322
+ const buffer = await (0, exports.toBuffer)(stream);
323
+ if (type === 'file') {
324
+ bodyPath = media.url;
325
+ }
326
+ else if (saveOriginalFileIfRequired) {
327
+ bodyPath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageIDV2)());
328
+ (0, fs_1.writeFileSync)(bodyPath, buffer);
329
+ didSaveToTmpPath = true;
330
+ }
331
+ const fileLength = buffer.length;
332
+ const fileSha256 = Crypto.createHash('sha256').update(buffer).digest();
333
+ stream === null || stream === void 0 ? void 0 : stream.destroy();
334
+ logger === null || logger === void 0 ? void 0 : logger.debug('prepare stream data successfully');
335
+ return {
336
+ mediaKey: undefined,
337
+ encWriteStream: buffer,
338
+ fileLength,
339
+ fileSha256,
340
+ fileEncSha256: undefined,
341
+ bodyPath,
342
+ didSaveToTmpPath
343
+ };
344
+ }
345
+ catch (error) {
346
+ // destroy all streams with error
347
+ stream.destroy();
348
+ if (didSaveToTmpPath) {
349
+ try {
350
+ await fs_1.promises.unlink(bodyPath);
351
+ }
352
+ catch (err) {
353
+ logger === null || logger === void 0 ? void 0 : logger.error({ err }, 'failed to save to tmp path');
354
+ }
355
+ }
356
+ throw error;
357
+ }
358
+ };
359
+ exports.prepareStream = prepareStream;
360
+ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
361
+ const { stream, type } = await (0, exports.getStream)(media, opts);
362
+ logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
261
363
  const mediaKey = Crypto.randomBytes(32);
262
364
  const { cipherKey, iv, macKey } = await getMediaKeys(mediaKey, mediaType);
263
- const encFilePath = join(getTmpFilesDirectory(), mediaType + generateMessageIDV2() + '-enc');
264
- const encFileWriteStream = createWriteStream(encFilePath);
265
- let originalFileStream;
266
- let originalFilePath;
267
- if (saveOriginalFileIfRequired) {
268
- originalFilePath = join(getTmpFilesDirectory(), mediaType + generateMessageIDV2() + '-original');
269
- originalFileStream = createWriteStream(originalFilePath);
365
+ const encWriteStream = new stream_1.Readable({ read: () => { } });
366
+ let bodyPath;
367
+ let writeStream;
368
+ let didSaveToTmpPath = false;
369
+ if (type === 'file') {
370
+ bodyPath = media.url;
371
+ }
372
+ else if (saveOriginalFileIfRequired) {
373
+ bodyPath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageIDV2)());
374
+ writeStream = (0, fs_1.createWriteStream)(bodyPath);
375
+ didSaveToTmpPath = true;
270
376
  }
271
377
  let fileLength = 0;
272
378
  const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv);
273
- const hmac = Crypto.createHmac('sha256', macKey).update(iv);
274
- const sha256Plain = Crypto.createHash('sha256');
275
- const sha256Enc = Crypto.createHash('sha256');
276
- const onChunk = (buff) => {
277
- sha256Enc.update(buff);
278
- hmac.update(buff);
279
- encFileWriteStream.write(buff);
280
- };
379
+ let hmac = Crypto.createHmac('sha256', macKey).update(iv);
380
+ let sha256Plain = Crypto.createHash('sha256');
381
+ let sha256Enc = Crypto.createHash('sha256');
281
382
  try {
282
383
  for await (const data of stream) {
283
384
  fileLength += data.length;
284
- if (type === 'remote' && opts?.maxContentLength && fileLength + data.length > opts.maxContentLength) {
285
- throw new Boom(`content length exceeded when encrypting "${type}"`, {
385
+ if (type === 'remote'
386
+ && (opts === null || opts === void 0 ? void 0 : opts.maxContentLength)
387
+ && fileLength + data.length > opts.maxContentLength) {
388
+ throw new boom_1.Boom(`content length exceeded when encrypting "${type}"`, {
286
389
  data: { media, type }
287
390
  });
288
391
  }
289
- if (originalFileStream) {
290
- if (!originalFileStream.write(data)) {
291
- await once(originalFileStream, 'drain');
392
+ sha256Plain = sha256Plain.update(data);
393
+ if (writeStream) {
394
+ if (!writeStream.write(data)) {
395
+ await (0, events_1.once)(writeStream, 'drain');
292
396
  }
293
397
  }
294
- sha256Plain.update(data);
295
398
  onChunk(aes.update(data));
296
399
  }
297
400
  onChunk(aes.final());
298
401
  const mac = hmac.digest().slice(0, 10);
299
- sha256Enc.update(mac);
402
+ sha256Enc = sha256Enc.update(mac);
300
403
  const fileSha256 = sha256Plain.digest();
301
404
  const fileEncSha256 = sha256Enc.digest();
302
- encFileWriteStream.write(mac);
303
- encFileWriteStream.end();
304
- originalFileStream?.end?.();
405
+ encWriteStream.push(mac);
406
+ encWriteStream.push(null);
407
+ writeStream === null || writeStream === void 0 ? void 0 : writeStream.end();
305
408
  stream.destroy();
306
- logger?.debug('encrypted data successfully');
409
+ logger === null || logger === void 0 ? void 0 : logger.debug('encrypted data successfully');
307
410
  return {
308
411
  mediaKey,
309
- originalFilePath,
310
- encFilePath,
412
+ encWriteStream,
413
+ bodyPath,
311
414
  mac,
312
415
  fileEncSha256,
313
416
  fileSha256,
314
- fileLength
417
+ fileLength,
418
+ didSaveToTmpPath
315
419
  };
316
420
  }
317
421
  catch (error) {
318
422
  // destroy all streams with error
319
- encFileWriteStream.destroy();
320
- originalFileStream?.destroy?.();
423
+ encWriteStream.destroy();
424
+ writeStream === null || writeStream === void 0 ? void 0 : writeStream.destroy();
321
425
  aes.destroy();
322
426
  hmac.destroy();
323
427
  sha256Plain.destroy();
324
428
  sha256Enc.destroy();
325
429
  stream.destroy();
326
- try {
327
- await fs.unlink(encFilePath);
328
- if (originalFilePath) {
329
- await fs.unlink(originalFilePath);
430
+ if (didSaveToTmpPath) {
431
+ try {
432
+ await fs_1.promises.unlink(bodyPath);
433
+ }
434
+ catch (err) {
435
+ logger === null || logger === void 0 ? void 0 : logger.error({ err }, 'failed to save to tmp path');
330
436
  }
331
- }
332
- catch (err) {
333
- logger?.error({ err }, 'failed deleting tmp files');
334
437
  }
335
438
  throw error;
336
439
  }
440
+ function onChunk(buff) {
441
+ sha256Enc = sha256Enc.update(buff);
442
+ hmac = hmac.update(buff);
443
+ encWriteStream.push(buff);
444
+ }
337
445
  };
446
+ exports.encryptedStream = encryptedStream;
338
447
  const DEF_HOST = 'mmg.whatsapp.net';
339
448
  const AES_CHUNK_SIZE = 16;
340
449
  const toSmallestChunkSize = (num) => {
341
450
  return Math.floor(num / AES_CHUNK_SIZE) * AES_CHUNK_SIZE;
342
451
  };
343
- export const getUrlFromDirectPath = (directPath) => `https://${DEF_HOST}${directPath}`;
344
- export const downloadContentFromMessage = async ({ mediaKey, directPath, url }, type, opts = {}) => {
345
- const isValidMediaUrl = url?.startsWith('https://mmg.whatsapp.net/');
346
- const downloadUrl = isValidMediaUrl ? url : getUrlFromDirectPath(directPath);
347
- if (!downloadUrl) {
348
- throw new Boom('No valid media URL or directPath present in message', { statusCode: 400 });
349
- }
452
+ const getUrlFromDirectPath = (directPath) => `https://${DEF_HOST}${directPath}`;
453
+ exports.getUrlFromDirectPath = getUrlFromDirectPath;
454
+ const downloadContentFromMessage = async ({ mediaKey, directPath, url }, type, opts = {}) => {
455
+ const downloadUrl = url || (0, exports.getUrlFromDirectPath)(directPath);
350
456
  const keys = await getMediaKeys(mediaKey, type);
351
- return downloadEncryptedContent(downloadUrl, keys, opts);
457
+ return (0, exports.downloadEncryptedContent)(downloadUrl, keys, opts);
352
458
  };
459
+ exports.downloadContentFromMessage = downloadContentFromMessage;
353
460
  /**
354
461
  * Decrypts and downloads an AES256-CBC encrypted file given the keys.
355
462
  * Assumes the SHA256 of the plaintext is appended to the end of the ciphertext
356
463
  * */
357
- export const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startByte, endByte, options } = {}) => {
464
+ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startByte, endByte, options } = {}) => {
358
465
  let bytesFetched = 0;
359
466
  let startChunk = 0;
360
467
  let firstBlockIsIV = false;
@@ -369,8 +476,8 @@ export const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, {
369
476
  }
370
477
  const endChunk = endByte ? toSmallestChunkSize(endByte || 0) + AES_CHUNK_SIZE : undefined;
371
478
  const headers = {
372
- ...(options?.headers || {}),
373
- Origin: DEFAULT_ORIGIN
479
+ ...(options === null || options === void 0 ? void 0 : options.headers) || {},
480
+ Origin: Defaults_1.DEFAULT_ORIGIN,
374
481
  };
375
482
  if (startChunk || endChunk) {
376
483
  headers.Range = `bytes=${startChunk}-`;
@@ -379,11 +486,11 @@ export const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, {
379
486
  }
380
487
  }
381
488
  // download the message
382
- const fetched = await getHttpStream(downloadUrl, {
383
- ...(options || {}),
489
+ const fetched = await (0, exports.getHttpStream)(downloadUrl, {
490
+ ...options || {},
384
491
  headers,
385
492
  maxBodyLength: Infinity,
386
- maxContentLength: Infinity
493
+ maxContentLength: Infinity,
387
494
  });
388
495
  let remainingBytes = Buffer.from([]);
389
496
  let aes;
@@ -398,7 +505,7 @@ export const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, {
398
505
  push(bytes);
399
506
  }
400
507
  };
401
- const output = new Transform({
508
+ const output = new stream_1.Transform({
402
509
  transform(chunk, _, callback) {
403
510
  let data = Buffer.concat([remainingBytes, chunk]);
404
511
  const decryptLength = toSmallestChunkSize(data.length);
@@ -433,15 +540,18 @@ export const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, {
433
540
  catch (error) {
434
541
  callback(error);
435
542
  }
436
- }
543
+ },
437
544
  });
438
545
  return fetched.pipe(output, { end: true });
439
546
  };
440
- export function extensionForMediaMessage(message) {
441
- const getExtension = (mimetype) => mimetype.split(';')[0]?.split('/')[1];
547
+ exports.downloadEncryptedContent = downloadEncryptedContent;
548
+ function extensionForMediaMessage(message) {
549
+ const getExtension = (mimetype) => mimetype.split(';')[0].split('/')[1];
442
550
  const type = Object.keys(message)[0];
443
551
  let extension;
444
- if (type === 'locationMessage' || type === 'liveLocationMessage' || type === 'productMessage') {
552
+ if (type === 'locationMessage' ||
553
+ type === 'liveLocationMessage' ||
554
+ type === 'productMessage') {
445
555
  extension = '.jpeg';
446
556
  }
447
557
  else {
@@ -450,39 +560,53 @@ export function extensionForMediaMessage(message) {
450
560
  }
451
561
  return extension;
452
562
  }
453
- export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
454
- return async (filePath, { mediaType, fileEncSha256B64, timeoutMs }) => {
563
+ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
564
+ return async (stream, { mediaType, fileEncSha256B64, newsletter, timeoutMs }) => {
565
+ var _a, _b;
455
566
  // send a query JSON to obtain the url & auth token to upload our media
456
567
  let uploadInfo = await refreshMediaConn(false);
457
568
  let urls;
458
569
  const hosts = [...customUploadHosts, ...uploadInfo.hosts];
459
- fileEncSha256B64 = encodeBase64EncodedStringForUpload(fileEncSha256B64);
460
- for (const { hostname } of hosts) {
570
+ const chunks = [];
571
+ if (!Buffer.isBuffer(stream)) {
572
+ for await (const chunk of stream) {
573
+ chunks.push(chunk);
574
+ }
575
+ }
576
+ const reqBody = Buffer.isBuffer(stream) ? stream : Buffer.concat(chunks);
577
+ fileEncSha256B64 = (0, exports.encodeBase64EncodedStringForUpload)(fileEncSha256B64);
578
+ let media = Defaults_1.MEDIA_PATH_MAP[mediaType];
579
+ if (newsletter) {
580
+ media = media === null || media === void 0 ? void 0 : media.replace('/mms/', '/newsletter/newsletter-');
581
+ }
582
+ for (const { hostname, maxContentLengthBytes } of hosts) {
461
583
  logger.debug(`uploading to "${hostname}"`);
462
584
  const auth = encodeURIComponent(uploadInfo.auth); // the auth token
463
- const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
464
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
585
+ const url = `https://${hostname}${media}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
465
586
  let result;
466
587
  try {
467
- const body = await axios.post(url, createReadStream(filePath), {
588
+ if (maxContentLengthBytes && reqBody.length > maxContentLengthBytes) {
589
+ throw new boom_1.Boom(`Body too large for "${hostname}"`, { statusCode: 413 });
590
+ }
591
+ const body = await axios_1.default.post(url, reqBody, {
468
592
  ...options,
469
- maxRedirects: 0,
470
593
  headers: {
471
- ...(options.headers || {}),
594
+ ...options.headers || {},
472
595
  'Content-Type': 'application/octet-stream',
473
- Origin: DEFAULT_ORIGIN
596
+ 'Origin': Defaults_1.DEFAULT_ORIGIN
474
597
  },
475
598
  httpsAgent: fetchAgent,
476
599
  timeout: timeoutMs,
477
600
  responseType: 'json',
478
601
  maxBodyLength: Infinity,
479
- maxContentLength: Infinity
602
+ maxContentLength: Infinity,
480
603
  });
481
604
  result = body.data;
482
- if (result?.url || result?.directPath) {
605
+ if ((result === null || result === void 0 ? void 0 : result.url) || (result === null || result === void 0 ? void 0 : result.directPath)) {
483
606
  urls = {
484
607
  mediaUrl: result.url,
485
- directPath: result.direct_path
608
+ directPath: result.direct_path,
609
+ handle: result.handle
486
610
  };
487
611
  break;
488
612
  }
@@ -492,36 +616,37 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, opt
492
616
  }
493
617
  }
494
618
  catch (error) {
495
- if (axios.isAxiosError(error)) {
496
- result = error.response?.data;
619
+ if (axios_1.default.isAxiosError(error)) {
620
+ result = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data;
497
621
  }
498
- const isLast = hostname === hosts[uploadInfo.hosts.length - 1]?.hostname;
622
+ const isLast = hostname === ((_b = hosts[uploadInfo.hosts.length - 1]) === null || _b === void 0 ? void 0 : _b.hostname);
499
623
  logger.warn({ trace: error.stack, uploadResult: result }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`);
500
624
  }
501
625
  }
502
626
  if (!urls) {
503
- throw new Boom('Media upload failed on all hosts', { statusCode: 500 });
627
+ throw new boom_1.Boom('Media upload failed on all hosts', { statusCode: 500 });
504
628
  }
505
629
  return urls;
506
630
  };
507
631
  };
632
+ exports.getWAUploadToServer = getWAUploadToServer;
508
633
  const getMediaRetryKey = (mediaKey) => {
509
- return hkdf(mediaKey, 32, { info: 'WhatsApp Media Retry Notification' });
634
+ return (0, crypto_1.hkdf)(mediaKey, 32, { info: 'WhatsApp Media Retry Notification' });
510
635
  };
511
636
  /**
512
637
  * Generate a binary node that will request the phone to re-upload the media & return the newly uploaded URL
513
638
  */
514
- export const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
639
+ const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
515
640
  const recp = { stanzaId: key.id };
516
- const recpBuffer = proto.ServerErrorReceipt.encode(recp).finish();
641
+ const recpBuffer = WAProto_1.proto.ServerErrorReceipt.encode(recp).finish();
517
642
  const iv = Crypto.randomBytes(12);
518
643
  const retryKey = await getMediaRetryKey(mediaKey);
519
- const ciphertext = aesEncryptGCM(recpBuffer, retryKey, iv, Buffer.from(key.id));
644
+ const ciphertext = (0, crypto_1.aesEncryptGCM)(recpBuffer, retryKey, iv, Buffer.from(key.id));
520
645
  const req = {
521
646
  tag: 'receipt',
522
647
  attrs: {
523
648
  id: key.id,
524
- to: jidNormalizedUser(meId),
649
+ to: (0, WABinary_1.jidNormalizedUser)(meId),
525
650
  type: 'server-error'
526
651
  },
527
652
  content: [
@@ -540,7 +665,7 @@ export const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
540
665
  tag: 'rmr',
541
666
  attrs: {
542
667
  jid: key.remoteJid,
543
- from_me: (!!key.fromMe).toString(),
668
+ 'from_me': (!!key.fromMe).toString(),
544
669
  // @ts-ignore
545
670
  participant: key.participant || undefined
546
671
  }
@@ -549,8 +674,9 @@ export const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
549
674
  };
550
675
  return req;
551
676
  };
552
- export const decodeMediaRetryNode = (node) => {
553
- const rmrNode = getBinaryNodeChild(node, 'rmr');
677
+ exports.encryptMediaRetryRequest = encryptMediaRetryRequest;
678
+ const decodeMediaRetryNode = (node) => {
679
+ const rmrNode = (0, WABinary_1.getBinaryNodeChild)(node, 'rmr');
554
680
  const event = {
555
681
  key: {
556
682
  id: node.attrs.id,
@@ -559,37 +685,40 @@ export const decodeMediaRetryNode = (node) => {
559
685
  participant: rmrNode.attrs.participant
560
686
  }
561
687
  };
562
- const errorNode = getBinaryNodeChild(node, 'error');
688
+ const errorNode = (0, WABinary_1.getBinaryNodeChild)(node, 'error');
563
689
  if (errorNode) {
564
690
  const errorCode = +errorNode.attrs.code;
565
- event.error = new Boom(`Failed to re-upload media (${errorCode})`, {
566
- data: errorNode.attrs,
567
- statusCode: getStatusCodeForMediaRetry(errorCode)
568
- });
691
+ event.error = new boom_1.Boom(`Failed to re-upload media (${errorCode})`, { data: errorNode.attrs, statusCode: (0, exports.getStatusCodeForMediaRetry)(errorCode) });
569
692
  }
570
693
  else {
571
- const encryptedInfoNode = getBinaryNodeChild(node, 'encrypt');
572
- const ciphertext = getBinaryNodeChildBuffer(encryptedInfoNode, 'enc_p');
573
- const iv = getBinaryNodeChildBuffer(encryptedInfoNode, 'enc_iv');
694
+ const encryptedInfoNode = (0, WABinary_1.getBinaryNodeChild)(node, 'encrypt');
695
+ const ciphertext = (0, WABinary_1.getBinaryNodeChildBuffer)(encryptedInfoNode, 'enc_p');
696
+ const iv = (0, WABinary_1.getBinaryNodeChildBuffer)(encryptedInfoNode, 'enc_iv');
574
697
  if (ciphertext && iv) {
575
698
  event.media = { ciphertext, iv };
576
699
  }
577
700
  else {
578
- event.error = new Boom('Failed to re-upload media (missing ciphertext)', { statusCode: 404 });
701
+ event.error = new boom_1.Boom('Failed to re-upload media (missing ciphertext)', { statusCode: 404 });
579
702
  }
580
703
  }
581
704
  return event;
582
705
  };
583
- export const decryptMediaRetryData = async ({ ciphertext, iv }, mediaKey, msgId) => {
706
+ exports.decodeMediaRetryNode = decodeMediaRetryNode;
707
+ const decryptMediaRetryData = async ({ ciphertext, iv }, mediaKey, msgId) => {
584
708
  const retryKey = await getMediaRetryKey(mediaKey);
585
- const plaintext = aesDecryptGCM(ciphertext, retryKey, iv, Buffer.from(msgId));
586
- return proto.MediaRetryNotification.decode(plaintext);
709
+ const plaintext = (0, crypto_1.aesDecryptGCM)(ciphertext, retryKey, iv, Buffer.from(msgId));
710
+ return WAProto_1.proto.MediaRetryNotification.decode(plaintext);
587
711
  };
588
- export const getStatusCodeForMediaRetry = (code) => MEDIA_RETRY_STATUS_MAP[code];
712
+ exports.decryptMediaRetryData = decryptMediaRetryData;
713
+ const getStatusCodeForMediaRetry = (code) => MEDIA_RETRY_STATUS_MAP[code];
714
+ exports.getStatusCodeForMediaRetry = getStatusCodeForMediaRetry;
589
715
  const MEDIA_RETRY_STATUS_MAP = {
590
- [proto.MediaRetryNotification.ResultType.SUCCESS]: 200,
591
- [proto.MediaRetryNotification.ResultType.DECRYPTION_ERROR]: 412,
592
- [proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
593
- [proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418
716
+ [WAProto_1.proto.MediaRetryNotification.ResultType.SUCCESS]: 200,
717
+ [WAProto_1.proto.MediaRetryNotification.ResultType.DECRYPTION_ERROR]: 412,
718
+ [WAProto_1.proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
719
+ [WAProto_1.proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418,
594
720
  };
595
- //# sourceMappingURL=messages-media.js.map
721
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
722
+ function __importStar(arg0) {
723
+ throw new Error('Function not implemented.');
724
+ }