@pontalabs/baileys 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +839 -267
- package/WAProto/GenerateStatics.sh +4 -3
- package/WAProto/WAProto.proto +511 -1215
- package/WAProto/index.d.ts +55 -14017
- package/WAProto/index.js +29 -97689
- package/lib/Defaults/index.d.ts +74 -72
- package/lib/Defaults/index.js +108 -94
- package/lib/Signal/Group/ciphertext-message.d.ts +7 -8
- package/lib/Signal/Group/ciphertext-message.js +16 -9
- package/lib/Signal/Group/group-session-builder.d.ts +13 -11
- package/lib/Signal/Group/group-session-builder.js +61 -19
- package/lib/Signal/Group/group_cipher.d.ts +16 -14
- package/lib/Signal/Group/group_cipher.js +70 -41
- package/lib/Signal/Group/index.d.ts +11 -12
- package/lib/Signal/Group/index.js +61 -12
- package/lib/Signal/Group/keyhelper.d.ts +14 -9
- package/lib/Signal/Group/keyhelper.js +58 -10
- package/lib/Signal/Group/sender-chain-key.d.ts +13 -13
- package/lib/Signal/Group/sender-chain-key.js +34 -13
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -16
- package/lib/Signal/Group/sender-key-distribution-message.js +36 -28
- package/lib/Signal/Group/sender-key-message.d.ts +18 -18
- package/lib/Signal/Group/sender-key-message.js +45 -38
- package/lib/Signal/Group/sender-key-name.d.ts +15 -14
- package/lib/Signal/Group/sender-key-name.js +31 -20
- package/lib/Signal/Group/sender-key-record.d.ts +25 -24
- package/lib/Signal/Group/sender-key-record.js +35 -18
- package/lib/Signal/Group/sender-key-state.d.ts +34 -29
- package/lib/Signal/Group/sender-key-state.js +100 -37
- package/lib/Signal/Group/sender-message-key.d.ts +10 -11
- package/lib/Signal/Group/sender-message-key.js +22 -15
- package/lib/Signal/libsignal.d.ts +8 -5
- package/lib/Signal/libsignal.js +142 -288
- package/lib/Signal/lid-mapping.d.ts +28 -23
- package/lib/Signal/lid-mapping.js +184 -277
- package/lib/Socket/Client/index.d.ts +2 -3
- package/lib/Socket/Client/index.js +22 -3
- package/lib/Socket/Client/types.d.ts +15 -15
- package/lib/Socket/Client/types.js +15 -8
- package/lib/Socket/Client/websocket.d.ts +12 -12
- package/lib/Socket/Client/websocket.js +37 -29
- package/lib/Socket/business.d.ts +178 -208
- package/lib/Socket/business.js +127 -91
- package/lib/Socket/chats.d.ts +93 -120
- package/lib/Socket/chats.js +652 -727
- package/lib/Socket/community.js +10 -2
- package/lib/Socket/groups.d.ts +111 -143
- package/lib/Socket/groups.js +186 -165
- package/lib/Socket/index.d.ts +183 -252
- package/lib/Socket/index.js +18 -38
- package/lib/Socket/messages-recv.d.ts +167 -196
- package/lib/Socket/messages-recv.js +1567 -1443
- package/lib/Socket/messages-send.d.ts +158 -192
- package/lib/Socket/messages-send.js +1208 -1102
- package/lib/Socket/newsletter.d.ts +138 -163
- package/lib/Socket/newsletter.js +249 -153
- package/lib/Socket/socket.d.ts +36 -50
- package/lib/Socket/socket.js +820 -749
- package/lib/Store/index.d.ts +4 -4
- package/lib/Store/index.js +24 -4
- package/lib/Store/make-in-memory-store.d.ts +104 -44
- package/lib/Store/make-in-memory-store.js +213 -199
- package/lib/Store/make-ordered-dictionary.d.ts +12 -13
- package/lib/Store/make-ordered-dictionary.js +45 -38
- package/lib/Store/object-repository.d.ts +10 -11
- package/lib/Store/object-repository.js +16 -9
- package/lib/Types/Auth.d.ts +97 -93
- package/lib/Types/Auth.js +3 -2
- package/lib/Types/Bussines.js +3 -2
- package/lib/Types/Call.d.ts +13 -14
- package/lib/Types/Call.js +3 -2
- package/lib/Types/Chat.d.ts +97 -78
- package/lib/Types/Chat.js +9 -8
- package/lib/Types/Contact.d.ts +9 -12
- package/lib/Types/Contact.js +3 -2
- package/lib/Types/Events.d.ts +176 -206
- package/lib/Types/Events.js +3 -2
- package/lib/Types/GroupMetadata.d.ts +48 -53
- package/lib/Types/GroupMetadata.js +3 -2
- package/lib/Types/Label.d.ts +14 -13
- package/lib/Types/Label.js +30 -24
- package/lib/Types/LabelAssociation.d.ts +20 -15
- package/lib/Types/LabelAssociation.js +12 -6
- package/lib/Types/Message.d.ts +412 -248
- package/lib/Types/Message.js +19 -17
- package/lib/Types/Product.d.ts +71 -58
- package/lib/Types/Product.js +3 -2
- package/lib/Types/Signal.d.ts +82 -71
- package/lib/Types/Signal.js +3 -2
- package/lib/Types/Socket.d.ts +81 -76
- package/lib/Types/Socket.js +3 -3
- package/lib/Types/State.d.ts +19 -75
- package/lib/Types/State.js +14 -56
- package/lib/Types/USync.d.ts +8 -8
- package/lib/Types/USync.js +3 -2
- package/lib/Types/index.d.ts +62 -47
- package/lib/Types/index.js +50 -26
- package/lib/Utils/auth-utils.d.ts +10 -13
- package/lib/Utils/auth-utils.js +472 -213
- package/lib/Utils/business.d.ts +20 -14
- package/lib/Utils/business.js +134 -110
- package/lib/Utils/chat-utils.d.ts +70 -88
- package/lib/Utils/chat-utils.js +403 -466
- package/lib/Utils/crypto.d.ts +46 -27
- package/lib/Utils/crypto.js +188 -117
- package/lib/Utils/decode-wa-message.d.ts +45 -58
- package/lib/Utils/decode-wa-message.js +311 -212
- package/lib/Utils/event-buffer.d.ts +17 -14
- package/lib/Utils/event-buffer.js +296 -321
- package/lib/Utils/generics.d.ts +92 -66
- package/lib/Utils/generics.js +436 -270
- package/lib/Utils/history.d.ts +23 -24
- package/lib/Utils/history.js +76 -106
- package/lib/Utils/index.d.ts +21 -24
- package/lib/Utils/index.js +41 -24
- package/lib/Utils/link-preview.d.ts +14 -12
- package/lib/Utils/link-preview.js +75 -40
- package/lib/Utils/logger.d.ts +11 -10
- package/lib/Utils/logger.js +7 -3
- package/lib/Utils/lt-hash.d.ts +14 -8
- package/lib/Utils/lt-hash.js +53 -3
- package/lib/Utils/make-mutex.d.ts +7 -7
- package/lib/Utils/make-mutex.js +44 -28
- package/lib/Utils/message-retry-manager.d.ts +88 -115
- package/lib/Utils/message-retry-manager.js +160 -265
- package/lib/Utils/messages-media.d.ts +107 -105
- package/lib/Utils/messages-media.js +619 -548
- package/lib/Utils/messages.d.ts +66 -52
- package/lib/Utils/messages.js +1558 -1730
- package/lib/Utils/noise-handler.d.ts +18 -18
- package/lib/Utils/noise-handler.js +130 -176
- package/lib/Utils/process-message.d.ts +32 -43
- package/lib/Utils/process-message.js +282 -484
- package/lib/Utils/rich-message-utils.js +724 -1220
- package/lib/Utils/signal.d.ts +32 -37
- package/lib/Utils/signal.js +105 -140
- package/lib/Utils/use-multi-file-auth-state.d.ts +5 -5
- package/lib/Utils/use-multi-file-auth-state.js +120 -70
- package/lib/Utils/use-single-file-auth-state.d.ts +13 -11
- package/lib/Utils/use-single-file-auth-state.js +66 -92
- package/lib/Utils/validate-connection.d.ts +13 -11
- package/lib/Utils/validate-connection.js +113 -128
- package/lib/WABinary/constants.d.ts +27 -25
- package/lib/WABinary/constants.js +1292 -1451
- package/lib/WABinary/decode.d.ts +9 -7
- package/lib/WABinary/decode.js +189 -163
- package/lib/WABinary/encode.d.ts +3 -3
- package/lib/WABinary/encode.js +155 -110
- package/lib/WABinary/generic-utils.d.ts +27 -14
- package/lib/WABinary/generic-utils.js +105 -177
- package/lib/WABinary/index.d.ts +5 -6
- package/lib/WABinary/index.js +25 -6
- package/lib/WABinary/jid-utils.d.ts +54 -41
- package/lib/WABinary/jid-utils.js +152 -83
- package/lib/WABinary/types.d.ts +13 -10
- package/lib/WABinary/types.js +3 -2
- package/lib/WAM/BinaryInfo.d.ts +15 -8
- package/lib/WAM/BinaryInfo.js +14 -7
- package/lib/WAM/constants.d.ts +37 -30
- package/lib/WAM/constants.js +11983 -19465
- package/lib/WAM/encode.d.ts +3 -3
- package/lib/WAM/encode.js +109 -95
- package/lib/WAM/index.d.ts +3 -4
- package/lib/WAM/index.js +23 -4
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -9
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +21 -37
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -19
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +26 -18
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -11
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +20 -12
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -11
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +24 -16
- package/lib/WAUSync/Protocols/index.d.ts +6 -6
- package/lib/WAUSync/Protocols/index.js +26 -6
- package/lib/WAUSync/USyncQuery.d.ts +28 -27
- package/lib/WAUSync/USyncQuery.js +62 -68
- package/lib/WAUSync/USyncUser.d.ts +10 -15
- package/lib/WAUSync/USyncUser.js +19 -20
- package/lib/WAUSync/index.d.ts +3 -4
- package/lib/WAUSync/index.js +23 -4
- package/lib/index.d.ts +12 -11
- package/lib/index.js +39 -12
- package/package.json +42 -86
- package/engine-requirements.js +0 -10
|
@@ -1,88 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
const WAProto_1 = require("../../WAProto")
|
|
6
|
+
const Types_1 = require("../Types")
|
|
7
|
+
const messages_1 = require("../Utils/messages")
|
|
8
|
+
const WABinary_1 = require("../WABinary")
|
|
9
|
+
const crypto_1 = require("./crypto")
|
|
10
|
+
const generics_1 = require("./generics")
|
|
11
|
+
const history_1 = require("./history")
|
|
12
|
+
|
|
10
13
|
const REAL_MSG_STUB_TYPES = new Set([
|
|
11
|
-
WAMessageStubType.CALL_MISSED_GROUP_VIDEO,
|
|
12
|
-
WAMessageStubType.CALL_MISSED_GROUP_VOICE,
|
|
13
|
-
WAMessageStubType.CALL_MISSED_VIDEO,
|
|
14
|
-
WAMessageStubType.CALL_MISSED_VOICE
|
|
15
|
-
])
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const ts = chat.tcTokenTimestamp ? toNumber(chat.tcTokenTimestamp) : 0;
|
|
22
|
-
if (chat.tcToken?.length && ts > 0) {
|
|
23
|
-
const jid = jidNormalizedUser(chat.id);
|
|
24
|
-
const storageJid = await resolveTcTokenJid(jid, getLIDForPN);
|
|
25
|
-
candidates.push({
|
|
26
|
-
storageJid,
|
|
27
|
-
token: Buffer.from(chat.tcToken),
|
|
28
|
-
ts,
|
|
29
|
-
senderTs: chat.tcTokenSenderTimestamp ? toNumber(chat.tcTokenSenderTimestamp) : undefined
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
if (!candidates.length) {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
const jids = candidates.map(c => c.storageJid);
|
|
37
|
-
const existing = await keyStore.get('tctoken', jids);
|
|
38
|
-
const entries = {};
|
|
39
|
-
for (const c of candidates) {
|
|
40
|
-
const existingEntry = existing[c.storageJid];
|
|
41
|
-
const existingTs = existingEntry?.timestamp ? Number(existingEntry.timestamp) : 0;
|
|
42
|
-
if (existingTs > 0 && existingTs >= c.ts) {
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
entries[c.storageJid] = {
|
|
46
|
-
...existingEntry,
|
|
47
|
-
token: c.token,
|
|
48
|
-
timestamp: String(c.ts),
|
|
49
|
-
...(c.senderTs !== undefined ? { senderTimestamp: c.senderTs } : {})
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
if (Object.keys(entries).length) {
|
|
53
|
-
logger?.debug({ count: Object.keys(entries).length }, 'storing tctokens from history sync');
|
|
54
|
-
try {
|
|
55
|
-
// Include updated __index so cross-session pruning picks these JIDs up.
|
|
56
|
-
const indexWrite = await buildMergedTcTokenIndexWrite(keyStore, Object.keys(entries));
|
|
57
|
-
await keyStore.set({ tctoken: { ...entries, ...indexWrite } });
|
|
58
|
-
}
|
|
59
|
-
catch (err) {
|
|
60
|
-
logger?.warn({ err }, 'failed to store tctokens from history sync');
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
14
|
+
Types_1.WAMessageStubType.CALL_MISSED_GROUP_VIDEO,
|
|
15
|
+
Types_1.WAMessageStubType.CALL_MISSED_GROUP_VOICE,
|
|
16
|
+
Types_1.WAMessageStubType.CALL_MISSED_VIDEO,
|
|
17
|
+
Types_1.WAMessageStubType.CALL_MISSED_VOICE
|
|
18
|
+
])
|
|
19
|
+
|
|
20
|
+
const REAL_MSG_REQ_ME_STUB_TYPES = new Set([
|
|
21
|
+
Types_1.WAMessageStubType.GROUP_PARTICIPANT_ADD
|
|
22
|
+
])
|
|
23
|
+
|
|
64
24
|
/** Cleans a received message to further processing */
|
|
65
|
-
|
|
25
|
+
const cleanMessage = (message, meId) => {
|
|
66
26
|
// ensure remoteJid and participant doesn't have device or agent in it
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
else {
|
|
71
|
-
message.key.remoteJid = jidNormalizedUser(message.key.remoteJid);
|
|
72
|
-
}
|
|
73
|
-
if (isHostedPnUser(message.key.participant) || isHostedLidUser(message.key.participant)) {
|
|
74
|
-
message.key.participant = jidEncode(jidDecode(message.key.participant)?.user, isHostedPnUser(message.key.participant) ? 's.whatsapp.net' : 'lid');
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
message.key.participant = jidNormalizedUser(message.key.participant);
|
|
78
|
-
}
|
|
79
|
-
const content = normalizeMessageContent(message.message);
|
|
27
|
+
message.key.remoteJid = WABinary_1.jidNormalizedUser(message.key.remoteJid)
|
|
28
|
+
message.key.participant = message.key.participant ? WABinary_1.jidNormalizedUser(message.key.participant) : undefined
|
|
29
|
+
const content = messages_1.normalizeMessageContent(message.message)
|
|
80
30
|
// if the message has a reaction, ensure fromMe & remoteJid are from our perspective
|
|
81
31
|
if (content?.reactionMessage) {
|
|
82
|
-
normaliseKey(content.reactionMessage.key)
|
|
32
|
+
normaliseKey(content.reactionMessage.key)
|
|
83
33
|
}
|
|
84
34
|
if (content?.pollUpdateMessage) {
|
|
85
|
-
normaliseKey(content.pollUpdateMessage.pollCreationMessageKey)
|
|
35
|
+
normaliseKey(content.pollUpdateMessage.pollCreationMessageKey)
|
|
86
36
|
}
|
|
87
37
|
function normaliseKey(msgKey) {
|
|
88
38
|
// if the reaction is from another user
|
|
@@ -91,244 +41,188 @@ export const cleanMessage = (message, meId, meLid) => {
|
|
|
91
41
|
// if the sender believed the message being reacted to is not from them
|
|
92
42
|
// we've to correct the key to be from them, or some other participant
|
|
93
43
|
msgKey.fromMe = !msgKey.fromMe
|
|
94
|
-
? areJidsSameUser(msgKey.participant || msgKey.remoteJid, meId)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
false;
|
|
44
|
+
? WABinary_1.areJidsSameUser(msgKey.participant || msgKey.remoteJid, meId)
|
|
45
|
+
// if the message being reacted to, was from them
|
|
46
|
+
// fromMe automatically becomes false
|
|
47
|
+
: false
|
|
99
48
|
// set the remoteJid to being the same as the chat the message came from
|
|
100
|
-
|
|
101
|
-
msgKey.remoteJid = message.key.remoteJid;
|
|
49
|
+
msgKey.remoteJid = message.key.remoteJid
|
|
102
50
|
// set participant of the message
|
|
103
|
-
msgKey.participant = msgKey.participant || message.key.participant
|
|
51
|
+
msgKey.participant = msgKey.participant || message.key.participant
|
|
104
52
|
}
|
|
105
53
|
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const normalizedContent = normalizeMessageContent(message.message)
|
|
110
|
-
const hasSomeContent = !!getContentType(normalizedContent)
|
|
111
|
-
return (
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const isRealMessage = (message, meId) => {
|
|
57
|
+
const normalizedContent = messages_1.normalizeMessageContent(message.message)
|
|
58
|
+
const hasSomeContent = !!messages_1.getContentType(normalizedContent)
|
|
59
|
+
return (
|
|
60
|
+
!!normalizedContent ||
|
|
112
61
|
REAL_MSG_STUB_TYPES.has(message.messageStubType) ||
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
62
|
+
(
|
|
63
|
+
REAL_MSG_REQ_ME_STUB_TYPES.has(message.messageStubType) &&
|
|
64
|
+
message.messageStubParameters?.some(p => WABinary_1.areJidsSameUser(meId, p))
|
|
65
|
+
)
|
|
66
|
+
) &&
|
|
67
|
+
hasSomeContent &&
|
|
68
|
+
!normalizedContent?.protocolMessage &&
|
|
69
|
+
!normalizedContent?.reactionMessage &&
|
|
70
|
+
!normalizedContent?.pollUpdateMessage
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const shouldIncrementChatUnread = (message) => (!message.key.fromMe && !message.messageStubType)
|
|
74
|
+
|
|
120
75
|
/**
|
|
121
76
|
* Get the ID of the chat from the given key.
|
|
122
77
|
* Typically -- that'll be the remoteJid, but for broadcasts, it'll be the participant
|
|
123
78
|
*/
|
|
124
|
-
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
if (isJidBroadcast(remoteJid) && !isJidStatusBroadcast(remoteJid) && !fromMe) {
|
|
131
|
-
if (!participant) {
|
|
132
|
-
throw new Boom('Cannot derive chat id: broadcast message key is missing participant', {
|
|
133
|
-
data: { remoteJid, fromMe }
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
return participant;
|
|
79
|
+
const getChatId = ({ remoteJid, participant, fromMe }) => {
|
|
80
|
+
if (WABinary_1.isJidBroadcast(remoteJid)
|
|
81
|
+
&& !WABinary_1.isJidStatusBroadcast(remoteJid)
|
|
82
|
+
&& !fromMe) {
|
|
83
|
+
return participant
|
|
137
84
|
}
|
|
138
|
-
return remoteJid
|
|
139
|
-
}
|
|
85
|
+
return remoteJid
|
|
86
|
+
}
|
|
87
|
+
|
|
140
88
|
/**
|
|
141
89
|
* Decrypt a poll vote
|
|
142
90
|
* @param vote encrypted vote
|
|
143
91
|
* @param ctx additional info about the poll required for decryption
|
|
144
92
|
* @returns list of SHA256 options
|
|
145
93
|
*/
|
|
146
|
-
|
|
94
|
+
function decryptPollVote({ encPayload, encIv }, { pollCreatorJid, pollMsgId, pollEncKey, voterJid, }) {
|
|
147
95
|
const sign = Buffer.concat([
|
|
148
96
|
toBinary(pollMsgId),
|
|
149
97
|
toBinary(pollCreatorJid),
|
|
150
98
|
toBinary(voterJid),
|
|
151
99
|
toBinary('Poll Vote'),
|
|
152
100
|
new Uint8Array([1])
|
|
153
|
-
])
|
|
154
|
-
const key0 = hmacSign(pollEncKey, new Uint8Array(32), 'sha256')
|
|
155
|
-
const decKey = hmacSign(sign, key0, 'sha256')
|
|
156
|
-
const aad = toBinary(`${pollMsgId}\u0000${voterJid}`)
|
|
157
|
-
const decrypted = aesDecryptGCM(encPayload, decKey, encIv, aad)
|
|
158
|
-
return proto.Message.PollVoteMessage.decode(decrypted)
|
|
159
|
-
function toBinary(txt) {
|
|
160
|
-
return Buffer.from(txt);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Decrypt an event response
|
|
165
|
-
* @param response encrypted event response
|
|
166
|
-
* @param ctx additional info about the event required for decryption
|
|
167
|
-
* @returns event response message
|
|
168
|
-
*/
|
|
169
|
-
export function decryptEventResponse({ encPayload, encIv }, { eventCreatorJid, eventMsgId, eventEncKey, responderJid }) {
|
|
170
|
-
const sign = Buffer.concat([
|
|
171
|
-
toBinary(eventMsgId),
|
|
172
|
-
toBinary(eventCreatorJid),
|
|
173
|
-
toBinary(responderJid),
|
|
174
|
-
toBinary('Event Response'),
|
|
175
|
-
new Uint8Array([1])
|
|
176
|
-
]);
|
|
177
|
-
const key0 = hmacSign(eventEncKey, new Uint8Array(32), 'sha256');
|
|
178
|
-
const decKey = hmacSign(sign, key0, 'sha256');
|
|
179
|
-
const aad = toBinary(`${eventMsgId}\u0000${responderJid}`);
|
|
180
|
-
const decrypted = aesDecryptGCM(encPayload, decKey, encIv, aad);
|
|
181
|
-
return proto.Message.EventResponseMessage.decode(decrypted);
|
|
101
|
+
])
|
|
102
|
+
const key0 = crypto_1.hmacSign(pollEncKey, new Uint8Array(32), 'sha256')
|
|
103
|
+
const decKey = crypto_1.hmacSign(sign, key0, 'sha256')
|
|
104
|
+
const aad = toBinary(`${pollMsgId}\u0000${voterJid}`)
|
|
105
|
+
const decrypted = crypto_1.aesDecryptGCM(encPayload, decKey, encIv, aad)
|
|
106
|
+
return WAProto_1.proto.Message.PollVoteMessage.decode(decrypted)
|
|
182
107
|
function toBinary(txt) {
|
|
183
|
-
return Buffer.from(txt)
|
|
108
|
+
return Buffer.from(txt)
|
|
184
109
|
}
|
|
185
110
|
}
|
|
111
|
+
|
|
186
112
|
const processMessage = async (message, { shouldProcessHistoryMsg, placeholderResendCache, ev, creds, signalRepository, keyStore, logger, options, getMessage }) => {
|
|
187
|
-
const meId = creds.me.id
|
|
188
|
-
const { accountSettings } = creds
|
|
189
|
-
const chat = { id: jidNormalizedUser(getChatId(message.key)) }
|
|
190
|
-
const isRealMsg = isRealMessage(message)
|
|
113
|
+
const meId = creds.me.id
|
|
114
|
+
const { accountSettings } = creds
|
|
115
|
+
const chat = { id: WABinary_1.jidNormalizedUser(getChatId(message.key)) }
|
|
116
|
+
const isRealMsg = isRealMessage(message, meId)
|
|
191
117
|
if (isRealMsg) {
|
|
192
|
-
chat.messages = [{ message }]
|
|
193
|
-
chat.conversationTimestamp = toNumber(message.messageTimestamp)
|
|
118
|
+
chat.messages = [{ message }]
|
|
119
|
+
chat.conversationTimestamp = generics_1.toNumber(message.messageTimestamp)
|
|
194
120
|
// only increment unread count if not CIPHERTEXT and from another person
|
|
195
121
|
if (shouldIncrementChatUnread(message)) {
|
|
196
|
-
chat.unreadCount = (chat.unreadCount || 0) + 1
|
|
122
|
+
chat.unreadCount = (chat.unreadCount || 0) + 1
|
|
197
123
|
}
|
|
198
124
|
}
|
|
199
|
-
const content = normalizeMessageContent(message.message)
|
|
125
|
+
const content = messages_1.normalizeMessageContent(message.message)
|
|
200
126
|
// unarchive chat if it's a real message, or someone reacted to our message
|
|
201
127
|
// and we've the unarchive chats setting on
|
|
202
|
-
if (
|
|
203
|
-
|
|
204
|
-
chat.
|
|
128
|
+
if (isRealMsg || content?.reactionMessage?.key?.fromMe
|
|
129
|
+
&& accountSettings?.unarchiveChats) {
|
|
130
|
+
chat.archived = false
|
|
131
|
+
chat.readOnly = false
|
|
205
132
|
}
|
|
206
|
-
const protocolMsg = content?.protocolMessage
|
|
133
|
+
const protocolMsg = content?.protocolMessage
|
|
207
134
|
if (protocolMsg) {
|
|
208
135
|
switch (protocolMsg.type) {
|
|
209
|
-
case proto.Message.ProtocolMessage.Type.HISTORY_SYNC_NOTIFICATION:
|
|
210
|
-
const histNotification = protocolMsg.historySyncNotification
|
|
211
|
-
const process = shouldProcessHistoryMsg
|
|
212
|
-
const isLatest = !creds.processedHistoryMessages?.length
|
|
136
|
+
case WAProto_1.proto.Message.ProtocolMessage.Type.HISTORY_SYNC_NOTIFICATION:
|
|
137
|
+
const histNotification = protocolMsg.historySyncNotification
|
|
138
|
+
const process = shouldProcessHistoryMsg
|
|
139
|
+
const isLatest = !creds.processedHistoryMessages?.length
|
|
213
140
|
logger?.info({
|
|
214
141
|
histNotification,
|
|
215
142
|
process,
|
|
216
143
|
id: message.key.id,
|
|
217
|
-
isLatest
|
|
218
|
-
}, 'got history notification')
|
|
144
|
+
isLatest,
|
|
145
|
+
}, 'got history notification')
|
|
219
146
|
if (process) {
|
|
220
|
-
|
|
221
|
-
if (histNotification.syncType !== proto.HistorySync.HistorySyncType.ON_DEMAND) {
|
|
147
|
+
if (histNotification.syncType !== WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND) {
|
|
222
148
|
ev.emit('creds.update', {
|
|
223
149
|
processedHistoryMessages: [
|
|
224
150
|
...(creds.processedHistoryMessages || []),
|
|
225
151
|
{ key: message.key, messageTimestamp: message.messageTimestamp }
|
|
226
152
|
]
|
|
227
|
-
})
|
|
153
|
+
})
|
|
228
154
|
}
|
|
229
|
-
const data = await downloadAndProcessHistorySyncNotification(histNotification, options
|
|
230
|
-
if (data.lidPnMappings?.length) {
|
|
231
|
-
logger?.debug({ count: data.lidPnMappings.length }, 'processing LID-PN mappings from history sync');
|
|
232
|
-
await signalRepository.lidMapping
|
|
233
|
-
.storeLIDPNMappings(data.lidPnMappings)
|
|
234
|
-
.catch(err => logger?.warn({ err }, 'failed to store LID-PN mappings from history sync'));
|
|
235
|
-
}
|
|
236
|
-
await storeTcTokensFromHistorySync(data.chats, signalRepository, keyStore, logger);
|
|
155
|
+
const data = await history_1.downloadAndProcessHistorySyncNotification(histNotification, options)
|
|
237
156
|
ev.emit('messaging-history.set', {
|
|
238
157
|
...data,
|
|
239
|
-
isLatest: histNotification.syncType !== proto.HistorySync.HistorySyncType.ON_DEMAND
|
|
240
|
-
|
|
158
|
+
isLatest: histNotification.syncType !== WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND
|
|
159
|
+
? isLatest
|
|
160
|
+
: undefined,
|
|
241
161
|
peerDataRequestSessionId: histNotification.peerDataRequestSessionId
|
|
242
|
-
})
|
|
162
|
+
})
|
|
243
163
|
}
|
|
244
|
-
break
|
|
245
|
-
case proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE:
|
|
246
|
-
const keys = protocolMsg.appStateSyncKeyShare.keys
|
|
164
|
+
break
|
|
165
|
+
case WAProto_1.proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE:
|
|
166
|
+
const keys = protocolMsg.appStateSyncKeyShare.keys
|
|
247
167
|
if (keys?.length) {
|
|
248
|
-
let newAppStateSyncKeyId = ''
|
|
168
|
+
let newAppStateSyncKeyId = ''
|
|
249
169
|
await keyStore.transaction(async () => {
|
|
250
|
-
const newKeys = []
|
|
170
|
+
const newKeys = []
|
|
251
171
|
for (const { keyData, keyId } of keys) {
|
|
252
|
-
const strKeyId = Buffer.from(keyId.keyId).toString('base64')
|
|
253
|
-
newKeys.push(strKeyId)
|
|
254
|
-
await keyStore.set({ 'app-state-sync-key': { [strKeyId]: keyData } })
|
|
255
|
-
newAppStateSyncKeyId = strKeyId
|
|
172
|
+
const strKeyId = Buffer.from(keyId.keyId).toString('base64')
|
|
173
|
+
newKeys.push(strKeyId)
|
|
174
|
+
await keyStore.set({ 'app-state-sync-key': { [strKeyId]: keyData } })
|
|
175
|
+
newAppStateSyncKeyId = strKeyId
|
|
256
176
|
}
|
|
257
|
-
logger?.info({ newAppStateSyncKeyId, newKeys }, 'injecting new app state sync keys')
|
|
258
|
-
}, meId)
|
|
259
|
-
ev.emit('creds.update', { myAppStateKeyId: newAppStateSyncKeyId })
|
|
177
|
+
logger?.info({ newAppStateSyncKeyId, newKeys }, 'injecting new app state sync keys')
|
|
178
|
+
}, meId)
|
|
179
|
+
ev.emit('creds.update', { myAppStateKeyId: newAppStateSyncKeyId })
|
|
260
180
|
}
|
|
261
181
|
else {
|
|
262
|
-
logger?.info({ protocolMsg }, 'recv app state sync with 0 keys')
|
|
182
|
+
logger?.info({ protocolMsg }, 'recv app state sync with 0 keys')
|
|
263
183
|
}
|
|
264
|
-
break
|
|
265
|
-
case proto.Message.ProtocolMessage.Type.REVOKE:
|
|
184
|
+
break
|
|
185
|
+
case WAProto_1.proto.Message.ProtocolMessage.Type.REVOKE:
|
|
266
186
|
ev.emit('messages.update', [
|
|
267
187
|
{
|
|
268
188
|
key: {
|
|
269
189
|
...message.key,
|
|
270
190
|
id: protocolMsg.key.id
|
|
271
191
|
},
|
|
272
|
-
update: { message: null, messageStubType: WAMessageStubType.REVOKE, key: message.key }
|
|
192
|
+
update: { message: null, messageStubType: Types_1.WAMessageStubType.REVOKE, key: message.key }
|
|
273
193
|
}
|
|
274
|
-
])
|
|
275
|
-
break
|
|
276
|
-
case proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING:
|
|
194
|
+
])
|
|
195
|
+
break
|
|
196
|
+
case WAProto_1.proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING:
|
|
277
197
|
Object.assign(chat, {
|
|
278
|
-
ephemeralSettingTimestamp: toNumber(message.messageTimestamp),
|
|
198
|
+
ephemeralSettingTimestamp: generics_1.toNumber(message.messageTimestamp),
|
|
279
199
|
ephemeralExpiration: protocolMsg.ephemeralExpiration || null
|
|
280
|
-
})
|
|
281
|
-
break
|
|
282
|
-
case proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE:
|
|
283
|
-
const response = protocolMsg.peerDataOperationRequestResponseMessage
|
|
200
|
+
})
|
|
201
|
+
break
|
|
202
|
+
case WAProto_1.proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE:
|
|
203
|
+
const response = protocolMsg.peerDataOperationRequestResponseMessage
|
|
284
204
|
if (response) {
|
|
205
|
+
await placeholderResendCache?.del(response.stanzaId)
|
|
285
206
|
// TODO: IMPLEMENT HISTORY SYNC ETC (sticker uploads etc.).
|
|
286
|
-
const peerDataOperationResult = response
|
|
207
|
+
const { peerDataOperationResult } = response
|
|
287
208
|
for (const result of peerDataOperationResult) {
|
|
288
|
-
const retryResponse = result
|
|
209
|
+
const { placeholderMessageResendResponse: retryResponse } = result
|
|
289
210
|
//eslint-disable-next-line max-depth
|
|
290
|
-
if (
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
//eslint-disable-next-line max-depth
|
|
301
|
-
if (msgId) {
|
|
302
|
-
await placeholderResendCache?.del(msgId);
|
|
303
|
-
}
|
|
304
|
-
let finalMsg;
|
|
305
|
-
//eslint-disable-next-line max-depth
|
|
306
|
-
if (cachedData && typeof cachedData === 'object') {
|
|
307
|
-
// Apply decoded message content onto cached metadata (preserves LID etc.)
|
|
308
|
-
cachedData.message = webMessageInfo.message;
|
|
309
|
-
//eslint-disable-next-line max-depth
|
|
310
|
-
if (webMessageInfo.messageTimestamp) {
|
|
311
|
-
cachedData.messageTimestamp = webMessageInfo.messageTimestamp;
|
|
312
|
-
}
|
|
313
|
-
finalMsg = cachedData;
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
finalMsg = webMessageInfo;
|
|
317
|
-
}
|
|
318
|
-
logger?.debug({ msgId, requestId: response.stanzaId }, 'received placeholder resend');
|
|
319
|
-
ev.emit('messages.upsert', {
|
|
320
|
-
messages: [finalMsg],
|
|
321
|
-
type: 'notify',
|
|
322
|
-
requestId: response.stanzaId
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
catch (err) {
|
|
326
|
-
logger?.warn({ err, stanzaId: response.stanzaId }, 'failed to decode placeholder resend response');
|
|
211
|
+
if (retryResponse) {
|
|
212
|
+
const webMessageInfo = WAProto_1.proto.WebMessageInfo.decode(retryResponse.webMessageInfoBytes)
|
|
213
|
+
// wait till another upsert event is available, don't want it to be part of the PDO response message
|
|
214
|
+
setTimeout(() => {
|
|
215
|
+
ev.emit('messages.upsert', {
|
|
216
|
+
messages: [webMessageInfo],
|
|
217
|
+
type: 'notify',
|
|
218
|
+
requestId: response.stanzaId
|
|
219
|
+
})
|
|
220
|
+
}, 500)
|
|
327
221
|
}
|
|
328
222
|
}
|
|
329
223
|
}
|
|
330
|
-
break
|
|
331
|
-
case proto.Message.ProtocolMessage.Type.MESSAGE_EDIT:
|
|
224
|
+
break
|
|
225
|
+
case WAProto_1.proto.Message.ProtocolMessage.Type.MESSAGE_EDIT:
|
|
332
226
|
ev.emit('messages.update', [
|
|
333
227
|
{
|
|
334
228
|
// flip the sender / fromMe properties because they're in the perspective of the sender
|
|
@@ -340,259 +234,160 @@ const processMessage = async (message, { shouldProcessHistoryMsg, placeholderRes
|
|
|
340
234
|
}
|
|
341
235
|
},
|
|
342
236
|
messageTimestamp: protocolMsg.timestampMs
|
|
343
|
-
? Math.floor(toNumber(protocolMsg.timestampMs) / 1000)
|
|
237
|
+
? Math.floor(generics_1.toNumber(protocolMsg.timestampMs) / 1000)
|
|
344
238
|
: message.messageTimestamp
|
|
345
239
|
}
|
|
346
240
|
}
|
|
347
|
-
])
|
|
348
|
-
break
|
|
349
|
-
case proto.Message.ProtocolMessage.Type.
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
messageTimestamp: Number(message.messageTimestamp)
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
break;
|
|
361
|
-
case proto.Message.ProtocolMessage.Type.LID_MIGRATION_MAPPING_SYNC:
|
|
362
|
-
const encodedPayload = protocolMsg.lidMigrationMappingSyncMessage?.encodedMappingPayload;
|
|
363
|
-
const { pnToLidMappings, chatDbMigrationTimestamp } = proto.LIDMigrationMappingSyncPayload.decode(encodedPayload);
|
|
364
|
-
logger?.debug({ pnToLidMappings, chatDbMigrationTimestamp }, 'got lid mappings and chat db migration timestamp');
|
|
365
|
-
const pairs = [];
|
|
241
|
+
])
|
|
242
|
+
break
|
|
243
|
+
case WAProto_1.proto.Message.ProtocolMessage.Type.LID_MIGRATION_MAPPING_SYNC:
|
|
244
|
+
const encodedPayload = protocolMsg.lidMigrationMappingSyncMessage?.encodedMappingPayload
|
|
245
|
+
const { pnToLidMappings, chatDbMigrationTimestamp } = WAProto_1.proto.LIDMigrationMappingSyncPayload.decode(encodedPayload)
|
|
246
|
+
|
|
247
|
+
logger?.debug({ pnToLidMappings, chatDbMigrationTimestamp }, 'got lid mappings and chat db migration timestamp')
|
|
248
|
+
|
|
249
|
+
const pairs = []
|
|
250
|
+
|
|
366
251
|
for (const { pn, latestLid, assignedLid } of pnToLidMappings) {
|
|
367
|
-
const lid = latestLid || assignedLid
|
|
368
|
-
pairs.push({ lid: `${lid}@lid`, pn: `${pn}@s.whatsapp.net` })
|
|
369
|
-
}
|
|
370
|
-
await signalRepository.lidMapping.storeLIDPNMappings(pairs);
|
|
371
|
-
if (pairs.length) {
|
|
372
|
-
for (const { pn, lid } of pairs) {
|
|
373
|
-
await signalRepository.migrateSession(pn, lid);
|
|
374
|
-
}
|
|
252
|
+
const lid = latestLid || assignedLid
|
|
253
|
+
pairs.push({ lid: `${lid}@lid`, pn: `${pn}@s.whatsapp.net` })
|
|
375
254
|
}
|
|
255
|
+
|
|
256
|
+
await signalRepository.lidMapping.storeLIDPNMappings(pairs)
|
|
257
|
+
break
|
|
258
|
+
case WAProto_1.proto.Message.ProtocolMessage.Type.LIMIT_SHARING:
|
|
259
|
+
ev.emit('limit-sharing.update', {
|
|
260
|
+
id: message.key.remoteJid,
|
|
261
|
+
author: WABinary_1.areJidsSameUser(message.key.remoteJid, protocolMsg.key.remoteJid) ? WABinary_1.jidNormalizedUser(meId) : message.key.remoteJid,
|
|
262
|
+
action: `${protocolMsg.limitSharing.sharingLimited ? 'on' : 'off'}`,
|
|
263
|
+
trigger: protocolMsg.limitSharing.trigger,
|
|
264
|
+
update_time: protocolMsg.limitSharing.limitSharingSettingTimestamp
|
|
265
|
+
})
|
|
266
|
+
break
|
|
376
267
|
}
|
|
377
268
|
}
|
|
378
269
|
else if (content?.reactionMessage) {
|
|
379
270
|
const reaction = {
|
|
380
271
|
...content.reactionMessage,
|
|
381
|
-
key: message.key
|
|
382
|
-
}
|
|
383
|
-
ev.emit('messages.reaction', [
|
|
384
|
-
{
|
|
272
|
+
key: message.key,
|
|
273
|
+
}
|
|
274
|
+
ev.emit('messages.reaction', [{
|
|
385
275
|
reaction,
|
|
386
276
|
key: content.reactionMessage?.key
|
|
387
|
-
}
|
|
388
|
-
]);
|
|
389
|
-
}
|
|
390
|
-
else if (content?.encEventResponseMessage) {
|
|
391
|
-
const encEventResponse = content.encEventResponseMessage;
|
|
392
|
-
const creationMsgKey = encEventResponse.eventCreationMessageKey;
|
|
393
|
-
// we need to fetch the event creation message to get the event enc key
|
|
394
|
-
const eventMsg = await getMessage(creationMsgKey);
|
|
395
|
-
if (eventMsg) {
|
|
396
|
-
try {
|
|
397
|
-
const meIdNormalised = jidNormalizedUser(meId);
|
|
398
|
-
// all jids need to be PN
|
|
399
|
-
const eventCreatorKey = creationMsgKey.participant || creationMsgKey.remoteJid;
|
|
400
|
-
const eventCreatorPn = isLidUser(eventCreatorKey)
|
|
401
|
-
? await signalRepository.lidMapping.getPNForLID(eventCreatorKey)
|
|
402
|
-
: eventCreatorKey;
|
|
403
|
-
const eventCreatorJid = getKeyAuthor({ remoteJid: jidNormalizedUser(eventCreatorPn), fromMe: meIdNormalised === eventCreatorPn }, meIdNormalised);
|
|
404
|
-
const responderJid = getKeyAuthor(message.key, meIdNormalised);
|
|
405
|
-
const eventEncKey = eventMsg?.messageContextInfo?.messageSecret;
|
|
406
|
-
if (!eventEncKey) {
|
|
407
|
-
logger?.warn({ creationMsgKey }, 'event response: missing messageSecret for decryption');
|
|
408
|
-
}
|
|
409
|
-
else {
|
|
410
|
-
const responseMsg = decryptEventResponse(encEventResponse, {
|
|
411
|
-
eventEncKey,
|
|
412
|
-
eventCreatorJid,
|
|
413
|
-
eventMsgId: creationMsgKey.id,
|
|
414
|
-
responderJid
|
|
415
|
-
});
|
|
416
|
-
const eventResponse = {
|
|
417
|
-
eventResponseMessageKey: message.key,
|
|
418
|
-
senderTimestampMs: responseMsg.timestampMs,
|
|
419
|
-
response: responseMsg
|
|
420
|
-
};
|
|
421
|
-
ev.emit('messages.update', [
|
|
422
|
-
{
|
|
423
|
-
key: creationMsgKey,
|
|
424
|
-
update: {
|
|
425
|
-
eventResponses: [eventResponse]
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
]);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
catch (err) {
|
|
432
|
-
logger?.warn({ err, creationMsgKey }, 'failed to decrypt event response');
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
else {
|
|
436
|
-
logger?.warn({ creationMsgKey }, 'event creation message not found, cannot decrypt response');
|
|
437
|
-
}
|
|
277
|
+
}])
|
|
438
278
|
}
|
|
439
279
|
else if (message.messageStubType) {
|
|
440
|
-
const jid = message.key?.remoteJid
|
|
280
|
+
const jid = message.key?.remoteJid
|
|
441
281
|
//let actor = whatsappID (message.participant)
|
|
442
|
-
let participants
|
|
443
|
-
|
|
444
|
-
const normalizeParticipant = (p = {}) => {
|
|
445
|
-
let parsed = p;
|
|
446
|
-
if (typeof parsed === 'string') {
|
|
447
|
-
try {
|
|
448
|
-
parsed = JSON.parse(parsed);
|
|
449
|
-
}
|
|
450
|
-
catch {
|
|
451
|
-
parsed = { id: parsed };
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
const jidVal = parsed.jid || parsed.id || parsed.phoneNumber || parsed.pn || null;
|
|
455
|
-
const lidVal = parsed.lid || parsed.lidJid || parsed.participantAlt || null;
|
|
456
|
-
const pnVal = parsed.pn || parsed.phoneNumber || null;
|
|
457
|
-
return {
|
|
458
|
-
...parsed,
|
|
459
|
-
id: jidVal,
|
|
460
|
-
jid: jidVal,
|
|
461
|
-
lid: lidVal,
|
|
462
|
-
pn: pnVal,
|
|
463
|
-
phoneNumber: pnVal
|
|
464
|
-
};
|
|
465
|
-
};
|
|
466
|
-
|
|
467
|
-
const getParticipants = () => Array.isArray(message.messageStubParameters)
|
|
468
|
-
? message.messageStubParameters.map((a) => normalizeParticipant(a))
|
|
469
|
-
: [];
|
|
470
|
-
|
|
471
|
-
const emitParticipantsUpdate = (action) => ev.emit('group-participants.update', {
|
|
472
|
-
id: jid,
|
|
473
|
-
author: message.key.participant,
|
|
474
|
-
authorPn: message.key.participantAlt,
|
|
475
|
-
authorUsername: message.key.participantUsername,
|
|
476
|
-
participants: Array.isArray(participants) ? participants.map((p) => normalizeParticipant(p)) : [],
|
|
477
|
-
action
|
|
478
|
-
});
|
|
282
|
+
let participants
|
|
283
|
+
const emitParticipantsUpdate = (action) => (ev.emit('group-participants.update', { id: jid, author: message.participant, participants, action }))
|
|
479
284
|
const emitGroupUpdate = (update) => {
|
|
480
|
-
ev.emit('groups.update', [
|
|
481
|
-
|
|
482
|
-
id: jid,
|
|
483
|
-
...update,
|
|
484
|
-
author: message.key.participant ?? undefined,
|
|
485
|
-
authorPn: message.key.participantAlt,
|
|
486
|
-
authorUsername: message.key.participantUsername
|
|
487
|
-
}
|
|
488
|
-
]);
|
|
489
|
-
};
|
|
285
|
+
ev.emit('groups.update', [{ id: jid, ...update, author: message.participant ? message.participant : undefined }])
|
|
286
|
+
}
|
|
490
287
|
const emitGroupRequestJoin = (participant, action, method) => {
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
author: message.key.participant,
|
|
495
|
-
authorPn: message.key.participantAlt,
|
|
496
|
-
authorUsername: message.key.participantUsername,
|
|
497
|
-
participant: p.id,
|
|
498
|
-
participantJid: p.jid,
|
|
499
|
-
participantLid: p.lid,
|
|
500
|
-
participantPn: p.pn,
|
|
501
|
-
action,
|
|
502
|
-
method: method
|
|
503
|
-
});
|
|
504
|
-
};
|
|
505
|
-
const participantsIncludesMe = () => Array.isArray(participants) && participants.find((p) => areJidsSameUser(meId, p.phoneNumber || p.pn || p.id || p.jid)); // ADD SUPPORT FOR LID
|
|
288
|
+
ev.emit('group.join-request', { id: jid, author: message.participant, participant, action, method: method })
|
|
289
|
+
}
|
|
290
|
+
const participantsIncludesMe = () => participants.find(jid => WABinary_1.areJidsSameUser(meId, jid))
|
|
506
291
|
switch (message.messageStubType) {
|
|
507
|
-
case WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER:
|
|
508
|
-
participants =
|
|
509
|
-
emitParticipantsUpdate('modify')
|
|
510
|
-
break
|
|
511
|
-
case WAMessageStubType.GROUP_PARTICIPANT_LEAVE:
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
292
|
+
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER:
|
|
293
|
+
participants = message.messageStubParameters || []
|
|
294
|
+
emitParticipantsUpdate('modify')
|
|
295
|
+
break
|
|
296
|
+
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_LEAVE:
|
|
297
|
+
participants = message.messageStubParameters || [];
|
|
298
|
+
emitParticipantsUpdate('leave');
|
|
299
|
+
// mark the chat read only if you left the group
|
|
300
|
+
if (participantsIncludesMe()) {
|
|
301
|
+
chat.readOnly = true;
|
|
302
|
+
}
|
|
303
|
+
break;
|
|
304
|
+
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_REMOVE:
|
|
305
|
+
participants = message.messageStubParameters || []
|
|
306
|
+
emitParticipantsUpdate('remove')
|
|
515
307
|
// mark the chat read only if you left the group
|
|
516
308
|
if (participantsIncludesMe()) {
|
|
517
|
-
chat.readOnly = true
|
|
309
|
+
chat.readOnly = true
|
|
518
310
|
}
|
|
519
|
-
break
|
|
520
|
-
case WAMessageStubType.GROUP_PARTICIPANT_ADD:
|
|
521
|
-
case WAMessageStubType.GROUP_PARTICIPANT_INVITE:
|
|
522
|
-
|
|
523
|
-
|
|
311
|
+
break
|
|
312
|
+
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_ADD:
|
|
313
|
+
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_INVITE:
|
|
314
|
+
let actionGp = 'invite'
|
|
315
|
+
participants = message.messageStubParameters || []
|
|
316
|
+
if (participantsIncludesMe()) chat.readOnly = false;
|
|
317
|
+
if (message?.key?.participant && !participants.includes(message?.key?.participant)) {
|
|
318
|
+
actionGp = 'approval-invite'
|
|
319
|
+
}
|
|
320
|
+
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN:
|
|
321
|
+
participants = message.messageStubParameters || []
|
|
524
322
|
if (participantsIncludesMe()) {
|
|
525
|
-
chat.readOnly = false
|
|
323
|
+
chat.readOnly = false
|
|
526
324
|
}
|
|
527
|
-
emitParticipantsUpdate('add')
|
|
528
|
-
break
|
|
529
|
-
case WAMessageStubType.GROUP_PARTICIPANT_DEMOTE:
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
const
|
|
571
|
-
|
|
572
|
-
|
|
325
|
+
emitParticipantsUpdate('add')
|
|
326
|
+
break
|
|
327
|
+
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_DEMOTE:
|
|
328
|
+
case Types_1.WAMessageStubType.COMMUNITY_PARTICIPANT_DEMOTE:
|
|
329
|
+
participants = message.messageStubParameters || []
|
|
330
|
+
emitParticipantsUpdate('demote')
|
|
331
|
+
break
|
|
332
|
+
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_PROMOTE:
|
|
333
|
+
case Types_1.WAMessageStubType.COMMUNITY_PARTICIPANT_PROMOTE:
|
|
334
|
+
participants = message.messageStubParameters || []
|
|
335
|
+
emitParticipantsUpdate('promote')
|
|
336
|
+
break
|
|
337
|
+
case Types_1.WAMessageStubType.GROUP_CHANGE_ANNOUNCE:
|
|
338
|
+
const announceValue = message.messageStubParameters?.[0]
|
|
339
|
+
emitGroupUpdate({ announce: announceValue === 'true' || announceValue === 'on' })
|
|
340
|
+
break
|
|
341
|
+
case Types_1.WAMessageStubType.GROUP_CHANGE_RESTRICT:
|
|
342
|
+
const restrictValue = message.messageStubParameters?.[0]
|
|
343
|
+
emitGroupUpdate({ restrict: restrictValue === 'true' || restrictValue === 'on' })
|
|
344
|
+
break
|
|
345
|
+
case Types_1.WAMessageStubType.GROUP_CHANGE_SUBJECT:
|
|
346
|
+
const name = message.messageStubParameters?.[0]
|
|
347
|
+
chat.name = name
|
|
348
|
+
emitGroupUpdate({ subject: name })
|
|
349
|
+
break
|
|
350
|
+
case Types_1.WAMessageStubType.GROUP_CHANGE_DESCRIPTION:
|
|
351
|
+
const description = message.messageStubParameters?.[0]
|
|
352
|
+
chat.description = description
|
|
353
|
+
emitGroupUpdate({ desc: description })
|
|
354
|
+
break
|
|
355
|
+
case Types_1.WAMessageStubType.GROUP_CHANGE_INVITE_LINK:
|
|
356
|
+
const code = message.messageStubParameters?.[0]
|
|
357
|
+
emitGroupUpdate({ inviteCode: code })
|
|
358
|
+
break
|
|
359
|
+
case Types_1.WAMessageStubType.GROUP_MEMBER_ADD_MODE:
|
|
360
|
+
const memberAddValue = message.messageStubParameters?.[0]
|
|
361
|
+
emitGroupUpdate({ memberAddMode: memberAddValue === 'all_member_add' })
|
|
362
|
+
break
|
|
363
|
+
case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE:
|
|
364
|
+
const approvalMode = message.messageStubParameters?.[0]
|
|
365
|
+
emitGroupUpdate({ joinApprovalMode: approvalMode === 'on' })
|
|
366
|
+
break
|
|
367
|
+
case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD:
|
|
368
|
+
const participant = message.messageStubParameters?.[0]
|
|
369
|
+
const action = message.messageStubParameters?.[1]
|
|
370
|
+
const method = message.messageStubParameters?.[2]
|
|
371
|
+
emitGroupRequestJoin(participant, action, method)
|
|
372
|
+
break
|
|
573
373
|
}
|
|
574
|
-
}
|
|
575
|
-
|
|
374
|
+
}
|
|
375
|
+
else if (content?.pollUpdateMessage) {
|
|
376
|
+
const creationMsgKey = content.pollUpdateMessage.pollCreationMessageKey
|
|
576
377
|
// we need to fetch the poll creation message to get the poll enc key
|
|
577
|
-
// TODO: make standalone, remove getMessage reference
|
|
578
|
-
// TODO: Remove entirely
|
|
579
378
|
const pollMsg = await getMessage(creationMsgKey)
|
|
580
|
-
if(pollMsg) {
|
|
581
|
-
const meIdNormalised = jidNormalizedUser(meId)
|
|
582
|
-
const pollCreatorJid = getKeyAuthor(creationMsgKey, meIdNormalised)
|
|
583
|
-
const voterJid = getKeyAuthor(message.key, meIdNormalised)
|
|
584
|
-
const pollEncKey = pollMsg.messageContextInfo?.messageSecret
|
|
585
|
-
|
|
379
|
+
if (pollMsg) {
|
|
380
|
+
const meIdNormalised = WABinary_1.jidNormalizedUser(meId)
|
|
381
|
+
const pollCreatorJid = generics_1.getKeyAuthor(creationMsgKey, meIdNormalised)
|
|
382
|
+
const voterJid = generics_1.getKeyAuthor(message.key, meIdNormalised)
|
|
383
|
+
const pollEncKey = pollMsg.messageContextInfo?.messageSecret
|
|
586
384
|
try {
|
|
587
|
-
const voteMsg = decryptPollVote(
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
voterJid,
|
|
594
|
-
}
|
|
595
|
-
)
|
|
385
|
+
const voteMsg = decryptPollVote(content.pollUpdateMessage.vote, {
|
|
386
|
+
pollEncKey,
|
|
387
|
+
pollCreatorJid,
|
|
388
|
+
pollMsgId: creationMsgKey.id,
|
|
389
|
+
voterJid,
|
|
390
|
+
})
|
|
596
391
|
ev.emit('messages.update', [
|
|
597
392
|
{
|
|
598
393
|
key: creationMsgKey,
|
|
@@ -601,28 +396,31 @@ const processMessage = async (message, { shouldProcessHistoryMsg, placeholderRes
|
|
|
601
396
|
{
|
|
602
397
|
pollUpdateMessageKey: message.key,
|
|
603
398
|
vote: voteMsg,
|
|
604
|
-
senderTimestampMs:
|
|
399
|
+
senderTimestampMs: content.pollUpdateMessage.senderTimestampMs.toNumber(),
|
|
605
400
|
}
|
|
606
401
|
]
|
|
607
402
|
}
|
|
608
403
|
}
|
|
609
404
|
])
|
|
610
|
-
} catch(err) {
|
|
611
|
-
logger?.warn(
|
|
612
|
-
{ err, creationMsgKey },
|
|
613
|
-
'failed to decrypt poll vote'
|
|
614
|
-
)
|
|
615
405
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
'poll creation message not found, cannot decrypt update'
|
|
620
|
-
)
|
|
406
|
+
catch (err) {
|
|
407
|
+
logger?.warn({ err, creationMsgKey }, 'failed to decrypt poll vote')
|
|
408
|
+
}
|
|
621
409
|
}
|
|
622
|
-
|
|
410
|
+
else {
|
|
411
|
+
logger?.warn({ creationMsgKey }, 'poll creation message not found, cannot decrypt update')
|
|
412
|
+
}
|
|
413
|
+
}
|
|
623
414
|
if (Object.keys(chat).length > 1) {
|
|
624
|
-
ev.emit('chats.update', [chat])
|
|
415
|
+
ev.emit('chats.update', [chat])
|
|
625
416
|
}
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
module.exports = {
|
|
420
|
+
cleanMessage,
|
|
421
|
+
isRealMessage,
|
|
422
|
+
shouldIncrementChatUnread,
|
|
423
|
+
getChatId,
|
|
424
|
+
decryptPollVote,
|
|
425
|
+
processMessage
|
|
426
|
+
}
|