@d0v3riz/baileys 6.7.18 → 6.7.20
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.
- package/README.md +1263 -4
- package/WAProto/GenerateStatics.sh +2 -0
- package/WAProto/WAProto.proto +4633 -0
- package/WAProto/index.d.ts +3212 -122
- package/WAProto/index.js +9635 -299
- package/lib/Defaults/baileys-version.json +1 -1
- package/lib/Defaults/index.d.ts +1 -1
- package/lib/Defaults/index.js +16 -16
- package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
- package/lib/Signal/Group/ciphertext-message.js +15 -0
- package/lib/Signal/Group/group-session-builder.d.ts +14 -0
- package/lib/Signal/Group/group-session-builder.js +64 -0
- package/lib/Signal/Group/group_cipher.d.ts +17 -0
- package/lib/Signal/Group/group_cipher.js +96 -0
- package/lib/Signal/Group/index.d.ts +11 -0
- package/lib/Signal/Group/index.js +57 -0
- package/lib/Signal/Group/keyhelper.d.ts +10 -0
- package/lib/Signal/Group/keyhelper.js +55 -0
- package/lib/Signal/Group/queue-job.d.ts +1 -0
- package/lib/Signal/Group/queue-job.js +57 -0
- package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
- package/lib/Signal/Group/sender-chain-key.js +34 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +66 -0
- package/lib/Signal/Group/sender-key-message.d.ts +18 -0
- package/lib/Signal/Group/sender-key-message.js +69 -0
- package/lib/Signal/Group/sender-key-name.d.ts +17 -0
- package/lib/Signal/Group/sender-key-name.js +51 -0
- package/lib/Signal/Group/sender-key-record.d.ts +30 -0
- package/lib/Signal/Group/sender-key-record.js +53 -0
- package/lib/Signal/Group/sender-key-state.d.ts +38 -0
- package/lib/Signal/Group/sender-key-state.js +99 -0
- package/lib/Signal/Group/sender-message-key.d.ts +11 -0
- package/{WASignalGroup/sender_message_key.js → lib/Signal/Group/sender-message-key.js} +29 -39
- package/lib/Signal/libsignal.js +33 -20
- package/lib/Socket/Client/websocket.js +1 -1
- package/lib/Socket/business.d.ts +5 -5
- package/lib/Socket/business.js +5 -5
- package/lib/Socket/chats.d.ts +4 -4
- package/lib/Socket/chats.js +70 -70
- package/lib/Socket/groups.d.ts +6 -6
- package/lib/Socket/groups.js +39 -24
- package/lib/Socket/index.d.ts +5 -5
- package/lib/Socket/index.js +2 -2
- package/lib/Socket/messages-recv.d.ts +5 -5
- package/lib/Socket/messages-recv.js +73 -56
- package/lib/Socket/messages-send.d.ts +5 -5
- package/lib/Socket/messages-send.js +53 -46
- package/lib/Socket/socket.d.ts +3 -3
- package/lib/Socket/socket.js +22 -29
- package/lib/Socket/usync.d.ts +3 -3
- package/lib/Socket/usync.js +10 -15
- package/lib/Types/Auth.d.ts +1 -1
- package/lib/Types/Chat.d.ts +1 -1
- package/lib/Types/Chat.js +7 -1
- package/lib/Types/Contact.d.ts +4 -0
- package/lib/Types/Events.d.ts +1 -1
- package/lib/Types/GroupMetadata.d.ts +7 -3
- package/lib/Types/Message.d.ts +7 -2
- package/lib/Types/Socket.d.ts +3 -3
- package/lib/Utils/auth-utils.js +8 -9
- package/lib/Utils/baileys-event-stream.js +1 -1
- package/lib/Utils/business.js +17 -11
- package/lib/Utils/chat-utils.d.ts +4 -4
- package/lib/Utils/chat-utils.js +64 -69
- package/lib/Utils/crypto.js +4 -10
- package/lib/Utils/decode-wa-message.js +6 -2
- package/lib/Utils/event-buffer.d.ts +2 -2
- package/lib/Utils/event-buffer.js +9 -13
- package/lib/Utils/generics.d.ts +1 -1
- package/lib/Utils/generics.js +28 -30
- package/lib/Utils/history.js +10 -5
- package/lib/Utils/link-preview.js +5 -9
- package/lib/Utils/lt-hash.js +2 -2
- package/lib/Utils/make-mutex.js +1 -1
- package/lib/Utils/messages-media.d.ts +2 -3
- package/lib/Utils/messages-media.js +80 -95
- package/lib/Utils/messages.d.ts +1 -1
- package/lib/Utils/messages.js +83 -75
- package/lib/Utils/process-message.d.ts +1 -1
- package/lib/Utils/process-message.js +25 -30
- package/lib/Utils/signal.js +9 -7
- package/lib/Utils/use-multi-file-auth-state.js +2 -3
- package/lib/Utils/validate-connection.js +17 -22
- package/lib/WABinary/constants.d.ts +4 -4
- package/lib/WABinary/constants.js +1271 -8
- package/lib/WABinary/decode.js +2 -1
- package/lib/WABinary/encode.js +2 -2
- package/lib/WABinary/generic-utils.js +1 -1
- package/lib/WABinary/jid-utils.js +8 -11
- package/lib/WAM/constants.js +2252 -2359
- package/lib/WAM/encode.js +5 -7
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +2 -2
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +2 -2
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +2 -2
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +5 -5
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +1 -1
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +1 -1
- package/lib/WAUSync/USyncQuery.js +17 -13
- package/package.json +11 -6
- package/WASignalGroup/GroupProtocol.js +0 -1697
- package/WASignalGroup/ciphertext_message.js +0 -16
- package/WASignalGroup/group_cipher.js +0 -120
- package/WASignalGroup/group_session_builder.js +0 -46
- package/WASignalGroup/index.js +0 -5
- package/WASignalGroup/keyhelper.js +0 -21
- package/WASignalGroup/protobufs.js +0 -3
- package/WASignalGroup/queue_job.js +0 -69
- package/WASignalGroup/sender_chain_key.js +0 -50
- package/WASignalGroup/sender_key_distribution_message.js +0 -78
- package/WASignalGroup/sender_key_message.js +0 -92
- package/WASignalGroup/sender_key_name.js +0 -70
- package/WASignalGroup/sender_key_record.js +0 -56
- package/WASignalGroup/sender_key_state.js +0 -129
package/lib/Utils/generics.js
CHANGED
|
@@ -17,21 +17,21 @@ const baileys_version_json_1 = require("../Defaults/baileys-version.json");
|
|
|
17
17
|
const Types_1 = require("../Types");
|
|
18
18
|
const WABinary_1 = require("../WABinary");
|
|
19
19
|
const PLATFORM_MAP = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
aix: 'AIX',
|
|
21
|
+
darwin: 'Mac OS',
|
|
22
|
+
win32: 'Windows',
|
|
23
|
+
android: 'Android',
|
|
24
|
+
freebsd: 'FreeBSD',
|
|
25
|
+
openbsd: 'OpenBSD',
|
|
26
|
+
sunos: 'Solaris'
|
|
27
27
|
};
|
|
28
28
|
exports.Browsers = {
|
|
29
|
-
ubuntu:
|
|
30
|
-
macOS:
|
|
31
|
-
baileys:
|
|
32
|
-
windows:
|
|
29
|
+
ubuntu: browser => ['Ubuntu', browser, '22.04.4'],
|
|
30
|
+
macOS: browser => ['Mac OS', browser, '14.4.1'],
|
|
31
|
+
baileys: browser => ['Baileys', browser, '6.5.0'],
|
|
32
|
+
windows: browser => ['Windows', browser, '10.0.22631'],
|
|
33
33
|
/** The appropriate browser based on your OS & release */
|
|
34
|
-
appropriate:
|
|
34
|
+
appropriate: browser => [PLATFORM_MAP[(0, os_1.platform)()] || 'Ubuntu', browser, (0, os_1.release)()]
|
|
35
35
|
};
|
|
36
36
|
const getPlatformId = (browser) => {
|
|
37
37
|
const platformType = WAProto_1.proto.DeviceProps.PlatformType[browser.toUpperCase()];
|
|
@@ -55,7 +55,7 @@ exports.BufferJSON = {
|
|
|
55
55
|
return value;
|
|
56
56
|
}
|
|
57
57
|
};
|
|
58
|
-
const getKeyAuthor = (key, meId = 'me') => ((
|
|
58
|
+
const getKeyAuthor = (key, meId = 'me') => ((key === null || key === void 0 ? void 0 : key.fromMe) ? meId : (key === null || key === void 0 ? void 0 : key.participant) || (key === null || key === void 0 ? void 0 : key.remoteJid)) || '';
|
|
59
59
|
exports.getKeyAuthor = getKeyAuthor;
|
|
60
60
|
const writeRandomPadMax16 = (msg) => {
|
|
61
61
|
const pad = (0, crypto_1.randomBytes)(1);
|
|
@@ -78,7 +78,7 @@ const unpadRandomMax16 = (e) => {
|
|
|
78
78
|
return new Uint8Array(t.buffer, t.byteOffset, t.length - r);
|
|
79
79
|
};
|
|
80
80
|
exports.unpadRandomMax16 = unpadRandomMax16;
|
|
81
|
-
const encodeWAMessage = (message) => (
|
|
81
|
+
const encodeWAMessage = (message) => (0, exports.writeRandomPadMax16)(WAProto_1.proto.Message.encode(message).finish());
|
|
82
82
|
exports.encodeWAMessage = encodeWAMessage;
|
|
83
83
|
const generateRegistrationId = () => {
|
|
84
84
|
return Uint16Array.from((0, crypto_1.randomBytes)(2))[0] & 16383;
|
|
@@ -94,7 +94,7 @@ const encodeBigEndian = (e, t = 4) => {
|
|
|
94
94
|
return a;
|
|
95
95
|
};
|
|
96
96
|
exports.encodeBigEndian = encodeBigEndian;
|
|
97
|
-
const toNumber = (t) =>
|
|
97
|
+
const toNumber = (t) => typeof t === 'object' && t ? ('toNumber' in t ? t.toNumber() : t.low) : t || 0;
|
|
98
98
|
exports.toNumber = toNumber;
|
|
99
99
|
/** unix timestamp of a date in seconds */
|
|
100
100
|
const unixTimestampSeconds = (date = new Date()) => Math.floor(date.getTime() / 1000);
|
|
@@ -112,8 +112,8 @@ const debouncedTimeout = (intervalMs = 1000, task) => {
|
|
|
112
112
|
timeout && clearTimeout(timeout);
|
|
113
113
|
timeout = undefined;
|
|
114
114
|
},
|
|
115
|
-
setTask: (newTask) => task = newTask,
|
|
116
|
-
setInterval: (newInterval) => intervalMs = newInterval
|
|
115
|
+
setTask: (newTask) => (task = newTask),
|
|
116
|
+
setInterval: (newInterval) => (intervalMs = newInterval)
|
|
117
117
|
};
|
|
118
118
|
};
|
|
119
119
|
exports.debouncedTimeout = debouncedTimeout;
|
|
@@ -156,8 +156,7 @@ async function promiseTimeout(ms, promise) {
|
|
|
156
156
|
})))
|
|
157
157
|
.catch(err => reject(err));
|
|
158
158
|
promise(resolve, reject);
|
|
159
|
-
})
|
|
160
|
-
.finally(cancel);
|
|
159
|
+
}).finally(cancel);
|
|
161
160
|
return p;
|
|
162
161
|
}
|
|
163
162
|
// inspired from whatsmeow code
|
|
@@ -185,11 +184,10 @@ function bindWaitForEvent(ev, event) {
|
|
|
185
184
|
return async (check, timeoutMs) => {
|
|
186
185
|
let listener;
|
|
187
186
|
let closeListener;
|
|
188
|
-
await
|
|
187
|
+
await promiseTimeout(timeoutMs, (resolve, reject) => {
|
|
189
188
|
closeListener = ({ connection, lastDisconnect }) => {
|
|
190
189
|
if (connection === 'close') {
|
|
191
|
-
reject((lastDisconnect === null || lastDisconnect === void 0 ? void 0 : lastDisconnect.error)
|
|
192
|
-
|| new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }));
|
|
190
|
+
reject((lastDisconnect === null || lastDisconnect === void 0 ? void 0 : lastDisconnect.error) || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }));
|
|
193
191
|
}
|
|
194
192
|
};
|
|
195
193
|
ev.on('connection.update', closeListener);
|
|
@@ -199,11 +197,10 @@ function bindWaitForEvent(ev, event) {
|
|
|
199
197
|
}
|
|
200
198
|
};
|
|
201
199
|
ev.on(event, listener);
|
|
202
|
-
})
|
|
203
|
-
.finally(() => {
|
|
200
|
+
}).finally(() => {
|
|
204
201
|
ev.off(event, listener);
|
|
205
202
|
ev.off('connection.update', closeListener);
|
|
206
|
-
})
|
|
203
|
+
});
|
|
207
204
|
};
|
|
208
205
|
}
|
|
209
206
|
const bindWaitForConnectionUpdate = (ev) => bindWaitForEvent(ev, 'connection.update');
|
|
@@ -276,9 +273,9 @@ const generateMdTagPrefix = () => {
|
|
|
276
273
|
};
|
|
277
274
|
exports.generateMdTagPrefix = generateMdTagPrefix;
|
|
278
275
|
const STATUS_MAP = {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
276
|
+
sender: WAProto_1.proto.WebMessageInfo.Status.SERVER_ACK,
|
|
277
|
+
played: WAProto_1.proto.WebMessageInfo.Status.PLAYED,
|
|
278
|
+
read: WAProto_1.proto.WebMessageInfo.Status.READ,
|
|
282
279
|
'read-self': WAProto_1.proto.WebMessageInfo.Status.READ
|
|
283
280
|
};
|
|
284
281
|
/**
|
|
@@ -354,8 +351,9 @@ const getCodeFromWSError = (error) => {
|
|
|
354
351
|
}
|
|
355
352
|
else if (
|
|
356
353
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
357
|
-
((_b = error === null || error === void 0 ? void 0 : error.code) === null || _b === void 0 ? void 0 : _b.startsWith('E'))
|
|
358
|
-
|
|
354
|
+
((_b = error === null || error === void 0 ? void 0 : error.code) === null || _b === void 0 ? void 0 : _b.startsWith('E')) ||
|
|
355
|
+
((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.includes('timed out'))) {
|
|
356
|
+
// handle ETIMEOUT, ENOTFOUND etc
|
|
359
357
|
statusCode = 408;
|
|
360
358
|
}
|
|
361
359
|
return statusCode;
|
package/lib/Utils/history.js
CHANGED
|
@@ -34,7 +34,12 @@ const processHistoryMessage = (item) => {
|
|
|
34
34
|
case WAProto_1.proto.HistorySync.HistorySyncType.FULL:
|
|
35
35
|
case WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND:
|
|
36
36
|
for (const chat of item.conversations) {
|
|
37
|
-
contacts.push({
|
|
37
|
+
contacts.push({
|
|
38
|
+
id: chat.id,
|
|
39
|
+
name: chat.name || undefined,
|
|
40
|
+
lid: chat.lidJid || undefined,
|
|
41
|
+
jid: (0, WABinary_1.isJidUser)(chat.id) ? chat.id : undefined
|
|
42
|
+
});
|
|
38
43
|
const msgs = chat.messages || [];
|
|
39
44
|
delete chat.messages;
|
|
40
45
|
delete chat.archived;
|
|
@@ -50,12 +55,12 @@ const processHistoryMessage = (item) => {
|
|
|
50
55
|
if (!message.key.fromMe && !chat.lastMessageRecvTimestamp) {
|
|
51
56
|
chat.lastMessageRecvTimestamp = (0, generics_1.toNumber)(message.messageTimestamp);
|
|
52
57
|
}
|
|
53
|
-
if ((message.messageStubType === Types_1.WAMessageStubType.BIZ_PRIVACY_MODE_TO_BSP
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
if ((message.messageStubType === Types_1.WAMessageStubType.BIZ_PRIVACY_MODE_TO_BSP ||
|
|
59
|
+
message.messageStubType === Types_1.WAMessageStubType.BIZ_PRIVACY_MODE_TO_FB) &&
|
|
60
|
+
((_b = message.messageStubParameters) === null || _b === void 0 ? void 0 : _b[0])) {
|
|
56
61
|
contacts.push({
|
|
57
62
|
id: message.key.participant || message.key.remoteJid,
|
|
58
|
-
verifiedName: (_c = message.messageStubParameters) === null || _c === void 0 ? void 0 : _c[0]
|
|
63
|
+
verifiedName: (_c = message.messageStubParameters) === null || _c === void 0 ? void 0 : _c[0]
|
|
59
64
|
});
|
|
60
65
|
}
|
|
61
66
|
}
|
|
@@ -72,9 +72,9 @@ const getUrlInfo = async (text, opts = {
|
|
|
72
72
|
if (retries >= maxRetry) {
|
|
73
73
|
return false;
|
|
74
74
|
}
|
|
75
|
-
if (forwardedURLObj.hostname === urlObj.hostname
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
if (forwardedURLObj.hostname === urlObj.hostname ||
|
|
76
|
+
forwardedURLObj.hostname === 'www.' + urlObj.hostname ||
|
|
77
|
+
'www.' + forwardedURLObj.hostname === urlObj.hostname) {
|
|
78
78
|
retries + 1;
|
|
79
79
|
return true;
|
|
80
80
|
}
|
|
@@ -99,16 +99,12 @@ const getUrlInfo = async (text, opts = {
|
|
|
99
99
|
mediaTypeOverride: 'thumbnail-link',
|
|
100
100
|
options: opts.fetchOpts
|
|
101
101
|
});
|
|
102
|
-
urlInfo.jpegThumbnail = (imageMessage === null || imageMessage === void 0 ? void 0 : imageMessage.jpegThumbnail)
|
|
103
|
-
? Buffer.from(imageMessage.jpegThumbnail)
|
|
104
|
-
: undefined;
|
|
102
|
+
urlInfo.jpegThumbnail = (imageMessage === null || imageMessage === void 0 ? void 0 : imageMessage.jpegThumbnail) ? Buffer.from(imageMessage.jpegThumbnail) : undefined;
|
|
105
103
|
urlInfo.highQualityThumbnail = imageMessage || undefined;
|
|
106
104
|
}
|
|
107
105
|
else {
|
|
108
106
|
try {
|
|
109
|
-
urlInfo.jpegThumbnail = image
|
|
110
|
-
? (await getCompressedJpegThumbnail(image, opts)).buffer
|
|
111
|
-
: undefined;
|
|
107
|
+
urlInfo.jpegThumbnail = image ? (await getCompressedJpegThumbnail(image, opts)).buffer : undefined;
|
|
112
108
|
}
|
|
113
109
|
catch (error) {
|
|
114
110
|
(_a = opts.logger) === null || _a === void 0 ? void 0 : _a.debug({ err: error.stack, url: previewLink }, 'error in generating thumbnail');
|
package/lib/Utils/lt-hash.js
CHANGED
|
@@ -33,12 +33,12 @@ class d {
|
|
|
33
33
|
async _addSingle(e, t) {
|
|
34
34
|
var r = this;
|
|
35
35
|
const n = new Uint8Array(await (0, crypto_1.hkdf)(Buffer.from(t), o, { info: r.salt })).buffer;
|
|
36
|
-
return r.performPointwiseWithOverflow(await e, n, (
|
|
36
|
+
return r.performPointwiseWithOverflow(await e, n, (e, t) => e + t);
|
|
37
37
|
}
|
|
38
38
|
async _subtractSingle(e, t) {
|
|
39
39
|
var r = this;
|
|
40
40
|
const n = new Uint8Array(await (0, crypto_1.hkdf)(Buffer.from(t), o, { info: r.salt })).buffer;
|
|
41
|
-
return r.performPointwiseWithOverflow(await e, n, (
|
|
41
|
+
return r.performPointwiseWithOverflow(await e, n, (e, t) => e - t);
|
|
42
42
|
}
|
|
43
43
|
performPointwiseWithOverflow(e, t, r) {
|
|
44
44
|
const n = new DataView(e), i = new DataView(t), a = new ArrayBuffer(n.byteLength), s = new DataView(a);
|
package/lib/Utils/make-mutex.js
CHANGED
|
@@ -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
|
-
|
|
66
|
-
|
|
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;
|
|
@@ -60,11 +60,11 @@ const getTmpFilesDirectory = () => (0, os_1.tmpdir)();
|
|
|
60
60
|
const getImageProcessingLibrary = async () => {
|
|
61
61
|
const [_jimp, sharp] = await Promise.all([
|
|
62
62
|
(async () => {
|
|
63
|
-
const jimp = await
|
|
63
|
+
const jimp = await Promise.resolve().then(() => __importStar(require('jimp'))).catch(() => { });
|
|
64
64
|
return jimp;
|
|
65
65
|
})(),
|
|
66
66
|
(async () => {
|
|
67
|
-
const sharp = await
|
|
67
|
+
const sharp = await Promise.resolve().then(() => __importStar(require('sharp'))).catch(() => { });
|
|
68
68
|
return sharp;
|
|
69
69
|
})()
|
|
70
70
|
]);
|
|
@@ -95,13 +95,13 @@ async function getMediaKeys(buffer, mediaType) {
|
|
|
95
95
|
return {
|
|
96
96
|
iv: expandedMediaKey.slice(0, 16),
|
|
97
97
|
cipherKey: expandedMediaKey.slice(16, 48),
|
|
98
|
-
macKey: expandedMediaKey.slice(48, 80)
|
|
98
|
+
macKey: expandedMediaKey.slice(48, 80)
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
/** Extracts video thumb using FFMPEG */
|
|
102
102
|
const extractVideoThumb = async (path, destPath, time, size) => new Promise((resolve, reject) => {
|
|
103
103
|
const cmd = `ffmpeg -ss ${time} -i ${path} -y -vf scale=${size.width}:-1 -vframes 1 -f image2 ${destPath}`;
|
|
104
|
-
(0, child_process_1.exec)(cmd,
|
|
104
|
+
(0, child_process_1.exec)(cmd, err => {
|
|
105
105
|
if (err) {
|
|
106
106
|
reject(err);
|
|
107
107
|
}
|
|
@@ -119,16 +119,13 @@ const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
|
119
119
|
if ('sharp' in lib && typeof ((_a = lib.sharp) === null || _a === void 0 ? void 0 : _a.default) === 'function') {
|
|
120
120
|
const img = lib.sharp.default(bufferOrFilePath);
|
|
121
121
|
const dimensions = await img.metadata();
|
|
122
|
-
const buffer = await img
|
|
123
|
-
.resize(width)
|
|
124
|
-
.jpeg({ quality: 50 })
|
|
125
|
-
.toBuffer();
|
|
122
|
+
const buffer = await img.resize(width).jpeg({ quality: 50 }).toBuffer();
|
|
126
123
|
return {
|
|
127
124
|
buffer,
|
|
128
125
|
original: {
|
|
129
126
|
width: dimensions.width,
|
|
130
|
-
height: dimensions.height
|
|
131
|
-
}
|
|
127
|
+
height: dimensions.height
|
|
128
|
+
}
|
|
132
129
|
};
|
|
133
130
|
}
|
|
134
131
|
else if ('jimp' in lib && typeof ((_b = lib.jimp) === null || _b === void 0 ? void 0 : _b.read) === 'function') {
|
|
@@ -138,10 +135,7 @@ const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
|
138
135
|
width: jimp.getWidth(),
|
|
139
136
|
height: jimp.getHeight()
|
|
140
137
|
};
|
|
141
|
-
const buffer = await jimp
|
|
142
|
-
.quality(50)
|
|
143
|
-
.resize(width, AUTO, RESIZE_BILINEAR)
|
|
144
|
-
.getBufferAsync(MIME_JPEG);
|
|
138
|
+
const buffer = await jimp.quality(50).resize(width, AUTO, RESIZE_BILINEAR).getBufferAsync(MIME_JPEG);
|
|
145
139
|
return {
|
|
146
140
|
buffer,
|
|
147
141
|
original: dimensions
|
|
@@ -152,10 +146,7 @@ const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
|
152
146
|
}
|
|
153
147
|
};
|
|
154
148
|
exports.extractImageThumb = extractImageThumb;
|
|
155
|
-
const encodeBase64EncodedStringForUpload = (b64) =>
|
|
156
|
-
.replace(/\+/g, '-')
|
|
157
|
-
.replace(/\//g, '_')
|
|
158
|
-
.replace(/\=+$/, '')));
|
|
149
|
+
const encodeBase64EncodedStringForUpload = (b64) => encodeURIComponent(b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, ''));
|
|
159
150
|
exports.encodeBase64EncodedStringForUpload = encodeBase64EncodedStringForUpload;
|
|
160
151
|
const generateProfilePicture = async (mediaUpload) => {
|
|
161
152
|
var _a, _b;
|
|
@@ -172,10 +163,11 @@ const generateProfilePicture = async (mediaUpload) => {
|
|
|
172
163
|
const lib = await getImageProcessingLibrary();
|
|
173
164
|
let img;
|
|
174
165
|
if ('sharp' in lib && typeof ((_a = lib.sharp) === null || _a === void 0 ? void 0 : _a.default) === 'function') {
|
|
175
|
-
img = lib.sharp
|
|
166
|
+
img = lib.sharp
|
|
167
|
+
.default(bufferOrFilePath)
|
|
176
168
|
.resize(640, 640)
|
|
177
169
|
.jpeg({
|
|
178
|
-
quality: 50
|
|
170
|
+
quality: 50
|
|
179
171
|
})
|
|
180
172
|
.toBuffer();
|
|
181
173
|
}
|
|
@@ -184,16 +176,13 @@ const generateProfilePicture = async (mediaUpload) => {
|
|
|
184
176
|
const jimp = await read(bufferOrFilePath);
|
|
185
177
|
const min = Math.min(jimp.getWidth(), jimp.getHeight());
|
|
186
178
|
const cropped = jimp.crop(0, 0, min, min);
|
|
187
|
-
img = cropped
|
|
188
|
-
.quality(50)
|
|
189
|
-
.resize(640, 640, RESIZE_BILINEAR)
|
|
190
|
-
.getBufferAsync(MIME_JPEG);
|
|
179
|
+
img = cropped.quality(50).resize(640, 640, RESIZE_BILINEAR).getBufferAsync(MIME_JPEG);
|
|
191
180
|
}
|
|
192
181
|
else {
|
|
193
182
|
throw new boom_1.Boom('No image processing library available');
|
|
194
183
|
}
|
|
195
184
|
return {
|
|
196
|
-
img: await img
|
|
185
|
+
img: await img
|
|
197
186
|
};
|
|
198
187
|
};
|
|
199
188
|
exports.generateProfilePicture = generateProfilePicture;
|
|
@@ -206,20 +195,17 @@ exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
|
|
|
206
195
|
async function getAudioDuration(buffer) {
|
|
207
196
|
const musicMetadata = await Promise.resolve().then(() => __importStar(require('music-metadata')));
|
|
208
197
|
let metadata;
|
|
198
|
+
const options = {
|
|
199
|
+
duration: true
|
|
200
|
+
};
|
|
209
201
|
if (Buffer.isBuffer(buffer)) {
|
|
210
|
-
metadata = await musicMetadata.parseBuffer(buffer, undefined,
|
|
202
|
+
metadata = await musicMetadata.parseBuffer(buffer, undefined, options);
|
|
211
203
|
}
|
|
212
204
|
else if (typeof buffer === 'string') {
|
|
213
|
-
|
|
214
|
-
try {
|
|
215
|
-
metadata = await musicMetadata.parseStream(rStream, undefined, { duration: true });
|
|
216
|
-
}
|
|
217
|
-
finally {
|
|
218
|
-
rStream.destroy();
|
|
219
|
-
}
|
|
205
|
+
metadata = await musicMetadata.parseFile(buffer, options);
|
|
220
206
|
}
|
|
221
207
|
else {
|
|
222
|
-
metadata = await musicMetadata.parseStream(buffer, undefined,
|
|
208
|
+
metadata = await musicMetadata.parseStream(buffer, undefined, options);
|
|
223
209
|
}
|
|
224
210
|
return metadata.format.duration;
|
|
225
211
|
}
|
|
@@ -228,7 +214,7 @@ async function getAudioDuration(buffer) {
|
|
|
228
214
|
*/
|
|
229
215
|
async function getAudioWaveform(buffer, logger) {
|
|
230
216
|
try {
|
|
231
|
-
const { default: decoder } = await eval(
|
|
217
|
+
const { default: decoder } = await eval("import('audio-decode')");
|
|
232
218
|
let audioData;
|
|
233
219
|
if (Buffer.isBuffer(buffer)) {
|
|
234
220
|
audioData = buffer;
|
|
@@ -255,9 +241,9 @@ async function getAudioWaveform(buffer, logger) {
|
|
|
255
241
|
}
|
|
256
242
|
// This guarantees that the largest data point will be set to 1, and the rest of the data will scale proportionally.
|
|
257
243
|
const multiplier = Math.pow(Math.max(...filteredData), -1);
|
|
258
|
-
const normalizedData = filteredData.map(
|
|
244
|
+
const normalizedData = filteredData.map(n => n * multiplier);
|
|
259
245
|
// Generate waveform like WhatsApp
|
|
260
|
-
const waveform = new Uint8Array(normalizedData.map(
|
|
246
|
+
const waveform = new Uint8Array(normalizedData.map(n => Math.floor(100 * n)));
|
|
261
247
|
return waveform;
|
|
262
248
|
}
|
|
263
249
|
catch (e) {
|
|
@@ -304,7 +290,7 @@ async function generateThumbnail(file, mediaType, options) {
|
|
|
304
290
|
if (original.width && original.height) {
|
|
305
291
|
originalImageDimensions = {
|
|
306
292
|
width: original.width,
|
|
307
|
-
height: original.height
|
|
293
|
+
height: original.height
|
|
308
294
|
};
|
|
309
295
|
}
|
|
310
296
|
}
|
|
@@ -331,88 +317,85 @@ const getHttpStream = async (url, options = {}) => {
|
|
|
331
317
|
};
|
|
332
318
|
exports.getHttpStream = getHttpStream;
|
|
333
319
|
const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
|
|
320
|
+
var _a, _b;
|
|
334
321
|
const { stream, type } = await (0, exports.getStream)(media, opts);
|
|
335
322
|
logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
|
|
336
323
|
const mediaKey = Crypto.randomBytes(32);
|
|
337
324
|
const { cipherKey, iv, macKey } = await getMediaKeys(mediaKey, mediaType);
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
let
|
|
341
|
-
let
|
|
342
|
-
if (
|
|
343
|
-
|
|
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;
|
|
325
|
+
const encFilePath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageIDV2)() + '-enc');
|
|
326
|
+
const encFileWriteStream = (0, fs_1.createWriteStream)(encFilePath);
|
|
327
|
+
let originalFileStream;
|
|
328
|
+
let originalFilePath;
|
|
329
|
+
if (saveOriginalFileIfRequired) {
|
|
330
|
+
originalFilePath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageIDV2)() + '-original');
|
|
331
|
+
originalFileStream = (0, fs_1.createWriteStream)(originalFilePath);
|
|
349
332
|
}
|
|
350
333
|
let fileLength = 0;
|
|
351
334
|
const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv);
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
335
|
+
const hmac = Crypto.createHmac('sha256', macKey).update(iv);
|
|
336
|
+
const sha256Plain = Crypto.createHash('sha256');
|
|
337
|
+
const sha256Enc = Crypto.createHash('sha256');
|
|
338
|
+
const onChunk = (buff) => {
|
|
339
|
+
sha256Enc.update(buff);
|
|
340
|
+
hmac.update(buff);
|
|
341
|
+
encFileWriteStream.write(buff);
|
|
342
|
+
};
|
|
355
343
|
try {
|
|
356
344
|
for await (const data of stream) {
|
|
357
345
|
fileLength += data.length;
|
|
358
|
-
if (type === 'remote'
|
|
359
|
-
&& (opts === null || opts === void 0 ? void 0 : opts.maxContentLength)
|
|
360
|
-
&& fileLength + data.length > opts.maxContentLength) {
|
|
346
|
+
if (type === 'remote' && (opts === null || opts === void 0 ? void 0 : opts.maxContentLength) && fileLength + data.length > opts.maxContentLength) {
|
|
361
347
|
throw new boom_1.Boom(`content length exceeded when encrypting "${type}"`, {
|
|
362
348
|
data: { media, type }
|
|
363
349
|
});
|
|
364
350
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
351
|
+
if (originalFileStream) {
|
|
352
|
+
if (!originalFileStream.write(data)) {
|
|
353
|
+
await (0, events_1.once)(originalFileStream, 'drain');
|
|
354
|
+
}
|
|
368
355
|
}
|
|
356
|
+
sha256Plain.update(data);
|
|
369
357
|
onChunk(aes.update(data));
|
|
370
358
|
}
|
|
371
359
|
onChunk(aes.final());
|
|
372
360
|
const mac = hmac.digest().slice(0, 10);
|
|
373
|
-
sha256Enc
|
|
361
|
+
sha256Enc.update(mac);
|
|
374
362
|
const fileSha256 = sha256Plain.digest();
|
|
375
363
|
const fileEncSha256 = sha256Enc.digest();
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
364
|
+
encFileWriteStream.write(mac);
|
|
365
|
+
encFileWriteStream.end();
|
|
366
|
+
(_a = originalFileStream === null || originalFileStream === void 0 ? void 0 : originalFileStream.end) === null || _a === void 0 ? void 0 : _a.call(originalFileStream);
|
|
379
367
|
stream.destroy();
|
|
380
368
|
logger === null || logger === void 0 ? void 0 : logger.debug('encrypted data successfully');
|
|
381
369
|
return {
|
|
382
370
|
mediaKey,
|
|
383
|
-
|
|
384
|
-
|
|
371
|
+
originalFilePath,
|
|
372
|
+
encFilePath,
|
|
385
373
|
mac,
|
|
386
374
|
fileEncSha256,
|
|
387
375
|
fileSha256,
|
|
388
|
-
fileLength
|
|
389
|
-
didSaveToTmpPath
|
|
376
|
+
fileLength
|
|
390
377
|
};
|
|
391
378
|
}
|
|
392
379
|
catch (error) {
|
|
393
380
|
// destroy all streams with error
|
|
394
|
-
|
|
395
|
-
|
|
381
|
+
encFileWriteStream.destroy();
|
|
382
|
+
(_b = originalFileStream === null || originalFileStream === void 0 ? void 0 : originalFileStream.destroy) === null || _b === void 0 ? void 0 : _b.call(originalFileStream);
|
|
396
383
|
aes.destroy();
|
|
397
384
|
hmac.destroy();
|
|
398
385
|
sha256Plain.destroy();
|
|
399
386
|
sha256Enc.destroy();
|
|
400
387
|
stream.destroy();
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
catch (err) {
|
|
406
|
-
logger === null || logger === void 0 ? void 0 : logger.error({ err }, 'failed to save to tmp path');
|
|
388
|
+
try {
|
|
389
|
+
await fs_1.promises.unlink(encFilePath);
|
|
390
|
+
if (originalFilePath) {
|
|
391
|
+
await fs_1.promises.unlink(originalFilePath);
|
|
407
392
|
}
|
|
408
393
|
}
|
|
394
|
+
catch (err) {
|
|
395
|
+
logger === null || logger === void 0 ? void 0 : logger.error({ err }, 'failed deleting tmp files');
|
|
396
|
+
}
|
|
409
397
|
throw error;
|
|
410
398
|
}
|
|
411
|
-
function onChunk(buff) {
|
|
412
|
-
sha256Enc = sha256Enc.update(buff);
|
|
413
|
-
hmac = hmac.update(buff);
|
|
414
|
-
encWriteStream.push(buff);
|
|
415
|
-
}
|
|
416
399
|
};
|
|
417
400
|
exports.encryptedStream = encryptedStream;
|
|
418
401
|
const DEF_HOST = 'mmg.whatsapp.net';
|
|
@@ -447,8 +430,8 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
|
|
|
447
430
|
}
|
|
448
431
|
const endChunk = endByte ? toSmallestChunkSize(endByte || 0) + AES_CHUNK_SIZE : undefined;
|
|
449
432
|
const headers = {
|
|
450
|
-
...(options === null || options === void 0 ? void 0 : options.headers) || {},
|
|
451
|
-
Origin: Defaults_1.DEFAULT_ORIGIN
|
|
433
|
+
...((options === null || options === void 0 ? void 0 : options.headers) || {}),
|
|
434
|
+
Origin: Defaults_1.DEFAULT_ORIGIN
|
|
452
435
|
};
|
|
453
436
|
if (startChunk || endChunk) {
|
|
454
437
|
headers.Range = `bytes=${startChunk}-`;
|
|
@@ -458,10 +441,10 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
|
|
|
458
441
|
}
|
|
459
442
|
// download the message
|
|
460
443
|
const fetched = await (0, exports.getHttpStream)(downloadUrl, {
|
|
461
|
-
...options || {},
|
|
444
|
+
...(options || {}),
|
|
462
445
|
headers,
|
|
463
446
|
maxBodyLength: Infinity,
|
|
464
|
-
maxContentLength: Infinity
|
|
447
|
+
maxContentLength: Infinity
|
|
465
448
|
});
|
|
466
449
|
let remainingBytes = Buffer.from([]);
|
|
467
450
|
let aes;
|
|
@@ -511,7 +494,7 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
|
|
|
511
494
|
catch (error) {
|
|
512
495
|
callback(error);
|
|
513
496
|
}
|
|
514
|
-
}
|
|
497
|
+
}
|
|
515
498
|
});
|
|
516
499
|
return fetched.pipe(output, { end: true });
|
|
517
500
|
};
|
|
@@ -520,9 +503,7 @@ function extensionForMediaMessage(message) {
|
|
|
520
503
|
const getExtension = (mimetype) => mimetype.split(';')[0].split('/')[1];
|
|
521
504
|
const type = Object.keys(message)[0];
|
|
522
505
|
let extension;
|
|
523
|
-
if (type === 'locationMessage' ||
|
|
524
|
-
type === 'liveLocationMessage' ||
|
|
525
|
-
type === 'productMessage') {
|
|
506
|
+
if (type === 'locationMessage' || type === 'liveLocationMessage' || type === 'productMessage') {
|
|
526
507
|
extension = '.jpeg';
|
|
527
508
|
}
|
|
528
509
|
else {
|
|
@@ -532,7 +513,7 @@ function extensionForMediaMessage(message) {
|
|
|
532
513
|
return extension;
|
|
533
514
|
}
|
|
534
515
|
const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
535
|
-
return async (
|
|
516
|
+
return async (filePath, { mediaType, fileEncSha256B64, timeoutMs }) => {
|
|
536
517
|
var _a, _b;
|
|
537
518
|
// send a query JSON to obtain the url & auth token to upload our media
|
|
538
519
|
let uploadInfo = await refreshMediaConn(false);
|
|
@@ -546,18 +527,19 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
546
527
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
547
528
|
let result;
|
|
548
529
|
try {
|
|
549
|
-
const body = await axios_1.default.post(url,
|
|
530
|
+
const body = await axios_1.default.post(url, (0, fs_1.createReadStream)(filePath), {
|
|
550
531
|
...options,
|
|
532
|
+
maxRedirects: 0,
|
|
551
533
|
headers: {
|
|
552
|
-
...options.headers || {},
|
|
534
|
+
...(options.headers || {}),
|
|
553
535
|
'Content-Type': 'application/octet-stream',
|
|
554
|
-
|
|
536
|
+
Origin: Defaults_1.DEFAULT_ORIGIN
|
|
555
537
|
},
|
|
556
538
|
httpsAgent: fetchAgent,
|
|
557
539
|
timeout: timeoutMs,
|
|
558
540
|
responseType: 'json',
|
|
559
541
|
maxBodyLength: Infinity,
|
|
560
|
-
maxContentLength: Infinity
|
|
542
|
+
maxContentLength: Infinity
|
|
561
543
|
});
|
|
562
544
|
result = body.data;
|
|
563
545
|
if ((result === null || result === void 0 ? void 0 : result.url) || (result === null || result === void 0 ? void 0 : result.directPath)) {
|
|
@@ -622,7 +604,7 @@ const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
|
|
|
622
604
|
tag: 'rmr',
|
|
623
605
|
attrs: {
|
|
624
606
|
jid: key.remoteJid,
|
|
625
|
-
|
|
607
|
+
from_me: (!!key.fromMe).toString(),
|
|
626
608
|
// @ts-ignore
|
|
627
609
|
participant: key.participant || undefined
|
|
628
610
|
}
|
|
@@ -645,7 +627,10 @@ const decodeMediaRetryNode = (node) => {
|
|
|
645
627
|
const errorNode = (0, WABinary_1.getBinaryNodeChild)(node, 'error');
|
|
646
628
|
if (errorNode) {
|
|
647
629
|
const errorCode = +errorNode.attrs.code;
|
|
648
|
-
event.error = new boom_1.Boom(`Failed to re-upload media (${errorCode})`, {
|
|
630
|
+
event.error = new boom_1.Boom(`Failed to re-upload media (${errorCode})`, {
|
|
631
|
+
data: errorNode.attrs,
|
|
632
|
+
statusCode: (0, exports.getStatusCodeForMediaRetry)(errorCode)
|
|
633
|
+
});
|
|
649
634
|
}
|
|
650
635
|
else {
|
|
651
636
|
const encryptedInfoNode = (0, WABinary_1.getBinaryNodeChild)(node, 'encrypt');
|
|
@@ -673,5 +658,5 @@ const MEDIA_RETRY_STATUS_MAP = {
|
|
|
673
658
|
[WAProto_1.proto.MediaRetryNotification.ResultType.SUCCESS]: 200,
|
|
674
659
|
[WAProto_1.proto.MediaRetryNotification.ResultType.DECRYPTION_ERROR]: 412,
|
|
675
660
|
[WAProto_1.proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
|
|
676
|
-
[WAProto_1.proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418
|
|
661
|
+
[WAProto_1.proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418
|
|
677
662
|
};
|
package/lib/Utils/messages.d.ts
CHANGED
|
@@ -38,7 +38,7 @@ export declare const extractMessageContent: (content: WAMessageContent | undefin
|
|
|
38
38
|
/**
|
|
39
39
|
* Returns the device predicted by message ID
|
|
40
40
|
*/
|
|
41
|
-
export declare const getDevice: (id: string) => "
|
|
41
|
+
export declare const getDevice: (id: string) => "web" | "unknown" | "android" | "ios" | "desktop";
|
|
42
42
|
/** Upserts a receipt in the message */
|
|
43
43
|
export declare const updateMessageWithReceipt: (msg: Pick<WAMessage, "userReceipt">, receipt: MessageUserReceipt) => void;
|
|
44
44
|
/** Update the message with a new reaction */
|