alipclutch-baileys 8.3.0 → 8.4.1
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 +3 -1
- package/README.md +10 -9
- package/WAProto/GenerateStatics.sh +4 -0
- package/WAProto/WAProto.proto +4775 -0
- package/WAProto/index.d.ts +55057 -0
- package/WAProto/index.js +56887 -17535
- package/WAProto/index.ts.ts +53473 -0
- package/lib/Defaults/baileys-version.json +2 -2
- package/lib/Defaults/index.d.ts +16 -7
- package/lib/Defaults/index.js +90 -119
- package/lib/Socket/Client/index.d.ts +2 -3
- package/lib/Socket/Client/index.js +2 -3
- package/lib/Socket/Client/types.d.ts +0 -1
- package/lib/Socket/Client/types.js +0 -1
- package/lib/Socket/Client/websocket.d.ts +0 -1
- package/lib/Socket/Client/websocket.js +0 -1
- package/lib/Socket/business.d.ts +59 -58
- package/lib/Socket/chats.d.ts +45 -230
- package/lib/Socket/chats.js +139 -238
- package/lib/Socket/groups.d.ts +41 -32
- package/lib/Socket/groups.js +38 -23
- package/lib/Socket/index.d.ts +63 -64
- package/lib/Socket/index.js +2 -3
- package/lib/Socket/messages-recv.js +9 -65
- package/lib/Socket/messages-send.d.ts +49 -47
- package/lib/Socket/messages-send.js +584 -395
- package/lib/Socket/newsletter.d.ts +39 -37
- package/lib/Socket/newsletter.js +88 -123
- package/lib/Socket/setup.js +433 -0
- package/lib/Socket/{dugong.d.ts → setup.ts} +17 -52
- package/lib/Socket/socket.d.ts +10 -10
- package/lib/Socket/socket.js +62 -38
- package/lib/Socket/usync.d.ts +3 -4
- package/lib/Socket/usync.js +0 -1
- package/lib/Store/index.d.ts +1 -2
- package/lib/Store/index.js +1 -3
- package/lib/Store/make-in-memory-store.d.ts +24 -24
- package/lib/Store/make-in-memory-store.js +26 -14
- package/lib/Store/make-ordered-dictionary.d.ts +1 -1
- package/lib/Store/make-ordered-dictionary.js +2 -2
- package/lib/Types/Auth.d.ts +0 -7
- package/lib/Types/Call.d.ts +1 -1
- package/lib/Types/Chat.d.ts +14 -7
- package/lib/Types/Contact.d.ts +5 -1
- package/lib/Types/Events.d.ts +44 -2
- package/lib/Types/GroupMetadata.d.ts +11 -2
- package/lib/Types/Label.js +1 -1
- package/lib/Types/LabelAssociation.js +1 -1
- package/lib/Types/Message.d.ts +148 -21
- package/lib/Types/Message.js +0 -2
- package/lib/Types/Newsletter.d.ts +73 -97
- package/lib/Types/Newsletter.js +18 -38
- package/lib/Types/Socket.d.ts +17 -9
- package/lib/Types/index.d.ts +8 -1
- package/lib/Types/index.js +2 -2
- package/lib/Utils/auth-utils.d.ts +3 -3
- package/lib/Utils/auth-utils.js +6 -13
- package/lib/Utils/business.js +2 -2
- package/lib/Utils/chat-utils.d.ts +15 -16
- package/lib/Utils/chat-utils.js +36 -35
- package/lib/Utils/crypto.d.ts +15 -16
- package/lib/Utils/crypto.js +71 -29
- package/lib/Utils/decode-wa-message.d.ts +22 -6
- package/lib/Utils/decode-wa-message.js +65 -56
- package/lib/Utils/event-buffer.d.ts +2 -2
- package/lib/Utils/event-buffer.js +11 -7
- package/lib/Utils/generics.d.ts +17 -20
- package/lib/Utils/generics.js +95 -75
- package/lib/Utils/history.d.ts +4 -0
- package/lib/Utils/history.js +4 -6
- package/lib/Utils/link-preview.d.ts +2 -2
- package/lib/Utils/link-preview.js +34 -1
- package/lib/Utils/logger.d.ts +10 -3
- package/lib/Utils/lt-hash.d.ts +2 -2
- package/lib/Utils/lt-hash.js +6 -6
- package/lib/Utils/make-mutex.d.ts +2 -2
- package/lib/Utils/messages-media.d.ts +28 -24
- package/lib/Utils/messages-media.js +272 -111
- package/lib/Utils/messages.d.ts +13 -10
- package/lib/Utils/messages.js +323 -50
- package/lib/Utils/noise-handler.d.ts +10 -12
- package/lib/Utils/noise-handler.js +18 -23
- package/lib/Utils/process-message.d.ts +5 -4
- package/lib/Utils/process-message.js +108 -25
- package/lib/Utils/signal.d.ts +2 -1
- package/lib/Utils/signal.js +26 -26
- package/lib/Utils/use-multi-file-auth-state.d.ts +0 -1
- package/lib/Utils/use-multi-file-auth-state.js +51 -6
- package/lib/Utils/validate-connection.d.ts +3 -4
- package/lib/Utils/validate-connection.js +90 -66
- package/lib/WABinary/constants.d.ts +24 -27
- package/lib/WABinary/constants.js +1276 -13
- package/lib/WABinary/decode.d.ts +3 -4
- package/lib/WABinary/decode.js +26 -13
- package/lib/WABinary/encode.d.ts +1 -2
- package/lib/WABinary/encode.js +137 -152
- package/lib/WABinary/generic-utils.d.ts +1 -4
- package/lib/WABinary/generic-utils.js +37 -125
- package/lib/WABinary/jid-utils.d.ts +11 -5
- package/lib/WABinary/jid-utils.js +28 -5
- package/lib/WABinary/jid-utils.js.bak +83 -0
- package/lib/WAM/BinaryInfo.d.ts +2 -11
- package/lib/WAM/encode.d.ts +1 -2
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.js +27 -15
- package/package.json +18 -31
- package/engine-requirements.js +0 -10
- package/lib/Defaults/phonenumber-mcc.json +0 -223
- package/lib/Socket/Client/abstract-socket-client.d.ts +0 -17
- 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.d.ts +0 -12
- package/lib/Socket/Client/web-socket-client.js +0 -62
- package/lib/Socket/dugong.js +0 -483
- package/lib/Socket/registration.d.ts +0 -267
- package/lib/Socket/registration.js +0 -166
- package/lib/Store/make-cache-manager-store.d.ts +0 -13
- package/lib/Store/make-cache-manager-store.js +0 -83
|
@@ -11,7 +11,7 @@ const generateIV = (counter) => {
|
|
|
11
11
|
new DataView(iv).setUint32(8, counter);
|
|
12
12
|
return new Uint8Array(iv);
|
|
13
13
|
};
|
|
14
|
-
const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER,
|
|
14
|
+
const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, logger, routingInfo }) => {
|
|
15
15
|
logger = logger.child({ class: 'ns' });
|
|
16
16
|
const authenticate = (data) => {
|
|
17
17
|
if (!isFinished) {
|
|
@@ -38,20 +38,20 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
38
38
|
authenticate(ciphertext);
|
|
39
39
|
return result;
|
|
40
40
|
};
|
|
41
|
-
const localHKDF = (data) => {
|
|
42
|
-
const key = (0, crypto_1.hkdf)(Buffer.from(data), 64, { salt, info: '' });
|
|
41
|
+
const localHKDF = async (data) => {
|
|
42
|
+
const key = await (0, crypto_1.hkdf)(Buffer.from(data), 64, { salt, info: '' });
|
|
43
43
|
return [key.slice(0, 32), key.slice(32)];
|
|
44
44
|
};
|
|
45
|
-
const mixIntoKey = (data) => {
|
|
46
|
-
const [write, read] = localHKDF(data);
|
|
45
|
+
const mixIntoKey = async (data) => {
|
|
46
|
+
const [write, read] = await localHKDF(data);
|
|
47
47
|
salt = write;
|
|
48
48
|
encKey = read;
|
|
49
49
|
decKey = read;
|
|
50
50
|
readCounter = 0;
|
|
51
51
|
writeCounter = 0;
|
|
52
52
|
};
|
|
53
|
-
const finishInit = () => {
|
|
54
|
-
const [write, read] = localHKDF(new Uint8Array(0));
|
|
53
|
+
const finishInit = async () => {
|
|
54
|
+
const [write, read] = await localHKDF(new Uint8Array(0));
|
|
55
55
|
encKey = write;
|
|
56
56
|
decKey = read;
|
|
57
57
|
hash = Buffer.from([]);
|
|
@@ -60,7 +60,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
60
60
|
isFinished = true;
|
|
61
61
|
};
|
|
62
62
|
const data = Buffer.from(Defaults_1.NOISE_MODE);
|
|
63
|
-
let hash =
|
|
63
|
+
let hash = data.byteLength === 32 ? data : (0, crypto_1.sha256)(data);
|
|
64
64
|
let salt = hash;
|
|
65
65
|
let encKey = hash;
|
|
66
66
|
let decKey = hash;
|
|
@@ -77,24 +77,19 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
77
77
|
authenticate,
|
|
78
78
|
mixIntoKey,
|
|
79
79
|
finishInit,
|
|
80
|
-
processHandshake: ({ serverHello }, noiseKey) => {
|
|
80
|
+
processHandshake: async ({ serverHello }, noiseKey) => {
|
|
81
81
|
authenticate(serverHello.ephemeral);
|
|
82
|
-
mixIntoKey(crypto_1.Curve.sharedKey(privateKey, serverHello.ephemeral));
|
|
82
|
+
await mixIntoKey(crypto_1.Curve.sharedKey(privateKey, serverHello.ephemeral));
|
|
83
83
|
const decStaticContent = decrypt(serverHello.static);
|
|
84
|
-
mixIntoKey(crypto_1.Curve.sharedKey(privateKey, decStaticContent));
|
|
84
|
+
await mixIntoKey(crypto_1.Curve.sharedKey(privateKey, decStaticContent));
|
|
85
85
|
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
|
-
}
|
|
86
|
+
const { intermediate: certIntermediate } = WAProto_1.proto.CertChain.decode(certDecoded);
|
|
87
|
+
const { issuerSerial } = WAProto_1.proto.CertChain.NoiseCertificate.Details.decode(certIntermediate.details);
|
|
88
|
+
if (issuerSerial !== Defaults_1.WA_CERT_DETAILS.SERIAL) {
|
|
89
|
+
throw new boom_1.Boom('certification match failed', { statusCode: 400 });
|
|
95
90
|
}
|
|
96
91
|
const keyEnc = encrypt(noiseKey.public);
|
|
97
|
-
mixIntoKey(crypto_1.Curve.sharedKey(noiseKey.private, serverHello.ephemeral));
|
|
92
|
+
await mixIntoKey(crypto_1.Curve.sharedKey(noiseKey.private, serverHello.ephemeral));
|
|
98
93
|
return keyEnc;
|
|
99
94
|
},
|
|
100
95
|
encodeFrame: (data) => {
|
|
@@ -125,7 +120,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
125
120
|
frame.set(data, introSize + 3);
|
|
126
121
|
return frame;
|
|
127
122
|
},
|
|
128
|
-
decodeFrame: (newData, onFrame) => {
|
|
123
|
+
decodeFrame: async (newData, onFrame) => {
|
|
129
124
|
var _a;
|
|
130
125
|
// the binary protocol uses its own framing mechanism
|
|
131
126
|
// on top of the WS frames
|
|
@@ -143,7 +138,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
143
138
|
inBytes = inBytes.slice(size + 3);
|
|
144
139
|
if (isFinished) {
|
|
145
140
|
const result = decrypt(frame);
|
|
146
|
-
frame = (0, WABinary_1.decodeBinaryNode)(result);
|
|
141
|
+
frame = await (0, WABinary_1.decodeBinaryNode)(result);
|
|
147
142
|
}
|
|
148
143
|
logger.trace({ msg: (_a = frame === null || frame === void 0 ? void 0 : frame.attrs) === null || _a === void 0 ? void 0 : _a.id }, 'recv frame');
|
|
149
144
|
onFrame(frame);
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { AxiosRequestConfig } from 'axios';
|
|
2
|
-
import type { Logger } from 'pino';
|
|
3
2
|
import { proto } from '../../WAProto';
|
|
4
|
-
import { AuthenticationCreds, BaileysEventEmitter, SignalKeyStoreWithTransaction, SocketConfig } from '../Types';
|
|
3
|
+
import { AuthenticationCreds, BaileysEventEmitter, CacheStore, SignalKeyStoreWithTransaction, SocketConfig } from '../Types';
|
|
4
|
+
import { ILogger } from './logger';
|
|
5
5
|
type ProcessMessageContext = {
|
|
6
6
|
shouldProcessHistoryMsg: boolean;
|
|
7
|
+
placeholderResendCache?: CacheStore;
|
|
7
8
|
creds: AuthenticationCreds;
|
|
8
9
|
keyStore: SignalKeyStoreWithTransaction;
|
|
9
10
|
ev: BaileysEventEmitter;
|
|
10
11
|
getMessage: SocketConfig['getMessage'];
|
|
11
|
-
logger?:
|
|
12
|
+
logger?: ILogger;
|
|
12
13
|
options: AxiosRequestConfig<{}>;
|
|
13
14
|
};
|
|
14
15
|
/** Cleans a received message to further processing */
|
|
@@ -37,5 +38,5 @@ type PollContext = {
|
|
|
37
38
|
* @returns list of SHA256 options
|
|
38
39
|
*/
|
|
39
40
|
export declare function decryptPollVote({ encPayload, encIv }: proto.Message.IPollEncValue, { pollCreatorJid, pollMsgId, pollEncKey, voterJid, }: PollContext): proto.Message.PollVoteMessage;
|
|
40
|
-
declare const processMessage: (message: proto.IWebMessageInfo, { shouldProcessHistoryMsg, ev, creds, keyStore, logger, options, getMessage }: ProcessMessageContext) => Promise<void>;
|
|
41
|
+
declare const processMessage: (message: proto.IWebMessageInfo, { shouldProcessHistoryMsg, placeholderResendCache, ev, creds, keyStore, logger, options, getMessage }: ProcessMessageContext) => Promise<void>;
|
|
41
42
|
export default processMessage;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getChatId = exports.shouldIncrementChatUnread = exports.isRealMessage = exports.cleanMessage = void 0;
|
|
4
|
+
exports.decryptPollVote = decryptPollVote;
|
|
4
5
|
const WAProto_1 = require("../../WAProto");
|
|
5
6
|
const Types_1 = require("../Types");
|
|
6
7
|
const messages_1 = require("../Utils/messages");
|
|
@@ -20,8 +21,21 @@ const REAL_MSG_REQ_ME_STUB_TYPES = new Set([
|
|
|
20
21
|
/** Cleans a received message to further processing */
|
|
21
22
|
const cleanMessage = (message, meId) => {
|
|
22
23
|
// ensure remoteJid and participant doesn't have device or agent in it
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
// normalize JIDs but catch errors to avoid throwing on invalid LIDs/JIDs
|
|
25
|
+
try {
|
|
26
|
+
message.key.remoteJid = (0, WABinary_1.jidNormalizedUser)(message.key.remoteJid);
|
|
27
|
+
}
|
|
28
|
+
catch (_e) {
|
|
29
|
+
// if normalization fails, retain original remoteJid
|
|
30
|
+
}
|
|
31
|
+
if (message.key.participant) {
|
|
32
|
+
try {
|
|
33
|
+
message.key.participant = (0, WABinary_1.jidNormalizedUser)(message.key.participant);
|
|
34
|
+
}
|
|
35
|
+
catch (_e) {
|
|
36
|
+
// ignore if can't normalize participant
|
|
37
|
+
}
|
|
38
|
+
}
|
|
25
39
|
const content = (0, messages_1.normalizeMessageContent)(message.message);
|
|
26
40
|
// if the message has a reaction, ensure fromMe & remoteJid are from our perspective
|
|
27
41
|
if (content === null || content === void 0 ? void 0 : content.reactionMessage) {
|
|
@@ -101,14 +115,14 @@ function decryptPollVote({ encPayload, encIv }, { pollCreatorJid, pollMsgId, pol
|
|
|
101
115
|
return Buffer.from(txt);
|
|
102
116
|
}
|
|
103
117
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
118
|
+
const processMessage = async (message, { shouldProcessHistoryMsg, placeholderResendCache, ev, creds, keyStore, logger, options, getMessage }) => {
|
|
119
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
107
120
|
const meId = creds.me.id;
|
|
108
121
|
const { accountSettings } = creds;
|
|
109
122
|
const chat = { id: (0, WABinary_1.jidNormalizedUser)((0, exports.getChatId)(message.key)) };
|
|
110
123
|
const isRealMsg = (0, exports.isRealMessage)(message, meId);
|
|
111
124
|
if (isRealMsg) {
|
|
125
|
+
chat.messages = [{ message }];
|
|
112
126
|
chat.conversationTimestamp = (0, generics_1.toNumber)(message.messageTimestamp);
|
|
113
127
|
// only increment unread count if not CIPHERTEXT and from another person
|
|
114
128
|
if ((0, exports.shouldIncrementChatUnread)(message)) {
|
|
@@ -116,6 +130,25 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
116
130
|
}
|
|
117
131
|
}
|
|
118
132
|
const content = (0, messages_1.normalizeMessageContent)(message.message);
|
|
133
|
+
const senderId = message.key.participant || message.key.remoteJid;
|
|
134
|
+
if ((0, WABinary_1.isLidUser)(senderId)) {
|
|
135
|
+
const jid = (0, WABinary_1.lidToJid)(senderId);
|
|
136
|
+
if (message.key.participant) {
|
|
137
|
+
message.key.participant = jid;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
message.key.remoteJid = jid;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const mJids = content && content.contextInfo && content.contextInfo.mentionedJid ? content.contextInfo.mentionedJid : [];
|
|
144
|
+
for (let i = 0; i < mJids.length; i++) {
|
|
145
|
+
if ((0, WABinary_1.isLidUser)(mJids[i])) {
|
|
146
|
+
mJids[i] = (0, WABinary_1.lidToJid)(mJids[i]);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (content && content.contextInfo && content.contextInfo.participant && (0, WABinary_1.isLidUser)(content.contextInfo.participant)) {
|
|
150
|
+
content.contextInfo.participant = (0, WABinary_1.lidToJid)(content.contextInfo.participant);
|
|
151
|
+
}
|
|
119
152
|
// unarchive chat if it's a real message, or someone reacted to our message
|
|
120
153
|
// and we've the unarchive chats setting on
|
|
121
154
|
if ((isRealMsg || ((_b = (_a = content === null || content === void 0 ? void 0 : content.reactionMessage) === null || _a === void 0 ? void 0 : _a.key) === null || _b === void 0 ? void 0 : _b.fromMe))
|
|
@@ -137,14 +170,22 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
137
170
|
isLatest,
|
|
138
171
|
}, 'got history notification');
|
|
139
172
|
if (process) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
173
|
+
if (histNotification.syncType !== WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND) {
|
|
174
|
+
ev.emit('creds.update', {
|
|
175
|
+
processedHistoryMessages: [
|
|
176
|
+
...(creds.processedHistoryMessages || []),
|
|
177
|
+
{ key: message.key, messageTimestamp: message.messageTimestamp }
|
|
178
|
+
]
|
|
179
|
+
});
|
|
180
|
+
}
|
|
146
181
|
const data = await (0, history_1.downloadAndProcessHistorySyncNotification)(histNotification, options);
|
|
147
|
-
ev.emit('messaging-history.set', {
|
|
182
|
+
ev.emit('messaging-history.set', {
|
|
183
|
+
...data,
|
|
184
|
+
isLatest: histNotification.syncType !== WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND
|
|
185
|
+
? isLatest
|
|
186
|
+
: undefined,
|
|
187
|
+
peerDataRequestSessionId: histNotification.peerDataRequestSessionId
|
|
188
|
+
});
|
|
148
189
|
}
|
|
149
190
|
break;
|
|
150
191
|
case WAProto_1.proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE:
|
|
@@ -187,17 +228,41 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
187
228
|
case WAProto_1.proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE:
|
|
188
229
|
const response = protocolMsg.peerDataOperationRequestResponseMessage;
|
|
189
230
|
if (response) {
|
|
231
|
+
placeholderResendCache === null || placeholderResendCache === void 0 ? void 0 : placeholderResendCache.del(response.stanzaId);
|
|
232
|
+
// TODO: IMPLEMENT HISTORY SYNC ETC (sticker uploads etc.).
|
|
190
233
|
const { peerDataOperationResult } = response;
|
|
191
234
|
for (const result of peerDataOperationResult) {
|
|
192
235
|
const { placeholderMessageResendResponse: retryResponse } = result;
|
|
193
236
|
if (retryResponse) {
|
|
194
237
|
const webMessageInfo = WAProto_1.proto.WebMessageInfo.decode(retryResponse.webMessageInfoBytes);
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
238
|
+
// wait till another upsert event is available, don't want it to be part of the PDO response message
|
|
239
|
+
setTimeout(() => {
|
|
240
|
+
ev.emit('messages.upsert', {
|
|
241
|
+
messages: [webMessageInfo],
|
|
242
|
+
type: 'notify',
|
|
243
|
+
requestId: response.stanzaId
|
|
244
|
+
});
|
|
245
|
+
}, 500);
|
|
198
246
|
}
|
|
199
247
|
}
|
|
200
248
|
}
|
|
249
|
+
case WAProto_1.proto.Message.ProtocolMessage.Type.MESSAGE_EDIT:
|
|
250
|
+
ev.emit('messages.update', [
|
|
251
|
+
{
|
|
252
|
+
// flip the sender / fromMe properties because they're in the perspective of the sender
|
|
253
|
+
key: { ...message.key, id: (_d = protocolMsg.key) === null || _d === void 0 ? void 0 : _d.id },
|
|
254
|
+
update: {
|
|
255
|
+
message: {
|
|
256
|
+
editedMessage: {
|
|
257
|
+
message: protocolMsg.editedMessage
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
messageTimestamp: protocolMsg.timestampMs
|
|
261
|
+
? Math.floor((0, generics_1.toNumber)(protocolMsg.timestampMs) / 1000)
|
|
262
|
+
: message.messageTimestamp
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
]);
|
|
201
266
|
break;
|
|
202
267
|
}
|
|
203
268
|
}
|
|
@@ -208,11 +273,11 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
208
273
|
};
|
|
209
274
|
ev.emit('messages.reaction', [{
|
|
210
275
|
reaction,
|
|
211
|
-
key: content.reactionMessage.key,
|
|
276
|
+
key: (_e = content.reactionMessage) === null || _e === void 0 ? void 0 : _e.key,
|
|
212
277
|
}]);
|
|
213
278
|
}
|
|
214
279
|
else if (message.messageStubType) {
|
|
215
|
-
const jid = message.key.remoteJid;
|
|
280
|
+
const jid = (_f = message.key) === null || _f === void 0 ? void 0 : _f.remoteJid;
|
|
216
281
|
//let actor = whatsappID (message.participant)
|
|
217
282
|
let participants;
|
|
218
283
|
const emitParticipantsUpdate = (action) => (ev.emit('group-participants.update', { id: jid, author: message.participant, participants, action }));
|
|
@@ -220,8 +285,15 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
220
285
|
var _a;
|
|
221
286
|
ev.emit('groups.update', [{ id: jid, ...update, author: (_a = message.participant) !== null && _a !== void 0 ? _a : undefined }]);
|
|
222
287
|
};
|
|
288
|
+
const emitGroupRequestJoin = (participant, action, method) => {
|
|
289
|
+
ev.emit('group.join-request', { id: jid, author: message.participant, participant, action, method: method });
|
|
290
|
+
};
|
|
223
291
|
const participantsIncludesMe = () => participants.find(jid => (0, WABinary_1.areJidsSameUser)(meId, jid));
|
|
224
292
|
switch (message.messageStubType) {
|
|
293
|
+
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER:
|
|
294
|
+
participants = message.messageStubParameters || [];
|
|
295
|
+
emitParticipantsUpdate('modify');
|
|
296
|
+
break;
|
|
225
297
|
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_LEAVE:
|
|
226
298
|
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_REMOVE:
|
|
227
299
|
participants = message.messageStubParameters || [];
|
|
@@ -249,30 +321,41 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
249
321
|
emitParticipantsUpdate('promote');
|
|
250
322
|
break;
|
|
251
323
|
case Types_1.WAMessageStubType.GROUP_CHANGE_ANNOUNCE:
|
|
252
|
-
const announceValue = (
|
|
324
|
+
const announceValue = (_g = message.messageStubParameters) === null || _g === void 0 ? void 0 : _g[0];
|
|
253
325
|
emitGroupUpdate({ announce: announceValue === 'true' || announceValue === 'on' });
|
|
254
326
|
break;
|
|
255
327
|
case Types_1.WAMessageStubType.GROUP_CHANGE_RESTRICT:
|
|
256
|
-
const restrictValue = (
|
|
328
|
+
const restrictValue = (_h = message.messageStubParameters) === null || _h === void 0 ? void 0 : _h[0];
|
|
257
329
|
emitGroupUpdate({ restrict: restrictValue === 'true' || restrictValue === 'on' });
|
|
258
330
|
break;
|
|
259
331
|
case Types_1.WAMessageStubType.GROUP_CHANGE_SUBJECT:
|
|
260
|
-
const name = (
|
|
332
|
+
const name = (_j = message.messageStubParameters) === null || _j === void 0 ? void 0 : _j[0];
|
|
261
333
|
chat.name = name;
|
|
262
334
|
emitGroupUpdate({ subject: name });
|
|
263
335
|
break;
|
|
336
|
+
case Types_1.WAMessageStubType.GROUP_CHANGE_DESCRIPTION:
|
|
337
|
+
const description = (_k = message.messageStubParameters) === null || _k === void 0 ? void 0 : _k[0];
|
|
338
|
+
chat.description = description;
|
|
339
|
+
emitGroupUpdate({ desc: description });
|
|
340
|
+
break;
|
|
264
341
|
case Types_1.WAMessageStubType.GROUP_CHANGE_INVITE_LINK:
|
|
265
|
-
const code = (
|
|
342
|
+
const code = (_l = message.messageStubParameters) === null || _l === void 0 ? void 0 : _l[0];
|
|
266
343
|
emitGroupUpdate({ inviteCode: code });
|
|
267
344
|
break;
|
|
268
345
|
case Types_1.WAMessageStubType.GROUP_MEMBER_ADD_MODE:
|
|
269
|
-
const memberAddValue = (
|
|
346
|
+
const memberAddValue = (_m = message.messageStubParameters) === null || _m === void 0 ? void 0 : _m[0];
|
|
270
347
|
emitGroupUpdate({ memberAddMode: memberAddValue === 'all_member_add' });
|
|
271
348
|
break;
|
|
272
349
|
case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE:
|
|
273
|
-
const approvalMode = (
|
|
350
|
+
const approvalMode = (_o = message.messageStubParameters) === null || _o === void 0 ? void 0 : _o[0];
|
|
274
351
|
emitGroupUpdate({ joinApprovalMode: approvalMode === 'on' });
|
|
275
352
|
break;
|
|
353
|
+
case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD:
|
|
354
|
+
const participant = (_p = message.messageStubParameters) === null || _p === void 0 ? void 0 : _p[0];
|
|
355
|
+
const action = (_q = message.messageStubParameters) === null || _q === void 0 ? void 0 : _q[1];
|
|
356
|
+
const method = (_r = message.messageStubParameters) === null || _r === void 0 ? void 0 : _r[2];
|
|
357
|
+
emitGroupRequestJoin(participant, action, method);
|
|
358
|
+
break;
|
|
276
359
|
}
|
|
277
360
|
}
|
|
278
361
|
else if (content === null || content === void 0 ? void 0 : content.pollUpdateMessage) {
|
|
@@ -283,7 +366,7 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
283
366
|
const meIdNormalised = (0, WABinary_1.jidNormalizedUser)(meId);
|
|
284
367
|
const pollCreatorJid = (0, generics_1.getKeyAuthor)(creationMsgKey, meIdNormalised);
|
|
285
368
|
const voterJid = (0, generics_1.getKeyAuthor)(message.key, meIdNormalised);
|
|
286
|
-
const pollEncKey = (
|
|
369
|
+
const pollEncKey = (_s = pollMsg.messageContextInfo) === null || _s === void 0 ? void 0 : _s.messageSecret;
|
|
287
370
|
try {
|
|
288
371
|
const voteMsg = decryptPollVote(content.pollUpdateMessage.vote, {
|
|
289
372
|
pollEncKey,
|
package/lib/Utils/signal.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SignalRepository } from '../Types';
|
|
2
2
|
import { AuthenticationCreds, AuthenticationState, KeyPair, SignalIdentity, SignalKeyStore, SignedKeyPair } from '../Types/Auth';
|
|
3
3
|
import { BinaryNode, JidWithDevice } from '../WABinary';
|
|
4
|
+
import { USyncQueryResultList } from '../WAUSync';
|
|
4
5
|
export declare const createSignalIdentity: (wid: string, accountSignatureKey: Uint8Array) => SignalIdentity;
|
|
5
6
|
export declare const getPreKeys: ({ get }: SignalKeyStore, min: number, limit: number) => Promise<{
|
|
6
7
|
[id: string]: KeyPair;
|
|
@@ -15,7 +16,7 @@ export declare const generateOrGetPreKeys: (creds: AuthenticationCreds, range: n
|
|
|
15
16
|
export declare const xmppSignedPreKey: (key: SignedKeyPair) => BinaryNode;
|
|
16
17
|
export declare const xmppPreKey: (pair: KeyPair, id: number) => BinaryNode;
|
|
17
18
|
export declare const parseAndInjectE2ESessions: (node: BinaryNode, repository: SignalRepository) => Promise<void>;
|
|
18
|
-
export declare const extractDeviceJids: (result:
|
|
19
|
+
export declare const extractDeviceJids: (result: USyncQueryResultList[], myJid: string, excludeZeroDevices: boolean) => JidWithDevice[];
|
|
19
20
|
/**
|
|
20
21
|
* get the next N keys for upload or processing
|
|
21
22
|
* @param count number of pre-keys to get or generate
|
package/lib/Utils/signal.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getNextPreKeysNode = exports.getNextPreKeys = exports.extractDeviceJids = exports.parseAndInjectE2ESessions = exports.xmppPreKey = exports.xmppSignedPreKey = exports.generateOrGetPreKeys = exports.getPreKeys = exports.createSignalIdentity = void 0;
|
|
4
|
+
const lodash_1 = require("lodash");
|
|
4
5
|
const Defaults_1 = require("../Defaults");
|
|
5
6
|
const WABinary_1 = require("../WABinary");
|
|
6
7
|
const crypto_1 = require("./crypto");
|
|
7
|
-
const lodash_1 = require("lodash")
|
|
8
8
|
const generics_1 = require("./generics");
|
|
9
9
|
const createSignalIdentity = (wid, accountSignatureKey) => {
|
|
10
10
|
return {
|
|
@@ -59,61 +59,61 @@ const xmppPreKey = (pair, id) => ({
|
|
|
59
59
|
exports.xmppPreKey = xmppPreKey;
|
|
60
60
|
const parseAndInjectE2ESessions = async (node, repository) => {
|
|
61
61
|
const extractKey = (key) => (key ? ({
|
|
62
|
-
keyId: WABinary_1.getBinaryNodeChildUInt(key, 'id', 3),
|
|
63
|
-
publicKey: crypto_1.generateSignalPubKey(WABinary_1.getBinaryNodeChildBuffer(key, 'value')),
|
|
64
|
-
signature: WABinary_1.getBinaryNodeChildBuffer(key, 'signature')
|
|
65
|
-
}) : undefined)
|
|
66
|
-
const nodes = WABinary_1.getBinaryNodeChildren(WABinary_1.getBinaryNodeChild(node, 'list'), 'user')
|
|
62
|
+
keyId: (0, WABinary_1.getBinaryNodeChildUInt)(key, 'id', 3),
|
|
63
|
+
publicKey: (0, crypto_1.generateSignalPubKey)((0, WABinary_1.getBinaryNodeChildBuffer)(key, 'value')),
|
|
64
|
+
signature: (0, WABinary_1.getBinaryNodeChildBuffer)(key, 'signature'),
|
|
65
|
+
}) : undefined);
|
|
66
|
+
const nodes = (0, WABinary_1.getBinaryNodeChildren)((0, WABinary_1.getBinaryNodeChild)(node, 'list'), 'user');
|
|
67
67
|
for (const node of nodes) {
|
|
68
|
-
WABinary_1.assertNodeErrorFree(node)
|
|
68
|
+
(0, WABinary_1.assertNodeErrorFree)(node);
|
|
69
69
|
}
|
|
70
70
|
// Most of the work in repository.injectE2ESession is CPU intensive, not IO
|
|
71
71
|
// So Promise.all doesn't really help here,
|
|
72
72
|
// but blocks even loop if we're using it inside keys.transaction, and it makes it "sync" actually
|
|
73
73
|
// This way we chunk it in smaller parts and between those parts we can yield to the event loop
|
|
74
74
|
// It's rare case when you need to E2E sessions for so many users, but it's possible
|
|
75
|
-
const chunkSize = 100
|
|
76
|
-
const chunks = lodash_1.chunk(nodes, chunkSize)
|
|
75
|
+
const chunkSize = 100;
|
|
76
|
+
const chunks = (0, lodash_1.chunk)(nodes, chunkSize);
|
|
77
77
|
for (const nodesChunk of chunks) {
|
|
78
78
|
await Promise.all(nodesChunk.map(async (node) => {
|
|
79
|
-
const signedKey = WABinary_1.getBinaryNodeChild(node, 'skey')
|
|
80
|
-
const key = WABinary_1.getBinaryNodeChild(node, 'key')
|
|
81
|
-
const identity = WABinary_1.getBinaryNodeChildBuffer(node, 'identity')
|
|
82
|
-
const jid = node.attrs.jid
|
|
83
|
-
const registrationId = WABinary_1.getBinaryNodeChildUInt(node, 'registration', 4)
|
|
79
|
+
const signedKey = (0, WABinary_1.getBinaryNodeChild)(node, 'skey');
|
|
80
|
+
const key = (0, WABinary_1.getBinaryNodeChild)(node, 'key');
|
|
81
|
+
const identity = (0, WABinary_1.getBinaryNodeChildBuffer)(node, 'identity');
|
|
82
|
+
const jid = node.attrs.jid;
|
|
83
|
+
const registrationId = (0, WABinary_1.getBinaryNodeChildUInt)(node, 'registration', 4);
|
|
84
84
|
await repository.injectE2ESession({
|
|
85
85
|
jid,
|
|
86
86
|
session: {
|
|
87
87
|
registrationId: registrationId,
|
|
88
|
-
identityKey: crypto_1.generateSignalPubKey(identity),
|
|
88
|
+
identityKey: (0, crypto_1.generateSignalPubKey)(identity),
|
|
89
89
|
signedPreKey: extractKey(signedKey),
|
|
90
90
|
preKey: extractKey(key)
|
|
91
91
|
}
|
|
92
|
-
})
|
|
93
|
-
}))
|
|
92
|
+
});
|
|
93
|
+
}));
|
|
94
94
|
}
|
|
95
|
-
}
|
|
95
|
+
};
|
|
96
96
|
exports.parseAndInjectE2ESessions = parseAndInjectE2ESessions;
|
|
97
97
|
const extractDeviceJids = (result, myJid, excludeZeroDevices) => {
|
|
98
|
-
const { user: myUser, device: myDevice } = WABinary_1.jidDecode(myJid)
|
|
99
|
-
const extracted = []
|
|
98
|
+
const { user: myUser, device: myDevice } = (0, WABinary_1.jidDecode)(myJid);
|
|
99
|
+
const extracted = [];
|
|
100
100
|
for (const userResult of result) {
|
|
101
|
-
const { devices, id } = userResult
|
|
102
|
-
const { user } = WABinary_1.jidDecode(id)
|
|
103
|
-
const deviceList = devices
|
|
101
|
+
const { devices, id } = userResult;
|
|
102
|
+
const { user } = (0, WABinary_1.jidDecode)(id);
|
|
103
|
+
const deviceList = devices === null || devices === void 0 ? void 0 : devices.deviceList;
|
|
104
104
|
if (Array.isArray(deviceList)) {
|
|
105
105
|
for (const { id: device, keyIndex } of deviceList) {
|
|
106
106
|
if ((!excludeZeroDevices || device !== 0) && // if zero devices are not-excluded, or device is non zero
|
|
107
107
|
(myUser !== user || myDevice !== device) && // either different user or if me user, not this device
|
|
108
108
|
(device === 0 || !!keyIndex) // ensure that "key-index" is specified for "non-zero" devices, produces a bad req otherwise
|
|
109
109
|
) {
|
|
110
|
-
extracted.push({ user, device })
|
|
110
|
+
extracted.push({ user, device });
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
return extracted
|
|
116
|
-
}
|
|
115
|
+
return extracted;
|
|
116
|
+
};
|
|
117
117
|
exports.extractDeviceJids = extractDeviceJids;
|
|
118
118
|
/**
|
|
119
119
|
* get the next N keys for upload or processing
|
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.useMultiFileAuthState = void 0;
|
|
4
|
+
const async_mutex_1 = require("async-mutex");
|
|
4
5
|
const promises_1 = require("fs/promises");
|
|
5
6
|
const path_1 = require("path");
|
|
6
7
|
const WAProto_1 = require("../../WAProto");
|
|
7
8
|
const auth_utils_1 = require("./auth-utils");
|
|
8
9
|
const generics_1 = require("./generics");
|
|
10
|
+
// We need to lock files due to the fact that we are using async functions to read and write files
|
|
11
|
+
// https://github.com/WhiskeySockets/Baileys/issues/794
|
|
12
|
+
// https://github.com/nodejs/node/issues/26338
|
|
13
|
+
// Use a Map to store mutexes for each file path
|
|
14
|
+
const fileLocks = new Map();
|
|
15
|
+
// Get or create a mutex for a specific file path
|
|
16
|
+
const getFileLock = (path) => {
|
|
17
|
+
let mutex = fileLocks.get(path);
|
|
18
|
+
if (!mutex) {
|
|
19
|
+
mutex = new async_mutex_1.Mutex();
|
|
20
|
+
fileLocks.set(path, mutex);
|
|
21
|
+
}
|
|
22
|
+
return mutex;
|
|
23
|
+
};
|
|
9
24
|
/**
|
|
10
25
|
* stores the full authentication state in a single folder.
|
|
11
26
|
* Far more efficient than singlefileauthstate
|
|
@@ -14,13 +29,32 @@ const generics_1 = require("./generics");
|
|
|
14
29
|
* Would recommend writing an auth state for use with a proper SQL or No-SQL DB
|
|
15
30
|
* */
|
|
16
31
|
const useMultiFileAuthState = async (folder) => {
|
|
17
|
-
|
|
18
|
-
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
+
const writeData = async (data, file) => {
|
|
34
|
+
const filePath = (0, path_1.join)(folder, fixFileName(file));
|
|
35
|
+
const mutex = getFileLock(filePath);
|
|
36
|
+
return mutex.acquire().then(async (release) => {
|
|
37
|
+
try {
|
|
38
|
+
await (0, promises_1.writeFile)(filePath, JSON.stringify(data, generics_1.BufferJSON.replacer));
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
release();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
19
44
|
};
|
|
20
45
|
const readData = async (file) => {
|
|
21
46
|
try {
|
|
22
|
-
const
|
|
23
|
-
|
|
47
|
+
const filePath = (0, path_1.join)(folder, fixFileName(file));
|
|
48
|
+
const mutex = getFileLock(filePath);
|
|
49
|
+
return await mutex.acquire().then(async (release) => {
|
|
50
|
+
try {
|
|
51
|
+
const data = await (0, promises_1.readFile)(filePath, { encoding: 'utf-8' });
|
|
52
|
+
return JSON.parse(data, generics_1.BufferJSON.reviver);
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
release();
|
|
56
|
+
}
|
|
57
|
+
});
|
|
24
58
|
}
|
|
25
59
|
catch (error) {
|
|
26
60
|
return null;
|
|
@@ -28,7 +62,18 @@ const useMultiFileAuthState = async (folder) => {
|
|
|
28
62
|
};
|
|
29
63
|
const removeData = async (file) => {
|
|
30
64
|
try {
|
|
31
|
-
|
|
65
|
+
const filePath = (0, path_1.join)(folder, fixFileName(file));
|
|
66
|
+
const mutex = getFileLock(filePath);
|
|
67
|
+
return mutex.acquire().then(async (release) => {
|
|
68
|
+
try {
|
|
69
|
+
await (0, promises_1.unlink)(filePath);
|
|
70
|
+
}
|
|
71
|
+
catch (_a) {
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
release();
|
|
75
|
+
}
|
|
76
|
+
});
|
|
32
77
|
}
|
|
33
78
|
catch (_a) {
|
|
34
79
|
}
|
|
@@ -72,7 +117,7 @@ const useMultiFileAuthState = async (folder) => {
|
|
|
72
117
|
}
|
|
73
118
|
}
|
|
74
119
|
},
|
|
75
|
-
saveCreds: () => {
|
|
120
|
+
saveCreds: async () => {
|
|
76
121
|
return writeData(creds, 'creds.json');
|
|
77
122
|
}
|
|
78
123
|
};
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { proto } from '../../WAProto';
|
|
2
2
|
import type { AuthenticationCreds, SignalCreds, SocketConfig } from '../Types';
|
|
3
3
|
import { BinaryNode } from '../WABinary';
|
|
4
|
-
export declare const generateMobileNode: (config: SocketConfig) => proto.IClientPayload;
|
|
5
4
|
export declare const generateLoginNode: (userJid: string, config: SocketConfig) => proto.IClientPayload;
|
|
6
5
|
export declare const generateRegistrationNode: ({ registrationId, signedPreKey, signedIdentityKey }: SignalCreds, config: SocketConfig) => proto.ClientPayload;
|
|
7
|
-
export declare const configureSuccessfulPairing: (stanza: BinaryNode, { advSecretKey, signedIdentityKey, signalIdentities }: Pick<AuthenticationCreds,
|
|
6
|
+
export declare const configureSuccessfulPairing: (stanza: BinaryNode, { advSecretKey, signedIdentityKey, signalIdentities }: Pick<AuthenticationCreds, "advSecretKey" | "signedIdentityKey" | "signalIdentities">) => {
|
|
8
7
|
creds: Partial<AuthenticationCreds>;
|
|
9
8
|
reply: BinaryNode;
|
|
10
|
-
};
|
|
11
|
-
export declare const encodeSignedDeviceIdentity: (account: proto.IADVSignedDeviceIdentity, includeSignatureKey: boolean) => Uint8Array
|
|
9
|
+
};
|
|
10
|
+
export declare const encodeSignedDeviceIdentity: (account: proto.IADVSignedDeviceIdentity, includeSignatureKey: boolean) => Uint8Array<ArrayBufferLike>;
|