@zapo-js/fake-server 0.3.0 → 1.0.0

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 (298) hide show
  1. package/README.md +3 -3
  2. package/dist/api/AppStateSyncManager.d.ts +0 -1
  3. package/dist/api/AppStateSyncManager.js +0 -1
  4. package/dist/api/FakePairingDriver.d.ts +0 -1
  5. package/dist/api/FakePairingDriver.js +0 -1
  6. package/dist/api/FakePeer.d.ts +77 -4
  7. package/dist/api/FakePeer.js +201 -1
  8. package/dist/api/FakeWaServer.d.ts +11 -1
  9. package/dist/api/FakeWaServer.js +34 -2
  10. package/dist/api/PreKeyDispenser.d.ts +0 -1
  11. package/dist/api/PreKeyDispenser.js +0 -1
  12. package/dist/api/Scenario.d.ts +0 -1
  13. package/dist/api/Scenario.js +0 -1
  14. package/dist/api/ServerRegistries.d.ts +0 -1
  15. package/dist/api/ServerRegistries.js +0 -1
  16. package/dist/api/iq-handlers.d.ts +0 -1
  17. package/dist/api/iq-handlers.js +0 -1
  18. package/dist/{cli.d.ts → bin.d.ts} +0 -1
  19. package/dist/{cli.js → bin.js} +1 -2
  20. package/dist/esm/api/AppStateSyncManager.js +146 -0
  21. package/dist/esm/api/FakePairingDriver.js +31 -0
  22. package/dist/esm/api/FakePeer.js +604 -0
  23. package/dist/esm/api/FakeWaServer.js +680 -0
  24. package/dist/esm/api/PreKeyDispenser.js +93 -0
  25. package/dist/esm/api/Scenario.js +32 -0
  26. package/dist/esm/api/ServerRegistries.js +261 -0
  27. package/dist/esm/api/iq-handlers.js +492 -0
  28. package/dist/esm/bin.js +246 -0
  29. package/dist/esm/index.js +26 -0
  30. package/dist/esm/infra/WaFakeConnection.js +49 -0
  31. package/dist/esm/infra/WaFakeConnectionPipeline.js +223 -0
  32. package/dist/esm/infra/WaFakeFrameSocket.js +117 -0
  33. package/dist/esm/infra/WaFakeMediaHttpsServer.js +126 -0
  34. package/dist/esm/infra/WaFakeNoiseHandshake.js +67 -0
  35. package/dist/esm/infra/WaFakeTransport.js +31 -0
  36. package/dist/esm/infra/WaFakeWsServer.js +96 -0
  37. package/dist/esm/package.json +3 -0
  38. package/dist/esm/protocol/auth/cert-chain.js +39 -0
  39. package/dist/esm/protocol/auth/client-payload-validate.js +55 -0
  40. package/dist/esm/protocol/auth/fake-primary-device.js +47 -0
  41. package/dist/esm/protocol/auth/pair-device.js +87 -0
  42. package/dist/esm/protocol/auth/success-node.js +26 -0
  43. package/dist/esm/protocol/iq/abprops.js +30 -0
  44. package/dist/esm/protocol/iq/appstate-sync.js +146 -0
  45. package/dist/esm/protocol/iq/business.js +59 -0
  46. package/dist/esm/protocol/iq/dirty-bits.js +19 -0
  47. package/dist/esm/protocol/iq/group-ops.js +154 -0
  48. package/dist/esm/protocol/iq/newsletter.js +14 -0
  49. package/dist/esm/protocol/iq/prekey-fetch.js +88 -0
  50. package/dist/esm/protocol/iq/privacy-token.js +26 -0
  51. package/dist/esm/protocol/iq/privacy.js +123 -0
  52. package/dist/esm/protocol/iq/profile.js +72 -0
  53. package/dist/esm/protocol/iq/router.js +111 -0
  54. package/dist/esm/protocol/iq/usync.js +64 -0
  55. package/dist/esm/protocol/push/app-state-key-share.js +26 -0
  56. package/dist/esm/protocol/push/call-failure.js +27 -0
  57. package/dist/esm/protocol/push/chatstate.js +23 -0
  58. package/dist/esm/protocol/push/error-stanza.js +13 -0
  59. package/dist/esm/protocol/push/history-sync.js +111 -0
  60. package/dist/esm/protocol/push/message.js +38 -0
  61. package/dist/esm/protocol/push/notification.js +29 -0
  62. package/dist/esm/protocol/push/presence.js +14 -0
  63. package/dist/esm/protocol/push/receipt.js +21 -0
  64. package/dist/esm/protocol/signal/fake-app-state-crypto.js +196 -0
  65. package/dist/esm/protocol/signal/fake-peer-double-ratchet.js +398 -0
  66. package/dist/esm/protocol/signal/fake-peer-group-recv-session.js +120 -0
  67. package/dist/esm/protocol/signal/fake-peer-identity.js +8 -0
  68. package/dist/esm/protocol/signal/fake-peer-key-bundle.js +25 -0
  69. package/dist/esm/protocol/signal/fake-sender-key.js +83 -0
  70. package/dist/esm/protocol/signal/prekey-upload.js +107 -0
  71. package/dist/esm/protocol/stream/stream-error.js +56 -0
  72. package/dist/esm/state/fake-app-state-collection.js +134 -0
  73. package/dist/esm/state/fake-media-store.js +53 -0
  74. package/dist/esm/transport/codec.js +8 -0
  75. package/dist/esm/transport/crypto.js +8 -0
  76. package/dist/esm/transport/protos.js +7 -0
  77. package/dist/esm/transport/util.js +8 -0
  78. package/dist/index.d.ts +0 -1
  79. package/dist/index.js +0 -1
  80. package/dist/infra/WaFakeConnection.d.ts +0 -1
  81. package/dist/infra/WaFakeConnection.js +0 -1
  82. package/dist/infra/WaFakeConnectionPipeline.d.ts +0 -1
  83. package/dist/infra/WaFakeConnectionPipeline.js +27 -24
  84. package/dist/infra/WaFakeFrameSocket.d.ts +0 -1
  85. package/dist/infra/WaFakeFrameSocket.js +0 -1
  86. package/dist/infra/WaFakeMediaHttpsServer.d.ts +0 -1
  87. package/dist/infra/WaFakeMediaHttpsServer.js +0 -1
  88. package/dist/infra/WaFakeNoiseHandshake.d.ts +8 -10
  89. package/dist/infra/WaFakeNoiseHandshake.js +19 -24
  90. package/dist/infra/WaFakeTransport.d.ts +2 -4
  91. package/dist/infra/WaFakeTransport.js +2 -1
  92. package/dist/infra/WaFakeWsServer.d.ts +0 -1
  93. package/dist/infra/WaFakeWsServer.js +0 -1
  94. package/dist/protocol/auth/cert-chain.d.ts +0 -1
  95. package/dist/protocol/auth/cert-chain.js +0 -1
  96. package/dist/protocol/auth/client-payload-validate.d.ts +0 -1
  97. package/dist/protocol/auth/client-payload-validate.js +0 -1
  98. package/dist/protocol/auth/fake-primary-device.d.ts +0 -1
  99. package/dist/protocol/auth/fake-primary-device.js +1 -3
  100. package/dist/protocol/auth/pair-device.d.ts +0 -1
  101. package/dist/protocol/auth/pair-device.js +4 -16
  102. package/dist/protocol/auth/success-node.d.ts +0 -1
  103. package/dist/protocol/auth/success-node.js +0 -1
  104. package/dist/protocol/iq/abprops.d.ts +0 -1
  105. package/dist/protocol/iq/abprops.js +0 -1
  106. package/dist/protocol/iq/appstate-sync.d.ts +0 -1
  107. package/dist/protocol/iq/appstate-sync.js +0 -1
  108. package/dist/protocol/iq/business.d.ts +0 -1
  109. package/dist/protocol/iq/business.js +0 -1
  110. package/dist/protocol/iq/dirty-bits.d.ts +0 -1
  111. package/dist/protocol/iq/dirty-bits.js +0 -1
  112. package/dist/protocol/iq/group-ops.d.ts +0 -1
  113. package/dist/protocol/iq/group-ops.js +0 -1
  114. package/dist/protocol/iq/newsletter.d.ts +0 -1
  115. package/dist/protocol/iq/newsletter.js +0 -1
  116. package/dist/protocol/iq/prekey-fetch.d.ts +0 -1
  117. package/dist/protocol/iq/prekey-fetch.js +0 -1
  118. package/dist/protocol/iq/privacy-token.d.ts +0 -1
  119. package/dist/protocol/iq/privacy-token.js +0 -1
  120. package/dist/protocol/iq/privacy.d.ts +0 -1
  121. package/dist/protocol/iq/privacy.js +15 -16
  122. package/dist/protocol/iq/profile.d.ts +0 -1
  123. package/dist/protocol/iq/profile.js +0 -1
  124. package/dist/protocol/iq/router.d.ts +0 -1
  125. package/dist/protocol/iq/router.js +0 -1
  126. package/dist/protocol/iq/usync.d.ts +0 -1
  127. package/dist/protocol/iq/usync.js +0 -1
  128. package/dist/protocol/push/app-state-key-share.d.ts +0 -1
  129. package/dist/protocol/push/app-state-key-share.js +0 -1
  130. package/dist/protocol/push/call-failure.d.ts +0 -1
  131. package/dist/protocol/push/call-failure.js +0 -1
  132. package/dist/protocol/push/chatstate.d.ts +0 -1
  133. package/dist/protocol/push/chatstate.js +0 -1
  134. package/dist/protocol/push/error-stanza.d.ts +0 -1
  135. package/dist/protocol/push/error-stanza.js +0 -1
  136. package/dist/protocol/push/history-sync.d.ts +0 -1
  137. package/dist/protocol/push/history-sync.js +0 -1
  138. package/dist/protocol/push/message.d.ts +0 -1
  139. package/dist/protocol/push/message.js +0 -1
  140. package/dist/protocol/push/notification.d.ts +0 -1
  141. package/dist/protocol/push/notification.js +0 -1
  142. package/dist/protocol/push/presence.d.ts +0 -1
  143. package/dist/protocol/push/presence.js +0 -1
  144. package/dist/protocol/push/receipt.d.ts +0 -1
  145. package/dist/protocol/push/receipt.js +0 -1
  146. package/dist/protocol/signal/fake-app-state-crypto.d.ts +7 -9
  147. package/dist/protocol/signal/fake-app-state-crypto.js +31 -33
  148. package/dist/protocol/signal/fake-peer-double-ratchet.d.ts +0 -1
  149. package/dist/protocol/signal/fake-peer-double-ratchet.js +23 -28
  150. package/dist/protocol/signal/fake-peer-group-recv-session.d.ts +0 -1
  151. package/dist/protocol/signal/fake-peer-group-recv-session.js +6 -10
  152. package/dist/protocol/signal/fake-peer-identity.d.ts +0 -1
  153. package/dist/protocol/signal/fake-peer-identity.js +0 -1
  154. package/dist/protocol/signal/fake-peer-key-bundle.d.ts +0 -1
  155. package/dist/protocol/signal/fake-peer-key-bundle.js +0 -1
  156. package/dist/protocol/signal/fake-sender-key.d.ts +0 -1
  157. package/dist/protocol/signal/fake-sender-key.js +5 -9
  158. package/dist/protocol/signal/prekey-upload.d.ts +0 -1
  159. package/dist/protocol/signal/prekey-upload.js +0 -1
  160. package/dist/protocol/stream/stream-error.d.ts +0 -1
  161. package/dist/protocol/stream/stream-error.js +0 -1
  162. package/dist/state/fake-app-state-collection.d.ts +0 -1
  163. package/dist/state/fake-app-state-collection.js +0 -1
  164. package/dist/state/fake-media-store.d.ts +0 -1
  165. package/dist/state/fake-media-store.js +2 -2
  166. package/dist/transport/codec.d.ts +2 -3
  167. package/dist/transport/codec.js +2 -3
  168. package/dist/transport/crypto.d.ts +5 -7
  169. package/dist/transport/crypto.js +6 -11
  170. package/dist/transport/protos.d.ts +2 -4
  171. package/dist/transport/protos.js +2 -4
  172. package/dist/transport/util.d.ts +8 -0
  173. package/dist/transport/util.js +15 -0
  174. package/package.json +21 -6
  175. package/dist/api/AppStateSyncManager.d.ts.map +0 -1
  176. package/dist/api/AppStateSyncManager.js.map +0 -1
  177. package/dist/api/FakePairingDriver.d.ts.map +0 -1
  178. package/dist/api/FakePairingDriver.js.map +0 -1
  179. package/dist/api/FakePeer.d.ts.map +0 -1
  180. package/dist/api/FakePeer.js.map +0 -1
  181. package/dist/api/FakeWaServer.d.ts.map +0 -1
  182. package/dist/api/FakeWaServer.js.map +0 -1
  183. package/dist/api/PreKeyDispenser.d.ts.map +0 -1
  184. package/dist/api/PreKeyDispenser.js.map +0 -1
  185. package/dist/api/Scenario.d.ts.map +0 -1
  186. package/dist/api/Scenario.js.map +0 -1
  187. package/dist/api/ServerRegistries.d.ts.map +0 -1
  188. package/dist/api/ServerRegistries.js.map +0 -1
  189. package/dist/api/iq-handlers.d.ts.map +0 -1
  190. package/dist/api/iq-handlers.js.map +0 -1
  191. package/dist/cli.d.ts.map +0 -1
  192. package/dist/cli.js.map +0 -1
  193. package/dist/index.d.ts.map +0 -1
  194. package/dist/index.js.map +0 -1
  195. package/dist/infra/WaFakeConnection.d.ts.map +0 -1
  196. package/dist/infra/WaFakeConnection.js.map +0 -1
  197. package/dist/infra/WaFakeConnectionPipeline.d.ts.map +0 -1
  198. package/dist/infra/WaFakeConnectionPipeline.js.map +0 -1
  199. package/dist/infra/WaFakeFrameSocket.d.ts.map +0 -1
  200. package/dist/infra/WaFakeFrameSocket.js.map +0 -1
  201. package/dist/infra/WaFakeMediaHttpsServer.d.ts.map +0 -1
  202. package/dist/infra/WaFakeMediaHttpsServer.js.map +0 -1
  203. package/dist/infra/WaFakeNoiseHandshake.d.ts.map +0 -1
  204. package/dist/infra/WaFakeNoiseHandshake.js.map +0 -1
  205. package/dist/infra/WaFakeTransport.d.ts.map +0 -1
  206. package/dist/infra/WaFakeTransport.js.map +0 -1
  207. package/dist/infra/WaFakeWsServer.d.ts.map +0 -1
  208. package/dist/infra/WaFakeWsServer.js.map +0 -1
  209. package/dist/protocol/auth/cert-chain.d.ts.map +0 -1
  210. package/dist/protocol/auth/cert-chain.js.map +0 -1
  211. package/dist/protocol/auth/client-payload-validate.d.ts.map +0 -1
  212. package/dist/protocol/auth/client-payload-validate.js.map +0 -1
  213. package/dist/protocol/auth/fake-primary-device.d.ts.map +0 -1
  214. package/dist/protocol/auth/fake-primary-device.js.map +0 -1
  215. package/dist/protocol/auth/pair-device.d.ts.map +0 -1
  216. package/dist/protocol/auth/pair-device.js.map +0 -1
  217. package/dist/protocol/auth/success-node.d.ts.map +0 -1
  218. package/dist/protocol/auth/success-node.js.map +0 -1
  219. package/dist/protocol/iq/abprops.d.ts.map +0 -1
  220. package/dist/protocol/iq/abprops.js.map +0 -1
  221. package/dist/protocol/iq/appstate-sync.d.ts.map +0 -1
  222. package/dist/protocol/iq/appstate-sync.js.map +0 -1
  223. package/dist/protocol/iq/business.d.ts.map +0 -1
  224. package/dist/protocol/iq/business.js.map +0 -1
  225. package/dist/protocol/iq/dirty-bits.d.ts.map +0 -1
  226. package/dist/protocol/iq/dirty-bits.js.map +0 -1
  227. package/dist/protocol/iq/group-ops.d.ts.map +0 -1
  228. package/dist/protocol/iq/group-ops.js.map +0 -1
  229. package/dist/protocol/iq/newsletter.d.ts.map +0 -1
  230. package/dist/protocol/iq/newsletter.js.map +0 -1
  231. package/dist/protocol/iq/prekey-fetch.d.ts.map +0 -1
  232. package/dist/protocol/iq/prekey-fetch.js.map +0 -1
  233. package/dist/protocol/iq/privacy-token.d.ts.map +0 -1
  234. package/dist/protocol/iq/privacy-token.js.map +0 -1
  235. package/dist/protocol/iq/privacy.d.ts.map +0 -1
  236. package/dist/protocol/iq/privacy.js.map +0 -1
  237. package/dist/protocol/iq/profile.d.ts.map +0 -1
  238. package/dist/protocol/iq/profile.js.map +0 -1
  239. package/dist/protocol/iq/router.d.ts.map +0 -1
  240. package/dist/protocol/iq/router.js.map +0 -1
  241. package/dist/protocol/iq/usync.d.ts.map +0 -1
  242. package/dist/protocol/iq/usync.js.map +0 -1
  243. package/dist/protocol/push/app-state-key-share.d.ts.map +0 -1
  244. package/dist/protocol/push/app-state-key-share.js.map +0 -1
  245. package/dist/protocol/push/call-failure.d.ts.map +0 -1
  246. package/dist/protocol/push/call-failure.js.map +0 -1
  247. package/dist/protocol/push/chatstate.d.ts.map +0 -1
  248. package/dist/protocol/push/chatstate.js.map +0 -1
  249. package/dist/protocol/push/error-stanza.d.ts.map +0 -1
  250. package/dist/protocol/push/error-stanza.js.map +0 -1
  251. package/dist/protocol/push/history-sync.d.ts.map +0 -1
  252. package/dist/protocol/push/history-sync.js.map +0 -1
  253. package/dist/protocol/push/message.d.ts.map +0 -1
  254. package/dist/protocol/push/message.js.map +0 -1
  255. package/dist/protocol/push/notification.d.ts.map +0 -1
  256. package/dist/protocol/push/notification.js.map +0 -1
  257. package/dist/protocol/push/presence.d.ts.map +0 -1
  258. package/dist/protocol/push/presence.js.map +0 -1
  259. package/dist/protocol/push/receipt.d.ts.map +0 -1
  260. package/dist/protocol/push/receipt.js.map +0 -1
  261. package/dist/protocol/signal/fake-app-state-crypto.d.ts.map +0 -1
  262. package/dist/protocol/signal/fake-app-state-crypto.js.map +0 -1
  263. package/dist/protocol/signal/fake-peer-double-ratchet.d.ts.map +0 -1
  264. package/dist/protocol/signal/fake-peer-double-ratchet.js.map +0 -1
  265. package/dist/protocol/signal/fake-peer-group-recv-session.d.ts.map +0 -1
  266. package/dist/protocol/signal/fake-peer-group-recv-session.js.map +0 -1
  267. package/dist/protocol/signal/fake-peer-identity.d.ts.map +0 -1
  268. package/dist/protocol/signal/fake-peer-identity.js.map +0 -1
  269. package/dist/protocol/signal/fake-peer-key-bundle.d.ts.map +0 -1
  270. package/dist/protocol/signal/fake-peer-key-bundle.js.map +0 -1
  271. package/dist/protocol/signal/fake-peer-recv-session.d.ts +0 -60
  272. package/dist/protocol/signal/fake-peer-recv-session.d.ts.map +0 -1
  273. package/dist/protocol/signal/fake-peer-recv-session.js +0 -284
  274. package/dist/protocol/signal/fake-peer-recv-session.js.map +0 -1
  275. package/dist/protocol/signal/fake-peer-session.d.ts +0 -87
  276. package/dist/protocol/signal/fake-peer-session.d.ts.map +0 -1
  277. package/dist/protocol/signal/fake-peer-session.js +0 -207
  278. package/dist/protocol/signal/fake-peer-session.js.map +0 -1
  279. package/dist/protocol/signal/fake-sender-key.d.ts.map +0 -1
  280. package/dist/protocol/signal/fake-sender-key.js.map +0 -1
  281. package/dist/protocol/signal/prekey-upload.d.ts.map +0 -1
  282. package/dist/protocol/signal/prekey-upload.js.map +0 -1
  283. package/dist/protocol/stream/stream-error.d.ts.map +0 -1
  284. package/dist/protocol/stream/stream-error.js.map +0 -1
  285. package/dist/state/fake-app-state-collection.d.ts.map +0 -1
  286. package/dist/state/fake-app-state-collection.js.map +0 -1
  287. package/dist/state/fake-media-store.d.ts.map +0 -1
  288. package/dist/state/fake-media-store.js.map +0 -1
  289. package/dist/transport/codec.d.ts.map +0 -1
  290. package/dist/transport/codec.js.map +0 -1
  291. package/dist/transport/crypto.d.ts.map +0 -1
  292. package/dist/transport/crypto.js.map +0 -1
  293. package/dist/transport/index.d.ts +0 -4
  294. package/dist/transport/index.d.ts.map +0 -1
  295. package/dist/transport/index.js +0 -20
  296. package/dist/transport/index.js.map +0 -1
  297. package/dist/transport/protos.d.ts.map +0 -1
  298. package/dist/transport/protos.js.map +0 -1
@@ -0,0 +1,492 @@
1
+ /** Registers the default IQ auto-handlers used by `FakeWaServer`. */
2
+ import { buildAbPropsResult } from '../protocol/iq/abprops.js';
3
+ import { buildAppStateSyncFullResult, buildAppStateSyncResult, parseAppStateSyncRequest } from '../protocol/iq/appstate-sync.js';
4
+ import { buildBusinessProfileResult, parseGetBusinessProfileIq } from '../protocol/iq/business.js';
5
+ import { parseClearDirtyBitsIq } from '../protocol/iq/dirty-bits.js';
6
+ import { buildGroupMetadataNode, buildGroupParticipantChangeResult, parseCreateGroupIq, parseGroupParticipantChangeIq, parseLeaveGroupIq, parseSetDescriptionIq, parseSetSubjectIq } from '../protocol/iq/group-ops.js';
7
+ import { buildNewsletterMyAddonsResult } from '../protocol/iq/newsletter.js';
8
+ import { buildPreKeyFetchResult } from '../protocol/iq/prekey-fetch.js';
9
+ import { buildBlocklistResult, buildPrivacyDisallowedListResult, buildPrivacySettingsResult, parseBlocklistChangeIq, parsePrivacyDisallowedListGetIq, parsePrivacySetCategoryIq } from '../protocol/iq/privacy.js';
10
+ import { parsePrivacyTokenIssueIq } from '../protocol/iq/privacy-token.js';
11
+ import { buildGetProfilePictureResult, buildSetProfilePictureResult, parseGetProfilePictureIq, parseSetProfilePictureIq, parseSetStatusIq } from '../protocol/iq/profile.js';
12
+ import { buildIqError, buildIqResult } from '../protocol/iq/router.js';
13
+ import { buildUsyncDevicesResult } from '../protocol/iq/usync.js';
14
+ import { parsePreKeyUploadIq } from '../protocol/signal/prekey-upload.js';
15
+ import { toUserJidPart } from './ServerRegistries.js';
16
+ export function parseUsyncRequestedUserJids(iq) {
17
+ if (!Array.isArray(iq.content))
18
+ return [];
19
+ const out = [];
20
+ for (const child of iq.content) {
21
+ if (child.tag !== 'usync')
22
+ continue;
23
+ if (!Array.isArray(child.content))
24
+ continue;
25
+ for (const inner of child.content) {
26
+ if (inner.tag !== 'list')
27
+ continue;
28
+ if (!Array.isArray(inner.content))
29
+ continue;
30
+ for (const userNode of inner.content) {
31
+ if (userNode.tag !== 'user')
32
+ continue;
33
+ if (typeof userNode.attrs.jid === 'string') {
34
+ out.push(userNode.attrs.jid);
35
+ }
36
+ }
37
+ }
38
+ }
39
+ return out;
40
+ }
41
+ export function parseRequestedKeyJids(iq) {
42
+ if (!Array.isArray(iq.content))
43
+ return [];
44
+ const out = [];
45
+ for (const child of iq.content) {
46
+ if (child.tag !== 'key')
47
+ continue;
48
+ if (!Array.isArray(child.content))
49
+ continue;
50
+ for (const userNode of child.content) {
51
+ if (userNode.tag !== 'user')
52
+ continue;
53
+ const jid = userNode.attrs.jid;
54
+ if (jid)
55
+ out.push(jid);
56
+ }
57
+ }
58
+ return out;
59
+ }
60
+ function buildGroupMetadataReply(iq, metadata) {
61
+ const result = buildIqResult(iq);
62
+ return {
63
+ ...result,
64
+ content: [
65
+ buildGroupMetadataNode({
66
+ groupJid: metadata.groupJid,
67
+ subject: metadata.subject,
68
+ creator: metadata.creator,
69
+ creationSeconds: metadata.creationSeconds,
70
+ participantJids: metadata.participants.map((peer) => toUserJidPart(peer.jid)),
71
+ ...(metadata.description !== undefined ? { description: metadata.description } : {})
72
+ })
73
+ ]
74
+ };
75
+ }
76
+ export function registerDefaultIqHandlers(router, deps) {
77
+ router.register({
78
+ label: 'prekey-upload',
79
+ matcher: { xmlns: 'encrypt', type: 'set' },
80
+ respond: (iq) => {
81
+ try {
82
+ const bundle = parsePreKeyUploadIq(iq);
83
+ deps.capturePreKeyBundle(bundle);
84
+ }
85
+ catch {
86
+ /* ignore */
87
+ }
88
+ return buildIqResult(iq);
89
+ }
90
+ });
91
+ router.register({
92
+ label: 'signal-digest',
93
+ matcher: { xmlns: 'encrypt', type: 'get', childTag: 'digest' },
94
+ respond: (iq) => buildIqError(iq, { code: 404, text: 'item-not-found' })
95
+ });
96
+ router.register({
97
+ label: 'media-conn',
98
+ matcher: { xmlns: 'w:m', type: 'set', childTag: 'media_conn' },
99
+ respond: (iq) => {
100
+ const info = deps.requireMediaHttpsInfo();
101
+ const result = buildIqResult(iq);
102
+ return {
103
+ ...result,
104
+ attrs: { ...result.attrs, from: 's.whatsapp.net' },
105
+ content: [
106
+ {
107
+ tag: 'media_conn',
108
+ attrs: { auth: 'fake-media-auth', ttl: '3600' },
109
+ content: [
110
+ {
111
+ tag: 'host',
112
+ attrs: {
113
+ hostname: `${info.host}:${info.port}`
114
+ }
115
+ }
116
+ ]
117
+ }
118
+ ]
119
+ };
120
+ }
121
+ });
122
+ router.register({
123
+ label: 'app-state-sync',
124
+ matcher: { xmlns: 'w:sync:app:state', type: 'set' },
125
+ respond: async (iq) => {
126
+ await deps.consumeOutboundAppStatePatches(iq);
127
+ if (deps.appStateCollectionProviders.size === 0) {
128
+ return buildAppStateSyncResult(iq);
129
+ }
130
+ const requests = parseAppStateSyncRequest(iq);
131
+ const payloads = [];
132
+ for (const request of requests) {
133
+ const provider = deps.appStateCollectionProviders.get(request.name);
134
+ if (!provider)
135
+ continue;
136
+ const payload = await provider();
137
+ if (payload) {
138
+ payloads.push(payload);
139
+ }
140
+ }
141
+ return buildAppStateSyncFullResult(iq, { payloads });
142
+ }
143
+ });
144
+ router.register({
145
+ label: 'usync',
146
+ matcher: { xmlns: 'usync', type: 'get', childTag: 'usync' },
147
+ respond: (iq) => {
148
+ const requestedUserJids = parseUsyncRequestedUserJids(iq);
149
+ const results = requestedUserJids.map((userJid) => ({
150
+ userJid,
151
+ deviceIds: deps.lookupDeviceIdsForUser(userJid)
152
+ }));
153
+ return buildUsyncDevicesResult(iq, results);
154
+ }
155
+ });
156
+ router.register({
157
+ label: 'prekey-fetch',
158
+ matcher: { xmlns: 'encrypt', type: 'get', childTag: 'key' },
159
+ respond: (iq) => {
160
+ const requestedDeviceJids = parseRequestedKeyJids(iq);
161
+ const bundles = [];
162
+ for (const deviceJid of requestedDeviceJids) {
163
+ const peer = deps.peerRegistry.get(deviceJid);
164
+ if (!peer)
165
+ continue;
166
+ const oneTime = peer.keyBundle.oneTimePreKeys[0];
167
+ bundles.push({
168
+ userJid: deviceJid,
169
+ registrationId: peer.keyBundle.registrationId,
170
+ identityPublicKey: peer.keyBundle.identityKeyPair.pubKey,
171
+ signedPreKey: {
172
+ id: peer.keyBundle.signedPreKey.id,
173
+ publicKey: peer.keyBundle.signedPreKey.keyPair.pubKey,
174
+ signature: peer.keyBundle.signedPreKey.signature
175
+ },
176
+ ...(oneTime
177
+ ? {
178
+ oneTimePreKey: {
179
+ id: oneTime.id,
180
+ publicKey: oneTime.keyPair.pubKey
181
+ }
182
+ }
183
+ : {})
184
+ });
185
+ }
186
+ return buildPreKeyFetchResult(iq, bundles);
187
+ }
188
+ });
189
+ router.register({
190
+ label: 'group-metadata',
191
+ matcher: { xmlns: 'w:g2', type: 'get', childTag: 'query' },
192
+ respond: (iq) => {
193
+ const groupJid = iq.attrs.to;
194
+ if (!groupJid) {
195
+ return buildIqError(iq, { code: 400, text: 'missing-to' });
196
+ }
197
+ const metadata = deps.groupRegistry.get(groupJid);
198
+ if (!metadata) {
199
+ return buildIqError(iq, { code: 404, text: 'group-not-found' });
200
+ }
201
+ return buildGroupMetadataReply(iq, metadata);
202
+ }
203
+ });
204
+ router.register({
205
+ label: 'abprops',
206
+ matcher: { xmlns: 'abt', type: 'get', childTag: 'props' },
207
+ respond: (iq) => buildAbPropsResult(iq, deps.abPropsInput)
208
+ });
209
+ router.register({
210
+ label: 'whatsapp-ping',
211
+ matcher: { xmlns: 'w:p', type: 'get' },
212
+ respond: (iq) => buildIqResult(iq)
213
+ });
214
+ router.register({
215
+ label: 'xmpp-ping',
216
+ matcher: { xmlns: 'urn:xmpp:ping', type: 'get' },
217
+ respond: (iq) => buildIqResult(iq)
218
+ });
219
+ router.register({
220
+ label: 'signed-prekey-rotate',
221
+ matcher: { xmlns: 'encrypt', type: 'set', childTag: 'rotate' },
222
+ respond: (iq) => buildIqResult(iq)
223
+ });
224
+ router.register({
225
+ label: 'remove-companion-device',
226
+ matcher: { xmlns: 'md', type: 'set', childTag: 'remove-companion-device' },
227
+ respond: (iq) => {
228
+ deps.notifyLogout();
229
+ return buildIqResult(iq);
230
+ }
231
+ });
232
+ router.register({
233
+ label: 'group-create',
234
+ matcher: { xmlns: 'w:g2', type: 'set', childTag: 'create' },
235
+ respond: (iq) => {
236
+ const parsed = parseCreateGroupIq(iq);
237
+ if (!parsed) {
238
+ return buildIqError(iq, { code: 400, text: 'invalid-create' });
239
+ }
240
+ const groupJid = `120363${Date.now()}@g.us`;
241
+ const creator = parsed.participantJids[0] ?? 's.whatsapp.net';
242
+ const creationSeconds = Math.floor(Date.now() / 1000);
243
+ const participants = [];
244
+ for (const jid of parsed.participantJids) {
245
+ const peer = deps.peerRegistry.get(jid);
246
+ if (peer)
247
+ participants.push(peer);
248
+ }
249
+ const mutable = {
250
+ groupJid,
251
+ subject: parsed.subject,
252
+ description: parsed.description,
253
+ creator,
254
+ creationSeconds,
255
+ participants
256
+ };
257
+ deps.groupRegistry.set(groupJid, mutable);
258
+ deps.notifyGroupOp({
259
+ action: 'create',
260
+ groupJid,
261
+ subject: parsed.subject,
262
+ participantJids: parsed.participantJids,
263
+ description: parsed.description
264
+ });
265
+ const result = buildIqResult(iq);
266
+ return {
267
+ ...result,
268
+ content: [
269
+ buildGroupMetadataNode({
270
+ groupJid,
271
+ subject: parsed.subject,
272
+ creator,
273
+ creationSeconds,
274
+ participantJids: parsed.participantJids,
275
+ description: parsed.description
276
+ })
277
+ ]
278
+ };
279
+ }
280
+ });
281
+ for (const action of ['add', 'remove', 'promote', 'demote']) {
282
+ router.register({
283
+ label: `group-${action}`,
284
+ matcher: { xmlns: 'w:g2', type: 'set', childTag: action },
285
+ respond: (iq) => {
286
+ const parsed = parseGroupParticipantChangeIq(iq);
287
+ if (!parsed) {
288
+ return buildIqError(iq, { code: 400, text: 'invalid-change' });
289
+ }
290
+ const group = deps.groupRegistry.get(parsed.groupJid);
291
+ if (group) {
292
+ if (parsed.action === 'add') {
293
+ for (const jid of parsed.participantJids) {
294
+ const peer = deps.peerRegistry.get(jid);
295
+ if (peer && !group.participants.includes(peer)) {
296
+ group.participants.push(peer);
297
+ }
298
+ }
299
+ }
300
+ else if (parsed.action === 'remove') {
301
+ const removed = new Set(parsed.participantJids);
302
+ group.participants = group.participants.filter((peer) => !removed.has(peer.jid));
303
+ }
304
+ }
305
+ deps.notifyGroupOp({
306
+ action: parsed.action,
307
+ groupJid: parsed.groupJid,
308
+ participantJids: parsed.participantJids
309
+ });
310
+ return buildGroupParticipantChangeResult(iq, parsed.action, parsed.participantJids);
311
+ }
312
+ });
313
+ }
314
+ router.register({
315
+ label: 'group-subject',
316
+ matcher: { xmlns: 'w:g2', type: 'set', childTag: 'subject' },
317
+ respond: (iq) => {
318
+ const parsed = parseSetSubjectIq(iq);
319
+ if (!parsed)
320
+ return buildIqError(iq, { code: 400, text: 'invalid-subject' });
321
+ const group = deps.groupRegistry.get(parsed.groupJid);
322
+ if (group)
323
+ group.subject = parsed.subject;
324
+ deps.notifyGroupOp({
325
+ action: 'subject',
326
+ groupJid: parsed.groupJid,
327
+ subject: parsed.subject
328
+ });
329
+ return buildIqResult(iq);
330
+ }
331
+ });
332
+ router.register({
333
+ label: 'group-description',
334
+ matcher: { xmlns: 'w:g2', type: 'set', childTag: 'description' },
335
+ respond: (iq) => {
336
+ const parsed = parseSetDescriptionIq(iq);
337
+ if (!parsed)
338
+ return buildIqError(iq, { code: 400, text: 'invalid-description' });
339
+ const group = deps.groupRegistry.get(parsed.groupJid);
340
+ if (group)
341
+ group.description = parsed.description ?? undefined;
342
+ deps.notifyGroupOp({
343
+ action: 'description',
344
+ groupJid: parsed.groupJid,
345
+ description: parsed.description
346
+ });
347
+ return buildIqResult(iq);
348
+ }
349
+ });
350
+ router.register({
351
+ label: 'group-leave',
352
+ matcher: { xmlns: 'w:g2', type: 'set', childTag: 'leave' },
353
+ respond: (iq) => {
354
+ const groupJids = parseLeaveGroupIq(iq) ?? [];
355
+ for (const groupJid of groupJids) {
356
+ deps.groupRegistry.delete(groupJid);
357
+ deps.notifyGroupOp({ action: 'leave', groupJid });
358
+ }
359
+ return buildIqResult(iq);
360
+ }
361
+ });
362
+ router.register({
363
+ label: 'privacy-get',
364
+ matcher: { xmlns: 'privacy', type: 'get', childTag: 'privacy' },
365
+ respond: (iq) => {
366
+ const disallowedCategory = parsePrivacyDisallowedListGetIq(iq);
367
+ if (disallowedCategory) {
368
+ return buildPrivacyDisallowedListResult(iq, disallowedCategory, deps.privacySettings.disallowed[disallowedCategory] ?? []);
369
+ }
370
+ return buildPrivacySettingsResult(iq, deps.privacySettings);
371
+ }
372
+ });
373
+ router.register({
374
+ label: 'privacy-set',
375
+ matcher: { xmlns: 'privacy', type: 'set', childTag: 'privacy' },
376
+ respond: (iq) => {
377
+ const change = parsePrivacySetCategoryIq(iq);
378
+ if (!change)
379
+ return buildIqError(iq, { code: 400, text: 'invalid-privacy-set' });
380
+ deps.mutatePrivacySettings(change.category, change.value);
381
+ deps.notifyPrivacySet(change);
382
+ return buildIqResult(iq);
383
+ }
384
+ });
385
+ router.register({
386
+ label: 'blocklist-get',
387
+ matcher: { xmlns: 'blocklist', type: 'get' },
388
+ respond: (iq) => buildBlocklistResult(iq, [...deps.blocklistJids])
389
+ });
390
+ router.register({
391
+ label: 'blocklist-set',
392
+ matcher: { xmlns: 'blocklist', type: 'set' },
393
+ respond: (iq) => {
394
+ const change = parseBlocklistChangeIq(iq);
395
+ if (!change) {
396
+ return buildIqError(iq, { code: 400, text: 'invalid-blocklist-set' });
397
+ }
398
+ deps.mutateBlocklist(change.action, change.jid);
399
+ deps.notifyBlocklistChange(change);
400
+ return buildIqResult(iq);
401
+ }
402
+ });
403
+ router.register({
404
+ label: 'privacy-token-issue',
405
+ matcher: { xmlns: 'privacy', type: 'set', childTag: 'tokens' },
406
+ respond: (iq) => {
407
+ const tokens = parsePrivacyTokenIssueIq(iq);
408
+ if (tokens) {
409
+ for (const token of tokens) {
410
+ deps.issuedPrivacyTokens.set(token.jid, token);
411
+ deps.notifyPrivacyTokenIssue(token);
412
+ }
413
+ }
414
+ return buildIqResult(iq);
415
+ }
416
+ });
417
+ router.register({
418
+ label: 'newsletter-my-addons',
419
+ matcher: { xmlns: 'newsletter', type: 'get', childTag: 'my_addons' },
420
+ respond: (iq) => buildNewsletterMyAddonsResult(iq)
421
+ });
422
+ router.register({
423
+ label: 'dirty-bits-clear',
424
+ matcher: { xmlns: 'urn:xmpp:whatsapp:dirty', type: 'set' },
425
+ respond: (iq) => {
426
+ const bits = parseClearDirtyBitsIq(iq);
427
+ if (bits) {
428
+ deps.notifyDirtyBitsClear({ bits });
429
+ }
430
+ return buildIqResult(iq);
431
+ }
432
+ });
433
+ router.register({
434
+ label: 'profile-picture-get',
435
+ matcher: { xmlns: 'w:profile:picture', type: 'get' },
436
+ respond: (iq) => {
437
+ const parsed = parseGetProfilePictureIq(iq);
438
+ if (!parsed)
439
+ return buildIqError(iq, { code: 400, text: 'invalid-target' });
440
+ const picture = deps.profilePicturesByJid.get(parsed.targetJid);
441
+ if (!picture) {
442
+ return buildIqError(iq, { code: 404, text: 'item-not-found' });
443
+ }
444
+ return buildGetProfilePictureResult(iq, { ...picture, type: parsed.type });
445
+ }
446
+ });
447
+ router.register({
448
+ label: 'profile-picture-set',
449
+ matcher: { xmlns: 'w:profile:picture', type: 'set' },
450
+ respond: (iq) => {
451
+ const parsed = parseSetProfilePictureIq(iq);
452
+ if (!parsed)
453
+ return buildIqError(iq, { code: 400, text: 'invalid-set' });
454
+ const targetJid = parsed.targetJid ?? 'me';
455
+ const newId = `${Date.now()}`;
456
+ deps.handleProfilePictureSet(targetJid, newId);
457
+ deps.notifyProfilePictureSet(parsed);
458
+ return buildSetProfilePictureResult(iq, newId);
459
+ }
460
+ });
461
+ router.register({
462
+ label: 'status-set',
463
+ matcher: { xmlns: 'status', type: 'set' },
464
+ respond: (iq) => {
465
+ const parsed = parseSetStatusIq(iq);
466
+ if (parsed) {
467
+ deps.setLatestStatusText(parsed.text);
468
+ deps.notifyStatusSet(parsed.text);
469
+ }
470
+ return buildIqResult(iq);
471
+ }
472
+ });
473
+ router.register({
474
+ label: 'business-profile-get',
475
+ matcher: { xmlns: 'w:biz', type: 'get', childTag: 'business_profile' },
476
+ respond: (iq) => {
477
+ const requestedJids = parseGetBusinessProfileIq(iq) ?? [];
478
+ const profiles = [];
479
+ for (const jid of requestedJids) {
480
+ const profile = deps.businessProfilesByJid.get(jid);
481
+ if (profile)
482
+ profiles.push(profile);
483
+ }
484
+ return buildBusinessProfileResult(iq, profiles);
485
+ }
486
+ });
487
+ router.register({
488
+ label: 'business-profile-set',
489
+ matcher: { xmlns: 'w:biz', type: 'set', childTag: 'business_profile' },
490
+ respond: (iq) => buildIqResult(iq)
491
+ });
492
+ }