@neelegirly/baileys 2.2.18 → 2.2.19

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 (40) hide show
  1. package/README.md +27 -25
  2. package/lib/Socket/business.d.ts +6 -1
  3. package/lib/Socket/chats.d.ts +6 -1
  4. package/lib/Socket/chats.js +121 -28
  5. package/lib/Socket/communities.d.ts +5 -0
  6. package/lib/Socket/groups.d.ts +6 -1
  7. package/lib/Socket/groups.js +15 -1
  8. package/lib/Socket/index.d.ts +6 -1
  9. package/lib/Socket/messages-recv.d.ts +5 -0
  10. package/lib/Socket/messages-recv.js +26 -8
  11. package/lib/Socket/messages-send.d.ts +6 -1
  12. package/lib/Socket/newsletter.d.ts +6 -1
  13. package/lib/Socket/registration.d.ts +5 -0
  14. package/lib/Socket/socket.js +55 -29
  15. package/lib/Types/Call.d.ts +3 -2
  16. package/lib/Types/Contact.d.ts +3 -1
  17. package/lib/Types/Events.d.ts +14 -1
  18. package/lib/Types/GroupMetadata.d.ts +9 -1
  19. package/lib/Types/Message.d.ts +21 -3
  20. package/lib/Types/Signal.d.ts +17 -1
  21. package/lib/Utils/chat-utils.d.ts +21 -1
  22. package/lib/Utils/chat-utils.js +27 -8
  23. package/lib/Utils/decode-wa-message.js +5 -1
  24. package/lib/Utils/event-buffer.js +3 -1
  25. package/lib/Utils/generics.js +9 -0
  26. package/lib/Utils/history.js +10 -11
  27. package/lib/Utils/messages-media.js +2 -2
  28. package/lib/Utils/messages.js +19 -2
  29. package/lib/Utils/process-message.js +5 -4
  30. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +1 -1
  31. package/lib/WAUSync/Protocols/USyncContactProtocol.js +27 -4
  32. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +9 -0
  33. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +31 -0
  34. package/lib/WAUSync/Protocols/index.d.ts +2 -1
  35. package/lib/WAUSync/Protocols/index.js +2 -1
  36. package/lib/WAUSync/USyncQuery.d.ts +2 -1
  37. package/lib/WAUSync/USyncQuery.js +5 -1
  38. package/lib/WAUSync/USyncUser.d.ts +4 -0
  39. package/lib/WAUSync/USyncUser.js +9 -1
  40. package/package.json +1 -1
@@ -364,7 +364,8 @@ const makeMessagesRecvSocket = (config) => {
364
364
  child,
365
365
  msg,
366
366
  participantPhoneNumber,
367
- mode
367
+ mode,
368
+ participantUsername
368
369
  ) => {
369
370
  if (participant && participant.endsWith("@lid") && participantPhoneNumber) {
370
371
  participant = participantPhoneNumber;
@@ -411,7 +412,7 @@ const makeMessagesRecvSocket = (config) => {
411
412
  const metadata = groups_1.extractGroupMetadata(child);
412
413
  msg.messageStubType = Types_1.WAMessageStubType.GROUP_CREATE;
413
414
  msg.messageStubParameters = [metadata.subject];
414
- msg.key = { participant: metadata.owner };
415
+ msg.key = { participant: metadata.owner, participantUsername: metadata.ownerUsername };
415
416
  ev.emit("chats.upsert", [
416
417
  {
417
418
  id: metadata.id,
@@ -423,6 +424,8 @@ const makeMessagesRecvSocket = (config) => {
423
424
  {
424
425
  ...metadata,
425
426
  author: participant,
427
+ authorPn: participantPhoneNumber,
428
+ authorUsername: participantUsername,
426
429
  },
427
430
  ]);
428
431
  break;
@@ -457,7 +460,7 @@ const makeMessagesRecvSocket = (config) => {
457
460
  case "leave":
458
461
  let stubType = `GROUP_PARTICIPANT_${child.tag.toUpperCase()}`;
459
462
  if (child.attrs?.reason === "linked_group_join") {
460
- stubType = GROUP_PARTICIPANT_LINKED_GROUP_JOIN;
463
+ stubType = "GROUP_PARTICIPANT_LINKED_GROUP_JOIN";
461
464
  }
462
465
  msg.messageStubType = Types_1.WAMessageStubType[stubType];
463
466
  const participants = (0, WABinary_1.getBinaryNodeChildren)(
@@ -494,7 +497,7 @@ const makeMessagesRecvSocket = (config) => {
494
497
  msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_SUBJECT;
495
498
  msg.messageStubType =
496
499
  Types_1.WAMessageStubType.COMMUNITY_PARENT_GROUP_SUBJECT_CHANGED;
497
- msg.messageStubParameters = [participantJid, child.attrs.subject];
500
+ msg.messageStubParameters = [child.attrs.subject, participantJid];
498
501
  break;
499
502
  case "description":
500
503
  const description = WABinary_1.getBinaryNodeChild(
@@ -614,7 +617,7 @@ const makeMessagesRecvSocket = (config) => {
614
617
  child,
615
618
  "sub_group_suggestions"
616
619
  );
617
- const reason = res.attrs?.reason;
620
+ const reason = res[0]?.attrs?.reason;
618
621
  if (reason === "approved")
619
622
  msg.messageStubType = Types_1.WAMessageStubType.GROUP_CREATE;
620
623
  else
@@ -633,10 +636,10 @@ const makeMessagesRecvSocket = (config) => {
633
636
  const serverId = node.attrs.server_id;
634
637
 
635
638
  const reactionsList = WABinary_1.getBinaryNodeChild(node, "reactions");
636
- const viewsList = WABinary_1.getBinaryNodeChild(node, "views_count");
639
+ const viewsList = WABinary_1.getBinaryNodeChildren(node, "views_count");
637
640
 
638
641
  if (reactionsList) {
639
- const reactions = WABinary_1.getBinaryNodeChild(
642
+ const reactions = WABinary_1.getBinaryNodeChildren(
640
643
  reactionsList,
641
644
  "reaction"
642
645
  );
@@ -766,7 +769,8 @@ const makeMessagesRecvSocket = (config) => {
766
769
  child,
767
770
  result,
768
771
  node.attrs.participant_pn,
769
- mode
772
+ mode,
773
+ node.attrs.participant_username
770
774
  );
771
775
  break;
772
776
  case "newsletter":
@@ -1175,6 +1179,7 @@ const makeMessagesRecvSocket = (config) => {
1175
1179
  remoteJid,
1176
1180
  fromMe,
1177
1181
  participant: node.attrs.participant,
1182
+ participantUsername: node.attrs.participant_username,
1178
1183
  id: node.attrs.id,
1179
1184
  ...(msg.key || {}),
1180
1185
  };
@@ -1557,12 +1562,24 @@ const makeMessagesRecvSocket = (config) => {
1557
1562
  const call = {
1558
1563
  chatId: attrs.from,
1559
1564
  from,
1565
+ callerPn: infoChild.attrs["caller_pn"],
1560
1566
  id: callId,
1561
1567
  date: new Date(+attrs.t * 1000),
1562
1568
  offline: !!attrs.offline,
1563
1569
  status,
1564
1570
  };
1565
1571
 
1572
+ if (status === "relaylatency") {
1573
+ const latencyValue =
1574
+ infoChild.attrs.latency ||
1575
+ infoChild.attrs["latency_ms"] ||
1576
+ infoChild.attrs["latency-ms"];
1577
+ const latencyMs = latencyValue ? Number(latencyValue) : undefined;
1578
+ if (Number.isFinite(latencyMs)) {
1579
+ call.latencyMs = latencyMs;
1580
+ }
1581
+ }
1582
+
1566
1583
  if (status === "offer") {
1567
1584
  call.isVideo = !!WABinary_1.getBinaryNodeChild(infoChild, "video");
1568
1585
  call.isGroup =
@@ -1577,6 +1594,7 @@ const makeMessagesRecvSocket = (config) => {
1577
1594
  if (existingCall) {
1578
1595
  call.isVideo = existingCall.isVideo;
1579
1596
  call.isGroup = existingCall.isGroup;
1597
+ call.callerPn = call.callerPn || existingCall.callerPn;
1580
1598
  }
1581
1599
 
1582
1600
  // delete data once call has ended
@@ -123,6 +123,11 @@ export declare const makeMessagesSocket: (config: SocketConfig) => {
123
123
  resyncAppState: (collections: readonly ("critical_block" | "critical_unblock_low" | "regular_high" | "regular_low" | "regular")[], isInitialSync: boolean) => Promise<void>
124
124
  chatModify: (mod: import("../Types").ChatModification, jid: string) => Promise<void>
125
125
  cleanDirtyBits: (type: "account_sync" | "groups", fromTimestamp?: string | number | undefined) => Promise<void>
126
+ serverProps: {
127
+ privacyTokenOn1to1: boolean
128
+ profilePicPrivacyToken: boolean
129
+ lidTrustedTokenIssueToLid: boolean
130
+ }
126
131
  addLabel: (jid: string, labels: import("../Types/Label").LabelActionBody) => Promise<void>
127
132
  addChatLabel: (jid: string, labelId: string) => Promise<void>
128
133
  removeChatLabel: (jid: string, labelId: string) => Promise<void>
@@ -165,4 +170,4 @@ export declare const makeMessagesSocket: (config: SocketConfig) => {
165
170
  requestPairingCode: (phoneNumber: string, code?: string) => Promise<string>
166
171
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>
167
172
  sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>
168
- }
173
+ }
@@ -101,6 +101,11 @@ export declare const makeNewsletterSocket: (config: SocketConfig) => {
101
101
  resyncAppState: (collections: readonly ("critical_block" | "critical_unblock_low" | "regular_high" | "regular_low" | "regular")[], isInitialSync: boolean) => Promise<void>
102
102
  chatModify: (mod: import("../Types").ChatModification, jid: string) => Promise<void>
103
103
  cleanDirtyBits: (type: "account_sync" | "groups", fromTimestamp?: string | number | undefined) => Promise<void>
104
+ serverProps: {
105
+ privacyTokenOn1to1: boolean
106
+ profilePicPrivacyToken: boolean
107
+ lidTrustedTokenIssueToLid: boolean
108
+ }
104
109
  addChatLabel: (jid: string, labelId: string) => Promise<void>
105
110
  removeChatLabel: (jid: string, labelId: string) => Promise<void>
106
111
  addMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>
@@ -144,4 +149,4 @@ export declare const makeNewsletterSocket: (config: SocketConfig) => {
144
149
  sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>
145
150
  }
146
151
 
147
- export declare const extractNewsletterMetadata: (node: BinaryNode, isCreate?: boolean) => NewsletterMetadata
152
+ export declare const extractNewsletterMetadata: (node: BinaryNode, isCreate?: boolean) => NewsletterMetadata
@@ -133,6 +133,11 @@ export declare const makeRegistrationSocket: (config: SocketConfig) => {
133
133
  resyncAppState: (collections: readonly ("critical_block" | "critical_unblock_low" | "regular_high" | "regular_low" | "regular")[], isInitialSync: boolean) => Promise<void>;
134
134
  chatModify: (mod: import("../Types").ChatModification, jid: string) => Promise<void>;
135
135
  cleanDirtyBits: (type: "account_sync" | "groups", fromTimestamp?: number | string) => Promise<void>;
136
+ serverProps: {
137
+ privacyTokenOn1to1: boolean;
138
+ profilePicPrivacyToken: boolean;
139
+ lidTrustedTokenIssueToLid: boolean;
140
+ };
136
141
  addChatLabel: (jid: string, labelId: string) => Promise<void>;
137
142
  removeChatLabel: (jid: string, labelId: string) => Promise<void>;
138
143
  addMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
@@ -403,43 +403,69 @@ const makeSocket = (config) => {
403
403
  }
404
404
  }
405
405
 
406
+ const isNoiseDecryptAuthError = (error) => {
407
+ const combined = `${error?.message || ''}\n${error?.stack || ''}`.toLowerCase()
408
+ return /unsupported state or unable to authenticate data|aesdecryptgcm|noise-handler|decipheriv\.final/.test(combined)
409
+ }
410
+
406
411
  const onMessageReceived = async (data) => {
407
- await noise.decodeFrame(data, frame => {
408
- // reset ping timeout
409
- lastDateRecv = new Date()
410
- let anyTriggered = false
411
- anyTriggered = ws.emit('frame', frame)
412
-
413
- // if it's a binary node
414
- if (!(frame instanceof Uint8Array)) {
415
- const msgId = frame.attrs.id
412
+ try {
413
+ await noise.decodeFrame(data, frame => {
414
+ // reset ping timeout
415
+ lastDateRecv = new Date()
416
+ let anyTriggered = false
417
+ anyTriggered = ws.emit('frame', frame)
416
418
 
417
- if (logger.level === 'trace') {
418
- logger.trace({ xml: WABinary_1.binaryNodeToString(frame), msg: 'recv xml' })
419
- }
419
+ // if it's a binary node
420
+ if (!(frame instanceof Uint8Array)) {
421
+ const msgId = frame.attrs.id
422
+
423
+ if (logger.level === 'trace') {
424
+ logger.trace({ xml: WABinary_1.binaryNodeToString(frame), msg: 'recv xml' })
425
+ }
420
426
 
421
- /* Check if this is a response to a message we sent */
422
- anyTriggered = ws.emit(`${Defaults_1.DEF_TAG_PREFIX}${msgId}`, frame) || anyTriggered
427
+ /* Check if this is a response to a message we sent */
428
+ anyTriggered = ws.emit(`${Defaults_1.DEF_TAG_PREFIX}${msgId}`, frame) || anyTriggered
423
429
 
424
- /* Check if this is a response to a message we are expecting */
425
- const l0 = frame.tag
426
- const l1 = frame.attrs || {}
427
- const l2 = Array.isArray(frame.content) ? frame.content[0]?.tag : ''
430
+ /* Check if this is a response to a message we are expecting */
431
+ const l0 = frame.tag
432
+ const l1 = frame.attrs || {}
433
+ const l2 = Array.isArray(frame.content) ? frame.content[0]?.tag : ''
428
434
 
429
- for (const key of Object.keys(l1)) {
430
- anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, frame) || anyTriggered
431
- anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, frame) || anyTriggered
432
- anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}`, frame) || anyTriggered
433
- }
435
+ for (const key of Object.keys(l1)) {
436
+ anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, frame) || anyTriggered
437
+ anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, frame) || anyTriggered
438
+ anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}`, frame) || anyTriggered
439
+ }
434
440
 
435
- anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},,${l2}`, frame) || anyTriggered
436
- anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0}`, frame) || anyTriggered
441
+ anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},,${l2}`, frame) || anyTriggered
442
+ anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0}`, frame) || anyTriggered
437
443
 
438
- if (!anyTriggered && logger.level === 'debug') {
439
- logger.debug({ unhandled: true, msgId, fromMe: false, frame }, 'communication recv')
444
+ if (!anyTriggered && logger.level === 'debug') {
445
+ logger.debug({ unhandled: true, msgId, fromMe: false, frame }, 'communication recv')
446
+ }
440
447
  }
441
- }
442
- })
448
+ })
449
+ } catch (error) {
450
+ const isNoiseDecryptError = isNoiseDecryptAuthError(error)
451
+ logger.warn(
452
+ { trace: error?.stack, msg: error?.message },
453
+ isNoiseDecryptError
454
+ ? 'noise decrypt failed, closing socket for retry'
455
+ : 'incoming frame decode failed, closing socket'
456
+ )
457
+ end(
458
+ error instanceof boom_1.Boom
459
+ ? error
460
+ : new boom_1.Boom(
461
+ isNoiseDecryptError ? 'Noise decrypt failed' : 'Failed to decode incoming frame',
462
+ {
463
+ statusCode: Types_1.DisconnectReason.connectionClosed,
464
+ data: { cause: error?.message || String(error || '') }
465
+ }
466
+ )
467
+ )
468
+ }
443
469
  }
444
470
 
445
471
  const end = (error) => {
@@ -1,8 +1,9 @@
1
- export type WACallUpdateType = 'offer' | 'ringing' | 'timeout' | 'reject' | 'accept' | 'terminate'
1
+ export type WACallUpdateType = 'offer' | 'ringing' | 'preaccept' | 'transport' | 'relaylatency' | 'timeout' | 'reject' | 'accept' | 'terminate'
2
2
 
3
3
  export type WACallEvent = {
4
4
  chatId: string
5
5
  from: string
6
+ callerPn?: string
6
7
  isGroup?: boolean
7
8
  groupJid?: string
8
9
  id: string
@@ -11,4 +12,4 @@ export type WACallEvent = {
11
12
  status: WACallUpdateType
12
13
  offline: boolean
13
14
  latencyMs?: number
14
- }
15
+ }
@@ -6,6 +6,8 @@ export interface Contact {
6
6
  name?: string
7
7
  /** name of the contact, the contact has set on their own on WA */
8
8
  notify?: string
9
+ /** username associated with this contact, when provided by WA */
10
+ username?: string
9
11
  /** I have no idea */
10
12
  verifiedName?: string
11
13
  /**
@@ -17,4 +19,4 @@ export interface Contact {
17
19
  */
18
20
  imgUrl?: string | null
19
21
  status?: string
20
- }
22
+ }
@@ -24,8 +24,15 @@ export type BaileysEventMap = {
24
24
  isLatest?: boolean
25
25
  progress?: number | null
26
26
  syncType?: proto.HistorySync.HistorySyncType
27
+ chunkOrder?: number | null
27
28
  peerDataRequestSessionId?: string | null
28
29
  }
30
+ /** signals history sync milestones (completion or stall) per sync type */
31
+ 'messaging-history.status': {
32
+ syncType: proto.HistorySync.HistorySyncType
33
+ status: 'complete' | 'paused'
34
+ explicit: boolean
35
+ }
29
36
  /** upsert chats */
30
37
  'chats.upsert': Chat[]
31
38
  /** update the given chats */
@@ -86,13 +93,18 @@ export type BaileysEventMap = {
86
93
  'group-participants.update': {
87
94
  id: string
88
95
  author: string
96
+ authorPn?: string
97
+ authorUsername?: string
89
98
  participants: string[]
90
99
  action: ParticipantAction
91
100
  }
92
101
  'group.join-request': {
93
102
  id: string
94
103
  author: string
104
+ authorPn?: string
105
+ authorUsername?: string
95
106
  participant: string
107
+ participantPn?: string
96
108
  action: RequestJoinAction
97
109
  method: RequestJoinMethod
98
110
  }
@@ -174,6 +186,7 @@ export type BufferedEventData = {
174
186
  isLatest: boolean
175
187
  progress?: number | null
176
188
  syncType?: proto.HistorySync.HistorySyncType
189
+ chunkOrder?: number | null
177
190
  peerDataRequestSessionId?: string
178
191
  }
179
192
  chatUpserts: {
@@ -234,4 +247,4 @@ export interface BaileysEventEmitter {
234
247
  off<T extends keyof BaileysEventMap>(event: T, listener: (arg: BaileysEventMap[T]) => void): void
235
248
  removeAllListeners<T extends keyof BaileysEventMap>(event: T): void
236
249
  emit<T extends keyof BaileysEventMap>(event: T, arg: BaileysEventMap[T]): boolean
237
- }
250
+ }
@@ -16,15 +16,21 @@ export interface GroupMetadata {
16
16
  id: string
17
17
  addressingMode: string
18
18
  owner: string | undefined
19
+ ownerPn?: string
20
+ ownerUsername?: string
19
21
  ownerCountry: string,
20
22
  subject: string
21
23
  /** group subject owner */
22
24
  subjectOwner?: string
25
+ subjectOwnerPn?: string
26
+ subjectOwnerUsername?: string
23
27
  /** group subject modification date */
24
28
  subjectTime?: number
25
29
  creation?: number
26
30
  desc?: string
27
31
  descOwner?: string
32
+ descOwnerPn?: string
33
+ descOwnerUsername?: string
28
34
  descId?: string
29
35
  /** if this group is part of a community, it returns the jid of the community to which it belongs */
30
36
  linkedParent?: string
@@ -48,6 +54,8 @@ export interface GroupMetadata {
48
54
  inviteCode?: string
49
55
  /** the person who added you to group or changed some setting in group */
50
56
  author?: string
57
+ authorPn?: string
58
+ authorUsername?: string
51
59
  }
52
60
 
53
61
  export interface WAGroupCreateResponse {
@@ -63,4 +71,4 @@ export interface GroupModificationResponse {
63
71
  participants?: {
64
72
  [key: string]: {}
65
73
  }
66
- }
74
+ }
@@ -19,6 +19,12 @@ export type WAContactMessage = proto.Message.IContactMessage
19
19
  export type WAContactsArrayMessage = proto.Message.IContactsArrayMessage
20
20
 
21
21
  export type WAMessageKey = proto.IMessageKey & {
22
+ remoteJidAlt?: string
23
+ remoteJidUsername?: string
24
+ participantAlt?: string
25
+ participantUsername?: string
26
+ participant_pn?: string
27
+ participant_lid?: string
22
28
  newsletter_server_id?: string
23
29
  }
24
30
 
@@ -199,6 +205,13 @@ export type PollResultOptions = {
199
205
  values: string[]
200
206
  }
201
207
 
208
+ export type AlbumMessageOptions = {
209
+ /** Number of images expected in the album */
210
+ expectedImageCount?: number
211
+ /** Number of videos expected in the album */
212
+ expectedVideoCount?: number
213
+ }
214
+
202
215
  type SharePhoneNumber = {
203
216
  sharePhoneNumber: boolean
204
217
  }
@@ -234,7 +247,10 @@ export type AnyMediaMessageContent = (({
234
247
  caption?: string
235
248
  } & Contextable & Buttonable & Templatable & Interactiveable )) & {
236
249
  mimetype?: string
237
- } & Editable
250
+ } & Editable & {
251
+ /** key of the parent albumMessage to associate this media with */
252
+ albumParentKey?: WAMessageKey
253
+ }
238
254
 
239
255
  export type ButtonReplyInfo = {
240
256
  displayText: string
@@ -332,7 +348,9 @@ export type AnyRegularMessageContent = (({
332
348
  }
333
349
  } | {
334
350
  pollResult: PollResultOptions
335
- } | {
351
+ } | ({
352
+ album: AlbumMessageOptions
353
+ } & Contextable & Mentionable) | {
336
354
  order: WAOrderMessage
337
355
  } | {
338
356
  product: WASendableProduct
@@ -470,4 +488,4 @@ export type MediaDecryptionKeyInfo = {
470
488
  macKey?: Buffer
471
489
  }
472
490
 
473
- export type MinimalMessage = Pick<proto.IWebMessageInfo, 'key' | 'messageTimestamp'>
491
+ export type MinimalMessage = Pick<proto.IWebMessageInfo, 'key' | 'messageTimestamp'>
@@ -49,7 +49,19 @@ type E2ESessionOpts = {
49
49
  session: E2ESession
50
50
  }
51
51
 
52
+ type LIDPNMapping = {
53
+ lid: string
54
+ pn: string
55
+ }
56
+
52
57
  export type SignalRepository = {
58
+ lidMapping: {
59
+ storeLIDPNMappings(mappings: LIDPNMapping[]): Promise<boolean>
60
+ getPNForLID(lid: string): Promise<string | null>
61
+ getLIDForPN(pn: string): Promise<string | null>
62
+ getLIDsForPNs(pns: string[]): Promise<LIDPNMapping[]>
63
+ }
64
+ migrateSession(fromJid: string, toJid: string): Promise<boolean>
53
65
  decryptGroupMessage(opts: DecryptGroupSignalOpts): Promise<Uint8Array>
54
66
  processSenderKeyDistributionMessage(opts: ProcessSenderKeyDistributionMessageOpts): Promise<void>
55
67
  decryptMessage(opts: DecryptSignalProtoOpts): Promise<Uint8Array>
@@ -63,6 +75,10 @@ export type SignalRepository = {
63
75
  }>
64
76
  injectE2ESession(opts: E2ESessionOpts): Promise<void>
65
77
  jidToSignalProtocolAddress(jid: string): string
78
+ validateSession(jid: string): Promise<{
79
+ exists: boolean
80
+ reason?: string
81
+ }>
66
82
  }
67
83
 
68
- export {}
84
+ export {}
@@ -10,8 +10,28 @@ export type ChatMutationMap = {
10
10
  [index: string]: ChatMutation
11
11
  }
12
12
 
13
+ export declare const makeLtHashGenerator: ({ indexValueMap, hash }: Pick<LTHashState, 'hash' | 'indexValueMap'>) => {
14
+ mix: (mac: {
15
+ indexMac: Uint8Array
16
+ valueMac: Uint8Array
17
+ operation: proto.SyncdMutation.SyncdOperation
18
+ }) => void
19
+ finish: () => Promise<{
20
+ hash: Buffer
21
+ indexValueMap: LTHashState['indexValueMap']
22
+ }>
23
+ }
24
+
13
25
  export declare const newLTHashState: () => LTHashState
14
26
 
27
+ export declare const ensureLTHashStateVersion: (state: LTHashState) => LTHashState
28
+
29
+ export declare const MAX_SYNC_ATTEMPTS: 2
30
+
31
+ export declare const isMissingKeyError: (error: any) => boolean
32
+
33
+ export declare const isAppStateSyncIrrecoverable: (error: any, attempts: number) => boolean
34
+
15
35
  export declare const encodeSyncdPatch: ({ type, index, syncAction, apiVersion, operation }: WAPatchCreate, myAppStateKeyId: string, state: LTHashState, getAppStateSyncKey: FetchAppStateSyncKey) => Promise<{
16
36
  patch: proto.ISyncdPatch
17
37
  state: LTHashState
@@ -79,4 +99,4 @@ export declare const chatModificationToAppPatch: (mod: ChatModification, jid: st
79
99
 
80
100
  export declare const processSyncAction: (syncAction: ChatMutation, ev: BaileysEventEmitter, me: Contact, initialSyncOpts?: InitialAppStateSyncOptions, logger?: ILogger) => void
81
101
 
82
- export {}
102
+ export {}
@@ -60,7 +60,7 @@ const makeLtHashGenerator = ({ indexValueMap, hash }) => {
60
60
  const prevOp = indexValueMap[indexMacBase64]
61
61
  if (operation === WAProto_1.proto.SyncdMutation.SyncdOperation.REMOVE) {
62
62
  if (!prevOp) {
63
- throw new boom_1.Boom('tried remove, but no previous op', { data: { indexMac, valueMac } })
63
+ return
64
64
  }
65
65
  // remove from index value mac, since this mutation is erased
66
66
  delete indexValueMap[indexMacBase64]
@@ -107,10 +107,23 @@ const generatePatchMac = (snapshotMac, valueMacs, version, type, key) => {
107
107
 
108
108
  const newLTHashState = () => ({ version: 0, hash: Buffer.alloc(128), indexValueMap: {} })
109
109
 
110
+ const ensureLTHashStateVersion = (state) => {
111
+ if (typeof state.version !== 'number' || Number.isNaN(state.version)) {
112
+ state.version = 0
113
+ }
114
+ return state
115
+ }
116
+
117
+ const MAX_SYNC_ATTEMPTS = 2
118
+
119
+ const isMissingKeyError = (error) => error?.data?.isMissingKey === true
120
+
121
+ const isAppStateSyncIrrecoverable = (error, attempts) => attempts >= MAX_SYNC_ATTEMPTS || error?.name === 'TypeError'
122
+
110
123
  const encodeSyncdPatch = async ({ type, index, syncAction, apiVersion, operation }, myAppStateKeyId, state, getAppStateSyncKey) => {
111
124
  const key = !!myAppStateKeyId ? await getAppStateSyncKey(myAppStateKeyId) : undefined
112
125
  if (!key) {
113
- throw new boom_1.Boom(`myAppStateKey ("${myAppStateKeyId}") not present`, { statusCode: 404 })
126
+ throw new boom_1.Boom(`myAppStateKey ("${myAppStateKeyId}") not present`, { data: { isMissingKey: true } })
114
127
  }
115
128
  const encKeyId = Buffer.from(myAppStateKeyId, 'base64')
116
129
  state = { ...state, indexValueMap: { ...state.indexValueMap } }
@@ -197,7 +210,7 @@ const decodeSyncdMutations = async (msgMutations, initialState, getAppStateSyncK
197
210
  const base64Key = Buffer.from(keyId).toString('base64')
198
211
  const keyEnc = await getAppStateSyncKey(base64Key)
199
212
  if (!keyEnc) {
200
- throw new boom_1.Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 404, data: { msgMutations } })
213
+ throw new boom_1.Boom(`failed to find key "${base64Key}" to decode mutation`, { data: { isMissingKey: true, msgMutations } })
201
214
  }
202
215
  return mutationKeys(keyEnc.keyData)
203
216
  }
@@ -208,7 +221,7 @@ const decodeSyncdPatch = async (msg, name, initialState, getAppStateSyncKey, onM
208
221
  const base64Key = Buffer.from(msg.keyId.id).toString('base64')
209
222
  const mainKeyObj = await getAppStateSyncKey(base64Key)
210
223
  if (!mainKeyObj) {
211
- throw new boom_1.Boom(`failed to find key "${base64Key}" to decode patch`, { statusCode: 404, data: { msg } })
224
+ throw new boom_1.Boom(`failed to find key "${base64Key}" to decode patch`, { data: { isMissingKey: true, msg } })
212
225
  }
213
226
  const mainKey = await mutationKeys(mainKeyObj.keyData)
214
227
  const mutationmacs = msg.mutations.map(mutation => mutation.record.value.blob.slice(-32))
@@ -291,7 +304,7 @@ const decodeSyncdSnapshot = async (name, snapshot, getAppStateSyncKey, minimumVe
291
304
  const base64Key = Buffer.from(snapshot.keyId.id).toString('base64')
292
305
  const keyEnc = await getAppStateSyncKey(base64Key)
293
306
  if (!keyEnc) {
294
- throw new boom_1.Boom(`failed to find key "${base64Key}" to decode mutation`)
307
+ throw new boom_1.Boom(`failed to find key "${base64Key}" to decode mutation`, { data: { isMissingKey: true } })
295
308
  }
296
309
  const result = await mutationKeys(keyEnc.keyData)
297
310
  const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey)
@@ -335,7 +348,7 @@ const decodePatches = async (name, syncds, initial, getAppStateSyncKey, options,
335
348
  const base64Key = Buffer.from(keyId.id).toString('base64')
336
349
  const keyEnc = await getAppStateSyncKey(base64Key)
337
350
  if (!keyEnc) {
338
- throw new boom_1.Boom(`failed to find key "${base64Key}" to decode mutation`)
351
+ throw new boom_1.Boom(`failed to find key "${base64Key}" to decode mutation`, { data: { isMissingKey: true } })
339
352
  }
340
353
  const result = await mutationKeys(keyEnc.keyData)
341
354
  const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey)
@@ -690,7 +703,8 @@ const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
690
703
  else if (action?.contactAction) {
691
704
  ev.emit('contacts.upsert', [{
692
705
  id,
693
- name: action.contactAction.fullName,
706
+ name: action.contactAction.fullName || action.contactAction.firstName || action.contactAction.username || undefined,
707
+ username: action.contactAction.username || undefined,
694
708
  lid: action.contactAction.lidJid || undefined,
695
709
  jid: WABinary_1.isJidUser(id) ? id : undefined
696
710
  }])
@@ -784,7 +798,12 @@ const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
784
798
 
785
799
  module.exports = {
786
800
  mutationKeys,
801
+ makeLtHashGenerator,
787
802
  newLTHashState,
803
+ ensureLTHashStateVersion,
804
+ MAX_SYNC_ATTEMPTS,
805
+ isMissingKeyError,
806
+ isAppStateSyncIrrecoverable,
788
807
  encodeSyncdPatch,
789
808
  decodeSyncdMutations,
790
809
  decodeSyncdPatch,
@@ -795,4 +814,4 @@ module.exports = {
795
814
  decodePatches,
796
815
  chatModificationToAppPatch,
797
816
  processSyncAction
798
- }
817
+ }
@@ -112,9 +112,13 @@ const fromMe = WABinary_1.isJidNewsletter(stanza.attrs.from)
112
112
  const pushname = stanza?.attrs?.notify
113
113
  const key = {
114
114
  remoteJid: chatId,
115
+ remoteJidUsername: !WABinary_1.isJidGroup(chatId)
116
+ ? stanza.attrs.peer_recipient_username || stanza.attrs.recipient_username
117
+ : undefined,
115
118
  fromMe,
116
119
  id: msgId,
117
120
  ...(participant !== undefined && { participant: fromMe ? meId : participant }),
121
+ ...(stanza.attrs.participant !== undefined && { participantUsername: stanza.attrs.participant_username }),
118
122
  ...(stanza.attrs.participant_pn !== undefined && { participant_pn: fromMe ? meId : stanza.attrs.participant_pn }),
119
123
  ...(stanza.attrs.participant_lid !== undefined && { participant_lid: fromMe ? meLid : stanza.attrs.participant_lid }),
120
124
  }
@@ -285,4 +289,4 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
285
289
  module.exports = {
286
290
  decodeMessageNode,
287
291
  decryptMessageNode
288
- }
292
+ }
@@ -188,6 +188,7 @@ function append(data, historyCache, event, eventData, logger) {
188
188
  data.historySets.empty = false
189
189
  data.historySets.syncType = eventData.syncType
190
190
  data.historySets.progress = eventData.progress
191
+ data.historySets.chunkOrder = eventData.chunkOrder
191
192
  data.historySets.peerDataRequestSessionId = eventData.peerDataRequestSessionId
192
193
  data.historySets.isLatest = eventData.isLatest || data.historySets.isLatest
193
194
  break
@@ -483,6 +484,7 @@ function consolidateEvents(data) {
483
484
  syncType: data.historySets.syncType,
484
485
  progress: data.historySets.progress,
485
486
  isLatest: data.historySets.isLatest,
487
+ chunkOrder: data.historySets.chunkOrder,
486
488
  peerDataRequestSessionId: data.historySets.peerDataRequestSessionId
487
489
  }
488
490
  }
@@ -562,4 +564,4 @@ const stringifyMessageKey = (key) => `${key.remoteJid},${key.id},${key.fromMe ?
562
564
 
563
565
  module.exports = {
564
566
  makeEventBuffer
565
- }
567
+ }
@@ -507,6 +507,15 @@ const getCallStatusFromNode = ({ tag, attrs }) => {
507
507
  status = 'terminate'
508
508
  }
509
509
  break
510
+ case 'preaccept':
511
+ status = 'preaccept'
512
+ break
513
+ case 'transport':
514
+ status = 'transport'
515
+ break
516
+ case 'relaylatency':
517
+ status = 'relaylatency'
518
+ break
510
519
  case 'reject':
511
520
  status = 'reject'
512
521
  break