@hansaka02/baileys 7.3.4 → 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.
Files changed (50) hide show
  1. package/README.md +203 -247
  2. package/lib/Defaults/baileys-version.json +2 -2
  3. package/lib/Defaults/connection.js +1 -1
  4. package/lib/Defaults/constants.js +13 -1
  5. package/lib/Defaults/history.js +3 -1
  6. package/lib/Signal/Group/sender-chain-key.js +1 -14
  7. package/lib/Signal/Group/sender-key-distribution-message.js +2 -2
  8. package/lib/Signal/Group/sender-key-record.js +2 -11
  9. package/lib/Signal/Group/sender-key-state.js +11 -57
  10. package/lib/Signal/libsignal.js +200 -116
  11. package/lib/Signal/lid-mapping.js +121 -68
  12. package/lib/Socket/Client/websocket.js +9 -2
  13. package/lib/Socket/business.js +5 -1
  14. package/lib/Socket/chats.js +180 -89
  15. package/lib/Socket/community.js +169 -41
  16. package/lib/Socket/groups.js +25 -21
  17. package/lib/Socket/messages-recv.js +458 -333
  18. package/lib/Socket/messages-send.js +517 -572
  19. package/lib/Socket/mex.js +61 -0
  20. package/lib/Socket/newsletter.js +159 -252
  21. package/lib/Socket/socket.js +283 -100
  22. package/lib/Types/Newsletter.js +32 -25
  23. package/lib/Utils/auth-utils.js +189 -354
  24. package/lib/Utils/browser-utils.js +43 -0
  25. package/lib/Utils/chat-utils.js +166 -41
  26. package/lib/Utils/decode-wa-message.js +77 -35
  27. package/lib/Utils/event-buffer.js +80 -24
  28. package/lib/Utils/generics.js +28 -128
  29. package/lib/Utils/history.js +10 -8
  30. package/lib/Utils/index.js +1 -1
  31. package/lib/Utils/link-preview.js +17 -32
  32. package/lib/Utils/lt-hash.js +28 -22
  33. package/lib/Utils/make-mutex.js +26 -28
  34. package/lib/Utils/message-retry-manager.js +51 -3
  35. package/lib/Utils/messages-media.js +343 -151
  36. package/lib/Utils/messages.js +806 -792
  37. package/lib/Utils/noise-handler.js +33 -2
  38. package/lib/Utils/pre-key-manager.js +126 -0
  39. package/lib/Utils/process-message.js +115 -55
  40. package/lib/Utils/signal.js +45 -18
  41. package/lib/Utils/validate-connection.js +52 -29
  42. package/lib/WABinary/constants.js +1268 -1268
  43. package/lib/WABinary/decode.js +58 -4
  44. package/lib/WABinary/encode.js +54 -7
  45. package/lib/WABinary/jid-utils.js +58 -11
  46. package/lib/WAM/constants.js +19064 -11563
  47. package/lib/WAM/encode.js +57 -8
  48. package/lib/WAUSync/USyncQuery.js +35 -19
  49. package/package.json +9 -8
  50. package/lib/Socket/usync.js +0 -83
@@ -2,7 +2,6 @@
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", { value: true })
4
4
 
5
- const { chunk } = require("lodash")
6
5
  const { KEY_BUNDLE_TYPE } = require("../Defaults/constants")
7
6
  const {
8
7
  S_WHATSAPP_NET,
@@ -11,7 +10,9 @@ const {
11
10
  getBinaryNodeChildUInt,
12
11
  getBinaryNodeChildBuffer,
13
12
  assertNodeErrorFree,
14
- jidDecode
13
+ jidDecode,
14
+ getServerFromDomainType,
15
+ WAJIDDomains,
15
16
  } = require("../WABinary")
16
17
  const {
17
18
  Curve,
@@ -19,6 +20,14 @@ const {
19
20
  } = require("./crypto")
20
21
  const { encodeBigEndian } = require("./generics")
21
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
+ }
30
+
22
31
  const createSignalIdentity = (wid, accountSignatureKey) => {
23
32
  return {
24
33
  identifier: { name: wid, deviceId: 0 },
@@ -71,15 +80,19 @@ const xmppPreKey = (pair, id) => ({
71
80
  })
72
81
 
73
82
  const parseAndInjectE2ESessions = async (node, repository) => {
74
- const extractKey = (key) => (key ? ({
75
- keyId: getBinaryNodeChildUInt(key, 'id', 3),
76
- publicKey: generateSignalPubKey(getBinaryNodeChildBuffer(key, 'value')),
77
- signature: getBinaryNodeChildBuffer(key, 'signature')
78
- }) : undefined)
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
79
90
  const nodes = getBinaryNodeChildren(getBinaryNodeChild(node, 'list'), 'user')
91
+
80
92
  for (const node of nodes) {
81
93
  assertNodeErrorFree(node)
82
94
  }
95
+
83
96
  // Most of the work in repository.injectE2ESession is CPU intensive, not IO
84
97
  // So Promise.all doesn't really help here,
85
98
  // but blocks even loop if we're using it inside keys.transaction, and it makes it "sync" actually
@@ -87,8 +100,9 @@ const parseAndInjectE2ESessions = async (node, repository) => {
87
100
  // It's rare case when you need to E2E sessions for so many users, but it's possible
88
101
  const chunkSize = 100
89
102
  const chunks = chunk(nodes, chunkSize)
103
+
90
104
  for (const nodesChunk of chunks) {
91
- await Promise.all(nodesChunk.map(async (node) => {
105
+ for (const node of nodesChunk) {
92
106
  const signedKey = getBinaryNodeChild(node, 'skey')
93
107
  const key = getBinaryNodeChild(node, 'key')
94
108
  const identity = getBinaryNodeChildBuffer(node, 'identity')
@@ -103,25 +117,38 @@ const parseAndInjectE2ESessions = async (node, repository) => {
103
117
  preKey: extractKey(key)
104
118
  }
105
119
  })
106
- }))
120
+ }
107
121
  }
108
122
  }
109
123
 
110
- const extractDeviceJids = (result, myJid, excludeZeroDevices) => {
124
+ const extractDeviceJids = (result, myJid, myLid, excludeZeroDevices) => {
111
125
  const { user: myUser, device: myDevice } = jidDecode(myJid)
112
126
  const extracted = []
127
+
113
128
  for (const userResult of result) {
114
129
  const { devices, id } = userResult
115
- const { user } = jidDecode(id)
130
+ const decoded = jidDecode(id), { user, server } = decoded
131
+
132
+ let { domainType } = decoded
133
+
116
134
  const deviceList = devices?.deviceList
117
- if (Array.isArray(deviceList)) {
118
- for (const { id: device, keyIndex } of deviceList) {
119
- if ((!excludeZeroDevices || device !== 0) && // if zero devices are not-excluded, or device is non zero
120
- (myUser !== user || myDevice !== device) && // either different user or if me user, not this device
121
- (device === 0 || !!keyIndex) // ensure that "key-index" is specified for "non-zero" devices, produces a bad req otherwise
122
- ) {
123
- extracted.push({ user, device })
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
124
145
  }
146
+ extracted.push({
147
+ user,
148
+ device,
149
+ domainType,
150
+ server: getServerFromDomainType(server, domainType)
151
+ })
125
152
  }
126
153
  }
127
154
  }
@@ -5,7 +5,12 @@ Object.defineProperty(exports, "__esModule", { value: true })
5
5
  const { Boom } = require("@hapi/boom")
6
6
  const { createHash } = require("crypto")
7
7
  const { proto } = require("../../WAProto")
8
- const { KEY_BUNDLE_TYPE } = require("../Defaults/constants")
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")
9
14
  const {
10
15
  jidDecode,
11
16
  getBinaryNodeChild,
@@ -25,7 +30,9 @@ const getUserAgent = (config) => {
25
30
  secondary: config.version[1],
26
31
  tertiary: config.version[2],
27
32
  },
28
- platform: proto.ClientPayload.UserAgent.Platform.WEB,
33
+ platform: /*config.browser[1].toLocaleLowerCase().includes('android')
34
+ ? proto.ClientPayload.UserAgent.Platform.ANDROID
35
+ :*/ proto.ClientPayload.UserAgent.Platform.WEB,
29
36
  releaseChannel: proto.ClientPayload.UserAgent.ReleaseChannel.RELEASE,
30
37
  osVersion: '0.1',
31
38
  device: 'Desktop',
@@ -39,13 +46,14 @@ const getUserAgent = (config) => {
39
46
 
40
47
  const PLATFORM_MAP = {
41
48
  'Mac OS': proto.ClientPayload.WebInfo.WebSubPlatform.DARWIN,
42
- 'Windows': proto.ClientPayload.WebInfo.WebSubPlatform.WIN32,
43
- 'Android': proto.ClientPayload.WebInfo.WebSubPlatform.WIN_HYBRID
49
+ 'Windows': proto.ClientPayload.WebInfo.WebSubPlatform.WIN32
44
50
  }
45
51
 
46
52
  const getWebInfo = (config) => {
47
53
  let webSubPlatform = proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER
48
- if (config.syncFullHistory && PLATFORM_MAP[config.browser[0]]) {
54
+ if (config.syncFullHistory &&
55
+ PLATFORM_MAP[config.browser[0]] &&
56
+ config.browser[1] === 'Desktop') {
49
57
  webSubPlatform = PLATFORM_MAP[config.browser[0]]
50
58
  }
51
59
  return { webSubPlatform }
@@ -57,7 +65,12 @@ const getClientPayload = (config) => {
57
65
  connectReason: proto.ClientPayload.ConnectReason.USER_ACTIVATED,
58
66
  userAgent: getUserAgent(config),
59
67
  }
60
- payload.webInfo = getWebInfo(config)
68
+
69
+ /*if (!config.browser[1].toLocaleLowerCase().includes('android')) {
70
+ payload.webInfo = getWebInfo(config)
71
+ }*/
72
+ payload.webInfo = getWebInfo(config)
73
+
61
74
  return payload
62
75
  }
63
76
 
@@ -65,17 +78,25 @@ const generateLoginNode = (userJid, config) => {
65
78
  const { user, device } = jidDecode(userJid)
66
79
  const payload = {
67
80
  ...getClientPayload(config),
68
- passive: false,
81
+ passive: true,
69
82
  pull: true,
70
83
  username: +user,
71
84
  device: device,
85
+ // TODO: investigate (hard set as false atm)
86
+ lidDbMigrated: false
72
87
  }
73
88
  return proto.ClientPayload.fromObject(payload)
74
89
  }
75
90
 
76
91
  const getPlatformType = (platform) => {
77
92
  const platformType = platform.toUpperCase()
78
- return proto.DeviceProps.PlatformType[platformType] || proto.DeviceProps.PlatformType.DESKTOP
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)
79
100
  }
80
101
 
81
102
  const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentityKey }, config) => {
@@ -141,54 +162,57 @@ const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, s
141
162
  const platformNode = getBinaryNodeChild(pairSuccessNode, 'platform')
142
163
  const deviceNode = getBinaryNodeChild(pairSuccessNode, 'device')
143
164
  const businessNode = getBinaryNodeChild(pairSuccessNode, 'biz')
165
+
144
166
  if (!deviceIdentityNode || !deviceNode) {
145
167
  throw new Boom('Missing device-identity or device in pair success node', { data: stanza })
146
168
  }
147
- const bizName = businessNode?.attrs?.name
169
+
170
+ const bizName = businessNode?.attrs.name
148
171
  const jid = deviceNode.attrs.jid
149
172
  const lid = deviceNode.attrs.lid
150
173
  const { details, hmac, accountType } = proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content)
151
174
 
152
175
  let hmacPrefix = Buffer.from([])
176
+
153
177
  if (accountType !== undefined && accountType === proto.ADVEncryptionType.HOSTED) {
154
- hmacPrefix = Buffer.from([6, 5])
178
+ hmacPrefix = WA_ADV_HOSTED_ACCOUNT_SIG_PREFIX
155
179
  }
156
-
180
+
157
181
  const advSign = hmacSign(Buffer.concat([hmacPrefix, details]), Buffer.from(advSecretKey, 'base64'))
182
+
158
183
  if (Buffer.compare(hmac, advSign) !== 0) {
159
184
  throw new Boom('Invalid account signature')
160
185
  }
161
-
186
+
162
187
  const account = proto.ADVSignedDeviceIdentity.decode(details)
163
188
  const { accountSignatureKey, accountSignature, details: deviceDetails } = account
164
-
165
- const decodedDeviceIdentity = proto.ADVDeviceIdentity.decode(deviceDetails)
166
-
167
- const accountSignaturePrefix =
168
- decodedDeviceIdentity.deviceType === proto.ADVEncryptionType.HOSTED
169
- ? Buffer.from([6, 5])
170
- : 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
171
193
  const accountMsg = Buffer.concat([accountSignaturePrefix, deviceDetails, signedIdentityKey.public])
194
+
172
195
  if (!Curve.verify(accountSignatureKey, accountMsg, accountSignature)) {
173
196
  throw new Boom('Failed to verify account signature')
174
197
  }
175
-
198
+
176
199
  const deviceMsg = Buffer.concat([
177
- Buffer.from([6, 1]),
200
+ WA_ADV_DEVICE_SIG_PREFIX,
178
201
  deviceDetails,
179
202
  signedIdentityKey.public,
180
203
  accountSignatureKey
181
204
  ])
205
+
182
206
  account.deviceSignature = Curve.sign(signedIdentityKey.private, deviceMsg)
207
+
183
208
  const identity = createSignalIdentity(lid, accountSignatureKey)
184
209
  const accountEnc = encodeSignedDeviceIdentity(account, false)
185
- const deviceIdentityData = proto.ADVDeviceIdentity.decode(account.details)
186
210
  const reply = {
187
211
  tag: 'iq',
188
212
  attrs: {
189
213
  to: S_WHATSAPP_NET,
190
214
  type: 'result',
191
- id: msgId,
215
+ id: msgId
192
216
  },
193
217
  content: [
194
218
  {
@@ -197,22 +221,21 @@ const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, s
197
221
  content: [
198
222
  {
199
223
  tag: 'device-identity',
200
- attrs: { 'key-index': deviceIdentityData.keyIndex.toString() },
224
+ attrs: { 'key-index': deviceIdentity.keyIndex.toString() },
201
225
  content: accountEnc
202
226
  }
203
227
  ]
204
228
  }
205
229
  ]
206
230
  }
231
+
207
232
  const authUpdate = {
208
233
  account,
209
234
  me: { id: jid, name: bizName, lid },
210
- signalIdentities: [
211
- ...(signalIdentities || []),
212
- identity
213
- ],
214
- platform: platformNode?.attrs?.name
235
+ signalIdentities: [...(signalIdentities || []), identity],
236
+ platform: platformNode?.attrs.name
215
237
  }
238
+
216
239
  return {
217
240
  creds: authUpdate,
218
241
  reply