@hansaka02/baileys 7.3.2 → 7.3.6
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/lib/Defaults/baileys-version.json +2 -2
- package/lib/Defaults/connection.js +51 -0
- package/lib/Defaults/constants.js +74 -0
- package/lib/Defaults/history.js +19 -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 +5 -18
- package/lib/Signal/Group/sender-key-distribution-message.js +7 -7
- package/lib/Signal/Group/sender-key-message.js +12 -8
- package/lib/Signal/Group/sender-key-record.js +7 -16
- package/lib/Signal/Group/sender-key-state.js +15 -61
- package/lib/Signal/Group/sender-message-key.js +2 -2
- package/lib/Signal/libsignal.js +237 -177
- package/lib/Signal/lid-mapping.js +128 -71
- package/lib/Socket/Client/types.js +2 -2
- package/lib/Socket/Client/websocket.js +25 -16
- package/lib/Socket/business.js +46 -33
- package/lib/Socket/chats.js +286 -170
- package/lib/Socket/community.js +215 -77
- package/lib/Socket/groups.js +77 -61
- package/lib/Socket/index.js +4 -4
- package/lib/Socket/messages-recv.js +629 -457
- package/lib/Socket/messages-send.js +645 -656
- package/lib/Socket/mex.js +61 -0
- package/lib/Socket/newsletter.js +166 -245
- package/lib/Socket/socket.js +396 -170
- package/lib/Store/index.js +27 -11
- package/lib/Store/make-cache-manager-store.js +14 -15
- package/lib/Store/make-in-memory-store.js +28 -24
- package/lib/Types/LabelAssociation.js +2 -2
- package/lib/Types/Message.js +6 -6
- package/lib/Types/MexUpdates.js +5 -5
- package/lib/Types/Newsletter.js +32 -25
- package/lib/Types/State.js +4 -4
- package/lib/Types/index.js +28 -12
- package/lib/Utils/auth-utils.js +212 -375
- package/lib/Utils/baileys-event-stream.js +68 -69
- package/lib/Utils/browser-utils.js +43 -0
- package/lib/Utils/business.js +63 -53
- package/lib/Utils/chat-utils.js +241 -106
- package/lib/Utils/crypto.js +25 -45
- package/lib/Utils/decode-wa-message.js +361 -311
- package/lib/Utils/event-buffer.js +97 -42
- package/lib/Utils/generics.js +90 -207
- package/lib/Utils/history.js +29 -27
- package/lib/Utils/index.js +28 -14
- package/lib/Utils/link-preview.js +24 -62
- package/lib/Utils/logger.js +5 -5
- package/lib/Utils/lt-hash.js +29 -23
- package/lib/Utils/make-mutex.js +26 -28
- package/lib/Utils/message-retry-manager.js +55 -7
- package/lib/Utils/messages-media.js +434 -247
- package/lib/Utils/messages.js +963 -917
- package/lib/Utils/noise-handler.js +60 -20
- package/lib/Utils/pre-key-manager.js +126 -0
- package/lib/Utils/process-message.js +216 -141
- package/lib/Utils/signal.js +75 -37
- package/lib/Utils/use-multi-file-auth-state.js +18 -22
- package/lib/Utils/validate-connection.js +96 -66
- package/lib/WABinary/constants.js +1268 -1268
- package/lib/WABinary/decode.js +62 -34
- package/lib/WABinary/encode.js +57 -36
- package/lib/WABinary/generic-utils.js +4 -4
- package/lib/WABinary/index.js +27 -11
- package/lib/WABinary/jid-utils.js +58 -11
- package/lib/WAM/constants.js +19064 -11563
- package/lib/WAM/encode.js +71 -14
- 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 +51 -28
- package/lib/WAUSync/index.js +27 -11
- package/lib/index.js +60 -31
- package/package.json +12 -17
- package/WAProto/AICommon/AICommon.d.ts +0 -11702
- package/WAProto/Adv/Adv.d.ts +0 -643
- package/WAProto/BotMetadata/BotMetadata.d.ts +0 -5654
- package/WAProto/Cert/Cert.d.ts +0 -613
- package/WAProto/ChatLockSettings/ChatLockSettings.d.ts +0 -476
- package/WAProto/CompanionReg/CompanionReg.d.ts +0 -1361
- package/WAProto/DeviceCapabilities/DeviceCapabilities.d.ts +0 -577
- package/WAProto/E2E/E2E.d.ts +0 -41724
- package/WAProto/Ephemeral/Ephemeral.d.ts +0 -114
- package/WAProto/HistorySync/HistorySync.d.ts +0 -51700
- package/WAProto/LidMigrationSyncPayload/LidMigrationSyncPayload.d.ts +0 -229
- package/WAProto/MdStorageChatRowOpaqueData/MdStorageChatRowOpaqueData.d.ts +0 -583
- package/WAProto/MdStorageMsgRowOpaqueData/MdStorageMsgRowOpaqueData.d.ts +0 -42897
- package/WAProto/MmsRetry/MmsRetry.d.ts +0 -243
- package/WAProto/Protocol/Protocol.d.ts +0 -270
- package/WAProto/Reporting/Reporting.d.ts +0 -371
- package/WAProto/ServerSync/ServerSync.d.ts +0 -1285
- package/WAProto/SignalLocalStorageProtocol/SignalLocalStorageProtocol.d.ts +0 -1868
- package/WAProto/SignalWhisperTextProtocol/SignalWhisperTextProtocol.d.ts +0 -767
- package/WAProto/StatusAttributions/StatusAttributions.d.ts +0 -1027
- package/WAProto/SyncAction/SyncAction.d.ts +0 -11193
- package/WAProto/UserPassword/UserPassword.d.ts +0 -363
- package/WAProto/VnameCert/VnameCert.d.ts +0 -821
- package/WAProto/Wa6/Wa6.d.ts +0 -2128
- package/WAProto/Web/Web.d.ts +0 -46383
- package/WAProto/index.d.ts +0 -55
- package/lib/Defaults/index.d.ts +0 -77
- package/lib/Signal/Group/ciphertext-message.d.ts +0 -9
- package/lib/Signal/Group/group-session-builder.d.ts +0 -17
- package/lib/Signal/Group/group_cipher.d.ts +0 -19
- package/lib/Signal/Group/index.d.ts +0 -11
- package/lib/Signal/Group/keyhelper.d.ts +0 -16
- package/lib/Signal/Group/sender-chain-key.d.ts +0 -14
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +0 -17
- package/lib/Signal/Group/sender-key-message.d.ts +0 -19
- package/lib/Signal/Group/sender-key-name.d.ts +0 -19
- package/lib/Signal/Group/sender-key-record.d.ts +0 -32
- package/lib/Signal/Group/sender-key-state.d.ts +0 -44
- package/lib/Signal/Group/sender-message-key.d.ts +0 -11
- package/lib/Signal/libsignal.d.ts +0 -8
- package/lib/Signal/lid-mapping.d.ts +0 -28
- package/lib/Socket/Client/index.d.ts +0 -2
- package/lib/Socket/Client/types.d.ts +0 -16
- package/lib/Socket/Client/websocket.d.ts +0 -13
- package/lib/Socket/business.d.ts +0 -187
- package/lib/Socket/chats.d.ts +0 -97
- package/lib/Socket/community.d.ts +0 -129
- package/lib/Socket/groups.d.ts +0 -129
- package/lib/Socket/index.d.ts +0 -191
- package/lib/Socket/messages-recv.d.ts +0 -174
- package/lib/Socket/messages-send.d.ts +0 -165
- package/lib/Socket/newsletter.d.ts +0 -145
- package/lib/Socket/socket.d.ts +0 -45
- package/lib/Socket/usync.d.ts +0 -37
- package/lib/Socket/usync.js +0 -83
- package/lib/Store/index.d.ts +0 -4
- package/lib/Store/make-cache-manager-store.d.ts +0 -14
- package/lib/Store/make-in-memory-store.d.ts +0 -123
- package/lib/Store/make-ordered-dictionary.d.ts +0 -12
- package/lib/Store/object-repository.d.ts +0 -10
- package/lib/Types/Auth.d.ts +0 -121
- package/lib/Types/Bussiness.d.ts +0 -28
- package/lib/Types/Call.d.ts +0 -14
- package/lib/Types/Chat.d.ts +0 -143
- package/lib/Types/Contact.d.ts +0 -23
- package/lib/Types/Events.d.ts +0 -226
- package/lib/Types/GroupMetadata.d.ts +0 -66
- package/lib/Types/Label.d.ts +0 -48
- package/lib/Types/LabelAssociation.d.ts +0 -35
- package/lib/Types/Message.d.ts +0 -484
- package/lib/Types/MexUpdates.d.ts +0 -9
- package/lib/Types/Newsletter.d.ts +0 -109
- package/lib/Types/Product.d.ts +0 -92
- package/lib/Types/Signal.d.ts +0 -98
- package/lib/Types/Socket.d.ts +0 -141
- package/lib/Types/State.d.ts +0 -41
- package/lib/Types/USync.d.ts +0 -26
- package/lib/Types/index.d.ts +0 -80
- package/lib/Utils/auth-utils.d.ts +0 -21
- package/lib/Utils/baileys-event-stream.d.ts +0 -18
- package/lib/Utils/business.d.ts +0 -29
- package/lib/Utils/chat-utils.d.ts +0 -82
- package/lib/Utils/crypto.d.ts +0 -56
- package/lib/Utils/decode-wa-message.d.ts +0 -53
- package/lib/Utils/event-buffer.d.ts +0 -39
- package/lib/Utils/generics.d.ts +0 -117
- package/lib/Utils/history.d.ts +0 -23
- package/lib/Utils/index.d.ts +0 -20
- package/lib/Utils/link-preview.d.ts +0 -23
- package/lib/Utils/logger.d.ts +0 -13
- package/lib/Utils/lt-hash.d.ts +0 -14
- package/lib/Utils/make-mutex.d.ts +0 -9
- package/lib/Utils/message-retry-manager.d.ts +0 -88
- package/lib/Utils/messages-media.d.ts +0 -135
- package/lib/Utils/messages.d.ts +0 -105
- package/lib/Utils/noise-handler.d.ts +0 -20
- package/lib/Utils/process-message.d.ts +0 -49
- package/lib/Utils/signal.d.ts +0 -42
- package/lib/Utils/use-mongo-file-auth-state.d.ts +0 -6
- package/lib/Utils/use-mongo-file-auth-state.js +0 -84
- package/lib/Utils/use-multi-file-auth-state.d.ts +0 -13
- package/lib/Utils/use-single-file-auth-state.d.ts +0 -13
- package/lib/Utils/use-single-file-auth-state.js +0 -80
- package/lib/Utils/validate-connection.d.ts +0 -13
- package/lib/WABinary/constants.d.ts +0 -30
- package/lib/WABinary/decode.d.ts +0 -9
- package/lib/WABinary/encode.d.ts +0 -3
- package/lib/WABinary/generic-utils.d.ts +0 -28
- package/lib/WABinary/index.d.ts +0 -5
- package/lib/WABinary/jid-utils.d.ts +0 -58
- package/lib/WABinary/types.d.ts +0 -22
- package/lib/WAM/BinaryInfo.d.ts +0 -16
- package/lib/WAM/constants.d.ts +0 -47
- package/lib/WAM/encode.d.ts +0 -3
- package/lib/WAM/index.d.ts +0 -3
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.d.ts +0 -28
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -10
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -26
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -14
- package/lib/WAUSync/Protocols/USyncLIDProtocol.d.ts +0 -10
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -14
- package/lib/WAUSync/Protocols/index.d.ts +0 -6
- package/lib/WAUSync/USyncQuery.d.ts +0 -31
- package/lib/WAUSync/USyncUser.d.ts +0 -12
- package/lib/WAUSync/index.d.ts +0 -3
- package/lib/index.d.ts +0 -13
package/lib/Utils/signal.js
CHANGED
|
@@ -2,16 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
const { KEY_BUNDLE_TYPE } = require("../Defaults/constants")
|
|
6
|
+
const {
|
|
7
|
+
S_WHATSAPP_NET,
|
|
8
|
+
getBinaryNodeChild,
|
|
9
|
+
getBinaryNodeChildren,
|
|
10
|
+
getBinaryNodeChildUInt,
|
|
11
|
+
getBinaryNodeChildBuffer,
|
|
12
|
+
assertNodeErrorFree,
|
|
13
|
+
jidDecode,
|
|
14
|
+
getServerFromDomainType,
|
|
15
|
+
WAJIDDomains,
|
|
16
|
+
} = require("../WABinary")
|
|
17
|
+
const {
|
|
18
|
+
Curve,
|
|
19
|
+
generateSignalPubKey
|
|
20
|
+
} = require("./crypto")
|
|
21
|
+
const { encodeBigEndian } = require("./generics")
|
|
22
|
+
|
|
23
|
+
function chunk(array, size) {
|
|
24
|
+
const chunks = []
|
|
25
|
+
for (let i = 0; i < array.length; i += size) {
|
|
26
|
+
chunks.push(array.slice(i, i + size))
|
|
27
|
+
}
|
|
28
|
+
return chunks
|
|
29
|
+
}
|
|
10
30
|
|
|
11
31
|
const createSignalIdentity = (wid, accountSignatureKey) => {
|
|
12
32
|
return {
|
|
13
33
|
identifier: { name: wid, deviceId: 0 },
|
|
14
|
-
identifierKey:
|
|
34
|
+
identifierKey: generateSignalPubKey(accountSignatureKey)
|
|
15
35
|
}
|
|
16
36
|
}
|
|
17
37
|
|
|
@@ -30,7 +50,7 @@ const generateOrGetPreKeys = (creds, range) => {
|
|
|
30
50
|
const newPreKeys = {}
|
|
31
51
|
if (remaining > 0) {
|
|
32
52
|
for (let i = creds.nextPreKeyId; i <= lastPreKeyId; i++) {
|
|
33
|
-
newPreKeys[i] =
|
|
53
|
+
newPreKeys[i] = Curve.generateKeyPair()
|
|
34
54
|
}
|
|
35
55
|
}
|
|
36
56
|
return {
|
|
@@ -44,7 +64,7 @@ const xmppSignedPreKey = (key) => ({
|
|
|
44
64
|
tag: 'skey',
|
|
45
65
|
attrs: {},
|
|
46
66
|
content: [
|
|
47
|
-
{ tag: 'id', attrs: {}, content:
|
|
67
|
+
{ tag: 'id', attrs: {}, content: encodeBigEndian(key.keyId, 3) },
|
|
48
68
|
{ tag: 'value', attrs: {}, content: key.keyPair.public },
|
|
49
69
|
{ tag: 'signature', attrs: {}, content: key.signature }
|
|
50
70
|
]
|
|
@@ -54,63 +74,81 @@ const xmppPreKey = (pair, id) => ({
|
|
|
54
74
|
tag: 'key',
|
|
55
75
|
attrs: {},
|
|
56
76
|
content: [
|
|
57
|
-
{ tag: 'id', attrs: {}, content:
|
|
77
|
+
{ tag: 'id', attrs: {}, content: encodeBigEndian(id, 3) },
|
|
58
78
|
{ tag: 'value', attrs: {}, content: pair.public }
|
|
59
79
|
]
|
|
60
80
|
})
|
|
61
81
|
|
|
62
82
|
const parseAndInjectE2ESessions = async (node, repository) => {
|
|
63
|
-
const extractKey = (key) =>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
const extractKey = (key) => key
|
|
84
|
+
? {
|
|
85
|
+
keyId: getBinaryNodeChildUInt(key, 'id', 3),
|
|
86
|
+
publicKey: generateSignalPubKey(getBinaryNodeChildBuffer(key, 'value')),
|
|
87
|
+
signature: getBinaryNodeChildBuffer(key, 'signature')
|
|
88
|
+
}
|
|
89
|
+
: undefined
|
|
90
|
+
const nodes = getBinaryNodeChildren(getBinaryNodeChild(node, 'list'), 'user')
|
|
91
|
+
|
|
69
92
|
for (const node of nodes) {
|
|
70
|
-
|
|
93
|
+
assertNodeErrorFree(node)
|
|
71
94
|
}
|
|
95
|
+
|
|
72
96
|
// Most of the work in repository.injectE2ESession is CPU intensive, not IO
|
|
73
97
|
// So Promise.all doesn't really help here,
|
|
74
98
|
// but blocks even loop if we're using it inside keys.transaction, and it makes it "sync" actually
|
|
75
99
|
// This way we chunk it in smaller parts and between those parts we can yield to the event loop
|
|
76
100
|
// It's rare case when you need to E2E sessions for so many users, but it's possible
|
|
77
101
|
const chunkSize = 100
|
|
78
|
-
const chunks =
|
|
102
|
+
const chunks = chunk(nodes, chunkSize)
|
|
103
|
+
|
|
79
104
|
for (const nodesChunk of chunks) {
|
|
80
|
-
|
|
81
|
-
const signedKey =
|
|
82
|
-
const key =
|
|
83
|
-
const identity =
|
|
105
|
+
for (const node of nodesChunk) {
|
|
106
|
+
const signedKey = getBinaryNodeChild(node, 'skey')
|
|
107
|
+
const key = getBinaryNodeChild(node, 'key')
|
|
108
|
+
const identity = getBinaryNodeChildBuffer(node, 'identity')
|
|
84
109
|
const jid = node.attrs.jid
|
|
85
|
-
const registrationId =
|
|
110
|
+
const registrationId = getBinaryNodeChildUInt(node, 'registration', 4)
|
|
86
111
|
await repository.injectE2ESession({
|
|
87
112
|
jid,
|
|
88
113
|
session: {
|
|
89
114
|
registrationId: registrationId,
|
|
90
|
-
identityKey:
|
|
115
|
+
identityKey: generateSignalPubKey(identity),
|
|
91
116
|
signedPreKey: extractKey(signedKey),
|
|
92
117
|
preKey: extractKey(key)
|
|
93
118
|
}
|
|
94
119
|
})
|
|
95
|
-
}
|
|
120
|
+
}
|
|
96
121
|
}
|
|
97
122
|
}
|
|
98
123
|
|
|
99
|
-
const extractDeviceJids = (result, myJid, excludeZeroDevices) => {
|
|
100
|
-
const { user: myUser, device: myDevice } =
|
|
124
|
+
const extractDeviceJids = (result, myJid, myLid, excludeZeroDevices) => {
|
|
125
|
+
const { user: myUser, device: myDevice } = jidDecode(myJid)
|
|
101
126
|
const extracted = []
|
|
127
|
+
|
|
102
128
|
for (const userResult of result) {
|
|
103
129
|
const { devices, id } = userResult
|
|
104
|
-
const { user } =
|
|
130
|
+
const decoded = jidDecode(id), { user, server } = decoded
|
|
131
|
+
|
|
132
|
+
let { domainType } = decoded
|
|
133
|
+
|
|
105
134
|
const deviceList = devices?.deviceList
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
)
|
|
112
|
-
|
|
135
|
+
|
|
136
|
+
if (!Array.isArray(deviceList)) continue
|
|
137
|
+
|
|
138
|
+
for (const { id: device, keyIndex, isHosted } of deviceList) {
|
|
139
|
+
if ((!excludeZeroDevices || device !== 0) && // if zero devices are not-excluded, or device is non zero
|
|
140
|
+
((myUser !== user && myLid !== user) || myDevice !== device) && // either different user or if me user, not this device
|
|
141
|
+
(device === 0 || !!keyIndex) // ensure that "key-index" is specified for "non-zero" devices, produces a bad req otherwise
|
|
142
|
+
) {
|
|
143
|
+
if (isHosted) {
|
|
144
|
+
domainType = domainType === WAJIDDomains.LID ? WAJIDDomains.HOSTED_LID : WAJIDDomains.HOSTED
|
|
113
145
|
}
|
|
146
|
+
extracted.push({
|
|
147
|
+
user,
|
|
148
|
+
device,
|
|
149
|
+
domainType,
|
|
150
|
+
server: getServerFromDomainType(server, domainType)
|
|
151
|
+
})
|
|
114
152
|
}
|
|
115
153
|
}
|
|
116
154
|
}
|
|
@@ -140,11 +178,11 @@ const getNextPreKeysNode = async (state, count) => {
|
|
|
140
178
|
attrs: {
|
|
141
179
|
xmlns: 'encrypt',
|
|
142
180
|
type: 'set',
|
|
143
|
-
to:
|
|
181
|
+
to: S_WHATSAPP_NET,
|
|
144
182
|
},
|
|
145
183
|
content: [
|
|
146
|
-
{ tag: 'registration', attrs: {}, content:
|
|
147
|
-
{ tag: 'type', attrs: {}, content:
|
|
184
|
+
{ tag: 'registration', attrs: {}, content: encodeBigEndian(creds.registrationId) },
|
|
185
|
+
{ tag: 'type', attrs: {}, content: KEY_BUNDLE_TYPE },
|
|
148
186
|
{ tag: 'identity', attrs: {}, content: creds.signedIdentityKey.public },
|
|
149
187
|
{ tag: 'list', attrs: {}, content: Object.keys(preKeys).map(k => xmppPreKey(preKeys[+k], +k)) },
|
|
150
188
|
xmppSignedPreKey(creds.signedPreKey)
|
|
@@ -1,17 +1,13 @@
|
|
|
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
|
-
const
|
|
5
|
+
const { Mutex } = require("async-mutex")
|
|
6
|
+
const { promises } = require("fs")
|
|
7
|
+
const { join } = require("path")
|
|
8
|
+
const { proto } = require("../../WAProto")
|
|
9
|
+
const { initAuthCreds } = require("./auth-utils")
|
|
10
|
+
const { BufferJSON } = require("./generics")
|
|
15
11
|
// We need to lock files due to the fact that we are using async functions to read and write files
|
|
16
12
|
// https://github.com/WhiskeySockets/Baileys/issues/794
|
|
17
13
|
// https://github.com/nodejs/node/issues/26338
|
|
@@ -22,7 +18,7 @@ const fileLocks = new Map()
|
|
|
22
18
|
const getFileLock = (path) => {
|
|
23
19
|
let mutex = fileLocks.get(path)
|
|
24
20
|
if (!mutex) {
|
|
25
|
-
mutex = new
|
|
21
|
+
mutex = new Mutex()
|
|
26
22
|
fileLocks.set(path, mutex)
|
|
27
23
|
}
|
|
28
24
|
|
|
@@ -39,11 +35,11 @@ const getFileLock = (path) => {
|
|
|
39
35
|
const useMultiFileAuthState = async (folder) => {
|
|
40
36
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
37
|
const writeData = async (data, file) => {
|
|
42
|
-
const filePath =
|
|
38
|
+
const filePath = join(folder, fixFileName(file))
|
|
43
39
|
const mutex = getFileLock(filePath)
|
|
44
40
|
return mutex.acquire().then(async (release) => {
|
|
45
41
|
try {
|
|
46
|
-
await
|
|
42
|
+
await promises.writeFile(filePath, JSON.stringify(data, BufferJSON.replacer))
|
|
47
43
|
} finally {
|
|
48
44
|
release()
|
|
49
45
|
}
|
|
@@ -51,47 +47,47 @@ const useMultiFileAuthState = async (folder) => {
|
|
|
51
47
|
}
|
|
52
48
|
const readData = async (file) => {
|
|
53
49
|
try {
|
|
54
|
-
const filePath =
|
|
50
|
+
const filePath = join(folder, fixFileName(file))
|
|
55
51
|
const mutex = getFileLock(filePath)
|
|
56
52
|
const data = await mutex.acquire().then(async (release) => {
|
|
57
53
|
try {
|
|
58
|
-
return await
|
|
54
|
+
return await promises.readFile(filePath, { encoding: 'utf-8' })
|
|
59
55
|
} finally {
|
|
60
56
|
release()
|
|
61
57
|
}
|
|
62
58
|
})
|
|
63
59
|
|
|
64
|
-
return JSON.parse(data,
|
|
60
|
+
return JSON.parse(data, BufferJSON.reviver)
|
|
65
61
|
} catch (error) {
|
|
66
62
|
return null
|
|
67
63
|
}
|
|
68
64
|
}
|
|
69
65
|
const removeData = async (file) => {
|
|
70
66
|
try {
|
|
71
|
-
const filePath =
|
|
67
|
+
const filePath = join(folder, fixFileName(file))
|
|
72
68
|
const mutex = getFileLock(filePath)
|
|
73
69
|
await mutex.acquire().then(async (release) => {
|
|
74
70
|
try {
|
|
75
|
-
await
|
|
71
|
+
await promises.unlink(filePath)
|
|
76
72
|
} finally {
|
|
77
73
|
release()
|
|
78
74
|
}
|
|
79
75
|
})
|
|
80
76
|
} catch {}
|
|
81
77
|
}
|
|
82
|
-
const folderInfo = await
|
|
78
|
+
const folderInfo = await promises.stat(folder).catch(() => { })
|
|
83
79
|
if (folderInfo) {
|
|
84
80
|
if (!folderInfo.isDirectory()) {
|
|
85
81
|
throw new Error(`found something that is not a directory at ${folder}, either delete it or specify a different location`)
|
|
86
82
|
}
|
|
87
83
|
}
|
|
88
84
|
else {
|
|
89
|
-
await
|
|
85
|
+
await promises.mkdir(folder, { recursive: true })
|
|
90
86
|
}
|
|
91
87
|
const fixFileName = (file) => {
|
|
92
88
|
return file?.replace(/\//g, '__')?.replace(/:/g, '-')
|
|
93
89
|
}
|
|
94
|
-
const creds = await readData('creds.json') ||
|
|
90
|
+
const creds = await readData('creds.json') || initAuthCreds()
|
|
95
91
|
return {
|
|
96
92
|
state: {
|
|
97
93
|
creds,
|
|
@@ -101,7 +97,7 @@ const useMultiFileAuthState = async (folder) => {
|
|
|
101
97
|
await Promise.all(ids.map(async (id) => {
|
|
102
98
|
let value = await readData(`${type}-${id}.json`)
|
|
103
99
|
if (type === 'app-state-sync-key' && value) {
|
|
104
|
-
value =
|
|
100
|
+
value = proto.Message.AppStateSyncKeyData.fromObject(value)
|
|
105
101
|
}
|
|
106
102
|
data[id] = value
|
|
107
103
|
}))
|
|
@@ -2,14 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
const { Boom } = require("@hapi/boom")
|
|
6
|
+
const { createHash } = require("crypto")
|
|
7
|
+
const { proto } = require("../../WAProto")
|
|
8
|
+
const {
|
|
9
|
+
KEY_BUNDLE_TYPE,
|
|
10
|
+
WA_ADV_ACCOUNT_SIG_PREFIX,
|
|
11
|
+
WA_ADV_DEVICE_SIG_PREFIX,
|
|
12
|
+
WA_ADV_HOSTED_ACCOUNT_SIG_PREFIX
|
|
13
|
+
} = require("../Defaults/constants")
|
|
14
|
+
const {
|
|
15
|
+
jidDecode,
|
|
16
|
+
getBinaryNodeChild,
|
|
17
|
+
S_WHATSAPP_NET
|
|
18
|
+
} = require("../WABinary")
|
|
19
|
+
const {
|
|
20
|
+
Curve,
|
|
21
|
+
hmacSign
|
|
22
|
+
} = require("./crypto")
|
|
23
|
+
const { encodeBigEndian } = require("./generics")
|
|
24
|
+
const { createSignalIdentity } = require("./signal")
|
|
13
25
|
|
|
14
26
|
const getUserAgent = (config) => {
|
|
15
27
|
return {
|
|
@@ -18,8 +30,10 @@ const getUserAgent = (config) => {
|
|
|
18
30
|
secondary: config.version[1],
|
|
19
31
|
tertiary: config.version[2],
|
|
20
32
|
},
|
|
21
|
-
platform:
|
|
22
|
-
|
|
33
|
+
platform: /*config.browser[1].toLocaleLowerCase().includes('android')
|
|
34
|
+
? proto.ClientPayload.UserAgent.Platform.ANDROID
|
|
35
|
+
:*/ proto.ClientPayload.UserAgent.Platform.WEB,
|
|
36
|
+
releaseChannel: proto.ClientPayload.UserAgent.ReleaseChannel.RELEASE,
|
|
23
37
|
osVersion: '0.1',
|
|
24
38
|
device: 'Desktop',
|
|
25
39
|
osBuildNumber: '0.1',
|
|
@@ -31,14 +45,15 @@ const getUserAgent = (config) => {
|
|
|
31
45
|
}
|
|
32
46
|
|
|
33
47
|
const PLATFORM_MAP = {
|
|
34
|
-
'Mac OS':
|
|
35
|
-
'Windows':
|
|
36
|
-
'Android': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WIN_HYBRID
|
|
48
|
+
'Mac OS': proto.ClientPayload.WebInfo.WebSubPlatform.DARWIN,
|
|
49
|
+
'Windows': proto.ClientPayload.WebInfo.WebSubPlatform.WIN32
|
|
37
50
|
}
|
|
38
51
|
|
|
39
52
|
const getWebInfo = (config) => {
|
|
40
|
-
let webSubPlatform =
|
|
41
|
-
if (config.syncFullHistory &&
|
|
53
|
+
let webSubPlatform = proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER
|
|
54
|
+
if (config.syncFullHistory &&
|
|
55
|
+
PLATFORM_MAP[config.browser[0]] &&
|
|
56
|
+
config.browser[1] === 'Desktop') {
|
|
42
57
|
webSubPlatform = PLATFORM_MAP[config.browser[0]]
|
|
43
58
|
}
|
|
44
59
|
return { webSubPlatform }
|
|
@@ -46,35 +61,48 @@ const getWebInfo = (config) => {
|
|
|
46
61
|
|
|
47
62
|
const getClientPayload = (config) => {
|
|
48
63
|
const payload = {
|
|
49
|
-
connectType:
|
|
50
|
-
connectReason:
|
|
64
|
+
connectType: proto.ClientPayload.ConnectType.WIFI_UNKNOWN,
|
|
65
|
+
connectReason: proto.ClientPayload.ConnectReason.USER_ACTIVATED,
|
|
51
66
|
userAgent: getUserAgent(config),
|
|
52
67
|
}
|
|
53
|
-
|
|
68
|
+
|
|
69
|
+
/*if (!config.browser[1].toLocaleLowerCase().includes('android')) {
|
|
70
|
+
payload.webInfo = getWebInfo(config)
|
|
71
|
+
}*/
|
|
72
|
+
payload.webInfo = getWebInfo(config)
|
|
73
|
+
|
|
54
74
|
return payload
|
|
55
75
|
}
|
|
56
76
|
|
|
57
77
|
const generateLoginNode = (userJid, config) => {
|
|
58
|
-
const { user, device } =
|
|
78
|
+
const { user, device } = jidDecode(userJid)
|
|
59
79
|
const payload = {
|
|
60
80
|
...getClientPayload(config),
|
|
61
|
-
passive:
|
|
81
|
+
passive: true,
|
|
62
82
|
pull: true,
|
|
63
83
|
username: +user,
|
|
64
84
|
device: device,
|
|
85
|
+
// TODO: investigate (hard set as false atm)
|
|
86
|
+
lidDbMigrated: false
|
|
65
87
|
}
|
|
66
|
-
return
|
|
88
|
+
return proto.ClientPayload.fromObject(payload)
|
|
67
89
|
}
|
|
68
90
|
|
|
69
91
|
const getPlatformType = (platform) => {
|
|
70
92
|
const platformType = platform.toUpperCase()
|
|
71
|
-
|
|
93
|
+
|
|
94
|
+
/*if (platformType === 'ANDROID') {
|
|
95
|
+
return proto.DeviceProps.PlatformType.ANDROID_PHONE
|
|
96
|
+
}*/
|
|
97
|
+
|
|
98
|
+
return (proto.DeviceProps.PlatformType[platformType] ||
|
|
99
|
+
proto.DeviceProps.PlatformType.CHROME)
|
|
72
100
|
}
|
|
73
101
|
|
|
74
102
|
const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentityKey }, config) => {
|
|
75
103
|
// the app version needs to be md5 hashed
|
|
76
104
|
// and passed in
|
|
77
|
-
const appVersionBuf =
|
|
105
|
+
const appVersionBuf = createHash('md5')
|
|
78
106
|
.update(config.version.join('.')) // join as string
|
|
79
107
|
.digest()
|
|
80
108
|
|
|
@@ -106,7 +134,7 @@ const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentity
|
|
|
106
134
|
}
|
|
107
135
|
}
|
|
108
136
|
|
|
109
|
-
const companionProto =
|
|
137
|
+
const companionProto = proto.DeviceProps.encode(companion).finish()
|
|
110
138
|
|
|
111
139
|
const registerPayload = {
|
|
112
140
|
...getClientPayload(config),
|
|
@@ -115,73 +143,76 @@ const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentity
|
|
|
115
143
|
devicePairingData: {
|
|
116
144
|
buildHash: appVersionBuf,
|
|
117
145
|
deviceProps: companionProto,
|
|
118
|
-
eRegid:
|
|
119
|
-
eKeytype:
|
|
146
|
+
eRegid: encodeBigEndian(registrationId),
|
|
147
|
+
eKeytype: KEY_BUNDLE_TYPE,
|
|
120
148
|
eIdent: signedIdentityKey.public,
|
|
121
|
-
eSkeyId:
|
|
149
|
+
eSkeyId: encodeBigEndian(signedPreKey.keyId, 3),
|
|
122
150
|
eSkeyVal: signedPreKey.keyPair.public,
|
|
123
151
|
eSkeySig: signedPreKey.signature,
|
|
124
152
|
}
|
|
125
153
|
}
|
|
126
154
|
|
|
127
|
-
return
|
|
155
|
+
return proto.ClientPayload.fromObject(registerPayload)
|
|
128
156
|
}
|
|
129
157
|
|
|
130
158
|
const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, signalIdentities }) => {
|
|
131
159
|
const msgId = stanza.attrs.id
|
|
132
|
-
const pairSuccessNode =
|
|
133
|
-
const deviceIdentityNode =
|
|
134
|
-
const platformNode =
|
|
135
|
-
const deviceNode =
|
|
136
|
-
const businessNode =
|
|
160
|
+
const pairSuccessNode = getBinaryNodeChild(stanza, 'pair-success')
|
|
161
|
+
const deviceIdentityNode = getBinaryNodeChild(pairSuccessNode, 'device-identity')
|
|
162
|
+
const platformNode = getBinaryNodeChild(pairSuccessNode, 'platform')
|
|
163
|
+
const deviceNode = getBinaryNodeChild(pairSuccessNode, 'device')
|
|
164
|
+
const businessNode = getBinaryNodeChild(pairSuccessNode, 'biz')
|
|
165
|
+
|
|
137
166
|
if (!deviceIdentityNode || !deviceNode) {
|
|
138
|
-
throw new
|
|
167
|
+
throw new Boom('Missing device-identity or device in pair success node', { data: stanza })
|
|
139
168
|
}
|
|
140
|
-
|
|
169
|
+
|
|
170
|
+
const bizName = businessNode?.attrs.name
|
|
141
171
|
const jid = deviceNode.attrs.jid
|
|
142
172
|
const lid = deviceNode.attrs.lid
|
|
143
|
-
const { details, hmac, accountType } =
|
|
173
|
+
const { details, hmac, accountType } = proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content)
|
|
144
174
|
|
|
145
175
|
let hmacPrefix = Buffer.from([])
|
|
146
|
-
|
|
147
|
-
|
|
176
|
+
|
|
177
|
+
if (accountType !== undefined && accountType === proto.ADVEncryptionType.HOSTED) {
|
|
178
|
+
hmacPrefix = WA_ADV_HOSTED_ACCOUNT_SIG_PREFIX
|
|
148
179
|
}
|
|
149
|
-
|
|
150
|
-
const advSign =
|
|
180
|
+
|
|
181
|
+
const advSign = hmacSign(Buffer.concat([hmacPrefix, details]), Buffer.from(advSecretKey, 'base64'))
|
|
182
|
+
|
|
151
183
|
if (Buffer.compare(hmac, advSign) !== 0) {
|
|
152
|
-
throw new
|
|
184
|
+
throw new Boom('Invalid account signature')
|
|
153
185
|
}
|
|
154
|
-
|
|
155
|
-
const account =
|
|
186
|
+
|
|
187
|
+
const account = proto.ADVSignedDeviceIdentity.decode(details)
|
|
156
188
|
const { accountSignatureKey, accountSignature, details: deviceDetails } = account
|
|
157
|
-
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
decodedDeviceIdentity.deviceType === WAProto_1.proto.ADVEncryptionType.HOSTED
|
|
162
|
-
? Buffer.from([6, 5])
|
|
163
|
-
: Buffer.from([6, 0])
|
|
189
|
+
const deviceIdentity = proto.ADVDeviceIdentity.decode(deviceDetails)
|
|
190
|
+
const accountSignaturePrefix = deviceIdentity.deviceType === proto.ADVEncryptionType.HOSTED
|
|
191
|
+
? WA_ADV_HOSTED_ACCOUNT_SIG_PREFIX
|
|
192
|
+
: WA_ADV_ACCOUNT_SIG_PREFIX
|
|
164
193
|
const accountMsg = Buffer.concat([accountSignaturePrefix, deviceDetails, signedIdentityKey.public])
|
|
165
|
-
|
|
166
|
-
|
|
194
|
+
|
|
195
|
+
if (!Curve.verify(accountSignatureKey, accountMsg, accountSignature)) {
|
|
196
|
+
throw new Boom('Failed to verify account signature')
|
|
167
197
|
}
|
|
168
|
-
|
|
198
|
+
|
|
169
199
|
const deviceMsg = Buffer.concat([
|
|
170
|
-
|
|
200
|
+
WA_ADV_DEVICE_SIG_PREFIX,
|
|
171
201
|
deviceDetails,
|
|
172
202
|
signedIdentityKey.public,
|
|
173
203
|
accountSignatureKey
|
|
174
204
|
])
|
|
175
|
-
|
|
176
|
-
|
|
205
|
+
|
|
206
|
+
account.deviceSignature = Curve.sign(signedIdentityKey.private, deviceMsg)
|
|
207
|
+
|
|
208
|
+
const identity = createSignalIdentity(lid, accountSignatureKey)
|
|
177
209
|
const accountEnc = encodeSignedDeviceIdentity(account, false)
|
|
178
|
-
const deviceIdentityData = WAProto_1.proto.ADVDeviceIdentity.decode(account.details)
|
|
179
210
|
const reply = {
|
|
180
211
|
tag: 'iq',
|
|
181
212
|
attrs: {
|
|
182
|
-
to:
|
|
213
|
+
to: S_WHATSAPP_NET,
|
|
183
214
|
type: 'result',
|
|
184
|
-
id: msgId
|
|
215
|
+
id: msgId
|
|
185
216
|
},
|
|
186
217
|
content: [
|
|
187
218
|
{
|
|
@@ -190,22 +221,21 @@ const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, s
|
|
|
190
221
|
content: [
|
|
191
222
|
{
|
|
192
223
|
tag: 'device-identity',
|
|
193
|
-
attrs: { 'key-index':
|
|
224
|
+
attrs: { 'key-index': deviceIdentity.keyIndex.toString() },
|
|
194
225
|
content: accountEnc
|
|
195
226
|
}
|
|
196
227
|
]
|
|
197
228
|
}
|
|
198
229
|
]
|
|
199
230
|
}
|
|
231
|
+
|
|
200
232
|
const authUpdate = {
|
|
201
233
|
account,
|
|
202
234
|
me: { id: jid, name: bizName, lid },
|
|
203
|
-
signalIdentities: [
|
|
204
|
-
|
|
205
|
-
identity
|
|
206
|
-
],
|
|
207
|
-
platform: platformNode?.attrs?.name
|
|
235
|
+
signalIdentities: [...(signalIdentities || []), identity],
|
|
236
|
+
platform: platformNode?.attrs.name
|
|
208
237
|
}
|
|
238
|
+
|
|
209
239
|
return {
|
|
210
240
|
creds: authUpdate,
|
|
211
241
|
reply
|
|
@@ -219,7 +249,7 @@ const encodeSignedDeviceIdentity = (account, includeSignatureKey) => {
|
|
|
219
249
|
if (!includeSignatureKey || !account.accountSignatureKey?.length) {
|
|
220
250
|
account.accountSignatureKey = null
|
|
221
251
|
}
|
|
222
|
-
return
|
|
252
|
+
return proto.ADVSignedDeviceIdentity.encode(account).finish()
|
|
223
253
|
}
|
|
224
254
|
|
|
225
255
|
module.exports = {
|