@hansaka02/baileys 7.3.2 → 7.3.4
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 +247 -203
- package/lib/Defaults/connection.js +51 -0
- package/lib/Defaults/constants.js +62 -0
- package/lib/Defaults/history.js +17 -0
- package/lib/Defaults/index.js +36 -142
- package/lib/Defaults/media.js +48 -0
- package/lib/Defaults/prefix.js +18 -0
- package/lib/Signal/Group/group-session-builder.js +10 -42
- package/lib/Signal/Group/group_cipher.js +9 -6
- package/lib/Signal/Group/index.js +39 -53
- package/lib/Signal/Group/keyhelper.js +8 -41
- package/lib/Signal/Group/sender-chain-key.js +4 -4
- package/lib/Signal/Group/sender-key-distribution-message.js +5 -5
- package/lib/Signal/Group/sender-key-message.js +12 -8
- package/lib/Signal/Group/sender-key-record.js +7 -7
- package/lib/Signal/Group/sender-key-state.js +4 -4
- package/lib/Signal/Group/sender-message-key.js +2 -2
- package/lib/Signal/libsignal.js +45 -69
- package/lib/Signal/lid-mapping.js +15 -11
- package/lib/Socket/Client/types.js +2 -2
- package/lib/Socket/Client/websocket.js +16 -14
- package/lib/Socket/business.js +41 -32
- package/lib/Socket/chats.js +123 -98
- package/lib/Socket/community.js +50 -40
- package/lib/Socket/groups.js +59 -47
- package/lib/Socket/index.js +4 -4
- package/lib/Socket/messages-recv.js +219 -172
- package/lib/Socket/messages-send.js +187 -143
- package/lib/Socket/newsletter.js +61 -47
- package/lib/Socket/socket.js +133 -90
- package/lib/Socket/usync.js +6 -6
- package/lib/Store/index.js +27 -11
- package/lib/Store/make-cache-manager-store.js +14 -15
- package/lib/Store/make-in-memory-store.js +28 -24
- package/lib/Types/LabelAssociation.js +2 -2
- package/lib/Types/Message.js +6 -6
- package/lib/Types/MexUpdates.js +5 -5
- package/lib/Types/State.js +4 -4
- package/lib/Types/index.js +28 -12
- package/lib/Utils/auth-utils.js +28 -26
- package/lib/Utils/baileys-event-stream.js +68 -69
- package/lib/Utils/business.js +63 -53
- package/lib/Utils/chat-utils.js +81 -71
- package/lib/Utils/crypto.js +25 -45
- package/lib/Utils/decode-wa-message.js +319 -311
- package/lib/Utils/event-buffer.js +21 -22
- package/lib/Utils/generics.js +65 -82
- package/lib/Utils/history.js +21 -21
- package/lib/Utils/index.js +27 -13
- package/lib/Utils/link-preview.js +7 -30
- package/lib/Utils/logger.js +5 -5
- package/lib/Utils/lt-hash.js +3 -3
- package/lib/Utils/message-retry-manager.js +4 -4
- package/lib/Utils/messages-media.js +104 -109
- package/lib/Utils/messages.js +203 -171
- package/lib/Utils/noise-handler.js +28 -19
- package/lib/Utils/process-message.js +111 -96
- package/lib/Utils/signal.js +36 -25
- package/lib/Utils/use-multi-file-auth-state.js +18 -22
- package/lib/Utils/validate-connection.js +52 -45
- package/lib/WABinary/decode.js +6 -32
- package/lib/WABinary/encode.js +3 -29
- package/lib/WABinary/generic-utils.js +4 -4
- package/lib/WABinary/index.js +27 -11
- package/lib/WAM/encode.js +16 -8
- package/lib/WAM/index.js +27 -11
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +20 -16
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +2 -2
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +7 -4
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +2 -2
- package/lib/WAUSync/Protocols/USyncLIDProtocol.js +0 -2
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +2 -2
- package/lib/WAUSync/Protocols/index.js +27 -11
- package/lib/WAUSync/USyncQuery.js +17 -10
- package/lib/WAUSync/index.js +27 -11
- package/lib/index.js +60 -31
- package/package.json +8 -14
- package/WAProto/AICommon/AICommon.d.ts +0 -11702
- package/WAProto/Adv/Adv.d.ts +0 -643
- package/WAProto/BotMetadata/BotMetadata.d.ts +0 -5654
- package/WAProto/Cert/Cert.d.ts +0 -613
- package/WAProto/ChatLockSettings/ChatLockSettings.d.ts +0 -476
- package/WAProto/CompanionReg/CompanionReg.d.ts +0 -1361
- package/WAProto/DeviceCapabilities/DeviceCapabilities.d.ts +0 -577
- package/WAProto/E2E/E2E.d.ts +0 -41724
- package/WAProto/Ephemeral/Ephemeral.d.ts +0 -114
- package/WAProto/HistorySync/HistorySync.d.ts +0 -51700
- package/WAProto/LidMigrationSyncPayload/LidMigrationSyncPayload.d.ts +0 -229
- package/WAProto/MdStorageChatRowOpaqueData/MdStorageChatRowOpaqueData.d.ts +0 -583
- package/WAProto/MdStorageMsgRowOpaqueData/MdStorageMsgRowOpaqueData.d.ts +0 -42897
- package/WAProto/MmsRetry/MmsRetry.d.ts +0 -243
- package/WAProto/Protocol/Protocol.d.ts +0 -270
- package/WAProto/Reporting/Reporting.d.ts +0 -371
- package/WAProto/ServerSync/ServerSync.d.ts +0 -1285
- package/WAProto/SignalLocalStorageProtocol/SignalLocalStorageProtocol.d.ts +0 -1868
- package/WAProto/SignalWhisperTextProtocol/SignalWhisperTextProtocol.d.ts +0 -767
- package/WAProto/StatusAttributions/StatusAttributions.d.ts +0 -1027
- package/WAProto/SyncAction/SyncAction.d.ts +0 -11193
- package/WAProto/UserPassword/UserPassword.d.ts +0 -363
- package/WAProto/VnameCert/VnameCert.d.ts +0 -821
- package/WAProto/Wa6/Wa6.d.ts +0 -2128
- package/WAProto/Web/Web.d.ts +0 -46383
- package/WAProto/index.d.ts +0 -55
- package/lib/Defaults/index.d.ts +0 -77
- package/lib/Signal/Group/ciphertext-message.d.ts +0 -9
- package/lib/Signal/Group/group-session-builder.d.ts +0 -17
- package/lib/Signal/Group/group_cipher.d.ts +0 -19
- package/lib/Signal/Group/index.d.ts +0 -11
- package/lib/Signal/Group/keyhelper.d.ts +0 -16
- package/lib/Signal/Group/sender-chain-key.d.ts +0 -14
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +0 -17
- package/lib/Signal/Group/sender-key-message.d.ts +0 -19
- package/lib/Signal/Group/sender-key-name.d.ts +0 -19
- package/lib/Signal/Group/sender-key-record.d.ts +0 -32
- package/lib/Signal/Group/sender-key-state.d.ts +0 -44
- package/lib/Signal/Group/sender-message-key.d.ts +0 -11
- package/lib/Signal/libsignal.d.ts +0 -8
- package/lib/Signal/lid-mapping.d.ts +0 -28
- package/lib/Socket/Client/index.d.ts +0 -2
- package/lib/Socket/Client/types.d.ts +0 -16
- package/lib/Socket/Client/websocket.d.ts +0 -13
- package/lib/Socket/business.d.ts +0 -187
- package/lib/Socket/chats.d.ts +0 -97
- package/lib/Socket/community.d.ts +0 -129
- package/lib/Socket/groups.d.ts +0 -129
- package/lib/Socket/index.d.ts +0 -191
- package/lib/Socket/messages-recv.d.ts +0 -174
- package/lib/Socket/messages-send.d.ts +0 -165
- package/lib/Socket/newsletter.d.ts +0 -145
- package/lib/Socket/socket.d.ts +0 -45
- package/lib/Socket/usync.d.ts +0 -37
- package/lib/Store/index.d.ts +0 -4
- package/lib/Store/make-cache-manager-store.d.ts +0 -14
- package/lib/Store/make-in-memory-store.d.ts +0 -123
- package/lib/Store/make-ordered-dictionary.d.ts +0 -12
- package/lib/Store/object-repository.d.ts +0 -10
- package/lib/Types/Auth.d.ts +0 -121
- package/lib/Types/Bussiness.d.ts +0 -28
- package/lib/Types/Call.d.ts +0 -14
- package/lib/Types/Chat.d.ts +0 -143
- package/lib/Types/Contact.d.ts +0 -23
- package/lib/Types/Events.d.ts +0 -226
- package/lib/Types/GroupMetadata.d.ts +0 -66
- package/lib/Types/Label.d.ts +0 -48
- package/lib/Types/LabelAssociation.d.ts +0 -35
- package/lib/Types/Message.d.ts +0 -484
- package/lib/Types/MexUpdates.d.ts +0 -9
- package/lib/Types/Newsletter.d.ts +0 -109
- package/lib/Types/Product.d.ts +0 -92
- package/lib/Types/Signal.d.ts +0 -98
- package/lib/Types/Socket.d.ts +0 -141
- package/lib/Types/State.d.ts +0 -41
- package/lib/Types/USync.d.ts +0 -26
- package/lib/Types/index.d.ts +0 -80
- package/lib/Utils/auth-utils.d.ts +0 -21
- package/lib/Utils/baileys-event-stream.d.ts +0 -18
- package/lib/Utils/business.d.ts +0 -29
- package/lib/Utils/chat-utils.d.ts +0 -82
- package/lib/Utils/crypto.d.ts +0 -56
- package/lib/Utils/decode-wa-message.d.ts +0 -53
- package/lib/Utils/event-buffer.d.ts +0 -39
- package/lib/Utils/generics.d.ts +0 -117
- package/lib/Utils/history.d.ts +0 -23
- package/lib/Utils/index.d.ts +0 -20
- package/lib/Utils/link-preview.d.ts +0 -23
- package/lib/Utils/logger.d.ts +0 -13
- package/lib/Utils/lt-hash.d.ts +0 -14
- package/lib/Utils/make-mutex.d.ts +0 -9
- package/lib/Utils/message-retry-manager.d.ts +0 -88
- package/lib/Utils/messages-media.d.ts +0 -135
- package/lib/Utils/messages.d.ts +0 -105
- package/lib/Utils/noise-handler.d.ts +0 -20
- package/lib/Utils/process-message.d.ts +0 -49
- package/lib/Utils/signal.d.ts +0 -42
- package/lib/Utils/use-mongo-file-auth-state.d.ts +0 -6
- package/lib/Utils/use-mongo-file-auth-state.js +0 -84
- package/lib/Utils/use-multi-file-auth-state.d.ts +0 -13
- package/lib/Utils/use-single-file-auth-state.d.ts +0 -13
- package/lib/Utils/use-single-file-auth-state.js +0 -80
- package/lib/Utils/validate-connection.d.ts +0 -13
- package/lib/WABinary/constants.d.ts +0 -30
- package/lib/WABinary/decode.d.ts +0 -9
- package/lib/WABinary/encode.d.ts +0 -3
- package/lib/WABinary/generic-utils.d.ts +0 -28
- package/lib/WABinary/index.d.ts +0 -5
- package/lib/WABinary/jid-utils.d.ts +0 -58
- package/lib/WABinary/types.d.ts +0 -22
- package/lib/WAM/BinaryInfo.d.ts +0 -16
- package/lib/WAM/constants.d.ts +0 -47
- package/lib/WAM/encode.d.ts +0 -3
- package/lib/WAM/index.d.ts +0 -3
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.d.ts +0 -28
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -10
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -26
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -14
- package/lib/WAUSync/Protocols/USyncLIDProtocol.d.ts +0 -10
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -14
- package/lib/WAUSync/Protocols/index.d.ts +0 -6
- package/lib/WAUSync/USyncQuery.d.ts +0 -31
- package/lib/WAUSync/USyncUser.d.ts +0 -12
- package/lib/WAUSync/index.d.ts +0 -3
- package/lib/index.d.ts +0 -13
|
@@ -1,43 +1,90 @@
|
|
|
1
1
|
"use strict"
|
|
2
2
|
|
|
3
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
-
return (mod && mod.__esModule) ? mod : { "default": mod }
|
|
5
|
-
}
|
|
6
|
-
|
|
7
3
|
Object.defineProperty(exports, "__esModule", { value: true })
|
|
8
4
|
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
5
|
+
const { default: NodeCache } = require("@cacheable/node-cache")
|
|
6
|
+
const { Boom } = require("@hapi/boom")
|
|
7
|
+
const { randomBytes } = require("crypto")
|
|
8
|
+
const { proto } = require("../../WAProto")
|
|
9
|
+
const {
|
|
10
|
+
KEY_BUNDLE_TYPE,
|
|
11
|
+
MIN_PREKEY_COUNT,
|
|
12
|
+
DEFAULT_CACHE_TTLS
|
|
13
|
+
} = require("../Defaults/constants")
|
|
14
|
+
const {
|
|
15
|
+
XWAPaths,
|
|
16
|
+
XWAPathsMexUpdates,
|
|
17
|
+
MexOperations,
|
|
18
|
+
MexUpdatesOperations,
|
|
19
|
+
WAMessageStubType,
|
|
20
|
+
WAMessageStatus
|
|
21
|
+
} = require("../Types")
|
|
22
|
+
const {
|
|
23
|
+
aesDecryptCTR,
|
|
24
|
+
aesEncryptGCM,
|
|
25
|
+
cleanMessage,
|
|
26
|
+
Curve,
|
|
27
|
+
decodeMediaRetryNode,
|
|
28
|
+
decodeMessageNode,
|
|
29
|
+
decryptMessageNode,
|
|
30
|
+
delay,
|
|
31
|
+
derivePairingCodeKey,
|
|
32
|
+
encodeBigEndian,
|
|
33
|
+
encodeSignedDeviceIdentity,
|
|
34
|
+
extractAddressingContext,
|
|
35
|
+
getCallStatusFromNode,
|
|
36
|
+
getHistoryMsg,
|
|
37
|
+
getNextPreKeys,
|
|
38
|
+
getStatusFromReceiptType,
|
|
39
|
+
hkdf,
|
|
40
|
+
NO_MESSAGE_FOUND_ERROR_TEXT,
|
|
41
|
+
MISSING_KEYS_ERROR_TEXT,
|
|
42
|
+
NACK_REASONS,
|
|
43
|
+
unixTimestampSeconds,
|
|
44
|
+
xmppPreKey,
|
|
45
|
+
xmppSignedPreKey,
|
|
46
|
+
generateMessageID
|
|
47
|
+
} = require("../Utils")
|
|
48
|
+
const {
|
|
49
|
+
areJidsSameUser,
|
|
50
|
+
binaryNodeToString,
|
|
51
|
+
getAllBinaryNodeChildren,
|
|
52
|
+
getBinaryNodeChild,
|
|
53
|
+
getBinaryNodeChildBuffer,
|
|
54
|
+
getBinaryNodeChildren,
|
|
55
|
+
getBinaryNodeChildString,
|
|
56
|
+
isJidGroup,
|
|
57
|
+
isJidStatusBroadcast,
|
|
58
|
+
isLidUser,
|
|
59
|
+
isJidUser,
|
|
60
|
+
jidDecode,
|
|
61
|
+
jidNormalizedUser,
|
|
62
|
+
S_WHATSAPP_NET
|
|
63
|
+
} = require("../WABinary")
|
|
64
|
+
const { extractGroupMetadata } = require("./groups")
|
|
65
|
+
const { makeMutex } = require("../Utils/make-mutex")
|
|
66
|
+
const { makeMessagesSocket } = require("./messages-send")
|
|
20
67
|
|
|
21
68
|
const makeMessagesRecvSocket = (config) => {
|
|
22
69
|
const { logger, retryRequestDelayMs, maxMsgRetryCount, getMessage, shouldIgnoreJid, enableAutoSessionRecreation } = config
|
|
23
|
-
const suki =
|
|
70
|
+
const suki = makeMessagesSocket(config)
|
|
24
71
|
const { ev, authState, ws, processingMutex, signalRepository, query, upsertMessage, resyncAppState, onUnexpectedError, assertSessions, sendNode, relayMessage, sendReceipt, uploadPreKeys, groupMetadata, getUSyncDevices, createParticipantNodes, messageRetryManager, sendPeerDataOperationMessage } = suki
|
|
25
72
|
|
|
26
73
|
/** this mutex ensures that each retryRequest will wait for the previous one to finish */
|
|
27
|
-
const retryMutex =
|
|
74
|
+
const retryMutex = makeMutex()
|
|
28
75
|
|
|
29
|
-
const msgRetryCache = config.msgRetryCounterCache || new
|
|
30
|
-
stdTTL:
|
|
76
|
+
const msgRetryCache = config.msgRetryCounterCache || new NodeCache({
|
|
77
|
+
stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY,
|
|
31
78
|
useClones: false
|
|
32
79
|
})
|
|
33
80
|
|
|
34
|
-
const callOfferCache = config.callOfferCache || new
|
|
35
|
-
stdTTL:
|
|
81
|
+
const callOfferCache = config.callOfferCache || new NodeCache({
|
|
82
|
+
stdTTL: DEFAULT_CACHE_TTLS.CALL_OFFER,
|
|
36
83
|
useClones: false
|
|
37
84
|
})
|
|
38
85
|
|
|
39
|
-
const placeholderResendCache = config.placeholderResendCache || new
|
|
40
|
-
stdTTL:
|
|
86
|
+
const placeholderResendCache = config.placeholderResendCache || new NodeCache({
|
|
87
|
+
stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY,
|
|
41
88
|
useClones: false
|
|
42
89
|
})
|
|
43
90
|
|
|
@@ -65,11 +112,11 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
65
112
|
stanza.attrs.recipient = attrs.recipient
|
|
66
113
|
}
|
|
67
114
|
|
|
68
|
-
if (!!attrs.type && (tag !== 'message' ||
|
|
115
|
+
if (!!attrs.type && (tag !== 'message' || getBinaryNodeChild({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
|
|
69
116
|
stanza.attrs.type = attrs.type
|
|
70
117
|
}
|
|
71
118
|
|
|
72
|
-
if (tag === 'message' &&
|
|
119
|
+
if (tag === 'message' && getBinaryNodeChild({ tag, attrs, content }, 'unavailable')) {
|
|
73
120
|
stanza.attrs.from = authState.creds.me.id
|
|
74
121
|
}
|
|
75
122
|
|
|
@@ -78,7 +125,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
78
125
|
}
|
|
79
126
|
|
|
80
127
|
const offerCall = async (toJid, isVideo = false) => {
|
|
81
|
-
const callId =
|
|
128
|
+
const callId = randomBytes(16).toString('hex').toUpperCase().substring(0, 64)
|
|
82
129
|
const offerContent = []
|
|
83
130
|
offerContent.push({ tag: 'audio', attrs: { enc: 'opus', rate: '16000' }, content: undefined })
|
|
84
131
|
offerContent.push({ tag: 'audio', attrs: { enc: 'opus', rate: '8000' }, content: undefined })
|
|
@@ -94,8 +141,8 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
94
141
|
offerContent.push({ tag: 'capability', attrs: { ver: '1' }, content: new Uint8Array([1, 4, 255, 131, 207, 4]) })
|
|
95
142
|
offerContent.push({ tag: 'encopt', attrs: { keygen: '2' }, content: undefined })
|
|
96
143
|
|
|
97
|
-
const encKey =
|
|
98
|
-
const devices = (await getUSyncDevices([toJid], true, false)).map(({ user, device }) =>
|
|
144
|
+
const encKey = randomBytes(32)
|
|
145
|
+
const devices = (await getUSyncDevices([toJid], true, false)).map(({ user, device }) => jidEncode(user, 's.whatsapp.net', device))
|
|
99
146
|
await assertSessions(devices, true)
|
|
100
147
|
|
|
101
148
|
const { nodes: destinations, shouldIncludeDeviceIdentity } = await createParticipantNodes(devices, {
|
|
@@ -109,14 +156,14 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
109
156
|
offerContent.push({
|
|
110
157
|
tag: 'device-identity',
|
|
111
158
|
attrs: {},
|
|
112
|
-
content:
|
|
159
|
+
content: encodeSignedDeviceIdentity(authState.creds.account, true)
|
|
113
160
|
})
|
|
114
161
|
}
|
|
115
162
|
|
|
116
163
|
const stanza = ({
|
|
117
164
|
tag: 'call',
|
|
118
165
|
attrs: {
|
|
119
|
-
id:
|
|
166
|
+
id: generateMessageID(),
|
|
120
167
|
to: toJid,
|
|
121
168
|
},
|
|
122
169
|
content: [{
|
|
@@ -159,7 +206,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
159
206
|
}
|
|
160
207
|
|
|
161
208
|
const sendRetryRequest = async (node, forceIncludeKeys = false) => {
|
|
162
|
-
const { fullMessage } =
|
|
209
|
+
const { fullMessage } = decodeMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '')
|
|
163
210
|
const { key: msgKey } = fullMessage
|
|
164
211
|
const msgId = msgKey.id
|
|
165
212
|
|
|
@@ -245,7 +292,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
245
292
|
}
|
|
246
293
|
}
|
|
247
294
|
|
|
248
|
-
const deviceIdentity =
|
|
295
|
+
const deviceIdentity = encodeSignedDeviceIdentity(account, true)
|
|
249
296
|
await authState.keys.transaction(async () => {
|
|
250
297
|
const receipt = {
|
|
251
298
|
tag: 'receipt',
|
|
@@ -267,7 +314,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
267
314
|
{
|
|
268
315
|
tag: 'registration',
|
|
269
316
|
attrs: {},
|
|
270
|
-
content:
|
|
317
|
+
content: encodeBigEndian(authState.creds.registrationId)
|
|
271
318
|
}
|
|
272
319
|
]
|
|
273
320
|
}
|
|
@@ -281,7 +328,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
281
328
|
}
|
|
282
329
|
|
|
283
330
|
if (retryCount > 1 || forceIncludeKeys || shouldRecreateSession) {
|
|
284
|
-
const { update, preKeys } = await
|
|
331
|
+
const { update, preKeys } = await getNextPreKeys(authState, 1)
|
|
285
332
|
const [keyId] = Object.keys(preKeys)
|
|
286
333
|
const key = preKeys[+keyId]
|
|
287
334
|
const content = receipt.content
|
|
@@ -290,10 +337,10 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
290
337
|
tag: 'keys',
|
|
291
338
|
attrs: {},
|
|
292
339
|
content: [
|
|
293
|
-
{ tag: 'type', attrs: {}, content: Buffer.from(
|
|
340
|
+
{ tag: 'type', attrs: {}, content: Buffer.from(KEY_BUNDLE_TYPE) },
|
|
294
341
|
{ tag: 'identity', attrs: {}, content: identityKey.public },
|
|
295
|
-
|
|
296
|
-
|
|
342
|
+
xmppPreKey(key, +keyId),
|
|
343
|
+
xmppSignedPreKey(signedPreKey),
|
|
297
344
|
{ tag: 'device-identity', attrs: {}, content: deviceIdentity }
|
|
298
345
|
]
|
|
299
346
|
});
|
|
@@ -306,10 +353,10 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
306
353
|
|
|
307
354
|
const handleEncryptNotification = async (node) => {
|
|
308
355
|
const from = node.attrs.from
|
|
309
|
-
if (from ===
|
|
310
|
-
const countChild =
|
|
356
|
+
if (from === S_WHATSAPP_NET) {
|
|
357
|
+
const countChild = getBinaryNodeChild(node, 'count')
|
|
311
358
|
const count = +countChild.attrs.value
|
|
312
|
-
const shouldUploadMorePreKeys = count <
|
|
359
|
+
const shouldUploadMorePreKeys = count < MIN_PREKEY_COUNT
|
|
313
360
|
logger.debug({ count, shouldUploadMorePreKeys }, 'recv pre-key count')
|
|
314
361
|
|
|
315
362
|
if (shouldUploadMorePreKeys) {
|
|
@@ -318,7 +365,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
318
365
|
}
|
|
319
366
|
|
|
320
367
|
else {
|
|
321
|
-
const identityNode =
|
|
368
|
+
const identityNode = getBinaryNodeChild(node, 'identity')
|
|
322
369
|
if (identityNode) {
|
|
323
370
|
logger.info({ jid: from }, 'identity changed')
|
|
324
371
|
// not handling right now
|
|
@@ -332,13 +379,13 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
332
379
|
}
|
|
333
380
|
|
|
334
381
|
const handleGroupNotification = (participant, child, msg, mode) => {
|
|
335
|
-
let participantJid = mode === 'lid' ?
|
|
382
|
+
let participantJid = mode === 'lid' ? getBinaryNodeChild(child, 'participant')?.attrs?.phone_number : getBinaryNodeChild(child, 'participant')?.attrs?.jid || participant
|
|
336
383
|
|
|
337
384
|
// TODO: Add participant LID
|
|
338
385
|
switch (child.tag) {
|
|
339
386
|
case 'create':
|
|
340
|
-
const metadata =
|
|
341
|
-
msg.messageStubType =
|
|
387
|
+
const metadata = extractGroupMetadata(child)
|
|
388
|
+
msg.messageStubType = WAMessageStubType.GROUP_CREATE
|
|
342
389
|
msg.messageStubParameters = [metadata.subject]
|
|
343
390
|
msg.key = { participant: metadata.owner }
|
|
344
391
|
ev.emit('chats.upsert', [{
|
|
@@ -352,22 +399,22 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
352
399
|
}])
|
|
353
400
|
break
|
|
354
401
|
case 'delete':
|
|
355
|
-
msg.messageStubType =
|
|
402
|
+
msg.messageStubType = WAMessageStubType.COMMUNITY_PARENT_GROUP_DELETED
|
|
356
403
|
msg.messageStubParameters = [participantJid, 'delete']
|
|
357
404
|
break
|
|
358
405
|
case 'ephemeral':
|
|
359
406
|
case 'not_ephemeral':
|
|
360
407
|
msg.message = {
|
|
361
408
|
protocolMessage: {
|
|
362
|
-
type:
|
|
409
|
+
type: proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
|
|
363
410
|
ephemeralExpiration: +(child.attrs.expiration || 0)
|
|
364
411
|
}
|
|
365
412
|
}
|
|
366
413
|
break
|
|
367
414
|
case 'modify':
|
|
368
|
-
const oldNumber = mode === 'lid' ?
|
|
415
|
+
const oldNumber = mode === 'lid' ? getBinaryNodeChildren(child, 'participant').map(p => p.attrs.phone_number) : getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid)
|
|
369
416
|
msg.messageStubParameters = oldNumber || []
|
|
370
|
-
msg.messageStubType =
|
|
417
|
+
msg.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER
|
|
371
418
|
break
|
|
372
419
|
case 'promote':
|
|
373
420
|
case 'demote':
|
|
@@ -378,97 +425,97 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
378
425
|
if (child.attrs?.reason === 'linked_group_join') {
|
|
379
426
|
stubType = GROUP_PARTICIPANT_LINKED_GROUP_JOIN
|
|
380
427
|
}
|
|
381
|
-
msg.messageStubType =
|
|
382
|
-
const participants = mode === 'lid' ?
|
|
428
|
+
msg.messageStubType = WAMessageStubType[stubType]
|
|
429
|
+
const participants = mode === 'lid' ? getBinaryNodeChildren(child, 'participant').map(p => p.attrs.phone_number) : getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid)
|
|
383
430
|
if (participants.length === 1 &&
|
|
384
431
|
// if recv. "remove" message and sender removed themselves
|
|
385
432
|
// mark as left
|
|
386
|
-
|
|
433
|
+
areJidsSameUser(participants[0], participant) &&
|
|
387
434
|
child.tag === 'remove') {
|
|
388
|
-
msg.messageStubType =
|
|
435
|
+
msg.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_LEAVE
|
|
389
436
|
}
|
|
390
437
|
msg.messageStubParameters = participants
|
|
391
438
|
break
|
|
392
439
|
case 'subject':
|
|
393
|
-
msg.messageStubType =
|
|
440
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_SUBJECT
|
|
394
441
|
msg.messageStubParameters = [participantJid, child.attrs.subject]
|
|
395
442
|
break
|
|
396
443
|
case 'description':
|
|
397
|
-
const description =
|
|
398
|
-
msg.messageStubType =
|
|
444
|
+
const description = getBinaryNodeChild(child, 'body')?.content?.toString()
|
|
445
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_DESCRIPTION
|
|
399
446
|
msg.messageStubParameters = description ? [description] : undefined
|
|
400
447
|
break
|
|
401
448
|
case 'announcement':
|
|
402
449
|
case 'not_announcement':
|
|
403
|
-
msg.messageStubType =
|
|
450
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_ANNOUNCE
|
|
404
451
|
msg.messageStubParameters = [(child.tag === 'announcement') ? 'on' : 'off']
|
|
405
452
|
break
|
|
406
453
|
case 'locked':
|
|
407
454
|
case 'unlocked':
|
|
408
|
-
msg.messageStubType =
|
|
455
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_RESTRICT
|
|
409
456
|
msg.messageStubParameters = [(child.tag === 'locked') ? 'on' : 'off']
|
|
410
457
|
break
|
|
411
458
|
case 'invite':
|
|
412
|
-
msg.messageStubType =
|
|
459
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_INVITE_LINK
|
|
413
460
|
msg.messageStubParameters = [child.attrs.code]
|
|
414
461
|
break
|
|
415
462
|
case 'member_add_mode':
|
|
416
463
|
const addMode = child.content
|
|
417
464
|
if (addMode) {
|
|
418
|
-
msg.messageStubType =
|
|
465
|
+
msg.messageStubType = WAMessageStubType.GROUP_MEMBER_ADD_MODE
|
|
419
466
|
msg.messageStubParameters = [addMode.toString()]
|
|
420
467
|
}
|
|
421
468
|
break
|
|
422
469
|
case 'membership_approval_mode':
|
|
423
|
-
const approvalMode =
|
|
470
|
+
const approvalMode = getBinaryNodeChild(child, 'group_join')
|
|
424
471
|
if (approvalMode) {
|
|
425
|
-
msg.messageStubType =
|
|
472
|
+
msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE
|
|
426
473
|
msg.messageStubParameters = [approvalMode.attrs.state]
|
|
427
474
|
}
|
|
428
475
|
break
|
|
429
476
|
case 'created_membership_requests':
|
|
430
|
-
participantJid = mode === 'lid' ?
|
|
477
|
+
participantJid = mode === 'lid' ? getBinaryNodeChild(child, 'requested_user')?.attrs?.phone_number : getBinaryNodeChild(child, 'requested_user')?.attrs?.jid || participant
|
|
431
478
|
|
|
432
|
-
msg.messageStubType =
|
|
479
|
+
msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD
|
|
433
480
|
msg.messageStubParameters = [participantJid, 'created', child.attrs.request_method]
|
|
434
481
|
break
|
|
435
482
|
case 'revoked_membership_requests':
|
|
436
|
-
participantJid = mode === 'lid' ?
|
|
483
|
+
participantJid = mode === 'lid' ? getBinaryNodeChild(child, 'requested_user')?.attrs?.phone_number : getBinaryNodeChild(child, 'requested_user')?.attrs?.jid || participant
|
|
437
484
|
|
|
438
|
-
const isDenied =
|
|
439
|
-
msg.messageStubType =
|
|
485
|
+
const isDenied = areJidsSameUser(participantJid, participant)
|
|
486
|
+
msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD
|
|
440
487
|
msg.messageStubParameters = [participantJid, isDenied ? 'revoked' : 'rejected']
|
|
441
488
|
break
|
|
442
489
|
case 'link':
|
|
443
490
|
case 'unlink':
|
|
444
491
|
const type = child.attrs?.unlink_type || child.attrs?.link_type
|
|
445
492
|
const stubMap = {
|
|
446
|
-
parent_group:
|
|
447
|
-
sibling_group:
|
|
448
|
-
sub_group:
|
|
493
|
+
parent_group: WAMessageStubType[`COMMUNITY_${child.tag.toUpperCase()}_PARENT_GROUP`],
|
|
494
|
+
sibling_group: WAMessageStubType[`COMMUNITY_${child.tag.toUpperCase()}_SIBLING_GROUP`],
|
|
495
|
+
sub_group: WAMessageStubType[`COMMUNITY_${child.tag.toUpperCase()}_SUB_GROUP`]
|
|
449
496
|
}
|
|
450
|
-
const groups =
|
|
497
|
+
const groups = getBinaryNodeChildren(child, 'group')
|
|
451
498
|
.map(g => g.attrs?.jid || g.attrs?.subject || '')
|
|
452
499
|
.filter(x => x)
|
|
453
|
-
msg.messageStubType = stubMap?.[type] ||
|
|
500
|
+
msg.messageStubType = stubMap?.[type] || WAMessageStubType[`COMMUNITY_${child.tag.toUpperCase()}_PARENT_GROUP`]
|
|
454
501
|
msg.messageStubParameters = [participantJid, child.tag, groups]
|
|
455
502
|
break
|
|
456
503
|
case 'linked_group_promote':
|
|
457
504
|
case 'linked_group_demote':
|
|
458
505
|
const stubtype = `COMMUNITY_PARTICIPANT_${child.tag.split('_')[2].toUpperCase()}`
|
|
459
|
-
const participantS = mode === 'lid' ?
|
|
460
|
-
msg.messageStubType =
|
|
506
|
+
const participantS = mode === 'lid' ? getBinaryNodeChildren(child, 'participant').map(p => p.attrs.phone_number) : getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid)
|
|
507
|
+
msg.messageStubType = WAMessageStubType[stubtype]
|
|
461
508
|
msg.messageStubParameters = participantS
|
|
462
509
|
break
|
|
463
510
|
case 'created_sub_group_suggestion':
|
|
464
|
-
msg.messageStubType =
|
|
511
|
+
msg.messageStubType = WAMessageStubType.SUGGESTED_SUBGROUP_ANNOUNCE
|
|
465
512
|
msg.messageStubParameters = [participantJid, 'add']
|
|
466
513
|
break
|
|
467
514
|
case 'revoked_sub_group_suggestions':
|
|
468
|
-
const res =
|
|
515
|
+
const res = getBinaryNodeChildren(child, 'sub_group_suggestions')
|
|
469
516
|
const reason = res.attrs?.reason
|
|
470
|
-
if (reason === 'approved') msg.messageStubType =
|
|
471
|
-
else msg.messageStubType =
|
|
517
|
+
if (reason === 'approved') msg.messageStubType = WAMessageStubType.GROUP_CREATE
|
|
518
|
+
else msg.messageStubType = WAMessageStubType.GENERIC_NOTIFICATION
|
|
472
519
|
msg.messageStubParameters = [participantJid, reason]
|
|
473
520
|
break
|
|
474
521
|
default:
|
|
@@ -478,15 +525,15 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
478
525
|
}
|
|
479
526
|
|
|
480
527
|
const handleNewsletterNotification = (id, node) => {
|
|
481
|
-
const messages =
|
|
482
|
-
const message =
|
|
528
|
+
const messages = getBinaryNodeChild(node, 'messages')
|
|
529
|
+
const message = getBinaryNodeChild(node, 'message')
|
|
483
530
|
const serverId = node.attrs.server_id
|
|
484
531
|
|
|
485
|
-
const reactionsList =
|
|
486
|
-
const viewsList =
|
|
532
|
+
const reactionsList = getBinaryNodeChild(node, 'reactions')
|
|
533
|
+
const viewsList = getBinaryNodeChild(node, 'views_count')
|
|
487
534
|
|
|
488
535
|
if (reactionsList) {
|
|
489
|
-
const reactions =
|
|
536
|
+
const reactions = getBinaryNodeChild(reactionsList, 'reaction')
|
|
490
537
|
|
|
491
538
|
if (reactions.length === 0) {
|
|
492
539
|
ev.emit('newsletter.reaction', {
|
|
@@ -528,23 +575,23 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
528
575
|
let contentPath
|
|
529
576
|
let action
|
|
530
577
|
|
|
531
|
-
if (operation ===
|
|
532
|
-
contentPath = content.data[
|
|
578
|
+
if (operation === MexOperations.UPDATE) {
|
|
579
|
+
contentPath = content.data[XWAPaths.METADATA_UPDATE]
|
|
533
580
|
|
|
534
581
|
ev.emit('newsletter-settings.update', {
|
|
535
582
|
id,
|
|
536
583
|
update: contentPath.thread_metadata.settings
|
|
537
584
|
})
|
|
538
|
-
} else if (operation ===
|
|
539
|
-
contentPath = content.data[
|
|
585
|
+
} else if (operation === MexUpdatesOperations.GROUP_MEMBER_LINK) {
|
|
586
|
+
contentPath = content.data[XWAPathsMexUpdates.GROUP_SHARING_CHANGE]
|
|
540
587
|
|
|
541
588
|
ev.emit('groups.update', [{
|
|
542
589
|
id,
|
|
543
590
|
author: contentPath.updated_by.id,
|
|
544
591
|
member_link_mode: contentPath.properties.member_link_mode
|
|
545
592
|
}])
|
|
546
|
-
} else if (operation ===
|
|
547
|
-
contentPath = content.data[
|
|
593
|
+
} else if (operation === MexUpdatesOperations.GROUP_LIMIT_SHARING) {
|
|
594
|
+
contentPath = content.data[XWAPathsMexUpdates.GROUP_SHARING_CHANGE]
|
|
548
595
|
|
|
549
596
|
ev.emit('limit-sharing.update', {
|
|
550
597
|
id,
|
|
@@ -553,8 +600,8 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
553
600
|
trigger: contentPath.properties.limit_sharing.limit_sharing_trigger,
|
|
554
601
|
update_time: contentPath.update_time
|
|
555
602
|
})
|
|
556
|
-
} else if (operation ===
|
|
557
|
-
contentPath = content.data[
|
|
603
|
+
} else if (operation === MexUpdatesOperations.OWNER_COMMUNITY) {
|
|
604
|
+
contentPath = content.data[XWAPathsMexUpdates.COMMUNITY_OWNER_CHANGE]
|
|
558
605
|
|
|
559
606
|
ev.emit('community-owner.update', {
|
|
560
607
|
id,
|
|
@@ -565,12 +612,12 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
565
612
|
})
|
|
566
613
|
} else {
|
|
567
614
|
|
|
568
|
-
if (operation ===
|
|
615
|
+
if (operation === MexOperations.PROMOTE) {
|
|
569
616
|
action = 'promote'
|
|
570
|
-
contentPath = content.data[
|
|
617
|
+
contentPath = content.data[XWAPaths.PROMOTE]
|
|
571
618
|
} else {
|
|
572
619
|
action = 'demote'
|
|
573
|
-
contentPath = content.data[
|
|
620
|
+
contentPath = content.data[XWAPaths.DEMOTE]
|
|
574
621
|
}
|
|
575
622
|
|
|
576
623
|
ev.emit('newsletter-participants.update', {
|
|
@@ -585,13 +632,13 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
585
632
|
|
|
586
633
|
const processNotification = async (node) => {
|
|
587
634
|
const result = {}
|
|
588
|
-
const [child] =
|
|
635
|
+
const [child] = getAllBinaryNodeChildren(node)
|
|
589
636
|
const nodeType = node.attrs.type
|
|
590
|
-
const from =
|
|
637
|
+
const from = jidNormalizedUser(node.attrs.from)
|
|
591
638
|
|
|
592
639
|
switch (nodeType) {
|
|
593
640
|
case 'privacy_token':
|
|
594
|
-
const tokenList =
|
|
641
|
+
const tokenList = getBinaryNodeChildren(child, 'token')
|
|
595
642
|
for (const { attrs, content } of tokenList) {
|
|
596
643
|
const jid = attrs.jid
|
|
597
644
|
ev.emit('chats.update', [
|
|
@@ -614,38 +661,38 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
614
661
|
handleMexNotification(node.attrs.from, child, result)
|
|
615
662
|
break
|
|
616
663
|
case 'mediaretry':
|
|
617
|
-
const event =
|
|
664
|
+
const event = decodeMediaRetryNode(node)
|
|
618
665
|
ev.emit('messages.media-update', [event])
|
|
619
666
|
break
|
|
620
667
|
case 'encrypt':
|
|
621
668
|
await handleEncryptNotification(node)
|
|
622
669
|
break
|
|
623
670
|
case 'devices':
|
|
624
|
-
const devices =
|
|
625
|
-
if (
|
|
626
|
-
|
|
671
|
+
const devices = getBinaryNodeChildren(child, 'device')
|
|
672
|
+
if (areJidsSameUser(child.attrs.jid, authState.creds.me.id) ||
|
|
673
|
+
areJidsSameUser(child.attrs.lid, authState.creds.me.lid)) {
|
|
627
674
|
const deviceData = devices.map(d => ({ id: d.attrs.jid, lid: d.attrs.lid }))
|
|
628
675
|
logger.info({ deviceData }, 'my own devices changed')
|
|
629
676
|
}
|
|
630
677
|
//TODO: drop a new event, add hashes
|
|
631
678
|
break
|
|
632
679
|
case 'server_sync':
|
|
633
|
-
const update =
|
|
680
|
+
const update = getBinaryNodeChild(node, 'collection')
|
|
634
681
|
if (update) {
|
|
635
682
|
const name = update.attrs.name
|
|
636
683
|
await resyncAppState([name], false)
|
|
637
684
|
}
|
|
638
685
|
break
|
|
639
686
|
case 'picture':
|
|
640
|
-
const setPicture =
|
|
641
|
-
const delPicture =
|
|
687
|
+
const setPicture = getBinaryNodeChild(node, 'set')
|
|
688
|
+
const delPicture = getBinaryNodeChild(node, 'delete')
|
|
642
689
|
ev.emit('contacts.update', [{
|
|
643
|
-
id:
|
|
690
|
+
id: jidNormalizedUser(node?.attrs?.from) || (setPicture || delPicture)?.attrs?.hash || '',
|
|
644
691
|
imgUrl: setPicture ? 'changed' : 'removed'
|
|
645
692
|
}])
|
|
646
|
-
if (
|
|
693
|
+
if (isJidGroup(from)) {
|
|
647
694
|
const node = setPicture || delPicture
|
|
648
|
-
result.messageStubType =
|
|
695
|
+
result.messageStubType = WAMessageStubType.GROUP_CHANGE_ICON
|
|
649
696
|
if (setPicture) {
|
|
650
697
|
result.messageStubParameters = [setPicture.attrs.id]
|
|
651
698
|
}
|
|
@@ -672,7 +719,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
672
719
|
})
|
|
673
720
|
}
|
|
674
721
|
else if (child.tag === 'blocklist') {
|
|
675
|
-
const blocklists =
|
|
722
|
+
const blocklists = getBinaryNodeChildren(child, 'item')
|
|
676
723
|
for (const { attrs } of blocklists) {
|
|
677
724
|
const blocklist = [attrs.jid]
|
|
678
725
|
const type = (attrs.action === 'block') ? 'add' : 'remove'
|
|
@@ -681,33 +728,33 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
681
728
|
}
|
|
682
729
|
break
|
|
683
730
|
case 'link_code_companion_reg':
|
|
684
|
-
const linkCodeCompanionReg =
|
|
685
|
-
const ref = toRequiredBuffer(
|
|
686
|
-
const primaryIdentityPublicKey = toRequiredBuffer(
|
|
687
|
-
const primaryEphemeralPublicKeyWrapped = toRequiredBuffer(
|
|
731
|
+
const linkCodeCompanionReg = getBinaryNodeChild(node, 'link_code_companion_reg')
|
|
732
|
+
const ref = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'link_code_pairing_ref'))
|
|
733
|
+
const primaryIdentityPublicKey = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'primary_identity_pub'))
|
|
734
|
+
const primaryEphemeralPublicKeyWrapped = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'link_code_pairing_wrapped_primary_ephemeral_pub'))
|
|
688
735
|
const codePairingPublicKey = await decipherLinkPublicKey(primaryEphemeralPublicKeyWrapped)
|
|
689
|
-
const companionSharedKey =
|
|
690
|
-
const random =
|
|
691
|
-
const linkCodeSalt =
|
|
736
|
+
const companionSharedKey = Curve.sharedKey(authState.creds.pairingEphemeralKeyPair.private, codePairingPublicKey)
|
|
737
|
+
const random = randomBytes(32)
|
|
738
|
+
const linkCodeSalt = randomBytes(32)
|
|
692
739
|
|
|
693
|
-
const linkCodePairingExpanded = await
|
|
740
|
+
const linkCodePairingExpanded = await hkdf(companionSharedKey, 32, {
|
|
694
741
|
salt: linkCodeSalt,
|
|
695
742
|
info: 'link_code_pairing_key_bundle_encryption_key'
|
|
696
743
|
})
|
|
697
744
|
|
|
698
745
|
const encryptPayload = Buffer.concat([Buffer.from(authState.creds.signedIdentityKey.public), primaryIdentityPublicKey, random])
|
|
699
|
-
const encryptIv =
|
|
700
|
-
const encrypted =
|
|
746
|
+
const encryptIv = randomBytes(12)
|
|
747
|
+
const encrypted = aesEncryptGCM(encryptPayload, linkCodePairingExpanded, encryptIv, Buffer.alloc(0))
|
|
701
748
|
const encryptedPayload = Buffer.concat([linkCodeSalt, encryptIv, encrypted])
|
|
702
|
-
const identitySharedKey =
|
|
749
|
+
const identitySharedKey = Curve.sharedKey(authState.creds.signedIdentityKey.private, primaryIdentityPublicKey)
|
|
703
750
|
const identityPayload = Buffer.concat([companionSharedKey, identitySharedKey, random])
|
|
704
751
|
|
|
705
|
-
authState.creds.advSecretKey = (await
|
|
752
|
+
authState.creds.advSecretKey = (await hkdf(identityPayload, 32, { info: 'adv_secret' })).toString('base64')
|
|
706
753
|
|
|
707
754
|
await query({
|
|
708
755
|
tag: 'iq',
|
|
709
756
|
attrs: {
|
|
710
|
-
to:
|
|
757
|
+
to: S_WHATSAPP_NET,
|
|
711
758
|
type: 'set',
|
|
712
759
|
id: suki.generateMessageTag(),
|
|
713
760
|
xmlns: 'md'
|
|
@@ -752,15 +799,15 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
752
799
|
async function decipherLinkPublicKey(data) {
|
|
753
800
|
const buffer = toRequiredBuffer(data)
|
|
754
801
|
const salt = buffer.slice(0, 32)
|
|
755
|
-
const secretKey = await
|
|
802
|
+
const secretKey = await derivePairingCodeKey(authState.creds.pairingCode, salt)
|
|
756
803
|
const iv = buffer.slice(32, 48)
|
|
757
804
|
const payload = buffer.slice(48, 80)
|
|
758
|
-
return
|
|
805
|
+
return aesDecryptCTR(payload, secretKey, iv)
|
|
759
806
|
}
|
|
760
807
|
|
|
761
808
|
function toRequiredBuffer(data) {
|
|
762
809
|
if (data === undefined) {
|
|
763
|
-
throw new
|
|
810
|
+
throw new Boom('Invalid buffer', { statusCode: 400 })
|
|
764
811
|
}
|
|
765
812
|
return data instanceof Buffer ? data : Buffer.from(data)
|
|
766
813
|
}
|
|
@@ -818,7 +865,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
818
865
|
// if it's the primary jid sending the request
|
|
819
866
|
// just re-send the message to everyone
|
|
820
867
|
// prevents the first message decryption failure
|
|
821
|
-
const sendToAll = !
|
|
868
|
+
const sendToAll = !jidDecode(participant)?.device
|
|
822
869
|
|
|
823
870
|
// Check if we should recreate session for this retry
|
|
824
871
|
let shouldRecreateSession = false
|
|
@@ -845,7 +892,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
845
892
|
|
|
846
893
|
await assertSessions([participant], shouldRecreateSession)
|
|
847
894
|
|
|
848
|
-
if (
|
|
895
|
+
if (isJidGroup(remoteJid)) {
|
|
849
896
|
await authState.keys.set({ 'sender-key-memory': { [remoteJid]: null } });
|
|
850
897
|
}
|
|
851
898
|
logger.debug({ participant, sendToAll, shouldRecreateSession, recreateReason }, 'forced new session for retry recp')
|
|
@@ -878,8 +925,8 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
878
925
|
const handleReceipt = async (node) => {
|
|
879
926
|
const { attrs, content } = node
|
|
880
927
|
const isLid = attrs.from.includes('lid')
|
|
881
|
-
const isNodeFromMe =
|
|
882
|
-
const remoteJid = !isNodeFromMe ||
|
|
928
|
+
const isNodeFromMe = areJidsSameUser(attrs.participant || attrs.from, isLid ? authState.creds.me?.lid : authState.creds.me?.id)
|
|
929
|
+
const remoteJid = !isNodeFromMe || isJidGroup(attrs.from) ? attrs.from : attrs.recipient
|
|
883
930
|
const fromMe = !attrs.recipient || ((attrs.type === 'retry' || attrs.type === 'sender') && isNodeFromMe)
|
|
884
931
|
|
|
885
932
|
const key = {
|
|
@@ -897,27 +944,27 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
897
944
|
|
|
898
945
|
const ids = [attrs.id]
|
|
899
946
|
if (Array.isArray(content)) {
|
|
900
|
-
const items =
|
|
947
|
+
const items = getBinaryNodeChildren(content[0], 'item')
|
|
901
948
|
ids.push(...items.map(i => i.attrs.id))
|
|
902
949
|
}
|
|
903
950
|
|
|
904
951
|
try {
|
|
905
952
|
await Promise.all([
|
|
906
953
|
processingMutex.mutex(async () => {
|
|
907
|
-
const status =
|
|
954
|
+
const status = getStatusFromReceiptType(attrs.type)
|
|
908
955
|
|
|
909
956
|
if (typeof status !== 'undefined' && (
|
|
910
957
|
// basically, we only want to know when a message from us has been delivered to/read by the other person
|
|
911
958
|
// or another device of ours has read some messages
|
|
912
|
-
status >=
|
|
959
|
+
status >= proto.WebMessageInfo.Status.SERVER_ACK ||
|
|
913
960
|
!isNodeFromMe)) {
|
|
914
|
-
if (
|
|
961
|
+
if (isJidGroup(remoteJid) || isJidStatusBroadcast(remoteJid)) {
|
|
915
962
|
if (attrs.participant) {
|
|
916
|
-
const updateKey = status ===
|
|
963
|
+
const updateKey = status === proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp'
|
|
917
964
|
ev.emit('message-receipt.update', ids.map(id => ({
|
|
918
965
|
key: { ...key, id },
|
|
919
966
|
receipt: {
|
|
920
|
-
userJid:
|
|
967
|
+
userJid: jidNormalizedUser(attrs.participant),
|
|
921
968
|
[updateKey]: +attrs.t
|
|
922
969
|
}
|
|
923
970
|
})))
|
|
@@ -935,7 +982,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
935
982
|
if (attrs.type === 'retry') {
|
|
936
983
|
// correctly set who is asking for the retry
|
|
937
984
|
key.participant = key.participant || attrs.from
|
|
938
|
-
const retryNode =
|
|
985
|
+
const retryNode = getBinaryNodeChild(node, 'retry')
|
|
939
986
|
|
|
940
987
|
if (ids[0] && key.participant && (await willSendMessageAgain(ids[0], key.participant))) {
|
|
941
988
|
if (key.fromMe) {
|
|
@@ -982,7 +1029,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
982
1029
|
const msg = await processNotification(node)
|
|
983
1030
|
|
|
984
1031
|
if (msg) {
|
|
985
|
-
const fromMe =
|
|
1032
|
+
const fromMe = areJidsSameUser(node.attrs.participant || remoteJid, authState.creds.me.id)
|
|
986
1033
|
msg.key = {
|
|
987
1034
|
remoteJid,
|
|
988
1035
|
fromMe,
|
|
@@ -992,7 +1039,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
992
1039
|
}
|
|
993
1040
|
msg.participant = msg.participant ? msg.participant : node.attrs.participant
|
|
994
1041
|
msg.messageTimestamp = +node.attrs.t
|
|
995
|
-
const fullMsg =
|
|
1042
|
+
const fullMsg = proto.WebMessageInfo.fromObject(msg)
|
|
996
1043
|
await upsertMessage(fullMsg, 'append')
|
|
997
1044
|
}
|
|
998
1045
|
})
|
|
@@ -1012,18 +1059,18 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1012
1059
|
|
|
1013
1060
|
let response
|
|
1014
1061
|
|
|
1015
|
-
const encNode =
|
|
1062
|
+
const encNode = getBinaryNodeChild(node, 'enc')
|
|
1016
1063
|
|
|
1017
1064
|
// TODO: temporary fix for crashes and issues resulting of failed msmsg decryption
|
|
1018
1065
|
if (encNode && encNode.attrs.type === 'msmsg') {
|
|
1019
1066
|
logger.debug({ key: node.attrs.key }, 'ignored msmsg')
|
|
1020
|
-
await sendMessageAck(node,
|
|
1067
|
+
await sendMessageAck(node, NACK_REASONS.MissingMessageSecret)
|
|
1021
1068
|
return
|
|
1022
1069
|
}
|
|
1023
1070
|
|
|
1024
|
-
if (
|
|
1071
|
+
if (getBinaryNodeChild(node, 'unavailable') && !encNode) {
|
|
1025
1072
|
await sendMessageAck(node)
|
|
1026
|
-
const { key } =
|
|
1073
|
+
const { key } = decodeMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '').fullMessage
|
|
1027
1074
|
response = await requestPlaceholderResend(key);
|
|
1028
1075
|
if (response === 'RESOLVED') {
|
|
1029
1076
|
return
|
|
@@ -1036,15 +1083,15 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1036
1083
|
}
|
|
1037
1084
|
}
|
|
1038
1085
|
|
|
1039
|
-
const { fullMessage: msg, category, author, decrypt } =
|
|
1086
|
+
const { fullMessage: msg, category, author, decrypt } = decryptMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger)
|
|
1040
1087
|
|
|
1041
|
-
if (response && msg?.messageStubParameters?.[0] ===
|
|
1042
|
-
msg.messageStubParameters = [
|
|
1088
|
+
if (response && msg?.messageStubParameters?.[0] === NO_MESSAGE_FOUND_ERROR_TEXT) {
|
|
1089
|
+
msg.messageStubParameters = [NO_MESSAGE_FOUND_ERROR_TEXT, response]
|
|
1043
1090
|
}
|
|
1044
1091
|
|
|
1045
|
-
if (msg.message?.protocolMessage?.type ===
|
|
1092
|
+
if (msg.message?.protocolMessage?.type === proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER &&
|
|
1046
1093
|
node.attrs.sender_pn) {
|
|
1047
|
-
const lid =
|
|
1094
|
+
const lid = jidNormalizedUser(node.attrs.from), pn = jidNormalizedUser(node.attrs.sender_pn)
|
|
1048
1095
|
ev.emit('lid-mapping.update', { lid, pn })
|
|
1049
1096
|
await signalRepository.lidMapping.storeLIDPNMappings([{ lid, pn }])
|
|
1050
1097
|
}
|
|
@@ -1053,7 +1100,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1053
1100
|
|
|
1054
1101
|
// store new mappings we didn't have before
|
|
1055
1102
|
if (!!alt) {
|
|
1056
|
-
const altServer =
|
|
1103
|
+
const altServer = jidDecode(alt)?.server
|
|
1057
1104
|
|
|
1058
1105
|
if (altServer === 'lid') {
|
|
1059
1106
|
if (typeof (await signalRepository.lidMapping.getPNForLID(alt)) === 'string') {
|
|
@@ -1084,9 +1131,9 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1084
1131
|
processingMutex.mutex(async () => {
|
|
1085
1132
|
await decrypt()
|
|
1086
1133
|
// message failed to decrypt
|
|
1087
|
-
if (msg.messageStubType ===
|
|
1088
|
-
if (msg?.messageStubParameters?.[0] ===
|
|
1089
|
-
return sendMessageAck(node,
|
|
1134
|
+
if (msg.messageStubType === proto.WebMessageInfo.StubType.CIPHERTEXT) {
|
|
1135
|
+
if (msg?.messageStubParameters?.[0] === MISSING_KEYS_ERROR_TEXT) {
|
|
1136
|
+
return sendMessageAck(node, NACK_REASONS.ParsingError)
|
|
1090
1137
|
}
|
|
1091
1138
|
|
|
1092
1139
|
const errorMessage = msg?.messageStubParameters?.[0] || ''
|
|
@@ -1101,7 +1148,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1101
1148
|
return
|
|
1102
1149
|
}
|
|
1103
1150
|
|
|
1104
|
-
if (
|
|
1151
|
+
if (getBinaryNodeChild(node, 'unavailable')) {
|
|
1105
1152
|
logger.debug('Message unavailable, skipping retry')
|
|
1106
1153
|
return
|
|
1107
1154
|
}
|
|
@@ -1113,24 +1160,24 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1113
1160
|
logger.debug('Uploading pre-keys for error recovery')
|
|
1114
1161
|
await uploadPreKeys(5)
|
|
1115
1162
|
logger.debug('Waiting for server to process new pre-keys')
|
|
1116
|
-
await
|
|
1163
|
+
await delay(1000)
|
|
1117
1164
|
}
|
|
1118
1165
|
catch (uploadErr) {
|
|
1119
1166
|
logger.error({ uploadErr }, 'Pre-key upload failed, proceeding with retry anyway')
|
|
1120
1167
|
}
|
|
1121
1168
|
}
|
|
1122
1169
|
|
|
1123
|
-
const encNode =
|
|
1170
|
+
const encNode = getBinaryNodeChild(node, 'enc')
|
|
1124
1171
|
await sendRetryRequest(node, !encNode)
|
|
1125
1172
|
if (retryRequestDelayMs) {
|
|
1126
|
-
await
|
|
1173
|
+
await delay(retryRequestDelayMs)
|
|
1127
1174
|
}
|
|
1128
1175
|
}
|
|
1129
1176
|
catch (err) {
|
|
1130
1177
|
logger.error({ err, isPreKeyError }, 'Failed to handle retry, attempting basic retry')
|
|
1131
1178
|
// Still attempt retry even if pre-key upload failed
|
|
1132
1179
|
try {
|
|
1133
|
-
const encNode =
|
|
1180
|
+
const encNode = getBinaryNodeChild(node, 'enc')
|
|
1134
1181
|
await sendRetryRequest(node, !encNode)
|
|
1135
1182
|
}
|
|
1136
1183
|
catch (retryErr) {
|
|
@@ -1156,7 +1203,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1156
1203
|
type = 'sender'
|
|
1157
1204
|
|
|
1158
1205
|
// need to specially handle this case
|
|
1159
|
-
if (
|
|
1206
|
+
if (isLidUser(msg.key.remoteJid) || isLidUser(msg.key.remoteJidAlt)) {
|
|
1160
1207
|
participant = author // TODO: investigate sending receipts to LIDs and not PNs
|
|
1161
1208
|
}
|
|
1162
1209
|
}
|
|
@@ -1167,13 +1214,13 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1167
1214
|
await sendReceipt(msg.key.remoteJid, participant, [msg.key.id], type)
|
|
1168
1215
|
|
|
1169
1216
|
// send ack for history message
|
|
1170
|
-
const isAnyHistoryMsg =
|
|
1217
|
+
const isAnyHistoryMsg = getHistoryMsg(msg.message)
|
|
1171
1218
|
if (isAnyHistoryMsg) {
|
|
1172
|
-
const jid =
|
|
1219
|
+
const jid = jidNormalizedUser(msg.key.remoteJid)
|
|
1173
1220
|
await sendReceipt(jid, undefined, [msg.key.id], 'hist_sync')
|
|
1174
1221
|
}
|
|
1175
1222
|
}
|
|
1176
|
-
|
|
1223
|
+
cleanMessage(msg, authState.creds.me.id)
|
|
1177
1224
|
await sendMessageAck(node)
|
|
1178
1225
|
await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify')
|
|
1179
1226
|
})
|
|
@@ -1187,7 +1234,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1187
1234
|
|
|
1188
1235
|
const fetchMessageHistory = async (count, oldestMsgKey, oldestMsgTimestamp) => {
|
|
1189
1236
|
if (!authState.creds.me?.id) {
|
|
1190
|
-
throw new
|
|
1237
|
+
throw new Boom('Not authenticated')
|
|
1191
1238
|
}
|
|
1192
1239
|
|
|
1193
1240
|
const pdoMessage = {
|
|
@@ -1198,7 +1245,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1198
1245
|
oldestMsgTimestampMs: oldestMsgTimestamp,
|
|
1199
1246
|
onDemandMsgCount: count
|
|
1200
1247
|
},
|
|
1201
|
-
peerDataOperationRequestType:
|
|
1248
|
+
peerDataOperationRequestType: proto.Message.PeerDataOperationRequestType.HISTORY_SYNC_ON_DEMAND
|
|
1202
1249
|
}
|
|
1203
1250
|
|
|
1204
1251
|
return sendPeerDataOperationMessage(pdoMessage)
|
|
@@ -1206,7 +1253,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1206
1253
|
|
|
1207
1254
|
const requestPlaceholderResend = async (messageKey) => {
|
|
1208
1255
|
if (!authState.creds.me?.id) {
|
|
1209
|
-
throw new
|
|
1256
|
+
throw new Boom('Not authenticated')
|
|
1210
1257
|
}
|
|
1211
1258
|
|
|
1212
1259
|
if (placeholderResendCache.get(messageKey?.id)) {
|
|
@@ -1218,7 +1265,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1218
1265
|
placeholderResendCache.set(messageKey?.id, true)
|
|
1219
1266
|
}
|
|
1220
1267
|
|
|
1221
|
-
await
|
|
1268
|
+
await delay(5000)
|
|
1222
1269
|
|
|
1223
1270
|
if (!placeholderResendCache.get(messageKey?.id)) {
|
|
1224
1271
|
logger.debug({ messageKey }, 'message received while resend requested')
|
|
@@ -1229,7 +1276,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1229
1276
|
placeholderMessageResendRequest: [{
|
|
1230
1277
|
messageKey
|
|
1231
1278
|
}],
|
|
1232
|
-
peerDataOperationRequestType:
|
|
1279
|
+
peerDataOperationRequestType: proto.Message.PeerDataOperationRequestType.PLACEHOLDER_MESSAGE_RESEND
|
|
1233
1280
|
}
|
|
1234
1281
|
|
|
1235
1282
|
setTimeout(() => {
|
|
@@ -1246,12 +1293,12 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1246
1293
|
let status
|
|
1247
1294
|
|
|
1248
1295
|
const { attrs } = node
|
|
1249
|
-
const [infoChild] =
|
|
1296
|
+
const [infoChild] = getAllBinaryNodeChildren(node)
|
|
1250
1297
|
const callId = infoChild.attrs['call-id']
|
|
1251
1298
|
const from = infoChild.attrs.from || infoChild.attrs['call-creator']
|
|
1252
|
-
status =
|
|
1299
|
+
status = getCallStatusFromNode(infoChild)
|
|
1253
1300
|
|
|
1254
|
-
if (
|
|
1301
|
+
if (isLidUser(from) && infoChild.tag === 'relaylatency') {
|
|
1255
1302
|
const verify = await callOfferCache.get(callId)
|
|
1256
1303
|
|
|
1257
1304
|
if (!verify) {
|
|
@@ -1279,7 +1326,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1279
1326
|
}
|
|
1280
1327
|
|
|
1281
1328
|
if (status === 'offer') {
|
|
1282
|
-
call.isVideo = !!
|
|
1329
|
+
call.isVideo = !!getBinaryNodeChild(infoChild, 'video')
|
|
1283
1330
|
call.isGroup = infoChild.attrs.type === 'group' || !!infoChild.attrs['group-jid']
|
|
1284
1331
|
call.groupJid = infoChild.attrs['group-jid']
|
|
1285
1332
|
await callOfferCache.set(call.id, call)
|
|
@@ -1326,7 +1373,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1326
1373
|
{
|
|
1327
1374
|
key,
|
|
1328
1375
|
update: {
|
|
1329
|
-
status:
|
|
1376
|
+
status: WAMessageStatus.ERROR,
|
|
1330
1377
|
messageStubParameters: [
|
|
1331
1378
|
attrs.error
|
|
1332
1379
|
]
|
|
@@ -1426,16 +1473,16 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1426
1473
|
id: call.id,
|
|
1427
1474
|
fromMe: false
|
|
1428
1475
|
},
|
|
1429
|
-
messageTimestamp:
|
|
1476
|
+
messageTimestamp: unixTimestampSeconds(call.date),
|
|
1430
1477
|
}
|
|
1431
1478
|
|
|
1432
1479
|
if (call.status === 'timeout') {
|
|
1433
1480
|
if (call.isGroup) {
|
|
1434
|
-
msg.messageStubType = call.isVideo ?
|
|
1481
|
+
msg.messageStubType = call.isVideo ? WAMessageStubType.CALL_MISSED_GROUP_VIDEO : WAMessageStubType.CALL_MISSED_GROUP_VOICE
|
|
1435
1482
|
}
|
|
1436
1483
|
|
|
1437
1484
|
else {
|
|
1438
|
-
msg.messageStubType = call.isVideo ?
|
|
1485
|
+
msg.messageStubType = call.isVideo ? WAMessageStubType.CALL_MISSED_VIDEO : WAMessageStubType.CALL_MISSED_VOICE
|
|
1439
1486
|
}
|
|
1440
1487
|
}
|
|
1441
1488
|
|
|
@@ -1443,7 +1490,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1443
1490
|
msg.message = { call: { callKey: Buffer.from(call.id) } }
|
|
1444
1491
|
}
|
|
1445
1492
|
|
|
1446
|
-
const protoMsg =
|
|
1493
|
+
const protoMsg = proto.WebMessageInfo.fromObject(msg)
|
|
1447
1494
|
upsertMessage(protoMsg, call.offline ? 'append' : 'notify')
|
|
1448
1495
|
}
|
|
1449
1496
|
})
|