@queenanya/baileys 9.2.4 → 9.4.3
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 +329 -1237
- package/WAProto/fix-imports.js +22 -18
- package/WAProto/index.js +22 -18
- package/lib/Defaults/index.d.ts +17 -0
- package/lib/Defaults/index.d.ts.map +1 -1
- package/lib/Defaults/index.js +29 -3
- package/lib/Defaults/index.js.map +1 -1
- package/lib/Signal/libsignal.d.ts.map +1 -1
- package/lib/Signal/libsignal.js +61 -2
- package/lib/Signal/libsignal.js.map +1 -1
- package/lib/Signal/lid-mapping.d.ts +5 -9
- package/lib/Signal/lid-mapping.d.ts.map +1 -1
- package/lib/Signal/lid-mapping.js +170 -70
- package/lib/Signal/lid-mapping.js.map +1 -1
- package/lib/Socket/business.d.ts +114 -2
- package/lib/Socket/business.d.ts.map +1 -1
- package/lib/Socket/chats.d.ts +14 -1
- package/lib/Socket/chats.d.ts.map +1 -1
- package/lib/Socket/chats.js +253 -38
- package/lib/Socket/chats.js.map +1 -1
- package/lib/Socket/communities.d.ts +114 -2
- package/lib/Socket/communities.d.ts.map +1 -1
- package/lib/Socket/groups.d.ts +9 -0
- package/lib/Socket/groups.d.ts.map +1 -1
- package/lib/Socket/groups.js +6 -0
- package/lib/Socket/groups.js.map +1 -1
- package/lib/Socket/index.d.ts +114 -2
- package/lib/Socket/index.d.ts.map +1 -1
- package/lib/Socket/index.js +0 -6
- package/lib/Socket/index.js.map +1 -1
- package/lib/Socket/messages-recv.d.ts +115 -3
- package/lib/Socket/messages-recv.d.ts.map +1 -1
- package/lib/Socket/messages-recv.js +739 -150
- package/lib/Socket/messages-recv.js.map +1 -1
- package/lib/Socket/messages-send.d.ts +118 -4
- package/lib/Socket/messages-send.d.ts.map +1 -1
- package/lib/Socket/messages-send.js +328 -86
- package/lib/Socket/messages-send.js.map +1 -1
- package/lib/Socket/newsletter.d.ts +9 -0
- package/lib/Socket/newsletter.d.ts.map +1 -1
- package/lib/Socket/newsletter.js +2 -2
- package/lib/Socket/newsletter.js.map +1 -1
- package/lib/Socket/socket.d.ts +2 -0
- package/lib/Socket/socket.d.ts.map +1 -1
- package/lib/Socket/socket.js +143 -17
- package/lib/Socket/socket.js.map +1 -1
- package/lib/Types/Auth.d.ts +2 -0
- package/lib/Types/Auth.d.ts.map +1 -1
- package/lib/Types/Call.d.ts +10 -1
- package/lib/Types/Call.d.ts.map +1 -1
- package/lib/Types/Contact.d.ts +2 -0
- package/lib/Types/Contact.d.ts.map +1 -1
- package/lib/Types/Events.d.ts +21 -1
- package/lib/Types/Events.d.ts.map +1 -1
- package/lib/Types/GroupMetadata.d.ts +4 -0
- package/lib/Types/GroupMetadata.d.ts.map +1 -1
- package/lib/Types/Message.d.ts +530 -16
- package/lib/Types/Message.d.ts.map +1 -1
- package/lib/Types/Message.js.map +1 -1
- package/lib/Types/Newsletter.d.ts +37 -31
- package/lib/Types/Newsletter.d.ts.map +1 -1
- package/lib/Types/Newsletter.js +27 -23
- package/lib/Types/Newsletter.js.map +1 -1
- package/lib/Types/State.d.ts +54 -0
- package/lib/Types/State.d.ts.map +1 -1
- package/lib/Types/State.js +42 -0
- package/lib/Types/State.js.map +1 -1
- package/lib/Types/index.d.ts +9 -0
- package/lib/Types/index.d.ts.map +1 -1
- package/lib/Types/index.js.map +1 -1
- package/lib/Utils/browser-utils.d.ts +13 -0
- package/lib/Utils/browser-utils.d.ts.map +1 -1
- package/lib/Utils/browser-utils.js +90 -10
- package/lib/Utils/browser-utils.js.map +1 -1
- package/lib/Utils/chat-utils.d.ts +30 -0
- package/lib/Utils/chat-utils.d.ts.map +1 -1
- package/lib/Utils/chat-utils.js +81 -52
- package/lib/Utils/chat-utils.js.map +1 -1
- package/lib/Utils/companion-reg-client-utils.d.ts +17 -0
- package/lib/Utils/companion-reg-client-utils.d.ts.map +1 -0
- package/lib/Utils/companion-reg-client-utils.js +34 -0
- package/lib/Utils/companion-reg-client-utils.js.map +1 -0
- package/lib/Utils/crypto.d.ts +4 -8
- package/lib/Utils/crypto.d.ts.map +1 -1
- package/lib/Utils/crypto.js +2 -26
- package/lib/Utils/crypto.js.map +1 -1
- package/lib/Utils/decode-wa-message.d.ts +12 -0
- package/lib/Utils/decode-wa-message.d.ts.map +1 -1
- package/lib/Utils/decode-wa-message.js +16 -0
- package/lib/Utils/decode-wa-message.js.map +1 -1
- package/lib/Utils/event-buffer.js +10 -1
- package/lib/Utils/event-buffer.js.map +1 -1
- package/lib/Utils/generics.d.ts +3 -1
- package/lib/Utils/generics.d.ts.map +1 -1
- package/lib/Utils/generics.js +16 -3
- package/lib/Utils/generics.js.map +1 -1
- package/lib/Utils/history.d.ts +5 -2
- package/lib/Utils/history.d.ts.map +1 -1
- package/lib/Utils/history.js +53 -17
- package/lib/Utils/history.js.map +1 -1
- package/lib/Utils/identity-change-handler.d.ts +44 -0
- package/lib/Utils/identity-change-handler.d.ts.map +1 -0
- package/lib/Utils/identity-change-handler.js +50 -0
- package/lib/Utils/identity-change-handler.js.map +1 -0
- package/lib/Utils/index.d.ts +6 -0
- package/lib/Utils/index.d.ts.map +1 -1
- package/lib/Utils/index.js +6 -0
- package/lib/Utils/index.js.map +1 -1
- package/lib/Utils/interactive-message.d.ts +201 -0
- package/lib/Utils/interactive-message.d.ts.map +1 -0
- package/lib/Utils/interactive-message.js +256 -0
- package/lib/Utils/interactive-message.js.map +1 -0
- package/lib/Utils/lt-hash.d.ts +7 -12
- package/lib/Utils/lt-hash.d.ts.map +1 -1
- package/lib/Utils/lt-hash.js +2 -42
- package/lib/Utils/lt-hash.js.map +1 -1
- package/lib/Utils/message-composer.d.ts +5 -0
- package/lib/Utils/message-composer.d.ts.map +1 -0
- package/lib/Utils/message-composer.js +5 -0
- package/lib/Utils/message-composer.js.map +1 -0
- package/lib/Utils/message-retry-manager.d.ts +30 -2
- package/lib/Utils/message-retry-manager.d.ts.map +1 -1
- package/lib/Utils/message-retry-manager.js +59 -2
- package/lib/Utils/message-retry-manager.js.map +1 -1
- package/lib/Utils/messages-media.d.ts +19 -5
- package/lib/Utils/messages-media.d.ts.map +1 -1
- package/lib/Utils/messages-media.js +26 -17
- package/lib/Utils/messages-media.js.map +1 -1
- package/lib/Utils/messages.d.ts.map +1 -1
- package/lib/Utils/messages.js +433 -13
- package/lib/Utils/messages.js.map +1 -1
- package/lib/Utils/noise-handler.d.ts +2 -2
- package/lib/Utils/noise-handler.d.ts.map +1 -1
- package/lib/Utils/noise-handler.js +10 -10
- package/lib/Utils/noise-handler.js.map +1 -1
- package/lib/Utils/offline-node-processor.d.ts +17 -0
- package/lib/Utils/offline-node-processor.d.ts.map +1 -0
- package/lib/Utils/offline-node-processor.js +40 -0
- package/lib/Utils/offline-node-processor.js.map +1 -0
- package/lib/Utils/process-message.d.ts.map +1 -1
- package/lib/Utils/process-message.js +96 -16
- package/lib/Utils/process-message.js.map +1 -1
- package/lib/Utils/reporting-utils.js +2 -2
- package/lib/Utils/reporting-utils.js.map +1 -1
- package/lib/Utils/stanza-ack.d.ts +11 -0
- package/lib/Utils/stanza-ack.d.ts.map +1 -0
- package/lib/Utils/stanza-ack.js +38 -0
- package/lib/Utils/stanza-ack.js.map +1 -0
- package/lib/Utils/sync-action-utils.d.ts.map +1 -1
- package/lib/Utils/sync-action-utils.js +2 -1
- package/lib/Utils/sync-action-utils.js.map +1 -1
- package/lib/Utils/tc-token-utils.d.ts +26 -1
- package/lib/Utils/tc-token-utils.d.ts.map +1 -1
- package/lib/Utils/tc-token-utils.js +149 -4
- package/lib/Utils/tc-token-utils.js.map +1 -1
- package/lib/Utils/use-mongo-file-auth-state.d.ts +16 -0
- package/lib/Utils/use-mongo-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-mongo-file-auth-state.js +60 -0
- package/lib/Utils/use-mongo-file-auth-state.js.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.js +1 -1
- package/lib/Utils/use-multi-file-auth-state.js.map +1 -1
- package/lib/Utils/validate-connection.d.ts.map +1 -1
- package/lib/Utils/validate-connection.js +11 -1
- package/lib/Utils/validate-connection.js.map +1 -1
- package/lib/WABinary/generic-utils.d.ts +9 -0
- package/lib/WABinary/generic-utils.d.ts.map +1 -1
- package/lib/WABinary/generic-utils.js +23 -0
- package/lib/WABinary/generic-utils.js.map +1 -1
- package/lib/WABinary/jid-utils.js.map +1 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +26 -3
- package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -1
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +10 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/index.d.ts +1 -0
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -1
- package/lib/WAUSync/Protocols/index.js +1 -0
- package/lib/WAUSync/Protocols/index.js.map +1 -1
- package/lib/WAUSync/USyncQuery.d.ts +1 -0
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -1
- package/lib/WAUSync/USyncQuery.js +5 -1
- package/lib/WAUSync/USyncQuery.js.map +1 -1
- package/lib/WAUSync/USyncUser.d.ts +4 -0
- package/lib/WAUSync/USyncUser.d.ts.map +1 -1
- package/lib/WAUSync/USyncUser.js +8 -0
- package/lib/WAUSync/USyncUser.js.map +1 -1
- package/lib/addons/anti-delete.d.ts +72 -0
- package/lib/addons/anti-delete.d.ts.map +1 -0
- package/lib/addons/anti-delete.js +165 -0
- package/lib/addons/anti-delete.js.map +1 -0
- package/lib/addons/auto-reply.d.ts +67 -0
- package/lib/addons/auto-reply.d.ts.map +1 -0
- package/lib/addons/auto-reply.js +145 -0
- package/lib/addons/auto-reply.js.map +1 -0
- package/lib/addons/browser-presets.d.ts +16 -0
- package/lib/addons/browser-presets.d.ts.map +1 -0
- package/lib/addons/browser-presets.js +24 -0
- package/lib/addons/browser-presets.js.map +1 -0
- package/lib/addons/button-sender.d.ts +260 -0
- package/lib/addons/button-sender.d.ts.map +1 -0
- package/lib/addons/button-sender.js +771 -0
- package/lib/addons/button-sender.js.map +1 -0
- package/lib/addons/call-handler.d.ts +79 -0
- package/lib/addons/call-handler.d.ts.map +1 -0
- package/lib/addons/call-handler.js +342 -0
- package/lib/addons/call-handler.js.map +1 -0
- package/lib/addons/from-chats.d.ts +30 -0
- package/lib/addons/from-chats.d.ts.map +1 -0
- package/lib/addons/from-chats.js +38 -0
- package/lib/addons/from-chats.js.map +1 -0
- package/lib/addons/from-messages-recv.d.ts +59 -0
- package/lib/addons/from-messages-recv.d.ts.map +1 -0
- package/lib/addons/from-messages-recv.js +326 -0
- package/lib/addons/from-messages-recv.js.map +1 -0
- package/lib/addons/from-messages-send.d.ts +50 -0
- package/lib/addons/from-messages-send.d.ts.map +1 -0
- package/lib/addons/from-messages-send.js +148 -0
- package/lib/addons/from-messages-send.js.map +1 -0
- package/lib/addons/from-messages.d.ts +52 -0
- package/lib/addons/from-messages.d.ts.map +1 -0
- package/lib/addons/from-messages.js +304 -0
- package/lib/addons/from-messages.js.map +1 -0
- package/lib/addons/index.d.ts +67 -0
- package/lib/addons/index.d.ts.map +1 -0
- package/lib/addons/index.js +86 -0
- package/lib/addons/index.js.map +1 -0
- package/lib/addons/interactive-message.d.ts +201 -0
- package/lib/addons/interactive-message.d.ts.map +1 -0
- package/lib/addons/interactive-message.js +256 -0
- package/lib/addons/interactive-message.js.map +1 -0
- package/lib/addons/jid-plot.d.ts +49 -0
- package/lib/addons/jid-plot.d.ts.map +1 -0
- package/lib/addons/jid-plot.js +84 -0
- package/lib/addons/jid-plot.js.map +1 -0
- package/lib/addons/jid-plotting.d.ts +54 -0
- package/lib/addons/jid-plotting.d.ts.map +1 -0
- package/lib/addons/jid-plotting.js +150 -0
- package/lib/addons/jid-plotting.js.map +1 -0
- package/lib/addons/lid-support.d.ts +41 -0
- package/lib/addons/lid-support.d.ts.map +1 -0
- package/lib/addons/lid-support.js +42 -0
- package/lib/addons/lid-support.js.map +1 -0
- package/lib/addons/message-composer.d.ts +142 -0
- package/lib/addons/message-composer.d.ts.map +1 -0
- package/lib/addons/message-composer.js +377 -0
- package/lib/addons/message-composer.js.map +1 -0
- package/lib/addons/message-scheduler.d.ts +77 -0
- package/lib/addons/message-scheduler.d.ts.map +1 -0
- package/lib/addons/message-scheduler.js +108 -0
- package/lib/addons/message-scheduler.js.map +1 -0
- package/lib/addons/message-search.d.ts +51 -0
- package/lib/addons/message-search.d.ts.map +1 -0
- package/lib/addons/message-search.js +171 -0
- package/lib/addons/message-search.js.map +1 -0
- package/lib/addons/message-utils.d.ts +88 -0
- package/lib/addons/message-utils.d.ts.map +1 -0
- package/lib/addons/message-utils.js +292 -0
- package/lib/addons/message-utils.js.map +1 -0
- package/lib/addons/outgoing-calls.d.ts +64 -0
- package/lib/addons/outgoing-calls.d.ts.map +1 -0
- package/lib/addons/outgoing-calls.js +139 -0
- package/lib/addons/outgoing-calls.js.map +1 -0
- package/lib/addons/pairing-fix.d.ts +31 -0
- package/lib/addons/pairing-fix.d.ts.map +1 -0
- package/lib/addons/pairing-fix.js +74 -0
- package/lib/addons/pairing-fix.js.map +1 -0
- package/lib/addons/past-participants.d.ts +42 -0
- package/lib/addons/past-participants.d.ts.map +1 -0
- package/lib/addons/past-participants.js +41 -0
- package/lib/addons/past-participants.js.map +1 -0
- package/lib/addons/rich-response.d.ts +111 -0
- package/lib/addons/rich-response.d.ts.map +1 -0
- package/lib/addons/rich-response.js +152 -0
- package/lib/addons/rich-response.js.map +1 -0
- package/lib/addons/scheduling.d.ts +41 -0
- package/lib/addons/scheduling.d.ts.map +1 -0
- package/lib/addons/scheduling.js +110 -0
- package/lib/addons/scheduling.js.map +1 -0
- package/lib/addons/status-posting.d.ts +177 -0
- package/lib/addons/status-posting.d.ts.map +1 -0
- package/lib/addons/status-posting.js +240 -0
- package/lib/addons/status-posting.js.map +1 -0
- package/lib/addons/stickerpack.d.ts +37 -0
- package/lib/addons/stickerpack.d.ts.map +1 -0
- package/lib/addons/stickerpack.js +39 -0
- package/lib/addons/stickerpack.js.map +1 -0
- package/lib/addons/templates.d.ts +72 -0
- package/lib/addons/templates.d.ts.map +1 -0
- package/lib/addons/templates.js +145 -0
- package/lib/addons/templates.js.map +1 -0
- package/lib/addons/vcard.d.ts +59 -0
- package/lib/addons/vcard.d.ts.map +1 -0
- package/lib/addons/vcard.js +88 -0
- package/lib/addons/vcard.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/package.json +5 -3
package/lib/Socket/chats.js
CHANGED
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
import NodeCache from '@cacheable/node-cache';
|
|
2
2
|
import { Boom } from '@hapi/boom';
|
|
3
|
+
import Long from 'long';
|
|
3
4
|
import { proto } from '../../WAProto/index.js';
|
|
4
|
-
import { DEFAULT_CACHE_TTLS, PROCESSABLE_HISTORY_TYPES } from '../Defaults/index.js';
|
|
5
|
+
import { DEFAULT_CACHE_TTLS, HISTORY_SYNC_PAUSED_TIMEOUT_MS, PROCESSABLE_HISTORY_TYPES } from '../Defaults/index.js';
|
|
5
6
|
import { ALL_WA_PATCH_NAMES } from '../Types/index.js';
|
|
6
7
|
import { SyncState } from '../Types/State.js';
|
|
7
|
-
import { chatModificationToAppPatch, decodePatches, decodeSyncdSnapshot, encodeSyncdPatch, extractSyncdPatches, generateProfilePicture, getHistoryMsg, newLTHashState, processSyncAction } from '../Utils/index.js';
|
|
8
|
+
import { chatModificationToAppPatch, decodePatches, decodeSyncdSnapshot, encodeSyncdPatch, ensureLTHashStateVersion, extractSyncdPatches, generateProfilePicture, getHistoryMsg, isAppStateSyncIrrecoverable, isMissingKeyError, MAX_SYNC_ATTEMPTS, newLTHashState, processSyncAction } from '../Utils/index.js';
|
|
8
9
|
import { makeMutex } from '../Utils/make-mutex.js';
|
|
9
10
|
import processMessage from '../Utils/process-message.js';
|
|
10
11
|
import { buildTcTokenFromJid } from '../Utils/tc-token-utils.js';
|
|
11
|
-
import { getBinaryNodeChild, getBinaryNodeChildren, jidDecode, jidNormalizedUser, reduceBinaryNodeToDictionary, S_WHATSAPP_NET } from '../WABinary/index.js';
|
|
12
|
+
import { getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser, isLidUser, isPnUser, jidDecode, jidNormalizedUser, reduceBinaryNodeToDictionary, S_WHATSAPP_NET } from '../WABinary/index.js';
|
|
12
13
|
import { USyncQuery, USyncUser } from '../WAUSync/index.js';
|
|
13
14
|
import { makeSocket } from './socket.js';
|
|
14
|
-
const MAX_SYNC_ATTEMPTS = 2;
|
|
15
15
|
export const makeChatsSocket = (config) => {
|
|
16
16
|
const { logger, markOnlineOnConnect, fireInitQueries, appStateMacVerification, shouldIgnoreJid, shouldSyncHistoryMessage, getMessage } = config;
|
|
17
17
|
const sock = makeSocket(config);
|
|
18
|
-
const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError } = sock;
|
|
18
|
+
const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError, sendUnifiedSession } = sock;
|
|
19
|
+
const getLIDForPN = signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping);
|
|
19
20
|
let privacySettings;
|
|
21
|
+
/** Server-assigned AB props for protocol behavior. */
|
|
22
|
+
const serverProps = {
|
|
23
|
+
/** AB prop 10518: gate tctoken on 1:1 messages. Default true (safe: avoids 463). */
|
|
24
|
+
privacyTokenOn1to1: true,
|
|
25
|
+
/** AB prop 9666: gate tctoken on profile picture IQs. WA Web default: true. */
|
|
26
|
+
profilePicPrivacyToken: true,
|
|
27
|
+
/** AB prop 14303: issue tctokens to LID instead of PN. WA Web default: false. */
|
|
28
|
+
lidTrustedTokenIssueToLid: false
|
|
29
|
+
};
|
|
20
30
|
let syncState = SyncState.Connecting;
|
|
21
31
|
/** this mutex ensures that messages are processed in order */
|
|
22
32
|
const messageMutex = makeMutex();
|
|
@@ -28,6 +38,15 @@ export const makeChatsSocket = (config) => {
|
|
|
28
38
|
const notificationMutex = makeMutex();
|
|
29
39
|
// Timeout for AwaitingInitialSync state
|
|
30
40
|
let awaitingSyncTimeout;
|
|
41
|
+
// In-memory history sync completion tracking (resets on reconnection)
|
|
42
|
+
const historySyncStatus = {
|
|
43
|
+
initialBootstrapComplete: false,
|
|
44
|
+
recentSyncComplete: false
|
|
45
|
+
};
|
|
46
|
+
let historySyncPausedTimeout;
|
|
47
|
+
// Collections blocked on missing app state sync keys (mirrors WA Web's "Blocked" state).
|
|
48
|
+
// When a key arrives via APP_STATE_SYNC_KEY_SHARE, these are re-synced.
|
|
49
|
+
const blockedCollections = new Set();
|
|
31
50
|
const placeholderResendCache = config.placeholderResendCache ||
|
|
32
51
|
new NodeCache({
|
|
33
52
|
stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
@@ -258,6 +277,42 @@ export const makeChatsSocket = (config) => {
|
|
|
258
277
|
return getBinaryNodeChildren(listNode, 'item').map(n => n.attrs.jid);
|
|
259
278
|
};
|
|
260
279
|
const updateBlockStatus = async (jid, action) => {
|
|
280
|
+
const normalizedJid = jidNormalizedUser(jid);
|
|
281
|
+
let lid;
|
|
282
|
+
let pn_jid;
|
|
283
|
+
if (isLidUser(normalizedJid) || isHostedLidUser(normalizedJid)) {
|
|
284
|
+
lid = normalizedJid;
|
|
285
|
+
if (action === 'block') {
|
|
286
|
+
const pn = await signalRepository.lidMapping.getPNForLID(normalizedJid);
|
|
287
|
+
if (!pn) {
|
|
288
|
+
throw new Boom(`Unable to resolve PN JID for LID: ${jid}`, { statusCode: 400 });
|
|
289
|
+
}
|
|
290
|
+
pn_jid = jidNormalizedUser(pn);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
else if (isPnUser(normalizedJid) || isHostedPnUser(normalizedJid)) {
|
|
294
|
+
const mapped = await signalRepository.lidMapping.getLIDForPN(normalizedJid);
|
|
295
|
+
if (!mapped) {
|
|
296
|
+
throw new Boom(`Unable to resolve LID for PN JID: ${jid}`, { statusCode: 400 });
|
|
297
|
+
}
|
|
298
|
+
lid = mapped;
|
|
299
|
+
if (action === 'block') {
|
|
300
|
+
pn_jid = jidNormalizedUser(normalizedJid);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
throw new Boom(`Invalid jid: ${jid}`, { statusCode: 400 });
|
|
305
|
+
}
|
|
306
|
+
const itemAttrs = {
|
|
307
|
+
action,
|
|
308
|
+
jid: lid
|
|
309
|
+
};
|
|
310
|
+
if (action === 'block') {
|
|
311
|
+
if (!pn_jid) {
|
|
312
|
+
throw new Boom(`pn_jid required for block: ${jid}`, { statusCode: 400 });
|
|
313
|
+
}
|
|
314
|
+
itemAttrs.pn_jid = pn_jid;
|
|
315
|
+
}
|
|
261
316
|
await query({
|
|
262
317
|
tag: 'iq',
|
|
263
318
|
attrs: {
|
|
@@ -268,10 +323,7 @@ export const makeChatsSocket = (config) => {
|
|
|
268
323
|
content: [
|
|
269
324
|
{
|
|
270
325
|
tag: 'item',
|
|
271
|
-
attrs:
|
|
272
|
-
action,
|
|
273
|
-
jid
|
|
274
|
-
}
|
|
326
|
+
attrs: itemAttrs
|
|
275
327
|
}
|
|
276
328
|
]
|
|
277
329
|
});
|
|
@@ -353,6 +405,15 @@ export const makeChatsSocket = (config) => {
|
|
|
353
405
|
};
|
|
354
406
|
};
|
|
355
407
|
const resyncAppState = ev.createBufferedFunction(async (collections, isInitialSync) => {
|
|
408
|
+
const appStateSyncKeyCache = new Map();
|
|
409
|
+
const getCachedAppStateSyncKey = async (keyId) => {
|
|
410
|
+
if (appStateSyncKeyCache.has(keyId)) {
|
|
411
|
+
return appStateSyncKeyCache.get(keyId) ?? undefined;
|
|
412
|
+
}
|
|
413
|
+
const key = await getAppStateSyncKey(keyId);
|
|
414
|
+
appStateSyncKeyCache.set(keyId, key ?? null);
|
|
415
|
+
return key;
|
|
416
|
+
};
|
|
356
417
|
// we use this to determine which events to fire
|
|
357
418
|
// otherwise when we resync from scratch -- all notifications will fire
|
|
358
419
|
const initialVersionMap = {};
|
|
@@ -361,6 +422,9 @@ export const makeChatsSocket = (config) => {
|
|
|
361
422
|
const collectionsToHandle = new Set(collections);
|
|
362
423
|
// in case something goes wrong -- ensure we don't enter a loop that cannot be exited from
|
|
363
424
|
const attemptsMap = {};
|
|
425
|
+
// collections that failed and need a full snapshot on retry
|
|
426
|
+
// mirrors WA Web's ErrorFatal -> force snapshot behavior
|
|
427
|
+
const forceSnapshotCollections = new Set();
|
|
364
428
|
// keep executing till all collections are done
|
|
365
429
|
// sometimes a single patch request will not return all the patches (God knows why)
|
|
366
430
|
// so we fetch till they're all done (this is determined by the "has_more_patches" flag)
|
|
@@ -371,6 +435,7 @@ export const makeChatsSocket = (config) => {
|
|
|
371
435
|
const result = await authState.keys.get('app-state-sync-version', [name]);
|
|
372
436
|
let state = result[name];
|
|
373
437
|
if (state) {
|
|
438
|
+
state = ensureLTHashStateVersion(state);
|
|
374
439
|
if (typeof initialVersionMap[name] === 'undefined') {
|
|
375
440
|
initialVersionMap[name] = state.version;
|
|
376
441
|
}
|
|
@@ -379,14 +444,18 @@ export const makeChatsSocket = (config) => {
|
|
|
379
444
|
state = newLTHashState();
|
|
380
445
|
}
|
|
381
446
|
states[name] = state;
|
|
382
|
-
|
|
447
|
+
const shouldForceSnapshot = forceSnapshotCollections.has(name);
|
|
448
|
+
if (shouldForceSnapshot) {
|
|
449
|
+
forceSnapshotCollections.delete(name);
|
|
450
|
+
}
|
|
451
|
+
logger.info(`resyncing ${name} from v${state.version}${shouldForceSnapshot ? ' (forcing snapshot)' : ''}`);
|
|
383
452
|
nodes.push({
|
|
384
453
|
tag: 'collection',
|
|
385
454
|
attrs: {
|
|
386
455
|
name,
|
|
387
456
|
version: state.version.toString(),
|
|
388
|
-
// return snapshot if
|
|
389
|
-
return_snapshot: (!state.version).toString()
|
|
457
|
+
// return snapshot if syncing from scratch or forcing after a failed attempt
|
|
458
|
+
return_snapshot: (shouldForceSnapshot || !state.version).toString()
|
|
390
459
|
}
|
|
391
460
|
});
|
|
392
461
|
}
|
|
@@ -412,7 +481,7 @@ export const makeChatsSocket = (config) => {
|
|
|
412
481
|
const { patches, hasMorePatches, snapshot } = decoded[name];
|
|
413
482
|
try {
|
|
414
483
|
if (snapshot) {
|
|
415
|
-
const { state: newState, mutationMap } = await decodeSyncdSnapshot(name, snapshot,
|
|
484
|
+
const { state: newState, mutationMap } = await decodeSyncdSnapshot(name, snapshot, getCachedAppStateSyncKey, initialVersionMap[name], appStateMacVerification.snapshot);
|
|
416
485
|
states[name] = newState;
|
|
417
486
|
Object.assign(globalMutationMap, mutationMap);
|
|
418
487
|
logger.info(`restored state of ${name} from snapshot to v${newState.version} with mutations`);
|
|
@@ -420,7 +489,7 @@ export const makeChatsSocket = (config) => {
|
|
|
420
489
|
}
|
|
421
490
|
// only process if there are syncd patches
|
|
422
491
|
if (patches.length) {
|
|
423
|
-
const { state: newState, mutationMap } = await decodePatches(name, patches, states[name],
|
|
492
|
+
const { state: newState, mutationMap } = await decodePatches(name, patches, states[name], getCachedAppStateSyncKey, config.options, initialVersionMap[name], logger, appStateMacVerification.patch);
|
|
424
493
|
await authState.keys.set({ 'app-state-sync-version': { [name]: newState } });
|
|
425
494
|
logger.info(`synced ${name} to v${newState.version}`);
|
|
426
495
|
initialVersionMap[name] = newState.version;
|
|
@@ -435,19 +504,37 @@ export const makeChatsSocket = (config) => {
|
|
|
435
504
|
}
|
|
436
505
|
}
|
|
437
506
|
catch (error) {
|
|
438
|
-
// if retry attempts overshoot
|
|
439
|
-
// or key not found
|
|
440
|
-
const isIrrecoverableError = attemptsMap[name] >= MAX_SYNC_ATTEMPTS ||
|
|
441
|
-
error.output?.statusCode === 404 ||
|
|
442
|
-
error.name === 'TypeError';
|
|
443
|
-
logger.info({ name, error: error.stack }, `failed to sync state from version${isIrrecoverableError ? '' : ', removing and trying from scratch'}`);
|
|
444
|
-
await authState.keys.set({ 'app-state-sync-version': { [name]: null } });
|
|
445
|
-
// increment number of retries
|
|
446
507
|
attemptsMap[name] = (attemptsMap[name] || 0) + 1;
|
|
447
|
-
|
|
448
|
-
|
|
508
|
+
const logData = {
|
|
509
|
+
name,
|
|
510
|
+
attempt: attemptsMap[name],
|
|
511
|
+
version: states[name].version,
|
|
512
|
+
statusCode: error.output?.statusCode,
|
|
513
|
+
errorType: error.name,
|
|
514
|
+
error: error.stack
|
|
515
|
+
};
|
|
516
|
+
if (isMissingKeyError(error) && attemptsMap[name] >= MAX_SYNC_ATTEMPTS) {
|
|
517
|
+
// WA Web treats missing keys as "Blocked" — park the collection
|
|
518
|
+
// until the key arrives via APP_STATE_SYNC_KEY_SHARE.
|
|
519
|
+
logger.warn(logData, `${name} blocked on missing key from v${states[name].version}, parking after ${attemptsMap[name]} attempts`);
|
|
520
|
+
blockedCollections.add(name);
|
|
449
521
|
collectionsToHandle.delete(name);
|
|
450
522
|
}
|
|
523
|
+
else if (isMissingKeyError(error)) {
|
|
524
|
+
// Retry with a snapshot which may use a different key.
|
|
525
|
+
logger.info(logData, `${name} blocked on missing key from v${states[name].version}, retrying with snapshot`);
|
|
526
|
+
forceSnapshotCollections.add(name);
|
|
527
|
+
}
|
|
528
|
+
else if (isAppStateSyncIrrecoverable(error, attemptsMap[name])) {
|
|
529
|
+
logger.warn(logData, `failed to sync ${name} from v${states[name].version}, giving up`);
|
|
530
|
+
collectionsToHandle.delete(name);
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
logger.info(logData, `failed to sync ${name} from v${states[name].version}, forcing snapshot retry`);
|
|
534
|
+
// force a full snapshot on retry to recover from
|
|
535
|
+
// corrupted local state (e.g. LTHash MAC mismatch)
|
|
536
|
+
forceSnapshotCollections.add(name);
|
|
537
|
+
}
|
|
451
538
|
}
|
|
452
539
|
}
|
|
453
540
|
}
|
|
@@ -464,7 +551,22 @@ export const makeChatsSocket = (config) => {
|
|
|
464
551
|
*/
|
|
465
552
|
const profilePictureUrl = async (jid, type = 'preview', timeoutMs) => {
|
|
466
553
|
const baseContent = [{ tag: 'picture', attrs: { type, query: 'url' } }];
|
|
467
|
-
|
|
554
|
+
// WA Web only includes tctoken for user JIDs (not groups/newsletters)
|
|
555
|
+
// and never for own profile pic (Chat model for self has no tcToken).
|
|
556
|
+
// Including tctoken for own JID causes the server to never respond.
|
|
557
|
+
const normalizedJid = jidNormalizedUser(jid);
|
|
558
|
+
const isUserJid = isPnUser(normalizedJid) || isLidUser(normalizedJid);
|
|
559
|
+
const me = authState.creds.me;
|
|
560
|
+
const isSelf = me && (normalizedJid === jidNormalizedUser(me.id) || (me.lid && normalizedJid === jidNormalizedUser(me.lid)));
|
|
561
|
+
let content = baseContent;
|
|
562
|
+
if (serverProps.profilePicPrivacyToken && isUserJid && !isSelf) {
|
|
563
|
+
content = await buildTcTokenFromJid({
|
|
564
|
+
authState,
|
|
565
|
+
jid: normalizedJid,
|
|
566
|
+
baseContent,
|
|
567
|
+
getLIDForPN
|
|
568
|
+
});
|
|
569
|
+
}
|
|
468
570
|
jid = jidNormalizedUser(jid);
|
|
469
571
|
const result = await query({
|
|
470
572
|
tag: 'iq',
|
|
@@ -474,7 +576,7 @@ export const makeChatsSocket = (config) => {
|
|
|
474
576
|
type: 'get',
|
|
475
577
|
xmlns: 'w:profile:picture'
|
|
476
578
|
},
|
|
477
|
-
content
|
|
579
|
+
content
|
|
478
580
|
}, timeoutMs);
|
|
479
581
|
const child = getBinaryNodeChild(result, 'picture');
|
|
480
582
|
return child?.attrs?.url;
|
|
@@ -499,12 +601,16 @@ export const makeChatsSocket = (config) => {
|
|
|
499
601
|
};
|
|
500
602
|
const sendPresenceUpdate = async (type, toJid) => {
|
|
501
603
|
const me = authState.creds.me;
|
|
502
|
-
|
|
604
|
+
const isAvailableType = type === 'available';
|
|
605
|
+
if (isAvailableType || type === 'unavailable') {
|
|
503
606
|
if (!me.name) {
|
|
504
607
|
logger.warn('no name present, ignoring presence update request...');
|
|
505
608
|
return;
|
|
506
609
|
}
|
|
507
|
-
ev.emit('connection.update', { isOnline:
|
|
610
|
+
ev.emit('connection.update', { isOnline: isAvailableType });
|
|
611
|
+
if (isAvailableType) {
|
|
612
|
+
void sendUnifiedSession();
|
|
613
|
+
}
|
|
508
614
|
await sendNode({
|
|
509
615
|
tag: 'presence',
|
|
510
616
|
attrs: {
|
|
@@ -536,7 +642,12 @@ export const makeChatsSocket = (config) => {
|
|
|
536
642
|
* @param tcToken token for subscription, use if present
|
|
537
643
|
*/
|
|
538
644
|
const presenceSubscribe = async (toJid) => {
|
|
539
|
-
|
|
645
|
+
// Only include tctoken for user JIDs — groups/newsletters don't use tctokens
|
|
646
|
+
const normalizedToJid = jidNormalizedUser(toJid);
|
|
647
|
+
const isUserJid = isPnUser(normalizedToJid) || isLidUser(normalizedToJid);
|
|
648
|
+
const tcTokenContent = isUserJid
|
|
649
|
+
? await buildTcTokenFromJid({ authState, jid: normalizedToJid, getLIDForPN })
|
|
650
|
+
: undefined;
|
|
540
651
|
return sendNode({
|
|
541
652
|
tag: 'presence',
|
|
542
653
|
attrs: {
|
|
@@ -591,7 +702,7 @@ export const makeChatsSocket = (config) => {
|
|
|
591
702
|
logger.debug({ patch: patchCreate }, 'applying app patch');
|
|
592
703
|
await resyncAppState([name], false);
|
|
593
704
|
const { [name]: currentSyncVersion } = await authState.keys.get('app-state-sync-version', [name]);
|
|
594
|
-
initial = currentSyncVersion
|
|
705
|
+
initial = currentSyncVersion ? ensureLTHashStateVersion(currentSyncVersion) : newLTHashState();
|
|
595
706
|
encodeResult = await encodeSyncdPatch(patchCreate, myAppStateKeyId, initial, getAppStateSyncKey);
|
|
596
707
|
const { patch, state } = encodeResult;
|
|
597
708
|
const node = {
|
|
@@ -637,22 +748,21 @@ export const makeChatsSocket = (config) => {
|
|
|
637
748
|
}
|
|
638
749
|
}
|
|
639
750
|
};
|
|
640
|
-
/**
|
|
751
|
+
/** fetch AB props */
|
|
641
752
|
const fetchProps = async () => {
|
|
642
|
-
//TODO: implement both protocol 1 and protocol 2 prop fetching, specially for abKey for WM
|
|
643
753
|
const resultNode = await query({
|
|
644
754
|
tag: 'iq',
|
|
645
755
|
attrs: {
|
|
646
756
|
to: S_WHATSAPP_NET,
|
|
647
|
-
xmlns: '
|
|
757
|
+
xmlns: 'abt',
|
|
648
758
|
type: 'get'
|
|
649
759
|
},
|
|
650
760
|
content: [
|
|
651
761
|
{
|
|
652
762
|
tag: 'props',
|
|
653
763
|
attrs: {
|
|
654
|
-
protocol: '
|
|
655
|
-
hash: authState
|
|
764
|
+
protocol: '1',
|
|
765
|
+
...(authState?.creds?.lastPropHash ? { hash: authState.creds.lastPropHash } : {})
|
|
656
766
|
}
|
|
657
767
|
}
|
|
658
768
|
]
|
|
@@ -667,7 +777,20 @@ export const makeChatsSocket = (config) => {
|
|
|
667
777
|
}
|
|
668
778
|
props = reduceBinaryNodeToDictionary(propsNode, 'prop');
|
|
669
779
|
}
|
|
670
|
-
|
|
780
|
+
// Extract protocol-relevant AB props (only the ones we need)
|
|
781
|
+
const privacyTokenProp = props['10518'] ?? props['privacy_token_sending_on_all_1_on_1_messages'];
|
|
782
|
+
if (privacyTokenProp !== undefined) {
|
|
783
|
+
serverProps.privacyTokenOn1to1 = privacyTokenProp === 'true' || privacyTokenProp === '1';
|
|
784
|
+
}
|
|
785
|
+
const profilePicProp = props['9666'] ?? props['profile_scraping_privacy_token_in_photo_iq'];
|
|
786
|
+
if (profilePicProp !== undefined) {
|
|
787
|
+
serverProps.profilePicPrivacyToken = profilePicProp === 'true' || profilePicProp === '1';
|
|
788
|
+
}
|
|
789
|
+
const lidIssueProp = props['14303'] ?? props['lid_trusted_token_issue_to_lid'];
|
|
790
|
+
if (lidIssueProp !== undefined) {
|
|
791
|
+
serverProps.lidTrustedTokenIssueToLid = lidIssueProp === 'true' || lidIssueProp === '1';
|
|
792
|
+
}
|
|
793
|
+
logger.debug({ serverProps }, 'fetched props');
|
|
671
794
|
return props;
|
|
672
795
|
};
|
|
673
796
|
/**
|
|
@@ -782,6 +905,13 @@ export const makeChatsSocket = (config) => {
|
|
|
782
905
|
quickReply: { timestamp, deleted: true }
|
|
783
906
|
}, '');
|
|
784
907
|
};
|
|
908
|
+
/**
|
|
909
|
+
* Clear a message from chat (delete for me)
|
|
910
|
+
*/
|
|
911
|
+
const clearMessage = (jid, key, timeStamp) => {
|
|
912
|
+
return chatModify({ delete: true, lastMessages: [{ key, messageTimestamp: timeStamp }] }, jid);
|
|
913
|
+
};
|
|
914
|
+
const deleteChat = clearMessage;
|
|
785
915
|
/**
|
|
786
916
|
* queries need to be fired on connection open
|
|
787
917
|
* help ensure parity with WA Web
|
|
@@ -807,6 +937,47 @@ export const makeChatsSocket = (config) => {
|
|
|
807
937
|
? shouldSyncHistoryMessage(historyMsg) &&
|
|
808
938
|
PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType)
|
|
809
939
|
: false;
|
|
940
|
+
if (historyMsg && shouldProcessHistoryMsg) {
|
|
941
|
+
const syncType = historyMsg.syncType;
|
|
942
|
+
// INITIAL_BOOTSTRAP — fire immediately, no progress check (same as WA Web K function)
|
|
943
|
+
if (syncType === proto.HistorySync.HistorySyncType.INITIAL_BOOTSTRAP &&
|
|
944
|
+
!historySyncStatus.initialBootstrapComplete) {
|
|
945
|
+
historySyncStatus.initialBootstrapComplete = true;
|
|
946
|
+
ev.emit('messaging-history.status', {
|
|
947
|
+
syncType,
|
|
948
|
+
status: 'complete',
|
|
949
|
+
explicit: true
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
// RECENT with progress === 100 — explicit completion
|
|
953
|
+
if (syncType === proto.HistorySync.HistorySyncType.RECENT &&
|
|
954
|
+
historyMsg.progress === 100 &&
|
|
955
|
+
!historySyncStatus.recentSyncComplete) {
|
|
956
|
+
historySyncStatus.recentSyncComplete = true;
|
|
957
|
+
clearTimeout(historySyncPausedTimeout);
|
|
958
|
+
historySyncPausedTimeout = undefined;
|
|
959
|
+
ev.emit('messaging-history.status', {
|
|
960
|
+
syncType,
|
|
961
|
+
status: 'complete',
|
|
962
|
+
explicit: true
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
// Reset 120s paused timeout on any RECENT chunk (like WA Web's handleChunkProgress)
|
|
966
|
+
if (syncType === proto.HistorySync.HistorySyncType.RECENT && !historySyncStatus.recentSyncComplete) {
|
|
967
|
+
clearTimeout(historySyncPausedTimeout);
|
|
968
|
+
historySyncPausedTimeout = setTimeout(() => {
|
|
969
|
+
if (!historySyncStatus.recentSyncComplete) {
|
|
970
|
+
historySyncStatus.recentSyncComplete = true;
|
|
971
|
+
ev.emit('messaging-history.status', {
|
|
972
|
+
syncType: proto.HistorySync.HistorySyncType.RECENT,
|
|
973
|
+
status: 'paused',
|
|
974
|
+
explicit: false
|
|
975
|
+
});
|
|
976
|
+
}
|
|
977
|
+
historySyncPausedTimeout = undefined;
|
|
978
|
+
}, HISTORY_SYNC_PAUSED_TIMEOUT_MS);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
810
981
|
// State machine: decide on sync and flush
|
|
811
982
|
if (historyMsg && syncState === SyncState.AwaitingInitialSync) {
|
|
812
983
|
if (awaitingSyncTimeout) {
|
|
@@ -826,6 +997,8 @@ export const makeChatsSocket = (config) => {
|
|
|
826
997
|
}
|
|
827
998
|
const doAppStateSync = async () => {
|
|
828
999
|
if (syncState === SyncState.Syncing) {
|
|
1000
|
+
// All collections will be synced, so clear any blocked ones
|
|
1001
|
+
blockedCollections.clear();
|
|
829
1002
|
logger.info('Doing app state sync');
|
|
830
1003
|
await resyncAppState(ALL_WA_PATCH_NAMES, true);
|
|
831
1004
|
// Sync is complete, go online and flush everything
|
|
@@ -885,6 +1058,11 @@ export const makeChatsSocket = (config) => {
|
|
|
885
1058
|
}
|
|
886
1059
|
});
|
|
887
1060
|
ev.on('connection.update', ({ connection, receivedPendingNotifications }) => {
|
|
1061
|
+
if (connection === 'close') {
|
|
1062
|
+
blockedCollections.clear();
|
|
1063
|
+
clearTimeout(historySyncPausedTimeout);
|
|
1064
|
+
historySyncPausedTimeout = undefined;
|
|
1065
|
+
}
|
|
888
1066
|
if (connection === 'open') {
|
|
889
1067
|
if (fireInitQueries) {
|
|
890
1068
|
executeInitQueries().catch(error => onUnexpectedError(error, 'init queries'));
|
|
@@ -894,6 +1072,10 @@ export const makeChatsSocket = (config) => {
|
|
|
894
1072
|
if (!receivedPendingNotifications || syncState !== SyncState.Connecting) {
|
|
895
1073
|
return;
|
|
896
1074
|
}
|
|
1075
|
+
historySyncStatus.initialBootstrapComplete = false;
|
|
1076
|
+
historySyncStatus.recentSyncComplete = false;
|
|
1077
|
+
clearTimeout(historySyncPausedTimeout);
|
|
1078
|
+
historySyncPausedTimeout = undefined;
|
|
897
1079
|
syncState = SyncState.AwaitingInitialSync;
|
|
898
1080
|
logger.info('Connection is now AwaitingInitialSync, buffering events');
|
|
899
1081
|
ev.buffer();
|
|
@@ -906,19 +1088,49 @@ export const makeChatsSocket = (config) => {
|
|
|
906
1088
|
setTimeout(() => ev.flush(), 0);
|
|
907
1089
|
return;
|
|
908
1090
|
}
|
|
909
|
-
|
|
1091
|
+
// On reconnection (accountSyncCounter > 0), the server does not push
|
|
1092
|
+
// history sync notifications — the device already has its data.
|
|
1093
|
+
// Skip the 20s wait and go online immediately.
|
|
1094
|
+
if (authState.creds.accountSyncCounter > 0) {
|
|
1095
|
+
logger.info('Reconnection with existing sync data, skipping history sync wait. Transitioning to Online.');
|
|
1096
|
+
syncState = SyncState.Online;
|
|
1097
|
+
setTimeout(() => ev.flush(), 0);
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
logger.info('First connection, awaiting history sync notification with a 20s timeout.');
|
|
910
1101
|
if (awaitingSyncTimeout) {
|
|
911
1102
|
clearTimeout(awaitingSyncTimeout);
|
|
912
1103
|
}
|
|
913
1104
|
awaitingSyncTimeout = setTimeout(() => {
|
|
914
1105
|
if (syncState === SyncState.AwaitingInitialSync) {
|
|
915
|
-
// TODO: investigate
|
|
916
1106
|
logger.warn('Timeout in AwaitingInitialSync, forcing state to Online and flushing buffer');
|
|
917
1107
|
syncState = SyncState.Online;
|
|
918
1108
|
ev.flush();
|
|
1109
|
+
// Increment so subsequent reconnections skip the 20s wait.
|
|
1110
|
+
// Late-arriving history is still processed via processMessage
|
|
1111
|
+
// regardless of the state machine phase.
|
|
1112
|
+
const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1;
|
|
1113
|
+
ev.emit('creds.update', { accountSyncCounter });
|
|
919
1114
|
}
|
|
920
1115
|
}, 20000);
|
|
921
1116
|
});
|
|
1117
|
+
// When an app state sync key arrives (myAppStateKeyId is set) and there are
|
|
1118
|
+
// collections blocked on a missing key, trigger a re-sync for just those collections.
|
|
1119
|
+
// This mirrors WA Web's Blocked → retry-on-key-arrival behavior.
|
|
1120
|
+
ev.on('creds.update', ({ myAppStateKeyId }) => {
|
|
1121
|
+
if (!myAppStateKeyId || blockedCollections.size === 0) {
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
// If we're in the middle of a full sync, doAppStateSync handles all collections
|
|
1125
|
+
if (syncState === SyncState.Syncing) {
|
|
1126
|
+
blockedCollections.clear();
|
|
1127
|
+
return;
|
|
1128
|
+
}
|
|
1129
|
+
const collections = [...blockedCollections];
|
|
1130
|
+
blockedCollections.clear();
|
|
1131
|
+
logger.info({ collections }, 'app state sync key arrived, re-syncing blocked collections');
|
|
1132
|
+
resyncAppState(collections, false).catch(error => onUnexpectedError(error, 'blocked collections resync'));
|
|
1133
|
+
});
|
|
922
1134
|
ev.on('lid-mapping.update', async ({ lid, pn }) => {
|
|
923
1135
|
try {
|
|
924
1136
|
await signalRepository.lidMapping.storeLIDPNMappings([{ lid, pn }]);
|
|
@@ -929,6 +1141,7 @@ export const makeChatsSocket = (config) => {
|
|
|
929
1141
|
});
|
|
930
1142
|
return {
|
|
931
1143
|
...sock,
|
|
1144
|
+
serverProps,
|
|
932
1145
|
createCallLink,
|
|
933
1146
|
getBotListV2,
|
|
934
1147
|
messageMutex,
|
|
@@ -962,6 +1175,8 @@ export const makeChatsSocket = (config) => {
|
|
|
962
1175
|
getBusinessProfile,
|
|
963
1176
|
resyncAppState,
|
|
964
1177
|
chatModify,
|
|
1178
|
+
clearMessage,
|
|
1179
|
+
deleteChat,
|
|
965
1180
|
cleanDirtyBits,
|
|
966
1181
|
addOrEditContact,
|
|
967
1182
|
removeContact,
|