zapo-js 1.1.0 → 1.1.2
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 +5 -1
- package/dist/appstate/sync/WaAppStateSyncClient.d.ts +11 -1
- package/dist/appstate/sync/WaAppStateSyncClient.js +36 -15
- package/dist/auth/credentials-flow.js +3 -1
- package/dist/auth/pairing/WaPairingFlow.js +2 -0
- package/dist/client/WaClient.js +26 -20
- package/dist/client/WaClientFactory.js +28 -6
- package/dist/client/connection/WaConnectionManager.js +3 -0
- package/dist/client/coordinators/WaAppStateMutationCoordinator.d.ts +8 -0
- package/dist/client/coordinators/WaAppStateMutationCoordinator.js +29 -5
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +1 -1
- package/dist/client/coordinators/WaMessageDispatchCoordinator.d.ts +6 -1
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +5 -5
- package/dist/client/coordinators/WaPassiveTasksCoordinator.d.ts +6 -1
- package/dist/client/coordinators/WaPassiveTasksCoordinator.js +3 -3
- package/dist/client/coordinators/WaProfileCoordinator.d.ts +11 -6
- package/dist/client/coordinators/WaProfileCoordinator.js +4 -1
- package/dist/client/coordinators/WaRetryCoordinator.d.ts +18 -1
- package/dist/client/coordinators/WaRetryCoordinator.js +83 -30
- package/dist/client/messaging/ignore-key.js +4 -2
- package/dist/client/types.d.ts +13 -10
- package/dist/esm/appstate/sync/WaAppStateSyncClient.js +36 -15
- package/dist/esm/auth/credentials-flow.js +3 -1
- package/dist/esm/auth/pairing/WaPairingFlow.js +2 -0
- package/dist/esm/client/WaClient.js +26 -20
- package/dist/esm/client/WaClientFactory.js +28 -6
- package/dist/esm/client/connection/WaConnectionManager.js +3 -0
- package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +29 -5
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +1 -1
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +6 -6
- package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +3 -3
- package/dist/esm/client/coordinators/WaProfileCoordinator.js +4 -1
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +84 -31
- package/dist/esm/client/messaging/ignore-key.js +4 -2
- package/dist/esm/message/WaMessageClient.js +3 -0
- package/dist/esm/message/primitives/incoming.js +20 -5
- package/dist/esm/protocol/constants.js +1 -1
- package/dist/esm/protocol/message.js +22 -0
- package/dist/esm/retry/replay.js +36 -2
- package/dist/esm/signal/session/SignalRatchet.js +2 -2
- package/dist/esm/transport/WaComms.js +4 -0
- package/dist/esm/transport/keepalive/WaKeepAlive.js +4 -0
- package/dist/esm/transport/node/WaNodeOrchestrator.js +2 -2
- package/dist/esm/transport/node/builders/global.js +3 -0
- package/dist/message/WaMessageClient.js +3 -0
- package/dist/message/primitives/incoming.d.ts +7 -1
- package/dist/message/primitives/incoming.js +20 -5
- package/dist/message/types.d.ts +5 -0
- package/dist/protocol/constants.d.ts +1 -1
- package/dist/protocol/constants.js +3 -2
- package/dist/protocol/message.d.ts +22 -0
- package/dist/protocol/message.js +23 -1
- package/dist/retry/replay.d.ts +12 -0
- package/dist/retry/replay.js +36 -2
- package/dist/signal/session/SignalRatchet.js +2 -2
- package/dist/transport/WaComms.js +4 -0
- package/dist/transport/keepalive/WaKeepAlive.js +4 -0
- package/dist/transport/node/WaNodeOrchestrator.d.ts +6 -1
- package/dist/transport/node/WaNodeOrchestrator.js +2 -2
- package/dist/transport/node/builders/global.d.ts +1 -0
- package/dist/transport/node/builders/global.js +3 -0
- package/package.json +1 -1
|
@@ -16,6 +16,12 @@ interface WaIncomingMessageAckHandlerOptions {
|
|
|
16
16
|
readonly emitNewsletterMessageUpdate?: (event: WaIncomingNewsletterMessageUpdateEvent) => void;
|
|
17
17
|
readonly emitUnhandledStanza?: (event: WaIncomingUnhandledStanzaEvent) => void;
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Rebuilds a `message` event from a recovered {@link proto.IWebMessageInfo}
|
|
21
|
+
* (placeholder resend). `meJid` is the current account user JID, used as the
|
|
22
|
+
* author fallback for self-sent group messages when the proto carries no
|
|
23
|
+
* participant and no `originalSelfAuthorUserJidString`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function buildRecoveredIncomingEvent(webMessageInfo: proto.IWebMessageInfo, meJid?: string | null): WaIncomingMessageEvent;
|
|
20
26
|
export declare function handleIncomingMessageAck(node: BinaryNode, options: WaIncomingMessageAckHandlerOptions): Promise<boolean>;
|
|
21
27
|
export {};
|
|
@@ -73,13 +73,22 @@ function buildIncomingEventRawNode(node) {
|
|
|
73
73
|
content: children
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Rebuilds a `message` event from a recovered {@link proto.IWebMessageInfo}
|
|
78
|
+
* (placeholder resend). `meJid` is the current account user JID, used as the
|
|
79
|
+
* author fallback for self-sent group messages when the proto carries no
|
|
80
|
+
* participant and no `originalSelfAuthorUserJidString`.
|
|
81
|
+
*/
|
|
82
|
+
function buildRecoveredIncomingEvent(webMessageInfo, meJid) {
|
|
77
83
|
const key = webMessageInfo.key ?? {};
|
|
78
84
|
const chatJid = key.remoteJid ?? undefined;
|
|
79
85
|
const fromMe = key.fromMe === true;
|
|
80
|
-
const participant = key.participant ?? undefined;
|
|
81
86
|
const isGroup = chatJid ? (0, jid_1.isGroupJid)(chatJid) : false;
|
|
82
87
|
const isBroadcast = chatJid ? (0, jid_1.isBroadcastJid)(chatJid) : false;
|
|
88
|
+
const rawSelfAuthor = webMessageInfo.originalSelfAuthorUserJidString ?? meJid ?? undefined;
|
|
89
|
+
const selfAuthor = fromMe && (isGroup || isBroadcast) && rawSelfAuthor ? (0, jid_1.toUserJid)(rawSelfAuthor) : undefined;
|
|
90
|
+
const participant = webMessageInfo.participant ?? key.participant ?? selfAuthor;
|
|
91
|
+
const pushName = webMessageInfo.pushName ?? undefined;
|
|
83
92
|
const rawSender = fromMe ? undefined : isGroup || isBroadcast ? participant : chatJid;
|
|
84
93
|
const sender = rawSender ? (0, jid_1.parseJidFull)(rawSender) : null;
|
|
85
94
|
const senderDevice = sender?.address.device;
|
|
@@ -94,7 +103,8 @@ function buildRecoveredIncomingEvent(webMessageInfo) {
|
|
|
94
103
|
attrs: {
|
|
95
104
|
...(stanzaId !== undefined ? { id: stanzaId } : {}),
|
|
96
105
|
...(chatJid !== undefined ? { from: chatJid } : {}),
|
|
97
|
-
...(participant !== undefined ? { participant } : {})
|
|
106
|
+
...(participant !== undefined ? { participant } : {}),
|
|
107
|
+
...(pushName !== undefined ? { notify: pushName } : {})
|
|
98
108
|
}
|
|
99
109
|
};
|
|
100
110
|
return {
|
|
@@ -111,6 +121,7 @@ function buildRecoveredIncomingEvent(webMessageInfo) {
|
|
|
111
121
|
},
|
|
112
122
|
timestampSeconds,
|
|
113
123
|
...(expirationSeconds !== undefined ? { expirationSeconds } : {}),
|
|
124
|
+
...(pushName !== undefined ? { pushName } : {}),
|
|
114
125
|
message
|
|
115
126
|
};
|
|
116
127
|
}
|
|
@@ -233,7 +244,7 @@ function processMsmsgEncNode(node, encNode, senderJid, options) {
|
|
|
233
244
|
encPayload: decoded.encPayload
|
|
234
245
|
}
|
|
235
246
|
};
|
|
236
|
-
const chatJid = node.attrs.from;
|
|
247
|
+
const chatJid = node.attrs.from ? (0, jid_1.toUserJid)(node.attrs.from) : node.attrs.from;
|
|
237
248
|
const sender = senderJid ? (0, jid_1.parseJidFull)(senderJid) : null;
|
|
238
249
|
const isGroup = chatJid ? (0, jid_1.isGroupJid)(chatJid) : false;
|
|
239
250
|
const isBroadcast = chatJid ? (0, jid_1.isBroadcastJid)(chatJid) : false;
|
|
@@ -306,7 +317,11 @@ async function decryptAndProcessEncNode(node, encNode, encType, senderJid, optio
|
|
|
306
317
|
}
|
|
307
318
|
}
|
|
308
319
|
if (shouldEmitIncomingMessage(message)) {
|
|
309
|
-
|
|
320
|
+
// remoteJid is the chat identity, which is deviceless: the device
|
|
321
|
+
// lives in senderDevice (from senderAddress), so strip any `:device`
|
|
322
|
+
// segment the `from` attr carries for 1:1 chats.
|
|
323
|
+
const fromAttr = node.attrs.from;
|
|
324
|
+
const chatJid = fromAttr ? (0, jid_1.toUserJid)(fromAttr) : fromAttr;
|
|
310
325
|
const isGroup = chatJid ? (0, jid_1.isGroupJid)(chatJid) : false;
|
|
311
326
|
const isBroadcast = chatJid ? (0, jid_1.isBroadcastJid)(chatJid) : false;
|
|
312
327
|
const senderUserJid = `${senderAddress.user}@${senderAddress.server}`;
|
package/dist/message/types.d.ts
CHANGED
|
@@ -268,6 +268,11 @@ export interface WaEncryptedMessageInput {
|
|
|
268
268
|
readonly participant?: string;
|
|
269
269
|
readonly deviceFanout?: string;
|
|
270
270
|
readonly metaNode?: BinaryNode;
|
|
271
|
+
/**
|
|
272
|
+
* Trusted-contact (privacy) token node, appended as a `<tctoken>` child.
|
|
273
|
+
* Recipients that require one nack a token-less send with error 463.
|
|
274
|
+
*/
|
|
275
|
+
readonly privacyTokenNode?: BinaryNode;
|
|
271
276
|
}
|
|
272
277
|
export interface WaSendReceiptInput {
|
|
273
278
|
readonly to: string;
|
|
@@ -5,7 +5,7 @@ export type { WaConnectionCode, WaConnectionOpenReason, WaDisconnectReason, WaFa
|
|
|
5
5
|
export { WA_IQ_TYPES, WA_NODE_TAGS, WA_XMLNS } from './nodes';
|
|
6
6
|
export { WA_CALL_CHILD_TAGS, WA_CALL_NODE_ATTRS, WA_CALL_PAYLOAD_TAGS, WA_CALL_RECEIPT_PAYLOAD_TAGS } from './call';
|
|
7
7
|
export type { WaCallPayloadTag } from './call';
|
|
8
|
-
export { WA_EDIT_ATTRS, WA_ENC_MEDIA_TYPES, WA_EVENT_META_TYPES, WA_MESSAGE_TAGS, WA_MESSAGE_TYPES, WA_POLL_META_TYPES, WA_RETRYABLE_ACK_CODES, WA_STANZA_MSG_TYPES } from './message';
|
|
8
|
+
export { WA_EDIT_ATTRS, WA_ENC_MEDIA_TYPES, WA_EVENT_META_TYPES, WA_MESSAGE_TAGS, WA_MESSAGE_TYPES, WA_NACK_REASONS, WA_POLL_META_TYPES, WA_RETRYABLE_ACK_CODES, WA_STANZA_MSG_TYPES } from './message';
|
|
9
9
|
export type { WaOutboundReceiptType } from './message';
|
|
10
10
|
export { WA_APP_STATE_COLLECTIONS, WA_APP_STATE_COLLECTION_STATES, WA_APP_STATE_ERROR_CODES, WA_APP_STATE_KDF_INFO, WA_APP_STATE_KEY_TYPES, WA_APP_STATE_SYNC_DATA_TYPE } from './appstate';
|
|
11
11
|
export { getWaMediaHkdfInfo, WA_MEDIA_HKDF_INFO, WA_PREVIEW_MEDIA_HKDF_INFO } from './media';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.WA_NEWSLETTER_VIEW_ROLES = exports.WA_NEWSLETTER_VERIFICATION_STATES = exports.WA_NEWSLETTER_STATE_TYPES = exports.WA_NEWSLETTER_SEND_TYPES = exports.WA_NEWSLETTER_ROLES = exports.WA_NEWSLETTER_RECEIVE_TYPES = exports.WA_NEWSLETTER_PICTURE_TYPES = exports.WA_NEWSLETTER_MUTE_VALUES = exports.WA_NEWSLETTER_MUTE_TYPES = exports.WA_NEWSLETTER_FETCH_KEY_TYPES = exports.WA_USYNC_MODES = exports.WA_USYNC_DEFAULTS = exports.WA_USYNC_CONTEXTS = exports.WA_GROUP_PARTICIPANT_TYPES = exports.WA_ABPROPS_REFRESH_BOUNDS = exports.WA_ABPROPS_PROTOCOL_VERSION = exports.resolveAbPropNameByCode = exports.AB_PROP_CONFIGS = exports.WA_EMAIL_XMLNS = exports.WA_EMAIL_TAGS = exports.WA_EMAIL_LIMITS = exports.WA_EMAIL_ERROR_CODES = exports.WA_EMAIL_CONTEXTS = exports.WA_STATUS_DISTRIBUTION_SETTINGS = exports.WA_META_NODE_ATTRS_BOT = exports.WA_BOT_NODE_ATTRS = exports.WA_BOT_MSG_SECRET_BYTES = exports.WA_BOT_MSG_EDIT_TYPES = exports.WA_BOT_MSG_BODY_TYPES = exports.WA_BOT_KNOWN_JIDS = exports.WA_BOT_HKDF_INFO = exports.WA_BOT_DEFAULT_CAPABILITIES = exports.WA_BIZ_BOT_TYPES = exports.WA_DEFAULTS = exports.WA_PRIVACY_VALUES = exports.WA_PRIVACY_TAGS = exports.WA_PRIVACY_SETTING_TO_CATEGORY = exports.WA_PRIVACY_DISALLOWED_LIST_CATEGORIES = exports.WA_PRIVACY_CATEGORY_TO_SETTING = exports.WA_PRIVACY_CATEGORIES = exports.WA_TC_TOKEN_DEFAULTS = exports.WA_PRIVACY_TOKEN_TYPES = exports.WA_PRIVACY_TOKEN_TAGS = void 0;
|
|
3
|
+
exports.WA_PRESENCE_TYPES = exports.WA_PRESENCE_LAST_SENTINELS = exports.WA_CHATSTATE_MEDIA = exports.WA_BUSINESS_HOURS_MODES = exports.WA_BUSINESS_HOURS_DAYS = exports.WA_REGISTRATION_NOTIFICATION_TAGS = exports.WA_NOTIFICATION_TYPES = exports.WA_NEWSLETTER_NOTIFICATION_TAGS = exports.WA_GROUP_NOTIFICATION_TAGS = exports.WA_BUSINESS_NOTIFICATION_TAGS = exports.WA_SUPPORTED_DIRTY_TYPES = exports.WA_DIRTY_TYPES = exports.WA_DIRTY_PROTOCOLS = exports.WA_ACCOUNT_SYNC_PROTOCOLS = exports.WA_PREVIEW_MEDIA_HKDF_INFO = exports.WA_MEDIA_HKDF_INFO = exports.getWaMediaHkdfInfo = exports.WA_APP_STATE_SYNC_DATA_TYPE = exports.WA_APP_STATE_KEY_TYPES = exports.WA_APP_STATE_KDF_INFO = exports.WA_APP_STATE_ERROR_CODES = exports.WA_APP_STATE_COLLECTION_STATES = exports.WA_APP_STATE_COLLECTIONS = exports.WA_STANZA_MSG_TYPES = exports.WA_RETRYABLE_ACK_CODES = exports.WA_POLL_META_TYPES = exports.WA_NACK_REASONS = exports.WA_MESSAGE_TYPES = exports.WA_MESSAGE_TAGS = exports.WA_EVENT_META_TYPES = exports.WA_ENC_MEDIA_TYPES = exports.WA_EDIT_ATTRS = exports.WA_CALL_RECEIPT_PAYLOAD_TAGS = exports.WA_CALL_PAYLOAD_TAGS = exports.WA_CALL_NODE_ATTRS = exports.WA_CALL_CHILD_TAGS = exports.WA_XMLNS = exports.WA_NODE_TAGS = exports.WA_IQ_TYPES = exports.WA_STREAM_SIGNALING = exports.WA_READY_STATES = exports.WA_LOGOUT_REASONS = exports.WA_FAILURE_REASONS = exports.WA_DISCONNECT_REASONS = exports.WA_CONNECTION_REASONS = exports.WA_PAIRING_KDF_INFO = exports.WA_SIGNALING = exports.WA_COMPANION_PLATFORM_IDS = exports.WA_BROWSERS = exports.getWaCompanionPlatformId = void 0;
|
|
4
|
+
exports.WA_NEWSLETTER_VIEW_ROLES = exports.WA_NEWSLETTER_VERIFICATION_STATES = exports.WA_NEWSLETTER_STATE_TYPES = exports.WA_NEWSLETTER_SEND_TYPES = exports.WA_NEWSLETTER_ROLES = exports.WA_NEWSLETTER_RECEIVE_TYPES = exports.WA_NEWSLETTER_PICTURE_TYPES = exports.WA_NEWSLETTER_MUTE_VALUES = exports.WA_NEWSLETTER_MUTE_TYPES = exports.WA_NEWSLETTER_FETCH_KEY_TYPES = exports.WA_USYNC_MODES = exports.WA_USYNC_DEFAULTS = exports.WA_USYNC_CONTEXTS = exports.WA_GROUP_PARTICIPANT_TYPES = exports.WA_ABPROPS_REFRESH_BOUNDS = exports.WA_ABPROPS_PROTOCOL_VERSION = exports.resolveAbPropNameByCode = exports.AB_PROP_CONFIGS = exports.WA_EMAIL_XMLNS = exports.WA_EMAIL_TAGS = exports.WA_EMAIL_LIMITS = exports.WA_EMAIL_ERROR_CODES = exports.WA_EMAIL_CONTEXTS = exports.WA_STATUS_DISTRIBUTION_SETTINGS = exports.WA_META_NODE_ATTRS_BOT = exports.WA_BOT_NODE_ATTRS = exports.WA_BOT_MSG_SECRET_BYTES = exports.WA_BOT_MSG_EDIT_TYPES = exports.WA_BOT_MSG_BODY_TYPES = exports.WA_BOT_KNOWN_JIDS = exports.WA_BOT_HKDF_INFO = exports.WA_BOT_DEFAULT_CAPABILITIES = exports.WA_BIZ_BOT_TYPES = exports.WA_DEFAULTS = exports.WA_PRIVACY_VALUES = exports.WA_PRIVACY_TAGS = exports.WA_PRIVACY_SETTING_TO_CATEGORY = exports.WA_PRIVACY_DISALLOWED_LIST_CATEGORIES = exports.WA_PRIVACY_CATEGORY_TO_SETTING = exports.WA_PRIVACY_CATEGORIES = exports.WA_TC_TOKEN_DEFAULTS = exports.WA_PRIVACY_TOKEN_TYPES = exports.WA_PRIVACY_TOKEN_TAGS = exports.WA_PRIVACY_TOKEN_NOTIFICATION_TYPE = void 0;
|
|
5
5
|
var browser_1 = require("./browser");
|
|
6
6
|
Object.defineProperty(exports, "getWaCompanionPlatformId", { enumerable: true, get: function () { return browser_1.getWaCompanionPlatformId; } });
|
|
7
7
|
Object.defineProperty(exports, "WA_BROWSERS", { enumerable: true, get: function () { return browser_1.WA_BROWSERS; } });
|
|
@@ -31,6 +31,7 @@ Object.defineProperty(exports, "WA_ENC_MEDIA_TYPES", { enumerable: true, get: fu
|
|
|
31
31
|
Object.defineProperty(exports, "WA_EVENT_META_TYPES", { enumerable: true, get: function () { return message_1.WA_EVENT_META_TYPES; } });
|
|
32
32
|
Object.defineProperty(exports, "WA_MESSAGE_TAGS", { enumerable: true, get: function () { return message_1.WA_MESSAGE_TAGS; } });
|
|
33
33
|
Object.defineProperty(exports, "WA_MESSAGE_TYPES", { enumerable: true, get: function () { return message_1.WA_MESSAGE_TYPES; } });
|
|
34
|
+
Object.defineProperty(exports, "WA_NACK_REASONS", { enumerable: true, get: function () { return message_1.WA_NACK_REASONS; } });
|
|
34
35
|
Object.defineProperty(exports, "WA_POLL_META_TYPES", { enumerable: true, get: function () { return message_1.WA_POLL_META_TYPES; } });
|
|
35
36
|
Object.defineProperty(exports, "WA_RETRYABLE_ACK_CODES", { enumerable: true, get: function () { return message_1.WA_RETRYABLE_ACK_CODES; } });
|
|
36
37
|
Object.defineProperty(exports, "WA_STANZA_MSG_TYPES", { enumerable: true, get: function () { return message_1.WA_STANZA_MSG_TYPES; } });
|
|
@@ -28,6 +28,28 @@ export declare const WA_MESSAGE_TYPES: Readonly<{
|
|
|
28
28
|
}>;
|
|
29
29
|
export type WaOutboundReceiptType = typeof WA_MESSAGE_TYPES.RECEIPT_TYPE_READ | typeof WA_MESSAGE_TYPES.RECEIPT_TYPE_READ_SELF | typeof WA_MESSAGE_TYPES.RECEIPT_TYPE_PLAYED | typeof WA_MESSAGE_TYPES.RECEIPT_TYPE_PLAYED_SELF | typeof WA_MESSAGE_TYPES.RECEIPT_TYPE_INACTIVE | typeof WA_MESSAGE_TYPES.RECEIPT_TYPE_HISTORY_SYNC;
|
|
30
30
|
export declare const WA_RETRYABLE_ACK_CODES: readonly ["408", "429", "500", "503"];
|
|
31
|
+
/**
|
|
32
|
+
* Stanza-ack `error` attr codes (nack reasons): sent when nacking a stanza
|
|
33
|
+
* that could not be handled, and matched against the `error` carried by an
|
|
34
|
+
* inbound publish ack (e.g. stale group addressing mode).
|
|
35
|
+
*/
|
|
36
|
+
export declare const WA_NACK_REASONS: Readonly<{
|
|
37
|
+
readonly STALE_GROUP_ADDRESSING_MODE: 421;
|
|
38
|
+
readonly NEW_CHAT_MESSAGES_CAPPED: 475;
|
|
39
|
+
readonly PARSING_ERROR: 487;
|
|
40
|
+
readonly UNRECOGNIZED_STANZA: 488;
|
|
41
|
+
readonly UNRECOGNIZED_STANZA_CLASS: 489;
|
|
42
|
+
readonly UNRECOGNIZED_STANZA_TYPE: 490;
|
|
43
|
+
readonly INVALID_PROTOBUF: 491;
|
|
44
|
+
readonly INVALID_HOSTED_COMPANION_STANZA: 493;
|
|
45
|
+
readonly MISSING_MESSAGE_SECRET: 495;
|
|
46
|
+
readonly SIGNAL_ERROR_OLD_COUNTER: 496;
|
|
47
|
+
readonly MESSAGE_DELETED_ON_PEER: 499;
|
|
48
|
+
readonly UNHANDLED_ERROR: 500;
|
|
49
|
+
readonly UNSUPPORTED_ADMIN_REVOKE: 550;
|
|
50
|
+
readonly UNSUPPORTED_LID_GROUP: 551;
|
|
51
|
+
readonly DB_OPERATION_FAILED: 552;
|
|
52
|
+
}>;
|
|
31
53
|
export declare const WA_STANZA_MSG_TYPES: Readonly<{
|
|
32
54
|
readonly TEXT: "text";
|
|
33
55
|
readonly MEDIA: "media";
|
package/dist/protocol/message.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WA_ENC_MEDIA_TYPES = exports.WA_EVENT_META_TYPES = exports.WA_POLL_META_TYPES = exports.WA_EDIT_ATTRS = exports.WA_STANZA_MSG_TYPES = exports.WA_RETRYABLE_ACK_CODES = exports.WA_MESSAGE_TYPES = exports.WA_MESSAGE_TAGS = void 0;
|
|
3
|
+
exports.WA_ENC_MEDIA_TYPES = exports.WA_EVENT_META_TYPES = exports.WA_POLL_META_TYPES = exports.WA_EDIT_ATTRS = exports.WA_STANZA_MSG_TYPES = exports.WA_NACK_REASONS = exports.WA_RETRYABLE_ACK_CODES = exports.WA_MESSAGE_TYPES = exports.WA_MESSAGE_TAGS = void 0;
|
|
4
4
|
exports.WA_MESSAGE_TAGS = Object.freeze({
|
|
5
5
|
MESSAGE: 'message',
|
|
6
6
|
ENC: 'enc',
|
|
@@ -30,6 +30,28 @@ exports.WA_MESSAGE_TYPES = Object.freeze({
|
|
|
30
30
|
RECEIPT_TYPE_VIEW: 'view'
|
|
31
31
|
});
|
|
32
32
|
exports.WA_RETRYABLE_ACK_CODES = Object.freeze(['408', '429', '500', '503']);
|
|
33
|
+
/**
|
|
34
|
+
* Stanza-ack `error` attr codes (nack reasons): sent when nacking a stanza
|
|
35
|
+
* that could not be handled, and matched against the `error` carried by an
|
|
36
|
+
* inbound publish ack (e.g. stale group addressing mode).
|
|
37
|
+
*/
|
|
38
|
+
exports.WA_NACK_REASONS = Object.freeze({
|
|
39
|
+
STALE_GROUP_ADDRESSING_MODE: 421,
|
|
40
|
+
NEW_CHAT_MESSAGES_CAPPED: 475,
|
|
41
|
+
PARSING_ERROR: 487,
|
|
42
|
+
UNRECOGNIZED_STANZA: 488,
|
|
43
|
+
UNRECOGNIZED_STANZA_CLASS: 489,
|
|
44
|
+
UNRECOGNIZED_STANZA_TYPE: 490,
|
|
45
|
+
INVALID_PROTOBUF: 491,
|
|
46
|
+
INVALID_HOSTED_COMPANION_STANZA: 493,
|
|
47
|
+
MISSING_MESSAGE_SECRET: 495,
|
|
48
|
+
SIGNAL_ERROR_OLD_COUNTER: 496,
|
|
49
|
+
MESSAGE_DELETED_ON_PEER: 499,
|
|
50
|
+
UNHANDLED_ERROR: 500,
|
|
51
|
+
UNSUPPORTED_ADMIN_REVOKE: 550,
|
|
52
|
+
UNSUPPORTED_LID_GROUP: 551,
|
|
53
|
+
DB_OPERATION_FAILED: 552
|
|
54
|
+
});
|
|
33
55
|
exports.WA_STANZA_MSG_TYPES = Object.freeze({
|
|
34
56
|
TEXT: 'text',
|
|
35
57
|
MEDIA: 'media',
|
package/dist/retry/replay.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { WaMessageClient } from '../message/WaMessageClient';
|
|
|
5
5
|
import type { WaRetryOutboundMessageRecord } from './types';
|
|
6
6
|
import type { SignalSessionResolver } from '../signal/session/resolver';
|
|
7
7
|
import type { SignalProtocol } from '../signal/session/SignalProtocol';
|
|
8
|
+
import type { BinaryNode } from '../transport/types';
|
|
8
9
|
export interface WaRetryReplayServiceOptions {
|
|
9
10
|
readonly logger: Logger;
|
|
10
11
|
readonly messageClient: WaMessageClient;
|
|
@@ -12,6 +13,12 @@ export interface WaRetryReplayServiceOptions {
|
|
|
12
13
|
readonly sessionResolver: SignalSessionResolver;
|
|
13
14
|
readonly getCurrentCredentials: () => WaAuthCredentials | null;
|
|
14
15
|
readonly resolveUserIcdc?: (userJid: string) => Promise<IcdcMeta | null>;
|
|
16
|
+
/**
|
|
17
|
+
* Resolves the trusted-contact (privacy) token node for a recipient user
|
|
18
|
+
* jid. A resend without it is nacked with error 463 by privacy-gated
|
|
19
|
+
* recipients.
|
|
20
|
+
*/
|
|
21
|
+
readonly resolvePrivacyTokenNode?: (recipientJid: string) => Promise<BinaryNode | null>;
|
|
15
22
|
}
|
|
16
23
|
export type WaRetryResendResult = 'resent' | 'ineligible';
|
|
17
24
|
/**
|
|
@@ -30,6 +37,11 @@ export declare class WaRetryReplayService {
|
|
|
30
37
|
resendOutboundMessage(outbound: WaRetryOutboundMessageRecord, requesterJid: string, retryCount: number): Promise<WaRetryResendResult>;
|
|
31
38
|
private resendPlaintextPayload;
|
|
32
39
|
private resolveSignedDeviceIdentity;
|
|
40
|
+
/**
|
|
41
|
+
* Resolves the trusted-contact token node for the requester's user jid. A
|
|
42
|
+
* failure (or absent resolver) yields no node and the resend still goes out.
|
|
43
|
+
*/
|
|
44
|
+
private resolvePrivacyToken;
|
|
33
45
|
private refreshRetryPlaintext;
|
|
34
46
|
private safeUserJid;
|
|
35
47
|
private resendGroupPlaintextPayload;
|
package/dist/retry/replay.js
CHANGED
|
@@ -69,6 +69,9 @@ class WaRetryReplayService {
|
|
|
69
69
|
const metaNode = (0, jid_1.isHostedDeviceJid)(requesterJid)
|
|
70
70
|
? (0, message_1.buildMetaNode)({ sender_intent: 'hosted' })
|
|
71
71
|
: undefined;
|
|
72
|
+
const privacyTokenNode = requesterIsSelf
|
|
73
|
+
? undefined
|
|
74
|
+
: await this.resolvePrivacyToken(requesterJid);
|
|
72
75
|
await this.options.messageClient.sendEncrypted({
|
|
73
76
|
to: requesterJid,
|
|
74
77
|
encType: encrypted.type,
|
|
@@ -77,7 +80,8 @@ class WaRetryReplayService {
|
|
|
77
80
|
id: outbound.messageId,
|
|
78
81
|
type: payload.type,
|
|
79
82
|
deviceIdentity,
|
|
80
|
-
metaNode
|
|
83
|
+
metaNode,
|
|
84
|
+
privacyTokenNode
|
|
81
85
|
});
|
|
82
86
|
return 'resent';
|
|
83
87
|
}
|
|
@@ -91,6 +95,32 @@ class WaRetryReplayService {
|
|
|
91
95
|
}
|
|
92
96
|
return _proto_1.proto.ADVSignedDeviceIdentity.encode(signedIdentity).finish();
|
|
93
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolves the trusted-contact token node for the requester's user jid. A
|
|
100
|
+
* failure (or absent resolver) yields no node and the resend still goes out.
|
|
101
|
+
*/
|
|
102
|
+
async resolvePrivacyToken(requesterJid) {
|
|
103
|
+
if (!this.options.resolvePrivacyTokenNode) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
let recipientUserJid;
|
|
107
|
+
try {
|
|
108
|
+
recipientUserJid = (0, jid_1.toUserJid)(requesterJid);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
return (await this.options.resolvePrivacyTokenNode(recipientUserJid)) ?? undefined;
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
this.options.logger.warn('retry resend privacy token resolution failed', {
|
|
118
|
+
to: recipientUserJid,
|
|
119
|
+
message: (0, primitives_1.toError)(error).message
|
|
120
|
+
});
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
94
124
|
async refreshRetryPlaintext(payload, options) {
|
|
95
125
|
if (!options.wrapAsDeviceSent && !this.options.resolveUserIcdc) {
|
|
96
126
|
return null;
|
|
@@ -202,6 +232,9 @@ class WaRetryReplayService {
|
|
|
202
232
|
const metaNode = (0, jid_1.isHostedDeviceJid)(requesterJid)
|
|
203
233
|
? (0, message_1.buildMetaNode)({ sender_intent: 'hosted' })
|
|
204
234
|
: undefined;
|
|
235
|
+
const privacyTokenNode = this.isRequesterCurrentAccount(requesterJid)
|
|
236
|
+
? undefined
|
|
237
|
+
: await this.resolvePrivacyToken(requesterJid);
|
|
205
238
|
await this.options.messageClient.sendEncrypted({
|
|
206
239
|
to: requesterJid,
|
|
207
240
|
encType: payload.encType,
|
|
@@ -211,7 +244,8 @@ class WaRetryReplayService {
|
|
|
211
244
|
type: payload.type,
|
|
212
245
|
participant: payload.participant,
|
|
213
246
|
deviceIdentity,
|
|
214
|
-
metaNode
|
|
247
|
+
metaNode,
|
|
248
|
+
privacyTokenNode
|
|
215
249
|
});
|
|
216
250
|
return 'resent';
|
|
217
251
|
}
|
|
@@ -163,9 +163,9 @@ async function decryptMsg(session, parsed, onPrevSessionDecryptError) {
|
|
|
163
163
|
}
|
|
164
164
|
catch (error) {
|
|
165
165
|
for (let i = 0; i < session.prevSessions.length; i += 1) {
|
|
166
|
-
const decodedPrev = (0, encoding_1.decodeSignalSessionSnapshot)(session.prevSessions[i], `prevSessions[${i}]`);
|
|
167
|
-
const prevSession = (0, SignalSession_1.snapshotToRecord)(decodedPrev);
|
|
168
166
|
try {
|
|
167
|
+
const decodedPrev = (0, encoding_1.decodeSignalSessionSnapshot)(session.prevSessions[i], `prevSessions[${i}]`);
|
|
168
|
+
const prevSession = (0, SignalSession_1.snapshotToRecord)(decodedPrev);
|
|
169
169
|
const [updatedPrev, plaintext] = await decryptMsgFromSession(prevSession, parsed);
|
|
170
170
|
const updatedSession = {
|
|
171
171
|
...updatedPrev,
|
|
@@ -172,6 +172,10 @@ class WaComms {
|
|
|
172
172
|
await this.socket.close(1000, 'stop_comms');
|
|
173
173
|
}
|
|
174
174
|
async closeSocketAndResume() {
|
|
175
|
+
if (!this.started || this.preventRetry) {
|
|
176
|
+
this.logger.debug('comms resume skipped: comms stopped or retry disabled');
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
175
179
|
this.logger.debug('comms close socket and resume requested');
|
|
176
180
|
this.resetConnectionState({
|
|
177
181
|
started: true,
|
|
@@ -104,6 +104,10 @@ class WaKeepAlive {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
catch (error) {
|
|
107
|
+
if (generation !== this.generation) {
|
|
108
|
+
this.logger.trace('keepalive stopped during in-flight ping, not resuming');
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
107
111
|
this.logger.warn('keepalive ping failed, reconnecting socket', {
|
|
108
112
|
message: (0, primitives_1.toError)(error).message
|
|
109
113
|
});
|
|
@@ -5,7 +5,12 @@ interface WaNodeOrchestratorOptions {
|
|
|
5
5
|
readonly sendNode: (node: BinaryNode) => Promise<void>;
|
|
6
6
|
readonly defaultTimeoutMs?: number;
|
|
7
7
|
readonly hostDomain?: string;
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Resolved lazily on first id-generator creation (post-connect, after
|
|
10
|
+
* credentials load) so a registered mobile session reconnecting without an
|
|
11
|
+
* explicit `mobileTransport` option still picks the mobile id format.
|
|
12
|
+
*/
|
|
13
|
+
readonly mobileIqIdFormat?: () => boolean;
|
|
9
14
|
}
|
|
10
15
|
/**
|
|
11
16
|
* Issues outgoing binary nodes and matches incoming responses back to their
|
|
@@ -15,7 +15,7 @@ class WaNodeOrchestrator {
|
|
|
15
15
|
this.sendNodeFn = options.sendNode;
|
|
16
16
|
this.defaultTimeoutMs = options.defaultTimeoutMs ?? constants_1.WA_DEFAULTS.NODE_QUERY_TIMEOUT_MS;
|
|
17
17
|
this.hostDomain = options.hostDomain ?? constants_1.WA_DEFAULTS.HOST_DOMAIN;
|
|
18
|
-
this.mobileIqIdFormat = options.mobileIqIdFormat
|
|
18
|
+
this.mobileIqIdFormat = options.mobileIqIdFormat ?? (() => false);
|
|
19
19
|
this.idGenerator = null;
|
|
20
20
|
this.idGeneratorReady = null;
|
|
21
21
|
this.pendingQueries = new Map();
|
|
@@ -137,7 +137,7 @@ class WaNodeOrchestrator {
|
|
|
137
137
|
if (this.idGenerator) {
|
|
138
138
|
return this.idGenerator;
|
|
139
139
|
}
|
|
140
|
-
if (this.mobileIqIdFormat) {
|
|
140
|
+
if (this.mobileIqIdFormat()) {
|
|
141
141
|
this.idGenerator = (0, helpers_1.createMobileNodeIdGenerator)();
|
|
142
142
|
this.logger.debug('generated stanza prefix (mobile)', {
|
|
143
143
|
prefix: this.idGenerator.prefix
|
|
@@ -62,6 +62,9 @@ function buildAckNode(input) {
|
|
|
62
62
|
to: input.to,
|
|
63
63
|
class: _protocol_1.WA_MESSAGE_TYPES.ACK_CLASS_MESSAGE
|
|
64
64
|
};
|
|
65
|
+
if (input.error !== undefined) {
|
|
66
|
+
attrs.error = String(input.error);
|
|
67
|
+
}
|
|
65
68
|
const type = input.typeOverride ?? input.node.attrs.type;
|
|
66
69
|
if (type) {
|
|
67
70
|
attrs.type = type;
|