@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/engine-requirements.js
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
const major = parseInt(process.versions.node.split(
|
|
1
|
+
const major = parseInt(process.versions.node.split('.')[0], 10);
|
|
2
2
|
|
|
3
3
|
if (major < 20) {
|
|
4
|
-
console.error(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
• Required : v20.0.0+
|
|
10
|
-
|
|
11
|
-
This package uses features available only in
|
|
12
|
-
Node.js 20 or newer.
|
|
13
|
-
|
|
14
|
-
Please update Node.js and try again.
|
|
15
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
16
|
-
`);
|
|
4
|
+
console.error(
|
|
5
|
+
`\n❌ This package requires Node.js 20+ to run reliably.\n` +
|
|
6
|
+
` You are using Node.js ${process.versions.node}.\n` +
|
|
7
|
+
` Please upgrade to Node.js 20+ to proceed.\n`
|
|
8
|
+
);
|
|
17
9
|
process.exit(1);
|
|
18
|
-
}
|
|
10
|
+
}
|
package/lib/Defaults/index.js
CHANGED
|
@@ -26,6 +26,8 @@ exports.VERSION =
|
|
|
26
26
|
exports.PLACEHOLDER_MAX_AGE_SECONDS =
|
|
27
27
|
exports.STATUS_EXPIRY_SECONDS =
|
|
28
28
|
exports.WA_DEFAULT_EPHEMERAL =
|
|
29
|
+
exports.WA_ADV_HOSTED_KEY_INDEX_LIST_SIG_PREFIX =
|
|
30
|
+
exports.WA_ADV_KEY_INDEX_LIST_SIG_PREFIX =
|
|
29
31
|
exports.WA_ADV_HOSTED_DEVICE_SIG_PREFIX =
|
|
30
32
|
exports.WA_ADV_HOSTED_ACCOUNT_SIG_PREFIX =
|
|
31
33
|
exports.WA_ADV_DEVICE_SIG_PREFIX =
|
|
@@ -42,7 +44,8 @@ const index_js_1 = require('../../WAProto/index.js')
|
|
|
42
44
|
const libsignal_1 = require('../Signal/libsignal')
|
|
43
45
|
const browser_utils_1 = require('../Utils/browser-utils')
|
|
44
46
|
const logger_1 = __importDefault(require('../Utils/logger'))
|
|
45
|
-
|
|
47
|
+
|
|
48
|
+
const version = [2, 3000, 1044798975]
|
|
46
49
|
exports.VERSION = version
|
|
47
50
|
exports.UNAUTHORIZED_CODES = [401, 403, 419]
|
|
48
51
|
exports.DEFAULT_ORIGIN = 'https://web.whatsapp.com'
|
|
@@ -55,16 +58,19 @@ exports.WA_ADV_ACCOUNT_SIG_PREFIX = Buffer.from([6, 0])
|
|
|
55
58
|
exports.WA_ADV_DEVICE_SIG_PREFIX = Buffer.from([6, 1])
|
|
56
59
|
exports.WA_ADV_HOSTED_ACCOUNT_SIG_PREFIX = Buffer.from([6, 5])
|
|
57
60
|
exports.WA_ADV_HOSTED_DEVICE_SIG_PREFIX = Buffer.from([6, 6])
|
|
61
|
+
|
|
62
|
+
exports.WA_ADV_KEY_INDEX_LIST_SIG_PREFIX = Buffer.from([6, 2])
|
|
63
|
+
exports.WA_ADV_HOSTED_KEY_INDEX_LIST_SIG_PREFIX = Buffer.from([6, 7])
|
|
58
64
|
exports.WA_DEFAULT_EPHEMERAL = 7 * 24 * 60 * 60
|
|
59
|
-
|
|
65
|
+
|
|
60
66
|
exports.STATUS_EXPIRY_SECONDS = 24 * 60 * 60
|
|
61
|
-
|
|
67
|
+
|
|
62
68
|
exports.PLACEHOLDER_MAX_AGE_SECONDS = 14 * 24 * 60 * 60
|
|
63
69
|
exports.NOISE_MODE = 'Noise_XX_25519_AESGCM_SHA256\0\0\0\0'
|
|
64
70
|
exports.DICT_VERSION = 3
|
|
65
71
|
exports.KEY_BUNDLE_TYPE = Buffer.from([5])
|
|
66
|
-
exports.NOISE_WA_HEADER = Buffer.from([87, 65, 6, exports.DICT_VERSION])
|
|
67
|
-
|
|
72
|
+
exports.NOISE_WA_HEADER = Buffer.from([87, 65, 6, exports.DICT_VERSION])
|
|
73
|
+
|
|
68
74
|
exports.URL_REGEX = /https:\/\/(?![^:@\/\s]+:[^:@\/\s]+@)[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(:\d+)?(\/[^\s]*)?/g
|
|
69
75
|
exports.WA_CERT_DETAILS = {
|
|
70
76
|
SERIAL: 0,
|
|
@@ -83,11 +89,10 @@ exports.PROCESSABLE_HISTORY_TYPES = [
|
|
|
83
89
|
]
|
|
84
90
|
exports.DEFAULT_CONNECTION_CONFIG = {
|
|
85
91
|
version: version,
|
|
86
|
-
browser: browser_utils_1.Browsers.windows('
|
|
92
|
+
browser: browser_utils_1.Browsers.windows('Desktop'),
|
|
87
93
|
waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat',
|
|
88
94
|
connectTimeoutMs: 20000,
|
|
89
95
|
keepAliveIntervalMs: 30000,
|
|
90
|
-
aiLabel: true,
|
|
91
96
|
logger: logger_1.default.child({ class: 'baileys' }),
|
|
92
97
|
emitOwnEvents: true,
|
|
93
98
|
defaultQueryTimeoutMs: 60000,
|
|
@@ -168,17 +173,17 @@ exports.MEDIA_HKDF_KEY_MAPPING = {
|
|
|
168
173
|
exports.MEDIA_KEYS = Object.keys(exports.MEDIA_PATH_MAP)
|
|
169
174
|
exports.MIN_PREKEY_COUNT = 5
|
|
170
175
|
exports.INITIAL_PREKEY_COUNT = 812
|
|
171
|
-
exports.UPLOAD_TIMEOUT = 30000
|
|
172
|
-
exports.MIN_UPLOAD_INTERVAL = 5000
|
|
176
|
+
exports.UPLOAD_TIMEOUT = 30000
|
|
177
|
+
exports.MIN_UPLOAD_INTERVAL = 5000
|
|
173
178
|
exports.DEFAULT_CACHE_TTLS = {
|
|
174
|
-
SIGNAL_STORE: 5 * 60,
|
|
175
|
-
MSG_RETRY: 60 * 60,
|
|
176
|
-
CALL_OFFER: 5 * 60,
|
|
177
|
-
USER_DEVICES: 5 * 60,
|
|
178
|
-
GROUP_METADATA: 30 * 60,
|
|
179
|
-
CALL_SESSION: 10 * 60,
|
|
180
|
-
USYNC_RESULTS: 10 * 60,
|
|
181
|
-
IDENTITY_PROOF: 60 * 60
|
|
179
|
+
SIGNAL_STORE: 5 * 60,
|
|
180
|
+
MSG_RETRY: 60 * 60,
|
|
181
|
+
CALL_OFFER: 5 * 60,
|
|
182
|
+
USER_DEVICES: 5 * 60,
|
|
183
|
+
GROUP_METADATA: 30 * 60,
|
|
184
|
+
CALL_SESSION: 10 * 60,
|
|
185
|
+
USYNC_RESULTS: 10 * 60,
|
|
186
|
+
IDENTITY_PROOF: 60 * 60
|
|
182
187
|
}
|
|
183
188
|
exports.TimeMs = {
|
|
184
189
|
Second: 1000,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
Object.defineProperty(exports, '__esModule', { value: true })
|
|
3
3
|
exports.GroupCipher = void 0
|
|
4
|
-
const
|
|
4
|
+
const rb = require('whatsapp-rust-bridge')
|
|
5
5
|
const sender_key_message_1 = require('./sender-key-message')
|
|
6
6
|
class GroupCipher {
|
|
7
7
|
constructor(senderKeyStore, senderKeyName) {
|
|
@@ -73,15 +73,15 @@ class GroupCipher {
|
|
|
73
73
|
}
|
|
74
74
|
async getPlainText(iv, key, ciphertext) {
|
|
75
75
|
try {
|
|
76
|
-
return Buffer.from(
|
|
77
|
-
} catch
|
|
76
|
+
return Buffer.from(rb.aesDecryptWithIV(ciphertext, key, iv))
|
|
77
|
+
} catch {
|
|
78
78
|
throw new Error('InvalidMessageException')
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
async getCipherText(iv, key, plaintext) {
|
|
82
82
|
try {
|
|
83
|
-
return Buffer.from(
|
|
84
|
-
} catch
|
|
83
|
+
return Buffer.from(rb.aesEncrypWithIV(plaintext, key, iv))
|
|
84
|
+
} catch {
|
|
85
85
|
throw new Error('InvalidMessageException')
|
|
86
86
|
}
|
|
87
87
|
}
|
|
@@ -55,7 +55,7 @@ exports.generateSenderKey = generateSenderKey
|
|
|
55
55
|
exports.generateSenderKeyId = generateSenderKeyId
|
|
56
56
|
exports.generateSenderSigningKey = generateSenderSigningKey
|
|
57
57
|
const nodeCrypto = __importStar(require('crypto'))
|
|
58
|
-
const
|
|
58
|
+
const rb = require('whatsapp-rust-bridge')
|
|
59
59
|
function generateSenderKey() {
|
|
60
60
|
return nodeCrypto.randomBytes(32)
|
|
61
61
|
}
|
|
@@ -64,10 +64,10 @@ function generateSenderKeyId() {
|
|
|
64
64
|
}
|
|
65
65
|
function generateSenderSigningKey(key) {
|
|
66
66
|
if (!key) {
|
|
67
|
-
key =
|
|
67
|
+
key = rb.generateKeyPair()
|
|
68
68
|
}
|
|
69
69
|
return {
|
|
70
|
-
public:
|
|
71
|
-
private: Buffer.from(key.
|
|
70
|
+
public: Buffer.from(key.pubKey),
|
|
71
|
+
private: Buffer.from(key.privKey)
|
|
72
72
|
}
|
|
73
73
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
Object.defineProperty(exports, '__esModule', { value: true })
|
|
3
3
|
exports.SenderChainKey = void 0
|
|
4
|
-
const
|
|
4
|
+
const rb = require('whatsapp-rust-bridge')
|
|
5
5
|
const sender_message_key_1 = require('./sender-message-key')
|
|
6
6
|
class SenderChainKey {
|
|
7
7
|
constructor(iteration, chainKey) {
|
|
@@ -26,7 +26,7 @@ class SenderChainKey {
|
|
|
26
26
|
return this.chainKey
|
|
27
27
|
}
|
|
28
28
|
getDerivative(seed, key) {
|
|
29
|
-
return Buffer.from(
|
|
29
|
+
return Buffer.from(rb.hmacSign(seed, key))
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
exports.SenderChainKey = SenderChainKey
|
|
@@ -22,7 +22,7 @@ class SenderKeyDistributionMessage extends ciphertext_message_1.CiphertextMessag
|
|
|
22
22
|
? Buffer.from(distributionMessage.signingKey, 'base64')
|
|
23
23
|
: distributionMessage.signingKey
|
|
24
24
|
} catch (e) {
|
|
25
|
-
throw new Error(String(e))
|
|
25
|
+
throw e instanceof Error ? e : new Error(String(e))
|
|
26
26
|
}
|
|
27
27
|
} else {
|
|
28
28
|
const version = this.intsToByteHighAndLow(this.CURRENT_VERSION, this.CURRENT_VERSION)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
Object.defineProperty(exports, '__esModule', { value: true })
|
|
3
3
|
exports.SenderKeyMessage = void 0
|
|
4
|
-
const
|
|
4
|
+
const rb = require('whatsapp-rust-bridge')
|
|
5
5
|
const index_js_1 = require('../../../WAProto/index.js')
|
|
6
6
|
const ciphertext_message_1 = require('./ciphertext-message')
|
|
7
7
|
class SenderKeyMessage extends ciphertext_message_1.CiphertextMessage {
|
|
@@ -53,11 +53,11 @@ class SenderKeyMessage extends ciphertext_message_1.CiphertextMessage {
|
|
|
53
53
|
verifySignature(signatureKey) {
|
|
54
54
|
const part1 = this.serialized.slice(0, this.serialized.length - this.SIGNATURE_LENGTH)
|
|
55
55
|
const part2 = this.serialized.slice(-1 * this.SIGNATURE_LENGTH)
|
|
56
|
-
const res =
|
|
56
|
+
const res = rb.verifySignature(signatureKey, part1, part2)
|
|
57
57
|
if (!res) throw new Error('Invalid signature!')
|
|
58
58
|
}
|
|
59
59
|
getSignature(signatureKey, serialized) {
|
|
60
|
-
return Buffer.from(
|
|
60
|
+
return Buffer.from(rb.calculateSignature(signatureKey, serialized))
|
|
61
61
|
}
|
|
62
62
|
serialize() {
|
|
63
63
|
return this.serialized
|
|
@@ -36,7 +36,7 @@ class SenderKeyRecord {
|
|
|
36
36
|
return this.senderKeyStates.map(state => state.getStructure())
|
|
37
37
|
}
|
|
38
38
|
static deserialize(data) {
|
|
39
|
-
const str = Buffer.from(data).toString('
|
|
39
|
+
const str = Buffer.from(data).toString('utf8')
|
|
40
40
|
const parsed = JSON.parse(str, generics_1.BufferJSON.reviver)
|
|
41
41
|
return new SenderKeyRecord(parsed)
|
|
42
42
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
Object.defineProperty(exports, '__esModule', { value: true })
|
|
3
3
|
exports.SenderMessageKey = void 0
|
|
4
|
-
const
|
|
4
|
+
const rb = require('whatsapp-rust-bridge')
|
|
5
5
|
class SenderMessageKey {
|
|
6
6
|
constructor(iteration, seed) {
|
|
7
|
-
|
|
8
|
-
const derived = Buffer.from(
|
|
7
|
+
|
|
8
|
+
const derived = Buffer.from(rb.hkdf(seed, 96, { salt: Buffer.alloc(32), info: 'WhisperGroup' }))
|
|
9
9
|
const keys = new Uint8Array(32)
|
|
10
|
-
keys.set(new Uint8Array(derived.slice(16, 32)))
|
|
11
|
-
keys.set(new Uint8Array(derived.slice(32, 48)), 16)
|
|
10
|
+
keys.set(new Uint8Array(derived.slice(16, 32)))
|
|
11
|
+
keys.set(new Uint8Array(derived.slice(32, 48)), 16)
|
|
12
12
|
this.iv = Buffer.from(derived.slice(0, 16))
|
|
13
13
|
this.cipherKey = Buffer.from(keys.buffer)
|
|
14
14
|
this.iteration = iteration
|
package/lib/Signal/libsignal.js
CHANGED
|
@@ -52,7 +52,7 @@ var __importStar =
|
|
|
52
52
|
})()
|
|
53
53
|
Object.defineProperty(exports, '__esModule', { value: true })
|
|
54
54
|
exports.makeLibSignalRepository = makeLibSignalRepository
|
|
55
|
-
const rb = require('
|
|
55
|
+
const rb = require('whatsapp-rust-bridge')
|
|
56
56
|
const lru_cache_1 = require('lru-cache')
|
|
57
57
|
const Utils_1 = require('../Utils')
|
|
58
58
|
const WABinary_1 = require('../WABinary')
|
|
@@ -60,18 +60,18 @@ const sender_key_name_1 = require('./Group/sender-key-name')
|
|
|
60
60
|
const sender_key_record_1 = require('./Group/sender-key-record')
|
|
61
61
|
const Group_1 = require('./Group')
|
|
62
62
|
const lid_mapping_1 = require('./lid-mapping')
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
function extractIdentityFromPkmsg(ciphertext) {
|
|
65
65
|
try {
|
|
66
66
|
if (!ciphertext || ciphertext.length < 2) {
|
|
67
67
|
return undefined
|
|
68
68
|
}
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
const version = ciphertext[0]
|
|
71
71
|
if ((version & 0xf) !== 3) {
|
|
72
72
|
return undefined
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
const identityKeyArr = rb.getPreKeyMessageIdentityKey(ciphertext)
|
|
76
76
|
if (identityKeyArr) {
|
|
77
77
|
return identityKeyArr
|
|
@@ -82,17 +82,11 @@ function extractIdentityFromPkmsg(ciphertext) {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
function makeLibSignalRepository(auth, logger, pnToLIDFunc) {
|
|
85
|
-
if (!rb) {
|
|
86
|
-
throw new Error(
|
|
87
|
-
'The Signal session (Double Ratchet encryption) requires the "whatsapp-rust-bridge" native ' +
|
|
88
|
-
'module, which failed to load. Make sure it is installed: npm install whatsapp-rust-bridge@0.5.4'
|
|
89
|
-
)
|
|
90
|
-
}
|
|
91
85
|
const lidMapping = new lid_mapping_1.LIDMappingStore(auth.keys, logger, pnToLIDFunc)
|
|
92
86
|
const storage = signalStorage(auth, lidMapping)
|
|
93
87
|
const parsedKeys = auth.keys
|
|
94
88
|
const migratedSessionCache = new lru_cache_1.LRUCache({
|
|
95
|
-
ttl: 3 * 24 * 60 * 60 * 1000,
|
|
89
|
+
ttl: 3 * 24 * 60 * 60 * 1000,
|
|
96
90
|
ttlAutopurge: true,
|
|
97
91
|
updateAgeOnGet: true
|
|
98
92
|
})
|
|
@@ -100,7 +94,7 @@ function makeLibSignalRepository(auth, logger, pnToLIDFunc) {
|
|
|
100
94
|
decryptGroupMessage({ group, authorJid, msg }) {
|
|
101
95
|
const senderName = jidToSignalSenderKeyName(group, authorJid)
|
|
102
96
|
const cipher = new Group_1.GroupCipher(storage, senderName)
|
|
103
|
-
|
|
97
|
+
|
|
104
98
|
return parsedKeys.transaction(async () => {
|
|
105
99
|
return cipher.decrypt(msg)
|
|
106
100
|
}, group)
|
|
@@ -134,7 +128,7 @@ function makeLibSignalRepository(auth, logger, pnToLIDFunc) {
|
|
|
134
128
|
async decryptMessage({ jid, type, ciphertext }) {
|
|
135
129
|
const addr = jidToSignalProtocolAddress(jid)
|
|
136
130
|
const session = new rb.SessionCipher(storage, addr)
|
|
137
|
-
|
|
131
|
+
|
|
138
132
|
if (type === 'pkmsg') {
|
|
139
133
|
const identityKey = extractIdentityFromPkmsg(ciphertext)
|
|
140
134
|
if (identityKey) {
|
|
@@ -157,8 +151,8 @@ function makeLibSignalRepository(auth, logger, pnToLIDFunc) {
|
|
|
157
151
|
}
|
|
158
152
|
return result
|
|
159
153
|
}
|
|
160
|
-
|
|
161
|
-
|
|
154
|
+
|
|
155
|
+
|
|
162
156
|
return parsedKeys.transaction(async () => {
|
|
163
157
|
return await doDecrypt()
|
|
164
158
|
}, jid)
|
|
@@ -166,7 +160,7 @@ function makeLibSignalRepository(auth, logger, pnToLIDFunc) {
|
|
|
166
160
|
async encryptMessage({ jid, data }) {
|
|
167
161
|
const addr = jidToSignalProtocolAddress(jid)
|
|
168
162
|
const cipher = new rb.SessionCipher(storage, addr)
|
|
169
|
-
|
|
163
|
+
|
|
170
164
|
return parsedKeys.transaction(async () => {
|
|
171
165
|
const { type: sigType, body } = await cipher.encrypt(data)
|
|
172
166
|
const type = sigType === 3 ? 'pkmsg' : 'msg'
|
|
@@ -198,25 +192,10 @@ function makeLibSignalRepository(auth, logger, pnToLIDFunc) {
|
|
|
198
192
|
await cipher.initOutgoing(session)
|
|
199
193
|
}, jid)
|
|
200
194
|
},
|
|
201
|
-
async getSessionInfo(jid) {
|
|
202
|
-
try {
|
|
203
|
-
const addr = jidToSignalProtocolAddress(jid)
|
|
204
|
-
const sessBytes = await storage.loadSession(addr.toString())
|
|
205
|
-
if (!sessBytes) return null
|
|
206
|
-
const session = rb.SessionRecord.deserialize(sessBytes)
|
|
207
|
-
const open = session.getOpenSession?.()
|
|
208
|
-
const baseKey = open?.indexInfo?.baseKey
|
|
209
|
-
const registrationId = open?.registrationId
|
|
210
|
-
if (!baseKey || typeof registrationId !== 'number') return null
|
|
211
|
-
return { baseKey: new Uint8Array(baseKey), registrationId }
|
|
212
|
-
} catch (error) {
|
|
213
|
-
return null
|
|
214
|
-
}
|
|
215
|
-
},
|
|
216
195
|
jidToSignalProtocolAddress(jid) {
|
|
217
196
|
return jidToSignalProtocolAddress(jid).toString()
|
|
218
197
|
},
|
|
219
|
-
|
|
198
|
+
|
|
220
199
|
lidMapping,
|
|
221
200
|
async validateSession(jid) {
|
|
222
201
|
try {
|
|
@@ -232,28 +211,28 @@ function makeLibSignalRepository(auth, logger, pnToLIDFunc) {
|
|
|
232
211
|
},
|
|
233
212
|
async deleteSession(jids) {
|
|
234
213
|
if (!jids.length) return
|
|
235
|
-
|
|
214
|
+
|
|
236
215
|
const sessionUpdates = {}
|
|
237
216
|
jids.forEach(jid => {
|
|
238
217
|
const addr = jidToSignalProtocolAddress(jid)
|
|
239
218
|
sessionUpdates[addr.toString()] = null
|
|
240
219
|
})
|
|
241
|
-
|
|
220
|
+
|
|
242
221
|
return parsedKeys.transaction(async () => {
|
|
243
222
|
await auth.keys.set({ session: sessionUpdates })
|
|
244
223
|
}, `delete-${jids.length}-sessions`)
|
|
245
224
|
},
|
|
246
225
|
async migrateSession(fromJid, toJid) {
|
|
247
|
-
|
|
226
|
+
|
|
248
227
|
if (!fromJid || (!(0, WABinary_1.isLidUser)(toJid) && !(0, WABinary_1.isHostedLidUser)(toJid)))
|
|
249
228
|
return { migrated: 0, skipped: 0, total: 0 }
|
|
250
|
-
|
|
229
|
+
|
|
251
230
|
if (!(0, WABinary_1.isPnUser)(fromJid) && !(0, WABinary_1.isHostedPnUser)(fromJid)) {
|
|
252
231
|
return { migrated: 0, skipped: 0, total: 1 }
|
|
253
232
|
}
|
|
254
233
|
const { user } = (0, WABinary_1.jidDecode)(fromJid)
|
|
255
234
|
logger.debug({ fromJid }, 'bulk device migration - loading all user devices')
|
|
256
|
-
|
|
235
|
+
|
|
257
236
|
const { [user]: userDevices } = await parsedKeys.get('device-list', [user])
|
|
258
237
|
if (!userDevices) {
|
|
259
238
|
return { migrated: 0, skipped: 0, total: 0 }
|
|
@@ -263,22 +242,22 @@ function makeLibSignalRepository(auth, logger, pnToLIDFunc) {
|
|
|
263
242
|
if (!userDevices.includes(fromDeviceStr)) {
|
|
264
243
|
userDevices.push(fromDeviceStr)
|
|
265
244
|
}
|
|
266
|
-
|
|
245
|
+
|
|
267
246
|
const uncachedDevices = userDevices.filter(device => {
|
|
268
247
|
const deviceKey = `${user}.${device}`
|
|
269
248
|
return !migratedSessionCache.has(deviceKey)
|
|
270
249
|
})
|
|
271
|
-
|
|
250
|
+
|
|
272
251
|
const deviceSessionKeys = uncachedDevices.map(device => `${user}.${device}`)
|
|
273
252
|
const existingSessions = await parsedKeys.get('session', deviceSessionKeys)
|
|
274
|
-
|
|
253
|
+
|
|
275
254
|
const deviceJids = []
|
|
276
255
|
for (const [sessionKey, sessionData] of Object.entries(existingSessions)) {
|
|
277
256
|
if (sessionData) {
|
|
278
|
-
|
|
257
|
+
|
|
279
258
|
const deviceStr = sessionKey.split('.')[1]
|
|
280
259
|
if (!deviceStr) continue
|
|
281
|
-
const deviceNum = parseInt(deviceStr)
|
|
260
|
+
const deviceNum = parseInt(deviceStr, 10)
|
|
282
261
|
let jid = deviceNum === 0 ? `${user}@s.whatsapp.net` : `${user}:${deviceNum}@s.whatsapp.net`
|
|
283
262
|
if (deviceNum === 99) {
|
|
284
263
|
jid = `${user}:99@hosted`
|
|
@@ -295,7 +274,7 @@ function makeLibSignalRepository(auth, logger, pnToLIDFunc) {
|
|
|
295
274
|
},
|
|
296
275
|
'bulk device migration complete - all user devices processed'
|
|
297
276
|
)
|
|
298
|
-
|
|
277
|
+
|
|
299
278
|
return parsedKeys.transaction(
|
|
300
279
|
async () => {
|
|
301
280
|
const migrationOps = deviceJids.map(jid => {
|
|
@@ -314,31 +293,31 @@ function makeLibSignalRepository(auth, logger, pnToLIDFunc) {
|
|
|
314
293
|
})
|
|
315
294
|
const totalOps = migrationOps.length
|
|
316
295
|
let migratedCount = 0
|
|
317
|
-
|
|
296
|
+
|
|
318
297
|
const pnAddrStrings = Array.from(new Set(migrationOps.map(op => op.fromAddr.toString())))
|
|
319
298
|
const pnSessions = await parsedKeys.get('session', pnAddrStrings)
|
|
320
|
-
|
|
299
|
+
|
|
321
300
|
const sessionUpdates = {}
|
|
322
301
|
for (const op of migrationOps) {
|
|
323
302
|
const pnAddrStr = op.fromAddr.toString()
|
|
324
303
|
const lidAddrStr = op.toAddr.toString()
|
|
325
304
|
const pnSession = pnSessions[pnAddrStr]
|
|
326
305
|
if (pnSession) {
|
|
327
|
-
|
|
306
|
+
|
|
328
307
|
const fromSession = rb.SessionRecord.deserialize(pnSession)
|
|
329
308
|
if (fromSession.haveOpenSession()) {
|
|
330
|
-
|
|
309
|
+
|
|
331
310
|
sessionUpdates[lidAddrStr] = fromSession.serialize()
|
|
332
311
|
sessionUpdates[pnAddrStr] = null
|
|
333
312
|
migratedCount++
|
|
334
313
|
}
|
|
335
314
|
}
|
|
336
315
|
}
|
|
337
|
-
|
|
316
|
+
|
|
338
317
|
if (Object.keys(sessionUpdates).length > 0) {
|
|
339
318
|
await parsedKeys.set({ session: sessionUpdates })
|
|
340
319
|
logger.debug({ migratedSessions: migratedCount }, 'bulk session migration complete')
|
|
341
|
-
|
|
320
|
+
|
|
342
321
|
for (const op of migrationOps) {
|
|
343
322
|
if (sessionUpdates[op.toAddr.toString()]) {
|
|
344
323
|
const deviceKey = `${op.pnUser}.${op.deviceId}`
|
|
@@ -374,12 +353,12 @@ const jidToSignalSenderKeyName = (group, user) => {
|
|
|
374
353
|
return new sender_key_name_1.SenderKeyName(group, jidToSignalProtocolAddress(user))
|
|
375
354
|
}
|
|
376
355
|
function signalStorage({ creds, keys }, lidMapping) {
|
|
377
|
-
|
|
356
|
+
|
|
378
357
|
const resolveLIDSignalAddress = async id => {
|
|
379
358
|
if (id.includes('.')) {
|
|
380
359
|
const [deviceId, device] = id.split('.')
|
|
381
360
|
const [user, domainType_] = deviceId.split('_')
|
|
382
|
-
const domainType = parseInt(domainType_ || '0')
|
|
361
|
+
const domainType = parseInt(domainType_ || '0', 10)
|
|
383
362
|
if (
|
|
384
363
|
domainType === WABinary_1.WAJIDDomains.LID ||
|
|
385
364
|
domainType === WABinary_1.WAJIDDomains.HOSTED_LID ||
|
|
@@ -403,22 +382,22 @@ function signalStorage({ creds, keys }, lidMapping) {
|
|
|
403
382
|
const fetched = await keys.get('session', keysToFetch)
|
|
404
383
|
const sess = fetched[wireJid] || fetched[id]
|
|
405
384
|
if (!sess) return null
|
|
406
|
-
|
|
385
|
+
|
|
407
386
|
if (typeof sess === 'object' && !Buffer.isBuffer(sess) && !ArrayBuffer.isView(sess) && sess._sessions) {
|
|
408
387
|
return null
|
|
409
388
|
}
|
|
410
|
-
|
|
389
|
+
|
|
411
390
|
return Buffer.isBuffer(sess) ? sess : Buffer.from(sess)
|
|
412
|
-
} catch
|
|
391
|
+
} catch {
|
|
413
392
|
return null
|
|
414
393
|
}
|
|
415
394
|
},
|
|
416
395
|
storeSession: async (id, session) => {
|
|
417
|
-
|
|
396
|
+
|
|
418
397
|
await keys.set({ session: { [id]: session.serialize() } })
|
|
419
398
|
},
|
|
420
399
|
isTrustedIdentity: () => {
|
|
421
|
-
return true
|
|
400
|
+
return true
|
|
422
401
|
},
|
|
423
402
|
loadIdentityKey: async id => {
|
|
424
403
|
const wireJid = await resolveLIDSignalAddress(id)
|
|
@@ -433,7 +412,7 @@ function signalStorage({ creds, keys }, lidMapping) {
|
|
|
433
412
|
existingKey.length === identityKey.length &&
|
|
434
413
|
existingKey.every((byte, i) => byte === identityKey[i])
|
|
435
414
|
if (existingKey && !keysMatch) {
|
|
436
|
-
|
|
415
|
+
|
|
437
416
|
await keys.set({
|
|
438
417
|
session: { [wireJid]: null },
|
|
439
418
|
'identity-key': { [wireJid]: identityKey }
|
|
@@ -441,7 +420,7 @@ function signalStorage({ creds, keys }, lidMapping) {
|
|
|
441
420
|
return true
|
|
442
421
|
}
|
|
443
422
|
if (!existingKey) {
|
|
444
|
-
|
|
423
|
+
|
|
445
424
|
await keys.set({ 'identity-key': { [wireJid]: identityKey } })
|
|
446
425
|
return true
|
|
447
426
|
}
|
|
@@ -462,7 +441,8 @@ function signalStorage({ creds, keys }, lidMapping) {
|
|
|
462
441
|
const key = creds.signedPreKey
|
|
463
442
|
return {
|
|
464
443
|
privKey: Buffer.from(key.keyPair.private),
|
|
465
|
-
pubKey: Buffer.from(key.keyPair.public)
|
|
444
|
+
pubKey: Buffer.from(key.keyPair.public),
|
|
445
|
+
signature: key.signature ? Buffer.from(key.signature) : undefined
|
|
466
446
|
}
|
|
467
447
|
},
|
|
468
448
|
loadSenderKey: async senderKeyName => {
|
|
@@ -6,7 +6,7 @@ const WABinary_1 = require('../WABinary')
|
|
|
6
6
|
class LIDMappingStore {
|
|
7
7
|
constructor(keys, logger, pnToLIDFunc) {
|
|
8
8
|
this.mappingCache = new lru_cache_1.LRUCache({
|
|
9
|
-
ttl: 3 * 24 * 60 * 60 * 1000,
|
|
9
|
+
ttl: 3 * 24 * 60 * 60 * 1000,
|
|
10
10
|
ttlAutopurge: true,
|
|
11
11
|
updateAgeOnGet: true
|
|
12
12
|
})
|
|
@@ -20,12 +20,10 @@ class LIDMappingStore {
|
|
|
20
20
|
if (pairs.length === 0) return
|
|
21
21
|
const validatedPairs = []
|
|
22
22
|
for (const { lid, pn } of pairs) {
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
)
|
|
28
|
-
) {
|
|
23
|
+
if (!(
|
|
24
|
+
((0, WABinary_1.isLidUser)(lid) && (0, WABinary_1.isPnUser)(pn)) ||
|
|
25
|
+
((0, WABinary_1.isPnUser)(lid) && (0, WABinary_1.isLidUser)(pn))
|
|
26
|
+
)) {
|
|
29
27
|
this.logger.warn(`Invalid LID-PN mapping: ${lid}, ${pn}`)
|
|
30
28
|
continue
|
|
31
29
|
}
|
|
@@ -77,7 +75,7 @@ class LIDMappingStore {
|
|
|
77
75
|
await this.keys.transaction(async () => {
|
|
78
76
|
await this.keys.set({ 'lid-mapping': batchData })
|
|
79
77
|
}, 'lid-mapping')
|
|
80
|
-
|
|
78
|
+
|
|
81
79
|
for (const [pnUser, lidUser] of Object.entries(pairMap)) {
|
|
82
80
|
this.mappingCache.set(`pn:${pnUser}`, lidUser)
|
|
83
81
|
this.mappingCache.set(`lid:${lidUser}`, pnUser)
|
|
@@ -86,6 +84,26 @@ class LIDMappingStore {
|
|
|
86
84
|
async getLIDForPN(pn) {
|
|
87
85
|
return (await this.getLIDsForPNs([pn]))?.[0]?.lid || null
|
|
88
86
|
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
async getStoredLIDForPN(pn) {
|
|
90
|
+
if (!(0, WABinary_1.isPnUser)(pn) && !(0, WABinary_1.isHostedPnUser)(pn)) return null
|
|
91
|
+
const decoded = (0, WABinary_1.jidDecode)(pn)
|
|
92
|
+
if (!decoded) return null
|
|
93
|
+
const pnUser = decoded.user
|
|
94
|
+
let lidUser = this.mappingCache.get(`pn:${pnUser}`)
|
|
95
|
+
if (!lidUser || typeof lidUser !== 'string') {
|
|
96
|
+
const stored = await this.keys.get('lid-mapping', [pnUser])
|
|
97
|
+
lidUser = stored[pnUser]
|
|
98
|
+
if (lidUser && typeof lidUser === 'string') {
|
|
99
|
+
this.mappingCache.set(`pn:${pnUser}`, lidUser)
|
|
100
|
+
this.mappingCache.set(`lid:${lidUser}`, pnUser)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (!lidUser || typeof lidUser !== 'string') return null
|
|
104
|
+
const pnDevice = decoded.device !== undefined ? decoded.device : 0
|
|
105
|
+
return `${lidUser}${!!pnDevice ? `:${pnDevice}` : ``}@${decoded.server === 'hosted' ? 'hosted.lid' : 'lid'}`
|
|
106
|
+
}
|
|
89
107
|
async getLIDsForPNs(pns) {
|
|
90
108
|
if (pns.length === 0) return null
|
|
91
109
|
const sortedPns = [...new Set(pns)].sort()
|
|
@@ -113,7 +131,7 @@ class LIDMappingStore {
|
|
|
113
131
|
this.logger.warn(`Invalid or empty LID user for PN ${pn}: lidUser = "${lidUser}"`)
|
|
114
132
|
return false
|
|
115
133
|
}
|
|
116
|
-
|
|
134
|
+
|
|
117
135
|
const pnDevice = decoded.device !== undefined ? decoded.device : 0
|
|
118
136
|
const deviceSpecificLid = `${normalizedLidUser}${!!pnDevice ? `:${pnDevice}` : ``}@${decoded.server === 'hosted' ? 'hosted.lid' : 'lid'}`
|
|
119
137
|
this.logger.trace(`getLIDForPN: ${pn} → ${deviceSpecificLid} (user mapping with device ${pnDevice})`)
|
|
@@ -168,7 +186,7 @@ class LIDMappingStore {
|
|
|
168
186
|
}
|
|
169
187
|
}
|
|
170
188
|
if (Object.keys(usyncFetch).length > 0) {
|
|
171
|
-
const result = await this.pnToLIDFunc?.(Object.keys(usyncFetch))
|
|
189
|
+
const result = await this.pnToLIDFunc?.(Object.keys(usyncFetch))
|
|
172
190
|
if (result && result.length > 0) {
|
|
173
191
|
await this.storeLIDPNMappings(result)
|
|
174
192
|
for (const pair of result) {
|
package/lib/Socket/aigroups.js
CHANGED
|
@@ -10,7 +10,7 @@ const makeAIGroupsSocket = config => {
|
|
|
10
10
|
const sock = (0, groups_1.makeGroupsSocket)(config)
|
|
11
11
|
const { ev, query } = sock
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
const aiGroupQuery = async (jid, type, content) =>
|
|
15
15
|
query({
|
|
16
16
|
tag: 'iq',
|
|
@@ -27,7 +27,7 @@ const makeAIGroupsSocket = config => {
|
|
|
27
27
|
return (0, exports.extractAIGroupMetadata)(result)
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
sock.ws.on('CB:notification,w:gp2', async node => {
|
|
32
32
|
const { attrs, content } = node
|
|
33
33
|
if (!Array.isArray(content) || content.length === 0) return
|
|
@@ -44,12 +44,12 @@ const makeAIGroupsSocket = config => {
|
|
|
44
44
|
if (!groupId) return
|
|
45
45
|
|
|
46
46
|
if (tag === 'create') {
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
try {
|
|
49
49
|
const meta = await aiGroupMetadata(groupId)
|
|
50
50
|
ev.emit('groups.upsert', [meta])
|
|
51
51
|
} catch {
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
ev.emit('groups.upsert', [{ id: groupId }])
|
|
54
54
|
}
|
|
55
55
|
} else if (tag === 'promote' || tag === 'demote' || tag === 'remove' || tag === 'add') {
|
|
@@ -189,7 +189,7 @@ const makeAIGroupsSocket = config => {
|
|
|
189
189
|
exports.makeAIGroupsSocket = makeAIGroupsSocket
|
|
190
190
|
|
|
191
191
|
const extractAIGroupMetadata = result => {
|
|
192
|
-
|
|
192
|
+
|
|
193
193
|
const createNode = (0, WABinary_1.getBinaryNodeChild)(result, 'create')
|
|
194
194
|
const group =
|
|
195
195
|
(0, WABinary_1.getBinaryNodeChild)(createNode || result, 'group') ||
|