vialeys 0.0.1 → 0.0.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 +11 -5
- package/WAProto/AICommon/AICommon.js +13991 -9169
- package/WAProto/AICommon/AICommon.proto +110 -3
- package/WAProto/CompanionReg/CompanionReg.js +114 -0
- package/WAProto/CompanionReg/CompanionReg.proto +3 -0
- package/WAProto/DeviceCapabilities/DeviceCapabilities.js +652 -0
- package/WAProto/DeviceCapabilities/DeviceCapabilities.proto +19 -0
- package/WAProto/E2E/E2E.js +77193 -51248
- package/WAProto/E2E/E2E.proto +68 -12
- package/WAProto/HistorySync/HistorySync.js +3375 -178
- package/WAProto/HistorySync/HistorySync.proto +3 -3
- package/WAProto/LidMigrationSyncPayload/LidMigrationSyncPayload.js +98 -49
- package/WAProto/LidMigrationSyncPayload/LidMigrationSyncPayload.proto +2 -2
- package/WAProto/MdStorageMsgRowOpaqueData/MdStorageMsgRowOpaqueData.js +75226 -48422
- package/WAProto/MdStorageMsgRowOpaqueData/MdStorageMsgRowOpaqueData.proto +6 -0
- package/WAProto/StatusAttributions/StatusAttributions.js +21 -0
- package/WAProto/StatusAttributions/StatusAttributions.proto +3 -0
- package/WAProto/SyncAction/SyncAction.js +9423 -2023
- package/WAProto/SyncAction/SyncAction.proto +208 -15
- package/WAProto/Wa6/Wa6.js +83 -0
- package/WAProto/Wa6/Wa6.proto +3 -0
- package/WAProto/Web/Web.js +92664 -63403
- package/WAProto/Web/Web.proto +31 -13
- package/engine-requirements.js +9 -7
- package/lib/Defaults/baileys-version.json +2 -2
- 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-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 +226 -171
- 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 -4
- 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 +103 -73
- 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 +370 -136
- 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 +62 -37
- package/package.json +1 -1
- package/WAProto/index.d.ts +0 -55
- 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,15 +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]
|
|
587
|
+
|
|
588
|
+
ev.emit('groups.update', [{
|
|
589
|
+
id,
|
|
590
|
+
author: contentPath.updated_by.id,
|
|
591
|
+
member_link_mode: contentPath.properties.member_link_mode
|
|
592
|
+
}])
|
|
593
|
+
} else if (operation === MexUpdatesOperations.GROUP_LIMIT_SHARING) {
|
|
594
|
+
contentPath = content.data[XWAPathsMexUpdates.GROUP_SHARING_CHANGE]
|
|
540
595
|
|
|
541
596
|
ev.emit('limit-sharing.update', {
|
|
542
597
|
id,
|
|
@@ -545,8 +600,8 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
545
600
|
trigger: contentPath.properties.limit_sharing.limit_sharing_trigger,
|
|
546
601
|
update_time: contentPath.update_time
|
|
547
602
|
})
|
|
548
|
-
} else if (operation ===
|
|
549
|
-
contentPath = content.data[
|
|
603
|
+
} else if (operation === MexUpdatesOperations.OWNER_COMMUNITY) {
|
|
604
|
+
contentPath = content.data[XWAPathsMexUpdates.COMMUNITY_OWNER_CHANGE]
|
|
550
605
|
|
|
551
606
|
ev.emit('community-owner.update', {
|
|
552
607
|
id,
|
|
@@ -557,12 +612,12 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
557
612
|
})
|
|
558
613
|
} else {
|
|
559
614
|
|
|
560
|
-
if (operation ===
|
|
615
|
+
if (operation === MexOperations.PROMOTE) {
|
|
561
616
|
action = 'promote'
|
|
562
|
-
contentPath = content.data[
|
|
617
|
+
contentPath = content.data[XWAPaths.PROMOTE]
|
|
563
618
|
} else {
|
|
564
619
|
action = 'demote'
|
|
565
|
-
contentPath = content.data[
|
|
620
|
+
contentPath = content.data[XWAPaths.DEMOTE]
|
|
566
621
|
}
|
|
567
622
|
|
|
568
623
|
ev.emit('newsletter-participants.update', {
|
|
@@ -577,13 +632,13 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
577
632
|
|
|
578
633
|
const processNotification = async (node) => {
|
|
579
634
|
const result = {}
|
|
580
|
-
const [child] =
|
|
635
|
+
const [child] = getAllBinaryNodeChildren(node)
|
|
581
636
|
const nodeType = node.attrs.type
|
|
582
|
-
const from =
|
|
637
|
+
const from = jidNormalizedUser(node.attrs.from)
|
|
583
638
|
|
|
584
639
|
switch (nodeType) {
|
|
585
640
|
case 'privacy_token':
|
|
586
|
-
const tokenList =
|
|
641
|
+
const tokenList = getBinaryNodeChildren(child, 'token')
|
|
587
642
|
for (const { attrs, content } of tokenList) {
|
|
588
643
|
const jid = attrs.jid
|
|
589
644
|
ev.emit('chats.update', [
|
|
@@ -603,41 +658,41 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
603
658
|
handleNewsletterNotification(node.attrs.from, child)
|
|
604
659
|
break
|
|
605
660
|
case 'mex':
|
|
606
|
-
handleMexNotification(node.attrs.from, child)
|
|
661
|
+
handleMexNotification(node.attrs.from, child, result)
|
|
607
662
|
break
|
|
608
663
|
case 'mediaretry':
|
|
609
|
-
const event =
|
|
664
|
+
const event = decodeMediaRetryNode(node)
|
|
610
665
|
ev.emit('messages.media-update', [event])
|
|
611
666
|
break
|
|
612
667
|
case 'encrypt':
|
|
613
668
|
await handleEncryptNotification(node)
|
|
614
669
|
break
|
|
615
670
|
case 'devices':
|
|
616
|
-
const devices =
|
|
617
|
-
if (
|
|
618
|
-
|
|
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)) {
|
|
619
674
|
const deviceData = devices.map(d => ({ id: d.attrs.jid, lid: d.attrs.lid }))
|
|
620
675
|
logger.info({ deviceData }, 'my own devices changed')
|
|
621
676
|
}
|
|
622
677
|
//TODO: drop a new event, add hashes
|
|
623
678
|
break
|
|
624
679
|
case 'server_sync':
|
|
625
|
-
const update =
|
|
680
|
+
const update = getBinaryNodeChild(node, 'collection')
|
|
626
681
|
if (update) {
|
|
627
682
|
const name = update.attrs.name
|
|
628
683
|
await resyncAppState([name], false)
|
|
629
684
|
}
|
|
630
685
|
break
|
|
631
686
|
case 'picture':
|
|
632
|
-
const setPicture =
|
|
633
|
-
const delPicture =
|
|
687
|
+
const setPicture = getBinaryNodeChild(node, 'set')
|
|
688
|
+
const delPicture = getBinaryNodeChild(node, 'delete')
|
|
634
689
|
ev.emit('contacts.update', [{
|
|
635
|
-
id:
|
|
690
|
+
id: jidNormalizedUser(node?.attrs?.from) || (setPicture || delPicture)?.attrs?.hash || '',
|
|
636
691
|
imgUrl: setPicture ? 'changed' : 'removed'
|
|
637
692
|
}])
|
|
638
|
-
if (
|
|
693
|
+
if (isJidGroup(from)) {
|
|
639
694
|
const node = setPicture || delPicture
|
|
640
|
-
result.messageStubType =
|
|
695
|
+
result.messageStubType = WAMessageStubType.GROUP_CHANGE_ICON
|
|
641
696
|
if (setPicture) {
|
|
642
697
|
result.messageStubParameters = [setPicture.attrs.id]
|
|
643
698
|
}
|
|
@@ -664,7 +719,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
664
719
|
})
|
|
665
720
|
}
|
|
666
721
|
else if (child.tag === 'blocklist') {
|
|
667
|
-
const blocklists =
|
|
722
|
+
const blocklists = getBinaryNodeChildren(child, 'item')
|
|
668
723
|
for (const { attrs } of blocklists) {
|
|
669
724
|
const blocklist = [attrs.jid]
|
|
670
725
|
const type = (attrs.action === 'block') ? 'add' : 'remove'
|
|
@@ -673,33 +728,33 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
673
728
|
}
|
|
674
729
|
break
|
|
675
730
|
case 'link_code_companion_reg':
|
|
676
|
-
const linkCodeCompanionReg =
|
|
677
|
-
const ref = toRequiredBuffer(
|
|
678
|
-
const primaryIdentityPublicKey = toRequiredBuffer(
|
|
679
|
-
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'))
|
|
680
735
|
const codePairingPublicKey = await decipherLinkPublicKey(primaryEphemeralPublicKeyWrapped)
|
|
681
|
-
const companionSharedKey =
|
|
682
|
-
const random =
|
|
683
|
-
const linkCodeSalt =
|
|
736
|
+
const companionSharedKey = Curve.sharedKey(authState.creds.pairingEphemeralKeyPair.private, codePairingPublicKey)
|
|
737
|
+
const random = randomBytes(32)
|
|
738
|
+
const linkCodeSalt = randomBytes(32)
|
|
684
739
|
|
|
685
|
-
const linkCodePairingExpanded = await
|
|
740
|
+
const linkCodePairingExpanded = await hkdf(companionSharedKey, 32, {
|
|
686
741
|
salt: linkCodeSalt,
|
|
687
742
|
info: 'link_code_pairing_key_bundle_encryption_key'
|
|
688
743
|
})
|
|
689
744
|
|
|
690
745
|
const encryptPayload = Buffer.concat([Buffer.from(authState.creds.signedIdentityKey.public), primaryIdentityPublicKey, random])
|
|
691
|
-
const encryptIv =
|
|
692
|
-
const encrypted =
|
|
746
|
+
const encryptIv = randomBytes(12)
|
|
747
|
+
const encrypted = aesEncryptGCM(encryptPayload, linkCodePairingExpanded, encryptIv, Buffer.alloc(0))
|
|
693
748
|
const encryptedPayload = Buffer.concat([linkCodeSalt, encryptIv, encrypted])
|
|
694
|
-
const identitySharedKey =
|
|
749
|
+
const identitySharedKey = Curve.sharedKey(authState.creds.signedIdentityKey.private, primaryIdentityPublicKey)
|
|
695
750
|
const identityPayload = Buffer.concat([companionSharedKey, identitySharedKey, random])
|
|
696
751
|
|
|
697
|
-
authState.creds.advSecretKey = (await
|
|
752
|
+
authState.creds.advSecretKey = (await hkdf(identityPayload, 32, { info: 'adv_secret' })).toString('base64')
|
|
698
753
|
|
|
699
754
|
await query({
|
|
700
755
|
tag: 'iq',
|
|
701
756
|
attrs: {
|
|
702
|
-
to:
|
|
757
|
+
to: S_WHATSAPP_NET,
|
|
703
758
|
type: 'set',
|
|
704
759
|
id: suki.generateMessageTag(),
|
|
705
760
|
xmlns: 'md'
|
|
@@ -744,15 +799,15 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
744
799
|
async function decipherLinkPublicKey(data) {
|
|
745
800
|
const buffer = toRequiredBuffer(data)
|
|
746
801
|
const salt = buffer.slice(0, 32)
|
|
747
|
-
const secretKey = await
|
|
802
|
+
const secretKey = await derivePairingCodeKey(authState.creds.pairingCode, salt)
|
|
748
803
|
const iv = buffer.slice(32, 48)
|
|
749
804
|
const payload = buffer.slice(48, 80)
|
|
750
|
-
return
|
|
805
|
+
return aesDecryptCTR(payload, secretKey, iv)
|
|
751
806
|
}
|
|
752
807
|
|
|
753
808
|
function toRequiredBuffer(data) {
|
|
754
809
|
if (data === undefined) {
|
|
755
|
-
throw new
|
|
810
|
+
throw new Boom('Invalid buffer', { statusCode: 400 })
|
|
756
811
|
}
|
|
757
812
|
return data instanceof Buffer ? data : Buffer.from(data)
|
|
758
813
|
}
|
|
@@ -810,7 +865,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
810
865
|
// if it's the primary jid sending the request
|
|
811
866
|
// just re-send the message to everyone
|
|
812
867
|
// prevents the first message decryption failure
|
|
813
|
-
const sendToAll = !
|
|
868
|
+
const sendToAll = !jidDecode(participant)?.device
|
|
814
869
|
|
|
815
870
|
// Check if we should recreate session for this retry
|
|
816
871
|
let shouldRecreateSession = false
|
|
@@ -837,7 +892,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
837
892
|
|
|
838
893
|
await assertSessions([participant], shouldRecreateSession)
|
|
839
894
|
|
|
840
|
-
if (
|
|
895
|
+
if (isJidGroup(remoteJid)) {
|
|
841
896
|
await authState.keys.set({ 'sender-key-memory': { [remoteJid]: null } });
|
|
842
897
|
}
|
|
843
898
|
logger.debug({ participant, sendToAll, shouldRecreateSession, recreateReason }, 'forced new session for retry recp')
|
|
@@ -870,8 +925,8 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
870
925
|
const handleReceipt = async (node) => {
|
|
871
926
|
const { attrs, content } = node
|
|
872
927
|
const isLid = attrs.from.includes('lid')
|
|
873
|
-
const isNodeFromMe =
|
|
874
|
-
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
|
|
875
930
|
const fromMe = !attrs.recipient || ((attrs.type === 'retry' || attrs.type === 'sender') && isNodeFromMe)
|
|
876
931
|
|
|
877
932
|
const key = {
|
|
@@ -889,27 +944,27 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
889
944
|
|
|
890
945
|
const ids = [attrs.id]
|
|
891
946
|
if (Array.isArray(content)) {
|
|
892
|
-
const items =
|
|
947
|
+
const items = getBinaryNodeChildren(content[0], 'item')
|
|
893
948
|
ids.push(...items.map(i => i.attrs.id))
|
|
894
949
|
}
|
|
895
950
|
|
|
896
951
|
try {
|
|
897
952
|
await Promise.all([
|
|
898
953
|
processingMutex.mutex(async () => {
|
|
899
|
-
const status =
|
|
954
|
+
const status = getStatusFromReceiptType(attrs.type)
|
|
900
955
|
|
|
901
956
|
if (typeof status !== 'undefined' && (
|
|
902
957
|
// basically, we only want to know when a message from us has been delivered to/read by the other person
|
|
903
958
|
// or another device of ours has read some messages
|
|
904
|
-
status >=
|
|
959
|
+
status >= proto.WebMessageInfo.Status.SERVER_ACK ||
|
|
905
960
|
!isNodeFromMe)) {
|
|
906
|
-
if (
|
|
961
|
+
if (isJidGroup(remoteJid) || isJidStatusBroadcast(remoteJid)) {
|
|
907
962
|
if (attrs.participant) {
|
|
908
|
-
const updateKey = status ===
|
|
963
|
+
const updateKey = status === proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp'
|
|
909
964
|
ev.emit('message-receipt.update', ids.map(id => ({
|
|
910
965
|
key: { ...key, id },
|
|
911
966
|
receipt: {
|
|
912
|
-
userJid:
|
|
967
|
+
userJid: jidNormalizedUser(attrs.participant),
|
|
913
968
|
[updateKey]: +attrs.t
|
|
914
969
|
}
|
|
915
970
|
})))
|
|
@@ -927,7 +982,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
927
982
|
if (attrs.type === 'retry') {
|
|
928
983
|
// correctly set who is asking for the retry
|
|
929
984
|
key.participant = key.participant || attrs.from
|
|
930
|
-
const retryNode =
|
|
985
|
+
const retryNode = getBinaryNodeChild(node, 'retry')
|
|
931
986
|
|
|
932
987
|
if (ids[0] && key.participant && (await willSendMessageAgain(ids[0], key.participant))) {
|
|
933
988
|
if (key.fromMe) {
|
|
@@ -974,7 +1029,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
974
1029
|
const msg = await processNotification(node)
|
|
975
1030
|
|
|
976
1031
|
if (msg) {
|
|
977
|
-
const fromMe =
|
|
1032
|
+
const fromMe = areJidsSameUser(node.attrs.participant || remoteJid, authState.creds.me.id)
|
|
978
1033
|
msg.key = {
|
|
979
1034
|
remoteJid,
|
|
980
1035
|
fromMe,
|
|
@@ -984,7 +1039,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
984
1039
|
}
|
|
985
1040
|
msg.participant = msg.participant ? msg.participant : node.attrs.participant
|
|
986
1041
|
msg.messageTimestamp = +node.attrs.t
|
|
987
|
-
const fullMsg =
|
|
1042
|
+
const fullMsg = proto.WebMessageInfo.fromObject(msg)
|
|
988
1043
|
await upsertMessage(fullMsg, 'append')
|
|
989
1044
|
}
|
|
990
1045
|
})
|
|
@@ -1004,18 +1059,18 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1004
1059
|
|
|
1005
1060
|
let response
|
|
1006
1061
|
|
|
1007
|
-
const encNode =
|
|
1062
|
+
const encNode = getBinaryNodeChild(node, 'enc')
|
|
1008
1063
|
|
|
1009
1064
|
// TODO: temporary fix for crashes and issues resulting of failed msmsg decryption
|
|
1010
1065
|
if (encNode && encNode.attrs.type === 'msmsg') {
|
|
1011
1066
|
logger.debug({ key: node.attrs.key }, 'ignored msmsg')
|
|
1012
|
-
await sendMessageAck(node,
|
|
1067
|
+
await sendMessageAck(node, NACK_REASONS.MissingMessageSecret)
|
|
1013
1068
|
return
|
|
1014
1069
|
}
|
|
1015
1070
|
|
|
1016
|
-
if (
|
|
1071
|
+
if (getBinaryNodeChild(node, 'unavailable') && !encNode) {
|
|
1017
1072
|
await sendMessageAck(node)
|
|
1018
|
-
const { key } =
|
|
1073
|
+
const { key } = decodeMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '').fullMessage
|
|
1019
1074
|
response = await requestPlaceholderResend(key);
|
|
1020
1075
|
if (response === 'RESOLVED') {
|
|
1021
1076
|
return
|
|
@@ -1028,15 +1083,15 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1028
1083
|
}
|
|
1029
1084
|
}
|
|
1030
1085
|
|
|
1031
|
-
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)
|
|
1032
1087
|
|
|
1033
|
-
if (response && msg?.messageStubParameters?.[0] ===
|
|
1034
|
-
msg.messageStubParameters = [
|
|
1088
|
+
if (response && msg?.messageStubParameters?.[0] === NO_MESSAGE_FOUND_ERROR_TEXT) {
|
|
1089
|
+
msg.messageStubParameters = [NO_MESSAGE_FOUND_ERROR_TEXT, response]
|
|
1035
1090
|
}
|
|
1036
1091
|
|
|
1037
|
-
if (msg.message?.protocolMessage?.type ===
|
|
1092
|
+
if (msg.message?.protocolMessage?.type === proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER &&
|
|
1038
1093
|
node.attrs.sender_pn) {
|
|
1039
|
-
const lid =
|
|
1094
|
+
const lid = jidNormalizedUser(node.attrs.from), pn = jidNormalizedUser(node.attrs.sender_pn)
|
|
1040
1095
|
ev.emit('lid-mapping.update', { lid, pn })
|
|
1041
1096
|
await signalRepository.lidMapping.storeLIDPNMappings([{ lid, pn }])
|
|
1042
1097
|
}
|
|
@@ -1045,7 +1100,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1045
1100
|
|
|
1046
1101
|
// store new mappings we didn't have before
|
|
1047
1102
|
if (!!alt) {
|
|
1048
|
-
const altServer =
|
|
1103
|
+
const altServer = jidDecode(alt)?.server
|
|
1049
1104
|
|
|
1050
1105
|
if (altServer === 'lid') {
|
|
1051
1106
|
if (typeof (await signalRepository.lidMapping.getPNForLID(alt)) === 'string') {
|
|
@@ -1076,9 +1131,9 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1076
1131
|
processingMutex.mutex(async () => {
|
|
1077
1132
|
await decrypt()
|
|
1078
1133
|
// message failed to decrypt
|
|
1079
|
-
if (msg.messageStubType ===
|
|
1080
|
-
if (msg?.messageStubParameters?.[0] ===
|
|
1081
|
-
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)
|
|
1082
1137
|
}
|
|
1083
1138
|
|
|
1084
1139
|
const errorMessage = msg?.messageStubParameters?.[0] || ''
|
|
@@ -1093,7 +1148,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1093
1148
|
return
|
|
1094
1149
|
}
|
|
1095
1150
|
|
|
1096
|
-
if (
|
|
1151
|
+
if (getBinaryNodeChild(node, 'unavailable')) {
|
|
1097
1152
|
logger.debug('Message unavailable, skipping retry')
|
|
1098
1153
|
return
|
|
1099
1154
|
}
|
|
@@ -1105,24 +1160,24 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1105
1160
|
logger.debug('Uploading pre-keys for error recovery')
|
|
1106
1161
|
await uploadPreKeys(5)
|
|
1107
1162
|
logger.debug('Waiting for server to process new pre-keys')
|
|
1108
|
-
await
|
|
1163
|
+
await delay(1000)
|
|
1109
1164
|
}
|
|
1110
1165
|
catch (uploadErr) {
|
|
1111
1166
|
logger.error({ uploadErr }, 'Pre-key upload failed, proceeding with retry anyway')
|
|
1112
1167
|
}
|
|
1113
1168
|
}
|
|
1114
1169
|
|
|
1115
|
-
const encNode =
|
|
1170
|
+
const encNode = getBinaryNodeChild(node, 'enc')
|
|
1116
1171
|
await sendRetryRequest(node, !encNode)
|
|
1117
1172
|
if (retryRequestDelayMs) {
|
|
1118
|
-
await
|
|
1173
|
+
await delay(retryRequestDelayMs)
|
|
1119
1174
|
}
|
|
1120
1175
|
}
|
|
1121
1176
|
catch (err) {
|
|
1122
1177
|
logger.error({ err, isPreKeyError }, 'Failed to handle retry, attempting basic retry')
|
|
1123
1178
|
// Still attempt retry even if pre-key upload failed
|
|
1124
1179
|
try {
|
|
1125
|
-
const encNode =
|
|
1180
|
+
const encNode = getBinaryNodeChild(node, 'enc')
|
|
1126
1181
|
await sendRetryRequest(node, !encNode)
|
|
1127
1182
|
}
|
|
1128
1183
|
catch (retryErr) {
|
|
@@ -1148,7 +1203,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1148
1203
|
type = 'sender'
|
|
1149
1204
|
|
|
1150
1205
|
// need to specially handle this case
|
|
1151
|
-
if (
|
|
1206
|
+
if (isLidUser(msg.key.remoteJid) || isLidUser(msg.key.remoteJidAlt)) {
|
|
1152
1207
|
participant = author // TODO: investigate sending receipts to LIDs and not PNs
|
|
1153
1208
|
}
|
|
1154
1209
|
}
|
|
@@ -1159,13 +1214,13 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1159
1214
|
await sendReceipt(msg.key.remoteJid, participant, [msg.key.id], type)
|
|
1160
1215
|
|
|
1161
1216
|
// send ack for history message
|
|
1162
|
-
const isAnyHistoryMsg =
|
|
1217
|
+
const isAnyHistoryMsg = getHistoryMsg(msg.message)
|
|
1163
1218
|
if (isAnyHistoryMsg) {
|
|
1164
|
-
const jid =
|
|
1219
|
+
const jid = jidNormalizedUser(msg.key.remoteJid)
|
|
1165
1220
|
await sendReceipt(jid, undefined, [msg.key.id], 'hist_sync')
|
|
1166
1221
|
}
|
|
1167
1222
|
}
|
|
1168
|
-
|
|
1223
|
+
cleanMessage(msg, authState.creds.me.id)
|
|
1169
1224
|
await sendMessageAck(node)
|
|
1170
1225
|
await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify')
|
|
1171
1226
|
})
|
|
@@ -1179,7 +1234,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1179
1234
|
|
|
1180
1235
|
const fetchMessageHistory = async (count, oldestMsgKey, oldestMsgTimestamp) => {
|
|
1181
1236
|
if (!authState.creds.me?.id) {
|
|
1182
|
-
throw new
|
|
1237
|
+
throw new Boom('Not authenticated')
|
|
1183
1238
|
}
|
|
1184
1239
|
|
|
1185
1240
|
const pdoMessage = {
|
|
@@ -1190,7 +1245,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1190
1245
|
oldestMsgTimestampMs: oldestMsgTimestamp,
|
|
1191
1246
|
onDemandMsgCount: count
|
|
1192
1247
|
},
|
|
1193
|
-
peerDataOperationRequestType:
|
|
1248
|
+
peerDataOperationRequestType: proto.Message.PeerDataOperationRequestType.HISTORY_SYNC_ON_DEMAND
|
|
1194
1249
|
}
|
|
1195
1250
|
|
|
1196
1251
|
return sendPeerDataOperationMessage(pdoMessage)
|
|
@@ -1198,7 +1253,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1198
1253
|
|
|
1199
1254
|
const requestPlaceholderResend = async (messageKey) => {
|
|
1200
1255
|
if (!authState.creds.me?.id) {
|
|
1201
|
-
throw new
|
|
1256
|
+
throw new Boom('Not authenticated')
|
|
1202
1257
|
}
|
|
1203
1258
|
|
|
1204
1259
|
if (placeholderResendCache.get(messageKey?.id)) {
|
|
@@ -1210,7 +1265,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1210
1265
|
placeholderResendCache.set(messageKey?.id, true)
|
|
1211
1266
|
}
|
|
1212
1267
|
|
|
1213
|
-
await
|
|
1268
|
+
await delay(5000)
|
|
1214
1269
|
|
|
1215
1270
|
if (!placeholderResendCache.get(messageKey?.id)) {
|
|
1216
1271
|
logger.debug({ messageKey }, 'message received while resend requested')
|
|
@@ -1221,7 +1276,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1221
1276
|
placeholderMessageResendRequest: [{
|
|
1222
1277
|
messageKey
|
|
1223
1278
|
}],
|
|
1224
|
-
peerDataOperationRequestType:
|
|
1279
|
+
peerDataOperationRequestType: proto.Message.PeerDataOperationRequestType.PLACEHOLDER_MESSAGE_RESEND
|
|
1225
1280
|
}
|
|
1226
1281
|
|
|
1227
1282
|
setTimeout(() => {
|
|
@@ -1238,12 +1293,12 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1238
1293
|
let status
|
|
1239
1294
|
|
|
1240
1295
|
const { attrs } = node
|
|
1241
|
-
const [infoChild] =
|
|
1296
|
+
const [infoChild] = getAllBinaryNodeChildren(node)
|
|
1242
1297
|
const callId = infoChild.attrs['call-id']
|
|
1243
1298
|
const from = infoChild.attrs.from || infoChild.attrs['call-creator']
|
|
1244
|
-
status =
|
|
1299
|
+
status = getCallStatusFromNode(infoChild)
|
|
1245
1300
|
|
|
1246
|
-
if (
|
|
1301
|
+
if (isLidUser(from) && infoChild.tag === 'relaylatency') {
|
|
1247
1302
|
const verify = await callOfferCache.get(callId)
|
|
1248
1303
|
|
|
1249
1304
|
if (!verify) {
|
|
@@ -1271,7 +1326,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1271
1326
|
}
|
|
1272
1327
|
|
|
1273
1328
|
if (status === 'offer') {
|
|
1274
|
-
call.isVideo = !!
|
|
1329
|
+
call.isVideo = !!getBinaryNodeChild(infoChild, 'video')
|
|
1275
1330
|
call.isGroup = infoChild.attrs.type === 'group' || !!infoChild.attrs['group-jid']
|
|
1276
1331
|
call.groupJid = infoChild.attrs['group-jid']
|
|
1277
1332
|
await callOfferCache.set(call.id, call)
|
|
@@ -1318,7 +1373,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1318
1373
|
{
|
|
1319
1374
|
key,
|
|
1320
1375
|
update: {
|
|
1321
|
-
status:
|
|
1376
|
+
status: WAMessageStatus.ERROR,
|
|
1322
1377
|
messageStubParameters: [
|
|
1323
1378
|
attrs.error
|
|
1324
1379
|
]
|
|
@@ -1418,16 +1473,16 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1418
1473
|
id: call.id,
|
|
1419
1474
|
fromMe: false
|
|
1420
1475
|
},
|
|
1421
|
-
messageTimestamp:
|
|
1476
|
+
messageTimestamp: unixTimestampSeconds(call.date),
|
|
1422
1477
|
}
|
|
1423
1478
|
|
|
1424
1479
|
if (call.status === 'timeout') {
|
|
1425
1480
|
if (call.isGroup) {
|
|
1426
|
-
msg.messageStubType = call.isVideo ?
|
|
1481
|
+
msg.messageStubType = call.isVideo ? WAMessageStubType.CALL_MISSED_GROUP_VIDEO : WAMessageStubType.CALL_MISSED_GROUP_VOICE
|
|
1427
1482
|
}
|
|
1428
1483
|
|
|
1429
1484
|
else {
|
|
1430
|
-
msg.messageStubType = call.isVideo ?
|
|
1485
|
+
msg.messageStubType = call.isVideo ? WAMessageStubType.CALL_MISSED_VIDEO : WAMessageStubType.CALL_MISSED_VOICE
|
|
1431
1486
|
}
|
|
1432
1487
|
}
|
|
1433
1488
|
|
|
@@ -1435,7 +1490,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1435
1490
|
msg.message = { call: { callKey: Buffer.from(call.id) } }
|
|
1436
1491
|
}
|
|
1437
1492
|
|
|
1438
|
-
const protoMsg =
|
|
1493
|
+
const protoMsg = proto.WebMessageInfo.fromObject(msg)
|
|
1439
1494
|
upsertMessage(protoMsg, call.offline ? 'append' : 'notify')
|
|
1440
1495
|
}
|
|
1441
1496
|
})
|