@d0v3riz/baileys 6.3.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +6 -5
  2. package/WAProto/WAProto.proto +58 -24
  3. package/WAProto/index.d.ts +649 -410
  4. package/WAProto/index.js +1632 -985
  5. package/WASignalGroup/group_cipher.js +38 -24
  6. package/WASignalGroup/queue_job.js +69 -0
  7. package/WASignalGroup/sender_key_record.js +4 -2
  8. package/lib/Defaults/baileys-version.json +1 -1
  9. package/lib/Defaults/index.js +1 -1
  10. package/lib/Socket/Client/abstract-socket-client.d.ts +1 -0
  11. package/lib/Socket/business.d.ts +5 -3
  12. package/lib/Socket/chats.d.ts +6 -5
  13. package/lib/Socket/groups.d.ts +4 -2
  14. package/lib/Socket/groups.js +1 -1
  15. package/lib/Socket/index.d.ts +9 -7
  16. package/lib/Socket/messages-recv.d.ts +6 -3
  17. package/lib/Socket/messages-recv.js +79 -3
  18. package/lib/Socket/messages-send.d.ts +4 -2
  19. package/lib/Socket/messages-send.js +17 -8
  20. package/lib/Socket/registration.d.ts +6 -4
  21. package/lib/Socket/socket.d.ts +4 -3
  22. package/lib/Socket/socket.js +69 -9
  23. package/lib/Store/make-in-memory-store.d.ts +2 -2
  24. package/lib/Types/Auth.d.ts +19 -17
  25. package/lib/Types/Call.d.ts +2 -2
  26. package/lib/Types/Chat.d.ts +13 -13
  27. package/lib/Types/Events.d.ts +3 -3
  28. package/lib/Types/GroupMetadata.d.ts +4 -2
  29. package/lib/Types/LabelAssociation.d.ts +2 -2
  30. package/lib/Types/Message.d.ts +57 -45
  31. package/lib/Types/Product.d.ts +14 -14
  32. package/lib/Types/Signal.d.ts +10 -10
  33. package/lib/Types/Socket.d.ts +5 -4
  34. package/lib/Types/State.d.ts +2 -2
  35. package/lib/Types/index.d.ts +5 -5
  36. package/lib/Utils/auth-utils.js +3 -1
  37. package/lib/Utils/chat-utils.d.ts +4 -4
  38. package/lib/Utils/crypto.d.ts +3 -0
  39. package/lib/Utils/crypto.js +15 -1
  40. package/lib/Utils/event-buffer.d.ts +2 -2
  41. package/lib/Utils/event-buffer.js +3 -3
  42. package/lib/Utils/generics.d.ts +7 -6
  43. package/lib/Utils/generics.js +25 -27
  44. package/lib/Utils/link-preview.d.ts +1 -1
  45. package/lib/Utils/link-preview.js +1 -24
  46. package/lib/Utils/make-mutex.d.ts +1 -1
  47. package/lib/Utils/messages-media.d.ts +9 -3
  48. package/lib/Utils/messages-media.js +54 -6
  49. package/lib/Utils/messages.d.ts +6 -5
  50. package/lib/Utils/messages.js +37 -7
  51. package/lib/Utils/process-message.d.ts +2 -2
  52. package/lib/Utils/validate-connection.js +1 -2
  53. package/lib/WABinary/jid-utils.d.ts +4 -4
  54. package/lib/WABinary/types.d.ts +4 -4
  55. package/lib/index.d.ts +2 -1
  56. package/lib/index.js +2 -0
  57. package/package.json +6 -5
@@ -1,3 +1,4 @@
1
+ const queue_job = require('./queue_job');
1
2
  const SenderKeyMessage = require('./sender_key_message');
2
3
  const crypto = require('libsignal/src/crypto');
3
4
 
@@ -7,11 +8,22 @@ class GroupCipher {
7
8
  this.senderKeyName = senderKeyName;
8
9
  }
9
10
 
11
+ queueJob(awaitable) {
12
+ return queue_job(this.senderKeyName.toString(), awaitable)
13
+ }
14
+
10
15
  async encrypt(paddedPlaintext) {
11
- try {
16
+ return await this.queueJob(async () => {
12
17
  const record = await this.senderKeyStore.loadSenderKey(this.senderKeyName);
18
+ if (!record) {
19
+ throw new Error("No SenderKeyRecord found for encryption")
20
+ }
13
21
  const senderKeyState = record.getSenderKeyState();
14
- const senderKey = senderKeyState.getSenderChainKey().getSenderMessageKey();
22
+ if (!senderKeyState) {
23
+ throw new Error("No session to encrypt message");
24
+ }
25
+ const iteration = senderKeyState.getSenderChainKey().getIteration()
26
+ const senderKey = this.getSenderKey(senderKeyState, iteration === 0 ? 0 : iteration + 1)
15
27
 
16
28
  const ciphertext = await this.getCipherText(
17
29
  senderKey.getIv(),
@@ -25,35 +37,37 @@ class GroupCipher {
25
37
  ciphertext,
26
38
  senderKeyState.getSigningKeyPrivate()
27
39
  );
28
- senderKeyState.setSenderChainKey(senderKeyState.getSenderChainKey().getNext());
29
40
  await this.senderKeyStore.storeSenderKey(this.senderKeyName, record);
30
- return senderKeyMessage.serialize();
31
- } catch (e) {
32
- //console.log(e.stack);
33
- throw new Error('NoSessionException');
34
- }
41
+ return senderKeyMessage.serialize()
42
+ })
35
43
  }
36
44
 
37
45
  async decrypt(senderKeyMessageBytes) {
38
- const record = await this.senderKeyStore.loadSenderKey(this.senderKeyName);
39
- if (!record) throw new Error(`No sender key for: ${this.senderKeyName}`);
40
-
41
- const senderKeyMessage = new SenderKeyMessage(null, null, null, null, senderKeyMessageBytes);
46
+ return await this.queueJob(async () => {
47
+ const record = await this.senderKeyStore.loadSenderKey(this.senderKeyName);
48
+ if (!record) {
49
+ throw new Error("No SenderKeyRecord found for decryption")
50
+ }
51
+ const senderKeyMessage = new SenderKeyMessage(null, null, null, null, senderKeyMessageBytes);
52
+ const senderKeyState = record.getSenderKeyState(senderKeyMessage.getKeyId());
53
+ if (!senderKeyState) {
54
+ throw new Error("No session found to decrypt message")
55
+ }
42
56
 
43
- const senderKeyState = record.getSenderKeyState(senderKeyMessage.getKeyId());
44
- senderKeyMessage.verifySignature(senderKeyState.getSigningKeyPublic());
45
- const senderKey = this.getSenderKey(senderKeyState, senderKeyMessage.getIteration());
46
- // senderKeyState.senderKeyStateStructure.senderSigningKey.private =
57
+ senderKeyMessage.verifySignature(senderKeyState.getSigningKeyPublic());
58
+ const senderKey = this.getSenderKey(senderKeyState, senderKeyMessage.getIteration());
59
+ // senderKeyState.senderKeyStateStructure.senderSigningKey.private =
47
60
 
48
- const plaintext = await this.getPlainText(
49
- senderKey.getIv(),
50
- senderKey.getCipherKey(),
51
- senderKeyMessage.getCipherText()
52
- );
61
+ const plaintext = await this.getPlainText(
62
+ senderKey.getIv(),
63
+ senderKey.getCipherKey(),
64
+ senderKeyMessage.getCipherText()
65
+ );
53
66
 
54
- await this.senderKeyStore.storeSenderKey(this.senderKeyName, record);
67
+ await this.senderKeyStore.storeSenderKey(this.senderKeyName, record);
55
68
 
56
- return plaintext;
69
+ return plaintext;
70
+ })
57
71
  }
58
72
 
59
73
  getSenderKey(senderKeyState, iteration) {
@@ -67,7 +81,7 @@ class GroupCipher {
67
81
  );
68
82
  }
69
83
 
70
- if (senderChainKey.getIteration() - iteration > 2000) {
84
+ if (iteration - senderChainKey.getIteration() > 2000) {
71
85
  throw new Error('Over 2000 messages into the future!');
72
86
  }
73
87
 
@@ -0,0 +1,69 @@
1
+ // vim: ts=4:sw=4:expandtab
2
+
3
+ /*
4
+ * jobQueue manages multiple queues indexed by device to serialize
5
+ * session io ops on the database.
6
+ */
7
+ 'use strict';
8
+
9
+
10
+ const _queueAsyncBuckets = new Map();
11
+ const _gcLimit = 10000;
12
+
13
+ async function _asyncQueueExecutor(queue, cleanup) {
14
+ let offt = 0;
15
+ while (true) {
16
+ let limit = Math.min(queue.length, _gcLimit); // Break up thundering hurds for GC duty.
17
+ for (let i = offt; i < limit; i++) {
18
+ const job = queue[i];
19
+ try {
20
+ job.resolve(await job.awaitable());
21
+ } catch (e) {
22
+ job.reject(e);
23
+ }
24
+ }
25
+ if (limit < queue.length) {
26
+ /* Perform lazy GC of queue for faster iteration. */
27
+ if (limit >= _gcLimit) {
28
+ queue.splice(0, limit);
29
+ offt = 0;
30
+ } else {
31
+ offt = limit;
32
+ }
33
+ } else {
34
+ break;
35
+ }
36
+ }
37
+ cleanup();
38
+ }
39
+
40
+ module.exports = function (bucket, awaitable) {
41
+ /* Run the async awaitable only when all other async calls registered
42
+ * here have completed (or thrown). The bucket argument is a hashable
43
+ * key representing the task queue to use. */
44
+ if (!awaitable.name) {
45
+ // Make debuging easier by adding a name to this function.
46
+ Object.defineProperty(awaitable, 'name', { writable: true });
47
+ if (typeof bucket === 'string') {
48
+ awaitable.name = bucket;
49
+ } else {
50
+ console.warn("Unhandled bucket type (for naming):", typeof bucket, bucket);
51
+ }
52
+ }
53
+ let inactive;
54
+ if (!_queueAsyncBuckets.has(bucket)) {
55
+ _queueAsyncBuckets.set(bucket, []);
56
+ inactive = true;
57
+ }
58
+ const queue = _queueAsyncBuckets.get(bucket);
59
+ const job = new Promise((resolve, reject) => queue.push({
60
+ awaitable,
61
+ resolve,
62
+ reject
63
+ }));
64
+ if (inactive) {
65
+ /* An executor is not currently active; Start one now. */
66
+ _asyncQueueExecutor(queue, () => _queueAsyncBuckets.delete(bucket));
67
+ }
68
+ return job;
69
+ };
@@ -22,18 +22,20 @@ class SenderKeyRecord {
22
22
  }
23
23
 
24
24
  getSenderKeyState(keyId) {
25
- if (!keyId && this.senderKeyStates.length) return this.senderKeyStates[0];
25
+ if (!keyId && this.senderKeyStates.length) return this.senderKeyStates[this.senderKeyStates.length - 1];
26
26
  for (let i = 0; i < this.senderKeyStates.length; i++) {
27
27
  const state = this.senderKeyStates[i];
28
28
  if (state.getKeyId() === keyId) {
29
29
  return state;
30
30
  }
31
31
  }
32
- throw new Error(`No keys for: ${keyId}`);
33
32
  }
34
33
 
35
34
  addSenderKeyState(id, iteration, chainKey, signatureKey) {
36
35
  this.senderKeyStates.push(new SenderKeyState(id, iteration, chainKey, null, signatureKey));
36
+ if (this.senderKeyStates.length > 5) {
37
+ this.senderKeyStates.shift()
38
+ }
37
39
  }
38
40
 
39
41
  setSenderKeyState(id, iteration, chainKey, keyPair) {
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": [2, 2325, 3]
2
+ "version": [2, 2329, 9]
3
3
  }
@@ -49,7 +49,7 @@ exports.DEFAULT_CONNECTION_CONFIG = {
49
49
  browser: Utils_1.Browsers.baileys('Chrome'),
50
50
  waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat',
51
51
  connectTimeoutMs: 20000,
52
- keepAliveIntervalMs: 15000,
52
+ keepAliveIntervalMs: 30000,
53
53
  logger: logger_1.default.child({ class: 'baileys' }),
54
54
  printQRInTerminal: false,
55
55
  emitOwnEvents: true,
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { EventEmitter } from 'events';
3
4
  import { URL } from 'url';
4
5
  import { SocketConfig } from '../../Types';
@@ -7,7 +7,7 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
7
7
  products: import("../Types").Product[];
8
8
  nextPageCursor: string | undefined;
9
9
  }>;
10
- getCollections: (jid?: string | undefined, limit?: number) => Promise<{
10
+ getCollections: (jid?: string, limit?: number) => Promise<{
11
11
  collections: import("../Types").CatalogCollection[];
12
12
  }>;
13
13
  productCreate: (create: ProductCreate) => Promise<import("../Types").Product>;
@@ -20,7 +20,7 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
20
20
  rejectCall: (callId: string, callFrom: string) => Promise<void>;
21
21
  getPrivacyTokens: (jids: string[]) => Promise<BinaryNode>;
22
22
  assertSessions: (jids: string[], force: boolean) => Promise<boolean>;
23
- relayMessage: (jid: string, message: import("../Types").WAProto.IMessage, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache, cachedGroupMetadata }: import("../Types").MessageRelayOptions) => Promise<string>;
23
+ relayMessage: (jid: string, message: import("../Types").WAProto.IMessage, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache, cachedGroupMetadata, statusJidList }: import("../Types").MessageRelayOptions) => Promise<string>;
24
24
  sendReceipt: (jid: string, participant: string | undefined, messageIds: string[], type: import("../Types").MessageReceiptType) => Promise<void>;
25
25
  sendReceipts: (keys: import("../Types").WAProto.IMessageKey[], type: import("../Types").MessageReceiptType) => Promise<void>;
26
26
  readMessages: (keys: import("../Types").WAProto.IMessageKey[]) => Promise<void>;
@@ -45,6 +45,7 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
45
45
  groupParticipantsUpdate: (jid: string, participants: string[], action: import("../Types").ParticipantAction) => Promise<{
46
46
  status: string;
47
47
  jid: string;
48
+ content: BinaryNode;
48
49
  }[]>;
49
50
  groupUpdateDescription: (jid: string, description?: string | undefined) => Promise<void>;
50
51
  groupInviteCode: (jid: string) => Promise<string | undefined>;
@@ -95,7 +96,7 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
95
96
  addMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
96
97
  removeMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
97
98
  type: "md";
98
- ws: import("./Client").MobileSocketClient | import("./Client").WebSocketClient;
99
+ ws: import("./Client/mobile-socket-client").MobileSocketClient | import("./Client/web-socket-client").WebSocketClient;
99
100
  ev: import("../Types").BaileysEventEmitter & {
100
101
  process(handler: (events: Partial<import("../Types").BaileysEventMap>) => void | Promise<void>): () => void;
101
102
  buffer(): void;
@@ -120,5 +121,6 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
120
121
  onUnexpectedError: (err: Error | import("@hapi/boom").Boom<any>, msg: string) => void;
121
122
  uploadPreKeys: (count?: number) => Promise<void>;
122
123
  uploadPreKeysToServerIfRequired: () => Promise<void>;
124
+ requestPairingCode: (phoneNumber: string) => Promise<string>;
123
125
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
124
126
  };
@@ -12,9 +12,9 @@ export declare const makeChatsSocket: (config: SocketConfig) => {
12
12
  }>;
13
13
  upsertMessage: (msg: proto.IWebMessageInfo, type: MessageUpsertType) => Promise<void>;
14
14
  appPatch: (patchCreate: WAPatchCreate) => Promise<void>;
15
- sendPresenceUpdate: (type: WAPresence, toJid?: string | undefined) => Promise<void>;
16
- presenceSubscribe: (toJid: string, tcToken?: Buffer | undefined) => Promise<void>;
17
- profilePictureUrl: (jid: string, type?: 'preview' | 'image', timeoutMs?: number | undefined) => Promise<string | undefined>;
15
+ sendPresenceUpdate: (type: WAPresence, toJid?: string) => Promise<void>;
16
+ presenceSubscribe: (toJid: string, tcToken?: Buffer) => Promise<void>;
17
+ profilePictureUrl: (jid: string, type?: 'preview' | 'image', timeoutMs?: number) => Promise<string | undefined>;
18
18
  onWhatsApp: (...jids: string[]) => Promise<{
19
19
  exists: boolean;
20
20
  jid: string;
@@ -39,13 +39,13 @@ export declare const makeChatsSocket: (config: SocketConfig) => {
39
39
  getBusinessProfile: (jid: string) => Promise<WABusinessProfile | void>;
40
40
  resyncAppState: (collections: readonly ("critical_block" | "critical_unblock_low" | "regular_high" | "regular_low" | "regular")[], isInitialSync: boolean) => Promise<void>;
41
41
  chatModify: (mod: ChatModification, jid: string) => Promise<void>;
42
- cleanDirtyBits: (type: 'account_sync' | 'groups', fromTimestamp?: string | number | undefined) => Promise<void>;
42
+ cleanDirtyBits: (type: 'account_sync' | 'groups', fromTimestamp?: number | string) => Promise<void>;
43
43
  addChatLabel: (jid: string, labelId: string) => Promise<void>;
44
44
  removeChatLabel: (jid: string, labelId: string) => Promise<void>;
45
45
  addMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
46
46
  removeMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
47
47
  type: "md";
48
- ws: import("./Client").MobileSocketClient | import("./Client").WebSocketClient;
48
+ ws: import("./Client/mobile-socket-client").MobileSocketClient | import("./Client/web-socket-client").WebSocketClient;
49
49
  ev: import("../Types").BaileysEventEmitter & {
50
50
  process(handler: (events: Partial<import("../Types").BaileysEventMap>) => void | Promise<void>): () => void;
51
51
  buffer(): void;
@@ -70,5 +70,6 @@ export declare const makeChatsSocket: (config: SocketConfig) => {
70
70
  onUnexpectedError: (err: Error | Boom<any>, msg: string) => void;
71
71
  uploadPreKeys: (count?: number) => Promise<void>;
72
72
  uploadPreKeysToServerIfRequired: () => Promise<void>;
73
+ requestPairingCode: (phoneNumber: string) => Promise<string>;
73
74
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
74
75
  };
@@ -17,8 +17,9 @@ export declare const makeGroupsSocket: (config: SocketConfig) => {
17
17
  groupParticipantsUpdate: (jid: string, participants: string[], action: ParticipantAction) => Promise<{
18
18
  status: string;
19
19
  jid: string;
20
+ content: BinaryNode;
20
21
  }[]>;
21
- groupUpdateDescription: (jid: string, description?: string | undefined) => Promise<void>;
22
+ groupUpdateDescription: (jid: string, description?: string) => Promise<void>;
22
23
  groupInviteCode: (jid: string) => Promise<string | undefined>;
23
24
  groupRevokeInvite: (jid: string) => Promise<string | undefined>;
24
25
  groupAcceptInvite: (code: string) => Promise<string | undefined>;
@@ -75,7 +76,7 @@ export declare const makeGroupsSocket: (config: SocketConfig) => {
75
76
  addMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
76
77
  removeMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
77
78
  type: "md";
78
- ws: import("./Client").MobileSocketClient | import("./Client").WebSocketClient;
79
+ ws: import("./Client/mobile-socket-client").MobileSocketClient | import("./Client/web-socket-client").WebSocketClient;
79
80
  ev: import("../Types").BaileysEventEmitter & {
80
81
  process(handler: (events: Partial<import("../Types").BaileysEventMap>) => void | Promise<void>): () => void;
81
82
  buffer(): void;
@@ -100,6 +101,7 @@ export declare const makeGroupsSocket: (config: SocketConfig) => {
100
101
  onUnexpectedError: (err: Error | import("@hapi/boom").Boom<any>, msg: string) => void;
101
102
  uploadPreKeys: (count?: number) => Promise<void>;
102
103
  uploadPreKeysToServerIfRequired: () => Promise<void>;
104
+ requestPairingCode: (phoneNumber: string) => Promise<string>;
103
105
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
104
106
  };
105
107
  export declare const extractGroupMetadata: (result: BinaryNode) => GroupMetadata;
@@ -152,7 +152,7 @@ const makeGroupsSocket = (config) => {
152
152
  const node = (0, WABinary_1.getBinaryNodeChild)(result, action);
153
153
  const participantsAffected = (0, WABinary_1.getBinaryNodeChildren)(node, 'participant');
154
154
  return participantsAffected.map(p => {
155
- return { status: p.attrs.error || '200', jid: p.attrs.jid };
155
+ return { status: p.attrs.error || '200', jid: p.attrs.jid, content: p };
156
156
  });
157
157
  },
158
158
  groupUpdateDescription: async (jid, description) => {
@@ -16,12 +16,12 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
16
16
  deleted: number;
17
17
  }>;
18
18
  productUpdate: (productId: string, update: import("../Types").ProductUpdate) => Promise<import("../Types").Product>;
19
- sendMessageAck: ({ tag, attrs }: import("..").BinaryNode) => Promise<void>;
20
- sendRetryRequest: (node: import("..").BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
19
+ sendMessageAck: ({ tag, attrs }: import("../index").BinaryNode) => Promise<void>;
20
+ sendRetryRequest: (node: import("../index").BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
21
21
  rejectCall: (callId: string, callFrom: string) => Promise<void>;
22
- getPrivacyTokens: (jids: string[]) => Promise<import("..").BinaryNode>;
22
+ getPrivacyTokens: (jids: string[]) => Promise<import("../index").BinaryNode>;
23
23
  assertSessions: (jids: string[], force: boolean) => Promise<boolean>;
24
- relayMessage: (jid: string, message: import("../Types").WAProto.IMessage, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache, cachedGroupMetadata }: import("../Types").MessageRelayOptions) => Promise<string>;
24
+ relayMessage: (jid: string, message: import("../Types").WAProto.IMessage, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache, cachedGroupMetadata, statusJidList }: import("../Types").MessageRelayOptions) => Promise<string>;
25
25
  sendReceipt: (jid: string, participant: string | undefined, messageIds: string[], type: import("../Types").MessageReceiptType) => Promise<void>;
26
26
  sendReceipts: (keys: import("../Types").WAProto.IMessageKey[], type: import("../Types").MessageReceiptType) => Promise<void>;
27
27
  readMessages: (keys: import("../Types").WAProto.IMessageKey[]) => Promise<void>;
@@ -46,6 +46,7 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
46
46
  groupParticipantsUpdate: (jid: string, participants: string[], action: import("../Types").ParticipantAction) => Promise<{
47
47
  status: string;
48
48
  jid: string;
49
+ content: import("../index").BinaryNode;
49
50
  }[]>;
50
51
  groupUpdateDescription: (jid: string, description?: string | undefined) => Promise<void>;
51
52
  groupInviteCode: (jid: string) => Promise<string | undefined>;
@@ -96,7 +97,7 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
96
97
  addMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
97
98
  removeMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
98
99
  type: "md";
99
- ws: import("./Client").MobileSocketClient | import("./Client").WebSocketClient;
100
+ ws: import("./Client/mobile-socket-client").MobileSocketClient | import("./Client/web-socket-client").WebSocketClient;
100
101
  ev: import("../Types").BaileysEventEmitter & {
101
102
  process(handler: (events: Partial<import("../Types").BaileysEventMap>) => void | Promise<void>): () => void;
102
103
  buffer(): void;
@@ -111,16 +112,17 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
111
112
  signalRepository: import("../Types").SignalRepository;
112
113
  user: import("../Types").Contact | undefined;
113
114
  generateMessageTag: () => string;
114
- query: (node: import("..").BinaryNode, timeoutMs?: number | undefined) => Promise<import("..").BinaryNode>;
115
+ query: (node: import("../index").BinaryNode, timeoutMs?: number | undefined) => Promise<import("../index").BinaryNode>;
115
116
  waitForMessage: <T_2>(msgId: string, timeoutMs?: number | undefined) => Promise<T_2>;
116
117
  waitForSocketOpen: () => Promise<void>;
117
118
  sendRawMessage: (data: Uint8Array | Buffer) => Promise<void>;
118
- sendNode: (frame: import("..").BinaryNode) => Promise<void>;
119
+ sendNode: (frame: import("../index").BinaryNode) => Promise<void>;
119
120
  logout: (msg?: string | undefined) => Promise<void>;
120
121
  end: (error: Error | undefined) => void;
121
122
  onUnexpectedError: (err: Error | import("@hapi/boom").Boom<any>, msg: string) => void;
122
123
  uploadPreKeys: (count?: number) => Promise<void>;
123
124
  uploadPreKeysToServerIfRequired: () => Promise<void>;
125
+ requestPairingCode: (phoneNumber: string) => Promise<string>;
124
126
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
125
127
  };
126
128
  export default makeWASocket;
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ import { Boom } from '@hapi/boom';
2
3
  import { proto } from '../../WAProto';
3
4
  import { MessageReceiptType, MessageRelayOptions, SocketConfig } from '../Types';
4
5
  import { BinaryNode } from '../WABinary';
@@ -8,7 +9,7 @@ export declare const makeMessagesRecvSocket: (config: SocketConfig) => {
8
9
  rejectCall: (callId: string, callFrom: string) => Promise<void>;
9
10
  getPrivacyTokens: (jids: string[]) => Promise<BinaryNode>;
10
11
  assertSessions: (jids: string[], force: boolean) => Promise<boolean>;
11
- relayMessage: (jid: string, message: proto.IMessage, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache, cachedGroupMetadata }: MessageRelayOptions) => Promise<string>;
12
+ relayMessage: (jid: string, message: proto.IMessage, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache, cachedGroupMetadata, statusJidList }: MessageRelayOptions) => Promise<string>;
12
13
  sendReceipt: (jid: string, participant: string | undefined, messageIds: string[], type: MessageReceiptType) => Promise<void>;
13
14
  sendReceipts: (keys: proto.IMessageKey[], type: MessageReceiptType) => Promise<void>;
14
15
  readMessages: (keys: proto.IMessageKey[]) => Promise<void>;
@@ -33,6 +34,7 @@ export declare const makeMessagesRecvSocket: (config: SocketConfig) => {
33
34
  groupParticipantsUpdate: (jid: string, participants: string[], action: import("../Types").ParticipantAction) => Promise<{
34
35
  status: string;
35
36
  jid: string;
37
+ content: BinaryNode;
36
38
  }[]>;
37
39
  groupUpdateDescription: (jid: string, description?: string | undefined) => Promise<void>;
38
40
  groupInviteCode: (jid: string) => Promise<string | undefined>;
@@ -83,7 +85,7 @@ export declare const makeMessagesRecvSocket: (config: SocketConfig) => {
83
85
  addMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
84
86
  removeMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
85
87
  type: "md";
86
- ws: import("./Client").MobileSocketClient | import("./Client").WebSocketClient;
88
+ ws: import("./Client/mobile-socket-client").MobileSocketClient | import("./Client/web-socket-client").WebSocketClient;
87
89
  ev: import("../Types").BaileysEventEmitter & {
88
90
  process(handler: (events: Partial<import("../Types").BaileysEventMap>) => void | Promise<void>): () => void;
89
91
  buffer(): void;
@@ -105,8 +107,9 @@ export declare const makeMessagesRecvSocket: (config: SocketConfig) => {
105
107
  sendNode: (frame: BinaryNode) => Promise<void>;
106
108
  logout: (msg?: string | undefined) => Promise<void>;
107
109
  end: (error: Error | undefined) => void;
108
- onUnexpectedError: (err: Error | import("@hapi/boom").Boom<any>, msg: string) => void;
110
+ onUnexpectedError: (err: Error | Boom<any>, msg: string) => void;
109
111
  uploadPreKeys: (count?: number) => Promise<void>;
110
112
  uploadPreKeysToServerIfRequired: () => Promise<void>;
113
+ requestPairingCode: (phoneNumber: string) => Promise<string>;
111
114
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
112
115
  };
@@ -4,13 +4,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.makeMessagesRecvSocket = void 0;
7
+ const boom_1 = require("@hapi/boom");
8
+ const crypto_1 = require("crypto");
7
9
  const node_cache_1 = __importDefault(require("node-cache"));
8
10
  const WAProto_1 = require("../../WAProto");
9
11
  const Defaults_1 = require("../Defaults");
10
12
  const Types_1 = require("../Types");
11
13
  const Utils_1 = require("../Utils");
14
+ const Utils_2 = require("../Utils");
12
15
  const make_mutex_1 = require("../Utils/make-mutex");
13
- const process_message_1 = require("../Utils/process-message");
14
16
  const WABinary_1 = require("../WABinary");
15
17
  const groups_1 = require("./groups");
16
18
  const messages_send_1 = require("./messages-send");
@@ -169,7 +171,10 @@ const makeMessagesRecvSocket = (config) => {
169
171
  name: metadata.subject,
170
172
  conversationTimestamp: metadata.creation,
171
173
  }]);
172
- ev.emit('groups.upsert', [metadata]);
174
+ ev.emit('groups.upsert', [{
175
+ ...metadata,
176
+ author: participant
177
+ }]);
173
178
  break;
174
179
  case 'ephemeral':
175
180
  case 'not_ephemeral':
@@ -296,11 +301,82 @@ const makeMessagesRecvSocket = (config) => {
296
301
  });
297
302
  }
298
303
  break;
304
+ case 'link_code_companion_reg':
305
+ const linkCodeCompanionReg = (0, WABinary_1.getBinaryNodeChild)(node, 'link_code_companion_reg');
306
+ const ref = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'link_code_pairing_ref'));
307
+ const primaryIdentityPublicKey = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'primary_identity_pub'));
308
+ const primaryEphemeralPublicKeyWrapped = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'link_code_pairing_wrapped_primary_ephemeral_pub'));
309
+ const codePairingPublicKey = decipherLinkPublicKey(primaryEphemeralPublicKeyWrapped);
310
+ const companionSharedKey = Utils_1.Curve.sharedKey(authState.creds.pairingEphemeralKeyPair.private, codePairingPublicKey);
311
+ const random = (0, crypto_1.randomBytes)(32);
312
+ const linkCodeSalt = (0, crypto_1.randomBytes)(32);
313
+ const linkCodePairingExpanded = (0, Utils_1.hkdf)(companionSharedKey, 32, {
314
+ salt: linkCodeSalt,
315
+ info: 'link_code_pairing_key_bundle_encryption_key'
316
+ });
317
+ const encryptPayload = Buffer.concat([Buffer.from(authState.creds.signedIdentityKey.public), primaryIdentityPublicKey, random]);
318
+ const encryptIv = (0, crypto_1.randomBytes)(12);
319
+ const encrypted = (0, Utils_1.aesEncryptGCM)(encryptPayload, linkCodePairingExpanded, encryptIv, Buffer.alloc(0));
320
+ const encryptedPayload = Buffer.concat([linkCodeSalt, encryptIv, encrypted]);
321
+ const identitySharedKey = Utils_1.Curve.sharedKey(authState.creds.signedIdentityKey.private, primaryIdentityPublicKey);
322
+ const identityPayload = Buffer.concat([companionSharedKey, identitySharedKey, random]);
323
+ authState.creds.advSecretKey = (0, Utils_1.hkdf)(identityPayload, 32, { info: 'adv_secret' }).toString('base64');
324
+ await query({
325
+ tag: 'iq',
326
+ attrs: {
327
+ to: WABinary_1.S_WHATSAPP_NET,
328
+ type: 'set',
329
+ id: sock.generateMessageTag(),
330
+ xmlns: 'md'
331
+ },
332
+ content: [
333
+ {
334
+ tag: 'link_code_companion_reg',
335
+ attrs: {
336
+ jid: authState.creds.me.id,
337
+ stage: 'companion_finish',
338
+ },
339
+ content: [
340
+ {
341
+ tag: 'link_code_pairing_wrapped_key_bundle',
342
+ attrs: {},
343
+ content: encryptedPayload
344
+ },
345
+ {
346
+ tag: 'companion_identity_public',
347
+ attrs: {},
348
+ content: authState.creds.signedIdentityKey.public
349
+ },
350
+ {
351
+ tag: 'link_code_pairing_ref',
352
+ attrs: {},
353
+ content: ref
354
+ }
355
+ ]
356
+ }
357
+ ]
358
+ });
359
+ authState.creds.registered = true;
360
+ ev.emit('creds.update', authState.creds);
299
361
  }
300
362
  if (Object.keys(result).length) {
301
363
  return result;
302
364
  }
303
365
  };
366
+ function decipherLinkPublicKey(data) {
367
+ const buffer = toRequiredBuffer(data);
368
+ const salt = buffer.slice(0, 32);
369
+ const secretKey = (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
370
+ const iv = buffer.slice(32, 48);
371
+ const payload = buffer.slice(48, 80);
372
+ return (0, Utils_1.aesDecryptCTR)(payload, secretKey, iv);
373
+ }
374
+ function toRequiredBuffer(data) {
375
+ if (data === undefined) {
376
+ throw new boom_1.Boom('Invalid buffer', { statusCode: 400 });
377
+ }
378
+ return data instanceof Buffer ? data : Buffer.from(data);
379
+ }
304
380
  const willSendMessageAgain = (id, participant) => {
305
381
  const key = `${id}:${participant}`;
306
382
  const retryCount = msgRetryCache.get(key) || 0;
@@ -501,7 +577,7 @@ const makeMessagesRecvSocket = (config) => {
501
577
  await sendReceipt(jid, undefined, [msg.key.id], 'hist_sync');
502
578
  }
503
579
  }
504
- (0, process_message_1.cleanMessage)(msg, authState.creds.me.id);
580
+ (0, Utils_2.cleanMessage)(msg, authState.creds.me.id);
505
581
  await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify');
506
582
  }),
507
583
  sendMessageAck(node)
@@ -6,7 +6,7 @@ import { BinaryNode } from '../WABinary';
6
6
  export declare const makeMessagesSocket: (config: SocketConfig) => {
7
7
  getPrivacyTokens: (jids: string[]) => Promise<BinaryNode>;
8
8
  assertSessions: (jids: string[], force: boolean) => Promise<boolean>;
9
- relayMessage: (jid: string, message: proto.IMessage, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache, cachedGroupMetadata }: MessageRelayOptions) => Promise<string>;
9
+ relayMessage: (jid: string, message: proto.IMessage, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache, cachedGroupMetadata, statusJidList }: MessageRelayOptions) => Promise<string>;
10
10
  sendReceipt: (jid: string, participant: string | undefined, messageIds: string[], type: MessageReceiptType) => Promise<void>;
11
11
  sendReceipts: (keys: WAMessageKey[], type: MessageReceiptType) => Promise<void>;
12
12
  readMessages: (keys: WAMessageKey[]) => Promise<void>;
@@ -31,6 +31,7 @@ export declare const makeMessagesSocket: (config: SocketConfig) => {
31
31
  groupParticipantsUpdate: (jid: string, participants: string[], action: import("../Types").ParticipantAction) => Promise<{
32
32
  status: string;
33
33
  jid: string;
34
+ content: BinaryNode;
34
35
  }[]>;
35
36
  groupUpdateDescription: (jid: string, description?: string | undefined) => Promise<void>;
36
37
  groupInviteCode: (jid: string) => Promise<string | undefined>;
@@ -81,7 +82,7 @@ export declare const makeMessagesSocket: (config: SocketConfig) => {
81
82
  addMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
82
83
  removeMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
83
84
  type: "md";
84
- ws: import("./Client").MobileSocketClient | import("./Client").WebSocketClient;
85
+ ws: import("./Client/mobile-socket-client").MobileSocketClient | import("./Client/web-socket-client").WebSocketClient;
85
86
  ev: import("../Types").BaileysEventEmitter & {
86
87
  process(handler: (events: Partial<import("../Types").BaileysEventMap>) => void | Promise<void>): () => void;
87
88
  buffer(): void;
@@ -106,5 +107,6 @@ export declare const makeMessagesSocket: (config: SocketConfig) => {
106
107
  onUnexpectedError: (err: Error | Boom<any>, msg: string) => void;
107
108
  uploadPreKeys: (count?: number) => Promise<void>;
108
109
  uploadPreKeysToServerIfRequired: () => Promise<void>;
110
+ requestPairingCode: (phoneNumber: string) => Promise<string>;
109
111
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
110
112
  };