@d0v3riz/baileys 6.7.2 → 6.7.5
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 +4 -3
- package/lib/Defaults/baileys-version.json +1 -1
- package/lib/Socket/business.d.ts +2 -0
- package/lib/Socket/business.js +1 -0
- package/lib/Socket/chats.d.ts +5 -6
- package/lib/Socket/chats.js +7 -2
- package/lib/Socket/groups.d.ts +1 -0
- package/lib/Socket/groups.js +2 -1
- package/lib/Socket/index.d.ts +2 -0
- package/lib/Socket/messages-recv.d.ts +1 -0
- package/lib/Socket/messages-recv.js +32 -15
- package/lib/Socket/messages-send.d.ts +1 -0
- package/lib/Socket/messages-send.js +8 -3
- package/lib/Socket/registration.d.ts +2 -0
- package/lib/Socket/socket.js +16 -3
- package/lib/Store/make-in-memory-store.d.ts +2 -2
- package/lib/Store/make-in-memory-store.js +6 -43
- package/lib/Types/Auth.d.ts +1 -0
- package/lib/Types/Chat.d.ts +1 -0
- package/lib/Types/Events.d.ts +8 -1
- package/lib/Types/GroupMetadata.d.ts +3 -1
- package/lib/Types/index.d.ts +7 -0
- package/lib/Utils/auth-utils.js +1 -0
- package/lib/Utils/crypto.d.ts +1 -1
- package/lib/Utils/crypto.js +4 -2
- package/lib/Utils/generics.d.ts +4 -9
- package/lib/Utils/generics.js +34 -8
- package/lib/Utils/messages-media.d.ts +1 -0
- package/lib/Utils/messages-media.js +8 -14
- package/lib/Utils/messages.d.ts +2 -1
- package/lib/Utils/messages.js +9 -7
- package/lib/Utils/noise-handler.d.ts +3 -2
- package/lib/Utils/noise-handler.js +18 -5
- package/lib/Utils/process-message.js +15 -2
- package/lib/Utils/signal.js +26 -16
- package/lib/Utils/use-multi-file-auth-state.js +16 -3
- package/lib/WABinary/decode.d.ts +2 -2
- package/lib/WABinary/decode.js +6 -4
- package/lib/WABinary/encode.d.ts +1 -1
- package/lib/WABinary/encode.js +8 -4
- package/package.json +9 -7
package/lib/Utils/generics.d.ts
CHANGED
|
@@ -2,16 +2,10 @@
|
|
|
2
2
|
import { AxiosRequestConfig } from 'axios';
|
|
3
3
|
import { Logger } from 'pino';
|
|
4
4
|
import { proto } from '../../WAProto';
|
|
5
|
-
import { BaileysEventEmitter, BaileysEventMap, WACallUpdateType, WAVersion } from '../Types';
|
|
5
|
+
import { BaileysEventEmitter, BaileysEventMap, BrowsersMap, WACallUpdateType, WAVersion } from '../Types';
|
|
6
6
|
import { BinaryNode } from '../WABinary';
|
|
7
|
-
export declare const Browsers:
|
|
8
|
-
|
|
9
|
-
macOS: (browser: any) => [string, string, string];
|
|
10
|
-
baileys: (browser: any) => [string, string, string];
|
|
11
|
-
windows: (browser: any) => [string, string, string];
|
|
12
|
-
/** The appropriate browser based on your OS & release */
|
|
13
|
-
appropriate: (browser: any) => [string, string, string];
|
|
14
|
-
};
|
|
7
|
+
export declare const Browsers: BrowsersMap;
|
|
8
|
+
export declare const getPlatformId: (browser: string) => any;
|
|
15
9
|
export declare const BufferJSON: {
|
|
16
10
|
replacer: (k: any, value: any) => any;
|
|
17
11
|
reviver: (_: any, value: any) => any;
|
|
@@ -38,6 +32,7 @@ export declare const delayCancellable: (ms: number) => {
|
|
|
38
32
|
cancel: () => void;
|
|
39
33
|
};
|
|
40
34
|
export declare function promiseTimeout<T>(ms: number | undefined, promise: (resolve: (v: T) => void, reject: (error: any) => void) => void): Promise<T>;
|
|
35
|
+
export declare const generateMessageIDV2: (userId?: string) => string;
|
|
41
36
|
export declare const generateMessageID: () => string;
|
|
42
37
|
export declare function bindWaitForEvent<T extends keyof BaileysEventMap>(ev: BaileysEventEmitter, event: T): (check: (u: BaileysEventMap[T]) => boolean | undefined, timeoutMs?: number) => Promise<void>;
|
|
43
38
|
export declare const bindWaitForConnectionUpdate: (ev: BaileysEventEmitter) => (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number) => Promise<void>;
|
package/lib/Utils/generics.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.bytesToCrockford = exports.trimUndefined = exports.isWABusinessPlatform = exports.getCodeFromWSError = exports.getCallStatusFromNode = exports.getErrorCodeFromStreamError = exports.getStatusFromReceiptType = exports.generateMdTagPrefix = exports.fetchLatestWaWebVersion = exports.fetchLatestBaileysVersion = exports.printQRIfNecessaryListener = exports.bindWaitForConnectionUpdate = exports.bindWaitForEvent = exports.generateMessageID = exports.promiseTimeout = exports.delayCancellable = exports.delay = exports.debouncedTimeout = exports.unixTimestampSeconds = exports.toNumber = exports.encodeBigEndian = exports.generateRegistrationId = exports.encodeWAMessage = exports.unpadRandomMax16 = exports.writeRandomPadMax16 = exports.getKeyAuthor = exports.BufferJSON = exports.Browsers = void 0;
|
|
6
|
+
exports.bytesToCrockford = exports.trimUndefined = exports.isWABusinessPlatform = exports.getCodeFromWSError = exports.getCallStatusFromNode = exports.getErrorCodeFromStreamError = exports.getStatusFromReceiptType = exports.generateMdTagPrefix = exports.fetchLatestWaWebVersion = exports.fetchLatestBaileysVersion = exports.printQRIfNecessaryListener = exports.bindWaitForConnectionUpdate = exports.bindWaitForEvent = exports.generateMessageID = exports.generateMessageIDV2 = exports.promiseTimeout = exports.delayCancellable = exports.delay = exports.debouncedTimeout = exports.unixTimestampSeconds = exports.toNumber = exports.encodeBigEndian = exports.generateRegistrationId = exports.encodeWAMessage = exports.unpadRandomMax16 = exports.writeRandomPadMax16 = exports.getKeyAuthor = exports.BufferJSON = exports.getPlatformId = exports.Browsers = void 0;
|
|
7
7
|
const boom_1 = require("@hapi/boom");
|
|
8
8
|
const axios_1 = __importDefault(require("axios"));
|
|
9
9
|
const crypto_1 = require("crypto");
|
|
@@ -16,16 +16,24 @@ const PLATFORM_MAP = {
|
|
|
16
16
|
'aix': 'AIX',
|
|
17
17
|
'darwin': 'Mac OS',
|
|
18
18
|
'win32': 'Windows',
|
|
19
|
-
'android': 'Android'
|
|
19
|
+
'android': 'Android',
|
|
20
|
+
'freebsd': 'FreeBSD',
|
|
21
|
+
'openbsd': 'OpenBSD',
|
|
22
|
+
'sunos': 'Solaris'
|
|
20
23
|
};
|
|
21
24
|
exports.Browsers = {
|
|
22
|
-
ubuntu: browser => ['Ubuntu', browser, '
|
|
23
|
-
macOS: browser => ['Mac OS', browser, '
|
|
24
|
-
baileys: browser => ['Baileys', browser, '
|
|
25
|
-
windows: browser => ['Windows', browser, '10.0.
|
|
25
|
+
ubuntu: (browser) => ['Ubuntu', browser, '22.04.4'],
|
|
26
|
+
macOS: (browser) => ['Mac OS', browser, '14.4.1'],
|
|
27
|
+
baileys: (browser) => ['Baileys', browser, '6.5.0'],
|
|
28
|
+
windows: (browser) => ['Windows', browser, '10.0.22631'],
|
|
26
29
|
/** The appropriate browser based on your OS & release */
|
|
27
|
-
appropriate: browser => [PLATFORM_MAP[(0, os_1.platform)()] || 'Ubuntu', browser, (0, os_1.release)()]
|
|
30
|
+
appropriate: (browser) => [PLATFORM_MAP[(0, os_1.platform)()] || 'Ubuntu', browser, (0, os_1.release)()]
|
|
28
31
|
};
|
|
32
|
+
const getPlatformId = (browser) => {
|
|
33
|
+
const platformType = WAProto_1.proto.DeviceProps.PlatformType[browser.toUpperCase()];
|
|
34
|
+
return platformType ? platformType.toString().charCodeAt(0).toString() : '49'; //chrome
|
|
35
|
+
};
|
|
36
|
+
exports.getPlatformId = getPlatformId;
|
|
29
37
|
exports.BufferJSON = {
|
|
30
38
|
replacer: (k, value) => {
|
|
31
39
|
if (Buffer.isBuffer(value) || value instanceof Uint8Array || (value === null || value === void 0 ? void 0 : value.type) === 'Buffer') {
|
|
@@ -147,8 +155,26 @@ async function promiseTimeout(ms, promise) {
|
|
|
147
155
|
return p;
|
|
148
156
|
}
|
|
149
157
|
exports.promiseTimeout = promiseTimeout;
|
|
158
|
+
// inspired from whatsmeow code
|
|
159
|
+
// https://github.com/tulir/whatsmeow/blob/64bc969fbe78d31ae0dd443b8d4c80a5d026d07a/send.go#L42
|
|
160
|
+
const generateMessageIDV2 = (userId) => {
|
|
161
|
+
const data = Buffer.alloc(8 + 20 + 16);
|
|
162
|
+
data.writeBigUInt64BE(BigInt(Math.floor(Date.now() / 1000)));
|
|
163
|
+
if (userId) {
|
|
164
|
+
const id = (0, WABinary_1.jidDecode)(userId);
|
|
165
|
+
if (id === null || id === void 0 ? void 0 : id.user) {
|
|
166
|
+
data.write(id.user, 8);
|
|
167
|
+
data.write('@c.us', 8 + id.user.length);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const random = (0, crypto_1.randomBytes)(16);
|
|
171
|
+
random.copy(data, 28);
|
|
172
|
+
const hash = (0, crypto_1.createHash)('sha256').update(data).digest();
|
|
173
|
+
return (process.env.WHATSAPP_CONN_IDMSG || 'WHPI') + hash.toString('hex').toUpperCase().substring(0, 18);
|
|
174
|
+
};
|
|
175
|
+
exports.generateMessageIDV2 = generateMessageIDV2;
|
|
150
176
|
// generate a random ID to attach to a message
|
|
151
|
-
const generateMessageID = () => (process.env.WHATSAPP_CONN_IDMSG || 'WHPI') + (0, crypto_1.randomBytes)(
|
|
177
|
+
const generateMessageID = () => (process.env.WHATSAPP_CONN_IDMSG || 'WHPI') + (0, crypto_1.randomBytes)(18).toString('hex').toUpperCase();
|
|
152
178
|
exports.generateMessageID = generateMessageID;
|
|
153
179
|
function bindWaitForEvent(ev, event) {
|
|
154
180
|
return async (check, timeoutMs) => {
|
|
@@ -93,6 +93,7 @@ export declare const getWAUploadToServer: ({ customUploadHosts, fetchAgent, logg
|
|
|
93
93
|
export declare const encryptMediaRetryRequest: (key: proto.IMessageKey, mediaKey: Buffer | Uint8Array, meId: string) => BinaryNode;
|
|
94
94
|
export declare const decodeMediaRetryNode: (node: BinaryNode) => {
|
|
95
95
|
key: proto.IMessageKey;
|
|
96
|
+
/** generates all the keys required to encrypt/decrypt & sign a media message */
|
|
96
97
|
media?: {
|
|
97
98
|
ciphertext: Uint8Array;
|
|
98
99
|
iv: Uint8Array;
|
|
@@ -22,9 +22,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
25
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
29
|
exports.getStatusCodeForMediaRetry = exports.decryptMediaRetryData = exports.decodeMediaRetryNode = exports.encryptMediaRetryRequest = exports.getWAUploadToServer = exports.extensionForMediaMessage = exports.downloadEncryptedContent = exports.downloadContentFromMessage = exports.getUrlFromDirectPath = exports.encryptedStream = exports.getHttpStream = exports.generateThumbnail = exports.getStream = exports.toBuffer = exports.toReadable = exports.getAudioWaveform = exports.getAudioDuration = exports.mediaMessageSHA256B64 = exports.generateProfilePicture = exports.encodeBase64EncodedStringForUpload = exports.extractImageThumb = exports.getMediaKeys = exports.hkdfInfoKey = void 0;
|
|
27
30
|
const boom_1 = require("@hapi/boom");
|
|
31
|
+
const axios_1 = __importDefault(require("axios"));
|
|
28
32
|
const child_process_1 = require("child_process");
|
|
29
33
|
const Crypto = __importStar(require("crypto"));
|
|
30
34
|
const events_1 = require("events");
|
|
@@ -313,8 +317,7 @@ async function generateThumbnail(file, mediaType, options) {
|
|
|
313
317
|
}
|
|
314
318
|
exports.generateThumbnail = generateThumbnail;
|
|
315
319
|
const getHttpStream = async (url, options = {}) => {
|
|
316
|
-
const
|
|
317
|
-
const fetched = await axios.get(url.toString(), { ...options, responseType: 'stream' });
|
|
320
|
+
const fetched = await axios_1.default.get(url.toString(), { ...options, responseType: 'stream' });
|
|
318
321
|
return fetched.data;
|
|
319
322
|
};
|
|
320
323
|
exports.getHttpStream = getHttpStream;
|
|
@@ -525,27 +528,18 @@ exports.extensionForMediaMessage = extensionForMediaMessage;
|
|
|
525
528
|
const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
526
529
|
return async (stream, { mediaType, fileEncSha256B64, timeoutMs }) => {
|
|
527
530
|
var _a, _b;
|
|
528
|
-
const { default: axios } = await import('axios');
|
|
529
531
|
// send a query JSON to obtain the url & auth token to upload our media
|
|
530
532
|
let uploadInfo = await refreshMediaConn(false);
|
|
531
533
|
let urls;
|
|
532
534
|
const hosts = [...customUploadHosts, ...uploadInfo.hosts];
|
|
533
|
-
const chunks = [];
|
|
534
|
-
for await (const chunk of stream) {
|
|
535
|
-
chunks.push(chunk);
|
|
536
|
-
}
|
|
537
|
-
const reqBody = Buffer.concat(chunks);
|
|
538
535
|
fileEncSha256B64 = (0, exports.encodeBase64EncodedStringForUpload)(fileEncSha256B64);
|
|
539
|
-
for (const { hostname
|
|
536
|
+
for (const { hostname } of hosts) {
|
|
540
537
|
logger.debug(`uploading to "${hostname}"`);
|
|
541
538
|
const auth = encodeURIComponent(uploadInfo.auth); // the auth token
|
|
542
539
|
const url = `https://${hostname}${Defaults_1.MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
|
|
543
540
|
let result;
|
|
544
541
|
try {
|
|
545
|
-
|
|
546
|
-
throw new boom_1.Boom(`Body too large for "${hostname}"`, { statusCode: 413 });
|
|
547
|
-
}
|
|
548
|
-
const body = await axios.post(url, reqBody, {
|
|
542
|
+
const body = await axios_1.default.post(url, stream, {
|
|
549
543
|
...options,
|
|
550
544
|
headers: {
|
|
551
545
|
...options.headers || {},
|
|
@@ -572,7 +566,7 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
572
566
|
}
|
|
573
567
|
}
|
|
574
568
|
catch (error) {
|
|
575
|
-
if (
|
|
569
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
576
570
|
result = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data;
|
|
577
571
|
}
|
|
578
572
|
const isLast = hostname === ((_b = hosts[uploadInfo.hosts.length - 1]) === null || _b === void 0 ? void 0 : _b.hostname);
|
package/lib/Utils/messages.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
import { Logger } from 'pino';
|
|
4
|
+
import { type Transform } from 'stream';
|
|
4
5
|
import { proto } from '../../WAProto';
|
|
5
6
|
import { AnyMediaMessageContent, AnyMessageContent, MediaGenerationOptions, MessageContentGenerationOptions, MessageGenerationOptions, MessageGenerationOptionsFromContent, MessageUserReceipt, WAMessage, WAMessageContent, WAProto } from '../Types';
|
|
6
7
|
import { MediaDownloadOptions } from './messages-media';
|
|
@@ -70,7 +71,7 @@ type DownloadMediaMessageContext = {
|
|
|
70
71
|
/**
|
|
71
72
|
* Downloads the given message. Throws an error if it's not a media message
|
|
72
73
|
*/
|
|
73
|
-
export declare const downloadMediaMessage: (message: WAMessage, type:
|
|
74
|
+
export declare const downloadMediaMessage: <Type extends "stream" | "buffer">(message: WAMessage, type: Type, options: MediaDownloadOptions, ctx?: DownloadMediaMessageContext) => Promise<Type extends "buffer" ? Buffer : Transform>;
|
|
74
75
|
/** Checks whether the given message is a media message; if it is returns the inner content */
|
|
75
76
|
export declare const assertMediaContent: (content: proto.IMessage | null | undefined) => proto.Message.IVideoMessage | proto.Message.IImageMessage | proto.Message.IAudioMessage | proto.Message.IDocumentMessage | proto.Message.IStickerMessage;
|
|
76
77
|
export {};
|
package/lib/Utils/messages.js
CHANGED
|
@@ -326,6 +326,10 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
326
326
|
break;
|
|
327
327
|
}
|
|
328
328
|
}
|
|
329
|
+
else if ('ptv' in message && message.ptv) {
|
|
330
|
+
const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options);
|
|
331
|
+
m.ptvMessage = videoMessage;
|
|
332
|
+
}
|
|
329
333
|
else if ('product' in message) {
|
|
330
334
|
const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options);
|
|
331
335
|
m.productMessage = Types_1.WAProto.Message.ProductMessage.fromObject({
|
|
@@ -706,12 +710,9 @@ const REUPLOAD_REQUIRED_STATUS = [410, 404];
|
|
|
706
710
|
* Downloads the given message. Throws an error if it's not a media message
|
|
707
711
|
*/
|
|
708
712
|
const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
return result;
|
|
713
|
-
}
|
|
714
|
-
catch (error) {
|
|
713
|
+
const result = await downloadMsg()
|
|
714
|
+
.catch(async (error) => {
|
|
715
|
+
var _a;
|
|
715
716
|
if (ctx) {
|
|
716
717
|
if (axios_1.default.isAxiosError(error)) {
|
|
717
718
|
// check if the message requires a reupload
|
|
@@ -725,7 +726,8 @@ const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
|
725
726
|
}
|
|
726
727
|
}
|
|
727
728
|
throw error;
|
|
728
|
-
}
|
|
729
|
+
});
|
|
730
|
+
return result;
|
|
729
731
|
async function downloadMsg() {
|
|
730
732
|
const mContent = (0, exports.extractMessageContent)(message.message);
|
|
731
733
|
if (!mContent) {
|
|
@@ -3,11 +3,12 @@ import { Logger } from 'pino';
|
|
|
3
3
|
import { proto } from '../../WAProto';
|
|
4
4
|
import { KeyPair } from '../Types';
|
|
5
5
|
import { BinaryNode } from '../WABinary';
|
|
6
|
-
export declare const makeNoiseHandler: ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, mobile, logger, }: {
|
|
6
|
+
export declare const makeNoiseHandler: ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, mobile, logger, routingInfo }: {
|
|
7
7
|
keyPair: KeyPair;
|
|
8
8
|
NOISE_HEADER: Uint8Array;
|
|
9
9
|
mobile: boolean;
|
|
10
10
|
logger: Logger;
|
|
11
|
+
routingInfo?: Buffer | undefined;
|
|
11
12
|
}) => {
|
|
12
13
|
encrypt: (plaintext: Uint8Array) => Buffer;
|
|
13
14
|
decrypt: (ciphertext: Uint8Array) => Buffer;
|
|
@@ -16,5 +17,5 @@ export declare const makeNoiseHandler: ({ keyPair: { private: privateKey, public
|
|
|
16
17
|
finishInit: () => void;
|
|
17
18
|
processHandshake: ({ serverHello }: proto.HandshakeMessage, noiseKey: KeyPair) => Buffer;
|
|
18
19
|
encodeFrame: (data: Buffer | Uint8Array) => Buffer;
|
|
19
|
-
decodeFrame: (newData: Buffer | Uint8Array, onFrame: (buff: Uint8Array | BinaryNode) => void) => void
|
|
20
|
+
decodeFrame: (newData: Buffer | Uint8Array, onFrame: (buff: Uint8Array | BinaryNode) => void) => Promise<void>;
|
|
20
21
|
};
|
|
@@ -11,7 +11,7 @@ const generateIV = (counter) => {
|
|
|
11
11
|
new DataView(iv).setUint32(8, counter);
|
|
12
12
|
return new Uint8Array(iv);
|
|
13
13
|
};
|
|
14
|
-
const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, mobile, logger, }) => {
|
|
14
|
+
const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, mobile, logger, routingInfo }) => {
|
|
15
15
|
logger = logger.child({ class: 'ns' });
|
|
16
16
|
const authenticate = (data) => {
|
|
17
17
|
if (!isFinished) {
|
|
@@ -101,10 +101,23 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
101
101
|
if (isFinished) {
|
|
102
102
|
data = encrypt(data);
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
let header;
|
|
105
|
+
if (routingInfo) {
|
|
106
|
+
header = Buffer.alloc(7);
|
|
107
|
+
header.write('ED', 0, 'utf8');
|
|
108
|
+
header.writeUint8(0, 2);
|
|
109
|
+
header.writeUint8(1, 3);
|
|
110
|
+
header.writeUint8(routingInfo.byteLength >> 16, 4);
|
|
111
|
+
header.writeUint16BE(routingInfo.byteLength & 65535, 5);
|
|
112
|
+
header = Buffer.concat([header, routingInfo, NOISE_HEADER]);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
header = Buffer.from(NOISE_HEADER);
|
|
116
|
+
}
|
|
117
|
+
const introSize = sentIntro ? 0 : header.length;
|
|
105
118
|
const frame = Buffer.alloc(introSize + 3 + data.byteLength);
|
|
106
119
|
if (!sentIntro) {
|
|
107
|
-
frame.set(
|
|
120
|
+
frame.set(header);
|
|
108
121
|
sentIntro = true;
|
|
109
122
|
}
|
|
110
123
|
frame.writeUInt8(data.byteLength >> 16, introSize);
|
|
@@ -112,7 +125,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
112
125
|
frame.set(data, introSize + 3);
|
|
113
126
|
return frame;
|
|
114
127
|
},
|
|
115
|
-
decodeFrame: (newData, onFrame) => {
|
|
128
|
+
decodeFrame: async (newData, onFrame) => {
|
|
116
129
|
var _a;
|
|
117
130
|
// the binary protocol uses its own framing mechanism
|
|
118
131
|
// on top of the WS frames
|
|
@@ -130,7 +143,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
130
143
|
inBytes = inBytes.slice(size + 3);
|
|
131
144
|
if (isFinished) {
|
|
132
145
|
const result = decrypt(frame);
|
|
133
|
-
frame = (0, WABinary_1.decodeBinaryNode)(result);
|
|
146
|
+
frame = await (0, WABinary_1.decodeBinaryNode)(result);
|
|
134
147
|
}
|
|
135
148
|
logger.trace({ msg: (_a = frame === null || frame === void 0 ? void 0 : frame.attrs) === null || _a === void 0 ? void 0 : _a.id }, 'recv frame');
|
|
136
149
|
onFrame(frame);
|
|
@@ -103,7 +103,7 @@ function decryptPollVote({ encPayload, encIv }, { pollCreatorJid, pollMsgId, pol
|
|
|
103
103
|
}
|
|
104
104
|
exports.decryptPollVote = decryptPollVote;
|
|
105
105
|
const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, keyStore, logger, options, getMessage }) => {
|
|
106
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
106
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
107
107
|
const meId = creds.me.id;
|
|
108
108
|
const { accountSettings } = creds;
|
|
109
109
|
const chat = { id: (0, WABinary_1.jidNormalizedUser)((0, exports.getChatId)(message.key)) };
|
|
@@ -220,8 +220,15 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
220
220
|
var _a;
|
|
221
221
|
ev.emit('groups.update', [{ id: jid, ...update, author: (_a = message.participant) !== null && _a !== void 0 ? _a : undefined }]);
|
|
222
222
|
};
|
|
223
|
+
const emitGroupRequestJoin = (participant, action, method) => {
|
|
224
|
+
ev.emit('group.join-request', { id: jid, author: message.participant, participant, action, method: method });
|
|
225
|
+
};
|
|
223
226
|
const participantsIncludesMe = () => participants.find(jid => (0, WABinary_1.areJidsSameUser)(meId, jid));
|
|
224
227
|
switch (message.messageStubType) {
|
|
228
|
+
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER:
|
|
229
|
+
participants = message.messageStubParameters || [];
|
|
230
|
+
emitParticipantsUpdate('modify');
|
|
231
|
+
break;
|
|
225
232
|
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_LEAVE:
|
|
226
233
|
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_REMOVE:
|
|
227
234
|
participants = message.messageStubParameters || [];
|
|
@@ -273,6 +280,12 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
273
280
|
const approvalMode = (_j = message.messageStubParameters) === null || _j === void 0 ? void 0 : _j[0];
|
|
274
281
|
emitGroupUpdate({ joinApprovalMode: approvalMode === 'on' });
|
|
275
282
|
break;
|
|
283
|
+
case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD:
|
|
284
|
+
const participant = (_k = message.messageStubParameters) === null || _k === void 0 ? void 0 : _k[0];
|
|
285
|
+
const action = (_l = message.messageStubParameters) === null || _l === void 0 ? void 0 : _l[1];
|
|
286
|
+
const method = (_m = message.messageStubParameters) === null || _m === void 0 ? void 0 : _m[2];
|
|
287
|
+
emitGroupRequestJoin(participant, action, method);
|
|
288
|
+
break;
|
|
276
289
|
}
|
|
277
290
|
}
|
|
278
291
|
else if (content === null || content === void 0 ? void 0 : content.pollUpdateMessage) {
|
|
@@ -283,7 +296,7 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
283
296
|
const meIdNormalised = (0, WABinary_1.jidNormalizedUser)(meId);
|
|
284
297
|
const pollCreatorJid = (0, generics_1.getKeyAuthor)(creationMsgKey, meIdNormalised);
|
|
285
298
|
const voterJid = (0, generics_1.getKeyAuthor)(message.key, meIdNormalised);
|
|
286
|
-
const pollEncKey = (
|
|
299
|
+
const pollEncKey = (_o = pollMsg.messageContextInfo) === null || _o === void 0 ? void 0 : _o.messageSecret;
|
|
287
300
|
try {
|
|
288
301
|
const voteMsg = decryptPollVote(content.pollUpdateMessage.vote, {
|
|
289
302
|
pollEncKey,
|
package/lib/Utils/signal.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getNextPreKeysNode = exports.getNextPreKeys = exports.extractDeviceJids = exports.parseAndInjectE2ESessions = exports.xmppPreKey = exports.xmppSignedPreKey = exports.generateOrGetPreKeys = exports.getPreKeys = exports.createSignalIdentity = void 0;
|
|
4
|
+
const lodash_1 = require("lodash");
|
|
4
5
|
const Defaults_1 = require("../Defaults");
|
|
5
6
|
const WABinary_1 = require("../WABinary");
|
|
6
7
|
const crypto_1 = require("./crypto");
|
|
@@ -66,22 +67,31 @@ const parseAndInjectE2ESessions = async (node, repository) => {
|
|
|
66
67
|
for (const node of nodes) {
|
|
67
68
|
(0, WABinary_1.assertNodeErrorFree)(node);
|
|
68
69
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
70
|
+
// Most of the work in repository.injectE2ESession is CPU intensive, not IO
|
|
71
|
+
// So Promise.all doesn't really help here,
|
|
72
|
+
// but blocks even loop if we're using it inside keys.transaction, and it makes it "sync" actually
|
|
73
|
+
// This way we chunk it in smaller parts and between those parts we can yield to the event loop
|
|
74
|
+
// It's rare case when you need to E2E sessions for so many users, but it's possible
|
|
75
|
+
const chunkSize = 100;
|
|
76
|
+
const chunks = (0, lodash_1.chunk)(nodes, chunkSize);
|
|
77
|
+
for (const nodesChunk of chunks) {
|
|
78
|
+
await Promise.all(nodesChunk.map(async (node) => {
|
|
79
|
+
const signedKey = (0, WABinary_1.getBinaryNodeChild)(node, 'skey');
|
|
80
|
+
const key = (0, WABinary_1.getBinaryNodeChild)(node, 'key');
|
|
81
|
+
const identity = (0, WABinary_1.getBinaryNodeChildBuffer)(node, 'identity');
|
|
82
|
+
const jid = node.attrs.jid;
|
|
83
|
+
const registrationId = (0, WABinary_1.getBinaryNodeChildUInt)(node, 'registration', 4);
|
|
84
|
+
await repository.injectE2ESession({
|
|
85
|
+
jid,
|
|
86
|
+
session: {
|
|
87
|
+
registrationId: registrationId,
|
|
88
|
+
identityKey: (0, crypto_1.generateSignalPubKey)(identity),
|
|
89
|
+
signedPreKey: extractKey(signedKey),
|
|
90
|
+
preKey: extractKey(key)
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
85
95
|
};
|
|
86
96
|
exports.parseAndInjectE2ESessions = parseAndInjectE2ESessions;
|
|
87
97
|
const extractDeviceJids = (result, myJid, excludeZeroDevices) => {
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.useMultiFileAuthState = void 0;
|
|
7
|
+
const async_lock_1 = __importDefault(require("async-lock"));
|
|
4
8
|
const promises_1 = require("fs/promises");
|
|
5
9
|
const path_1 = require("path");
|
|
6
10
|
const WAProto_1 = require("../../WAProto");
|
|
7
11
|
const auth_utils_1 = require("./auth-utils");
|
|
8
12
|
const generics_1 = require("./generics");
|
|
13
|
+
// We need to lock files due to the fact that we are using async functions to read and write files
|
|
14
|
+
// https://github.com/WhiskeySockets/Baileys/issues/794
|
|
15
|
+
// https://github.com/nodejs/node/issues/26338
|
|
16
|
+
// Default pending is 1000, set it to infinity
|
|
17
|
+
// https://github.com/rogierschouten/async-lock/issues/63
|
|
18
|
+
const fileLock = new async_lock_1.default({ maxPending: Infinity });
|
|
9
19
|
/**
|
|
10
20
|
* stores the full authentication state in a single folder.
|
|
11
21
|
* Far more efficient than singlefileauthstate
|
|
@@ -15,11 +25,13 @@ const generics_1 = require("./generics");
|
|
|
15
25
|
* */
|
|
16
26
|
const useMultiFileAuthState = async (folder) => {
|
|
17
27
|
const writeData = (data, file) => {
|
|
18
|
-
|
|
28
|
+
const filePath = (0, path_1.join)(folder, fixFileName(file));
|
|
29
|
+
return fileLock.acquire(filePath, () => (0, promises_1.writeFile)((0, path_1.join)(filePath), JSON.stringify(data, generics_1.BufferJSON.replacer)));
|
|
19
30
|
};
|
|
20
31
|
const readData = async (file) => {
|
|
21
32
|
try {
|
|
22
|
-
const
|
|
33
|
+
const filePath = (0, path_1.join)(folder, fixFileName(file));
|
|
34
|
+
const data = await fileLock.acquire(filePath, () => (0, promises_1.readFile)(filePath, { encoding: 'utf-8' }));
|
|
23
35
|
return JSON.parse(data, generics_1.BufferJSON.reviver);
|
|
24
36
|
}
|
|
25
37
|
catch (error) {
|
|
@@ -28,7 +40,8 @@ const useMultiFileAuthState = async (folder) => {
|
|
|
28
40
|
};
|
|
29
41
|
const removeData = async (file) => {
|
|
30
42
|
try {
|
|
31
|
-
|
|
43
|
+
const filePath = (0, path_1.join)(folder, fixFileName(file));
|
|
44
|
+
await fileLock.acquire(filePath, () => (0, promises_1.unlink)(filePath));
|
|
32
45
|
}
|
|
33
46
|
catch (_a) {
|
|
34
47
|
}
|
package/lib/WABinary/decode.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { BinaryNode, BinaryNodeCodingOptions } from './types';
|
|
3
|
-
export declare const decompressingIfRequired: (buffer: Buffer) => Buffer
|
|
3
|
+
export declare const decompressingIfRequired: (buffer: Buffer) => Promise<Buffer>;
|
|
4
4
|
export declare const decodeDecompressedBinaryNode: (buffer: Buffer, opts: Pick<BinaryNodeCodingOptions, 'DOUBLE_BYTE_TOKENS' | 'SINGLE_BYTE_TOKENS' | 'TAGS'>, indexRef?: {
|
|
5
5
|
index: number;
|
|
6
6
|
}) => BinaryNode;
|
|
7
|
-
export declare const decodeBinaryNode: (buff: Buffer) => BinaryNode
|
|
7
|
+
export declare const decodeBinaryNode: (buff: Buffer) => Promise<BinaryNode>;
|
package/lib/WABinary/decode.js
CHANGED
|
@@ -24,12 +24,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.decodeBinaryNode = exports.decodeDecompressedBinaryNode = exports.decompressingIfRequired = void 0;
|
|
27
|
+
const util_1 = require("util");
|
|
27
28
|
const zlib_1 = require("zlib");
|
|
28
29
|
const constants = __importStar(require("./constants"));
|
|
29
30
|
const jid_utils_1 = require("./jid-utils");
|
|
30
|
-
const
|
|
31
|
+
const inflatePromise = (0, util_1.promisify)(zlib_1.inflate);
|
|
32
|
+
const decompressingIfRequired = async (buffer) => {
|
|
31
33
|
if (2 & buffer.readUInt8()) {
|
|
32
|
-
buffer =
|
|
34
|
+
buffer = await inflatePromise(buffer.slice(1));
|
|
33
35
|
}
|
|
34
36
|
else { // nodes with no compression have a 0x00 prefix, we remove that
|
|
35
37
|
buffer = buffer.slice(1);
|
|
@@ -245,8 +247,8 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
245
247
|
};
|
|
246
248
|
};
|
|
247
249
|
exports.decodeDecompressedBinaryNode = decodeDecompressedBinaryNode;
|
|
248
|
-
const decodeBinaryNode = (buff) => {
|
|
249
|
-
const decompBuff = (0, exports.decompressingIfRequired)(buff);
|
|
250
|
+
const decodeBinaryNode = async (buff) => {
|
|
251
|
+
const decompBuff = await (0, exports.decompressingIfRequired)(buff);
|
|
250
252
|
return (0, exports.decodeDecompressedBinaryNode)(decompBuff, constants);
|
|
251
253
|
};
|
|
252
254
|
exports.decodeBinaryNode = decodeBinaryNode;
|
package/lib/WABinary/encode.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { BinaryNode, BinaryNodeCodingOptions } from './types';
|
|
3
|
-
export declare const encodeBinaryNode: (
|
|
3
|
+
export declare const encodeBinaryNode: (node: BinaryNode, opts?: Pick<BinaryNodeCodingOptions, 'TAGS' | 'TOKEN_MAP'>, buffer?: number[]) => Buffer;
|
package/lib/WABinary/encode.js
CHANGED
|
@@ -26,7 +26,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.encodeBinaryNode = void 0;
|
|
27
27
|
const constants = __importStar(require("./constants"));
|
|
28
28
|
const jid_utils_1 = require("./jid-utils");
|
|
29
|
-
const encodeBinaryNode = (
|
|
29
|
+
const encodeBinaryNode = (node, opts = constants, buffer = [0]) => {
|
|
30
|
+
const encoded = encodeBinaryNodeInner(node, opts, buffer);
|
|
31
|
+
return Buffer.from(encoded);
|
|
32
|
+
};
|
|
33
|
+
exports.encodeBinaryNode = encodeBinaryNode;
|
|
34
|
+
const encodeBinaryNodeInner = ({ tag, attrs, content }, opts, buffer) => {
|
|
30
35
|
const { TAGS, TOKEN_MAP } = opts;
|
|
31
36
|
const pushByte = (value) => buffer.push(value & 0xff);
|
|
32
37
|
const pushInt = (value, n, littleEndian = false) => {
|
|
@@ -214,7 +219,7 @@ const encodeBinaryNode = ({ tag, attrs, content }, opts = constants, buffer = [0
|
|
|
214
219
|
else if (Array.isArray(content)) {
|
|
215
220
|
writeListStart(content.length);
|
|
216
221
|
for (const item of content) {
|
|
217
|
-
(
|
|
222
|
+
encodeBinaryNodeInner(item, opts, buffer);
|
|
218
223
|
}
|
|
219
224
|
}
|
|
220
225
|
else if (typeof content === 'undefined') {
|
|
@@ -223,6 +228,5 @@ const encodeBinaryNode = ({ tag, attrs, content }, opts = constants, buffer = [0
|
|
|
223
228
|
else {
|
|
224
229
|
throw new Error(`invalid children for header "${tag}": ${content} (${typeof content})`);
|
|
225
230
|
}
|
|
226
|
-
return
|
|
231
|
+
return buffer;
|
|
227
232
|
};
|
|
228
|
-
exports.encodeBinaryNode = encodeBinaryNode;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@d0v3riz/baileys",
|
|
3
|
-
"version": "6.7.
|
|
3
|
+
"version": "6.7.5",
|
|
4
4
|
"description": "WhatsApp API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"whatsapp",
|
|
@@ -46,17 +46,19 @@
|
|
|
46
46
|
"@adiwajshing/keyed-db": "^0.2.4",
|
|
47
47
|
"@d0v3riz/ws": "^8.13.0",
|
|
48
48
|
"@hapi/boom": "^9.1.3",
|
|
49
|
+
"async-lock": "^1.4.1",
|
|
49
50
|
"audio-decode": "^2.1.3",
|
|
50
|
-
"axios": "^1.
|
|
51
|
+
"axios": "^1.6.0",
|
|
51
52
|
"cache-manager": "4.0.1",
|
|
52
53
|
"futoin-hkdf": "^1.5.1",
|
|
53
54
|
"libphonenumber-js": "^1.10.20",
|
|
54
55
|
"libsignal": "https://github.com/d0v3riz/libsignal-node.git",
|
|
56
|
+
"lodash": "^4.17.21",
|
|
55
57
|
"music-metadata": "^7.12.3",
|
|
56
58
|
"node-cache": "^5.1.2",
|
|
57
59
|
"pino": "^7.0.0",
|
|
58
60
|
"protobufjs": "^7.2.4",
|
|
59
|
-
"uuid": "^
|
|
61
|
+
"uuid": "^10.0.0",
|
|
60
62
|
"ws": "^8.13.0"
|
|
61
63
|
},
|
|
62
64
|
"devDependencies": {
|
|
@@ -70,22 +72,22 @@
|
|
|
70
72
|
"eslint": "^8.0.0",
|
|
71
73
|
"jest": "^27.0.6",
|
|
72
74
|
"jimp": "^0.16.1",
|
|
75
|
+
"json": "^11.0.0",
|
|
73
76
|
"link-preview-js": "^3.0.0",
|
|
74
77
|
"open": "^8.4.2",
|
|
75
78
|
"qrcode-terminal": "^0.12.0",
|
|
76
79
|
"release-it": "^15.10.3",
|
|
77
|
-
"sharp": "^0.
|
|
80
|
+
"sharp": "^0.32.6",
|
|
78
81
|
"ts-jest": "^27.0.3",
|
|
79
82
|
"ts-node": "^10.8.1",
|
|
80
83
|
"typedoc": "^0.24.7",
|
|
81
|
-
"typescript": "^4.6.4"
|
|
82
|
-
"json": "^11.0.0"
|
|
84
|
+
"typescript": "^4.6.4"
|
|
83
85
|
},
|
|
84
86
|
"peerDependencies": {
|
|
85
87
|
"jimp": "^0.16.1",
|
|
86
88
|
"link-preview-js": "^3.0.0",
|
|
87
89
|
"qrcode-terminal": "^0.12.0",
|
|
88
|
-
"sharp": "^0.32.
|
|
90
|
+
"sharp": "^0.32.6"
|
|
89
91
|
},
|
|
90
92
|
"peerDependenciesMeta": {
|
|
91
93
|
"jimp": {
|