@mrlegendbot/baileys 1.2.1 → 1.2.4

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 (212) hide show
  1. package/README.upstream.md +1312 -0
  2. package/WAProto/WAProto.json +1 -0
  3. package/WAProto/WAProto.proto +6275 -0
  4. package/WAProto/compiler.js +550 -0
  5. package/WAProto/index.js +2 -97691
  6. package/lib/Defaults/index.js +89 -92
  7. package/lib/Signal/Group/ciphertext-message.js +9 -10
  8. package/lib/Signal/Group/group-session-builder.js +21 -22
  9. package/lib/Signal/Group/group_cipher.js +75 -69
  10. package/lib/Signal/Group/index.js +0 -1
  11. package/lib/Signal/Group/keyhelper.js +9 -10
  12. package/lib/Signal/Group/sender-chain-key.js +21 -22
  13. package/lib/Signal/Group/sender-key-distribution-message.js +51 -60
  14. package/lib/Signal/Group/sender-key-message.js +56 -62
  15. package/lib/Signal/Group/sender-key-name.js +38 -40
  16. package/lib/Signal/Group/sender-key-record.js +33 -34
  17. package/lib/Signal/Group/sender-key-state.js +72 -76
  18. package/lib/Signal/Group/sender-message-key.js +22 -23
  19. package/lib/Signal/libsignal.js +506 -405
  20. package/lib/Signal/lid-mapping.js +276 -258
  21. package/lib/Socket/Client/index.js +0 -1
  22. package/lib/Socket/Client/types.js +6 -7
  23. package/lib/Socket/Client/websocket.js +48 -49
  24. package/lib/Socket/business.js +349 -369
  25. package/lib/Socket/chats.js +1172 -1148
  26. package/lib/Socket/communities.js +473 -413
  27. package/lib/Socket/groups.js +387 -331
  28. package/lib/Socket/index.js +6 -8
  29. package/lib/Socket/messages-recv.js +1782 -1719
  30. package/lib/Socket/messages-send.js +1503 -2450
  31. package/lib/Socket/mex.js +40 -35
  32. package/lib/Socket/newsletter.js +239 -191
  33. package/lib/Socket/socket.js +992 -923
  34. package/lib/Store/index.js +8 -0
  35. package/lib/Store/keyed-db.js +108 -0
  36. package/lib/Store/make-cache-manager-store.js +70 -0
  37. package/lib/Store/make-in-memory-store.js +417 -0
  38. package/lib/Store/make-ordered-dictionary.js +69 -0
  39. package/lib/Store/object-repository.js +27 -0
  40. package/lib/Types/Auth.js +0 -1
  41. package/lib/Types/Bussines.js +0 -1
  42. package/lib/Types/Call.js +0 -1
  43. package/lib/Types/Chat.js +1 -8
  44. package/lib/Types/Contact.js +0 -1
  45. package/lib/Types/Events.js +1 -2
  46. package/lib/Types/GroupMetadata.js +0 -1
  47. package/lib/Types/Label.js +20 -22
  48. package/lib/Types/LabelAssociation.js +2 -4
  49. package/lib/Types/Message.js +3 -5
  50. package/lib/Types/Mex.js +26 -31
  51. package/lib/Types/Product.js +0 -1
  52. package/lib/Types/Signal.js +1 -2
  53. package/lib/Types/Socket.js +2 -3
  54. package/lib/Types/State.js +4 -52
  55. package/lib/Types/USync.js +0 -1
  56. package/lib/Types/index.js +10 -11
  57. package/lib/Utils/auth-utils.js +240 -277
  58. package/lib/Utils/browser-utils.js +20 -23
  59. package/lib/Utils/business.js +200 -204
  60. package/lib/Utils/chat-utils.js +836 -810
  61. package/lib/Utils/companion-reg-client-utils.js +23 -25
  62. package/lib/Utils/crypto.js +70 -86
  63. package/lib/Utils/decode-wa-message.js +277 -284
  64. package/lib/Utils/event-buffer.js +592 -595
  65. package/lib/Utils/generics.js +312 -335
  66. package/lib/Utils/history.js +123 -115
  67. package/lib/Utils/index.js +1 -2
  68. package/lib/Utils/link-preview.js +74 -73
  69. package/lib/Utils/logger.js +3 -2
  70. package/lib/Utils/lt-hash.js +0 -6
  71. package/lib/Utils/make-mutex.js +27 -27
  72. package/lib/Utils/message-retry-manager.js +213 -254
  73. package/lib/Utils/messages-media.js +741 -715
  74. package/lib/Utils/messages.js +791 -827
  75. package/lib/Utils/noise-handler.js +215 -187
  76. package/lib/Utils/pre-key-manager.js +69 -98
  77. package/lib/Utils/process-message.js +617 -586
  78. package/lib/Utils/reporting-utils.js +553 -234
  79. package/lib/Utils/signal.js +217 -170
  80. package/lib/Utils/stanza-ack.js +27 -35
  81. package/lib/Utils/sync-action-utils.js +37 -41
  82. package/lib/Utils/tc-token-utils.js +120 -141
  83. package/lib/Utils/use-multi-file-auth-state.js +87 -105
  84. package/lib/Utils/use-sqlite-auth-state.js +162 -0
  85. package/lib/Utils/validate-connection.js +190 -188
  86. package/lib/WABinary/constants.js +28 -1294
  87. package/lib/WABinary/decode.js +245 -249
  88. package/lib/WABinary/encode.js +201 -206
  89. package/lib/WABinary/generic-utils.js +86 -89
  90. package/lib/WABinary/index.js +0 -1
  91. package/lib/WABinary/jid-utils.js +68 -77
  92. package/lib/WABinary/types.js +0 -1
  93. package/lib/WAM/BinaryInfo.js +7 -8
  94. package/lib/WAM/constants.js +19892 -22853
  95. package/lib/WAM/encode.js +121 -132
  96. package/lib/WAM/index.js +0 -1
  97. package/lib/WAUSync/Protocols/USyncContactProtocol.js +46 -43
  98. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +47 -48
  99. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +22 -23
  100. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +30 -33
  101. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +19 -20
  102. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +53 -44
  103. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +24 -24
  104. package/lib/WAUSync/Protocols/index.js +0 -1
  105. package/lib/WAUSync/USyncQuery.js +79 -88
  106. package/lib/WAUSync/USyncUser.js +28 -29
  107. package/lib/WAUSync/index.js +0 -1
  108. package/lib/index.js +2 -2
  109. package/package.json +22 -86
  110. package/WAProto/GenerateStatics.sh +0 -3
  111. package/WAProto/fix-imports.js +0 -85
  112. package/WAProto/index.d.ts +0 -14017
  113. package/lib/Defaults/index.d.ts +0 -75
  114. package/lib/Signal/Group/ciphertext-message.d.ts +0 -10
  115. package/lib/Signal/Group/group-session-builder.d.ts +0 -15
  116. package/lib/Signal/Group/group_cipher.d.ts +0 -17
  117. package/lib/Signal/Group/index.d.ts +0 -12
  118. package/lib/Signal/Group/keyhelper.d.ts +0 -11
  119. package/lib/Signal/Group/sender-chain-key.d.ts +0 -14
  120. package/lib/Signal/Group/sender-key-distribution-message.d.ts +0 -17
  121. package/lib/Signal/Group/sender-key-message.d.ts +0 -19
  122. package/lib/Signal/Group/sender-key-name.d.ts +0 -18
  123. package/lib/Signal/Group/sender-key-record.d.ts +0 -31
  124. package/lib/Signal/Group/sender-key-state.d.ts +0 -39
  125. package/lib/Signal/Group/sender-message-key.d.ts +0 -12
  126. package/lib/Signal/libsignal.d.ts +0 -5
  127. package/lib/Signal/lid-mapping.d.ts +0 -23
  128. package/lib/Socket/Client/index.d.ts +0 -3
  129. package/lib/Socket/Client/types.d.ts +0 -16
  130. package/lib/Socket/Client/websocket.d.ts +0 -13
  131. package/lib/Socket/business.d.ts +0 -217
  132. package/lib/Socket/chats.d.ts +0 -125
  133. package/lib/Socket/communities.d.ts +0 -273
  134. package/lib/Socket/groups.d.ts +0 -161
  135. package/lib/Socket/index.d.ts +0 -260
  136. package/lib/Socket/messages-recv.d.ts +0 -203
  137. package/lib/Socket/messages-send.d.ts +0 -199
  138. package/lib/Socket/mex.d.ts +0 -3
  139. package/lib/Socket/newsletter.d.ts +0 -170
  140. package/lib/Socket/socket.d.ts +0 -59
  141. package/lib/Types/Auth.d.ts +0 -117
  142. package/lib/Types/Bussines.d.ts +0 -25
  143. package/lib/Types/Call.d.ts +0 -15
  144. package/lib/Types/Chat.d.ts +0 -124
  145. package/lib/Types/Contact.d.ts +0 -26
  146. package/lib/Types/Events.d.ts +0 -256
  147. package/lib/Types/GroupMetadata.d.ts +0 -71
  148. package/lib/Types/Label.d.ts +0 -47
  149. package/lib/Types/LabelAssociation.d.ts +0 -30
  150. package/lib/Types/Message.d.ts +0 -320
  151. package/lib/Types/Mex.d.ts +0 -141
  152. package/lib/Types/Product.d.ts +0 -79
  153. package/lib/Types/Signal.d.ts +0 -87
  154. package/lib/Types/Socket.d.ts +0 -136
  155. package/lib/Types/State.d.ts +0 -97
  156. package/lib/Types/USync.d.ts +0 -26
  157. package/lib/Types/index.d.ts +0 -66
  158. package/lib/Utils/auth-utils.d.ts +0 -24
  159. package/lib/Utils/browser-utils.d.ts +0 -4
  160. package/lib/Utils/business.d.ts +0 -23
  161. package/lib/Utils/chat-utils.d.ts +0 -100
  162. package/lib/Utils/companion-reg-client-utils.d.ts +0 -17
  163. package/lib/Utils/crypto.d.ts +0 -37
  164. package/lib/Utils/decode-wa-message.d.ts +0 -66
  165. package/lib/Utils/event-buffer.d.ts +0 -36
  166. package/lib/Utils/generics.d.ts +0 -92
  167. package/lib/Utils/history.d.ts +0 -24
  168. package/lib/Utils/identity-change-handler.d.ts +0 -44
  169. package/lib/Utils/identity-change-handler.js +0 -50
  170. package/lib/Utils/index.d.ts +0 -22
  171. package/lib/Utils/link-preview.d.ts +0 -21
  172. package/lib/Utils/logger.d.ts +0 -12
  173. package/lib/Utils/lt-hash.d.ts +0 -8
  174. package/lib/Utils/make-mutex.d.ts +0 -9
  175. package/lib/Utils/message-retry-manager.d.ts +0 -115
  176. package/lib/Utils/messages-media.d.ts +0 -133
  177. package/lib/Utils/messages.d.ts +0 -91
  178. package/lib/Utils/noise-handler.d.ts +0 -20
  179. package/lib/Utils/offline-node-processor.d.ts +0 -17
  180. package/lib/Utils/offline-node-processor.js +0 -40
  181. package/lib/Utils/pre-key-manager.d.ts +0 -28
  182. package/lib/Utils/process-message.d.ts +0 -60
  183. package/lib/Utils/reporting-utils.d.ts +0 -11
  184. package/lib/Utils/signal.d.ts +0 -47
  185. package/lib/Utils/stanza-ack.d.ts +0 -11
  186. package/lib/Utils/sync-action-utils.d.ts +0 -19
  187. package/lib/Utils/tc-token-utils.d.ts +0 -37
  188. package/lib/Utils/use-multi-file-auth-state.d.ts +0 -13
  189. package/lib/Utils/validate-connection.d.ts +0 -11
  190. package/lib/WABinary/constants.d.ts +0 -28
  191. package/lib/WABinary/decode.d.ts +0 -7
  192. package/lib/WABinary/encode.d.ts +0 -3
  193. package/lib/WABinary/generic-utils.d.ts +0 -15
  194. package/lib/WABinary/index.d.ts +0 -6
  195. package/lib/WABinary/jid-utils.d.ts +0 -48
  196. package/lib/WABinary/types.d.ts +0 -19
  197. package/lib/WAM/BinaryInfo.d.ts +0 -9
  198. package/lib/WAM/constants.d.ts +0 -40
  199. package/lib/WAM/encode.d.ts +0 -3
  200. package/lib/WAM/index.d.ts +0 -4
  201. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -10
  202. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -23
  203. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -13
  204. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -13
  205. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +0 -10
  206. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +0 -26
  207. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +0 -10
  208. package/lib/WAUSync/Protocols/index.d.ts +0 -6
  209. package/lib/WAUSync/USyncQuery.d.ts +0 -30
  210. package/lib/WAUSync/USyncUser.d.ts +0 -17
  211. package/lib/WAUSync/index.d.ts +0 -4
  212. package/lib/index.d.ts +0 -12
@@ -1,317 +1,310 @@
1
1
  import { Boom } from '@hapi/boom';
2
- import { proto } from '../../WAProto/index.js';
3
- import { areJidsSameUser, isHostedLidUser, isHostedPnUser, isJidBroadcast, isJidGroup, isJidMetaAI, isJidNewsletter, isJidStatusBroadcast, isLidUser, isPnUser
4
- // transferDevice
5
- } from '../WABinary/index.js';
2
+ import { proto } from '../../WAProto/compiler.js';
3
+ import { areJidsSameUser, isHostedLidUser, isHostedPnUser, isJidBroadcast, isJidGroup, isJidNewsletter, isJidStatusBroadcast, isLidUser, isPnUser } from '../WABinary/index.js';
6
4
  import { unpadRandomMax16 } from './generics.js';
7
5
  export const getDecryptionJid = async (sender, repository) => {
8
- if (isLidUser(sender) || isHostedLidUser(sender)) {
9
- return sender;
10
- }
11
- const mapped = await repository.lidMapping.getLIDForPN(sender);
12
- return mapped || sender;
6
+ if (isLidUser(sender) || isHostedLidUser(sender)) {
7
+ return sender;
8
+ }
9
+ const mapped = await repository.lidMapping.getLIDForPN(sender);
10
+ return mapped || sender;
13
11
  };
14
12
  const storeMappingFromEnvelope = async (stanza, sender, repository, decryptionJid, logger) => {
15
- // TODO: Handle hosted IDs
16
- const { senderAlt } = extractAddressingContext(stanza);
17
- if (senderAlt && isLidUser(senderAlt) && isPnUser(sender) && decryptionJid === sender) {
18
- try {
19
- await repository.lidMapping.storeLIDPNMappings([{ lid: senderAlt, pn: sender }]);
20
- await repository.migrateSession(sender, senderAlt);
21
- logger.debug({ sender, senderAlt }, 'Stored LID mapping from envelope');
22
- }
23
- catch (error) {
24
- logger.warn({ sender, senderAlt, error }, 'Failed to store LID mapping');
25
- }
13
+ const {
14
+ senderAlt
15
+ } = extractAddressingContext(stanza);
16
+ if (senderAlt && isLidUser(senderAlt) && isPnUser(sender) && decryptionJid === sender) {
17
+ try {
18
+ await repository.lidMapping.storeLIDPNMappings([{
19
+ lid: senderAlt,
20
+ pn: sender
21
+ }]);
22
+ await repository.migrateSession(sender, senderAlt);
23
+ logger.debug({
24
+ sender,
25
+ senderAlt
26
+ }, 'Stored LID mapping from envelope');
27
+ } catch (error) {
28
+ logger.warn({
29
+ sender,
30
+ senderAlt,
31
+ error
32
+ }, 'Failed to store LID mapping');
26
33
  }
34
+ }
27
35
  };
28
36
  export const NO_MESSAGE_FOUND_ERROR_TEXT = 'Message absent from node';
29
37
  export const MISSING_KEYS_ERROR_TEXT = 'Key used already or never filled';
30
38
  export const ACCOUNT_RESTRICTED_TEXT = 'Your account has been restricted';
31
- // Retry configuration for failed decryption
32
39
  export const DECRYPTION_RETRY_CONFIG = {
33
- maxRetries: 3,
34
- baseDelayMs: 100,
35
- sessionRecordErrors: ['No session record', 'SessionError: No session record']
40
+ maxRetries: 3,
41
+ baseDelayMs: 100,
42
+ sessionRecordErrors: ['No session record', 'SessionError: No session record']
36
43
  };
37
- /** NACK reason codes we send to the server (client → server) */
38
44
  export const NACK_REASONS = {
39
- SenderReachoutTimelocked: 463,
40
- ParsingError: 487,
41
- UnrecognizedStanza: 488,
42
- UnrecognizedStanzaClass: 489,
43
- UnrecognizedStanzaType: 490,
44
- InvalidProtobuf: 491,
45
- InvalidHostedCompanionStanza: 493,
46
- MissingMessageSecret: 495,
47
- SignalErrorOldCounter: 496,
48
- MessageDeletedOnPeer: 499,
49
- UnhandledError: 500,
50
- UnsupportedAdminRevoke: 550,
51
- UnsupportedLIDGroup: 551,
52
- DBOperationFailed: 552
45
+ SenderReachoutTimelocked: 463,
46
+ ParsingError: 487,
47
+ UnrecognizedStanza: 488,
48
+ UnrecognizedStanzaClass: 489,
49
+ UnrecognizedStanzaType: 490,
50
+ InvalidProtobuf: 491,
51
+ InvalidHostedCompanionStanza: 493,
52
+ MissingMessageSecret: 495,
53
+ SignalErrorOldCounter: 496,
54
+ MessageDeletedOnPeer: 499,
55
+ UnhandledError: 500,
56
+ UnsupportedAdminRevoke: 550,
57
+ UnsupportedLIDGroup: 551,
58
+ DBOperationFailed: 552
53
59
  };
54
- /**
55
- * Server-side error codes returned in ack stanzas (server → client) that we
56
- * currently have dedicated handlers for. Extend as more handlers are added.
57
- * Distinct from the client-side NackReason enum (WAWebCreateNackFromStanza).
58
- */
59
60
  export const SERVER_ERROR_CODES = {
60
- /**
61
- * 1:1 message missing privacy token (tctoken). Usually means the account is
62
- * restricted: WhatsApp blocks starting new chats but preserves existing ones,
63
- * since established chats already carry a tctoken.
64
- */
65
- MessageAccountRestriction: '463',
66
- /** Stanza validation failure (SMAX_INVALID) — likely stale device session */
67
- SmaxInvalid: '479'
61
+ MessageAccountRestriction: '463',
62
+ SmaxInvalid: '479'
68
63
  };
69
- export const extractAddressingContext = (stanza) => {
70
- let senderAlt;
71
- let recipientAlt;
72
- const sender = stanza.attrs.participant || stanza.attrs.from;
73
- const addressingMode = stanza.attrs.addressing_mode || (sender?.endsWith('lid') ? 'lid' : 'pn');
74
- if (addressingMode === 'lid') {
75
- // Message is LID-addressed: sender is LID, extract corresponding PN
76
- // without device data
77
- senderAlt = stanza.attrs.participant_pn || stanza.attrs.sender_pn || stanza.attrs.peer_recipient_pn;
78
- recipientAlt = stanza.attrs.recipient_pn;
79
- // with device data
80
- //if (sender && senderAlt) senderAlt = transferDevice(sender, senderAlt)
81
- }
82
- else {
83
- // Message is PN-addressed: sender is PN, extract corresponding LID
84
- // without device data
85
- senderAlt = stanza.attrs.participant_lid || stanza.attrs.sender_lid || stanza.attrs.peer_recipient_lid;
86
- recipientAlt = stanza.attrs.recipient_lid;
87
- //with device data
88
- //if (sender && senderAlt) senderAlt = transferDevice(sender, senderAlt)
89
- }
90
- return {
91
- addressingMode,
92
- senderAlt,
93
- recipientAlt
94
- };
64
+ export const extractAddressingContext = stanza => {
65
+ let senderAlt;
66
+ let recipientAlt;
67
+ const sender = stanza.attrs.participant || stanza.attrs.from;
68
+ const addressingMode = stanza.attrs.addressing_mode || (sender?.endsWith('lid') ? 'lid' : 'pn');
69
+ if (addressingMode === 'lid') {
70
+ senderAlt = stanza.attrs.participant_pn || stanza.attrs.sender_pn || stanza.attrs.peer_recipient_pn;
71
+ recipientAlt = stanza.attrs.recipient_pn;
72
+ } else {
73
+ senderAlt = stanza.attrs.participant_lid || stanza.attrs.sender_lid || stanza.attrs.peer_recipient_lid;
74
+ recipientAlt = stanza.attrs.recipient_lid;
75
+ }
76
+ return {
77
+ addressingMode,
78
+ senderAlt,
79
+ recipientAlt
80
+ };
95
81
  };
96
- /**
97
- * Decode the received node as a message.
98
- * @note this will only parse the message, not decrypt it
99
- */
100
82
  export function decodeMessageNode(stanza, meId, meLid) {
101
- let msgType;
102
- let chatId;
103
- let author;
104
- let fromMe = false;
105
- const msgId = stanza.attrs.id;
106
- const from = stanza.attrs.from;
107
- const participant = stanza.attrs.participant;
108
- const recipient = stanza.attrs.recipient;
109
- if (!msgId) {
110
- throw new Boom('Invalid message stanza: missing id attribute', { data: stanza });
83
+ let msgType;
84
+ let chatId;
85
+ let author;
86
+ let fromMe = false;
87
+ const msgId = stanza.attrs.id;
88
+ const from = stanza.attrs.from;
89
+ const participant = stanza.attrs.participant;
90
+ const recipient = stanza.attrs.recipient;
91
+ if (!msgId) {
92
+ throw new Boom('Invalid message stanza: missing id attribute', {
93
+ data: stanza
94
+ });
95
+ }
96
+ if (!from) {
97
+ throw new Boom('Invalid message stanza: missing from attribute', {
98
+ data: stanza
99
+ });
100
+ }
101
+ const addressingContext = extractAddressingContext(stanza);
102
+ const isMe = jid => areJidsSameUser(jid, meId);
103
+ const isMeLid = jid => areJidsSameUser(jid, meLid);
104
+ if (isPnUser(from) || isLidUser(from) || isHostedLidUser(from) || isHostedPnUser(from)) {
105
+ if (recipient) {
106
+ if (!isMe(from) && !isMeLid(from)) {
107
+ throw new Boom('receipient present, but msg not from me', {
108
+ data: stanza
109
+ });
110
+ }
111
+ if (isMe(from) || isMeLid(from)) {
112
+ fromMe = true;
113
+ }
114
+ chatId = recipient;
115
+ } else {
116
+ if (isMe(from) || isMeLid(from)) {
117
+ fromMe = true;
118
+ }
119
+ chatId = from;
111
120
  }
112
- if (!from) {
113
- throw new Boom('Invalid message stanza: missing from attribute', { data: stanza });
121
+ msgType = 'chat';
122
+ author = from;
123
+ } else if (isJidGroup(from)) {
124
+ if (!participant) {
125
+ throw new Boom('No participant in group message');
114
126
  }
115
- const addressingContext = extractAddressingContext(stanza);
116
- const isMe = (jid) => areJidsSameUser(jid, meId);
117
- const isMeLid = (jid) => areJidsSameUser(jid, meLid);
118
- if (isPnUser(from) || isLidUser(from) || isHostedLidUser(from) || isHostedPnUser(from)) {
119
- if (recipient && !isJidMetaAI(recipient)) {
120
- if (!isMe(from) && !isMeLid(from)) {
121
- throw new Boom('receipient present, but msg not from me', { data: stanza });
122
- }
123
- if (isMe(from) || isMeLid(from)) {
124
- fromMe = true;
125
- }
126
- chatId = recipient;
127
- }
128
- else {
129
- // Peer-routed self stanzas (history sync, app-state sync, etc.) arrive
130
- // with `from` set to our own device but no `recipient` attribute —
131
- // still mark as fromMe so self-only protocolMessage handlers run.
132
- if (isMe(from) || isMeLid(from)) {
133
- fromMe = true;
134
- }
135
- chatId = from;
136
- }
137
- msgType = 'chat';
138
- author = from;
127
+ if (isMe(participant) || isMeLid(participant)) {
128
+ fromMe = true;
139
129
  }
140
- else if (isJidGroup(from)) {
141
- if (!participant) {
142
- throw new Boom('No participant in group message');
143
- }
144
- if (isMe(participant) || isMeLid(participant)) {
145
- fromMe = true;
146
- }
147
- msgType = 'group';
148
- author = participant;
149
- chatId = from;
130
+ msgType = 'group';
131
+ author = participant;
132
+ chatId = from;
133
+ } else if (isJidBroadcast(from)) {
134
+ if (!participant) {
135
+ throw new Boom('No participant in group message');
150
136
  }
151
- else if (isJidBroadcast(from)) {
152
- if (!participant) {
153
- throw new Boom('No participant in group message');
154
- }
155
- const isParticipantMe = isMe(participant);
156
- if (isJidStatusBroadcast(from)) {
157
- msgType = isParticipantMe ? 'direct_peer_status' : 'other_status';
158
- }
159
- else {
160
- msgType = isParticipantMe ? 'peer_broadcast' : 'other_broadcast';
161
- }
162
- fromMe = isParticipantMe;
163
- chatId = from;
164
- author = participant;
137
+ const isParticipantMe = isMe(participant);
138
+ if (isJidStatusBroadcast(from)) {
139
+ msgType = isParticipantMe ? 'direct_peer_status' : 'other_status';
140
+ } else {
141
+ msgType = isParticipantMe ? 'peer_broadcast' : 'other_broadcast';
165
142
  }
166
- else if (isJidNewsletter(from)) {
167
- msgType = 'newsletter';
168
- chatId = from;
169
- author = from;
170
- if (isMe(from) || isMeLid(from)) {
171
- fromMe = true;
172
- }
143
+ fromMe = isParticipantMe;
144
+ chatId = from;
145
+ author = participant;
146
+ } else if (isJidNewsletter(from)) {
147
+ msgType = 'newsletter';
148
+ chatId = from;
149
+ author = from;
150
+ if (stanza.attrs.is_sender) {
151
+ fromMe = true;
173
152
  }
174
- else {
175
- throw new Boom('Unknown message type', { data: stanza });
153
+ if (isMe(from) || isMeLid(from)) {
154
+ fromMe = true;
176
155
  }
177
- const pushname = stanza?.attrs?.notify;
178
- const key = {
179
- remoteJid: chatId,
180
- remoteJidAlt: !isJidGroup(chatId) ? addressingContext.senderAlt : undefined,
181
- remoteJidUsername: !isJidGroup(chatId)
182
- ? stanza.attrs.peer_recipient_username || stanza.attrs.recipient_username
183
- : undefined,
184
- fromMe,
185
- id: msgId,
186
- participant,
187
- participantAlt: isJidGroup(chatId) ? addressingContext.senderAlt : undefined,
188
- participantUsername: stanza.attrs.participant ? stanza.attrs.participant_username : undefined,
189
- addressingMode: addressingContext.addressingMode,
190
- ...(msgType === 'newsletter' && stanza.attrs.server_id ? { server_id: stanza.attrs.server_id } : {})
191
- };
192
- const fullMessage = {
193
- key,
194
- category: stanza.attrs.category,
195
- messageTimestamp: +stanza.attrs.t,
196
- pushName: pushname,
197
- broadcast: isJidBroadcast(from)
198
- };
199
- if (key.fromMe) {
200
- fullMessage.status = proto.WebMessageInfo.Status.SERVER_ACK;
201
- }
202
- return {
203
- fullMessage,
204
- author,
205
- sender: msgType === 'chat' ? author : chatId
206
- };
156
+ } else {
157
+ throw new Boom('Unknown message type', {
158
+ data: stanza
159
+ });
160
+ }
161
+ const pushname = stanza?.attrs?.notify;
162
+ const key = {
163
+ remoteJid: chatId,
164
+ remoteJidAlt: !isJidGroup(chatId) ? addressingContext.senderAlt : undefined,
165
+ remoteJidUsername: !isJidGroup(chatId) ? stanza.attrs.peer_recipient_username || stanza.attrs.recipient_username : undefined,
166
+ fromMe,
167
+ id: msgId,
168
+ participant,
169
+ participantAlt: isJidGroup(chatId) ? addressingContext.senderAlt : undefined,
170
+ participantUsername: stanza.attrs.participant ? stanza.attrs.participant_username : undefined,
171
+ addressingMode: addressingContext.addressingMode,
172
+ ...(msgType === 'newsletter' && stanza.attrs.server_id ? {
173
+ server_id: stanza.attrs.server_id
174
+ } : {})
175
+ };
176
+ const fullMessage = {
177
+ key,
178
+ category: stanza.attrs.category,
179
+ messageTimestamp: +stanza.attrs.t,
180
+ pushName: pushname,
181
+ broadcast: isJidBroadcast(from)
182
+ };
183
+ if (key.fromMe) {
184
+ fullMessage.status = proto.WebMessageInfo.Status.SERVER_ACK;
185
+ }
186
+ return {
187
+ fullMessage,
188
+ author,
189
+ sender: msgType === 'chat' ? author : chatId
190
+ };
207
191
  }
208
192
  export const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
209
- const { fullMessage, author, sender } = decodeMessageNode(stanza, meId, meLid);
210
- return {
211
- fullMessage,
212
- category: stanza.attrs.category,
213
- author,
214
- async decrypt() {
215
- let decryptables = 0;
216
- if (Array.isArray(stanza.content)) {
217
- for (const { tag, attrs, content } of stanza.content) {
218
- if (tag === 'verified_name' && content instanceof Uint8Array) {
219
- const cert = proto.VerifiedNameCertificate.decode(content);
220
- const details = proto.VerifiedNameCertificate.Details.decode(cert.details);
221
- fullMessage.verifiedBizName = details.verifiedName;
222
- }
223
- if (tag === 'unavailable' && attrs.type === 'view_once') {
224
- fullMessage.key.isViewOnce = true; // TODO: remove from here and add a STUB TYPE
225
- }
226
- if (attrs.count && tag === 'enc') {
227
- fullMessage.retryCount = Number(attrs.count);
228
- }
229
- if (tag !== 'enc' && tag !== 'plaintext') {
230
- continue;
231
- }
232
- if (!(content instanceof Uint8Array)) {
233
- continue;
234
- }
235
- decryptables += 1;
236
- let msgBuffer;
237
- const decryptionJid = await getDecryptionJid(author, repository);
238
- if (tag !== 'plaintext') {
239
- // TODO: Handle hosted devices
240
- await storeMappingFromEnvelope(stanza, author, repository, decryptionJid, logger);
241
- }
242
- try {
243
- const e2eType = tag === 'plaintext' ? 'plaintext' : attrs.type;
244
- switch (e2eType) {
245
- case 'skmsg':
246
- msgBuffer = await repository.decryptGroupMessage({
247
- group: sender,
248
- authorJid: author,
249
- msg: content
250
- });
251
- break;
252
- case 'pkmsg':
253
- case 'msg':
254
- msgBuffer = await repository.decryptMessage({
255
- jid: decryptionJid,
256
- type: e2eType,
257
- ciphertext: content
258
- });
259
- break;
260
- case 'plaintext':
261
- msgBuffer = content;
262
- break;
263
- default:
264
- throw new Error(`Unknown e2e type: ${e2eType}`);
265
- }
266
- let msg = proto.Message.decode(e2eType !== 'plaintext' ? unpadRandomMax16(msgBuffer) : msgBuffer);
267
- msg = msg.deviceSentMessage?.message || msg;
268
- if (msg.senderKeyDistributionMessage) {
269
- //eslint-disable-next-line max-depth
270
- try {
271
- await repository.processSenderKeyDistributionMessage({
272
- authorJid: author,
273
- item: msg.senderKeyDistributionMessage
274
- });
275
- }
276
- catch (err) {
277
- logger.error({ key: fullMessage.key, err }, 'failed to process sender key distribution message');
278
- }
279
- }
280
- if (fullMessage.message) {
281
- Object.assign(fullMessage.message, msg);
282
- }
283
- else {
284
- fullMessage.message = msg;
285
- }
286
- }
287
- catch (err) {
288
- const errorContext = {
289
- key: fullMessage.key,
290
- err,
291
- messageType: tag === 'plaintext' ? 'plaintext' : attrs.type,
292
- sender,
293
- author,
294
- isSessionRecordError: isSessionRecordError(err)
295
- };
296
- logger.error(errorContext, 'failed to decrypt message');
297
- fullMessage.messageStubType = proto.WebMessageInfo.StubType.CIPHERTEXT;
298
- fullMessage.messageStubParameters = [err.message.toString()];
299
- }
300
- }
193
+ const {
194
+ fullMessage,
195
+ author,
196
+ sender
197
+ } = decodeMessageNode(stanza, meId, meLid);
198
+ return {
199
+ fullMessage,
200
+ category: stanza.attrs.category,
201
+ author,
202
+ async decrypt() {
203
+ let decryptables = 0;
204
+ if (Array.isArray(stanza.content)) {
205
+ for (const {
206
+ tag,
207
+ attrs,
208
+ content
209
+ } of stanza.content) {
210
+ if (tag === 'verified_name' && content instanceof Uint8Array) {
211
+ const cert = proto.VerifiedNameCertificate.decode(content);
212
+ const details = proto.VerifiedNameCertificate.Details.decode(cert.details);
213
+ fullMessage.verifiedBizName = details.verifiedName;
214
+ }
215
+ if (tag === 'unavailable' && attrs.type === 'view_once') {
216
+ fullMessage.key.isViewOnce = true;
217
+ }
218
+ if (attrs.count && tag === 'enc') {
219
+ fullMessage.retryCount = Number(attrs.count);
220
+ }
221
+ if (tag !== 'enc' && tag !== 'plaintext') {
222
+ continue;
223
+ }
224
+ if (!(content instanceof Uint8Array)) {
225
+ continue;
226
+ }
227
+ decryptables += 1;
228
+ let msgBuffer;
229
+ const decryptionJid = await getDecryptionJid(author, repository);
230
+ if (tag !== 'plaintext') {
231
+ await storeMappingFromEnvelope(stanza, author, repository, decryptionJid, logger);
232
+ }
233
+ try {
234
+ const e2eType = tag === 'plaintext' ? 'plaintext' : attrs.type;
235
+ switch (e2eType) {
236
+ case 'skmsg':
237
+ msgBuffer = await repository.decryptGroupMessage({
238
+ group: sender,
239
+ authorJid: author,
240
+ msg: content
241
+ });
242
+ break;
243
+ case 'pkmsg':
244
+ case 'msg':
245
+ msgBuffer = await repository.decryptMessage({
246
+ jid: decryptionJid,
247
+ type: e2eType,
248
+ ciphertext: content
249
+ });
250
+ break;
251
+ case 'plaintext':
252
+ msgBuffer = content;
253
+ break;
254
+ default:
255
+ throw new Error(`Unknown e2e type: ${e2eType}`);
256
+ }
257
+ if (!msgBuffer) {
258
+ continue;
259
+ }
260
+ const msgToDecode = e2eType !== 'plaintext' ? unpadRandomMax16(msgBuffer) : msgBuffer;
261
+ let msg = proto.Message.decode(msgToDecode);
262
+ const outerMessageContextInfo = msg.messageContextInfo;
263
+ msg = msg.deviceSentMessage?.message || msg;
264
+ if (outerMessageContextInfo && !msg.messageContextInfo) {
265
+ msg.messageContextInfo = outerMessageContextInfo;
301
266
  }
302
- // if nothing was found to decrypt
303
- if (!decryptables && !fullMessage.key?.isViewOnce) {
304
- fullMessage.messageStubType = proto.WebMessageInfo.StubType.CIPHERTEXT;
305
- fullMessage.messageStubParameters = [NO_MESSAGE_FOUND_ERROR_TEXT];
267
+ if (msg.senderKeyDistributionMessage) {
268
+ try {
269
+ await repository.processSenderKeyDistributionMessage({
270
+ authorJid: author,
271
+ item: msg.senderKeyDistributionMessage
272
+ });
273
+ } catch (err) {
274
+ logger.error({
275
+ key: fullMessage.key,
276
+ err
277
+ }, 'failed to process sender key distribution message');
278
+ }
306
279
  }
280
+ if (fullMessage.message) {
281
+ Object.assign(fullMessage.message, msg);
282
+ } else {
283
+ fullMessage.message = msg;
284
+ }
285
+ } catch (err) {
286
+ const errorContext = {
287
+ key: fullMessage.key,
288
+ err,
289
+ messageType: tag === 'plaintext' ? 'plaintext' : attrs.type,
290
+ sender,
291
+ author,
292
+ isSessionRecordError: isSessionRecordError(err)
293
+ };
294
+ logger.error(errorContext, 'failed to decrypt message');
295
+ fullMessage.messageStubType = proto.WebMessageInfo.StubType.CIPHERTEXT;
296
+ fullMessage.messageStubParameters = [err.message.toString()];
297
+ }
307
298
  }
308
- };
299
+ }
300
+ if (!decryptables && !fullMessage.key?.isViewOnce) {
301
+ fullMessage.messageStubType = proto.WebMessageInfo.StubType.CIPHERTEXT;
302
+ fullMessage.messageStubParameters = [NO_MESSAGE_FOUND_ERROR_TEXT];
303
+ }
304
+ }
305
+ };
309
306
  };
310
- /**
311
- * Utility function to check if an error is related to missing session record
312
- */
313
307
  function isSessionRecordError(error) {
314
- const errorMessage = error?.message || error?.toString() || '';
315
- return DECRYPTION_RETRY_CONFIG.sessionRecordErrors.some(errorPattern => errorMessage.includes(errorPattern));
308
+ const errorMessage = error?.message || error?.toString() || '';
309
+ return DECRYPTION_RETRY_CONFIG.sessionRecordErrors.some(errorPattern => errorMessage.includes(errorPattern));
316
310
  }
317
- //# sourceMappingURL=decode-wa-message.js.map