violetics 7.0.1-alpha → 7.0.2-alpha
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 -2
- package/README.md +1001 -232
- package/WAProto/index.js +75379 -142631
- package/engine-requirements.js +11 -8
- package/lib/Defaults/index.js +132 -146
- package/lib/Signal/Group/ciphertext-message.js +2 -6
- package/lib/Signal/Group/group-session-builder.js +7 -42
- package/lib/Signal/Group/group_cipher.js +37 -52
- package/lib/Signal/Group/index.js +11 -57
- package/lib/Signal/Group/keyhelper.js +7 -45
- package/lib/Signal/Group/sender-chain-key.js +7 -16
- package/lib/Signal/Group/sender-key-distribution-message.js +8 -12
- package/lib/Signal/Group/sender-key-message.js +9 -13
- package/lib/Signal/Group/sender-key-name.js +2 -6
- package/lib/Signal/Group/sender-key-record.js +9 -22
- package/lib/Signal/Group/sender-key-state.js +27 -43
- package/lib/Signal/Group/sender-message-key.js +4 -8
- package/lib/Signal/libsignal.js +319 -94
- package/lib/Signal/lid-mapping.js +224 -139
- package/lib/Socket/Client/index.js +2 -19
- package/lib/Socket/Client/types.js +10 -0
- package/lib/Socket/Client/websocket.js +53 -0
- package/lib/Socket/business.js +162 -44
- package/lib/Socket/chats.js +477 -418
- package/lib/Socket/communities.js +430 -0
- package/lib/Socket/groups.js +110 -99
- package/lib/Socket/index.js +10 -10
- package/lib/Socket/messages-recv.js +884 -561
- package/lib/Socket/messages-send.js +859 -428
- package/lib/Socket/mex.js +41 -0
- package/lib/Socket/newsletter.js +195 -390
- package/lib/Socket/socket.js +465 -315
- package/lib/Store/index.js +3 -10
- package/lib/Store/make-in-memory-store.js +73 -79
- package/lib/Store/make-ordered-dictionary.js +4 -7
- package/lib/Store/object-repository.js +2 -6
- package/lib/Types/Auth.js +1 -2
- package/lib/Types/Bussines.js +1 -0
- package/lib/Types/Call.js +1 -2
- package/lib/Types/Chat.js +7 -4
- package/lib/Types/Contact.js +1 -2
- package/lib/Types/Events.js +1 -2
- package/lib/Types/GroupMetadata.js +1 -2
- package/lib/Types/Label.js +2 -5
- package/lib/Types/LabelAssociation.js +2 -5
- package/lib/Types/Message.js +17 -9
- package/lib/Types/Newsletter.js +33 -38
- package/lib/Types/Product.js +1 -2
- package/lib/Types/Signal.js +1 -2
- package/lib/Types/Socket.js +2 -2
- package/lib/Types/State.js +12 -2
- package/lib/Types/USync.js +1 -2
- package/lib/Types/index.js +14 -31
- package/lib/Utils/auth-utils.js +228 -152
- package/lib/Utils/browser-utils.js +28 -0
- package/lib/Utils/business.js +66 -70
- package/lib/Utils/chat-utils.js +331 -249
- package/lib/Utils/crypto.js +57 -91
- package/lib/Utils/decode-wa-message.js +168 -84
- package/lib/Utils/event-buffer.js +138 -80
- package/lib/Utils/generics.js +180 -297
- package/lib/Utils/history.js +83 -49
- package/lib/Utils/identity-change-handler.js +48 -0
- package/lib/Utils/index.js +19 -33
- package/lib/Utils/link-preview.js +14 -23
- package/lib/Utils/logger.js +2 -7
- package/lib/Utils/lt-hash.js +2 -46
- package/lib/Utils/make-mutex.js +24 -47
- package/lib/Utils/message-retry-manager.js +224 -0
- package/lib/Utils/messages-media.js +501 -496
- package/lib/Utils/messages.js +1428 -362
- package/lib/Utils/noise-handler.js +145 -100
- package/lib/Utils/pre-key-manager.js +105 -0
- package/lib/Utils/process-message.js +356 -150
- package/lib/Utils/reporting-utils.js +257 -0
- package/lib/Utils/signal.js +78 -73
- package/lib/Utils/sync-action-utils.js +47 -0
- package/lib/Utils/tc-token-utils.js +17 -0
- package/lib/Utils/use-multi-file-auth-state.js +35 -45
- package/lib/Utils/validate-connection.js +91 -107
- package/lib/WABinary/constants.js +1300 -1304
- package/lib/WABinary/decode.js +26 -48
- package/lib/WABinary/encode.js +109 -155
- package/lib/WABinary/generic-utils.js +161 -149
- package/lib/WABinary/index.js +5 -21
- package/lib/WABinary/jid-utils.js +73 -40
- package/lib/WABinary/types.js +1 -2
- package/lib/WAM/BinaryInfo.js +2 -6
- package/lib/WAM/constants.js +19070 -11568
- package/lib/WAM/encode.js +17 -23
- package/lib/WAM/index.js +3 -19
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +8 -12
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +11 -15
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +9 -13
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +9 -14
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +20 -23
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +13 -9
- package/lib/WAUSync/Protocols/index.js +4 -20
- package/lib/WAUSync/USyncQuery.js +40 -36
- package/lib/WAUSync/USyncUser.js +2 -6
- package/lib/WAUSync/index.js +3 -19
- package/lib/index.js +11 -44
- package/package.json +74 -107
- package/lib/Defaults/baileys-version.json +0 -3
- package/lib/Defaults/phonenumber-mcc.json +0 -223
- package/lib/Signal/Group/queue-job.js +0 -57
- package/lib/Socket/Client/abstract-socket-client.js +0 -13
- package/lib/Socket/Client/mobile-socket-client.js +0 -65
- package/lib/Socket/Client/web-socket-client.js +0 -118
- package/lib/Socket/groupStatus.js +0 -637
- package/lib/Socket/registration.js +0 -166
- package/lib/Socket/usync.js +0 -70
- package/lib/Store/make-cache-manager-store.js +0 -83
- package/lib/Utils/baileys-event-stream.js +0 -63
package/lib/Utils/history.js
CHANGED
|
@@ -1,17 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import { promisify } from 'util';
|
|
2
|
+
import { inflate } from 'zlib';
|
|
3
|
+
import { proto } from '../../WAProto/index.js';
|
|
4
|
+
import { WAMessageStubType } from '../Types/index.js';
|
|
5
|
+
import { isHostedLidUser, isHostedPnUser, isLidUser, isPnUser } from '../WABinary/index.js';
|
|
6
|
+
import { toNumber } from './generics.js';
|
|
7
|
+
import { normalizeMessageContent } from './messages.js';
|
|
8
|
+
import { downloadContentFromMessage } from './messages-media.js';
|
|
9
|
+
const inflatePromise = promisify(inflate);
|
|
10
|
+
const extractPnFromMessages = (messages) => {
|
|
11
|
+
for (const msgItem of messages) {
|
|
12
|
+
const message = msgItem.message;
|
|
13
|
+
// Only extract from outgoing messages (fromMe: true) in 1:1 chats
|
|
14
|
+
// because userReceipt.userJid is the recipient's JID
|
|
15
|
+
if (!message?.key?.fromMe || !message.userReceipt?.length) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
const userJid = message.userReceipt[0]?.userJid;
|
|
19
|
+
if (userJid && (isPnUser(userJid) || isHostedPnUser(userJid))) {
|
|
20
|
+
return userJid;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return undefined;
|
|
24
|
+
};
|
|
25
|
+
export const downloadHistory = async (msg, options) => {
|
|
26
|
+
const stream = await downloadContentFromMessage(msg, 'md-msg-hist', { options });
|
|
15
27
|
const bufferArray = [];
|
|
16
28
|
for await (const chunk of stream) {
|
|
17
29
|
bufferArray.push(chunk);
|
|
@@ -19,57 +31,74 @@ const downloadHistory = async (msg, options) => {
|
|
|
19
31
|
let buffer = Buffer.concat(bufferArray);
|
|
20
32
|
// decompress buffer
|
|
21
33
|
buffer = await inflatePromise(buffer);
|
|
22
|
-
const syncData =
|
|
34
|
+
const syncData = proto.HistorySync.decode(buffer);
|
|
23
35
|
return syncData;
|
|
24
36
|
};
|
|
25
|
-
|
|
26
|
-
const processHistoryMessage = (item) => {
|
|
27
|
-
var _a, _b, _c;
|
|
37
|
+
export const processHistoryMessage = (item, logger) => {
|
|
28
38
|
const messages = [];
|
|
29
39
|
const contacts = [];
|
|
30
40
|
const chats = [];
|
|
41
|
+
const lidPnMappings = [];
|
|
42
|
+
logger?.trace({ progress: item.progress }, 'processing history of type ' + item.syncType?.toString());
|
|
43
|
+
// Extract LID-PN mappings for all sync types
|
|
44
|
+
for (const m of item.phoneNumberToLidMappings || []) {
|
|
45
|
+
if (m.lidJid && m.pnJid) {
|
|
46
|
+
lidPnMappings.push({ lid: m.lidJid, pn: m.pnJid });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
31
49
|
switch (item.syncType) {
|
|
32
|
-
case
|
|
33
|
-
case
|
|
34
|
-
case
|
|
50
|
+
case proto.HistorySync.HistorySyncType.INITIAL_BOOTSTRAP:
|
|
51
|
+
case proto.HistorySync.HistorySyncType.RECENT:
|
|
52
|
+
case proto.HistorySync.HistorySyncType.FULL:
|
|
53
|
+
case proto.HistorySync.HistorySyncType.ON_DEMAND:
|
|
35
54
|
for (const chat of item.conversations) {
|
|
36
|
-
contacts.push({
|
|
55
|
+
contacts.push({
|
|
37
56
|
id: chat.id,
|
|
38
|
-
name: chat.name || undefined,
|
|
39
|
-
lid: chat.lidJid || undefined,
|
|
40
|
-
|
|
57
|
+
name: chat.displayName || chat.name || chat.username || undefined,
|
|
58
|
+
lid: chat.lidJid || chat.accountLid || undefined,
|
|
59
|
+
phoneNumber: chat.pnJid || undefined
|
|
41
60
|
});
|
|
61
|
+
const chatId = chat.id;
|
|
62
|
+
const isLid = isLidUser(chatId) || isHostedLidUser(chatId);
|
|
63
|
+
const isPn = isPnUser(chatId) || isHostedPnUser(chatId);
|
|
64
|
+
if (isLid && chat.pnJid) {
|
|
65
|
+
lidPnMappings.push({ lid: chatId, pn: chat.pnJid });
|
|
66
|
+
}
|
|
67
|
+
else if (isPn && chat.lidJid) {
|
|
68
|
+
lidPnMappings.push({ lid: chat.lidJid, pn: chatId });
|
|
69
|
+
}
|
|
70
|
+
else if (isLid && !chat.pnJid) {
|
|
71
|
+
// Fallback: extract PN from userReceipt in messages when pnJid is missing
|
|
72
|
+
const pnFromReceipt = extractPnFromMessages(chat.messages || []);
|
|
73
|
+
if (pnFromReceipt) {
|
|
74
|
+
lidPnMappings.push({ lid: chatId, pn: pnFromReceipt });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
42
77
|
const msgs = chat.messages || [];
|
|
43
78
|
delete chat.messages;
|
|
44
|
-
delete chat.archived;
|
|
45
|
-
delete chat.muteEndTime;
|
|
46
|
-
delete chat.pinned;
|
|
47
79
|
for (const item of msgs) {
|
|
48
80
|
const message = item.message;
|
|
49
81
|
messages.push(message);
|
|
50
|
-
if (!
|
|
82
|
+
if (!chat.messages?.length) {
|
|
51
83
|
// keep only the most recent message in the chat array
|
|
52
84
|
chat.messages = [{ message }];
|
|
53
85
|
}
|
|
54
86
|
if (!message.key.fromMe && !chat.lastMessageRecvTimestamp) {
|
|
55
|
-
chat.lastMessageRecvTimestamp =
|
|
87
|
+
chat.lastMessageRecvTimestamp = toNumber(message.messageTimestamp);
|
|
56
88
|
}
|
|
57
|
-
if ((message.messageStubType ===
|
|
58
|
-
|
|
59
|
-
|
|
89
|
+
if ((message.messageStubType === WAMessageStubType.BIZ_PRIVACY_MODE_TO_BSP ||
|
|
90
|
+
message.messageStubType === WAMessageStubType.BIZ_PRIVACY_MODE_TO_FB) &&
|
|
91
|
+
message.messageStubParameters?.[0]) {
|
|
60
92
|
contacts.push({
|
|
61
93
|
id: message.key.participant || message.key.remoteJid,
|
|
62
|
-
verifiedName:
|
|
94
|
+
verifiedName: message.messageStubParameters?.[0]
|
|
63
95
|
});
|
|
64
96
|
}
|
|
65
97
|
}
|
|
66
|
-
if ((0, WABinary_1.isJidUser)(chat.id) && chat.readOnly && chat.archived) {
|
|
67
|
-
delete chat.readOnly;
|
|
68
|
-
}
|
|
69
98
|
chats.push({ ...chat });
|
|
70
99
|
}
|
|
71
100
|
break;
|
|
72
|
-
case
|
|
101
|
+
case proto.HistorySync.HistorySyncType.PUSH_NAME:
|
|
73
102
|
for (const c of item.pushnames) {
|
|
74
103
|
contacts.push({ id: c.id, notify: c.pushname });
|
|
75
104
|
}
|
|
@@ -79,18 +108,23 @@ const processHistoryMessage = (item) => {
|
|
|
79
108
|
chats,
|
|
80
109
|
contacts,
|
|
81
110
|
messages,
|
|
111
|
+
lidPnMappings,
|
|
112
|
+
syncType: item.syncType,
|
|
113
|
+
progress: item.progress
|
|
82
114
|
};
|
|
83
115
|
};
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
116
|
+
export const downloadAndProcessHistorySyncNotification = async (msg, options, logger) => {
|
|
117
|
+
let historyMsg;
|
|
118
|
+
if (msg.initialHistBootstrapInlinePayload) {
|
|
119
|
+
historyMsg = proto.HistorySync.decode(await inflatePromise(msg.initialHistBootstrapInlinePayload));
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
historyMsg = await downloadHistory(msg, options);
|
|
123
|
+
}
|
|
124
|
+
return processHistoryMessage(historyMsg, logger);
|
|
88
125
|
};
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
const normalizedContent = !!message ? (0, messages_1.normalizeMessageContent)(message) : undefined;
|
|
93
|
-
const anyHistoryMsg = (_a = normalizedContent === null || normalizedContent === void 0 ? void 0 : normalizedContent.protocolMessage) === null || _a === void 0 ? void 0 : _a.historySyncNotification;
|
|
126
|
+
export const getHistoryMsg = (message) => {
|
|
127
|
+
const normalizedContent = !!message ? normalizeMessageContent(message) : undefined;
|
|
128
|
+
const anyHistoryMsg = normalizedContent?.protocolMessage?.historySyncNotification;
|
|
94
129
|
return anyHistoryMsg;
|
|
95
|
-
};
|
|
96
|
-
exports.getHistoryMsg = getHistoryMsg;
|
|
130
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import NodeCache from '@cacheable/node-cache';
|
|
2
|
+
import { areJidsSameUser, getBinaryNodeChild, jidDecode } from '../WABinary/index.js';
|
|
3
|
+
import { isStringNullOrEmpty } from './generics.js';
|
|
4
|
+
export async function handleIdentityChange(node, ctx) {
|
|
5
|
+
const from = node.attrs.from;
|
|
6
|
+
if (!from) {
|
|
7
|
+
return { action: 'invalid_notification' };
|
|
8
|
+
}
|
|
9
|
+
const identityNode = getBinaryNodeChild(node, 'identity');
|
|
10
|
+
if (!identityNode) {
|
|
11
|
+
return { action: 'no_identity_node' };
|
|
12
|
+
}
|
|
13
|
+
ctx.logger.info({ jid: from }, 'identity changed');
|
|
14
|
+
const decoded = jidDecode(from);
|
|
15
|
+
if (decoded?.device && decoded.device !== 0) {
|
|
16
|
+
ctx.logger.debug({ jid: from, device: decoded.device }, 'ignoring identity change from companion device');
|
|
17
|
+
return { action: 'skipped_companion_device', device: decoded.device };
|
|
18
|
+
}
|
|
19
|
+
const isSelfPrimary = ctx.meId && (areJidsSameUser(from, ctx.meId) || (ctx.meLid && areJidsSameUser(from, ctx.meLid)));
|
|
20
|
+
if (isSelfPrimary) {
|
|
21
|
+
ctx.logger.info({ jid: from }, 'self primary identity changed');
|
|
22
|
+
return { action: 'skipped_self_primary' };
|
|
23
|
+
}
|
|
24
|
+
if (ctx.debounceCache.get(from)) {
|
|
25
|
+
ctx.logger.debug({ jid: from }, 'skipping identity assert (debounced)');
|
|
26
|
+
return { action: 'debounced' };
|
|
27
|
+
}
|
|
28
|
+
ctx.debounceCache.set(from, true);
|
|
29
|
+
const isOfflineNotification = !isStringNullOrEmpty(node.attrs.offline);
|
|
30
|
+
const hasExistingSession = await ctx.validateSession(from);
|
|
31
|
+
if (!hasExistingSession.exists) {
|
|
32
|
+
ctx.logger.debug({ jid: from }, 'no old session, skipping session refresh');
|
|
33
|
+
return { action: 'skipped_no_session' };
|
|
34
|
+
}
|
|
35
|
+
ctx.logger.debug({ jid: from }, 'old session exists, will refresh session');
|
|
36
|
+
if (isOfflineNotification) {
|
|
37
|
+
ctx.logger.debug({ jid: from }, 'skipping session refresh during offline processing');
|
|
38
|
+
return { action: 'skipped_offline' };
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
await ctx.assertSessions([from], true);
|
|
42
|
+
return { action: 'session_refreshed' };
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
ctx.logger.warn({ error, jid: from }, 'failed to assert sessions after identity change');
|
|
46
|
+
return { action: 'session_refresh_failed', error };
|
|
47
|
+
}
|
|
48
|
+
}
|
package/lib/Utils/index.js
CHANGED
|
@@ -1,33 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
__exportStar(require("./messages-media"), exports);
|
|
21
|
-
__exportStar(require("./validate-connection"), exports);
|
|
22
|
-
__exportStar(require("./crypto"), exports);
|
|
23
|
-
__exportStar(require("./signal"), exports);
|
|
24
|
-
__exportStar(require("./noise-handler"), exports);
|
|
25
|
-
__exportStar(require("./history"), exports);
|
|
26
|
-
__exportStar(require("./chat-utils"), exports);
|
|
27
|
-
__exportStar(require("./lt-hash"), exports);
|
|
28
|
-
__exportStar(require("./auth-utils"), exports);
|
|
29
|
-
__exportStar(require("./baileys-event-stream"), exports);
|
|
30
|
-
__exportStar(require("./use-multi-file-auth-state"), exports);
|
|
31
|
-
__exportStar(require("./link-preview"), exports);
|
|
32
|
-
__exportStar(require("./event-buffer"), exports);
|
|
33
|
-
__exportStar(require("./process-message"), exports);
|
|
1
|
+
export * from './generics.js';
|
|
2
|
+
export * from './decode-wa-message.js';
|
|
3
|
+
export * from './messages.js';
|
|
4
|
+
export * from './messages-media.js';
|
|
5
|
+
export * from './validate-connection.js';
|
|
6
|
+
export * from './crypto.js';
|
|
7
|
+
export * from './signal.js';
|
|
8
|
+
export * from './noise-handler.js';
|
|
9
|
+
export * from './history.js';
|
|
10
|
+
export * from './chat-utils.js';
|
|
11
|
+
export * from './lt-hash.js';
|
|
12
|
+
export * from './auth-utils.js';
|
|
13
|
+
export * from './use-multi-file-auth-state.js';
|
|
14
|
+
export * from './link-preview.js';
|
|
15
|
+
export * from './event-buffer.js';
|
|
16
|
+
export * from './process-message.js';
|
|
17
|
+
export * from './message-retry-manager.js';
|
|
18
|
+
export * from './browser-utils.js';
|
|
19
|
+
export * from './identity-change-handler.js';
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.getUrlInfo = void 0;
|
|
4
|
-
const messages_1 = require("./messages");
|
|
5
|
-
const messages_media_1 = require("./messages-media");
|
|
1
|
+
import { prepareWAMessageMedia } from './messages.js';
|
|
2
|
+
import { extractImageThumb, getHttpStream } from './messages-media.js';
|
|
6
3
|
const THUMBNAIL_WIDTH_PX = 192;
|
|
7
4
|
/** Fetches an image and generates a thumbnail for it */
|
|
8
5
|
const getCompressedJpegThumbnail = async (url, { thumbnailWidth, fetchOpts }) => {
|
|
9
|
-
const stream = await
|
|
10
|
-
const result = await
|
|
6
|
+
const stream = await getHttpStream(url, fetchOpts);
|
|
7
|
+
const result = await extractImageThumb(stream, thumbnailWidth);
|
|
11
8
|
return result;
|
|
12
9
|
};
|
|
13
10
|
/**
|
|
@@ -16,11 +13,10 @@ const getCompressedJpegThumbnail = async (url, { thumbnailWidth, fetchOpts }) =>
|
|
|
16
13
|
* @param text first matched URL in text
|
|
17
14
|
* @returns the URL info required to generate link preview
|
|
18
15
|
*/
|
|
19
|
-
const getUrlInfo = async (text, opts = {
|
|
16
|
+
export const getUrlInfo = async (text, opts = {
|
|
20
17
|
thumbnailWidth: THUMBNAIL_WIDTH_PX,
|
|
21
18
|
fetchOpts: { timeout: 3000 }
|
|
22
19
|
}) => {
|
|
23
|
-
var _a;
|
|
24
20
|
try {
|
|
25
21
|
// retries
|
|
26
22
|
const retries = 0;
|
|
@@ -39,9 +35,9 @@ const getUrlInfo = async (text, opts = {
|
|
|
39
35
|
if (retries >= maxRetry) {
|
|
40
36
|
return false;
|
|
41
37
|
}
|
|
42
|
-
if (forwardedURLObj.hostname === urlObj.hostname
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
if (forwardedURLObj.hostname === urlObj.hostname ||
|
|
39
|
+
forwardedURLObj.hostname === 'www.' + urlObj.hostname ||
|
|
40
|
+
'www.' + forwardedURLObj.hostname === urlObj.hostname) {
|
|
45
41
|
retries + 1;
|
|
46
42
|
return true;
|
|
47
43
|
}
|
|
@@ -49,7 +45,7 @@ const getUrlInfo = async (text, opts = {
|
|
|
49
45
|
return false;
|
|
50
46
|
}
|
|
51
47
|
},
|
|
52
|
-
headers: opts.fetchOpts
|
|
48
|
+
headers: opts.fetchOpts?.headers
|
|
53
49
|
});
|
|
54
50
|
if (info && 'title' in info && info.title) {
|
|
55
51
|
const [image] = info.images;
|
|
@@ -61,24 +57,20 @@ const getUrlInfo = async (text, opts = {
|
|
|
61
57
|
originalThumbnailUrl: image
|
|
62
58
|
};
|
|
63
59
|
if (opts.uploadImage) {
|
|
64
|
-
const { imageMessage } = await
|
|
60
|
+
const { imageMessage } = await prepareWAMessageMedia({ image: { url: image } }, {
|
|
65
61
|
upload: opts.uploadImage,
|
|
66
62
|
mediaTypeOverride: 'thumbnail-link',
|
|
67
63
|
options: opts.fetchOpts
|
|
68
64
|
});
|
|
69
|
-
urlInfo.jpegThumbnail =
|
|
70
|
-
? Buffer.from(imageMessage.jpegThumbnail)
|
|
71
|
-
: undefined;
|
|
65
|
+
urlInfo.jpegThumbnail = imageMessage?.jpegThumbnail ? Buffer.from(imageMessage.jpegThumbnail) : undefined;
|
|
72
66
|
urlInfo.highQualityThumbnail = imageMessage || undefined;
|
|
73
67
|
}
|
|
74
68
|
else {
|
|
75
69
|
try {
|
|
76
|
-
urlInfo.jpegThumbnail = image
|
|
77
|
-
? (await getCompressedJpegThumbnail(image, opts)).buffer
|
|
78
|
-
: undefined;
|
|
70
|
+
urlInfo.jpegThumbnail = image ? (await getCompressedJpegThumbnail(image, opts)).buffer : undefined;
|
|
79
71
|
}
|
|
80
72
|
catch (error) {
|
|
81
|
-
|
|
73
|
+
opts.logger?.debug({ err: error.stack, url: previewLink }, 'error in generating thumbnail');
|
|
82
74
|
}
|
|
83
75
|
}
|
|
84
76
|
return urlInfo;
|
|
@@ -89,5 +81,4 @@ const getUrlInfo = async (text, opts = {
|
|
|
89
81
|
throw error;
|
|
90
82
|
}
|
|
91
83
|
}
|
|
92
|
-
};
|
|
93
|
-
exports.getUrlInfo = getUrlInfo;
|
|
84
|
+
};
|
package/lib/Utils/logger.js
CHANGED
|
@@ -1,7 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const pino_1 = __importDefault(require("pino"));
|
|
7
|
-
exports.default = (0, pino_1.default)({ timestamp: () => `,"time":"${new Date().toJSON()}"` });
|
|
1
|
+
import P from 'pino';
|
|
2
|
+
export default P({ timestamp: () => `,"time":"${new Date().toJSON()}"` });
|
package/lib/Utils/lt-hash.js
CHANGED
|
@@ -1,51 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LT_HASH_ANTI_TAMPERING = void 0;
|
|
4
|
-
const crypto_1 = require("./crypto");
|
|
1
|
+
import { LTHashAntiTampering } from 'whatsapp-rust-bridge';
|
|
5
2
|
/**
|
|
6
3
|
* LT Hash is a summation based hash algorithm that maintains the integrity of a piece of data
|
|
7
4
|
* over a series of mutations. You can add/remove mutations and it'll return a hash equal to
|
|
8
5
|
* if the same series of mutations was made sequentially.
|
|
9
6
|
*/
|
|
10
|
-
const
|
|
11
|
-
class d {
|
|
12
|
-
constructor(e) {
|
|
13
|
-
this.salt = e;
|
|
14
|
-
}
|
|
15
|
-
add(e, t) {
|
|
16
|
-
var r = this;
|
|
17
|
-
for (const item of t) {
|
|
18
|
-
e = r._addSingle(e, item);
|
|
19
|
-
}
|
|
20
|
-
return e;
|
|
21
|
-
}
|
|
22
|
-
subtract(e, t) {
|
|
23
|
-
var r = this;
|
|
24
|
-
for (const item of t) {
|
|
25
|
-
e = r._subtractSingle(e, item);
|
|
26
|
-
}
|
|
27
|
-
return e;
|
|
28
|
-
}
|
|
29
|
-
subtractThenAdd(e, t, r) {
|
|
30
|
-
var n = this;
|
|
31
|
-
return n.add(n.subtract(e, r), t);
|
|
32
|
-
}
|
|
33
|
-
_addSingle(e, t) {
|
|
34
|
-
var r = this;
|
|
35
|
-
const n = new Uint8Array((0, crypto_1.hkdf)(Buffer.from(t), o, { info: r.salt })).buffer;
|
|
36
|
-
return r.performPointwiseWithOverflow(e, n, ((e, t) => e + t));
|
|
37
|
-
}
|
|
38
|
-
_subtractSingle(e, t) {
|
|
39
|
-
var r = this;
|
|
40
|
-
const n = new Uint8Array((0, crypto_1.hkdf)(Buffer.from(t), o, { info: r.salt })).buffer;
|
|
41
|
-
return r.performPointwiseWithOverflow(e, n, ((e, t) => e - t));
|
|
42
|
-
}
|
|
43
|
-
performPointwiseWithOverflow(e, t, r) {
|
|
44
|
-
const n = new DataView(e), i = new DataView(t), a = new ArrayBuffer(n.byteLength), s = new DataView(a);
|
|
45
|
-
for (let e = 0; e < n.byteLength; e += 2) {
|
|
46
|
-
s.setUint16(e, r(n.getUint16(e, !0), i.getUint16(e, !0)), !0);
|
|
47
|
-
}
|
|
48
|
-
return a;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
exports.LT_HASH_ANTI_TAMPERING = new d('WhatsApp Patch Integrity');
|
|
7
|
+
export const LT_HASH_ANTI_TAMPERING = new LTHashAntiTampering();
|
package/lib/Utils/make-mutex.js
CHANGED
|
@@ -1,55 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Creates a mutex that processes tasks sequentially.
|
|
6
|
-
* @param taskTimeoutMs max time (ms) a single task may run before being forcefully
|
|
7
|
-
* rejected to unblock the queue. Default: 30 000 ms.
|
|
8
|
-
*/
|
|
9
|
-
const makeMutex = (taskTimeoutMs = 30000) => {
|
|
10
|
-
let task = Promise.resolve();
|
|
1
|
+
import { Mutex as AsyncMutex } from 'async-mutex';
|
|
2
|
+
export const makeMutex = () => {
|
|
3
|
+
const mutex = new AsyncMutex();
|
|
11
4
|
return {
|
|
12
5
|
mutex(code) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// if there is an error, we swallow so as to not block the queue
|
|
16
|
-
try {
|
|
17
|
-
await task;
|
|
18
|
-
}
|
|
19
|
-
catch (_a) { }
|
|
20
|
-
// run current task with a timeout guard so a single hung task
|
|
21
|
-
// (e.g. a stalled WA query) never freezes the whole processing queue
|
|
22
|
-
let timeoutHandle;
|
|
23
|
-
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
24
|
-
timeoutHandle = setTimeout(
|
|
25
|
-
() => reject(new Error(`makeMutex: task timed out after ${taskTimeoutMs}ms`)),
|
|
26
|
-
taskTimeoutMs
|
|
27
|
-
);
|
|
28
|
-
});
|
|
29
|
-
try {
|
|
30
|
-
const result = await Promise.race([code(), timeoutPromise]);
|
|
31
|
-
return result;
|
|
32
|
-
}
|
|
33
|
-
finally {
|
|
34
|
-
clearTimeout(timeoutHandle);
|
|
35
|
-
}
|
|
36
|
-
})();
|
|
37
|
-
// we replace the existing task, appending the new piece of execution to it
|
|
38
|
-
// so the next task will have to wait for this one to finish
|
|
39
|
-
return task;
|
|
40
|
-
},
|
|
6
|
+
return mutex.runExclusive(code);
|
|
7
|
+
}
|
|
41
8
|
};
|
|
42
9
|
};
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
const map = {};
|
|
10
|
+
export const makeKeyedMutex = () => {
|
|
11
|
+
const map = new Map();
|
|
46
12
|
return {
|
|
47
|
-
mutex(key, task) {
|
|
48
|
-
|
|
49
|
-
|
|
13
|
+
async mutex(key, task) {
|
|
14
|
+
let entry = map.get(key);
|
|
15
|
+
if (!entry) {
|
|
16
|
+
entry = { mutex: new AsyncMutex(), refCount: 0 };
|
|
17
|
+
map.set(key, entry);
|
|
18
|
+
}
|
|
19
|
+
entry.refCount++;
|
|
20
|
+
try {
|
|
21
|
+
return await entry.mutex.runExclusive(task);
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
entry.refCount--;
|
|
25
|
+
// only delete it if this is still the current entry
|
|
26
|
+
if (entry.refCount === 0 && map.get(key) === entry) {
|
|
27
|
+
map.delete(key);
|
|
28
|
+
}
|
|
50
29
|
}
|
|
51
|
-
return map[key].mutex(task);
|
|
52
30
|
}
|
|
53
31
|
};
|
|
54
|
-
};
|
|
55
|
-
exports.makeKeyedMutex = makeKeyedMutex;
|
|
32
|
+
};
|