@kelvdra/baileys 1.0.4 → 1.0.5
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 +21 -0
- package/WAProto/index.js +65472 -137440
- package/lib/Defaults/index.d.ts +1 -1
- package/lib/Defaults/index.js +22 -3
- package/lib/Socket/chats.js +12 -13
- package/lib/Socket/groups.js +140 -7
- package/lib/Socket/hydra.js +44 -0
- package/lib/Socket/messages-recv.js +736 -324
- package/lib/Socket/messages-send.js +481 -110
- package/lib/Socket/mex.js +44 -6
- package/lib/Socket/newsletter.d.ts +16 -9
- package/lib/Socket/newsletter.js +259 -70
- package/lib/Types/Mex.d.ts +141 -0
- package/lib/Types/Mex.js +37 -0
- package/lib/Types/State.js +54 -1
- package/lib/Utils/auth-utils.js +12 -1
- package/lib/Utils/chat-utils.js +36 -2
- package/lib/Utils/companion-reg-client-utils.d.ts +17 -0
- package/lib/Utils/companion-reg-client-utils.js +35 -0
- package/lib/Utils/decode-wa-message.js +23 -4
- package/lib/Utils/generics.js +4 -1
- package/lib/Utils/identity-change-handler.d.ts +44 -0
- package/lib/Utils/identity-change-handler.js +50 -0
- package/lib/Utils/index.js +1 -1
- package/lib/Utils/message-retry-manager.js +25 -1
- package/lib/Utils/messages-media.js +162 -43
- package/lib/Utils/messages.d.ts +1 -1
- package/lib/Utils/messages.js +230 -9
- package/lib/Utils/offline-node-processor.d.ts +17 -0
- package/lib/Utils/offline-node-processor.js +40 -0
- package/lib/Utils/reporting-utils.d.ts +11 -0
- package/lib/Utils/reporting-utils.js +258 -0
- package/lib/Utils/signal.js +45 -1
- package/lib/Utils/stanza-ack.d.ts +11 -0
- package/lib/Utils/stanza-ack.js +38 -0
- package/lib/Utils/sync-action-utils.d.ts +19 -0
- package/lib/Utils/sync-action-utils.js +49 -0
- package/lib/Utils/tc-token-utils.d.ts +37 -0
- package/lib/Utils/tc-token-utils.js +163 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +10 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
- package/package.json +3 -1
package/lib/Types/Mex.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export var XWAPaths;
|
|
2
|
+
(function (XWAPaths) {
|
|
3
|
+
XWAPaths["xwa2_newsletter_create"] = "xwa2_newsletter_create";
|
|
4
|
+
XWAPaths["xwa2_newsletter_subscribers"] = "xwa2_newsletter_subscribers";
|
|
5
|
+
XWAPaths["xwa2_newsletter_view"] = "xwa2_newsletter_view";
|
|
6
|
+
XWAPaths["xwa2_newsletter_metadata"] = "xwa2_newsletter";
|
|
7
|
+
XWAPaths["xwa2_newsletter_admin_count"] = "xwa2_newsletter_admin";
|
|
8
|
+
XWAPaths["xwa2_newsletter_mute_v2"] = "xwa2_newsletter_mute_v2";
|
|
9
|
+
XWAPaths["xwa2_newsletter_unmute_v2"] = "xwa2_newsletter_unmute_v2";
|
|
10
|
+
XWAPaths["xwa2_newsletter_follow"] = "xwa2_newsletter_follow";
|
|
11
|
+
XWAPaths["xwa2_newsletter_unfollow"] = "xwa2_newsletter_unfollow";
|
|
12
|
+
XWAPaths["xwa2_newsletter_join_v2"] = "xwa2_newsletter_join_v2";
|
|
13
|
+
XWAPaths["xwa2_newsletter_leave_v2"] = "xwa2_newsletter_leave_v2";
|
|
14
|
+
XWAPaths["xwa2_newsletter_change_owner"] = "xwa2_newsletter_change_owner";
|
|
15
|
+
XWAPaths["xwa2_newsletter_demote"] = "xwa2_newsletter_demote";
|
|
16
|
+
XWAPaths["xwa2_newsletter_delete_v2"] = "xwa2_newsletter_delete_v2";
|
|
17
|
+
XWAPaths["xwa2_fetch_account_reachout_timelock"] = "xwa2_fetch_account_reachout_timelock";
|
|
18
|
+
XWAPaths["xwa2_message_capping_info"] = "xwa2_message_capping_info";
|
|
19
|
+
})(XWAPaths || (XWAPaths = {}));
|
|
20
|
+
export var QueryIds;
|
|
21
|
+
(function (QueryIds) {
|
|
22
|
+
QueryIds["CREATE"] = "8823471724422422";
|
|
23
|
+
QueryIds["UPDATE_METADATA"] = "24250201037901610";
|
|
24
|
+
QueryIds["METADATA"] = "6563316087068696";
|
|
25
|
+
QueryIds["SUBSCRIBERS"] = "9783111038412085";
|
|
26
|
+
QueryIds["FOLLOW"] = "24404358912487870";
|
|
27
|
+
QueryIds["UNFOLLOW"] = "9767147403369991";
|
|
28
|
+
QueryIds["MUTE"] = "29766401636284406";
|
|
29
|
+
QueryIds["UNMUTE"] = "9864994326891137";
|
|
30
|
+
QueryIds["ADMIN_COUNT"] = "7130823597031706";
|
|
31
|
+
QueryIds["CHANGE_OWNER"] = "7341777602580933";
|
|
32
|
+
QueryIds["DEMOTE"] = "6551828931592903";
|
|
33
|
+
QueryIds["DELETE"] = "30062808666639665";
|
|
34
|
+
QueryIds["REACHOUT_TIMELOCK"] = "23983697327930364";
|
|
35
|
+
QueryIds["MESSAGE_CAPPING_INFO"] = "24503548349331633";
|
|
36
|
+
})(QueryIds || (QueryIds = {}));
|
|
37
|
+
//# sourceMappingURL=Mex.js.map
|
package/lib/Types/State.js
CHANGED
|
@@ -10,4 +10,57 @@ export var SyncState;
|
|
|
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
12
|
})(SyncState || (SyncState = {}));
|
|
13
|
-
//# sourceMappingURL=State.js.map
|
|
13
|
+
//# sourceMappingURL=State.js.map
|
|
14
|
+
|
|
15
|
+
// Added from Baileys v7.0.0-rc10
|
|
16
|
+
export var NewChatMessageCappingMVStatusType;
|
|
17
|
+
(function (NewChatMessageCappingMVStatusType) {
|
|
18
|
+
NewChatMessageCappingMVStatusType["NOT_ELIGIBLE"] = "NOT_ELIGIBLE";
|
|
19
|
+
NewChatMessageCappingMVStatusType["NOT_ACTIVE"] = "NOT_ACTIVE";
|
|
20
|
+
NewChatMessageCappingMVStatusType["ACTIVE"] = "ACTIVE";
|
|
21
|
+
NewChatMessageCappingMVStatusType["ACTIVE_UPGRADE_AVAILABLE"] = "ACTIVE_UPGRADE_AVAILABLE";
|
|
22
|
+
})(NewChatMessageCappingMVStatusType || (NewChatMessageCappingMVStatusType = {}));
|
|
23
|
+
|
|
24
|
+
// Added from Baileys v7.0.0-rc10
|
|
25
|
+
export var NewChatMessageCappingOTEStatusType;
|
|
26
|
+
(function (NewChatMessageCappingOTEStatusType) {
|
|
27
|
+
NewChatMessageCappingOTEStatusType["NOT_ELIGIBLE"] = "NOT_ELIGIBLE";
|
|
28
|
+
NewChatMessageCappingOTEStatusType["ELIGIBLE"] = "ELIGIBLE";
|
|
29
|
+
NewChatMessageCappingOTEStatusType["ACTIVE_IN_CURRENT_CYCLE"] = "ACTIVE_IN_CURRENT_CYCLE";
|
|
30
|
+
NewChatMessageCappingOTEStatusType["EXHAUSTED"] = "EXHAUSTED";
|
|
31
|
+
})(NewChatMessageCappingOTEStatusType || (NewChatMessageCappingOTEStatusType = {}));
|
|
32
|
+
//# sourceMappingURL=State.js.map
|
|
33
|
+
|
|
34
|
+
// Added from Baileys v7.0.0-rc10
|
|
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
|
+
|
|
43
|
+
// Added from Baileys v7.0.0-rc10
|
|
44
|
+
export var ReachoutTimelockEnforcementType;
|
|
45
|
+
(function (ReachoutTimelockEnforcementType) {
|
|
46
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_ALCOHOL"] = "BIZ_COMMERCE_VIOLATION_ALCOHOL";
|
|
47
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_ADULT"] = "BIZ_COMMERCE_VIOLATION_ADULT";
|
|
48
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_ANIMALS"] = "BIZ_COMMERCE_VIOLATION_ANIMALS";
|
|
49
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_BODY_PARTS_FLUIDS"] = "BIZ_COMMERCE_VIOLATION_BODY_PARTS_FLUIDS";
|
|
50
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DATING"] = "BIZ_COMMERCE_VIOLATION_DATING";
|
|
51
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DIGITAL_SERVICES_PRODUCTS"] = "BIZ_COMMERCE_VIOLATION_DIGITAL_SERVICES_PRODUCTS";
|
|
52
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DRUGS"] = "BIZ_COMMERCE_VIOLATION_DRUGS";
|
|
53
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DRUGS_ONLY_OTC"] = "BIZ_COMMERCE_VIOLATION_DRUGS_ONLY_OTC";
|
|
54
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_GAMBLING"] = "BIZ_COMMERCE_VIOLATION_GAMBLING";
|
|
55
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_HEALTHCARE"] = "BIZ_COMMERCE_VIOLATION_HEALTHCARE";
|
|
56
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_REAL_FAKE_CURRENCY"] = "BIZ_COMMERCE_VIOLATION_REAL_FAKE_CURRENCY";
|
|
57
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_SUPPLEMENTS"] = "BIZ_COMMERCE_VIOLATION_SUPPLEMENTS";
|
|
58
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_TOBACCO"] = "BIZ_COMMERCE_VIOLATION_TOBACCO";
|
|
59
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_VIOLENT_CONTENT"] = "BIZ_COMMERCE_VIOLATION_VIOLENT_CONTENT";
|
|
60
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_WEAPONS"] = "BIZ_COMMERCE_VIOLATION_WEAPONS";
|
|
61
|
+
ReachoutTimelockEnforcementType["BIZ_QUALITY"] = "BIZ_QUALITY";
|
|
62
|
+
/** This means there is no restriction */
|
|
63
|
+
ReachoutTimelockEnforcementType["DEFAULT"] = "DEFAULT";
|
|
64
|
+
ReachoutTimelockEnforcementType["WEB_COMPANION_ONLY"] = "WEB_COMPANION_ONLY";
|
|
65
|
+
})(ReachoutTimelockEnforcementType || (ReachoutTimelockEnforcementType = {}));
|
|
66
|
+
|
package/lib/Utils/auth-utils.js
CHANGED
|
@@ -7,6 +7,7 @@ import { DEFAULT_CACHE_TTLS } from '../Defaults/index.js';
|
|
|
7
7
|
import { Curve, signedKeyPair } from './crypto.js';
|
|
8
8
|
import { delay, generateRegistrationId } from './generics.js';
|
|
9
9
|
import { PreKeyManager } from './pre-key-manager.js';
|
|
10
|
+
import { Boom } from '@hapi/boom';
|
|
10
11
|
/**
|
|
11
12
|
* Adds caching capability to a SignalKeyStore
|
|
12
13
|
* @param store the store to add caching to
|
|
@@ -254,4 +255,14 @@ export const initAuthCreds = () => {
|
|
|
254
255
|
additionalData: undefined
|
|
255
256
|
};
|
|
256
257
|
};
|
|
257
|
-
//# sourceMappingURL=auth-utils.js.map
|
|
258
|
+
//# sourceMappingURL=auth-utils.js.map
|
|
259
|
+
|
|
260
|
+
// Added from Baileys v7.0.0-rc10
|
|
261
|
+
export const assertMeId = (creds) => {
|
|
262
|
+
const id = creds.me?.id;
|
|
263
|
+
if (!id) {
|
|
264
|
+
throw new Boom('Cannot proceed: socket is not authenticated yet (creds.me.id is missing)', { statusCode: 401 });
|
|
265
|
+
}
|
|
266
|
+
return id;
|
|
267
|
+
};
|
|
268
|
+
|
package/lib/Utils/chat-utils.js
CHANGED
|
@@ -6,6 +6,8 @@ import { aesDecrypt, aesEncrypt, hkdf, hmacSign } from './crypto.js';
|
|
|
6
6
|
import { toNumber } from './generics.js';
|
|
7
7
|
import { LT_HASH_ANTI_TAMPERING } from './lt-hash.js';
|
|
8
8
|
import { downloadContentFromMessage } from './messages-media.js';
|
|
9
|
+
import { expandAppStateKeys } from 'whatsapp-rust-bridge';
|
|
10
|
+
import { emitSyncActionResults, processContactAction } from './sync-action-utils.js';
|
|
9
11
|
const mutationKeys = async (keydata) => {
|
|
10
12
|
const expanded = await hkdf(keydata, 160, { info: 'WhatsApp Mutation Keys' });
|
|
11
13
|
return {
|
|
@@ -42,7 +44,7 @@ const to64BitNetworkOrder = (e) => {
|
|
|
42
44
|
buff.writeUint32BE(e, 4);
|
|
43
45
|
return buff;
|
|
44
46
|
};
|
|
45
|
-
const makeLtHashGenerator = ({ indexValueMap, hash }) => {
|
|
47
|
+
export const makeLtHashGenerator = ({ indexValueMap, hash }) => {
|
|
46
48
|
indexValueMap = { ...indexValueMap };
|
|
47
49
|
const addBuffs = [];
|
|
48
50
|
const subBuffs = [];
|
|
@@ -760,4 +762,36 @@ export const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) =
|
|
|
760
762
|
return lastMsgTimestamp >= chatLastMsgTimestamp;
|
|
761
763
|
}
|
|
762
764
|
};
|
|
763
|
-
//# sourceMappingURL=chat-utils.js.map
|
|
765
|
+
//# sourceMappingURL=chat-utils.js.map
|
|
766
|
+
|
|
767
|
+
// Added from Baileys v7.0.0-rc10
|
|
768
|
+
export const MAX_SYNC_ATTEMPTS = 2;
|
|
769
|
+
/**
|
|
770
|
+
* Check if an error is a missing app state sync key.
|
|
771
|
+
* WA Web treats these as "Blocked" (waits for key arrival), not fatal.
|
|
772
|
+
* In Baileys we retry with a snapshot which may use a different key.
|
|
773
|
+
*/
|
|
774
|
+
|
|
775
|
+
// Added from Baileys v7.0.0-rc10
|
|
776
|
+
export const ensureLTHashStateVersion = (state) => {
|
|
777
|
+
if (typeof state.version !== 'number' || isNaN(state.version)) {
|
|
778
|
+
state.version = 0;
|
|
779
|
+
}
|
|
780
|
+
return state;
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
// Added from Baileys v7.0.0-rc10
|
|
784
|
+
export const isAppStateSyncIrrecoverable = (error, attempts) => {
|
|
785
|
+
return attempts >= MAX_SYNC_ATTEMPTS || error?.name === 'TypeError';
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
// Added from Baileys v7.0.0-rc10
|
|
789
|
+
export const isMissingKeyError = (error) => {
|
|
790
|
+
return error?.data?.isMissingKey === true;
|
|
791
|
+
};
|
|
792
|
+
/**
|
|
793
|
+
* Determines if an app state sync error is unrecoverable.
|
|
794
|
+
* TypeError indicates a WASM crash; otherwise we give up after MAX_SYNC_ATTEMPTS.
|
|
795
|
+
* Missing keys are NOT checked here — they are handled separately as "Blocked".
|
|
796
|
+
*/
|
|
797
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { WABrowserDescription } from '../Types/index.js';
|
|
2
|
+
export declare enum CompanionWebClientType {
|
|
3
|
+
UNKNOWN = 0,
|
|
4
|
+
CHROME = 1,
|
|
5
|
+
EDGE = 2,
|
|
6
|
+
FIREFOX = 3,
|
|
7
|
+
IE = 4,
|
|
8
|
+
OPERA = 5,
|
|
9
|
+
SAFARI = 6,
|
|
10
|
+
ELECTRON = 7,
|
|
11
|
+
UWP = 8,
|
|
12
|
+
OTHER_WEB_CLIENT = 9
|
|
13
|
+
}
|
|
14
|
+
export declare const getCompanionWebClientType: ([os, browserName]: WABrowserDescription) => CompanionWebClientType;
|
|
15
|
+
export declare const getCompanionPlatformId: (browser: WABrowserDescription) => string;
|
|
16
|
+
export declare const buildPairingQRData: (ref: string, noiseKeyB64: string, identityKeyB64: string, advB64: string, browser: WABrowserDescription) => string;
|
|
17
|
+
//# sourceMappingURL=companion-reg-client-utils.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export var CompanionWebClientType;
|
|
2
|
+
(function (CompanionWebClientType) {
|
|
3
|
+
CompanionWebClientType[CompanionWebClientType["UNKNOWN"] = 0] = "UNKNOWN";
|
|
4
|
+
CompanionWebClientType[CompanionWebClientType["CHROME"] = 1] = "CHROME";
|
|
5
|
+
CompanionWebClientType[CompanionWebClientType["EDGE"] = 2] = "EDGE";
|
|
6
|
+
CompanionWebClientType[CompanionWebClientType["FIREFOX"] = 3] = "FIREFOX";
|
|
7
|
+
CompanionWebClientType[CompanionWebClientType["IE"] = 4] = "IE";
|
|
8
|
+
CompanionWebClientType[CompanionWebClientType["OPERA"] = 5] = "OPERA";
|
|
9
|
+
CompanionWebClientType[CompanionWebClientType["SAFARI"] = 6] = "SAFARI";
|
|
10
|
+
CompanionWebClientType[CompanionWebClientType["ELECTRON"] = 7] = "ELECTRON";
|
|
11
|
+
CompanionWebClientType[CompanionWebClientType["UWP"] = 8] = "UWP";
|
|
12
|
+
CompanionWebClientType[CompanionWebClientType["OTHER_WEB_CLIENT"] = 9] = "OTHER_WEB_CLIENT";
|
|
13
|
+
})(CompanionWebClientType || (CompanionWebClientType = {}));
|
|
14
|
+
const BROWSER_TO_COMPANION_WEB_CLIENT = {
|
|
15
|
+
Chrome: CompanionWebClientType.CHROME,
|
|
16
|
+
Edge: CompanionWebClientType.EDGE,
|
|
17
|
+
Firefox: CompanionWebClientType.FIREFOX,
|
|
18
|
+
IE: CompanionWebClientType.IE,
|
|
19
|
+
Opera: CompanionWebClientType.OPERA,
|
|
20
|
+
Safari: CompanionWebClientType.SAFARI
|
|
21
|
+
};
|
|
22
|
+
export const getCompanionWebClientType = ([os, browserName]) => {
|
|
23
|
+
if (browserName === 'Desktop') {
|
|
24
|
+
return os === 'Windows' ? CompanionWebClientType.UWP : CompanionWebClientType.ELECTRON;
|
|
25
|
+
}
|
|
26
|
+
return BROWSER_TO_COMPANION_WEB_CLIENT[browserName] || CompanionWebClientType.OTHER_WEB_CLIENT;
|
|
27
|
+
};
|
|
28
|
+
export const getCompanionPlatformId = (browser) => {
|
|
29
|
+
return getCompanionWebClientType(browser).toString();
|
|
30
|
+
};
|
|
31
|
+
export const buildPairingQRData = (ref, noiseKeyB64, identityKeyB64, advB64, browser) => {
|
|
32
|
+
return ('https://wa.me/settings/linked_devices#' +
|
|
33
|
+
[ref, noiseKeyB64, identityKeyB64, advB64, getCompanionPlatformId(browser)].join(','));
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=companion-reg-client-utils.js.map
|
|
@@ -137,6 +137,9 @@ export function decodeMessageNode(stanza, meId, meLid) {
|
|
|
137
137
|
msgType = 'newsletter';
|
|
138
138
|
chatId = from;
|
|
139
139
|
author = from;
|
|
140
|
+
if (isMe(from) || isMeLid(from)) {
|
|
141
|
+
fromMe = true;
|
|
142
|
+
}
|
|
140
143
|
}
|
|
141
144
|
else {
|
|
142
145
|
throw new Boom('Unknown message type', { data: stanza });
|
|
@@ -144,13 +147,12 @@ export function decodeMessageNode(stanza, meId, meLid) {
|
|
|
144
147
|
const pushname = stanza?.attrs?.notify;
|
|
145
148
|
const key = {
|
|
146
149
|
remoteJid: chatId,
|
|
150
|
+
remoteJidAlt: !isJidGroup(chatId) ? addressingContext.senderAlt : undefined,
|
|
147
151
|
fromMe,
|
|
148
152
|
id: msgId,
|
|
149
|
-
senderLid: stanza?.attrs?.sender_lid,
|
|
150
|
-
senderPn: stanza?.attrs?.sender_pn,
|
|
151
153
|
participant,
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
participantAlt: isJidGroup(chatId) ? addressingContext.senderAlt : undefined,
|
|
155
|
+
addressingMode: addressingContext.addressingMode,
|
|
154
156
|
...(msgType === 'newsletter' && stanza.attrs.server_id ? { server_id: stanza.attrs.server_id } : {})
|
|
155
157
|
};
|
|
156
158
|
const fullMessage = {
|
|
@@ -279,3 +281,20 @@ function isSessionRecordError(error) {
|
|
|
279
281
|
return DECRYPTION_RETRY_CONFIG.sessionRecordErrors.some(errorPattern => errorMessage.includes(errorPattern));
|
|
280
282
|
}
|
|
281
283
|
//# sourceMappingURL=decode-wa-message.js.map
|
|
284
|
+
|
|
285
|
+
// Added from Baileys v7.0.0-rc10
|
|
286
|
+
export const ACCOUNT_RESTRICTED_TEXT = 'Your account has been restricted';
|
|
287
|
+
// Retry configuration for failed decryption
|
|
288
|
+
|
|
289
|
+
// Added from Baileys v7.0.0-rc10
|
|
290
|
+
export const SERVER_ERROR_CODES = {
|
|
291
|
+
/**
|
|
292
|
+
* 1:1 message missing privacy token (tctoken). Usually means the account is
|
|
293
|
+
* restricted: WhatsApp blocks starting new chats but preserves existing ones,
|
|
294
|
+
* since established chats already carry a tctoken.
|
|
295
|
+
*/
|
|
296
|
+
MessageAccountRestriction: '463',
|
|
297
|
+
/** Stanza validation failure (SMAX_INVALID) — likely stale device session */
|
|
298
|
+
SmaxInvalid: '479'
|
|
299
|
+
};
|
|
300
|
+
|
package/lib/Utils/generics.js
CHANGED
|
@@ -36,6 +36,9 @@ export const writeRandomPadMax16 = (msg) => {
|
|
|
36
36
|
const padLength = (pad[0] & 0x0f) + 1;
|
|
37
37
|
return Buffer.concat([msg, Buffer.alloc(padLength, padLength)]);
|
|
38
38
|
};
|
|
39
|
+
export const isStringNullOrEmpty = (value) =>
|
|
40
|
+
// eslint-disable-next-line eqeqeq
|
|
41
|
+
value == null || value === '';
|
|
39
42
|
export const unpadRandomMax16 = (e) => {
|
|
40
43
|
const t = new Uint8Array(e);
|
|
41
44
|
if (0 === t.length) {
|
|
@@ -378,4 +381,4 @@ export function bytesToCrockford(buffer) {
|
|
|
378
381
|
export function encodeNewsletterMessage(message) {
|
|
379
382
|
return proto.Message.encode(message).finish();
|
|
380
383
|
}
|
|
381
|
-
//# sourceMappingURL=generics.js.map
|
|
384
|
+
//# sourceMappingURL=generics.js.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import NodeCache from '@cacheable/node-cache';
|
|
2
|
+
import { type BinaryNode } from '../WABinary/index.js';
|
|
3
|
+
import type { ILogger } from './logger.js';
|
|
4
|
+
export type IdentityChangeResult = {
|
|
5
|
+
action: 'no_identity_node';
|
|
6
|
+
} | {
|
|
7
|
+
action: 'invalid_notification';
|
|
8
|
+
} | {
|
|
9
|
+
action: 'skipped_companion_device';
|
|
10
|
+
device: number;
|
|
11
|
+
} | {
|
|
12
|
+
action: 'skipped_self_primary';
|
|
13
|
+
} | {
|
|
14
|
+
action: 'debounced';
|
|
15
|
+
} | {
|
|
16
|
+
action: 'skipped_offline';
|
|
17
|
+
} | {
|
|
18
|
+
action: 'skipped_no_session';
|
|
19
|
+
} | {
|
|
20
|
+
action: 'session_refreshed';
|
|
21
|
+
} | {
|
|
22
|
+
action: 'session_refresh_failed';
|
|
23
|
+
error: unknown;
|
|
24
|
+
};
|
|
25
|
+
export type IdentityChangeContext = {
|
|
26
|
+
meId: string | undefined;
|
|
27
|
+
meLid: string | undefined;
|
|
28
|
+
validateSession: (jid: string) => Promise<{
|
|
29
|
+
exists: boolean;
|
|
30
|
+
reason?: string;
|
|
31
|
+
}>;
|
|
32
|
+
assertSessions: (jids: string[], force?: boolean) => Promise<boolean>;
|
|
33
|
+
debounceCache: NodeCache<boolean>;
|
|
34
|
+
logger: ILogger;
|
|
35
|
+
/**
|
|
36
|
+
* Invoked right before `assertSessions` is called for an existing-session identity change.
|
|
37
|
+
* Used to kick off fire-and-forget side effects (e.g. tctoken re-issuance) in the same
|
|
38
|
+
* order WA Web does — i.e. before the E2E session is re-established.
|
|
39
|
+
* Must not throw; implementations are responsible for their own error handling.
|
|
40
|
+
*/
|
|
41
|
+
onBeforeSessionRefresh?: (jid: string) => void;
|
|
42
|
+
};
|
|
43
|
+
export declare function handleIdentityChange(node: BinaryNode, ctx: IdentityChangeContext): Promise<IdentityChangeResult>;
|
|
44
|
+
//# sourceMappingURL=identity-change-handler.d.ts.map
|
|
@@ -0,0 +1,50 @@
|
|
|
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
|
+
ctx.onBeforeSessionRefresh?.(from);
|
|
41
|
+
try {
|
|
42
|
+
await ctx.assertSessions([from], true);
|
|
43
|
+
return { action: 'session_refreshed' };
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
ctx.logger.warn({ error, jid: from }, 'failed to assert sessions after identity change');
|
|
47
|
+
return { action: 'session_refresh_failed', error };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=identity-change-handler.js.map
|
package/lib/Utils/index.js
CHANGED
|
@@ -169,4 +169,28 @@ export class MessageRetryManager {
|
|
|
169
169
|
this.messageKeyIndex.delete(messageId);
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
|
-
//# sourceMappingURL=message-retry-manager.js.map
|
|
172
|
+
//# sourceMappingURL=message-retry-manager.js.map
|
|
173
|
+
|
|
174
|
+
// Added from Baileys v7.0.0-rc10
|
|
175
|
+
export var RetryReason;
|
|
176
|
+
(function (RetryReason) {
|
|
177
|
+
RetryReason[RetryReason["UnknownError"] = 0] = "UnknownError";
|
|
178
|
+
RetryReason[RetryReason["SignalErrorNoSession"] = 1] = "SignalErrorNoSession";
|
|
179
|
+
RetryReason[RetryReason["SignalErrorInvalidKey"] = 2] = "SignalErrorInvalidKey";
|
|
180
|
+
RetryReason[RetryReason["SignalErrorInvalidKeyId"] = 3] = "SignalErrorInvalidKeyId";
|
|
181
|
+
/** MAC verification failed - most common cause of decryption failures */
|
|
182
|
+
RetryReason[RetryReason["SignalErrorInvalidMessage"] = 4] = "SignalErrorInvalidMessage";
|
|
183
|
+
RetryReason[RetryReason["SignalErrorInvalidSignature"] = 5] = "SignalErrorInvalidSignature";
|
|
184
|
+
RetryReason[RetryReason["SignalErrorFutureMessage"] = 6] = "SignalErrorFutureMessage";
|
|
185
|
+
/** Explicit MAC failure - session is definitely out of sync */
|
|
186
|
+
RetryReason[RetryReason["SignalErrorBadMac"] = 7] = "SignalErrorBadMac";
|
|
187
|
+
RetryReason[RetryReason["SignalErrorInvalidSession"] = 8] = "SignalErrorInvalidSession";
|
|
188
|
+
RetryReason[RetryReason["SignalErrorInvalidMsgKey"] = 9] = "SignalErrorInvalidMsgKey";
|
|
189
|
+
RetryReason[RetryReason["BadBroadcastEphemeralSetting"] = 10] = "BadBroadcastEphemeralSetting";
|
|
190
|
+
RetryReason[RetryReason["UnknownCompanionNoPrekey"] = 11] = "UnknownCompanionNoPrekey";
|
|
191
|
+
RetryReason[RetryReason["AdvFailure"] = 12] = "AdvFailure";
|
|
192
|
+
RetryReason[RetryReason["StatusRevokeDelay"] = 13] = "StatusRevokeDelay";
|
|
193
|
+
})(RetryReason || (RetryReason = {}));
|
|
194
|
+
/** Error codes that indicate a MAC failure and require immediate session recreation */
|
|
195
|
+
const MAC_ERROR_CODES = new Set([RetryReason.SignalErrorInvalidMessage, RetryReason.SignalErrorBadMac]);
|
|
196
|
+
|