amiudmodz 4.0.6 → 5.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/README.md +130 -0
- package/lib/Defaults/index.js +9 -4
- package/lib/Socket/Client/web-socket-client.js +13 -5
- package/lib/Socket/chats.js +50 -77
- package/lib/Socket/groupStatus.js +51 -41
- package/lib/Socket/groups.js +8 -5
- package/lib/Socket/messages-recv.js +26 -10
- package/lib/Socket/messages-send.js +38 -42
- package/lib/Socket/newsletter.js +1 -1
- package/lib/Socket/socket.js +18 -6
- package/lib/Utils/auth-utils.js +9 -1
- package/lib/Utils/crypto.js +10 -2
- package/lib/Utils/event-buffer.js +14 -17
- package/lib/Utils/make-mutex.js +20 -16
- package/lib/Utils/messages-media.js +15 -10
- package/lib/Utils/messages.js +6 -2
- package/lib/Utils/noise-handler.js +27 -13
- package/lib/Utils/process-message.js +30 -22
- package/lib/Utils/use-multi-file-auth-state.js +10 -5
- package/lib/WABinary/decode.js +21 -11
- package/lib/WABinary/encode.js +8 -8
- package/package.json +11 -1
|
@@ -68,7 +68,9 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
68
68
|
let writeCounter = 0;
|
|
69
69
|
let isFinished = false;
|
|
70
70
|
let sentIntro = false;
|
|
71
|
-
|
|
71
|
+
|
|
72
|
+
let inChunks = [];
|
|
73
|
+
let inBytesLength = 0;
|
|
72
74
|
authenticate(NOISE_HEADER);
|
|
73
75
|
authenticate(publicKey);
|
|
74
76
|
return {
|
|
@@ -128,26 +130,38 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
128
130
|
decodeFrame: (newData, onFrame) => {
|
|
129
131
|
var _a;
|
|
130
132
|
|
|
133
|
+
inChunks.push(newData);
|
|
134
|
+
inBytesLength += newData.length;
|
|
135
|
+
logger.trace(`recv ${newData.length} bytes, total recv ${inBytesLength} bytes`);
|
|
136
|
+
|
|
137
|
+
while (inBytesLength >= 3) {
|
|
138
|
+
// Only concat when necessary
|
|
139
|
+
if (inChunks.length > 1) {
|
|
140
|
+
const combined = Buffer.concat(inChunks);
|
|
141
|
+
inChunks = [combined];
|
|
142
|
+
}
|
|
143
|
+
const inBytes = inChunks[0];
|
|
144
|
+
const size = (inBytes.readUInt8(0) << 16) | inBytes.readUInt16BE(1);
|
|
145
|
+
if (inBytesLength < size + 3) {
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
131
148
|
|
|
149
|
+
let frame = inBytes.subarray(3, size + 3);
|
|
132
150
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
151
|
+
const remaining = inBytes.subarray(size + 3);
|
|
152
|
+
// Reuse existing buffer reference when possible
|
|
153
|
+
if (remaining.length > 0) {
|
|
154
|
+
inChunks = [remaining];
|
|
155
|
+
} else {
|
|
156
|
+
inChunks = [];
|
|
136
157
|
}
|
|
137
|
-
|
|
138
|
-
inBytes = Buffer.concat([inBytes, newData]);
|
|
139
|
-
logger.trace(`recv ${newData.length} bytes, total recv ${inBytes.length} bytes`);
|
|
140
|
-
let size = getBytesSize();
|
|
141
|
-
while (size && inBytes.length >= size + 3) {
|
|
142
|
-
let frame = inBytes.slice(3, size + 3);
|
|
143
|
-
inBytes = inBytes.slice(size + 3);
|
|
158
|
+
inBytesLength -= (size + 3);
|
|
144
159
|
if (isFinished) {
|
|
145
160
|
const result = decrypt(frame);
|
|
146
161
|
frame = (0, WABinary_1.decodeBinaryNode)(result);
|
|
147
162
|
}
|
|
148
|
-
logger.trace({ msg: (_a = frame
|
|
163
|
+
logger.trace({ msg: (_a = frame?.attrs)?.id }, 'recv frame');
|
|
149
164
|
onFrame(frame);
|
|
150
|
-
size = getBytesSize();
|
|
151
165
|
}
|
|
152
166
|
}
|
|
153
167
|
};
|
|
@@ -154,6 +154,9 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
154
154
|
await keyStore.transaction(async () => {
|
|
155
155
|
const newKeys = [];
|
|
156
156
|
for (const { keyData, keyId } of keys) {
|
|
157
|
+
if (!keyId?.keyId) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
157
160
|
const strKeyId = Buffer.from(keyId.keyId).toString('base64');
|
|
158
161
|
newKeys.push(strKeyId);
|
|
159
162
|
await keyStore.set({ 'app-state-sync-key': { [strKeyId]: keyData } });
|
|
@@ -284,30 +287,35 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
284
287
|
const pollCreatorJid = (0, generics_1.getKeyAuthor)(creationMsgKey, meIdNormalised);
|
|
285
288
|
const voterJid = (0, generics_1.getKeyAuthor)(message.key, meIdNormalised);
|
|
286
289
|
const pollEncKey = (_k = pollMsg.messageContextInfo) === null || _k === void 0 ? void 0 : _k.messageSecret;
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
290
|
+
if (pollEncKey) {
|
|
291
|
+
try {
|
|
292
|
+
const voteMsg = decryptPollVote(content.pollUpdateMessage.vote, {
|
|
293
|
+
pollEncKey,
|
|
294
|
+
pollCreatorJid,
|
|
295
|
+
pollMsgId: creationMsgKey.id,
|
|
296
|
+
voterJid,
|
|
297
|
+
});
|
|
298
|
+
ev.emit('messages.update', [
|
|
299
|
+
{
|
|
300
|
+
key: creationMsgKey,
|
|
301
|
+
update: {
|
|
302
|
+
pollUpdates: [
|
|
303
|
+
{
|
|
304
|
+
pollUpdateMessageKey: message.key,
|
|
305
|
+
vote: voteMsg,
|
|
306
|
+
senderTimestampMs: content.pollUpdateMessage.senderTimestampMs.toNumber(),
|
|
307
|
+
}
|
|
308
|
+
]
|
|
309
|
+
}
|
|
305
310
|
}
|
|
306
|
-
|
|
307
|
-
|
|
311
|
+
]);
|
|
312
|
+
}
|
|
313
|
+
catch (err) {
|
|
314
|
+
logger === null || logger === void 0 ? void 0 : logger.warn({ err, creationMsgKey }, 'failed to decrypt poll vote');
|
|
315
|
+
}
|
|
308
316
|
}
|
|
309
|
-
|
|
310
|
-
logger === null || logger === void 0 ? void 0 : logger.warn({
|
|
317
|
+
else {
|
|
318
|
+
logger === null || logger === void 0 ? void 0 : logger.warn({ creationMsgKey }, 'poll secret key not found, cannot decrypt update');
|
|
311
319
|
}
|
|
312
320
|
}
|
|
313
321
|
else {
|
|
@@ -17,6 +17,13 @@ const useMultiFileAuthState = async (folder) => {
|
|
|
17
17
|
}
|
|
18
18
|
return mutex;
|
|
19
19
|
};
|
|
20
|
+
const releaseFileLock = (path) => {
|
|
21
|
+
// Clean up mutex if no more waiters to prevent memory leak
|
|
22
|
+
const mutex = fileLocks.get(path);
|
|
23
|
+
if (mutex && !mutex.isLocked()) {
|
|
24
|
+
fileLocks.delete(path);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
20
27
|
const writeData = async (data, file) => {
|
|
21
28
|
const filePath = (0, path_1.join)(folder, fixFileName(file));
|
|
22
29
|
const tempPath = filePath + '.tmp';
|
|
@@ -27,12 +34,12 @@ const useMultiFileAuthState = async (folder) => {
|
|
|
27
34
|
await (0, promises_1.rename)(tempPath, filePath);
|
|
28
35
|
}
|
|
29
36
|
catch (error) {
|
|
30
|
-
|
|
31
37
|
await (0, promises_1.unlink)(tempPath).catch(() => { });
|
|
32
38
|
throw error;
|
|
33
39
|
}
|
|
34
40
|
finally {
|
|
35
41
|
release();
|
|
42
|
+
releaseFileLock(filePath);
|
|
36
43
|
}
|
|
37
44
|
});
|
|
38
45
|
};
|
|
@@ -47,6 +54,7 @@ const useMultiFileAuthState = async (folder) => {
|
|
|
47
54
|
}
|
|
48
55
|
finally {
|
|
49
56
|
release();
|
|
57
|
+
releaseFileLock(filePath);
|
|
50
58
|
}
|
|
51
59
|
});
|
|
52
60
|
}
|
|
@@ -54,10 +62,6 @@ const useMultiFileAuthState = async (folder) => {
|
|
|
54
62
|
if (error.code === 'ENOENT') {
|
|
55
63
|
return null;
|
|
56
64
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
65
|
return null;
|
|
62
66
|
}
|
|
63
67
|
};
|
|
@@ -73,6 +77,7 @@ const useMultiFileAuthState = async (folder) => {
|
|
|
73
77
|
}
|
|
74
78
|
finally {
|
|
75
79
|
release();
|
|
80
|
+
releaseFileLock(filePath);
|
|
76
81
|
}
|
|
77
82
|
});
|
|
78
83
|
}
|
package/lib/WABinary/decode.js
CHANGED
|
@@ -65,10 +65,19 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
65
65
|
const readInt = (n, littleEndian = false) => {
|
|
66
66
|
checkEOS(n);
|
|
67
67
|
let val = 0;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
if (n === 4) {
|
|
69
|
+
val = littleEndian ? buffer.readUInt32LE(indexRef.index) : buffer.readUInt32BE(indexRef.index);
|
|
70
|
+
} else if (n === 2) {
|
|
71
|
+
val = littleEndian ? buffer.readUInt16LE(indexRef.index) : buffer.readUInt16BE(indexRef.index);
|
|
72
|
+
} else if (n === 1) {
|
|
73
|
+
val = buffer[indexRef.index];
|
|
74
|
+
} else {
|
|
75
|
+
for (let i = 0; i < n; i++) {
|
|
76
|
+
const shift = littleEndian ? i : n - 1 - i;
|
|
77
|
+
val |= buffer[indexRef.index + i] << (shift * 8);
|
|
78
|
+
}
|
|
71
79
|
}
|
|
80
|
+
indexRef.index += n;
|
|
72
81
|
return val;
|
|
73
82
|
};
|
|
74
83
|
const readInt20 = () => {
|
|
@@ -109,16 +118,17 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
109
118
|
};
|
|
110
119
|
const readPacked8 = (tag) => {
|
|
111
120
|
const startByte = readByte();
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
const length = startByte & 127;
|
|
122
|
+
const charCount = (length * 2) - (startByte >> 7 !== 0 ? 1 : 0);
|
|
123
|
+
const chars = new Array(charCount);
|
|
124
|
+
for (let i = 0; i < length; i++) {
|
|
114
125
|
const curByte = readByte();
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
value = value.slice(0, -1);
|
|
126
|
+
chars[i * 2] = String.fromCharCode(unpackByte(tag, (curByte & 0xf0) >> 4));
|
|
127
|
+
if (i * 2 + 1 < charCount) {
|
|
128
|
+
chars[i * 2 + 1] = String.fromCharCode(unpackByte(tag, curByte & 0x0f));
|
|
129
|
+
}
|
|
120
130
|
}
|
|
121
|
-
return
|
|
131
|
+
return chars.join('');
|
|
122
132
|
};
|
|
123
133
|
const isListTag = (tag) => {
|
|
124
134
|
return tag === TAGS.LIST_EMPTY || tag === TAGS.LIST_8 || tag === TAGS.LIST_16;
|
package/lib/WABinary/encode.js
CHANGED
|
@@ -47,8 +47,12 @@ const encodeBinaryNodeInner = ({ tag, attrs, content }, opts, buffer) => {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
const pushBytes = (bytes) => {
|
|
50
|
-
|
|
51
|
-
buffer.push(
|
|
50
|
+
if (bytes.length < 1000) {
|
|
51
|
+
buffer.push(...bytes);
|
|
52
|
+
} else {
|
|
53
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
54
|
+
buffer.push(bytes[i]);
|
|
55
|
+
}
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
|
|
@@ -143,16 +147,12 @@ const encodeBinaryNodeInner = ({ tag, attrs, content }, opts, buffer) => {
|
|
|
143
147
|
}
|
|
144
148
|
pushByte(roundedLength)
|
|
145
149
|
const packFunction = type === 'nibble' ? packNibble : packHex
|
|
146
|
-
const packBytePair = (v1, v2) => {
|
|
147
|
-
const result = (packFunction(v1) << 4) | packFunction(v2)
|
|
148
|
-
return result
|
|
149
|
-
}
|
|
150
150
|
const strLengthHalf = Math.floor(str.length / 2)
|
|
151
151
|
for (let i = 0; i < strLengthHalf; i++) {
|
|
152
|
-
|
|
152
|
+
buffer.push((packFunction(str[2 * i]) << 4) | packFunction(str[2 * i + 1]))
|
|
153
153
|
}
|
|
154
154
|
if (str.length % 2 !== 0) {
|
|
155
|
-
|
|
155
|
+
buffer.push((packFunction(str[str.length - 1]) << 4) | 15)
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amiudmodz",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
|
+
"description": "WhatsApp Baileys mod Powered by UDMODZ",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"whatsapp",
|
|
7
|
+
"baileys",
|
|
8
|
+
"udmodz",
|
|
9
|
+
"bot",
|
|
10
|
+
"whatsapp-api",
|
|
11
|
+
"whatsapp-web",
|
|
12
|
+
"badiys"
|
|
13
|
+
],
|
|
4
14
|
"main": "lib/index.js",
|
|
5
15
|
"types": "lib/index.d.ts",
|
|
6
16
|
"files": [
|