@baileys-md/baileys 10.1.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +1303 -2
- package/WAProto/GenerateStatics.sh +3 -0
- package/WAProto/WAProto.proto +4633 -0
- package/WAProto/fix-imports.js +29 -0
- package/WAProto/index.js +13516 -4182
- package/lib/Defaults/baileys-version.js +1 -0
- package/lib/Defaults/index.js +51 -72
- package/lib/Signal/Group/ciphertext-message.js +12 -0
- package/lib/Signal/Group/group-session-builder.js +30 -0
- package/lib/Signal/Group/group_cipher.js +94 -0
- package/lib/Signal/Group/index.js +12 -0
- package/lib/Signal/Group/keyhelper.js +19 -0
- package/lib/Signal/Group/queue-job.js +54 -0
- package/lib/Signal/Group/sender-chain-key.js +32 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +63 -0
- package/lib/Signal/Group/sender-key-message.js +67 -0
- package/lib/Signal/Group/sender-key-name.js +48 -0
- package/lib/Signal/Group/sender-key-record.js +50 -0
- package/lib/Signal/Group/sender-key-state.js +96 -0
- package/{WASignalGroup/sender_message_key.js → lib/Signal/Group/sender-message-key.js} +4 -16
- package/lib/Signal/libsignal.js +41 -61
- package/lib/Socket/Client/index.js +3 -19
- package/lib/Socket/Client/types.js +11 -0
- package/lib/Socket/Client/websocket.js +50 -0
- package/lib/Socket/business.js +37 -42
- package/lib/Socket/chats.js +194 -187
- package/lib/Socket/communities.js +351 -0
- package/lib/Socket/groups.js +87 -90
- package/lib/Socket/index.js +7 -8
- package/lib/Socket/messages-recv.js +360 -335
- package/lib/Socket/messages-send.js +156 -279
- package/lib/Socket/mex.js +42 -0
- package/lib/Socket/newsletter.js +144 -213
- package/lib/Socket/socket.js +128 -161
- package/lib/Socket/usync.js +19 -26
- package/lib/Types/Auth.js +2 -2
- package/lib/Types/Call.js +2 -2
- package/lib/Types/Chat.js +8 -4
- package/lib/Types/Contact.js +2 -2
- package/lib/Types/Events.js +2 -2
- package/lib/Types/GroupMetadata.js +2 -2
- package/lib/Types/Label.js +3 -5
- package/lib/Types/LabelAssociation.js +3 -5
- package/lib/Types/Message.js +7 -7
- package/lib/Types/Newsletter.js +30 -17
- package/lib/Types/Product.js +2 -2
- package/lib/Types/Signal.js +2 -2
- package/lib/Types/Socket.js +3 -2
- package/lib/Types/State.js +2 -2
- package/lib/Types/USync.js +2 -2
- package/lib/Types/index.js +15 -31
- package/lib/Utils/auth-utils.js +31 -47
- package/lib/Utils/baileys-event-stream.js +15 -22
- package/lib/Utils/business.js +66 -69
- package/lib/Utils/chat-utils.js +200 -195
- package/lib/Utils/crypto.js +70 -85
- package/lib/Utils/decode-wa-message.js +47 -51
- package/lib/Utils/event-buffer.js +36 -46
- package/lib/Utils/generics.js +116 -188
- package/lib/Utils/history.js +37 -46
- package/lib/Utils/index.js +19 -33
- package/lib/Utils/link-preview.js +14 -55
- package/lib/Utils/logger.js +3 -7
- package/lib/Utils/lt-hash.js +23 -26
- package/lib/{Store → Utils}/make-in-memory-store.js +19 -27
- package/lib/Utils/make-mutex.js +7 -10
- package/lib/{Store → Utils}/make-ordered-dictionary.js +1 -3
- package/lib/Utils/messages-media.js +236 -368
- package/lib/Utils/messages.js +278 -510
- package/lib/Utils/noise-handler.js +22 -31
- package/lib/{Store → Utils}/object-repository.js +1 -4
- package/lib/Utils/process-message.js +144 -148
- package/lib/Utils/signal.js +71 -64
- package/lib/Utils/use-multi-file-auth-state.js +112 -84
- package/lib/Utils/validate-connection.js +72 -115
- package/lib/WABinary/constants.js +1281 -20
- package/lib/WABinary/decode.js +15 -52
- package/lib/WABinary/encode.js +14 -48
- package/lib/WABinary/generic-utils.js +31 -39
- package/lib/WABinary/index.js +6 -21
- package/lib/WABinary/jid-utils.js +23 -40
- package/lib/WABinary/types.js +2 -2
- package/lib/WAM/BinaryInfo.js +2 -5
- package/lib/WAM/constants.js +2257 -2366
- package/lib/WAM/encode.js +17 -21
- package/lib/WAM/index.js +4 -19
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +8 -11
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +11 -14
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +9 -12
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +9 -13
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +20 -22
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +3 -6
- package/lib/WAUSync/Protocols/index.js +5 -20
- package/lib/WAUSync/USyncQuery.js +34 -32
- package/lib/WAUSync/USyncUser.js +2 -5
- package/lib/WAUSync/index.js +4 -19
- package/lib/index.js +11 -33
- package/package.json +25 -54
- package/WASignalGroup/GroupProtocol.js +0 -1697
- package/WASignalGroup/ciphertext_message.js +0 -16
- package/WASignalGroup/group_cipher.js +0 -120
- package/WASignalGroup/group_session_builder.js +0 -46
- package/WASignalGroup/index.js +0 -5
- package/WASignalGroup/keyhelper.js +0 -21
- package/WASignalGroup/protobufs.js +0 -3
- package/WASignalGroup/queue_job.js +0 -69
- package/WASignalGroup/sender_chain_key.js +0 -50
- package/WASignalGroup/sender_key_distribution_message.js +0 -78
- package/WASignalGroup/sender_key_message.js +0 -92
- package/WASignalGroup/sender_key_name.js +0 -70
- package/WASignalGroup/sender_key_record.js +0 -56
- package/WASignalGroup/sender_key_state.js +0 -129
- package/lib/Defaults/baileys-version.json +0 -3
- package/lib/Defaults/phonenumber-mcc.json +0 -223
- package/lib/Socket/Client/abstract-socket-client.js +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.js +0 -166
- package/lib/Store/index.js +0 -8
- package/lib/Store/make-cache-manager-store.js +0 -83
- package/lib/Store/make-mongo-store.js +0 -567
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const Defaults_1 = require("../Defaults");
|
|
7
|
-
const WABinary_1 = require("../WABinary");
|
|
8
|
-
const crypto_1 = require("./crypto");
|
|
1
|
+
import { Boom } from '@hapi/boom';
|
|
2
|
+
import { proto } from '../../WAProto/index.js';
|
|
3
|
+
import { NOISE_MODE, WA_CERT_DETAILS } from '../Defaults/index.js';
|
|
4
|
+
import { decodeBinaryNode } from '../WABinary/index.js';
|
|
5
|
+
import { aesDecryptGCM, aesEncryptGCM, Curve, hkdf, sha256 } from './crypto.js';
|
|
9
6
|
const generateIV = (counter) => {
|
|
10
7
|
const iv = new ArrayBuffer(12);
|
|
11
8
|
new DataView(iv).setUint32(8, counter);
|
|
12
9
|
return new Uint8Array(iv);
|
|
13
10
|
};
|
|
14
|
-
const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER,
|
|
11
|
+
export const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, logger, routingInfo }) => {
|
|
15
12
|
logger = logger.child({ class: 'ns' });
|
|
16
13
|
const authenticate = (data) => {
|
|
17
14
|
if (!isFinished) {
|
|
18
|
-
hash =
|
|
15
|
+
hash = sha256(Buffer.concat([hash, data]));
|
|
19
16
|
}
|
|
20
17
|
};
|
|
21
18
|
const encrypt = (plaintext) => {
|
|
22
|
-
const result =
|
|
19
|
+
const result = aesEncryptGCM(plaintext, encKey, generateIV(writeCounter), hash);
|
|
23
20
|
writeCounter += 1;
|
|
24
21
|
authenticate(result);
|
|
25
22
|
return result;
|
|
@@ -28,7 +25,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
28
25
|
// before the handshake is finished, we use the same counter
|
|
29
26
|
// after handshake, the counters are different
|
|
30
27
|
const iv = generateIV(isFinished ? readCounter : writeCounter);
|
|
31
|
-
const result =
|
|
28
|
+
const result = aesDecryptGCM(ciphertext, decKey, iv, hash);
|
|
32
29
|
if (isFinished) {
|
|
33
30
|
readCounter += 1;
|
|
34
31
|
}
|
|
@@ -39,7 +36,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
39
36
|
return result;
|
|
40
37
|
};
|
|
41
38
|
const localHKDF = async (data) => {
|
|
42
|
-
const key = await
|
|
39
|
+
const key = await hkdf(Buffer.from(data), 64, { salt, info: '' });
|
|
43
40
|
return [key.slice(0, 32), key.slice(32)];
|
|
44
41
|
};
|
|
45
42
|
const mixIntoKey = async (data) => {
|
|
@@ -59,8 +56,8 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
59
56
|
writeCounter = 0;
|
|
60
57
|
isFinished = true;
|
|
61
58
|
};
|
|
62
|
-
const data = Buffer.from(
|
|
63
|
-
let hash = data.byteLength === 32 ? data :
|
|
59
|
+
const data = Buffer.from(NOISE_MODE);
|
|
60
|
+
let hash = data.byteLength === 32 ? data : sha256(data);
|
|
64
61
|
let salt = hash;
|
|
65
62
|
let encKey = hash;
|
|
66
63
|
let decKey = hash;
|
|
@@ -79,22 +76,17 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
79
76
|
finishInit,
|
|
80
77
|
processHandshake: async ({ serverHello }, noiseKey) => {
|
|
81
78
|
authenticate(serverHello.ephemeral);
|
|
82
|
-
await mixIntoKey(
|
|
79
|
+
await mixIntoKey(Curve.sharedKey(privateKey, serverHello.ephemeral));
|
|
83
80
|
const decStaticContent = decrypt(serverHello.static);
|
|
84
|
-
await mixIntoKey(
|
|
81
|
+
await mixIntoKey(Curve.sharedKey(privateKey, decStaticContent));
|
|
85
82
|
const certDecoded = decrypt(serverHello.payload);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const { intermediate: certIntermediate } = WAProto_1.proto.CertChain.decode(certDecoded);
|
|
91
|
-
const { issuerSerial } = WAProto_1.proto.CertChain.NoiseCertificate.Details.decode(certIntermediate.details);
|
|
92
|
-
if (issuerSerial !== Defaults_1.WA_CERT_DETAILS.SERIAL) {
|
|
93
|
-
throw new boom_1.Boom('certification match failed', { statusCode: 400 });
|
|
94
|
-
}
|
|
83
|
+
const { intermediate: certIntermediate } = proto.CertChain.decode(certDecoded);
|
|
84
|
+
const { issuerSerial } = proto.CertChain.NoiseCertificate.Details.decode(certIntermediate.details);
|
|
85
|
+
if (issuerSerial !== WA_CERT_DETAILS.SERIAL) {
|
|
86
|
+
throw new Boom('certification match failed', { statusCode: 400 });
|
|
95
87
|
}
|
|
96
88
|
const keyEnc = encrypt(noiseKey.public);
|
|
97
|
-
await mixIntoKey(
|
|
89
|
+
await mixIntoKey(Curve.sharedKey(noiseKey.private, serverHello.ephemeral));
|
|
98
90
|
return keyEnc;
|
|
99
91
|
},
|
|
100
92
|
encodeFrame: (data) => {
|
|
@@ -126,7 +118,6 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
126
118
|
return frame;
|
|
127
119
|
},
|
|
128
120
|
decodeFrame: async (newData, onFrame) => {
|
|
129
|
-
var _a;
|
|
130
121
|
// the binary protocol uses its own framing mechanism
|
|
131
122
|
// on top of the WS frames
|
|
132
123
|
// so we get this data and separate out the frames
|
|
@@ -143,13 +134,13 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
143
134
|
inBytes = inBytes.slice(size + 3);
|
|
144
135
|
if (isFinished) {
|
|
145
136
|
const result = decrypt(frame);
|
|
146
|
-
frame = await
|
|
137
|
+
frame = await decodeBinaryNode(result);
|
|
147
138
|
}
|
|
148
|
-
logger.trace({ msg:
|
|
139
|
+
logger.trace({ msg: frame?.attrs?.id }, 'recv frame');
|
|
149
140
|
onFrame(frame);
|
|
150
141
|
size = getBytesSize();
|
|
151
142
|
}
|
|
152
143
|
}
|
|
153
144
|
};
|
|
154
145
|
};
|
|
155
|
-
|
|
146
|
+
//# sourceMappingURL=noise-handler.js.map
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ObjectRepository = void 0;
|
|
4
1
|
class ObjectRepository {
|
|
5
2
|
constructor(entities = {}) {
|
|
6
3
|
this.entityMap = new Map(Object.entries(entities));
|
|
@@ -24,4 +21,4 @@ class ObjectRepository {
|
|
|
24
21
|
return this.findAll();
|
|
25
22
|
}
|
|
26
23
|
}
|
|
27
|
-
|
|
24
|
+
export { ObjectRepository }
|
|
@@ -1,34 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const WABinary_1 = require("../WABinary");
|
|
9
|
-
const crypto_1 = require("./crypto");
|
|
10
|
-
const generics_1 = require("./generics");
|
|
11
|
-
const history_1 = require("./history");
|
|
1
|
+
import { proto } from '../../WAProto/index.js';
|
|
2
|
+
import { WAMessageStubType } from '../Types/index.js';
|
|
3
|
+
import { getContentType, normalizeMessageContent } from '../Utils/messages.js';
|
|
4
|
+
import { areJidsSameUser, isJidBroadcast, isJidStatusBroadcast, jidNormalizedUser } from '../WABinary/index.js';
|
|
5
|
+
import { aesDecryptGCM, hmacSign } from './crypto.js';
|
|
6
|
+
import { toNumber } from './generics.js';
|
|
7
|
+
import { downloadAndProcessHistorySyncNotification } from './history.js';
|
|
12
8
|
const REAL_MSG_STUB_TYPES = new Set([
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
]);
|
|
18
|
-
const REAL_MSG_REQ_ME_STUB_TYPES = new Set([
|
|
19
|
-
Types_1.WAMessageStubType.GROUP_PARTICIPANT_ADD
|
|
9
|
+
WAMessageStubType.CALL_MISSED_GROUP_VIDEO,
|
|
10
|
+
WAMessageStubType.CALL_MISSED_GROUP_VOICE,
|
|
11
|
+
WAMessageStubType.CALL_MISSED_VIDEO,
|
|
12
|
+
WAMessageStubType.CALL_MISSED_VOICE
|
|
20
13
|
]);
|
|
14
|
+
const REAL_MSG_REQ_ME_STUB_TYPES = new Set([WAMessageStubType.GROUP_PARTICIPANT_ADD]);
|
|
21
15
|
/** Cleans a received message to further processing */
|
|
22
|
-
const cleanMessage = (message, meId) => {
|
|
16
|
+
export const cleanMessage = (message, meId) => {
|
|
23
17
|
// ensure remoteJid and participant doesn't have device or agent in it
|
|
24
|
-
message.key.remoteJid =
|
|
25
|
-
message.key.participant = message.key.participant ?
|
|
26
|
-
const content =
|
|
18
|
+
message.key.remoteJid = jidNormalizedUser(message.key.remoteJid);
|
|
19
|
+
message.key.participant = message.key.participant ? jidNormalizedUser(message.key.participant) : undefined;
|
|
20
|
+
const content = normalizeMessageContent(message.message);
|
|
27
21
|
// if the message has a reaction, ensure fromMe & remoteJid are from our perspective
|
|
28
|
-
if (content
|
|
22
|
+
if (content?.reactionMessage) {
|
|
29
23
|
normaliseKey(content.reactionMessage.key);
|
|
30
24
|
}
|
|
31
|
-
if (content
|
|
25
|
+
if (content?.pollUpdateMessage) {
|
|
32
26
|
normaliseKey(content.pollUpdateMessage.pollCreationMessageKey);
|
|
33
27
|
}
|
|
34
28
|
function normaliseKey(msgKey) {
|
|
@@ -38,10 +32,10 @@ const cleanMessage = (message, meId) => {
|
|
|
38
32
|
// if the sender believed the message being reacted to is not from them
|
|
39
33
|
// we've to correct the key to be from them, or some other participant
|
|
40
34
|
msgKey.fromMe = !msgKey.fromMe
|
|
41
|
-
?
|
|
42
|
-
// if the message being reacted to, was from them
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
? areJidsSameUser(msgKey.participant || msgKey.remoteJid, meId)
|
|
36
|
+
: // if the message being reacted to, was from them
|
|
37
|
+
// fromMe automatically becomes false
|
|
38
|
+
false;
|
|
45
39
|
// set the remoteJid to being the same as the chat the message came from
|
|
46
40
|
msgKey.remoteJid = message.key.remoteJid;
|
|
47
41
|
// set participant of the message
|
|
@@ -49,43 +43,36 @@ const cleanMessage = (message, meId) => {
|
|
|
49
43
|
}
|
|
50
44
|
}
|
|
51
45
|
};
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
&&
|
|
62
|
-
|
|
63
|
-
&& !(normalizedContent === null || normalizedContent === void 0 ? void 0 : normalizedContent.reactionMessage)
|
|
64
|
-
&& !(normalizedContent === null || normalizedContent === void 0 ? void 0 : normalizedContent.pollUpdateMessage);
|
|
46
|
+
export const isRealMessage = (message, meId) => {
|
|
47
|
+
const normalizedContent = normalizeMessageContent(message.message);
|
|
48
|
+
const hasSomeContent = !!getContentType(normalizedContent);
|
|
49
|
+
return ((!!normalizedContent ||
|
|
50
|
+
REAL_MSG_STUB_TYPES.has(message.messageStubType) ||
|
|
51
|
+
(REAL_MSG_REQ_ME_STUB_TYPES.has(message.messageStubType) &&
|
|
52
|
+
message.messageStubParameters?.some(p => areJidsSameUser(meId, p)))) &&
|
|
53
|
+
hasSomeContent &&
|
|
54
|
+
!normalizedContent?.protocolMessage &&
|
|
55
|
+
!normalizedContent?.reactionMessage &&
|
|
56
|
+
!normalizedContent?.pollUpdateMessage);
|
|
65
57
|
};
|
|
66
|
-
|
|
67
|
-
const shouldIncrementChatUnread = (message) => (!message.key.fromMe && !message.messageStubType);
|
|
68
|
-
exports.shouldIncrementChatUnread = shouldIncrementChatUnread;
|
|
58
|
+
export const shouldIncrementChatUnread = (message) => !message.key.fromMe && !message.messageStubType;
|
|
69
59
|
/**
|
|
70
60
|
* Get the ID of the chat from the given key.
|
|
71
61
|
* Typically -- that'll be the remoteJid, but for broadcasts, it'll be the participant
|
|
72
62
|
*/
|
|
73
|
-
const getChatId = ({ remoteJid, participant, fromMe }) => {
|
|
74
|
-
if ((
|
|
75
|
-
&& !(0, WABinary_1.isJidStatusBroadcast)(remoteJid)
|
|
76
|
-
&& !fromMe) {
|
|
63
|
+
export const getChatId = ({ remoteJid, participant, fromMe }) => {
|
|
64
|
+
if (isJidBroadcast(remoteJid) && !isJidStatusBroadcast(remoteJid) && !fromMe) {
|
|
77
65
|
return participant;
|
|
78
66
|
}
|
|
79
67
|
return remoteJid;
|
|
80
68
|
};
|
|
81
|
-
exports.getChatId = getChatId;
|
|
82
69
|
/**
|
|
83
70
|
* Decrypt a poll vote
|
|
84
71
|
* @param vote encrypted vote
|
|
85
72
|
* @param ctx additional info about the poll required for decryption
|
|
86
73
|
* @returns list of SHA256 options
|
|
87
74
|
*/
|
|
88
|
-
function decryptPollVote({ encPayload, encIv }, { pollCreatorJid, pollMsgId, pollEncKey, voterJid
|
|
75
|
+
export function decryptPollVote({ encPayload, encIv }, { pollCreatorJid, pollMsgId, pollEncKey, voterJid }) {
|
|
89
76
|
const sign = Buffer.concat([
|
|
90
77
|
toBinary(pollMsgId),
|
|
91
78
|
toBinary(pollCreatorJid),
|
|
@@ -93,52 +80,50 @@ function decryptPollVote({ encPayload, encIv }, { pollCreatorJid, pollMsgId, pol
|
|
|
93
80
|
toBinary('Poll Vote'),
|
|
94
81
|
new Uint8Array([1])
|
|
95
82
|
]);
|
|
96
|
-
const key0 =
|
|
97
|
-
const decKey =
|
|
83
|
+
const key0 = hmacSign(pollEncKey, new Uint8Array(32), 'sha256');
|
|
84
|
+
const decKey = hmacSign(sign, key0, 'sha256');
|
|
98
85
|
const aad = toBinary(`${pollMsgId}\u0000${voterJid}`);
|
|
99
|
-
const decrypted =
|
|
100
|
-
return
|
|
86
|
+
const decrypted = aesDecryptGCM(encPayload, decKey, encIv, aad);
|
|
87
|
+
return proto.Message.PollVoteMessage.decode(decrypted);
|
|
101
88
|
function toBinary(txt) {
|
|
102
89
|
return Buffer.from(txt);
|
|
103
90
|
}
|
|
104
91
|
}
|
|
105
|
-
const processMessage = async (message, { shouldProcessHistoryMsg, placeholderResendCache, ev, creds, keyStore, logger, options
|
|
106
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
92
|
+
const processMessage = async (message, { shouldProcessHistoryMsg, placeholderResendCache, ev, creds, keyStore, logger, options }) => {
|
|
107
93
|
const meId = creds.me.id;
|
|
108
94
|
const { accountSettings } = creds;
|
|
109
|
-
const chat = { id:
|
|
110
|
-
const isRealMsg =
|
|
95
|
+
const chat = { id: jidNormalizedUser(getChatId(message.key)) };
|
|
96
|
+
const isRealMsg = isRealMessage(message, meId);
|
|
111
97
|
if (isRealMsg) {
|
|
112
98
|
chat.messages = [{ message }];
|
|
113
|
-
chat.conversationTimestamp =
|
|
99
|
+
chat.conversationTimestamp = toNumber(message.messageTimestamp);
|
|
114
100
|
// only increment unread count if not CIPHERTEXT and from another person
|
|
115
|
-
if (
|
|
101
|
+
if (shouldIncrementChatUnread(message)) {
|
|
116
102
|
chat.unreadCount = (chat.unreadCount || 0) + 1;
|
|
117
103
|
}
|
|
118
104
|
}
|
|
119
|
-
const content =
|
|
105
|
+
const content = normalizeMessageContent(message.message);
|
|
120
106
|
// unarchive chat if it's a real message, or someone reacted to our message
|
|
121
107
|
// and we've the unarchive chats setting on
|
|
122
|
-
if ((isRealMsg ||
|
|
123
|
-
&& (accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.unarchiveChats)) {
|
|
108
|
+
if ((isRealMsg || content?.reactionMessage?.key?.fromMe) && accountSettings?.unarchiveChats) {
|
|
124
109
|
chat.archived = false;
|
|
125
110
|
chat.readOnly = false;
|
|
126
111
|
}
|
|
127
|
-
const protocolMsg = content
|
|
112
|
+
const protocolMsg = content?.protocolMessage;
|
|
128
113
|
if (protocolMsg) {
|
|
129
114
|
switch (protocolMsg.type) {
|
|
130
|
-
case
|
|
115
|
+
case proto.Message.ProtocolMessage.Type.HISTORY_SYNC_NOTIFICATION:
|
|
131
116
|
const histNotification = protocolMsg.historySyncNotification;
|
|
132
117
|
const process = shouldProcessHistoryMsg;
|
|
133
|
-
const isLatest = !
|
|
134
|
-
logger
|
|
118
|
+
const isLatest = !creds.processedHistoryMessages?.length;
|
|
119
|
+
logger?.info({
|
|
135
120
|
histNotification,
|
|
136
121
|
process,
|
|
137
122
|
id: message.key.id,
|
|
138
|
-
isLatest
|
|
123
|
+
isLatest
|
|
139
124
|
}, 'got history notification');
|
|
140
125
|
if (process) {
|
|
141
|
-
if (histNotification.syncType !==
|
|
126
|
+
if (histNotification.syncType !== proto.HistorySync.HistorySyncType.ON_DEMAND) {
|
|
142
127
|
ev.emit('creds.update', {
|
|
143
128
|
processedHistoryMessages: [
|
|
144
129
|
...(creds.processedHistoryMessages || []),
|
|
@@ -146,19 +131,17 @@ const processMessage = async (message, { shouldProcessHistoryMsg, placeholderRes
|
|
|
146
131
|
]
|
|
147
132
|
});
|
|
148
133
|
}
|
|
149
|
-
const data = await
|
|
134
|
+
const data = await downloadAndProcessHistorySyncNotification(histNotification, options);
|
|
150
135
|
ev.emit('messaging-history.set', {
|
|
151
136
|
...data,
|
|
152
|
-
isLatest: histNotification.syncType !==
|
|
153
|
-
? isLatest
|
|
154
|
-
: undefined,
|
|
137
|
+
isLatest: histNotification.syncType !== proto.HistorySync.HistorySyncType.ON_DEMAND ? isLatest : undefined,
|
|
155
138
|
peerDataRequestSessionId: histNotification.peerDataRequestSessionId
|
|
156
139
|
});
|
|
157
140
|
}
|
|
158
141
|
break;
|
|
159
|
-
case
|
|
142
|
+
case proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE:
|
|
160
143
|
const keys = protocolMsg.appStateSyncKeyShare.keys;
|
|
161
|
-
if (keys
|
|
144
|
+
if (keys?.length) {
|
|
162
145
|
let newAppStateSyncKeyId = '';
|
|
163
146
|
await keyStore.transaction(async () => {
|
|
164
147
|
const newKeys = [];
|
|
@@ -168,41 +151,42 @@ const processMessage = async (message, { shouldProcessHistoryMsg, placeholderRes
|
|
|
168
151
|
await keyStore.set({ 'app-state-sync-key': { [strKeyId]: keyData } });
|
|
169
152
|
newAppStateSyncKeyId = strKeyId;
|
|
170
153
|
}
|
|
171
|
-
logger
|
|
154
|
+
logger?.info({ newAppStateSyncKeyId, newKeys }, 'injecting new app state sync keys');
|
|
172
155
|
});
|
|
173
156
|
ev.emit('creds.update', { myAppStateKeyId: newAppStateSyncKeyId });
|
|
174
157
|
}
|
|
175
158
|
else {
|
|
176
|
-
logger
|
|
159
|
+
logger?.info({ protocolMsg }, 'recv app state sync with 0 keys');
|
|
177
160
|
}
|
|
178
161
|
break;
|
|
179
|
-
case
|
|
162
|
+
case proto.Message.ProtocolMessage.Type.REVOKE:
|
|
180
163
|
ev.emit('messages.update', [
|
|
181
164
|
{
|
|
182
165
|
key: {
|
|
183
166
|
...message.key,
|
|
184
167
|
id: protocolMsg.key.id
|
|
185
168
|
},
|
|
186
|
-
update: { message: null, messageStubType:
|
|
169
|
+
update: { message: null, messageStubType: WAMessageStubType.REVOKE, key: message.key }
|
|
187
170
|
}
|
|
188
171
|
]);
|
|
189
172
|
break;
|
|
190
|
-
case
|
|
173
|
+
case proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING:
|
|
191
174
|
Object.assign(chat, {
|
|
192
|
-
ephemeralSettingTimestamp:
|
|
175
|
+
ephemeralSettingTimestamp: toNumber(message.messageTimestamp),
|
|
193
176
|
ephemeralExpiration: protocolMsg.ephemeralExpiration || null
|
|
194
177
|
});
|
|
195
178
|
break;
|
|
196
|
-
case
|
|
179
|
+
case proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE:
|
|
197
180
|
const response = protocolMsg.peerDataOperationRequestResponseMessage;
|
|
198
181
|
if (response) {
|
|
199
|
-
placeholderResendCache
|
|
182
|
+
placeholderResendCache?.del(response.stanzaId);
|
|
200
183
|
// TODO: IMPLEMENT HISTORY SYNC ETC (sticker uploads etc.).
|
|
201
184
|
const { peerDataOperationResult } = response;
|
|
202
185
|
for (const result of peerDataOperationResult) {
|
|
203
186
|
const { placeholderMessageResendResponse: retryResponse } = result;
|
|
187
|
+
//eslint-disable-next-line max-depth
|
|
204
188
|
if (retryResponse) {
|
|
205
|
-
const webMessageInfo =
|
|
189
|
+
const webMessageInfo = proto.WebMessageInfo.decode(retryResponse.webMessageInfoBytes);
|
|
206
190
|
// wait till another upsert event is available, don't want it to be part of the PDO response message
|
|
207
191
|
setTimeout(() => {
|
|
208
192
|
ev.emit('messages.upsert', {
|
|
@@ -214,11 +198,12 @@ const processMessage = async (message, { shouldProcessHistoryMsg, placeholderRes
|
|
|
214
198
|
}
|
|
215
199
|
}
|
|
216
200
|
}
|
|
217
|
-
|
|
201
|
+
break;
|
|
202
|
+
case proto.Message.ProtocolMessage.Type.MESSAGE_EDIT:
|
|
218
203
|
ev.emit('messages.update', [
|
|
219
204
|
{
|
|
220
205
|
// flip the sender / fromMe properties because they're in the perspective of the sender
|
|
221
|
-
key: { ...message.key, id:
|
|
206
|
+
key: { ...message.key, id: protocolMsg.key?.id },
|
|
222
207
|
update: {
|
|
223
208
|
message: {
|
|
224
209
|
editedMessage: {
|
|
@@ -226,7 +211,7 @@ const processMessage = async (message, { shouldProcessHistoryMsg, placeholderRes
|
|
|
226
211
|
}
|
|
227
212
|
},
|
|
228
213
|
messageTimestamp: protocolMsg.timestampMs
|
|
229
|
-
? Math.floor(
|
|
214
|
+
? Math.floor(toNumber(protocolMsg.timestampMs) / 1000)
|
|
230
215
|
: message.messageTimestamp
|
|
231
216
|
}
|
|
232
217
|
}
|
|
@@ -234,36 +219,37 @@ const processMessage = async (message, { shouldProcessHistoryMsg, placeholderRes
|
|
|
234
219
|
break;
|
|
235
220
|
}
|
|
236
221
|
}
|
|
237
|
-
else if (content
|
|
222
|
+
else if (content?.reactionMessage) {
|
|
238
223
|
const reaction = {
|
|
239
224
|
...content.reactionMessage,
|
|
240
|
-
key: message.key
|
|
225
|
+
key: message.key
|
|
241
226
|
};
|
|
242
|
-
ev.emit('messages.reaction', [
|
|
227
|
+
ev.emit('messages.reaction', [
|
|
228
|
+
{
|
|
243
229
|
reaction,
|
|
244
|
-
key:
|
|
245
|
-
}
|
|
230
|
+
key: content.reactionMessage?.key
|
|
231
|
+
}
|
|
232
|
+
]);
|
|
246
233
|
}
|
|
247
234
|
else if (message.messageStubType) {
|
|
248
|
-
const jid =
|
|
235
|
+
const jid = message.key?.remoteJid;
|
|
249
236
|
//let actor = whatsappID (message.participant)
|
|
250
237
|
let participants;
|
|
251
|
-
const emitParticipantsUpdate = (action) =>
|
|
238
|
+
const emitParticipantsUpdate = (action) => ev.emit('group-participants.update', { id: jid, author: message.participant, participants, action });
|
|
252
239
|
const emitGroupUpdate = (update) => {
|
|
253
|
-
|
|
254
|
-
ev.emit('groups.update', [{ id: jid, ...update, author: (_a = message.participant) !== null && _a !== void 0 ? _a : undefined }]);
|
|
240
|
+
ev.emit('groups.update', [{ id: jid, ...update, author: message.participant ?? undefined }]);
|
|
255
241
|
};
|
|
256
242
|
const emitGroupRequestJoin = (participant, action, method) => {
|
|
257
243
|
ev.emit('group.join-request', { id: jid, author: message.participant, participant, action, method: method });
|
|
258
244
|
};
|
|
259
|
-
const participantsIncludesMe = () => participants.find(jid =>
|
|
245
|
+
const participantsIncludesMe = () => participants.find(jid => areJidsSameUser(meId, jid));
|
|
260
246
|
switch (message.messageStubType) {
|
|
261
|
-
case
|
|
247
|
+
case WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER:
|
|
262
248
|
participants = message.messageStubParameters || [];
|
|
263
249
|
emitParticipantsUpdate('modify');
|
|
264
250
|
break;
|
|
265
|
-
case
|
|
266
|
-
case
|
|
251
|
+
case WAMessageStubType.GROUP_PARTICIPANT_LEAVE:
|
|
252
|
+
case WAMessageStubType.GROUP_PARTICIPANT_REMOVE:
|
|
267
253
|
participants = message.messageStubParameters || [];
|
|
268
254
|
emitParticipantsUpdate('remove');
|
|
269
255
|
// mark the chat read only if you left the group
|
|
@@ -271,77 +257,82 @@ const processMessage = async (message, { shouldProcessHistoryMsg, placeholderRes
|
|
|
271
257
|
chat.readOnly = true;
|
|
272
258
|
}
|
|
273
259
|
break;
|
|
274
|
-
case
|
|
275
|
-
case
|
|
276
|
-
case
|
|
260
|
+
case WAMessageStubType.GROUP_PARTICIPANT_ADD:
|
|
261
|
+
case WAMessageStubType.GROUP_PARTICIPANT_INVITE:
|
|
262
|
+
case WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN:
|
|
277
263
|
participants = message.messageStubParameters || [];
|
|
278
264
|
if (participantsIncludesMe()) {
|
|
279
265
|
chat.readOnly = false;
|
|
280
266
|
}
|
|
281
267
|
emitParticipantsUpdate('add');
|
|
282
268
|
break;
|
|
283
|
-
case
|
|
269
|
+
case WAMessageStubType.GROUP_PARTICIPANT_DEMOTE:
|
|
284
270
|
participants = message.messageStubParameters || [];
|
|
285
271
|
emitParticipantsUpdate('demote');
|
|
286
272
|
break;
|
|
287
|
-
case
|
|
273
|
+
case WAMessageStubType.GROUP_PARTICIPANT_PROMOTE:
|
|
288
274
|
participants = message.messageStubParameters || [];
|
|
289
275
|
emitParticipantsUpdate('promote');
|
|
290
276
|
break;
|
|
291
|
-
case
|
|
292
|
-
const announceValue =
|
|
277
|
+
case WAMessageStubType.GROUP_CHANGE_ANNOUNCE:
|
|
278
|
+
const announceValue = message.messageStubParameters?.[0];
|
|
293
279
|
emitGroupUpdate({ announce: announceValue === 'true' || announceValue === 'on' });
|
|
294
280
|
break;
|
|
295
|
-
case
|
|
296
|
-
const restrictValue =
|
|
281
|
+
case WAMessageStubType.GROUP_CHANGE_RESTRICT:
|
|
282
|
+
const restrictValue = message.messageStubParameters?.[0];
|
|
297
283
|
emitGroupUpdate({ restrict: restrictValue === 'true' || restrictValue === 'on' });
|
|
298
284
|
break;
|
|
299
|
-
case
|
|
300
|
-
const name =
|
|
285
|
+
case WAMessageStubType.GROUP_CHANGE_SUBJECT:
|
|
286
|
+
const name = message.messageStubParameters?.[0];
|
|
301
287
|
chat.name = name;
|
|
302
288
|
emitGroupUpdate({ subject: name });
|
|
303
289
|
break;
|
|
304
|
-
case
|
|
305
|
-
const description =
|
|
290
|
+
case WAMessageStubType.GROUP_CHANGE_DESCRIPTION:
|
|
291
|
+
const description = message.messageStubParameters?.[0];
|
|
306
292
|
chat.description = description;
|
|
307
293
|
emitGroupUpdate({ desc: description });
|
|
308
294
|
break;
|
|
309
|
-
case
|
|
310
|
-
const code =
|
|
295
|
+
case WAMessageStubType.GROUP_CHANGE_INVITE_LINK:
|
|
296
|
+
const code = message.messageStubParameters?.[0];
|
|
311
297
|
emitGroupUpdate({ inviteCode: code });
|
|
312
298
|
break;
|
|
313
|
-
case
|
|
314
|
-
const memberAddValue =
|
|
299
|
+
case WAMessageStubType.GROUP_MEMBER_ADD_MODE:
|
|
300
|
+
const memberAddValue = message.messageStubParameters?.[0];
|
|
315
301
|
emitGroupUpdate({ memberAddMode: memberAddValue === 'all_member_add' });
|
|
316
302
|
break;
|
|
317
|
-
case
|
|
318
|
-
const approvalMode =
|
|
303
|
+
case WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE:
|
|
304
|
+
const approvalMode = message.messageStubParameters?.[0];
|
|
319
305
|
emitGroupUpdate({ joinApprovalMode: approvalMode === 'on' });
|
|
320
306
|
break;
|
|
321
|
-
case
|
|
322
|
-
const participant =
|
|
323
|
-
const action =
|
|
324
|
-
const method =
|
|
307
|
+
case WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD:
|
|
308
|
+
const participant = message.messageStubParameters?.[0];
|
|
309
|
+
const action = message.messageStubParameters?.[1];
|
|
310
|
+
const method = message.messageStubParameters?.[2];
|
|
325
311
|
emitGroupRequestJoin(participant, action, method);
|
|
326
312
|
break;
|
|
327
313
|
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
const creationMsgKey = content.pollUpdateMessage.pollCreationMessageKey;
|
|
314
|
+
} /* else if(content?.pollUpdateMessage) {
|
|
315
|
+
const creationMsgKey = content.pollUpdateMessage.pollCreationMessageKey!
|
|
331
316
|
// we need to fetch the poll creation message to get the poll enc key
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
const
|
|
337
|
-
const
|
|
317
|
+
// TODO: make standalone, remove getMessage reference
|
|
318
|
+
// TODO: Remove entirely
|
|
319
|
+
const pollMsg = await getMessage(creationMsgKey)
|
|
320
|
+
if(pollMsg) {
|
|
321
|
+
const meIdNormalised = jidNormalizedUser(meId)
|
|
322
|
+
const pollCreatorJid = getKeyAuthor(creationMsgKey, meIdNormalised)
|
|
323
|
+
const voterJid = getKeyAuthor(message.key, meIdNormalised)
|
|
324
|
+
const pollEncKey = pollMsg.messageContextInfo?.messageSecret!
|
|
325
|
+
|
|
338
326
|
try {
|
|
339
|
-
const voteMsg = decryptPollVote(
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
327
|
+
const voteMsg = decryptPollVote(
|
|
328
|
+
content.pollUpdateMessage.vote!,
|
|
329
|
+
{
|
|
330
|
+
pollEncKey,
|
|
331
|
+
pollCreatorJid,
|
|
332
|
+
pollMsgId: creationMsgKey.id!,
|
|
333
|
+
voterJid,
|
|
334
|
+
}
|
|
335
|
+
)
|
|
345
336
|
ev.emit('messages.update', [
|
|
346
337
|
{
|
|
347
338
|
key: creationMsgKey,
|
|
@@ -350,23 +341,28 @@ const processMessage = async (message, { shouldProcessHistoryMsg, placeholderRes
|
|
|
350
341
|
{
|
|
351
342
|
pollUpdateMessageKey: message.key,
|
|
352
343
|
vote: voteMsg,
|
|
353
|
-
senderTimestampMs: content.pollUpdateMessage.senderTimestampMs.toNumber(),
|
|
344
|
+
senderTimestampMs: (content.pollUpdateMessage.senderTimestampMs! as Long).toNumber(),
|
|
354
345
|
}
|
|
355
346
|
]
|
|
356
347
|
}
|
|
357
348
|
}
|
|
358
|
-
])
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
|
|
349
|
+
])
|
|
350
|
+
} catch(err) {
|
|
351
|
+
logger?.warn(
|
|
352
|
+
{ err, creationMsgKey },
|
|
353
|
+
'failed to decrypt poll vote'
|
|
354
|
+
)
|
|
362
355
|
}
|
|
356
|
+
} else {
|
|
357
|
+
logger?.warn(
|
|
358
|
+
{ creationMsgKey },
|
|
359
|
+
'poll creation message not found, cannot decrypt update'
|
|
360
|
+
)
|
|
363
361
|
}
|
|
364
|
-
|
|
365
|
-
logger === null || logger === void 0 ? void 0 : logger.warn({ creationMsgKey }, 'poll creation message not found, cannot decrypt update');
|
|
366
|
-
}
|
|
367
|
-
}
|
|
362
|
+
} */
|
|
368
363
|
if (Object.keys(chat).length > 1) {
|
|
369
364
|
ev.emit('chats.update', [chat]);
|
|
370
365
|
}
|
|
371
366
|
};
|
|
372
|
-
|
|
367
|
+
export default processMessage;
|
|
368
|
+
//# sourceMappingURL=process-message.js.map
|