@badzz88/baileys 8.5.2 → 8.5.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 +1 -1
- package/WAProto/WAProto.proto +1256 -75
- package/WAProto/index.d.ts +36042 -19649
- package/WAProto/index.js +181990 -135645
- package/engine-requirements.js +7 -15
- package/lib/Defaults/index.js +22 -17
- package/lib/Signal/Group/group_cipher.js +5 -5
- package/lib/Signal/Group/keyhelper.js +4 -4
- package/lib/Signal/Group/sender-chain-key.js +2 -2
- package/lib/Signal/Group/sender-key-distribution-message.js +1 -1
- package/lib/Signal/Group/sender-key-message.js +3 -3
- package/lib/Signal/Group/sender-key-record.js +1 -1
- package/lib/Signal/Group/sender-message-key.js +5 -5
- package/lib/Signal/libsignal.js +39 -59
- package/lib/Signal/lid-mapping.js +28 -10
- package/lib/Socket/aigroups.js +5 -5
- package/lib/Socket/business.js +3 -11
- package/lib/Socket/chats.js +668 -319
- package/lib/Socket/communities.js +85 -89
- package/lib/Socket/graphql.js +435 -228
- package/lib/Socket/groups.js +132 -211
- package/lib/Socket/index.js +9 -7
- package/lib/Socket/interactive-handler.js +117 -60
- package/lib/Socket/interop.js +56 -175
- package/lib/Socket/managed-account.js +79 -48
- package/lib/Socket/messages-recv.js +898 -340
- package/lib/Socket/messages-send.js +462 -160
- package/lib/Socket/mex.js +40 -53
- package/lib/Socket/newsletter.js +291 -291
- package/lib/Socket/privacy.js +77 -265
- package/lib/Socket/registration.js +164 -157
- package/lib/Socket/socket.js +181 -199
- package/lib/Socket/username.js +144 -227
- package/lib/Store/make-cache-manager-store.js +2 -2
- package/lib/Store/make-in-memory-store.js +25 -141
- package/lib/Types/Auth.js +3 -3
- package/lib/Types/Label.js +1 -1
- package/lib/Types/LabelAssociation.js +1 -1
- package/lib/Types/Newsletter.js +96 -65
- package/lib/Types/State.js +4 -4
- package/lib/Types/index.js +1 -1
- package/lib/Utils/auth-utils.js +52 -57
- package/lib/Utils/browser-utils.js +1 -1
- package/lib/Utils/business.js +2 -6
- package/lib/Utils/chat-utils.js +102 -38
- package/lib/Utils/crypto.js +54 -84
- package/lib/Utils/decode-wa-message.js +316 -83
- package/lib/Utils/event-buffer.js +37 -61
- package/lib/Utils/generics.js +157 -103
- package/lib/Utils/group-history.js +3 -12
- package/lib/Utils/history.js +15 -15
- package/lib/Utils/index.js +1 -5
- package/lib/Utils/link-preview.js +3 -8
- package/lib/Utils/lt-hash.js +2 -35
- package/lib/Utils/make-mutex.js +1 -1
- package/lib/Utils/message-inspect.js +393 -0
- package/lib/Utils/message-retry-manager.js +27 -92
- package/lib/Utils/messages-media.js +159 -130
- package/lib/Utils/messages.js +144 -566
- package/lib/Utils/meta-ai-msmsg.js +62 -202
- package/lib/Utils/noise-handler.js +19 -21
- package/lib/Utils/offline-node-processor.js +3 -8
- package/lib/Utils/pre-key-manager.js +13 -23
- package/lib/Utils/process-message.js +197 -106
- package/lib/Utils/reporting-utils.js +2 -2
- package/lib/Utils/signal.js +28 -63
- package/lib/Utils/stanza-ack.js +39 -12
- package/lib/Utils/sync-action-utils.js +4 -7
- package/lib/Utils/tc-token-utils.js +20 -25
- package/lib/Utils/use-multi-file-auth-state.js +30 -14
- package/lib/Utils/validate-connection.js +59 -19
- package/lib/WABinary/decode.js +50 -16
- package/lib/WABinary/encode.js +54 -224
- package/lib/WABinary/generic-utils.js +7 -97
- package/lib/WABinary/jid-utils.js +27 -14
- package/lib/WAM/encode.js +7 -7
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +58 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +7 -1
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +13 -5
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -4
- package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +20 -7
- package/lib/WAUSync/Protocols/USyncNewsletterProtocol.js +865 -0
- package/lib/WAUSync/Protocols/USyncPictureProtocol.js +1 -1
- package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +2 -2
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +7 -2
- package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +1 -1
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +2 -1
- package/lib/WAUSync/Protocols/index.js +1 -0
- package/lib/WAUSync/USyncBackoff.js +26 -0
- package/lib/WAUSync/USyncQuery.js +77 -6
- package/lib/WAUSync/USyncUser.js +16 -8
- package/lib/WAUSync/index.js +1 -0
- package/lib/antiban.js +608 -854
- package/lib/index.js +3 -3
- package/package.json +16 -19
- package/lib/Socket/luxu.js +0 -387
- package/lib/Socket/text-router.js +0 -83
- package/lib/Store/keyed-db.js +0 -108
- package/lib/Types/Mex.js +0 -112
- package/lib/Utils/command-loader.d.ts +0 -31
- package/lib/Utils/command-loader.js +0 -100
- package/lib/Utils/companion-reg-client-utils.js +0 -42
- package/lib/Utils/curve25519-js.js +0 -275
- package/lib/Utils/native-bridge.js +0 -82
- package/lib/Utils/session-pool.d.ts +0 -16
- package/lib/Utils/session-pool.js +0 -94
- package/lib/Utils/sticker.d.ts +0 -17
- package/lib/Utils/sticker.js +0 -145
- package/lib/Utils/view-once-cache.d.ts +0 -9
- package/lib/Utils/view-once-cache.js +0 -79
package/lib/Utils/stanza-ack.js
CHANGED
|
@@ -1,24 +1,50 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
Object.defineProperty(exports, '__esModule', { value: true })
|
|
3
3
|
exports.buildAckStanza = buildAckStanza
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const CALL_STANZA_TAGS = new Set([
|
|
7
|
+
'offer',
|
|
8
|
+
'offer_notice',
|
|
9
|
+
'terminate',
|
|
10
|
+
'accept',
|
|
11
|
+
'reject',
|
|
12
|
+
'preaccept',
|
|
13
|
+
'transport',
|
|
14
|
+
'video',
|
|
15
|
+
'duration',
|
|
16
|
+
'mute_v2',
|
|
17
|
+
'lobby',
|
|
18
|
+
'heartbeat',
|
|
19
|
+
'relaylatency',
|
|
20
|
+
'link_query',
|
|
21
|
+
'group_update',
|
|
22
|
+
'accept_ack',
|
|
23
|
+
'enc-rekey',
|
|
24
|
+
'enc_rekey',
|
|
25
|
+
'peer_state',
|
|
26
|
+
'group_info',
|
|
27
|
+
'video_state',
|
|
28
|
+
'video_state_ack',
|
|
29
|
+
'flow_control',
|
|
30
|
+
'waiting_room_request'
|
|
31
|
+
])
|
|
32
|
+
|
|
12
33
|
function buildAckStanza(node, errorCode, meId) {
|
|
13
34
|
const { tag, attrs } = node
|
|
35
|
+
const isCallStanza = CALL_STANZA_TAGS.has(tag)
|
|
14
36
|
const stanza = {
|
|
15
37
|
tag: 'ack',
|
|
16
38
|
attrs: {
|
|
17
39
|
id: attrs.id,
|
|
18
40
|
to: attrs.from,
|
|
19
|
-
class: tag
|
|
41
|
+
class: isCallStanza ? 'call' : tag
|
|
20
42
|
}
|
|
21
43
|
}
|
|
44
|
+
|
|
45
|
+
if (isCallStanza) {
|
|
46
|
+
stanza.attrs.type = tag
|
|
47
|
+
}
|
|
22
48
|
if (errorCode) {
|
|
23
49
|
stanza.attrs.error = errorCode.toString()
|
|
24
50
|
}
|
|
@@ -28,11 +54,12 @@ function buildAckStanza(node, errorCode, meId) {
|
|
|
28
54
|
if (attrs.recipient) {
|
|
29
55
|
stanza.attrs.recipient = attrs.recipient
|
|
30
56
|
}
|
|
31
|
-
|
|
32
|
-
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
if (attrs.type && !isCallStanza) {
|
|
33
60
|
stanza.attrs.type = attrs.type
|
|
34
61
|
}
|
|
35
|
-
|
|
62
|
+
|
|
36
63
|
if (tag === 'message' && meId) {
|
|
37
64
|
stanza.attrs.from = meId
|
|
38
65
|
}
|
|
@@ -2,10 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, '__esModule', { value: true })
|
|
3
3
|
exports.emitSyncActionResults = exports.processContactAction = void 0
|
|
4
4
|
const WABinary_1 = require('../WABinary')
|
|
5
|
-
|
|
6
|
-
* Process contactAction and return events to emit.
|
|
7
|
-
* Pure function - no side effects.
|
|
8
|
-
*/
|
|
5
|
+
|
|
9
6
|
const processContactAction = (action, id, logger) => {
|
|
10
7
|
const results = []
|
|
11
8
|
if (!id) {
|
|
@@ -17,9 +14,9 @@ const processContactAction = (action, id, logger) => {
|
|
|
17
14
|
}
|
|
18
15
|
const lidJid = action.lidJid
|
|
19
16
|
const idIsPn = (0, WABinary_1.isPnUser)(id)
|
|
20
|
-
|
|
17
|
+
|
|
21
18
|
const phoneNumber = idIsPn ? id : action.pnJid || undefined
|
|
22
|
-
|
|
19
|
+
|
|
23
20
|
results.push({
|
|
24
21
|
event: 'contacts.upsert',
|
|
25
22
|
data: [
|
|
@@ -32,7 +29,7 @@ const processContactAction = (action, id, logger) => {
|
|
|
32
29
|
}
|
|
33
30
|
]
|
|
34
31
|
})
|
|
35
|
-
|
|
32
|
+
|
|
36
33
|
if (lidJid && (0, WABinary_1.isLidUser)(lidJid) && idIsPn) {
|
|
37
34
|
results.push({
|
|
38
35
|
event: 'lid-mapping.update',
|
|
@@ -10,21 +10,16 @@ exports.resolveIssuanceJid = resolveIssuanceJid
|
|
|
10
10
|
exports.buildTcTokenFromJid = buildTcTokenFromJid
|
|
11
11
|
exports.storeTcTokensFromIqResult = storeTcTokensFromIqResult
|
|
12
12
|
const WABinary_1 = require('../WABinary')
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
|
|
14
|
+
|
|
15
15
|
const BOT_PHONE_REGEX = /^1313555\d{4}$|^131655500\d{2}$/
|
|
16
|
-
|
|
17
|
-
* Mirrors WA Web's `Wid.isRegularUser()` (user ∧ ¬PSA ∧ ¬Bot). Used to gate tctoken
|
|
18
|
-
* storage against malformed notifications — WA Web filters server-side but we
|
|
19
|
-
* defend here for parity with `WAWebSetTcTokenChatAction.handleIncomingTcToken`.
|
|
20
|
-
* Works for both pre- and post-normalized JIDs (`@c.us` vs `@s.whatsapp.net`).
|
|
21
|
-
*/
|
|
16
|
+
|
|
22
17
|
function isRegularUser(jid) {
|
|
23
18
|
if (!jid) return false
|
|
24
19
|
const user = jid.split('@')[0] ?? ''
|
|
25
|
-
if (user === '0') return false
|
|
26
|
-
if (BOT_PHONE_REGEX.test(user)) return false
|
|
27
|
-
if ((0, WABinary_1.isJidMetaAI)(jid)) return false
|
|
20
|
+
if (user === '0') return false
|
|
21
|
+
if (BOT_PHONE_REGEX.test(user)) return false
|
|
22
|
+
if ((0, WABinary_1.isJidMetaAI)(jid)) return false
|
|
28
23
|
return !!(
|
|
29
24
|
(0, WABinary_1.isPnUser)(jid) ||
|
|
30
25
|
(0, WABinary_1.isLidUser)(jid) ||
|
|
@@ -33,11 +28,11 @@ function isRegularUser(jid) {
|
|
|
33
28
|
jid.endsWith('@c.us')
|
|
34
29
|
)
|
|
35
30
|
}
|
|
36
|
-
const TC_TOKEN_BUCKET_DURATION = 604800
|
|
37
|
-
const TC_TOKEN_NUM_BUCKETS = 4
|
|
38
|
-
|
|
31
|
+
const TC_TOKEN_BUCKET_DURATION = 604800
|
|
32
|
+
const TC_TOKEN_NUM_BUCKETS = 4
|
|
33
|
+
|
|
39
34
|
exports.TC_TOKEN_INDEX_KEY = '__index'
|
|
40
|
-
|
|
35
|
+
|
|
41
36
|
async function readTcTokenIndex(keys) {
|
|
42
37
|
const data = await keys.get('tctoken', [exports.TC_TOKEN_INDEX_KEY])
|
|
43
38
|
const entry = data[exports.TC_TOKEN_INDEX_KEY]
|
|
@@ -50,7 +45,7 @@ async function readTcTokenIndex(keys) {
|
|
|
50
45
|
return []
|
|
51
46
|
}
|
|
52
47
|
}
|
|
53
|
-
|
|
48
|
+
|
|
54
49
|
async function buildMergedTcTokenIndexWrite(keys, addedJids) {
|
|
55
50
|
const persisted = await readTcTokenIndex(keys)
|
|
56
51
|
const merged = new Set(persisted)
|
|
@@ -61,10 +56,10 @@ async function buildMergedTcTokenIndexWrite(keys, addedJids) {
|
|
|
61
56
|
[exports.TC_TOKEN_INDEX_KEY]: { token: Buffer.from(JSON.stringify([...merged])) }
|
|
62
57
|
}
|
|
63
58
|
}
|
|
64
|
-
|
|
59
|
+
|
|
65
60
|
function isTcTokenExpired(timestamp) {
|
|
66
61
|
if (timestamp === null || timestamp === undefined) return true
|
|
67
|
-
const ts = typeof timestamp === 'string' ? parseInt(timestamp) : timestamp
|
|
62
|
+
const ts = typeof timestamp === 'string' ? parseInt(timestamp, 10) : timestamp
|
|
68
63
|
if (isNaN(ts)) return true
|
|
69
64
|
const now = Math.floor(Date.now() / 1000)
|
|
70
65
|
const currentBucket = Math.floor(now / TC_TOKEN_BUCKET_DURATION)
|
|
@@ -79,13 +74,13 @@ function shouldSendNewTcToken(senderTimestamp) {
|
|
|
79
74
|
const senderBucket = Math.floor(senderTimestamp / TC_TOKEN_BUCKET_DURATION)
|
|
80
75
|
return currentBucket > senderBucket
|
|
81
76
|
}
|
|
82
|
-
|
|
77
|
+
|
|
83
78
|
async function resolveTcTokenJid(jid, getLIDForPN) {
|
|
84
79
|
if ((0, WABinary_1.isLidUser)(jid)) return jid
|
|
85
80
|
const lid = await getLIDForPN(jid)
|
|
86
81
|
return lid ?? jid
|
|
87
82
|
}
|
|
88
|
-
|
|
83
|
+
|
|
89
84
|
async function resolveIssuanceJid(jid, issueToLid, getLIDForPN, getPNForLID) {
|
|
90
85
|
if (issueToLid) {
|
|
91
86
|
if ((0, WABinary_1.isLidUser)(jid)) return jid
|
|
@@ -107,9 +102,9 @@ async function buildTcTokenFromJid({ authState, jid, baseContent = [], getLIDFor
|
|
|
107
102
|
const tcTokenBuffer = entry?.token
|
|
108
103
|
if (!tcTokenBuffer?.length || isTcTokenExpired(entry?.timestamp)) {
|
|
109
104
|
if (tcTokenBuffer) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
113
108
|
const cleared =
|
|
114
109
|
entry?.senderTimestamp !== undefined
|
|
115
110
|
? { token: Buffer.alloc(0), senderTimestamp: entry.senderTimestamp }
|
|
@@ -136,7 +131,7 @@ async function storeTcTokensFromIqResult({ result, fallbackJid, keys, getLIDForP
|
|
|
136
131
|
if (tokenNode.attrs.type !== 'trusted_contact' || !(tokenNode.content instanceof Uint8Array)) {
|
|
137
132
|
continue
|
|
138
133
|
}
|
|
139
|
-
|
|
134
|
+
|
|
140
135
|
const rawJid = (0, WABinary_1.jidNormalizedUser)(fallbackJid || tokenNode.attrs.jid)
|
|
141
136
|
if (!isRegularUser(rawJid)) continue
|
|
142
137
|
const storageJid = await resolveTcTokenJid(rawJid, getLIDForPN)
|
|
@@ -144,7 +139,7 @@ async function storeTcTokensFromIqResult({ result, fallbackJid, keys, getLIDForP
|
|
|
144
139
|
const existingEntry = existingTcData[storageJid]
|
|
145
140
|
const existingTs = existingEntry?.timestamp ? Number(existingEntry.timestamp) : 0
|
|
146
141
|
const incomingTs = tokenNode.attrs.t ? Number(tokenNode.attrs.t) : 0
|
|
147
|
-
|
|
142
|
+
|
|
148
143
|
if (!incomingTs) continue
|
|
149
144
|
if (existingTs > 0 && existingTs > incomingTs) continue
|
|
150
145
|
await keys.set({
|
|
@@ -7,12 +7,12 @@ const path_1 = require('path')
|
|
|
7
7
|
const index_js_1 = require('../../WAProto/index.js')
|
|
8
8
|
const auth_utils_1 = require('./auth-utils')
|
|
9
9
|
const generics_1 = require('./generics')
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
14
|
const fileLocks = new Map()
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
const getFileLock = path => {
|
|
17
17
|
let mutex = fileLocks.get(path)
|
|
18
18
|
if (!mutex) {
|
|
@@ -21,21 +21,37 @@ const getFileLock = path => {
|
|
|
21
21
|
}
|
|
22
22
|
return mutex
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
* stores the full authentication state in a single folder.
|
|
26
|
-
* Far more efficient than singlefileauthstate
|
|
27
|
-
*
|
|
28
|
-
* Again, I wouldn't endorse this for any production level use other than perhaps a bot.
|
|
29
|
-
* Would recommend writing an auth state for use with a proper SQL or No-SQL DB
|
|
30
|
-
* */
|
|
24
|
+
|
|
31
25
|
const useMultiFileAuthState = async folder => {
|
|
32
|
-
|
|
26
|
+
|
|
33
27
|
const writeData = async (data, file) => {
|
|
34
28
|
const filePath = (0, path_1.join)(folder, fixFileName(file))
|
|
35
29
|
const mutex = getFileLock(filePath)
|
|
36
30
|
return mutex.acquire().then(async release => {
|
|
31
|
+
const tmpPath = `${filePath}.tmp`
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
const existingStat = await (0, promises_1.stat)(filePath).catch(() => undefined)
|
|
37
38
|
try {
|
|
38
|
-
await (0, promises_1.writeFile)(
|
|
39
|
+
await (0, promises_1.writeFile)(
|
|
40
|
+
tmpPath,
|
|
41
|
+
JSON.stringify(data, generics_1.BufferJSON.replacer),
|
|
42
|
+
existingStat ? { mode: existingStat.mode & 0o777 } : undefined
|
|
43
|
+
)
|
|
44
|
+
try {
|
|
45
|
+
await (0, promises_1.rename)(tmpPath, filePath)
|
|
46
|
+
} catch {
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
await (0, promises_1.writeFile)(
|
|
50
|
+
filePath,
|
|
51
|
+
JSON.stringify(data, generics_1.BufferJSON.replacer),
|
|
52
|
+
existingStat ? { mode: existingStat.mode & 0o777 } : undefined
|
|
53
|
+
)
|
|
54
|
+
}
|
|
39
55
|
} finally {
|
|
40
56
|
release()
|
|
41
57
|
}
|
|
@@ -7,24 +7,48 @@ exports.encodeSignedDeviceIdentity =
|
|
|
7
7
|
void 0
|
|
8
8
|
const boom_1 = require('@hapi/boom')
|
|
9
9
|
const crypto_1 = require('crypto')
|
|
10
|
-
const
|
|
10
|
+
const rb = require('whatsapp-rust-bridge')
|
|
11
11
|
const index_js_1 = require('../../WAProto/index.js')
|
|
12
12
|
const Defaults_1 = require('../Defaults')
|
|
13
13
|
const WABinary_1 = require('../WABinary')
|
|
14
14
|
const crypto_2 = require('./crypto')
|
|
15
15
|
const generics_1 = require('./generics')
|
|
16
16
|
const signal_1 = require('./signal')
|
|
17
|
+
const MOBILE_PLATFORMS = new Set(['Android', 'iOS'])
|
|
17
18
|
const getUserAgent = config => {
|
|
19
|
+
const os = config.browser[0]
|
|
20
|
+
let platform, device, osVersion
|
|
21
|
+
if (os === 'Android') {
|
|
22
|
+
platform = index_js_1.proto.ClientPayload.UserAgent.Platform.ANDROID
|
|
23
|
+
device = 'Android'
|
|
24
|
+
osVersion = config.browser[2] || '15.0.0'
|
|
25
|
+
} else if (os === 'iOS') {
|
|
26
|
+
platform = index_js_1.proto.ClientPayload.UserAgent.Platform.IOS
|
|
27
|
+
device = 'iPhone'
|
|
28
|
+
osVersion = config.browser[2] || '18.0'
|
|
29
|
+
} else if (config.syncFullHistory && os === 'Mac OS' && config.browser[1] === 'Desktop') {
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
platform = index_js_1.proto.ClientPayload.UserAgent.Platform.MACOS
|
|
33
|
+
device = 'Desktop'
|
|
34
|
+
osVersion = '0.1'
|
|
35
|
+
} else {
|
|
36
|
+
platform = index_js_1.proto.ClientPayload.UserAgent.Platform.WEB
|
|
37
|
+
device = 'Desktop'
|
|
38
|
+
osVersion = '0.1'
|
|
39
|
+
}
|
|
18
40
|
return {
|
|
19
41
|
appVersion: {
|
|
20
42
|
primary: config.version[0],
|
|
21
43
|
secondary: config.version[1],
|
|
22
44
|
tertiary: config.version[2]
|
|
23
45
|
},
|
|
24
|
-
platform
|
|
46
|
+
platform,
|
|
47
|
+
|
|
48
|
+
|
|
25
49
|
releaseChannel: index_js_1.proto.ClientPayload.UserAgent.ReleaseChannel.RELEASE,
|
|
26
|
-
osVersion
|
|
27
|
-
device
|
|
50
|
+
osVersion,
|
|
51
|
+
device,
|
|
28
52
|
osBuildNumber: '0.1',
|
|
29
53
|
localeLanguageIso6391: 'en',
|
|
30
54
|
mnc: '000',
|
|
@@ -34,7 +58,9 @@ const getUserAgent = config => {
|
|
|
34
58
|
}
|
|
35
59
|
const PLATFORM_MAP = {
|
|
36
60
|
'Mac OS': index_js_1.proto.ClientPayload.WebInfo.WebSubPlatform.DARWIN,
|
|
37
|
-
Windows: index_js_1.proto.ClientPayload.WebInfo.WebSubPlatform.
|
|
61
|
+
Windows: index_js_1.proto.ClientPayload.WebInfo.WebSubPlatform.WIN_HYBRID,
|
|
62
|
+
Android: index_js_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER,
|
|
63
|
+
iOS: index_js_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER
|
|
38
64
|
}
|
|
39
65
|
const getWebInfo = config => {
|
|
40
66
|
let webSubPlatform = index_js_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER
|
|
@@ -49,14 +75,16 @@ const getClientPayload = config => {
|
|
|
49
75
|
connectReason: index_js_1.proto.ClientPayload.ConnectReason.USER_ACTIVATED,
|
|
50
76
|
userAgent: getUserAgent(config)
|
|
51
77
|
}
|
|
52
|
-
|
|
78
|
+
if (!MOBILE_PLATFORMS.has(config.browser[0])) {
|
|
79
|
+
payload.webInfo = getWebInfo(config)
|
|
80
|
+
}
|
|
53
81
|
return payload
|
|
54
82
|
}
|
|
55
83
|
const generateLoginNode = (userJid, config, creds) => {
|
|
56
84
|
const { user, device } = (0, WABinary_1.jidDecode)(userJid)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
60
88
|
const effectiveDevice = config.masqueradeAsPrimary ? 0 : device
|
|
61
89
|
const payload = {
|
|
62
90
|
...getClientPayload(config),
|
|
@@ -66,8 +94,8 @@ const generateLoginNode = (userJid, config, creds) => {
|
|
|
66
94
|
device: effectiveDevice,
|
|
67
95
|
lidDbMigrated: false
|
|
68
96
|
}
|
|
69
|
-
|
|
70
|
-
|
|
97
|
+
|
|
98
|
+
|
|
71
99
|
if (creds?.interopData?.accountId) {
|
|
72
100
|
payload.interopData = {
|
|
73
101
|
accountId: creds.interopData.accountId,
|
|
@@ -83,18 +111,23 @@ const getPlatformType = platform => {
|
|
|
83
111
|
return index_js_1.proto.DeviceProps.PlatformType[platformType] || index_js_1.proto.DeviceProps.PlatformType.CHROME
|
|
84
112
|
}
|
|
85
113
|
const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentityKey }, config) => {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const appVersionBuf = Buffer.from(
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
const appVersionBuf = Buffer.from(rb.md5(Buffer.from(config.version.join('.'))))
|
|
89
117
|
const companion = {
|
|
90
118
|
os: config.browser[0],
|
|
91
119
|
platformType: getPlatformType(config.browser[1]),
|
|
92
120
|
requireFullSync: config.syncFullHistory,
|
|
93
121
|
historySyncConfig: {
|
|
122
|
+
fullSyncDaysLimit: 30,
|
|
123
|
+
fullSyncSizeMbLimit: undefined,
|
|
94
124
|
storageQuotaMb: 10240,
|
|
95
125
|
inlineInitialPayloadInE2EeMsg: true,
|
|
96
126
|
recentSyncDaysLimit: undefined,
|
|
97
|
-
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
supportCallLogHistory: config.browser[0] === 'Windows',
|
|
98
131
|
supportBotUserAgentChatHistory: true,
|
|
99
132
|
supportCagReactionsAndPolls: true,
|
|
100
133
|
supportBizHostedMsg: true,
|
|
@@ -103,9 +136,16 @@ const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentity
|
|
|
103
136
|
supportFbidBotChatHistory: true,
|
|
104
137
|
supportAddOnHistorySyncMigration: undefined,
|
|
105
138
|
supportMessageAssociation: true,
|
|
106
|
-
supportGroupHistory:
|
|
139
|
+
supportGroupHistory: true,
|
|
107
140
|
onDemandReady: undefined,
|
|
108
|
-
supportGuestChat:
|
|
141
|
+
supportGuestChat: true,
|
|
142
|
+
completeOnDemandReady: undefined,
|
|
143
|
+
thumbnailSyncDaysLimit: undefined,
|
|
144
|
+
initialSyncMaxMessagesPerChat: undefined,
|
|
145
|
+
supportManusHistory: true,
|
|
146
|
+
supportHatchHistory: true,
|
|
147
|
+
supportedBotChannelFbids: undefined,
|
|
148
|
+
supportInlineContacts: true
|
|
109
149
|
},
|
|
110
150
|
version: {
|
|
111
151
|
primary: 10,
|
|
@@ -209,8 +249,8 @@ const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, s
|
|
|
209
249
|
exports.configureSuccessfulPairing = configureSuccessfulPairing
|
|
210
250
|
const encodeSignedDeviceIdentity = (account, includeSignatureKey) => {
|
|
211
251
|
account = { ...account }
|
|
212
|
-
|
|
213
|
-
|
|
252
|
+
|
|
253
|
+
|
|
214
254
|
if (!includeSignatureKey || !account.accountSignatureKey?.length) {
|
|
215
255
|
account.accountSignatureKey = null
|
|
216
256
|
}
|
package/lib/WABinary/decode.js
CHANGED
|
@@ -56,17 +56,37 @@ const util_1 = require('util')
|
|
|
56
56
|
const zlib_1 = require('zlib')
|
|
57
57
|
const constants = __importStar(require('./constants'))
|
|
58
58
|
const jid_utils_1 = require('./jid-utils')
|
|
59
|
+
const rb = require('whatsapp-rust-bridge')
|
|
59
60
|
const inflatePromise = (0, util_1.promisify)(zlib_1.inflate)
|
|
60
61
|
const decompressingIfRequired = async buffer => {
|
|
61
62
|
if (2 & buffer.readUInt8()) {
|
|
62
63
|
buffer = await inflatePromise(buffer.slice(1))
|
|
63
64
|
} else {
|
|
64
|
-
|
|
65
|
+
|
|
65
66
|
buffer = buffer.slice(1)
|
|
66
67
|
}
|
|
67
68
|
return buffer
|
|
68
69
|
}
|
|
69
70
|
exports.decompressingIfRequired = decompressingIfRequired
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
const rustNodeToJs = node => {
|
|
74
|
+
if (!node || typeof node !== 'object') return node
|
|
75
|
+
const result = { tag: node.tag, attrs: node.attrs || {} }
|
|
76
|
+
const content = node.content
|
|
77
|
+
if (content === undefined || content === null) {
|
|
78
|
+
|
|
79
|
+
} else if (content instanceof Uint8Array) {
|
|
80
|
+
result.content = Buffer.from(content)
|
|
81
|
+
} else if (typeof content === 'string') {
|
|
82
|
+
result.content = content
|
|
83
|
+
} else if (Array.isArray(content)) {
|
|
84
|
+
result.content = content.map(rustNodeToJs)
|
|
85
|
+
} else {
|
|
86
|
+
result.content = content
|
|
87
|
+
}
|
|
88
|
+
return result
|
|
89
|
+
}
|
|
70
90
|
const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) => {
|
|
71
91
|
const { DOUBLE_BYTE_TOKENS, SINGLE_BYTE_TOKENS, TAGS } = opts
|
|
72
92
|
const checkEOS = length => {
|
|
@@ -90,7 +110,7 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
90
110
|
return value
|
|
91
111
|
}
|
|
92
112
|
const readStringFromChars = length => {
|
|
93
|
-
return readBytes(length).toString('
|
|
113
|
+
return readBytes(length).toString('utf8')
|
|
94
114
|
}
|
|
95
115
|
const readInt = (n, littleEndian = false) => {
|
|
96
116
|
checkEOS(n)
|
|
@@ -176,7 +196,7 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
176
196
|
const domainType = Number(rawDomainType)
|
|
177
197
|
const device = readByte()
|
|
178
198
|
const user = readString(readByte())
|
|
179
|
-
let server = 's.whatsapp.net'
|
|
199
|
+
let server = 's.whatsapp.net'
|
|
180
200
|
if (domainType === jid_utils_1.WAJIDDomains.LID) {
|
|
181
201
|
server = 'lid'
|
|
182
202
|
} else if (domainType === jid_utils_1.WAJIDDomains.HOSTED) {
|
|
@@ -197,13 +217,13 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
197
217
|
const device = readInt(2)
|
|
198
218
|
const integrator = readInt(2)
|
|
199
219
|
let server = 'interop'
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
203
223
|
if (indexRef.index < buffer.length) {
|
|
204
224
|
const serverTag = buffer[indexRef.index]
|
|
205
|
-
|
|
206
|
-
|
|
225
|
+
|
|
226
|
+
|
|
207
227
|
const isValidStringTag =
|
|
208
228
|
(serverTag >= 1 && serverTag <= 235) ||
|
|
209
229
|
serverTag === TAGS.BINARY_8 ||
|
|
@@ -212,7 +232,7 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
212
232
|
serverTag === TAGS.NIBBLE_8 ||
|
|
213
233
|
serverTag === TAGS.HEX_8
|
|
214
234
|
if (isValidStringTag) {
|
|
215
|
-
indexRef.index++
|
|
235
|
+
indexRef.index++
|
|
216
236
|
server = readString(serverTag)
|
|
217
237
|
}
|
|
218
238
|
}
|
|
@@ -261,7 +281,7 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
261
281
|
case TAGS.NIBBLE_8:
|
|
262
282
|
return readPacked8(tag)
|
|
263
283
|
default:
|
|
264
|
-
|
|
284
|
+
|
|
265
285
|
process.stderr.write(`[WABinary] unknown string tag 0x${tag.toString(16)} — token table outdated?\n`)
|
|
266
286
|
return ''
|
|
267
287
|
}
|
|
@@ -277,14 +297,16 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
277
297
|
const getTokenDouble = (index1, index2) => {
|
|
278
298
|
const dict = DOUBLE_BYTE_TOKENS[index1]
|
|
279
299
|
if (!dict) {
|
|
280
|
-
|
|
300
|
+
|
|
281
301
|
process.stderr.write(`[WABinary] unknown double-byte token dict ${index1} — token table outdated?\n`)
|
|
282
302
|
return ''
|
|
283
303
|
}
|
|
284
304
|
const value = dict[index2]
|
|
285
305
|
if (typeof value === 'undefined') {
|
|
286
|
-
|
|
287
|
-
process.stderr.write(
|
|
306
|
+
|
|
307
|
+
process.stderr.write(
|
|
308
|
+
`[WABinary] unknown double-byte token dict=${index1} idx=${index2} — token table outdated?\n`
|
|
309
|
+
)
|
|
288
310
|
return ''
|
|
289
311
|
}
|
|
290
312
|
return value
|
|
@@ -299,7 +321,7 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
299
321
|
if (listSize === 0 || !header) {
|
|
300
322
|
throw new Error('invalid node')
|
|
301
323
|
}
|
|
302
|
-
|
|
324
|
+
|
|
303
325
|
const attributesLength = (listSize - 1) >> 1
|
|
304
326
|
for (let i = 0; i < attributesLength; i++) {
|
|
305
327
|
const key = readString(readByte())
|
|
@@ -336,8 +358,20 @@ const decodeDecompressedBinaryNode = (buffer, opts, indexRef = { index: 0 }) =>
|
|
|
336
358
|
}
|
|
337
359
|
}
|
|
338
360
|
exports.decodeDecompressedBinaryNode = decodeDecompressedBinaryNode
|
|
361
|
+
const JS_DECODE_OPTS = {
|
|
362
|
+
TAGS: constants.TAGS,
|
|
363
|
+
SINGLE_BYTE_TOKENS: constants.SINGLE_BYTE_TOKENS,
|
|
364
|
+
DOUBLE_BYTE_TOKENS: constants.DOUBLE_BYTE_TOKENS,
|
|
365
|
+
}
|
|
339
366
|
const decodeBinaryNode = buff => {
|
|
340
|
-
const
|
|
341
|
-
|
|
367
|
+
const u8 = buff instanceof Uint8Array ? buff : new Uint8Array(buff.buffer, buff.byteOffset, buff.byteLength)
|
|
368
|
+
try {
|
|
369
|
+
const internal = rb.decodeNode(u8)
|
|
370
|
+
return rustNodeToJs(internal.toJSON())
|
|
371
|
+
} catch (_) {
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
return (0, exports.decodeDecompressedBinaryNode)(buff, JS_DECODE_OPTS)
|
|
375
|
+
}
|
|
342
376
|
}
|
|
343
377
|
exports.decodeBinaryNode = decodeBinaryNode
|