@queenanya/baileys 6.9.2 → 7.0.1

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 CHANGED
@@ -422,7 +422,8 @@ await sock.sendMessage(
422
422
  {
423
423
  video: "./Media/ma_gif.mp4",
424
424
  caption: "hello!",
425
- gifPlayback: true
425
+ gifPlayback: true,
426
+ ptv: false // if set to true, will send as a `video note`
426
427
  }
427
428
  )
428
429
 
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": [2, 2403, 2]
2
+ "version": [2, 2413, 1]
3
3
  }
@@ -48,7 +48,7 @@ exports.PROCESSABLE_HISTORY_TYPES = [
48
48
  ];
49
49
  exports.DEFAULT_CONNECTION_CONFIG = {
50
50
  version: baileys_version_json_1.version,
51
- browser: Utils_1.Browsers.ubuntu("Firefox"),
51
+ browser: Utils_1.Browsers.ubuntu('Firefox'),
52
52
  waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat',
53
53
  connectTimeoutMs: 20000,
54
54
  keepAliveIntervalMs: 30000,
@@ -2,6 +2,7 @@
2
2
  import { GetCatalogOptions, ProductCreate, ProductUpdate, SocketConfig } from '../Types';
3
3
  import { BinaryNode } from '../WABinary';
4
4
  export declare const makeBusinessSocket: (config: SocketConfig) => {
5
+ logger: import("pino").Logger<import("pino").LoggerOptions>;
5
6
  getOrderDetails: (orderId: string, tokenBase64: string) => Promise<import("../Types").OrderDetails>;
6
7
  getCatalog: ({ jid, limit, cursor }: GetCatalogOptions) => Promise<{
7
8
  products: import("../Types").Product[];
@@ -248,6 +248,7 @@ const makeBusinessSocket = (config) => {
248
248
  };
249
249
  return {
250
250
  ...sock,
251
+ logger: config.logger,
251
252
  getOrderDetails,
252
253
  getCatalog,
253
254
  getCollections,
@@ -511,7 +511,7 @@ const makeChatsSocket = (config) => {
511
511
  let presence;
512
512
  const jid = attrs.from;
513
513
  const participant = attrs.participant || attrs.from;
514
- if (shouldIgnoreJid(jid)) {
514
+ if (shouldIgnoreJid(jid) && jid !== '@s.whatsapp.net') {
515
515
  return;
516
516
  }
517
517
  if (tag === 'presence') {
@@ -610,7 +610,7 @@ const makeChatsSocket = (config) => {
610
610
  content: [
611
611
  { tag: 'props', attrs: {
612
612
  protocol: '2',
613
- hash: ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.lastPropHash) || ""
613
+ hash: ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.lastPropHash) || ''
614
614
  } }
615
615
  ]
616
616
  });
@@ -193,6 +193,7 @@ const makeGroupsSocket = (config) => {
193
193
  * @param inviteMessage the message to accept
194
194
  */
195
195
  groupAcceptInviteV4: ev.createBufferedFunction(async (key, inviteMessage) => {
196
+ var _a;
196
197
  key = typeof key === 'string' ? { remoteJid: key } : key;
197
198
  const results = await groupQuery(inviteMessage.groupJid, 'set', [{
198
199
  tag: 'accept',
@@ -224,7 +225,7 @@ const makeGroupsSocket = (config) => {
224
225
  await upsertMessage({
225
226
  key: {
226
227
  remoteJid: inviteMessage.groupJid,
227
- id: (0, Utils_1.generateMessageID)(),
228
+ id: (0, Utils_1.generateMessageIDV2)((_a = sock.user) === null || _a === void 0 ? void 0 : _a.id),
228
229
  fromMe: false,
229
230
  participant: key.remoteJid,
230
231
  },
@@ -3,6 +3,7 @@ import { UserFacingSocketConfig } from '../Types';
3
3
  declare const makeWASocket: (config: UserFacingSocketConfig) => {
4
4
  register: (code: string) => Promise<import("./registration").ExistsResponse>;
5
5
  requestRegistrationCode: (registrationOptions?: import("./registration").RegistrationOptions | undefined) => Promise<import("./registration").ExistsResponse>;
6
+ logger: import("pino").Logger<import("pino").LoggerOptions>;
6
7
  getOrderDetails: (orderId: string, tokenBase64: string) => Promise<import("../Types").OrderDetails>;
7
8
  getCatalog: ({ jid, limit, cursor }: import("../Types").GetCatalogOptions) => Promise<{
8
9
  products: import("../Types").Product[];
@@ -163,6 +163,8 @@ const makeMessagesRecvSocket = (config) => {
163
163
  }
164
164
  };
165
165
  const handleGroupNotification = (participant, child, msg) => {
166
+ var _a, _b;
167
+ const participantJid = ((_b = (_a = (0, WABinary_1.getBinaryNodeChild)(child, 'participant')) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.jid) || participant;
166
168
  switch (child === null || child === void 0 ? void 0 : child.tag) {
167
169
  case 'create':
168
170
  const metadata = (0, groups_1.extractGroupMetadata)(child);
@@ -237,6 +239,15 @@ const makeMessagesRecvSocket = (config) => {
237
239
  msg.messageStubParameters = [approvalMode.attrs.state];
238
240
  }
239
241
  break;
242
+ case 'created_membership_requests':
243
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
244
+ msg.messageStubParameters = [participantJid, 'created', child.attrs.request_method];
245
+ break;
246
+ case 'revoked_membership_requests':
247
+ const isDenied = (0, WABinary_1.areJidsSameUser)(participantJid, participant);
248
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
249
+ msg.messageStubParameters = [participantJid, isDenied ? 'revoked' : 'rejected'];
250
+ break;
240
251
  }
241
252
  };
242
253
  const processNotification = async (node) => {
@@ -461,7 +472,7 @@ const makeMessagesRecvSocket = (config) => {
461
472
  fromMe,
462
473
  participant: attrs.participant
463
474
  };
464
- if (shouldIgnoreJid(remoteJid)) {
475
+ if (shouldIgnoreJid(remoteJid) && remoteJid !== '@s.whatsapp.net') {
465
476
  logger.debug({ remoteJid }, 'ignoring receipt from jid');
466
477
  await sendMessageAck(node);
467
478
  return;
@@ -480,7 +491,7 @@ const makeMessagesRecvSocket = (config) => {
480
491
  // or another device of ours has read some messages
481
492
  status > WAProto_1.proto.WebMessageInfo.Status.DELIVERY_ACK ||
482
493
  !isNodeFromMe)) {
483
- if ((0, WABinary_1.isJidGroup)(remoteJid)) {
494
+ if ((0, WABinary_1.isJidGroup)(remoteJid) || (0, WABinary_1.isJidStatusBroadcast)(remoteJid)) {
484
495
  if (attrs.participant) {
485
496
  const updateKey = status === WAProto_1.proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp';
486
497
  ev.emit('message-receipt.update', ids.map(id => ({
@@ -527,7 +538,7 @@ const makeMessagesRecvSocket = (config) => {
527
538
  };
528
539
  const handleNotification = async (node) => {
529
540
  const remoteJid = node.attrs.from;
530
- if (shouldIgnoreJid(remoteJid)) {
541
+ if (shouldIgnoreJid(remoteJid) && remoteJid !== '@s.whatsapp.net') {
531
542
  logger.debug({ remoteJid, id: node.attrs.id }, 'ignored notification');
532
543
  await sendMessageAck(node);
533
544
  return;
@@ -556,17 +567,17 @@ const makeMessagesRecvSocket = (config) => {
556
567
  };
557
568
  const handleMessage = async (node) => {
558
569
  var _a, _b;
570
+ if (shouldIgnoreJid(node.attrs.from) && node.attrs.from !== '@s.whatsapp.net') {
571
+ logger.debug({ key: node.attrs.key }, 'ignored message');
572
+ await sendMessageAck(node);
573
+ return;
574
+ }
559
575
  const { fullMessage: msg, category, author, decrypt } = (0, Utils_1.decryptMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger);
560
576
  if (((_b = (_a = msg.message) === null || _a === void 0 ? void 0 : _a.protocolMessage) === null || _b === void 0 ? void 0 : _b.type) === WAProto_1.proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER) {
561
577
  if (node.attrs.sender_pn) {
562
578
  ev.emit('chats.phoneNumberShare', { lid: node.attrs.from, jid: node.attrs.sender_pn });
563
579
  }
564
580
  }
565
- if (shouldIgnoreJid(msg.key.remoteJid)) {
566
- logger.debug({ key: msg.key }, 'ignored message');
567
- await sendMessageAck(node);
568
- return;
569
- }
570
581
  await Promise.all([
571
582
  processingMutex.mutex(async () => {
572
583
  await decrypt();
@@ -27,7 +27,7 @@ export declare const makeMessagesSocket: (config: SocketConfig) => {
27
27
  }[]>;
28
28
  groupRequestParticipantsUpdate: (jid: string, participants: string[], action: "reject" | "approve") => Promise<{
29
29
  status: string;
30
- jid: string; /** Bulk read messages. Keys can be from different chats & participants */
30
+ jid: string;
31
31
  }[]>;
32
32
  groupParticipantsUpdate: (jid: string, participants: string[], action: import("../Types").ParticipantAction) => Promise<{
33
33
  status: string;
@@ -247,6 +247,7 @@ const makeMessagesSocket = (config) => {
247
247
  return { nodes, shouldIncludeDeviceIdentity };
248
248
  };
249
249
  const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache, cachedGroupMetadata, statusJidList }) => {
250
+ var _a;
250
251
  const meId = authState.creds.me.id;
251
252
  let shouldIncludeDeviceIdentity = false;
252
253
  const { user, server } = (0, WABinary_1.jidDecode)(jid);
@@ -254,7 +255,7 @@ const makeMessagesSocket = (config) => {
254
255
  const isGroup = server === 'g.us';
255
256
  const isStatus = jid === statusJid;
256
257
  const isLid = server === 'lid';
257
- msgId = msgId || (0, Utils_1.generateMessageID)();
258
+ msgId = msgId || (0, Utils_1.generateMessageIDV2)((_a = sock.user) === null || _a === void 0 ? void 0 : _a.id);
258
259
  useUserDevicesCache = useUserDevicesCache !== false;
259
260
  const participants = [];
260
261
  const destinationJid = (!isStatus) ? (0, WABinary_1.jidEncode)(user, isLid ? 'lid' : isGroup ? 'g.us' : 's.whatsapp.net') : statusJid;
@@ -601,7 +602,7 @@ const makeMessagesSocket = (config) => {
601
602
  return message;
602
603
  },
603
604
  sendMessage: async (jid, content, options = {}) => {
604
- var _a, _b;
605
+ var _a, _b, _c;
605
606
  const userJid = authState.creds.me.id;
606
607
  if (typeof content === 'object' &&
607
608
  'disappearingMessagesInChat' in content &&
@@ -631,6 +632,7 @@ const makeMessagesSocket = (config) => {
631
632
  upload: waUploadToServer,
632
633
  mediaCache: config.mediaCache,
633
634
  options: config.options,
635
+ messageId: (0, Utils_1.generateMessageIDV2)((_a = sock.user) === null || _a === void 0 ? void 0 : _a.id),
634
636
  ...options,
635
637
  });
636
638
  const isDeleteMsg = 'delete' in content && !!content.delete;
@@ -639,7 +641,7 @@ const makeMessagesSocket = (config) => {
639
641
  // required for delete
640
642
  if (isDeleteMsg) {
641
643
  // if the chat is a group, and I am not the author, then delete the message as an admin
642
- if ((0, WABinary_1.isJidGroup)((_a = content.delete) === null || _a === void 0 ? void 0 : _a.remoteJid) && !((_b = content.delete) === null || _b === void 0 ? void 0 : _b.fromMe)) {
644
+ if ((0, WABinary_1.isJidGroup)((_b = content.delete) === null || _b === void 0 ? void 0 : _b.remoteJid) && !((_c = content.delete) === null || _c === void 0 ? void 0 : _c.fromMe)) {
643
645
  additionalAttributes.edit = '8';
644
646
  }
645
647
  else {
@@ -4,6 +4,7 @@ import { KeyPair, SignedKeyPair, SocketConfig } from '../Types';
4
4
  export declare const makeRegistrationSocket: (config: SocketConfig) => {
5
5
  register: (code: string) => Promise<ExistsResponse>;
6
6
  requestRegistrationCode: (registrationOptions?: RegistrationOptions) => Promise<ExistsResponse>;
7
+ logger: import("pino").Logger<import("pino").LoggerOptions>;
7
8
  getOrderDetails: (orderId: string, tokenBase64: string) => Promise<import("../Types").OrderDetails>;
8
9
  getCatalog: ({ jid, limit, cursor }: import("../Types").GetCatalogOptions) => Promise<{
9
10
  products: import("../Types").Product[];
@@ -39,9 +40,6 @@ export declare const makeRegistrationSocket: (config: SocketConfig) => {
39
40
  groupMetadata: (jid: string) => Promise<import("../Types").GroupMetadata>;
40
41
  groupCreate: (subject: string, participants: string[]) => Promise<import("../Types").GroupMetadata>;
41
42
  groupLeave: (id: string) => Promise<void>;
42
- /** the network code of your mobile network
43
- * @see {@link https://de.wikipedia.org/wiki/Mobile_Network_Code}
44
- */
45
43
  groupUpdateSubject: (jid: string, subject: string) => Promise<void>;
46
44
  groupRequestParticipantsList: (jid: string) => Promise<{
47
45
  [key: string]: string;
@@ -18,12 +18,16 @@ const Client_1 = require("./Client");
18
18
  * - query phone connection
19
19
  */
20
20
  const makeSocket = (config) => {
21
+ var _a, _b;
21
22
  const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository, } = config;
22
23
  let url = typeof waWebSocketUrl === 'string' ? new url_1.URL(waWebSocketUrl) : waWebSocketUrl;
23
24
  config.mobile = config.mobile || url.protocol === 'tcp:';
24
25
  if (config.mobile && url.protocol !== 'tcp:') {
25
26
  url = new url_1.URL(`tcp://${Defaults_1.MOBILE_ENDPOINT}:${Defaults_1.MOBILE_PORT}`);
26
27
  }
28
+ if (!config.mobile && url.protocol === 'wss' && ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.routingInfo)) {
29
+ url.searchParams.append('ED', authState.creds.routingInfo.toString('base64url'));
30
+ }
27
31
  const ws = config.socket ? config.socket : config.mobile ? new Client_1.MobileSocketClient(url, config) : new Client_1.WebSocketClient(url, config);
28
32
  ws.connect();
29
33
  const ev = (0, Utils_1.makeEventBuffer)(logger);
@@ -34,7 +38,8 @@ const makeSocket = (config) => {
34
38
  keyPair: ephemeralKeyPair,
35
39
  NOISE_HEADER: config.mobile ? Defaults_1.MOBILE_NOISE_HEADER : Defaults_1.NOISE_WA_HEADER,
36
40
  mobile: config.mobile,
37
- logger
41
+ logger,
42
+ routingInfo: (_b = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _b === void 0 ? void 0 : _b.routingInfo
38
43
  });
39
44
  const { creds } = authState;
40
45
  // add transaction capability
@@ -398,7 +403,7 @@ const makeSocket = (config) => {
398
403
  {
399
404
  tag: 'companion_platform_id',
400
405
  attrs: {},
401
- content: '49' // Chrome
406
+ content: (0, Utils_1.getPlatformId)(browser[1])
402
407
  },
403
408
  {
404
409
  tag: 'companion_platform_display',
@@ -526,6 +531,14 @@ const makeSocket = (config) => {
526
531
  ws.on('CB:ib,,downgrade_webclient', () => {
527
532
  end(new boom_1.Boom('Multi-device beta not joined', { statusCode: Types_1.DisconnectReason.multideviceMismatch }));
528
533
  });
534
+ ws.on('CB:ib,,edge_routing', (node) => {
535
+ const edgeRoutingNode = (0, WABinary_1.getBinaryNodeChild)(node, 'edge_routing');
536
+ const routingInfo = (0, WABinary_1.getBinaryNodeChild)(edgeRoutingNode, 'routing_info');
537
+ if (routingInfo === null || routingInfo === void 0 ? void 0 : routingInfo.content) {
538
+ authState.creds.routingInfo = Buffer.from(routingInfo === null || routingInfo === void 0 ? void 0 : routingInfo.content);
539
+ ev.emit('creds.update', authState.creds);
540
+ }
541
+ });
529
542
  let didStartBuffer = false;
530
543
  process.nextTick(() => {
531
544
  var _a;
@@ -17,10 +17,10 @@ export declare const waLabelAssociationKey: Comparable<LabelAssociation, string>
17
17
  export type BaileysInMemoryStoreConfig = {
18
18
  chatKey?: Comparable<Chat, string>;
19
19
  labelAssociationKey?: Comparable<LabelAssociation, string>;
20
- logger: Logger;
20
+ logger?: Logger;
21
21
  socket?: WASocket;
22
22
  };
23
- declare const _default: ({ logger, chatKey, labelAssociationKey, socket }: BaileysInMemoryStoreConfig) => {
23
+ declare const _default: (config: BaileysInMemoryStoreConfig) => {
24
24
  chats: KeyedDB<Chat, string>;
25
25
  contacts: {
26
26
  [_: string]: Contact;
@@ -23,48 +23,11 @@ exports.waLabelAssociationKey = {
23
23
  compare: (k1, k2) => k2.localeCompare(k1)
24
24
  };
25
25
  const makeMessagesDictionary = () => (0, make_ordered_dictionary_1.default)(exports.waMessageID);
26
- const predefinedLabels = Object.freeze({
27
- '1': {
28
- id: '1',
29
- name: 'New customer',
30
- predefinedId: '1',
31
- color: 1,
32
- deleted: false
33
- },
34
- '2': {
35
- id: '2',
36
- name: 'New order',
37
- predefinedId: '2',
38
- color: 2,
39
- deleted: false
40
- },
41
- '3': {
42
- id: '3',
43
- name: 'Pending payment',
44
- predefinedId: '3',
45
- color: 3,
46
- deleted: false
47
- },
48
- '4': {
49
- id: '4',
50
- name: 'Paid',
51
- predefinedId: '4',
52
- color: 4,
53
- deleted: false
54
- },
55
- '5': {
56
- id: '5',
57
- name: 'Order completed',
58
- predefinedId: '5',
59
- color: 5,
60
- deleted: false
61
- }
62
- });
63
- exports.default = ({ logger, chatKey, labelAssociationKey, socket }) => {
64
- // const logger = _logger || DEFAULT_CONNECTION_CONFIG.logger.child({ stream: 'in-mem-store' })
65
- chatKey = chatKey || (0, exports.waChatKey)(true);
66
- labelAssociationKey = labelAssociationKey || exports.waLabelAssociationKey;
67
- logger = logger || Defaults_1.DEFAULT_CONNECTION_CONFIG.logger.child({ stream: 'in-mem-store' });
26
+ exports.default = (config) => {
27
+ const socket = config.socket;
28
+ const chatKey = config.chatKey || (0, exports.waChatKey)(true);
29
+ const labelAssociationKey = config.labelAssociationKey || exports.waLabelAssociationKey;
30
+ const logger = config.logger || Defaults_1.DEFAULT_CONNECTION_CONFIG.logger.child({ stream: 'in-mem-store' });
68
31
  const KeyedDB = require('@adiwajshing/keyed-db').default;
69
32
  const chats = new KeyedDB(chatKey, c => c.id);
70
33
  const messages = {};
@@ -72,7 +35,7 @@ exports.default = ({ logger, chatKey, labelAssociationKey, socket }) => {
72
35
  const groupMetadata = {};
73
36
  const presences = {};
74
37
  const state = { connection: 'close' };
75
- const labels = new object_repository_1.ObjectRepository(predefinedLabels);
38
+ const labels = new object_repository_1.ObjectRepository();
76
39
  const labelAssociations = new KeyedDB(labelAssociationKey, labelAssociationKey.key);
77
40
  const assertMessageList = (jid) => {
78
41
  if (!messages[jid]) {
@@ -65,6 +65,7 @@ export type AuthenticationCreds = SignalCreds & {
65
65
  registration: RegistrationOptions;
66
66
  pairingCode: string | undefined;
67
67
  lastPropHash: string | undefined;
68
+ routingInfo: Buffer | undefined;
68
69
  };
69
70
  export type SignalDataTypeMap = {
70
71
  'pre-key': KeyPair;
@@ -4,7 +4,7 @@ import { AuthenticationCreds } from './Auth';
4
4
  import { WACallEvent } from './Call';
5
5
  import { Chat, ChatUpdate, PresenceData } from './Chat';
6
6
  import { Contact } from './Contact';
7
- import { GroupMetadata, ParticipantAction } from './GroupMetadata';
7
+ import { GroupMetadata, ParticipantAction, RequestJoinAction, RequestJoinMethod } from './GroupMetadata';
8
8
  import { Label } from './Label';
9
9
  import { LabelAssociation } from './LabelAssociation';
10
10
  import { MessageUpsertType, MessageUserReceiptUpdate, WAMessage, WAMessageKey, WAMessageUpdate } from './Message';
@@ -78,6 +78,13 @@ export type BaileysEventMap = {
78
78
  participants: string[];
79
79
  action: ParticipantAction;
80
80
  };
81
+ 'group.join-request': {
82
+ id: string;
83
+ author: string;
84
+ participant: string;
85
+ action: RequestJoinAction;
86
+ method: RequestJoinMethod;
87
+ };
81
88
  'blocklist.set': {
82
89
  blocklist: string[];
83
90
  };
@@ -5,6 +5,8 @@ export type GroupParticipant = (Contact & {
5
5
  admin?: 'admin' | 'superadmin' | null;
6
6
  });
7
7
  export type ParticipantAction = 'add' | 'remove' | 'promote' | 'demote';
8
+ export type RequestJoinAction = 'created' | 'revoked' | 'rejected';
9
+ export type RequestJoinMethod = 'invite_link' | 'linked_group_join' | 'non_admin_add' | undefined;
8
10
  export interface GroupMetadata {
9
11
  id: string;
10
12
  owner: string | undefined;
@@ -14,6 +14,13 @@ import { SocketConfig } from './Socket';
14
14
  export type UserFacingSocketConfig = Partial<SocketConfig> & {
15
15
  auth: AuthenticationState;
16
16
  };
17
+ export type BrowsersMap = {
18
+ ubuntu(browser: string): [string, string, string];
19
+ macOS(browser: string): [string, string, string];
20
+ baileys(browser: string): [string, string, string];
21
+ windows(browser: string): [string, string, string];
22
+ appropriate(browser: string): [string, string, string];
23
+ };
17
24
  export declare enum DisconnectReason {
18
25
  connectionClosed = 428,
19
26
  connectionLost = 408,
@@ -200,6 +200,7 @@ const initAuthCreds = () => {
200
200
  registration: {},
201
201
  pairingCode: undefined,
202
202
  lastPropHash: undefined,
203
+ routingInfo: undefined,
203
204
  };
204
205
  };
205
206
  exports.initAuthCreds = initAuthCreds;
@@ -2,16 +2,19 @@
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
- ubuntu: (browser: any) => [string, string, string];
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
+ /**
8
+ const COMPANION_PLATFORM_MAP = {
9
+ 'Chrome': '49',
10
+ 'Edge': '50',
11
+ 'Firefox': '51',
12
+ 'Opera': '53',
13
+ 'Safari': '54'
14
+ }
15
+ */
16
+ export declare const Browsers: BrowsersMap;
17
+ export declare const getPlatformId: (browser: string) => any;
15
18
  export declare const BufferJSON: {
16
19
  replacer: (k: any, value: any) => any;
17
20
  reviver: (_: any, value: any) => any;
@@ -38,6 +41,7 @@ export declare const delayCancellable: (ms: number) => {
38
41
  cancel: () => void;
39
42
  };
40
43
  export declare function promiseTimeout<T>(ms: number | undefined, promise: (resolve: (v: T) => void, reject: (error: any) => void) => void): Promise<T>;
44
+ export declare const generateMessageIDV2: (userId?: string) => string;
41
45
  export declare const generateMessageID: () => string;
42
46
  export declare function bindWaitForEvent<T extends keyof BaileysEventMap>(ev: BaileysEventEmitter, event: T): (check: (u: BaileysEventMap[T]) => boolean | undefined, timeoutMs?: number) => Promise<void>;
43
47
  export declare const bindWaitForConnectionUpdate: (ev: BaileysEventEmitter) => (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number) => Promise<void>;
@@ -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");
@@ -12,20 +12,38 @@ const WAProto_1 = require("../../WAProto");
12
12
  const baileys_version_json_1 = require("../Defaults/baileys-version.json");
13
13
  const Types_1 = require("../Types");
14
14
  const WABinary_1 = require("../WABinary");
15
+ /** Added Extra Browsers or Platforms*/
15
16
  const PLATFORM_MAP = {
16
17
  'aix': 'AIX',
17
18
  'darwin': 'Mac OS',
18
19
  'win32': 'Windows',
19
- 'android': 'Android'
20
+ 'android': 'Android',
21
+ 'freebsd': 'FreeBSD',
22
+ 'openbsd': 'OpenBSD',
23
+ 'sunos': 'Solaris'
20
24
  };
25
+ /**
26
+ const COMPANION_PLATFORM_MAP = {
27
+ 'Chrome': '49',
28
+ 'Edge': '50',
29
+ 'Firefox': '51',
30
+ 'Opera': '53',
31
+ 'Safari': '54'
32
+ }
33
+ */
21
34
  exports.Browsers = {
22
- ubuntu: browser => ['Ubuntu', browser, '20.0.04'],
23
- macOS: browser => ['Mac OS', browser, '10.15.7'],
24
- baileys: browser => ['Ubuntu', browser, '20.0.04'],
25
- windows: browser => ['Windows', browser, '10.0.22621'],
35
+ ubuntu: (browser) => ['Ubuntu', browser, '22.04.4'],
36
+ macOS: (browser) => ['Mac OS', browser, '14.4.1'],
37
+ baileys: (browser) => ['Baileys', browser, '6.5.0'],
38
+ windows: (browser) => ['Windows', browser, '10.0.22631'],
26
39
  /** The appropriate browser based on your OS & release */
27
- appropriate: browser => [PLATFORM_MAP[(0, os_1.platform)()] || 'Ubuntu', browser, (0, os_1.release)()]
40
+ appropriate: (browser) => [PLATFORM_MAP[(0, os_1.platform)()] || 'Ubuntu', browser, (0, os_1.release)()]
41
+ };
42
+ const getPlatformId = (browser) => {
43
+ const platformType = WAProto_1.proto.DeviceProps.PlatformType[browser.toUpperCase()];
44
+ return platformType ? platformType.toString().charCodeAt(0) : '51'; // Firefox
28
45
  };
46
+ exports.getPlatformId = getPlatformId;
29
47
  exports.BufferJSON = {
30
48
  replacer: (k, value) => {
31
49
  if (Buffer.isBuffer(value) || value instanceof Uint8Array || (value === null || value === void 0 ? void 0 : value.type) === 'Buffer') {
@@ -147,8 +165,26 @@ async function promiseTimeout(ms, promise) {
147
165
  return p;
148
166
  }
149
167
  exports.promiseTimeout = promiseTimeout;
168
+ // inspired from whatsmeow code
169
+ // https://github.com/tulir/whatsmeow/blob/64bc969fbe78d31ae0dd443b8d4c80a5d026d07a/send.go#L42
170
+ const generateMessageIDV2 = (userId) => {
171
+ const data = Buffer.alloc(8 + 20 + 16);
172
+ data.writeBigUInt64BE(BigInt(Math.floor(Date.now() / 1000)));
173
+ if (userId) {
174
+ const id = (0, WABinary_1.jidDecode)(userId);
175
+ if (id === null || id === void 0 ? void 0 : id.user) {
176
+ data.write(id.user, 8);
177
+ data.write('@c.us', 8 + id.user.length);
178
+ }
179
+ }
180
+ const random = (0, crypto_1.randomBytes)(16);
181
+ random.copy(data, 28);
182
+ const hash = (0, crypto_1.createHash)('sha256').update(data).digest();
183
+ return '3EB0' + hash.toString('hex').toUpperCase().substring(0, 18);
184
+ };
185
+ exports.generateMessageIDV2 = generateMessageIDV2;
150
186
  // generate a random ID to attach to a message
151
- const generateMessageID = () => 'BAE5' + (0, crypto_1.randomBytes)(6).toString('hex').toUpperCase();
187
+ const generateMessageID = () => '3EB0' + (0, crypto_1.randomBytes)(18).toString('hex').toUpperCase();
152
188
  exports.generateMessageID = generateMessageID;
153
189
  function bindWaitForEvent(ev, event) {
154
190
  return async (check, timeoutMs) => {
@@ -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 { default: axios } = await import('axios');
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,7 +528,6 @@ 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;
@@ -545,7 +547,7 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
545
547
  if (maxContentLengthBytes && reqBody.length > maxContentLengthBytes) {
546
548
  throw new boom_1.Boom(`Body too large for "${hostname}"`, { statusCode: 413 });
547
549
  }
548
- const body = await axios.post(url, reqBody, {
550
+ const body = await axios_1.default.post(url, reqBody, {
549
551
  ...options,
550
552
  headers: {
551
553
  ...options.headers || {},
@@ -572,7 +574,7 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
572
574
  }
573
575
  }
574
576
  catch (error) {
575
- if (axios.isAxiosError(error)) {
577
+ if (axios_1.default.isAxiosError(error)) {
576
578
  result = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data;
577
579
  }
578
580
  const isLast = hostname === ((_b = hosts[uploadInfo.hosts.length - 1]) === null || _b === void 0 ? void 0 : _b.hostname);
@@ -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: 'buffer' | 'stream', options: MediaDownloadOptions, ctx?: DownloadMediaMessageContext) => Promise<Buffer | import("stream").Transform>;
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 {};
@@ -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({
@@ -700,12 +704,9 @@ const REUPLOAD_REQUIRED_STATUS = [410, 404];
700
704
  * Downloads the given message. Throws an error if it's not a media message
701
705
  */
702
706
  const downloadMediaMessage = async (message, type, options, ctx) => {
703
- var _a;
704
- try {
705
- const result = await downloadMsg();
706
- return result;
707
- }
708
- catch (error) {
707
+ const result = await downloadMsg()
708
+ .catch(async (error) => {
709
+ var _a;
709
710
  if (ctx) {
710
711
  if (axios_1.default.isAxiosError(error)) {
711
712
  // check if the message requires a reupload
@@ -719,7 +720,8 @@ const downloadMediaMessage = async (message, type, options, ctx) => {
719
720
  }
720
721
  }
721
722
  throw error;
722
- }
723
+ });
724
+ return result;
723
725
  async function downloadMsg() {
724
726
  const mContent = (0, exports.extractMessageContent)(message.message);
725
727
  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;
@@ -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
- const introSize = sentIntro ? 0 : NOISE_HEADER.length;
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(NOISE_HEADER);
120
+ frame.set(header);
108
121
  sentIntro = true;
109
122
  }
110
123
  frame.writeUInt8(data.byteLength >> 16, introSize);
@@ -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,6 +220,9 @@ 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) {
225
228
  case Types_1.WAMessageStubType.GROUP_PARTICIPANT_LEAVE:
@@ -273,6 +276,12 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
273
276
  const approvalMode = (_j = message.messageStubParameters) === null || _j === void 0 ? void 0 : _j[0];
274
277
  emitGroupUpdate({ joinApprovalMode: approvalMode === 'on' });
275
278
  break;
279
+ case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD:
280
+ const participant = (_k = message.messageStubParameters) === null || _k === void 0 ? void 0 : _k[0];
281
+ const action = (_l = message.messageStubParameters) === null || _l === void 0 ? void 0 : _l[1];
282
+ const method = (_m = message.messageStubParameters) === null || _m === void 0 ? void 0 : _m[2];
283
+ emitGroupRequestJoin(participant, action, method);
284
+ break;
276
285
  }
277
286
  }
278
287
  else if (content === null || content === void 0 ? void 0 : content.pollUpdateMessage) {
@@ -283,7 +292,7 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
283
292
  const meIdNormalised = (0, WABinary_1.jidNormalizedUser)(meId);
284
293
  const pollCreatorJid = (0, generics_1.getKeyAuthor)(creationMsgKey, meIdNormalised);
285
294
  const voterJid = (0, generics_1.getKeyAuthor)(message.key, meIdNormalised);
286
- const pollEncKey = (_k = pollMsg.messageContextInfo) === null || _k === void 0 ? void 0 : _k.messageSecret;
295
+ const pollEncKey = (_o = pollMsg.messageContextInfo) === null || _o === void 0 ? void 0 : _o.messageSecret;
287
296
  try {
288
297
  const voteMsg = decryptPollVote(content.pollUpdateMessage.vote, {
289
298
  pollEncKey,
@@ -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
- await Promise.all(nodes.map(async (node) => {
70
- const signedKey = (0, WABinary_1.getBinaryNodeChild)(node, 'skey');
71
- const key = (0, WABinary_1.getBinaryNodeChild)(node, 'key');
72
- const identity = (0, WABinary_1.getBinaryNodeChildBuffer)(node, 'identity');
73
- const jid = node.attrs.jid;
74
- const registrationId = (0, WABinary_1.getBinaryNodeChildUInt)(node, 'registration', 4);
75
- await repository.injectE2ESession({
76
- jid,
77
- session: {
78
- registrationId: registrationId,
79
- identityKey: (0, crypto_1.generateSignalPubKey)(identity),
80
- signedPreKey: extractKey(signedKey),
81
- preKey: extractKey(key)
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
- return (0, promises_1.writeFile)((0, path_1.join)(folder, fixFileName(file)), JSON.stringify(data, generics_1.BufferJSON.replacer));
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 data = await (0, promises_1.readFile)((0, path_1.join)(folder, fixFileName(file)), { encoding: 'utf-8' });
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
- await (0, promises_1.unlink)((0, path_1.join)(folder, fixFileName(file)));
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@queenanya/baileys",
3
- "version": "6.9.2",
3
+ "version": "7.0.1",
4
4
  "description": "WhatsApp API",
5
5
  "keywords": [
6
6
  "whatsapp",
@@ -44,14 +44,16 @@
44
44
  "dependencies": {
45
45
  "@adiwajshing/keyed-db": "^0.2.4",
46
46
  "@hapi/boom": "^9.1.3",
47
- "@queenanya/pkg": "latest",
47
+ "@queenanya/invite": "latest",
48
+ "async-lock": "^1.4.1",
48
49
  "audio-decode": "^2.1.3",
49
- "axios": "^1.3.3",
50
+ "axios": "^1.6.0",
50
51
  "cache-manager": "4.0.1",
51
52
  "futoin-hkdf": "^1.5.1",
52
53
  "json": "^11.0.0",
53
54
  "libphonenumber-js": "^1.10.20",
54
55
  "libsignal": "npm:@queenanya/libsignal@latest",
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",
@@ -75,7 +77,7 @@
75
77
  "open": "^8.4.2",
76
78
  "qrcode-terminal": "^0.12.0",
77
79
  "release-it": "^15.10.3",
78
- "sharp": "^0.30.5",
80
+ "sharp": "^0.32.6",
79
81
  "ts-jest": "^27.0.3",
80
82
  "ts-node": "^10.8.1",
81
83
  "typedoc": "^0.24.7",
@@ -85,7 +87,7 @@
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.2"
90
+ "sharp": "^0.32.6"
89
91
  },
90
92
  "peerDependenciesMeta": {
91
93
  "jimp": {