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