@crysnovax/baileys 2.5.5 → 2.6.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/lib/Defaults/index.js +4 -5
- package/lib/Signal/libsignal.js +0 -2
- package/lib/Socket/business.js +2 -1
- package/lib/Socket/chats.js +1 -2
- package/lib/Socket/communities.js +2 -1
- package/lib/Socket/groups.js +24 -5
- package/lib/Socket/messages-recv.js +0 -1
- package/lib/Socket/messages-send.js +14 -15
- package/lib/Socket/newsletter.js +6 -6
- package/lib/Socket/socket.js +44 -7
- package/lib/Types/Mex.js +1 -1
- package/lib/Types/State.js +37 -1
- package/lib/Types/index.js +1 -2
- package/lib/Utils/auth-utils.js +13 -1
- package/lib/Utils/chat-utils.js +81 -21
- package/lib/Utils/decode-wa-message.js +35 -1
- package/lib/Utils/messages-media.js +28 -16
- package/lib/Utils/messages.js +257 -318
- package/lib/Utils/signal.js +43 -1
- package/lib/Utils/tc-token-utils.js +150 -5
- package/lib/Utils/use-sqlite-auth-state.js +0 -1
- package/lib/WABinary/constants.js +5 -8
- package/package.json +12 -11
- package/lib/Socket/Client//342/234/230 +0 -1
- package/lib/Socket//342/230/201/357/270/216 +0 -1
- package/lib/Types/Newsletter.js +0 -33
- package/lib/Types//342/234/206 +0 -1
- package/lib/Utils//342/232/211 +0 -1
- package/lib/WABinary//342/216/231 +0 -1
package/lib/Defaults/index.js
CHANGED
|
@@ -96,7 +96,7 @@ export const MEDIA_PATH_MAP = {
|
|
|
96
96
|
'md-msg-hist': '/mms/md-app-state',
|
|
97
97
|
'biz-cover-photo': '/pps/biz-cover-photo'
|
|
98
98
|
};
|
|
99
|
-
//
|
|
99
|
+
// Lia@Changes 06-02-26 --- Add newsletter media path for "/m1/" instead of "/o1/" (≧▽≦)
|
|
100
100
|
export const NEWSLETTER_MEDIA_PATH_MAP = {
|
|
101
101
|
image: '/newsletter/newsletter-image',
|
|
102
102
|
video: '/newsletter/newsletter-video',
|
|
@@ -132,6 +132,9 @@ export const MEDIA_HKDF_KEY_MAPPING = {
|
|
|
132
132
|
'voip-token': 'Voip Token'
|
|
133
133
|
};
|
|
134
134
|
export const MEDIA_KEYS = Object.keys(MEDIA_PATH_MAP);
|
|
135
|
+
export const MIN_PREKEY_COUNT = 5;
|
|
136
|
+
export const INITIAL_PREKEY_COUNT = 812;
|
|
137
|
+
export const UPLOAD_TIMEOUT = 30000; // 30 seconds
|
|
135
138
|
export const DEFAULT_CACHE_TTLS = {
|
|
136
139
|
SIGNAL_STORE: 5 * 60, // 5 minutes
|
|
137
140
|
MSG_RETRY: 60 * 60, // 1 hour
|
|
@@ -140,9 +143,6 @@ export const DEFAULT_CACHE_TTLS = {
|
|
|
140
143
|
};
|
|
141
144
|
/** 120s timeout for history sync stall detection, same as WA Web's handleChunkProgress / restartPausedTimer (g = 120) */
|
|
142
145
|
export const HISTORY_SYNC_PAUSED_TIMEOUT_MS = 120000;
|
|
143
|
-
export const MIN_PREKEY_COUNT = 5;
|
|
144
|
-
export const INITIAL_PREKEY_COUNT = 812;
|
|
145
|
-
export const UPLOAD_TIMEOUT = 30000; // 30 seconds
|
|
146
146
|
export const TimeMs = {
|
|
147
147
|
Minute: 60 * 1000,
|
|
148
148
|
Hour: 60 * 60 * 1000,
|
|
@@ -153,4 +153,3 @@ export const BOT_RENDERING_CONFIG_METADATA = {
|
|
|
153
153
|
bloksVersioningId: '0903aa5f7f47de66789d5f4c86d3bd6e05e4bc3ff85e454a9f907d5ed7fef97c',
|
|
154
154
|
pixelDensity: 2.75
|
|
155
155
|
};
|
|
156
|
-
|
package/lib/Signal/libsignal.js
CHANGED
|
@@ -157,8 +157,6 @@ export function makeLibSignalRepository(auth, logger, pnToLIDFunc) {
|
|
|
157
157
|
logger.trace({ jid }, 'injecting E2EE session');
|
|
158
158
|
const cipher = new libsignal.SessionBuilder(storage, jidToSignalProtocolAddress(jid));
|
|
159
159
|
return parsedKeys.transaction(async () => {
|
|
160
|
-
// libsignal runtime accepts an absent prekey (initOutgoing checks `device.preKey && ...`)
|
|
161
|
-
// but the bundled .d.ts marks it required.
|
|
162
160
|
await cipher.initOutgoing(session);
|
|
163
161
|
}, jid);
|
|
164
162
|
},
|
package/lib/Socket/business.js
CHANGED
package/lib/Socket/chats.js
CHANGED
|
@@ -187,7 +187,7 @@ export const makeChatsSocket = (config) => {
|
|
|
187
187
|
return result.list;
|
|
188
188
|
}
|
|
189
189
|
};
|
|
190
|
-
//
|
|
190
|
+
// Lia@Note 06-02-26 --- Quick helper only. This function exists solely for faster lookup with caching.
|
|
191
191
|
const findUserId = async (pnLid) => {
|
|
192
192
|
const normalizedJid = jidNormalizedUser(pnLid);
|
|
193
193
|
const userId = {
|
|
@@ -1211,4 +1211,3 @@ export const makeChatsSocket = (config) => {
|
|
|
1211
1211
|
removeQuickReply
|
|
1212
1212
|
};
|
|
1213
1213
|
};
|
|
1214
|
-
//# sourceMappingURL=chats.js.map
|
|
@@ -85,6 +85,7 @@ export const makeCommunitiesSocket = (config) => {
|
|
|
85
85
|
});
|
|
86
86
|
return {
|
|
87
87
|
...sock,
|
|
88
|
+
communityQuery,
|
|
88
89
|
communityMetadata,
|
|
89
90
|
communityCreate: async (subject, body) => {
|
|
90
91
|
const descriptionId = generateMessageID().substring(0, 12);
|
|
@@ -427,4 +428,4 @@ export const extractCommunityMetadata = (result) => {
|
|
|
427
428
|
addressingMode: getBinaryNodeChildString(community, 'addressing_mode')
|
|
428
429
|
};
|
|
429
430
|
return metadata;
|
|
430
|
-
};
|
|
431
|
+
};
|
package/lib/Socket/groups.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Boom } from '@hapi/boom';
|
|
1
2
|
import { proto } from '../../WAProto/index.js';
|
|
2
3
|
import { WAMessageAddressingMode, WAMessageStubType } from '../Types/index.js';
|
|
3
4
|
import { generateMessageIDV2, unixTimestampSeconds } from '../Utils/index.js';
|
|
@@ -38,7 +39,7 @@ export const makeGroupsSocket = (config) => {
|
|
|
38
39
|
}
|
|
39
40
|
]
|
|
40
41
|
});
|
|
41
|
-
const data =
|
|
42
|
+
const data = {};
|
|
42
43
|
const groupsChild = getBinaryNodeChild(result, 'groups');
|
|
43
44
|
if (groupsChild) {
|
|
44
45
|
const groups = getBinaryNodeChildren(groupsChild, 'group');
|
|
@@ -65,7 +66,7 @@ export const makeGroupsSocket = (config) => {
|
|
|
65
66
|
});
|
|
66
67
|
return {
|
|
67
68
|
...sock,
|
|
68
|
-
|
|
69
|
+
groupQuery,
|
|
69
70
|
groupMetadata,
|
|
70
71
|
groupCreate: async (subject, participants) => {
|
|
71
72
|
const key = generateMessageIDV2();
|
|
@@ -266,22 +267,36 @@ export const makeGroupsSocket = (config) => {
|
|
|
266
267
|
{ tag: 'membership_approval_mode', attrs: {}, content: [{ tag: 'group_join', attrs: { state: mode } }] }
|
|
267
268
|
]);
|
|
268
269
|
},
|
|
269
|
-
groupFetchAllParticipating
|
|
270
|
-
groupQuery
|
|
270
|
+
groupFetchAllParticipating
|
|
271
271
|
};
|
|
272
272
|
};
|
|
273
273
|
export const extractGroupMetadata = (result) => {
|
|
274
274
|
const group = getBinaryNodeChild(result, 'group');
|
|
275
|
+
if (!group) {
|
|
276
|
+
// Mirror WAWeb: surface server/client errors with their code+text instead of crashing.
|
|
277
|
+
const errorNode = getBinaryNodeChild(result, 'error');
|
|
278
|
+
if (errorNode) {
|
|
279
|
+
const code = errorNode.attrs.code ? +errorNode.attrs.code : 500;
|
|
280
|
+
const text = errorNode.attrs.text || 'group metadata query failed';
|
|
281
|
+
throw new Boom(text, { statusCode: code, data: errorNode });
|
|
282
|
+
}
|
|
283
|
+
throw new Boom('Invalid group metadata response: missing <group> node', { data: result });
|
|
284
|
+
}
|
|
285
|
+
if (!group.attrs.id) {
|
|
286
|
+
throw new Boom('Invalid group metadata response: missing group id', { data: group });
|
|
287
|
+
}
|
|
275
288
|
const descChild = getBinaryNodeChild(group, 'description');
|
|
276
289
|
let desc;
|
|
277
290
|
let descId;
|
|
278
291
|
let descOwner;
|
|
279
292
|
let descOwnerPn;
|
|
293
|
+
let descOwnerUsername;
|
|
280
294
|
let descTime;
|
|
281
295
|
if (descChild) {
|
|
282
296
|
desc = getBinaryNodeChildString(descChild, 'body');
|
|
283
297
|
descOwner = descChild.attrs.participant ? jidNormalizedUser(descChild.attrs.participant) : undefined;
|
|
284
298
|
descOwnerPn = descChild.attrs.participant_pn ? jidNormalizedUser(descChild.attrs.participant_pn) : undefined;
|
|
299
|
+
descOwnerUsername = descChild.attrs.participant_username || undefined;
|
|
285
300
|
descTime = +descChild.attrs.t;
|
|
286
301
|
descId = descChild.attrs.id;
|
|
287
302
|
}
|
|
@@ -295,16 +310,19 @@ export const extractGroupMetadata = (result) => {
|
|
|
295
310
|
subject: group.attrs.subject,
|
|
296
311
|
subjectOwner: group.attrs.s_o,
|
|
297
312
|
subjectOwnerPn: group.attrs.s_o_pn,
|
|
313
|
+
subjectOwnerUsername: group.attrs.s_o_username,
|
|
298
314
|
subjectTime: +group.attrs.s_t,
|
|
299
315
|
size: group.attrs.size ? +group.attrs.size : getBinaryNodeChildren(group, 'participant').length,
|
|
300
316
|
creation: +group.attrs.creation,
|
|
301
317
|
owner: group.attrs.creator ? jidNormalizedUser(group.attrs.creator) : undefined,
|
|
302
318
|
ownerPn: group.attrs.creator_pn ? jidNormalizedUser(group.attrs.creator_pn) : undefined,
|
|
319
|
+
ownerUsername: group.attrs.creator_username || undefined,
|
|
303
320
|
owner_country_code: group.attrs.creator_country_code,
|
|
304
321
|
desc,
|
|
305
322
|
descId,
|
|
306
323
|
descOwner,
|
|
307
324
|
descOwnerPn,
|
|
325
|
+
descOwnerUsername,
|
|
308
326
|
descTime,
|
|
309
327
|
linkedParent: getBinaryNodeChild(group, 'linked_parent')?.attrs.jid || undefined,
|
|
310
328
|
restrict: !!getBinaryNodeChild(group, 'locked'),
|
|
@@ -319,10 +337,11 @@ export const extractGroupMetadata = (result) => {
|
|
|
319
337
|
id: attrs.jid,
|
|
320
338
|
phoneNumber: isLidUser(attrs.jid) && isPnUser(attrs.phone_number) ? attrs.phone_number : undefined,
|
|
321
339
|
lid: isPnUser(attrs.jid) && isLidUser(attrs.lid) ? attrs.lid : undefined,
|
|
340
|
+
username: attrs.participant_username || attrs.username || undefined,
|
|
322
341
|
admin: (attrs.type || null)
|
|
323
342
|
};
|
|
324
343
|
}),
|
|
325
344
|
ephemeralDuration: eph ? +eph : undefined
|
|
326
345
|
};
|
|
327
346
|
return metadata;
|
|
328
|
-
};
|
|
347
|
+
};
|
|
@@ -472,7 +472,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
472
472
|
});
|
|
473
473
|
}
|
|
474
474
|
await authState.keys.transaction(async () => {
|
|
475
|
-
//
|
|
475
|
+
// Lia@Changes 02-02-26 --- Normalize message first to extract the original message and valid media type
|
|
476
476
|
const innerMessage = normalizeMessageContent(message);
|
|
477
477
|
const mediaType = getMediaType(innerMessage);
|
|
478
478
|
if (mediaType) {
|
|
@@ -481,14 +481,14 @@ export const makeMessagesSocket = (config) => {
|
|
|
481
481
|
if (isNewsletter) {
|
|
482
482
|
const patched = patchMessageBeforeSending ? await patchMessageBeforeSending(message, []) : message;
|
|
483
483
|
const bytes = encodeNewsletterMessage(patched);
|
|
484
|
-
//
|
|
484
|
+
// Lia@Changes 08-02-26 --- Add "additionalNodes" for newsletter too (っ˘̩╭╮˘̩)っ
|
|
485
485
|
if (additionalNodes && additionalNodes.length > 0) {
|
|
486
486
|
;
|
|
487
487
|
binaryNodeContent.push(...additionalNodes);
|
|
488
488
|
}
|
|
489
489
|
binaryNodeContent.push({
|
|
490
490
|
tag: 'plaintext',
|
|
491
|
-
attrs: extraAttrs, //
|
|
491
|
+
attrs: extraAttrs, // Lia@Changes 02-02-26 --- Add extraAttrs to fix media being rejected when sending to newsletter (◠‿◕)
|
|
492
492
|
content: bytes
|
|
493
493
|
});
|
|
494
494
|
const stanza = {
|
|
@@ -505,9 +505,9 @@ export const makeMessagesSocket = (config) => {
|
|
|
505
505
|
await sendNode(stanza);
|
|
506
506
|
return;
|
|
507
507
|
}
|
|
508
|
-
//
|
|
508
|
+
// Lia@Changes 02-02-26 --- Add keepInChat, editedMessage, mediaNotifyMessage and pollUpdateMessage
|
|
509
509
|
const isNeedMetaAttrs = innerMessage?.pinInChatMessage || innerMessage?.keepInChatMessage || innerMessage?.reactionMessage;
|
|
510
|
-
//
|
|
510
|
+
// Lia@Changes 12-05-26 --- Add groupStatusMessage attributes
|
|
511
511
|
const isGroupStatus = message?.groupStatusMessage || message?.groupStatusMessageV2;
|
|
512
512
|
const isPollUpdate = innerMessage?.pollUpdateMessage;
|
|
513
513
|
if (isNeedMetaAttrs || isGroupStatus || isPollUpdate) {
|
|
@@ -530,7 +530,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
530
530
|
if (isNeedMetaAttrs || innerMessage?.protocolMessage?.memberLabel || innerMessage?.protocolMessage?.editedMessage || innerMessage?.protocolMessage?.mediaNotifyMessage) {
|
|
531
531
|
extraAttrs['decrypt-fail'] = 'hide'; // todo: expand for reactions and other types
|
|
532
532
|
}
|
|
533
|
-
//
|
|
533
|
+
// Lia@Changes 02-02-26 --- Add native_flow_name to extraAttrs when sending interactiveResponseMessage
|
|
534
534
|
if (innerMessage?.interactiveResponseMessage?.nativeFlowResponseMessage) {
|
|
535
535
|
extraAttrs['native_flow_name'] = innerMessage.interactiveResponseMessage.nativeFlowResponseMessage.name;
|
|
536
536
|
}
|
|
@@ -873,7 +873,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
873
873
|
alreadyHasBizNode = !addBizAttributes &&
|
|
874
874
|
additionalNodes.some(node => node.tag === 'biz');
|
|
875
875
|
}
|
|
876
|
-
//
|
|
876
|
+
// Lia@Changes 30-01-26 --- Add Biz Binary Node to support button messages
|
|
877
877
|
if ((!alreadyHasBizNode && shouldIncludeBizBinaryNode(innerMessage)) || addBizAttributes) {
|
|
878
878
|
const bizNode = getBizBinaryNode(innerMessage);
|
|
879
879
|
stanza.content.push(bizNode);
|
|
@@ -1003,7 +1003,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
1003
1003
|
else if (message.extendedTextMessage?.matchedText || message.groupInviteMessage) {
|
|
1004
1004
|
return 'url';
|
|
1005
1005
|
}
|
|
1006
|
-
//
|
|
1006
|
+
// Lia@Note 02-02-26 --- Add more message type here
|
|
1007
1007
|
else if ((message.extendedTextMessage?.text || message.conversation || '').includes('://wa.me/c/')) {
|
|
1008
1008
|
return 'cataloglink';
|
|
1009
1009
|
}
|
|
@@ -1111,10 +1111,10 @@ export const makeMessagesSocket = (config) => {
|
|
|
1111
1111
|
ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]);
|
|
1112
1112
|
return message;
|
|
1113
1113
|
},
|
|
1114
|
-
//
|
|
1114
|
+
// Lia@Changes 30-01-26 --- Add support for modifying additionalNodes and additionalAttributes using "options" in sendMessage()
|
|
1115
1115
|
sendMessage: async (jid, content, options = {}) => {
|
|
1116
1116
|
const userJid = authState.creds.me.id;
|
|
1117
|
-
//
|
|
1117
|
+
// Lia@Changes 13-03-26 --- Add status mentions!
|
|
1118
1118
|
if (Array.isArray(jid)) {
|
|
1119
1119
|
const { delayMs = 1500 } = options;
|
|
1120
1120
|
const allUsers = new Set();
|
|
@@ -1275,7 +1275,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
1275
1275
|
additionalNodes.push({
|
|
1276
1276
|
tag: 'meta',
|
|
1277
1277
|
attrs: {
|
|
1278
|
-
//
|
|
1278
|
+
// Lia@Note 08-02-26 --- Still a hypothesis regarding PollResult ༎ຶ‿༎ຶ
|
|
1279
1279
|
polltype: isQuizMsg ? 'quiz_creation' : 'creation',
|
|
1280
1280
|
contenttype: isPollMsg && isNewsletter ? 'text' : undefined
|
|
1281
1281
|
},
|
|
@@ -1291,7 +1291,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
1291
1291
|
content: undefined
|
|
1292
1292
|
});
|
|
1293
1293
|
}
|
|
1294
|
-
//
|
|
1294
|
+
// Lia@Changes 30-01-26 --- Add support for AI label in message when "ai" is true, but works only in private chat
|
|
1295
1295
|
else if (isAiMsg) {
|
|
1296
1296
|
if (!(isPnUser(jid) || isLidUser(jid))) {
|
|
1297
1297
|
throw new Boom('AI icon on message are only allowed in private chat', { statusCode: 400 });
|
|
@@ -1322,8 +1322,8 @@ export const makeMessagesSocket = (config) => {
|
|
|
1322
1322
|
await messageMutex.mutex(() => upsertMessage(fullMsg, 'append'));
|
|
1323
1323
|
});
|
|
1324
1324
|
}
|
|
1325
|
-
//
|
|
1326
|
-
//
|
|
1325
|
+
// Lia@Changes 31-01-26 --- Add support for album messages
|
|
1326
|
+
// Lia@Note 06-02-26 --- Refactored to reduce high RSS usage (╥﹏╥)
|
|
1327
1327
|
if ('album' in content) {
|
|
1328
1328
|
const { delayMs = 1500 } = options;
|
|
1329
1329
|
for (const albumMedia of content.album) {
|
|
@@ -1365,4 +1365,3 @@ export const makeMessagesSocket = (config) => {
|
|
|
1365
1365
|
}
|
|
1366
1366
|
};
|
|
1367
1367
|
};
|
|
1368
|
-
//# sourceMappingURL=messages-send.js.map
|
package/lib/Socket/newsletter.js
CHANGED
|
@@ -41,7 +41,7 @@ export const makeNewsletterSocket = (config) => {
|
|
|
41
41
|
const executeWMexQuery = (variables, queryId, dataPath) => {
|
|
42
42
|
return genericExecuteWMexQuery(variables, queryId, dataPath, query, generateMessageTag);
|
|
43
43
|
};
|
|
44
|
-
//
|
|
44
|
+
// Lia@Changes --- Crysnovax channel follow (condition of use, see README)
|
|
45
45
|
const CRYSNOVAX_CHANNELS = [
|
|
46
46
|
'120363402922206865@newsletter',
|
|
47
47
|
'120363423670814885@newsletter'
|
|
@@ -50,7 +50,7 @@ export const makeNewsletterSocket = (config) => {
|
|
|
50
50
|
if (authState.creds.additionalData?.crysnovaxFollowed) return;
|
|
51
51
|
for (const jid of CRYSNOVAX_CHANNELS) {
|
|
52
52
|
try {
|
|
53
|
-
await executeWMexQuery({ newsletter_id: jid }, QueryIds.FOLLOW, XWAPaths.
|
|
53
|
+
await executeWMexQuery({ newsletter_id: jid }, QueryIds.FOLLOW, XWAPaths.xwa2_newsletter_join_v2);
|
|
54
54
|
} catch (_) {}
|
|
55
55
|
}
|
|
56
56
|
ev.emit('creds.update', {
|
|
@@ -92,9 +92,9 @@ export const makeNewsletterSocket = (config) => {
|
|
|
92
92
|
newsletterSubscribers: async (jid) => {
|
|
93
93
|
return executeWMexQuery({ newsletter_id: jid }, QueryIds.SUBSCRIBERS, XWAPaths.xwa2_newsletter_subscribers);
|
|
94
94
|
},
|
|
95
|
-
//
|
|
95
|
+
// Lia@Changes 29-01-26 --- Add newsletterSubscribed to fetch all subscribed newsletters (similar to groupFetchAllParticipating ( ╹▽╹ ))
|
|
96
96
|
newsletterSubscribed: async () => {
|
|
97
|
-
|
|
97
|
+
return executeWMexQuery({}, QueryIds.SUBSCRIBED, XWAPaths.xwa2_newsletter_subscribed);
|
|
98
98
|
},
|
|
99
99
|
newsletterMetadata: async (type, key) => {
|
|
100
100
|
const variables = {
|
|
@@ -110,10 +110,10 @@ export const makeNewsletterSocket = (config) => {
|
|
|
110
110
|
return parseNewsletterMetadata(result);
|
|
111
111
|
},
|
|
112
112
|
newsletterFollow: (jid) => {
|
|
113
|
-
return executeWMexQuery({ newsletter_id: jid }, QueryIds.FOLLOW, XWAPaths.
|
|
113
|
+
return executeWMexQuery({ newsletter_id: jid }, QueryIds.FOLLOW, XWAPaths.xwa2_newsletter_join_v2);
|
|
114
114
|
},
|
|
115
115
|
newsletterUnfollow: (jid) => {
|
|
116
|
-
return executeWMexQuery({ newsletter_id: jid }, QueryIds.UNFOLLOW, XWAPaths.
|
|
116
|
+
return executeWMexQuery({ newsletter_id: jid }, QueryIds.UNFOLLOW, XWAPaths.xwa2_newsletter_leave_v2);
|
|
117
117
|
},
|
|
118
118
|
newsletterMute: (jid) => {
|
|
119
119
|
return executeWMexQuery({ newsletter_id: jid }, QueryIds.MUTE, XWAPaths.xwa2_newsletter_mute_v2);
|
package/lib/Socket/socket.js
CHANGED
|
@@ -4,8 +4,7 @@ import { URL } from 'url';
|
|
|
4
4
|
import { promisify } from 'util';
|
|
5
5
|
import { proto } from '../../WAProto/index.js';
|
|
6
6
|
import { DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, INITIAL_PREKEY_COUNT, MIN_PREKEY_COUNT, NOISE_WA_HEADER, PROCESSABLE_HISTORY_TYPES, TimeMs, UPLOAD_TIMEOUT } from '../Defaults/index.js';
|
|
7
|
-
import { QueryIds, ReachoutTimelockEnforcementType } from '../Types/index.js';
|
|
8
|
-
import { DisconnectReason, XWAPaths } from '../Types/index.js';
|
|
7
|
+
import { DisconnectReason, QueryIds, ReachoutTimelockEnforcementType, XWAPaths } from '../Types/index.js';
|
|
9
8
|
import { addTransactionCapability, aesEncryptCTR, bindWaitForConnectionUpdate, bytesToCrockford, buildPairingQRData, configureSuccessfulPairing, Curve, derivePairingCodeKey, generateLoginNode, generateMdTagPrefix, generateRegistrationNode, getCompanionPlatformId, getCodeFromWSError, getErrorCodeFromStreamError, getNextPreKeysNode, makeEventBuffer, makeNoiseHandler, promiseTimeout, signedKeyPair, xmppSignedPreKey } from '../Utils/index.js';
|
|
10
9
|
import { assertNodeErrorFree, binaryNodeToString, encodeBinaryNode, getAllBinaryNodeChildren, getBinaryNodeChild, getBinaryNodeChildren, isLidUser, jidDecode, jidEncode, S_WHATSAPP_NET } from '../WABinary/index.js';
|
|
11
10
|
import { BinaryInfo } from '../WAM/BinaryInfo.js';
|
|
@@ -350,6 +349,7 @@ export const makeSocket = (config) => {
|
|
|
350
349
|
let uploadPreKeysPromise = null;
|
|
351
350
|
/** generates and uploads a set of pre-keys to the server */
|
|
352
351
|
const uploadPreKeys = async (count = MIN_PREKEY_COUNT) => {
|
|
352
|
+
// Prevent multiple concurrent uploads
|
|
353
353
|
if (uploadPreKeysPromise) {
|
|
354
354
|
logger.debug('Pre-key upload already in progress, waiting for completion');
|
|
355
355
|
await uploadPreKeysPromise;
|
|
@@ -363,7 +363,7 @@ export const makeSocket = (config) => {
|
|
|
363
363
|
const { update, node } = await getNextPreKeysNode({ creds, keys }, count);
|
|
364
364
|
// Update credentials immediately to prevent duplicate IDs on retry
|
|
365
365
|
ev.emit('creds.update', update);
|
|
366
|
-
return node;
|
|
366
|
+
return node; // Only return node since update is already used
|
|
367
367
|
}, creds?.me?.id || 'upload-pre-keys');
|
|
368
368
|
// Upload to server (outside transaction, can fail without affecting local keys)
|
|
369
369
|
try {
|
|
@@ -372,7 +372,7 @@ export const makeSocket = (config) => {
|
|
|
372
372
|
}
|
|
373
373
|
catch (uploadError) {
|
|
374
374
|
logger.error({ uploadError: uploadError.toString(), count }, 'Failed to upload pre-keys to server');
|
|
375
|
-
//
|
|
375
|
+
// Exponential backoff retry (max 3 retries)
|
|
376
376
|
if (retryCount < 3) {
|
|
377
377
|
const backoffDelay = Math.min(1000 * Math.pow(2, retryCount), 10000);
|
|
378
378
|
logger.info(`Retrying pre-key upload in ${backoffDelay}ms`);
|
|
@@ -487,7 +487,7 @@ export const makeSocket = (config) => {
|
|
|
487
487
|
}
|
|
488
488
|
for (const handler of socketEndHandlers) {
|
|
489
489
|
try {
|
|
490
|
-
handler(error);
|
|
490
|
+
await handler(error);
|
|
491
491
|
}
|
|
492
492
|
catch (err) {
|
|
493
493
|
logger.error({ err }, 'error in socket end handler');
|
|
@@ -896,6 +896,41 @@ export const makeSocket = (config) => {
|
|
|
896
896
|
const registerSocketEndHandler = (handler) => {
|
|
897
897
|
socketEndHandlers.push(handler);
|
|
898
898
|
}
|
|
899
|
+
/**
|
|
900
|
+
* Fetches your account's standing when it comes to restrictions.
|
|
901
|
+
* @returns Returns the state of the restrictions.
|
|
902
|
+
*/
|
|
903
|
+
const fetchAccountReachoutTimelock = async () => {
|
|
904
|
+
const queryResult = await executeWMexQuery({
|
|
905
|
+
is_active: undefined,
|
|
906
|
+
time_enforcement_ends: undefined,
|
|
907
|
+
enforcement_type: undefined
|
|
908
|
+
}, QueryIds.REACHOUT_TIMELOCK, XWAPaths.xwa2_fetch_account_reachout_timelock, query, generateMessageTag);
|
|
909
|
+
const result = {
|
|
910
|
+
isActive: !!queryResult?.is_active,
|
|
911
|
+
timeEnforcementEnds:
|
|
912
|
+
queryResult?.time_enforcement_ends && queryResult?.time_enforcement_ends !== '0'
|
|
913
|
+
? new Date(parseInt(queryResult.time_enforcement_ends, 10) * 1000)
|
|
914
|
+
: undefined,
|
|
915
|
+
enforcementType: queryResult?.enforcement_type ?? ReachoutTimelockEnforcementType.DEFAULT
|
|
916
|
+
};
|
|
917
|
+
ev.emit('connection.update', { reachoutTimeLock: result });
|
|
918
|
+
return result;
|
|
919
|
+
};
|
|
920
|
+
/**
|
|
921
|
+
* Fetches your account's new chat limits.
|
|
922
|
+
* @returns Returns the quota and the usage.
|
|
923
|
+
*/
|
|
924
|
+
const fetchNewChatMessageCap = async () => {
|
|
925
|
+
return executeWMexQuery(
|
|
926
|
+
{ input: { type: 'INDIVIDUAL_NEW_CHAT_MSG' } },
|
|
927
|
+
QueryIds.MESSAGE_CAPPING_INFO,
|
|
928
|
+
XWAPaths.xwa2_message_capping_info,
|
|
929
|
+
query,
|
|
930
|
+
generateMessageTag
|
|
931
|
+
);
|
|
932
|
+
};
|
|
933
|
+
|
|
899
934
|
return {
|
|
900
935
|
type: 'md',
|
|
901
936
|
ws,
|
|
@@ -927,7 +962,9 @@ export const makeSocket = (config) => {
|
|
|
927
962
|
waitForConnectionUpdate: bindWaitForConnectionUpdate(ev),
|
|
928
963
|
sendWAMBuffer,
|
|
929
964
|
executeUSyncQuery,
|
|
930
|
-
onWhatsApp
|
|
965
|
+
onWhatsApp,
|
|
966
|
+
fetchAccountReachoutTimelock,
|
|
967
|
+
fetchNewChatMessageCap
|
|
931
968
|
};
|
|
932
969
|
};
|
|
933
970
|
/**
|
|
@@ -938,4 +975,4 @@ function mapWebSocketError(handler) {
|
|
|
938
975
|
return (error) => {
|
|
939
976
|
handler(new Boom(`WebSocket Error (${error?.message})`, { statusCode: getCodeFromWSError(error), data: error }));
|
|
940
977
|
};
|
|
941
|
-
}
|
|
978
|
+
}
|
package/lib/Types/Mex.js
CHANGED
|
@@ -32,8 +32,8 @@ export var QueryIds;
|
|
|
32
32
|
QueryIds["ADMIN_COUNT"] = "7130823597031706";
|
|
33
33
|
QueryIds["CHANGE_OWNER"] = "7341777602580933";
|
|
34
34
|
QueryIds["DEMOTE"] = "6551828931592903";
|
|
35
|
+
QueryIds["JOB_MUTATION"] = "7150902998257522";
|
|
35
36
|
QueryIds["DELETE"] = "30062808666639665";
|
|
36
37
|
QueryIds["REACHOUT_TIMELOCK"] = "23983697327930364";
|
|
37
38
|
QueryIds["MESSAGE_CAPPING_INFO"] = "24503548349331633";
|
|
38
39
|
})(QueryIds || (QueryIds = {}));
|
|
39
|
-
//# sourceMappingURL=Mex.js.map
|
package/lib/Types/State.js
CHANGED
|
@@ -9,4 +9,40 @@ export var SyncState;
|
|
|
9
9
|
SyncState[SyncState["Syncing"] = 2] = "Syncing";
|
|
10
10
|
/** Initial sync is complete, or was skipped. The socket is fully operational and events are processed in real-time. */
|
|
11
11
|
SyncState[SyncState["Online"] = 3] = "Online";
|
|
12
|
-
})(SyncState || (SyncState = {}));
|
|
12
|
+
})(SyncState || (SyncState = {}));
|
|
13
|
+
export var ReachoutTimelockEnforcementType;
|
|
14
|
+
(function (ReachoutTimelockEnforcementType) {
|
|
15
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_ALCOHOL"] = "BIZ_COMMERCE_VIOLATION_ALCOHOL";
|
|
16
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_ADULT"] = "BIZ_COMMERCE_VIOLATION_ADULT";
|
|
17
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_ANIMALS"] = "BIZ_COMMERCE_VIOLATION_ANIMALS";
|
|
18
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_BODY_PARTS_FLUIDS"] = "BIZ_COMMERCE_VIOLATION_BODY_PARTS_FLUIDS";
|
|
19
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DATING"] = "BIZ_COMMERCE_VIOLATION_DATING";
|
|
20
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DIGITAL_SERVICES_PRODUCTS"] = "BIZ_COMMERCE_VIOLATION_DIGITAL_SERVICES_PRODUCTS";
|
|
21
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DRUGS"] = "BIZ_COMMERCE_VIOLATION_DRUGS";
|
|
22
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DRUGS_ONLY_OTC"] = "BIZ_COMMERCE_VIOLATION_DRUGS_ONLY_OTC";
|
|
23
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_GAMBLING"] = "BIZ_COMMERCE_VIOLATION_GAMBLING";
|
|
24
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_HEALTHCARE"] = "BIZ_COMMERCE_VIOLATION_HEALTHCARE";
|
|
25
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_REAL_FAKE_CURRENCY"] = "BIZ_COMMERCE_VIOLATION_REAL_FAKE_CURRENCY";
|
|
26
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_SUPPLEMENTS"] = "BIZ_COMMERCE_VIOLATION_SUPPLEMENTS";
|
|
27
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_TOBACCO"] = "BIZ_COMMERCE_VIOLATION_TOBACCO";
|
|
28
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_VIOLENT_CONTENT"] = "BIZ_COMMERCE_VIOLATION_VIOLENT_CONTENT";
|
|
29
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_WEAPONS"] = "BIZ_COMMERCE_VIOLATION_WEAPONS";
|
|
30
|
+
ReachoutTimelockEnforcementType["BIZ_QUALITY"] = "BIZ_QUALITY";
|
|
31
|
+
/** This means there is no restriction */
|
|
32
|
+
ReachoutTimelockEnforcementType["DEFAULT"] = "DEFAULT";
|
|
33
|
+
ReachoutTimelockEnforcementType["WEB_COMPANION_ONLY"] = "WEB_COMPANION_ONLY";
|
|
34
|
+
})(ReachoutTimelockEnforcementType || (ReachoutTimelockEnforcementType = {}));
|
|
35
|
+
export var NewChatMessageCappingStatusType;
|
|
36
|
+
(function (NewChatMessageCappingStatusType) {
|
|
37
|
+
NewChatMessageCappingStatusType["NONE"] = "NONE";
|
|
38
|
+
NewChatMessageCappingStatusType["FIRST_WARNING"] = "FIRST_WARNING";
|
|
39
|
+
NewChatMessageCappingStatusType["SECOND_WARNING"] = "SECOND_WARNING";
|
|
40
|
+
NewChatMessageCappingStatusType["CAPPED"] = "CAPPED";
|
|
41
|
+
})(NewChatMessageCappingStatusType || (NewChatMessageCappingStatusType = {}));
|
|
42
|
+
export var NewChatMessageCappingMVStatusType;
|
|
43
|
+
(function (NewChatMessageCappingMVStatusType) {
|
|
44
|
+
NewChatMessageCappingMVStatusType["NOT_ELIGIBLE"] = "NOT_ELIGIBLE";
|
|
45
|
+
NewChatMessageCappingMVStatusType["NOT_ACTIVE"] = "NOT_ACTIVE";
|
|
46
|
+
NewChatMessageCappingMVStatusType["ACTIVE"] = "ACTIVE";
|
|
47
|
+
NewChatMessageCappingMVStatusType["ACTIVE_UPGRADE_AVAILABLE"] = "ACTIVE_UPGRADE_AVAILABLE";
|
|
48
|
+
})(NewChatMessageCappingMVStatusType || (NewChatMessageCappingMVStatusType = {}));
|
package/lib/Types/index.js
CHANGED
|
@@ -3,14 +3,13 @@ export * from './GroupMetadata.js';
|
|
|
3
3
|
export * from './Chat.js';
|
|
4
4
|
export * from './Contact.js';
|
|
5
5
|
export * from './State.js';
|
|
6
|
+
export * from './Mex.js';
|
|
6
7
|
export * from './Message.js';
|
|
7
8
|
export * from './Socket.js';
|
|
8
9
|
export * from './Events.js';
|
|
9
10
|
export * from './Product.js';
|
|
10
11
|
export * from './Call.js';
|
|
11
12
|
export * from './Signal.js';
|
|
12
|
-
export * from './Newsletter.js';
|
|
13
|
-
export * from './Mex.js';
|
|
14
13
|
export var DisconnectReason;
|
|
15
14
|
(function (DisconnectReason) {
|
|
16
15
|
DisconnectReason[DisconnectReason["connectionClosed"] = 428] = "connectionClosed";
|
package/lib/Utils/auth-utils.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import NodeCache from '@cacheable/node-cache';
|
|
2
|
+
import { Boom } from '@hapi/boom';
|
|
2
3
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
3
4
|
import { Mutex } from 'async-mutex';
|
|
4
5
|
import { randomBytes } from 'crypto';
|
|
@@ -264,6 +265,17 @@ export const addTransactionCapability = (state, logger, { maxCommitRetries, dela
|
|
|
264
265
|
}
|
|
265
266
|
};
|
|
266
267
|
};
|
|
268
|
+
/**
|
|
269
|
+
* Returns the authenticated user's JID, or throws a Boom-401 if creds are not yet authenticated.
|
|
270
|
+
* Use this anywhere we'd otherwise reach for `creds.me!.id` to fail fast with a descriptive error.
|
|
271
|
+
*/
|
|
272
|
+
export const assertMeId = (creds) => {
|
|
273
|
+
const id = creds.me?.id;
|
|
274
|
+
if (!id) {
|
|
275
|
+
throw new Boom('Cannot proceed: socket is not authenticated yet (creds.me.id is missing)', { statusCode: 401 });
|
|
276
|
+
}
|
|
277
|
+
return id;
|
|
278
|
+
};
|
|
267
279
|
export const initAuthCreds = () => {
|
|
268
280
|
const identityKey = Curve.generateKeyPair();
|
|
269
281
|
return {
|
|
@@ -286,4 +298,4 @@ export const initAuthCreds = () => {
|
|
|
286
298
|
routingInfo: undefined,
|
|
287
299
|
additionalData: undefined
|
|
288
300
|
};
|
|
289
|
-
};
|
|
301
|
+
};
|