@areumtecnologia/wasockets 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -39,15 +39,35 @@ function makeLibSignalRepository(auth, logger, pnToLIDFunc) {
39
39
  })
40
40
 
41
41
  const repository = {
42
- decryptGroupMessage({ group, authorJid, msg }) {
43
- const senderName = jidToSignalSenderKeyName(group, authorJid)
44
- const cipher = new GroupCipher(storage, senderName)
45
-
46
- // Use transaction to ensure atomicity
47
- return parsedKeys.transaction(async () => {
48
- return cipher.decrypt(msg)
49
- }, group)
50
- },
42
+ decryptGroupMessage({ group, authorJid, msg }) {
43
+ const decryptWithAuthor = (author) => {
44
+ const senderName = jidToSignalSenderKeyName(group, author)
45
+ const cipher = new GroupCipher(storage, senderName)
46
+ return cipher.decrypt(msg)
47
+ }
48
+
49
+ // Use transaction to ensure atomicity
50
+ return parsedKeys.transaction(async () => {
51
+ try {
52
+ return await decryptWithAuthor(authorJid)
53
+ }
54
+
55
+ catch (error) {
56
+ if (!isMissingSenderKeySessionError(error)) {
57
+ throw error
58
+ }
59
+
60
+ const alternateAuthorJid = await getAlternateSenderKeyAuthor(authorJid, lidMapping)
61
+
62
+ if (!alternateAuthorJid || alternateAuthorJid === authorJid) {
63
+ throw error
64
+ }
65
+
66
+ logger.debug({ group, authorJid, alternateAuthorJid }, 'retrying group decrypt with alternate sender key identity')
67
+ return await decryptWithAuthor(alternateAuthorJid)
68
+ }
69
+ }, group)
70
+ },
51
71
 
52
72
  async processSenderKeyDistributionMessage({ item, authorJid }) {
53
73
  const builder = new GroupSessionBuilder(storage)
@@ -68,13 +88,25 @@ function makeLibSignalRepository(auth, logger, pnToLIDFunc) {
68
88
  return parsedKeys.transaction(async () => {
69
89
  const { [senderNameStr]: senderKey } = await auth.keys.get('sender-key', [senderNameStr])
70
90
 
71
- if (!senderKey) {
72
- await storage.storeSenderKey(senderName, new SenderKeyRecord())
73
- }
74
-
75
- await builder.process(senderName, senderMsg)
76
- }, item.groupId)
77
- },
91
+ if (!senderKey) {
92
+ await storage.storeSenderKey(senderName, new SenderKeyRecord())
93
+ }
94
+
95
+ await builder.process(senderName, senderMsg)
96
+
97
+ const alternateAuthorJid = await getAlternateSenderKeyAuthor(authorJid, lidMapping)
98
+
99
+ if (alternateAuthorJid && alternateAuthorJid !== authorJid) {
100
+ const primarySenderName = senderName.toString()
101
+ const alternateSenderName = jidToSignalSenderKeyName(item.groupId, alternateAuthorJid).toString()
102
+ const { [primarySenderName]: primarySenderKey } = await auth.keys.get('sender-key', [primarySenderName])
103
+
104
+ if (primarySenderKey) {
105
+ await auth.keys.set({ 'sender-key': { [alternateSenderName]: primarySenderKey } })
106
+ }
107
+ }
108
+ }, item.groupId)
109
+ },
78
110
 
79
111
  async decryptMessage({ jid, type, ciphertext }) {
80
112
  const addr = jidToSignalProtocolAddress(jid)
@@ -351,11 +383,28 @@ const jidToSignalProtocolAddress = (jid) => {
351
383
  return new ProtocolAddress(signalUser, finalDevice)
352
384
  }
353
385
 
354
- const jidToSignalSenderKeyName = (group, user) => {
355
- return new SenderKeyName(group, jidToSignalProtocolAddress(user))
356
- }
357
-
358
- function signalStorage({ creds, keys }, lidMapping) {
386
+ const jidToSignalSenderKeyName = (group, user) => {
387
+ return new SenderKeyName(group, jidToSignalProtocolAddress(user))
388
+ }
389
+
390
+ const getAlternateSenderKeyAuthor = async (authorJid, lidMapping) => {
391
+ if (isPnUser(authorJid) || isHostedPnUser(authorJid)) {
392
+ return await lidMapping.getLIDForPN(authorJid)
393
+ }
394
+
395
+ if (isLidUser(authorJid) || isHostedLidUser(authorJid)) {
396
+ return await lidMapping.getPNForLID(authorJid)
397
+ }
398
+
399
+ return null
400
+ }
401
+
402
+ const isMissingSenderKeySessionError = (error) => {
403
+ const message = error?.message || error?.toString?.() || ''
404
+ return message.includes('No session found to decrypt message')
405
+ }
406
+
407
+ function signalStorage({ creds, keys }, lidMapping) {
359
408
  // Shared function to resolve PN signal address to LID if mapping exists
360
409
  const resolveLIDSignalAddress = async (id) => {
361
410
  if (id.includes('.')) {
@@ -448,4 +497,4 @@ function signalStorage({ creds, keys }, lidMapping) {
448
497
 
449
498
  module.exports = {
450
499
  makeLibSignalRepository
451
- }
500
+ }
@@ -27,11 +27,11 @@ class WebSocketClient extends AbstractSocketClient {
27
27
  }
28
28
 
29
29
  get isClosing() {
30
- this.socket?.readyState === CLOSING
30
+ return this.socket?.readyState === CLOSING
31
31
  }
32
32
 
33
33
  get isConnecting() {
34
- this.socket?.readyState === CONNECTING
34
+ return this.socket?.readyState === CONNECTING
35
35
  }
36
36
 
37
37
  connect() {
@@ -68,4 +68,4 @@ class WebSocketClient extends AbstractSocketClient {
68
68
 
69
69
  module.exports = {
70
70
  WebSocketClient
71
- }
71
+ }
@@ -3,13 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true })
4
4
 
5
5
  const {
6
- QueryIds,
7
- XWAPaths
6
+ QueryIds,
7
+ XWAPaths
8
8
  } = require("../Types")
9
9
  const { generateProfilePicture } = require("../Utils")
10
10
  const { getBinaryNodeChild } = require("../WABinary")
11
11
  const { makeGroupsSocket } = require("./groups")
12
- const { executeWMexQuery: genericExecuteWMexQuery } = require("./mex")
12
+ const { executeWMexQuery: genericExecuteWMexQuery } = require("./mex")
13
13
 
14
14
  const parseNewsletterCreateResponse = (response) => {
15
15
  const { id, thread_metadata: thread, viewer_metadata: viewer } = response
@@ -34,29 +34,29 @@ const parseNewsletterMetadata = (result) => {
34
34
  if (typeof result !== 'object' || result === null) {
35
35
  return null
36
36
  }
37
-
37
+
38
38
  if ('id' in result && typeof result.id === 'string') {
39
39
  return result
40
40
  }
41
-
41
+
42
42
  if ('result' in result && typeof result.result === 'object' && result.result !== null && 'id' in result.result) {
43
43
  return result.result
44
44
  }
45
-
45
+
46
46
  return null
47
47
  }
48
48
 
49
49
  const makeNewsletterSocket = (config) => {
50
50
  const suki = makeGroupsSocket(config)
51
- const {
52
- query,
53
- generateMessageTag
51
+ const {
52
+ query,
53
+ generateMessageTag
54
54
  } = suki
55
-
55
+
56
56
  const executeWMexQuery = (variables, queryId, dataPath) => {
57
57
  return genericExecuteWMexQuery(variables, queryId, dataPath, query, generateMessageTag)
58
58
  }
59
-
59
+
60
60
  const newsletterUpdate = async (jid, updates) => {
61
61
  const variables = {
62
62
  newsletter_id: jid,
@@ -65,13 +65,13 @@ const makeNewsletterSocket = (config) => {
65
65
  settings: null
66
66
  }
67
67
  }
68
-
68
+
69
69
  return executeWMexQuery(variables, QueryIds.UPDATE_METADATA, XWAPaths.UPDATE)
70
70
  }
71
-
71
+
72
72
  return {
73
73
  ...suki,
74
- executeWMexQuery,
74
+ executeWMexQuery,
75
75
  newsletterCreate: async (name, description) => {
76
76
  const variables = {
77
77
  input: {
@@ -79,15 +79,18 @@ const makeNewsletterSocket = (config) => {
79
79
  description: description ?? null
80
80
  }
81
81
  }
82
-
82
+
83
83
  const rawResponse = await executeWMexQuery(variables, QueryIds.CREATE, XWAPaths.CREATE)
84
-
84
+
85
85
  return parseNewsletterCreateResponse(rawResponse)
86
86
  },
87
87
  newsletterUpdate,
88
88
  newsletterSubscribers: async (jid) => {
89
89
  return executeWMexQuery({ newsletter_id: jid }, QueryIds.SUBSCRIBERS, XWAPaths.SUBSCRIBERS)
90
90
  },
91
+ newsletterSubscribed: async () => {
92
+ return executeWMexQuery({}, QueryIds.SUBSCRIBED, XWAPaths.xwa2_newsletter_subscribed);
93
+ },
91
94
  newsletterMetadata: async (type, key) => {
92
95
  const variables = {
93
96
  fetch_creation_time: true,
@@ -98,9 +101,9 @@ const makeNewsletterSocket = (config) => {
98
101
  type: type.toUpperCase()
99
102
  }
100
103
  }
101
-
104
+
102
105
  const result = await executeWMexQuery(variables, QueryIds.METADATA, XWAPaths.METADATA)
103
-
106
+
104
107
  return parseNewsletterMetadata(result)
105
108
  },
106
109
  newsletterFollow: (jid) => {
@@ -150,15 +153,15 @@ const makeNewsletterSocket = (config) => {
150
153
  const messageUpdateAttrs = {
151
154
  count: count.toString()
152
155
  }
153
-
156
+
154
157
  if (typeof since === 'number') {
155
158
  messageUpdateAttrs.since = since.toString()
156
159
  }
157
-
160
+
158
161
  if (after) {
159
162
  messageUpdateAttrs.after = after.toString()
160
163
  }
161
-
164
+
162
165
  const result = await query({
163
166
  tag: 'iq',
164
167
  attrs: {
@@ -174,7 +177,7 @@ const makeNewsletterSocket = (config) => {
174
177
  }
175
178
  ]
176
179
  })
177
-
180
+
178
181
  return result
179
182
  },
180
183
  subscribeNewsletterUpdates: async (jid) => {
@@ -188,10 +191,10 @@ const makeNewsletterSocket = (config) => {
188
191
  },
189
192
  content: [{ tag: 'live_updates', attrs: {}, content: [] }]
190
193
  })
191
-
194
+
192
195
  const liveUpdatesNode = getBinaryNodeChild(result, 'live_updates')
193
196
  const duration = liveUpdatesNode?.attrs?.duration
194
-
197
+
195
198
  return duration ? { duration: duration } : null
196
199
  },
197
200
  newsletterAdminCount: async (jid) => {
@@ -211,6 +214,6 @@ const makeNewsletterSocket = (config) => {
211
214
  }
212
215
 
213
216
  module.exports = {
214
- makeNewsletterSocket,
215
- parseNewsletterMetadata
217
+ makeNewsletterSocket,
218
+ parseNewsletterMetadata
216
219
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@areumtecnologia/wasockets",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "WhatsApp API Modification By areumtecnologia",
5
5
  "keywords": [
6
6
  "whatsapp",
@@ -19,14 +19,12 @@
19
19
  },
20
20
  "license": "MIT",
21
21
  "author": "areumtecnologia",
22
-
23
22
  "main": "lib/index.js",
24
23
  "files": [
25
24
  "lib/*",
26
25
  "WAProto/*",
27
26
  "engine-requirements.js"
28
27
  ],
29
-
30
28
  "scripts": {
31
29
  "changelog:last": "conventional-changelog -p angular -r 2",
32
30
  "changelog:preview": "conventional-changelog -p angular -u",
@@ -37,7 +35,6 @@
37
35
  "release": "release-it",
38
36
  "test": "jest"
39
37
  },
40
-
41
38
  "dependencies": {
42
39
  "@hapi/boom": "^9.1.3",
43
40
  "@adiwajshing/keyed-db": "^0.2.4",
@@ -57,7 +54,6 @@
57
54
  "qrcode-terminal": "^0.12.0",
58
55
  "ws": "^8.13.0"
59
56
  },
60
-
61
57
  "devDependencies": {
62
58
  "@types/jest": "^29.5.14",
63
59
  "@types/node": "^16.0.0",
@@ -77,28 +73,22 @@
77
73
  "typedoc-plugin-markdown": "4.4.2",
78
74
  "typescript": "^5.8.2"
79
75
  },
80
-
81
76
  "peerDependencies": {
82
- "jimp": "^0.22.12",
77
+ "jimp": "^0.22.12",
83
78
  "sharp": "*"
84
79
  },
85
-
86
80
  "peerDependenciesMeta": {
87
81
  "jimp": {
88
82
  "optional": true
89
83
  }
90
84
  },
91
-
92
85
  "packageManager": "yarn@1.22.19",
93
-
94
86
  "engines": {
95
87
  "node": ">=20.0.0"
96
88
  },
97
-
98
89
  "directories": {
99
90
  "lib": "lib"
100
91
  },
101
-
102
92
  "bugs": {
103
93
  "url": "https://github.com/areumtecnologia/WaSockets/issues"
104
94
  }