zapo-js 0.2.0 → 0.3.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 (351) hide show
  1. package/README.md +7 -3
  2. package/dist/appstate/WaAppStateCrypto.js +49 -41
  3. package/dist/appstate/WaAppStateSyncClient.js +79 -42
  4. package/dist/appstate/index.js +2 -2
  5. package/dist/auth/WaAuthClient.js +20 -11
  6. package/dist/auth/{flow/WaAuthCredentialsFlow.js → credentials-flow.js} +83 -18
  7. package/dist/auth/pairing/WaPairingFlow.js +26 -29
  8. package/dist/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +29 -13
  9. package/dist/client/WaClient.js +115 -75
  10. package/dist/client/WaClientFactory.js +113 -30
  11. package/dist/client/connection/WaConnectionManager.js +4 -1
  12. package/dist/client/coordinators/WaAbPropsCoordinator.js +141 -0
  13. package/dist/client/coordinators/WaBusinessCoordinator.js +3 -12
  14. package/dist/client/coordinators/WaEmailCoordinator.js +63 -0
  15. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +33 -8
  16. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +55 -25
  17. package/dist/client/coordinators/WaOfflineResumeCoordinator.js +114 -0
  18. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +38 -20
  19. package/dist/client/coordinators/WaProfileCoordinator.js +3 -1
  20. package/dist/client/coordinators/WaRetryCoordinator.js +11 -9
  21. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +22 -4
  22. package/dist/client/dirty.js +1 -1
  23. package/dist/client/events/abprops.js +43 -0
  24. package/dist/client/events/privacy-token.js +1 -2
  25. package/dist/client/events/registration.js +42 -0
  26. package/dist/client/incoming.js +37 -0
  27. package/dist/client/mailbox.js +17 -1
  28. package/dist/client/media.js +243 -0
  29. package/dist/client/messages.js +163 -86
  30. package/dist/crypto/core/index.js +4 -1
  31. package/dist/crypto/core/random.js +3 -9
  32. package/dist/crypto/core/xeddsa.js +57 -0
  33. package/dist/crypto/curves/X25519.js +18 -0
  34. package/dist/crypto/curves/constants.js +2 -1
  35. package/dist/esm/appstate/WaAppStateCrypto.js +39 -31
  36. package/dist/esm/appstate/WaAppStateSyncClient.js +68 -31
  37. package/dist/esm/appstate/index.js +1 -1
  38. package/dist/esm/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +1 -1
  39. package/dist/esm/auth/WaAuthClient.js +17 -8
  40. package/dist/esm/auth/{flow/WaAuthCredentialsFlow.js → credentials-flow.js} +83 -18
  41. package/dist/esm/auth/pairing/WaPairingFlow.js +25 -28
  42. package/dist/esm/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +20 -6
  43. package/dist/esm/client/WaClient.js +116 -76
  44. package/dist/esm/client/WaClientFactory.js +114 -31
  45. package/dist/esm/client/connection/WaConnectionManager.js +4 -1
  46. package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +137 -0
  47. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +4 -13
  48. package/dist/esm/client/coordinators/WaEmailCoordinator.js +60 -0
  49. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +35 -10
  50. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +47 -17
  51. package/dist/esm/client/coordinators/WaOfflineResumeCoordinator.js +110 -0
  52. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +38 -20
  53. package/dist/esm/client/coordinators/WaProfileCoordinator.js +3 -1
  54. package/dist/esm/client/coordinators/WaRetryCoordinator.js +11 -9
  55. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +24 -6
  56. package/dist/esm/client/dirty.js +1 -1
  57. package/dist/esm/client/events/abprops.js +40 -0
  58. package/dist/esm/client/events/privacy-token.js +1 -2
  59. package/dist/esm/client/events/registration.js +39 -0
  60. package/dist/esm/client/incoming.js +36 -0
  61. package/dist/esm/client/mailbox.js +17 -1
  62. package/dist/esm/client/media.js +234 -0
  63. package/dist/esm/client/messages.js +162 -85
  64. package/dist/esm/crypto/core/index.js +1 -0
  65. package/dist/esm/crypto/core/random.js +2 -7
  66. package/dist/esm/crypto/core/xeddsa.js +53 -0
  67. package/dist/esm/crypto/curves/X25519.js +20 -2
  68. package/dist/esm/crypto/curves/constants.js +1 -0
  69. package/dist/esm/infra/perf/StoreLock.js +7 -4
  70. package/dist/esm/media/WaMediaCrypto.js +257 -62
  71. package/dist/esm/media/WaMediaTransferClient.js +47 -190
  72. package/dist/esm/media/constants.js +2 -0
  73. package/dist/esm/media/processor.js +1 -0
  74. package/dist/esm/message/addon-crypto.js +130 -3
  75. package/dist/esm/message/content.js +12 -6
  76. package/dist/esm/message/icdc.js +8 -8
  77. package/dist/esm/message/incoming.js +14 -12
  78. package/dist/esm/message/phash.js +32 -12
  79. package/dist/esm/message/reporting-token.js +3 -3
  80. package/dist/esm/message/use-case-secret.js +1 -1
  81. package/dist/esm/protocol/abprops.js +159 -0
  82. package/dist/esm/protocol/browser.js +14 -0
  83. package/dist/esm/protocol/constants.js +3 -1
  84. package/dist/esm/protocol/email.js +30 -0
  85. package/dist/esm/protocol/jid.js +44 -10
  86. package/dist/esm/protocol/nodes.js +6 -2
  87. package/dist/esm/protocol/notification.js +7 -1
  88. package/dist/esm/retry/reason.js +1 -1
  89. package/dist/esm/signal/api/SignalDeviceSyncApi.js +5 -2
  90. package/dist/esm/signal/api/SignalDigestSyncApi.js +8 -6
  91. package/dist/esm/signal/api/SignalIdentitySyncApi.js +4 -4
  92. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +1 -1
  93. package/dist/esm/signal/api/SignalSessionSyncApi.js +1 -1
  94. package/dist/esm/signal/crypto/WaAdvSignature.js +5 -51
  95. package/dist/esm/signal/crypto/constants.js +0 -4
  96. package/dist/esm/signal/encoding.js +11 -54
  97. package/dist/esm/signal/group/SenderKeyChain.js +3 -3
  98. package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
  99. package/dist/esm/signal/group/SenderKeyManager.js +13 -10
  100. package/dist/esm/signal/registration/keygen.js +2 -3
  101. package/dist/esm/signal/registration/utils.js +2 -2
  102. package/dist/esm/signal/session/SignalProtocol.js +18 -17
  103. package/dist/esm/signal/session/SignalRatchet.js +21 -10
  104. package/dist/esm/signal/session/SignalSerializer.js +5 -6
  105. package/dist/esm/signal/session/SignalSession.js +11 -9
  106. package/dist/esm/signal/session/resolver.js +6 -6
  107. package/dist/esm/store/contracts/identity.store.js +1 -0
  108. package/dist/esm/store/contracts/message-secret.store.js +1 -0
  109. package/dist/esm/store/contracts/pre-key.store.js +1 -0
  110. package/dist/esm/store/contracts/session.store.js +1 -0
  111. package/dist/esm/store/createStore.js +48 -12
  112. package/dist/esm/store/index.js +4 -0
  113. package/dist/esm/store/locks/identity.lock.js +16 -0
  114. package/dist/esm/store/locks/message-secret.lock.js +17 -0
  115. package/dist/esm/store/locks/pre-key.lock.js +27 -0
  116. package/dist/esm/store/locks/session.lock.js +19 -0
  117. package/dist/esm/store/locks/signal.lock.js +0 -24
  118. package/dist/esm/store/noop.store.js +20 -0
  119. package/dist/esm/store/providers/memory/device-list.store.js +3 -0
  120. package/dist/esm/store/providers/memory/identity.store.js +31 -0
  121. package/dist/esm/store/providers/memory/message-secret.store.js +81 -0
  122. package/dist/esm/store/providers/memory/participants.store.js +3 -0
  123. package/dist/esm/store/providers/memory/pre-key.store.js +97 -0
  124. package/dist/esm/store/providers/memory/retry.store.js +25 -11
  125. package/dist/esm/store/providers/memory/session.store.js +45 -0
  126. package/dist/esm/store/providers/memory/signal.store.js +1 -164
  127. package/dist/esm/transport/WaComms.js +4 -3
  128. package/dist/esm/transport/WaWebSocket.js +9 -1
  129. package/dist/esm/transport/index.js +6 -0
  130. package/dist/esm/transport/keepalive/WaKeepAlive.js +17 -8
  131. package/dist/esm/transport/node/WaMobileTcpSocket.js +114 -0
  132. package/dist/esm/transport/node/WaNodeOrchestrator.js +17 -8
  133. package/dist/esm/transport/node/builders/abprops.js +20 -0
  134. package/dist/esm/transport/node/builders/device.js +11 -0
  135. package/dist/esm/transport/node/builders/email.js +65 -0
  136. package/dist/esm/transport/node/builders/offline.js +14 -0
  137. package/dist/esm/transport/node/builders/prekeys.js +37 -40
  138. package/dist/esm/transport/node/builders/presence.js +13 -0
  139. package/dist/esm/transport/node/builders/privacy-token.js +19 -23
  140. package/dist/esm/transport/node/builders/retry.js +1 -1
  141. package/dist/esm/transport/node/helpers.js +24 -0
  142. package/dist/esm/transport/node/mex/argo-decoder.js +152 -0
  143. package/dist/esm/transport/node/mex/client.js +83 -0
  144. package/dist/esm/transport/node/mex/persist-ids.js +10 -0
  145. package/dist/esm/transport/noise/WaClientPayload.js +15 -10
  146. package/dist/esm/transport/noise/WaFrameCodec.js +2 -2
  147. package/dist/esm/transport/noise/WaMobileClientPayload.js +53 -0
  148. package/dist/esm/transport/noise/WaNoiseCert.js +9 -27
  149. package/dist/esm/transport/noise/WaNoiseSession.js +12 -11
  150. package/dist/infra/perf/StoreLock.js +7 -4
  151. package/dist/media/WaMediaCrypto.js +253 -58
  152. package/dist/media/WaMediaTransferClient.js +50 -223
  153. package/dist/media/constants.js +3 -1
  154. package/dist/media/processor.js +2 -0
  155. package/dist/message/addon-crypto.js +131 -0
  156. package/dist/message/content.js +13 -5
  157. package/dist/message/icdc.js +8 -8
  158. package/dist/message/incoming.js +14 -12
  159. package/dist/message/phash.js +32 -12
  160. package/dist/message/reporting-token.js +2 -2
  161. package/dist/message/use-case-secret.js +1 -1
  162. package/dist/protocol/abprops.js +163 -0
  163. package/dist/protocol/browser.js +15 -0
  164. package/dist/protocol/constants.js +14 -2
  165. package/dist/protocol/email.js +33 -0
  166. package/dist/protocol/jid.js +45 -10
  167. package/dist/protocol/nodes.js +6 -2
  168. package/dist/protocol/notification.js +8 -2
  169. package/dist/retry/reason.js +1 -1
  170. package/dist/signal/api/SignalDeviceSyncApi.js +5 -2
  171. package/dist/signal/api/SignalDigestSyncApi.js +8 -6
  172. package/dist/signal/api/SignalIdentitySyncApi.js +4 -4
  173. package/dist/signal/crypto/WaAdvSignature.js +2 -50
  174. package/dist/signal/crypto/constants.js +1 -5
  175. package/dist/signal/encoding.js +11 -49
  176. package/dist/signal/group/SenderKeyChain.js +2 -2
  177. package/dist/signal/group/SenderKeyCodec.js +4 -5
  178. package/dist/signal/group/SenderKeyManager.js +12 -9
  179. package/dist/signal/registration/keygen.js +1 -2
  180. package/dist/signal/registration/utils.js +2 -2
  181. package/dist/signal/session/SignalProtocol.js +18 -17
  182. package/dist/signal/session/SignalRatchet.js +19 -8
  183. package/dist/signal/session/SignalSerializer.js +5 -6
  184. package/dist/signal/session/SignalSession.js +11 -9
  185. package/dist/signal/session/resolver.js +6 -6
  186. package/dist/store/contracts/identity.store.js +2 -0
  187. package/dist/store/contracts/message-secret.store.js +2 -0
  188. package/dist/store/contracts/pre-key.store.js +2 -0
  189. package/dist/store/contracts/session.store.js +2 -0
  190. package/dist/store/createStore.js +47 -11
  191. package/dist/store/index.js +9 -1
  192. package/dist/store/locks/identity.lock.js +19 -0
  193. package/dist/store/locks/message-secret.lock.js +20 -0
  194. package/dist/store/locks/pre-key.lock.js +30 -0
  195. package/dist/store/locks/session.lock.js +22 -0
  196. package/dist/store/locks/signal.lock.js +0 -24
  197. package/dist/store/noop.store.js +21 -1
  198. package/dist/store/providers/memory/device-list.store.js +3 -0
  199. package/dist/store/providers/memory/identity.store.js +35 -0
  200. package/dist/store/providers/memory/message-secret.store.js +85 -0
  201. package/dist/store/providers/memory/participants.store.js +3 -0
  202. package/dist/store/providers/memory/pre-key.store.js +101 -0
  203. package/dist/store/providers/memory/retry.store.js +24 -10
  204. package/dist/store/providers/memory/session.store.js +49 -0
  205. package/dist/store/providers/memory/signal.store.js +1 -164
  206. package/dist/transport/WaComms.js +4 -3
  207. package/dist/transport/WaWebSocket.js +9 -1
  208. package/dist/transport/index.js +17 -1
  209. package/dist/transport/keepalive/WaKeepAlive.js +17 -8
  210. package/dist/transport/node/WaMobileTcpSocket.js +118 -0
  211. package/dist/transport/node/WaNodeOrchestrator.js +16 -7
  212. package/dist/transport/node/builders/abprops.js +23 -0
  213. package/dist/transport/node/builders/device.js +14 -0
  214. package/dist/transport/node/builders/email.js +72 -0
  215. package/dist/transport/node/builders/offline.js +17 -0
  216. package/dist/transport/node/builders/prekeys.js +36 -39
  217. package/dist/transport/node/builders/presence.js +16 -0
  218. package/dist/transport/node/builders/privacy-token.js +18 -22
  219. package/dist/transport/node/builders/retry.js +1 -1
  220. package/dist/transport/node/helpers.js +26 -0
  221. package/dist/transport/node/mex/argo-decoder.js +189 -0
  222. package/dist/transport/node/mex/client.js +86 -0
  223. package/dist/transport/node/mex/persist-ids.js +13 -0
  224. package/dist/transport/noise/WaClientPayload.js +14 -9
  225. package/dist/transport/noise/WaFrameCodec.js +1 -1
  226. package/dist/transport/noise/WaMobileClientPayload.js +56 -0
  227. package/dist/transport/noise/WaNoiseCert.js +8 -26
  228. package/dist/transport/noise/WaNoiseSession.js +11 -10
  229. package/dist/types/appstate/WaAppStateCrypto.d.ts +11 -8
  230. package/dist/types/appstate/WaAppStateSyncClient.d.ts +6 -2
  231. package/dist/types/appstate/index.d.ts +1 -1
  232. package/dist/types/appstate/{WaAppStateSyncResponseParser.d.ts → response-parser.d.ts} +1 -1
  233. package/dist/types/appstate/types.d.ts +1 -1
  234. package/dist/types/auth/WaAuthClient.d.ts +9 -3
  235. package/dist/types/auth/credentials-flow.d.ts +20 -0
  236. package/dist/types/auth/pairing/WaPairingFlow.d.ts +3 -2
  237. package/dist/types/auth/pairing/{WaPairingCodeCrypto.d.ts → pairing-code-crypto.d.ts} +6 -1
  238. package/dist/types/auth/types.d.ts +40 -0
  239. package/dist/types/client/WaClient.d.ts +19 -8
  240. package/dist/types/client/WaClientFactory.d.ts +10 -4
  241. package/dist/types/client/coordinators/WaAbPropsCoordinator.d.ts +26 -0
  242. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +1 -1
  243. package/dist/types/client/coordinators/WaEmailCoordinator.d.ts +24 -0
  244. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +6 -1
  245. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +15 -2
  246. package/dist/types/client/coordinators/WaOfflineResumeCoordinator.d.ts +31 -0
  247. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +13 -2
  248. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +1 -1
  249. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +4 -2
  250. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +6 -0
  251. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +11 -1
  252. package/dist/types/client/dirty.d.ts +3 -1
  253. package/dist/types/client/events/abprops.d.ts +14 -0
  254. package/dist/types/client/events/registration.d.ts +17 -0
  255. package/dist/types/client/incoming.d.ts +6 -1
  256. package/dist/types/client/mailbox.d.ts +2 -0
  257. package/dist/types/client/media.d.ts +31 -0
  258. package/dist/types/client/messages.d.ts +2 -0
  259. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +1 -1
  260. package/dist/types/client/types.d.ts +100 -1
  261. package/dist/types/crypto/core/index.d.ts +1 -0
  262. package/dist/types/crypto/core/primitives.d.ts +1 -1
  263. package/dist/types/crypto/core/random.d.ts +1 -1
  264. package/dist/types/crypto/core/xeddsa.d.ts +2 -0
  265. package/dist/types/crypto/curves/constants.d.ts +1 -0
  266. package/dist/types/crypto/index.d.ts +1 -0
  267. package/dist/types/index.d.ts +2 -1
  268. package/dist/types/infra/log/ConsoleLogger.d.ts +1 -1
  269. package/dist/types/infra/log/PinoLogger.d.ts +1 -1
  270. package/dist/types/infra/perf/StoreLock.d.ts +1 -0
  271. package/dist/types/media/WaMediaCrypto.d.ts +15 -6
  272. package/dist/types/media/WaMediaTransferClient.d.ts +3 -11
  273. package/dist/types/media/constants.d.ts +2 -0
  274. package/dist/types/media/index.d.ts +1 -0
  275. package/dist/types/media/processor.d.ts +28 -0
  276. package/dist/types/media/types.d.ts +9 -3
  277. package/dist/types/message/addon-crypto.d.ts +34 -3
  278. package/dist/types/message/content.d.ts +3 -1
  279. package/dist/types/message/icdc.d.ts +4 -4
  280. package/dist/types/message/types.d.ts +16 -24
  281. package/dist/types/protocol/abprops.d.ts +142 -0
  282. package/dist/types/protocol/browser.d.ts +1 -0
  283. package/dist/types/protocol/constants.d.ts +5 -1
  284. package/dist/types/protocol/email.d.ts +32 -0
  285. package/dist/types/protocol/jid.d.ts +1 -0
  286. package/dist/types/protocol/nodes.d.ts +4 -0
  287. package/dist/types/protocol/notification.d.ts +6 -0
  288. package/dist/types/protocol/stream.d.ts +1 -0
  289. package/dist/types/retry/reason.d.ts +1 -1
  290. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +3 -0
  291. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +3 -3
  292. package/dist/types/signal/crypto/WaAdvSignature.d.ts +0 -2
  293. package/dist/types/signal/crypto/constants.d.ts +0 -1
  294. package/dist/types/signal/encoding.d.ts +7 -1
  295. package/dist/types/signal/group/SenderKeyChain.d.ts +1 -1
  296. package/dist/types/signal/group/SenderKeyManager.d.ts +7 -2
  297. package/dist/types/signal/registration/utils.d.ts +2 -1
  298. package/dist/types/signal/session/SignalProtocol.d.ts +11 -2
  299. package/dist/types/signal/session/SignalSerializer.d.ts +2 -1
  300. package/dist/types/signal/session/resolver.d.ts +4 -2
  301. package/dist/types/signal/types.d.ts +16 -4
  302. package/dist/types/store/contracts/identity.store.d.ts +11 -0
  303. package/dist/types/store/contracts/message-secret.store.d.ts +16 -0
  304. package/dist/types/store/contracts/pre-key.store.d.ts +13 -0
  305. package/dist/types/store/contracts/session.store.d.ts +14 -0
  306. package/dist/types/store/contracts/signal.store.d.ts +1 -34
  307. package/dist/types/store/index.d.ts +9 -1
  308. package/dist/types/store/locks/identity.lock.d.ts +3 -0
  309. package/dist/types/store/locks/message-secret.lock.d.ts +3 -0
  310. package/dist/types/store/locks/pre-key.lock.d.ts +3 -0
  311. package/dist/types/store/locks/session.lock.d.ts +3 -0
  312. package/dist/types/store/noop.store.d.ts +4 -0
  313. package/dist/types/store/providers/memory/identity.store.d.ts +18 -0
  314. package/dist/types/store/providers/memory/message-secret.store.d.ts +21 -0
  315. package/dist/types/store/providers/memory/pre-key.store.d.ts +23 -0
  316. package/dist/types/store/providers/memory/retry.store.d.ts +7 -1
  317. package/dist/types/store/providers/memory/session.store.d.ts +21 -0
  318. package/dist/types/store/providers/memory/signal.store.d.ts +3 -45
  319. package/dist/types/store/providers/memory/thread.store.d.ts +1 -1
  320. package/dist/types/store/types.d.ts +21 -1
  321. package/dist/types/transport/WaWebSocket.d.ts +1 -0
  322. package/dist/types/transport/index.d.ts +8 -1
  323. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +4 -1
  324. package/dist/types/transport/node/WaMobileTcpSocket.d.ts +18 -0
  325. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +6 -2
  326. package/dist/types/transport/node/builders/abprops.d.ts +5 -0
  327. package/dist/types/transport/node/builders/device.d.ts +2 -0
  328. package/dist/types/transport/node/builders/email.d.ts +11 -0
  329. package/dist/types/transport/node/builders/offline.d.ts +2 -0
  330. package/dist/types/transport/node/builders/prekeys.d.ts +4 -3
  331. package/dist/types/transport/node/builders/presence.d.ts +6 -0
  332. package/dist/types/transport/node/helpers.d.ts +3 -0
  333. package/dist/types/transport/node/mex/argo-decoder.d.ts +11 -0
  334. package/dist/types/transport/node/mex/client.d.ts +18 -0
  335. package/dist/types/transport/node/mex/persist-ids.d.ts +14 -0
  336. package/dist/types/transport/noise/WaMobileClientPayload.d.ts +29 -0
  337. package/dist/types/transport/noise/WaNoiseCert.d.ts +7 -1
  338. package/dist/types/transport/noise/WaNoiseSession.d.ts +1 -0
  339. package/dist/types/transport/types.d.ts +8 -0
  340. package/package.json +6 -4
  341. package/dist/auth/pairing/constants.js +0 -5
  342. package/dist/client/connection/WaKeyShareCoordinator.js +0 -63
  343. package/dist/esm/auth/pairing/constants.js +0 -2
  344. package/dist/esm/client/connection/WaKeyShareCoordinator.js +0 -59
  345. package/dist/esm/transport/node/builders/index.js +0 -11
  346. package/dist/transport/node/builders/index.js +0 -51
  347. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +0 -14
  348. package/dist/types/auth/pairing/constants.d.ts +0 -2
  349. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +0 -14
  350. package/dist/types/transport/node/builders/index.d.ts +0 -11
  351. /package/dist/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +0 -0
@@ -3,12 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildMediaMessageContent = buildMediaMessageContent;
4
4
  exports.getMediaConn = getMediaConn;
5
5
  const node_fs_1 = require("node:fs");
6
+ const media_1 = require("./media");
6
7
  const conn_1 = require("../media/conn");
7
8
  const constants_1 = require("../media/constants");
8
9
  const WaMediaCrypto_1 = require("../media/WaMediaCrypto");
9
10
  const content_1 = require("../message/content");
10
11
  const constants_2 = require("../protocol/constants");
11
- const media_1 = require("../transport/node/builders/media");
12
+ const media_2 = require("../transport/node/builders/media");
12
13
  const bytes_1 = require("../util/bytes");
13
14
  const primitives_1 = require("../util/primitives");
14
15
  async function buildMediaMessageContent(options, content) {
@@ -30,11 +31,14 @@ async function getMediaConn(options, forceRefresh = false) {
30
31
  if (!forceRefresh && cached && Date.now() + constants_1.MEDIA_CONN_CACHE_GRACE_MS < cached.expiresAtMs) {
31
32
  return cached;
32
33
  }
33
- const response = await options.queryWithContext('media_conn.fetch', (0, media_1.buildMediaConnIq)(), options.iqTimeoutMs ?? constants_2.WA_DEFAULTS.IQ_TIMEOUT_MS);
34
+ const response = await options.queryWithContext('media_conn.fetch', (0, media_2.buildMediaConnIq)(), options.iqTimeoutMs ?? constants_2.WA_DEFAULTS.IQ_TIMEOUT_MS);
34
35
  const mediaConn = (0, conn_1.parseMediaConnResponse)(response, Date.now());
35
36
  options.setMediaConnCache(mediaConn);
36
37
  return mediaConn;
37
38
  }
39
+ function needsSidecar(content) {
40
+ return content.type === 'video' || content.type === 'ptv' || content.type === 'audio';
41
+ }
38
42
  function resolveUploadType(content) {
39
43
  if (content.type === 'video' && content.gifPlayback)
40
44
  return 'gif';
@@ -42,85 +46,146 @@ function resolveUploadType(content) {
42
46
  return 'ptt';
43
47
  return content.type;
44
48
  }
45
- function isReadableStream(value) {
46
- return (!!value &&
47
- typeof value === 'object' &&
48
- 'pipe' in value &&
49
- typeof value.pipe === 'function');
49
+ function resolveMimetype(content) {
50
+ if (content.mimetype)
51
+ return content.mimetype;
52
+ if (content.type === 'sticker')
53
+ return 'image/webp';
54
+ throw new Error(`mimetype is required for ${content.type} messages`);
50
55
  }
51
56
  async function buildMediaMessage(options, content) {
52
- const uploaded = isReadableStream(content.media)
53
- ? await uploadMediaStream(options, content, content.media)
54
- : await uploadMediaBytes(options, content, (0, bytes_1.toBytesView)(content.media));
55
- const mediaKeyTimestamp = Math.floor(Date.now() / 1000);
56
- const common = {
57
- url: uploaded.url,
58
- mimetype: content.mimetype,
59
- fileSha256: uploaded.fileSha256,
60
- fileLength: uploaded.fileLength,
61
- mediaKey: uploaded.mediaKey,
62
- fileEncSha256: uploaded.fileEncSha256,
63
- directPath: uploaded.directPath,
64
- mediaKeyTimestamp
65
- };
66
- switch (content.type) {
67
- case 'image':
68
- return {
69
- imageMessage: {
70
- ...common,
71
- caption: content.caption,
72
- width: content.width,
73
- height: content.height
74
- }
75
- };
76
- case 'video':
77
- return {
78
- videoMessage: {
79
- ...common,
80
- caption: content.caption,
81
- gifPlayback: content.gifPlayback,
82
- seconds: content.seconds,
83
- width: content.width,
84
- height: content.height,
85
- metadataUrl: uploaded.metadataUrl
86
- }
87
- };
88
- case 'ptv':
89
- return {
90
- ptvMessage: {
91
- ...common,
92
- seconds: content.seconds,
93
- width: content.width,
94
- height: content.height
95
- }
96
- };
97
- case 'audio':
98
- return {
99
- audioMessage: {
100
- ...common,
101
- seconds: content.seconds,
102
- ptt: content.ptt
103
- }
104
- };
105
- case 'document':
106
- return {
107
- documentMessage: {
108
- ...common,
109
- caption: content.caption,
110
- fileName: content.fileName ?? 'file',
111
- title: content.fileName ?? undefined
112
- }
113
- };
114
- case 'sticker':
115
- return {
116
- stickerMessage: {
117
- ...common,
118
- width: content.width,
119
- height: content.height
57
+ const needsTempFile = (0, media_1.hasMediaProcessingTasks)(options.media, content) ||
58
+ (content.type === 'sticker' && content.firstFrameLength === undefined);
59
+ const resolved = await (0, media_1.resolveMediaInputs)(needsTempFile, content.media);
60
+ try {
61
+ let detectedFirstFrameLength;
62
+ if (content.type === 'sticker' &&
63
+ content.firstFrameLength === undefined &&
64
+ resolved.processorInput) {
65
+ const input = resolved.processorInput;
66
+ const header = typeof input === 'string' ? await (0, media_1.readFileHead)(input, 100) : input.subarray(0, 100);
67
+ detectedFirstFrameLength = (0, media_1.parseWebpAnimation)(header)?.firstFrameLength;
68
+ }
69
+ const firstFrameLength = content.type === 'sticker'
70
+ ? (content.firstFrameLength ?? detectedFirstFrameLength)
71
+ : undefined;
72
+ const uploadPromise = (0, media_1.isReadableStream)(resolved.uploadMedia)
73
+ ? uploadMediaStream(options, content, resolved.uploadMedia, firstFrameLength)
74
+ : uploadMediaBytes(options, content, resolved.uploadMedia, firstFrameLength);
75
+ const processPromise = (0, media_1.runMediaProcessor)(options.media, resolved.processorInput, content, options.logger);
76
+ const [uploadResult, processResult] = await Promise.allSettled([
77
+ uploadPromise,
78
+ processPromise
79
+ ]);
80
+ if (uploadResult.status === 'rejected')
81
+ throw uploadResult.reason;
82
+ if (processResult.status === 'rejected')
83
+ throw processResult.reason;
84
+ const uploaded = uploadResult.value;
85
+ const processed = processResult.value;
86
+ const mediaKeyTimestamp = Math.floor(Date.now() / 1000);
87
+ const uploadedFields = {
88
+ url: uploaded.url,
89
+ fileSha256: uploaded.fileSha256,
90
+ fileLength: uploaded.fileLength,
91
+ mediaKey: uploaded.mediaKey,
92
+ fileEncSha256: uploaded.fileEncSha256,
93
+ directPath: uploaded.directPath,
94
+ mediaKeyTimestamp,
95
+ mimetype: resolveMimetype(content)
96
+ };
97
+ function spread(c) {
98
+ const result = {};
99
+ for (const key in c) {
100
+ if (key !== 'type' &&
101
+ key !== 'media' &&
102
+ key !== 'fileLength' &&
103
+ key !== 'mimetype') {
104
+ result[key] = c[key];
120
105
  }
121
- };
122
- default:
123
- throw new Error(`unsupported media message type: ${String(content.type)}`);
106
+ }
107
+ return result;
108
+ }
109
+ switch (content.type) {
110
+ case 'image':
111
+ return {
112
+ imageMessage: {
113
+ ...spread(content),
114
+ ...uploadedFields,
115
+ width: content.width ?? processed.width,
116
+ height: content.height ?? processed.height,
117
+ jpegThumbnail: content.jpegThumbnail ?? processed.jpegThumbnail
118
+ }
119
+ };
120
+ case 'video':
121
+ return {
122
+ videoMessage: {
123
+ ...spread(content),
124
+ ...uploadedFields,
125
+ seconds: content.seconds ?? processed.seconds,
126
+ width: content.width ?? processed.width,
127
+ height: content.height ?? processed.height,
128
+ jpegThumbnail: content.jpegThumbnail ?? processed.jpegThumbnail,
129
+ streamingSidecar: uploaded.streamingSidecar,
130
+ metadataUrl: uploaded.metadataUrl
131
+ }
132
+ };
133
+ case 'ptv':
134
+ return {
135
+ ptvMessage: {
136
+ ...spread(content),
137
+ ...uploadedFields,
138
+ seconds: content.seconds ?? processed.seconds,
139
+ width: content.width ?? processed.width,
140
+ height: content.height ?? processed.height,
141
+ jpegThumbnail: content.jpegThumbnail ?? processed.jpegThumbnail,
142
+ streamingSidecar: uploaded.streamingSidecar
143
+ }
144
+ };
145
+ case 'audio':
146
+ return {
147
+ audioMessage: {
148
+ ...spread(content),
149
+ ...uploadedFields,
150
+ seconds: content.seconds ?? processed.seconds,
151
+ streamingSidecar: uploaded.streamingSidecar,
152
+ waveform: content.waveform ?? processed.waveform
153
+ }
154
+ };
155
+ case 'document':
156
+ return {
157
+ documentMessage: {
158
+ ...spread(content),
159
+ ...uploadedFields,
160
+ fileName: content.fileName ?? 'file',
161
+ title: content.title ?? content.fileName ?? undefined,
162
+ jpegThumbnail: content.jpegThumbnail ?? processed.jpegThumbnail
163
+ }
164
+ };
165
+ case 'sticker':
166
+ return {
167
+ stickerMessage: {
168
+ ...spread(content),
169
+ ...uploadedFields,
170
+ width: content.width ?? processed.width,
171
+ height: content.height ?? processed.height,
172
+ pngThumbnail: content.pngThumbnail ?? processed.pngThumbnail,
173
+ isAnimated: content.isAnimated ??
174
+ processed.isAnimated ??
175
+ firstFrameLength !== undefined,
176
+ firstFrameLength: content.firstFrameLength ?? uploaded.firstFrameLength,
177
+ firstFrameSidecar: content.firstFrameSidecar ?? uploaded.firstFrameSidecar,
178
+ stickerSentTs: content.stickerSentTs ?? Date.now()
179
+ }
180
+ };
181
+ default:
182
+ throw new Error(`unsupported media message type: ${String(content.type)}`);
183
+ }
184
+ }
185
+ finally {
186
+ if (resolved.tempFilePath) {
187
+ await (0, media_1.cleanupTempFile)(resolved.tempFilePath);
188
+ }
124
189
  }
125
190
  }
126
191
  function buildUploadUrl(host, uploadType, auth, fileEncSha256) {
@@ -151,11 +216,14 @@ function parseUploadResponse(body, status) {
151
216
  ...(parsed.metadata_url ? { metadataUrl: parsed.metadata_url } : {})
152
217
  };
153
218
  }
154
- async function uploadMediaBytes(options, content, mediaBytes) {
219
+ async function uploadMediaBytes(options, content, mediaBytes, firstFrameLength) {
155
220
  const uploadType = resolveUploadType(content);
156
221
  const mediaKey = await WaMediaCrypto_1.WaMediaCrypto.generateMediaKey();
157
222
  const [encrypted, mediaConn] = await Promise.all([
158
- WaMediaCrypto_1.WaMediaCrypto.encryptBytes(uploadType, mediaKey, mediaBytes),
223
+ WaMediaCrypto_1.WaMediaCrypto.encryptBytes(uploadType, mediaKey, mediaBytes, {
224
+ sidecar: needsSidecar(content),
225
+ firstFrameLength
226
+ }),
159
227
  getMediaConn(options)
160
228
  ]);
161
229
  const selectedHost = mediaConn.hosts.find((host) => !host.isFallback)?.hostname ?? mediaConn.hosts[0].hostname;
@@ -170,7 +238,7 @@ async function uploadMediaBytes(options, content, mediaBytes) {
170
238
  method: 'POST',
171
239
  body: encrypted.ciphertextHmac,
172
240
  contentLength: encrypted.ciphertextHmac.byteLength,
173
- contentType: content.mimetype
241
+ contentType: resolveMimetype(content)
174
242
  });
175
243
  const responseBody = await options.mediaTransfer.readResponseBytes(uploadResponse);
176
244
  const parsed = parseUploadResponse(responseBody, uploadResponse.status);
@@ -179,13 +247,19 @@ async function uploadMediaBytes(options, content, mediaBytes) {
179
247
  mediaKey,
180
248
  fileSha256: encrypted.fileSha256,
181
249
  fileEncSha256: encrypted.fileEncSha256,
182
- fileLength: mediaBytes.byteLength
250
+ fileLength: mediaBytes.byteLength,
251
+ streamingSidecar: encrypted.streamingSidecar,
252
+ firstFrameSidecar: encrypted.firstFrameSidecar,
253
+ firstFrameLength
183
254
  };
184
255
  }
185
- async function uploadMediaStream(options, content, stream) {
256
+ async function uploadMediaStream(options, content, stream, firstFrameLength) {
186
257
  const uploadType = resolveUploadType(content);
187
258
  const mediaKey = await WaMediaCrypto_1.WaMediaCrypto.generateMediaKey();
188
- const encResult = await WaMediaCrypto_1.WaMediaCrypto.encryptToFile(uploadType, mediaKey, stream);
259
+ const encResult = await WaMediaCrypto_1.WaMediaCrypto.encryptToFile(uploadType, mediaKey, stream, {
260
+ sidecar: needsSidecar(content),
261
+ firstFrameLength
262
+ });
189
263
  let readStream;
190
264
  try {
191
265
  const mediaConn = await getMediaConn(options);
@@ -204,7 +278,7 @@ async function uploadMediaStream(options, content, stream) {
204
278
  method: 'POST',
205
279
  body: readStream,
206
280
  contentLength: encResult.fileSize,
207
- contentType: content.mimetype
281
+ contentType: resolveMimetype(content)
208
282
  });
209
283
  const responseBody = await options.mediaTransfer.readResponseBytes(uploadResponse);
210
284
  const parsed = parseUploadResponse(responseBody, uploadResponse.status);
@@ -213,7 +287,10 @@ async function uploadMediaStream(options, content, stream) {
213
287
  mediaKey,
214
288
  fileSha256: encResult.fileSha256,
215
289
  fileEncSha256: encResult.fileEncSha256,
216
- fileLength: encResult.plaintextLength
290
+ fileLength: encResult.plaintextLength,
291
+ streamingSidecar: encResult.streamingSidecar,
292
+ firstFrameSidecar: encResult.firstFrameSidecar,
293
+ firstFrameLength
217
294
  };
218
295
  }
219
296
  finally {
@@ -3,7 +3,7 @@
3
3
  * Cryptographic utilities
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.aesCtrDecrypt = exports.aesCtrEncrypt = exports.pbkdf2DeriveAesCtrKey = exports.hmacSign = exports.importHmacSha512Key = exports.importHmacKey = exports.aesCbcDecrypt = exports.aesCbcEncrypt = exports.importAesCbcKey = exports.aesGcmDecrypt = exports.aesGcmEncrypt = exports.importAesGcmKey = exports.sha512 = exports.sha256 = exports.sha1 = exports.randomIntAsync = exports.randomFillAsync = exports.randomBytesAsync = exports.buildNonce = exports.readVersionedContent = exports.prependVersion = exports.toRawPubKey = exports.toSerializedPubKey = exports.hkdfSplit = exports.hkdf = exports.X25519 = exports.Ed25519 = void 0;
6
+ exports.xeddsaVerify = exports.xeddsaSign = exports.aesCtrDecrypt = exports.aesCtrEncrypt = exports.pbkdf2DeriveAesCtrKey = exports.hmacSign = exports.importHmacSha512Key = exports.importHmacKey = exports.aesCbcDecrypt = exports.aesCbcEncrypt = exports.importAesCbcKey = exports.aesGcmDecrypt = exports.aesGcmEncrypt = exports.importAesGcmKey = exports.sha512 = exports.sha256 = exports.sha1 = exports.randomIntAsync = exports.randomFillAsync = exports.randomBytesAsync = exports.buildNonce = exports.readVersionedContent = exports.prependVersion = exports.toRawPubKey = exports.toSerializedPubKey = exports.hkdfSplit = exports.hkdf = exports.X25519 = exports.Ed25519 = void 0;
7
7
  var Ed25519_1 = require("../curves/Ed25519");
8
8
  Object.defineProperty(exports, "Ed25519", { enumerable: true, get: function () { return Ed25519_1.Ed25519; } });
9
9
  var X25519_1 = require("../curves/X25519");
@@ -38,3 +38,6 @@ Object.defineProperty(exports, "hmacSign", { enumerable: true, get: function ()
38
38
  Object.defineProperty(exports, "pbkdf2DeriveAesCtrKey", { enumerable: true, get: function () { return primitives_1.pbkdf2DeriveAesCtrKey; } });
39
39
  Object.defineProperty(exports, "aesCtrEncrypt", { enumerable: true, get: function () { return primitives_1.aesCtrEncrypt; } });
40
40
  Object.defineProperty(exports, "aesCtrDecrypt", { enumerable: true, get: function () { return primitives_1.aesCtrDecrypt; } });
41
+ var xeddsa_1 = require("../core/xeddsa");
42
+ Object.defineProperty(exports, "xeddsaSign", { enumerable: true, get: function () { return xeddsa_1.xeddsaSign; } });
43
+ Object.defineProperty(exports, "xeddsaVerify", { enumerable: true, get: function () { return xeddsa_1.xeddsaVerify; } });
@@ -1,16 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.randomIntAsync = void 0;
4
- exports.randomBytesAsync = randomBytesAsync;
3
+ exports.randomBytesAsync = exports.randomIntAsync = void 0;
5
4
  exports.randomFillAsync = randomFillAsync;
6
5
  const node_crypto_1 = require("node:crypto");
7
6
  const node_util_1 = require("node:util");
8
- const bytes_1 = require("../../util/bytes");
9
- const randomBytesAsyncImpl = (0, node_util_1.promisify)(node_crypto_1.randomBytes);
10
- const randomIntAsyncImpl = (0, node_util_1.promisify)(node_crypto_1.randomInt);
11
- async function randomBytesAsync(size) {
12
- return (0, bytes_1.toBytesView)(await randomBytesAsyncImpl(size));
13
- }
14
7
  async function randomFillAsync(target, offset, size) {
15
8
  await new Promise((resolve, reject) => {
16
9
  const onDone = (error) => {
@@ -32,4 +25,5 @@ async function randomFillAsync(target, offset, size) {
32
25
  });
33
26
  return target;
34
27
  }
35
- exports.randomIntAsync = randomIntAsyncImpl;
28
+ exports.randomIntAsync = (0, node_util_1.promisify)(node_crypto_1.randomInt);
29
+ exports.randomBytesAsync = (0, node_util_1.promisify)(node_crypto_1.randomBytes);
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.xeddsaVerify = xeddsaVerify;
4
+ exports.xeddsaSign = xeddsaSign;
5
+ const primitives_1 = require("../core/primitives");
6
+ const random_1 = require("../core/random");
7
+ const Ed25519_1 = require("../curves/Ed25519");
8
+ const X25519_1 = require("../curves/X25519");
9
+ const edwards_1 = require("../math/edwards");
10
+ const le_1 = require("../math/le");
11
+ const mod_1 = require("../math/mod");
12
+ const bytes_1 = require("../../util/bytes");
13
+ const PREFIX_SIGNATURE_RANDOM = new Uint8Array([
14
+ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
15
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
16
+ ]);
17
+ async function xeddsaVerify(curvePublicKey, message, signature) {
18
+ if (signature.length !== 64) {
19
+ return false;
20
+ }
21
+ if ((signature[63] & 0x60) !== 0) {
22
+ return false;
23
+ }
24
+ const lastByteIndex = 63;
25
+ const originalLastByte = signature[lastByteIndex];
26
+ const signBit = originalLastByte & 0x80;
27
+ signature[lastByteIndex] = originalLastByte & 0x7f;
28
+ const edPublic = (0, X25519_1.montgomeryToEdwardsPublic)(curvePublicKey, signBit);
29
+ try {
30
+ return await Ed25519_1.Ed25519.verify(message, signature, edPublic);
31
+ }
32
+ finally {
33
+ signature[lastByteIndex] = originalLastByte;
34
+ }
35
+ }
36
+ async function xeddsaSign(privateKey, message) {
37
+ (0, bytes_1.assertByteLength)(privateKey, 32, `invalid curve25519 private key length ${privateKey.length}`);
38
+ const clampedPrivateKey = (0, X25519_1.clampCurvePrivateKeyInPlace)(privateKey);
39
+ const privateScalar = (0, le_1.bytesToBigIntLE)(clampedPrivateKey);
40
+ const encodedPublic = (0, edwards_1.encodeExtendedPoint)((0, edwards_1.scalarMultBase)(privateScalar));
41
+ const pubKeySignBit = encodedPublic[31] & 0x80;
42
+ const randomSuffix = await (0, random_1.randomBytesAsync)(64);
43
+ const hashInput = (0, bytes_1.concatBytes)([
44
+ PREFIX_SIGNATURE_RANDOM,
45
+ clampedPrivateKey,
46
+ message,
47
+ randomSuffix
48
+ ]);
49
+ const r = (0, mod_1.modGroup)((0, le_1.bytesToBigIntLE)(await (0, primitives_1.sha512)(hashInput)));
50
+ const encodedR = (0, edwards_1.encodeExtendedPoint)((0, edwards_1.scalarMultBase)(r));
51
+ const hInput = (0, bytes_1.concatBytes)([encodedR, encodedPublic, message]);
52
+ const h = (0, mod_1.modGroup)((0, le_1.bytesToBigIntLE)(await (0, primitives_1.sha512)(hInput)));
53
+ const s = (0, mod_1.modGroup)(r + h * privateScalar);
54
+ const encodedS = (0, le_1.bigIntToBytesLE)(s, 32);
55
+ encodedS[31] = (encodedS[31] & 0x7f) | pubKeySignBit;
56
+ return (0, bytes_1.concatBytes)([encodedR, encodedS]);
57
+ }
@@ -9,6 +9,8 @@ const types_1 = require("../curves/types");
9
9
  const constants_2 = require("../math/constants");
10
10
  const fe_1 = require("../math/fe");
11
11
  const bytes_1 = require("../../util/bytes");
12
+ const runtime_1 = require("../../util/runtime");
13
+ const IS_BUN = (0, runtime_1.isBunRuntime)();
12
14
  // Pre-allocated temps for montgomeryToEdwardsPublic (safe: single-threaded)
13
15
  const _mx = (0, fe_1.fe)();
14
16
  const _m1 = (0, fe_1.fe)();
@@ -69,6 +71,22 @@ class X25519 {
69
71
  static async scalarMult(privKey, pubKey) {
70
72
  (0, bytes_1.assertByteLength)(privKey, 32, 'x25519 private key must be 32 bytes');
71
73
  (0, bytes_1.assertByteLength)(pubKey, 32, 'x25519 public key must be 32 bytes');
74
+ // TODO: When Bun supports deriveBits with X25519 change to Async Web Crypto API
75
+ // https://github.com/oven-sh/bun/pull/29152
76
+ if (IS_BUN) {
77
+ const spki = new Uint8Array(constants_1.X25519_SPKI_PREFIX.length + 32);
78
+ spki.set(constants_1.X25519_SPKI_PREFIX, 0);
79
+ spki.set(pubKey, constants_1.X25519_SPKI_PREFIX.length);
80
+ const shared = (0, node_crypto_1.diffieHellman)({
81
+ privateKey: (0, node_crypto_1.createPrivateKey)({
82
+ key: (0, types_1.pkcs8FromRawPrivate)(constants_1.X25519_PKCS8_PREFIX, privKey),
83
+ format: 'der',
84
+ type: 'pkcs8'
85
+ }),
86
+ publicKey: (0, node_crypto_1.createPublicKey)({ key: spki, format: 'der', type: 'spki' })
87
+ });
88
+ return (0, bytes_1.toBytesView)(shared);
89
+ }
72
90
  const [privateKey, publicKey] = await Promise.all([
73
91
  node_crypto_1.webcrypto.subtle.importKey('pkcs8', (0, types_1.pkcs8FromRawPrivate)(constants_1.X25519_PKCS8_PREFIX, privKey), { name: 'X25519' }, false, ['deriveBits']),
74
92
  node_crypto_1.webcrypto.subtle.importKey('raw', pubKey, { name: 'X25519' }, false, [])
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ED25519_PKCS8_PREFIX = exports.X25519_PKCS8_PREFIX = void 0;
3
+ exports.ED25519_PKCS8_PREFIX = exports.X25519_SPKI_PREFIX = exports.X25519_PKCS8_PREFIX = void 0;
4
4
  const bytes_1 = require("../../util/bytes");
5
5
  exports.X25519_PKCS8_PREFIX = (0, bytes_1.hexToBytes)('302e020100300506032b656e04220420');
6
+ exports.X25519_SPKI_PREFIX = (0, bytes_1.hexToBytes)('302a300506032b656e032100');
6
7
  exports.ED25519_PKCS8_PREFIX = (0, bytes_1.hexToBytes)('302e020100300506032b657004220420');
@@ -4,15 +4,18 @@ import { aesCbcDecrypt, aesCbcEncrypt, hmacSign, importAesCbcKey, importHmacKey,
4
4
  import { randomBytesAsync } from '../crypto/core/random.js';
5
5
  import { proto } from '../proto.js';
6
6
  import { WA_APP_STATE_KDF_INFO } from '../protocol/constants.js';
7
- import { bytesToBase64 } from '../util/bytes.js';
8
- import { concatBytes, EMPTY_BYTES, intToBytes, TEXT_DECODER, TEXT_ENCODER, uint8Equal } from '../util/bytes.js';
7
+ import { bytesToBase64, concatBytes, EMPTY_BYTES, intToBytes, TEXT_DECODER, TEXT_ENCODER, uint8TimingSafeEqual } from '../util/bytes.js';
9
8
  import { setBoundedMapEntry } from '../util/collections.js';
10
9
  import { normalizeNonNegativeInteger } from '../util/primitives.js';
11
10
  const DEFAULT_DERIVED_KEYS_CACHE_MAX_SIZE = 256;
12
11
  export class WaAppStateCrypto {
13
- constructor(derivedKeysCacheMaxSize = DEFAULT_DERIVED_KEYS_CACHE_MAX_SIZE) {
12
+ constructor(derivedKeysCacheMaxSize = DEFAULT_DERIVED_KEYS_CACHE_MAX_SIZE, skipMacVerification = false) {
14
13
  this.derivedKeysCache = new Map();
15
14
  this.derivedKeysCacheMaxSize = normalizeNonNegativeInteger(derivedKeysCacheMaxSize, DEFAULT_DERIVED_KEYS_CACHE_MAX_SIZE);
15
+ this.skipMacVerification = skipMacVerification;
16
+ }
17
+ get isMacVerificationSkipped() {
18
+ return this.skipMacVerification;
16
19
  }
17
20
  clearCache() {
18
21
  this.derivedKeysCache.clear();
@@ -25,19 +28,25 @@ export class WaAppStateCrypto {
25
28
  return cached;
26
29
  }
27
30
  const derived = await hkdf(keyData, null, WA_APP_STATE_KDF_INFO.MUTATION_KEYS, APP_STATE_DERIVED_KEY_LENGTH);
31
+ const [indexHmacKey, valueEncryptionAesKey, valueMacHmacKey, snapshotMacHmacKey, patchMacHmacKey] = await Promise.all([
32
+ importHmacKey(derived.subarray(0, APP_STATE_DERIVED_INDEX_KEY_END)),
33
+ importAesCbcKey(derived.subarray(APP_STATE_DERIVED_INDEX_KEY_END, APP_STATE_DERIVED_VALUE_ENCRYPTION_KEY_END)),
34
+ importHmacSha512Key(derived.subarray(APP_STATE_DERIVED_VALUE_ENCRYPTION_KEY_END, APP_STATE_DERIVED_VALUE_MAC_KEY_END)),
35
+ importHmacKey(derived.subarray(APP_STATE_DERIVED_VALUE_MAC_KEY_END, APP_STATE_DERIVED_SNAPSHOT_MAC_KEY_END)),
36
+ importHmacKey(derived.subarray(APP_STATE_DERIVED_SNAPSHOT_MAC_KEY_END, APP_STATE_DERIVED_PATCH_MAC_KEY_END))
37
+ ]);
28
38
  const keys = {
29
- indexKey: derived.subarray(0, APP_STATE_DERIVED_INDEX_KEY_END),
30
- valueEncryptionKey: derived.subarray(APP_STATE_DERIVED_INDEX_KEY_END, APP_STATE_DERIVED_VALUE_ENCRYPTION_KEY_END),
31
- valueMacKey: derived.subarray(APP_STATE_DERIVED_VALUE_ENCRYPTION_KEY_END, APP_STATE_DERIVED_VALUE_MAC_KEY_END),
32
- snapshotMacKey: derived.subarray(APP_STATE_DERIVED_VALUE_MAC_KEY_END, APP_STATE_DERIVED_SNAPSHOT_MAC_KEY_END),
33
- patchMacKey: derived.subarray(APP_STATE_DERIVED_SNAPSHOT_MAC_KEY_END, APP_STATE_DERIVED_PATCH_MAC_KEY_END)
39
+ indexHmacKey,
40
+ valueEncryptionAesKey,
41
+ valueMacHmacKey,
42
+ snapshotMacHmacKey,
43
+ patchMacHmacKey
34
44
  };
35
45
  this.touchDerivedKeysCacheEntry(cacheKey, keys);
36
46
  return keys;
37
47
  }
38
- async generateIndexMac(indexKey, indexBytes) {
39
- const key = await importHmacKey(indexKey);
40
- return hmacSign(key, indexBytes);
48
+ async generateIndexMac(indexHmacKey, indexBytes) {
49
+ return hmacSign(indexHmacKey, indexBytes);
41
50
  }
42
51
  async encryptMutation(args) {
43
52
  const derivedKeys = await this.deriveKeys(args.keyData);
@@ -52,13 +61,12 @@ export class WaAppStateCrypto {
52
61
  if (iv.byteLength !== APP_STATE_IV_LENGTH) {
53
62
  throw new Error(`invalid IV length ${iv.byteLength}`);
54
63
  }
55
- const indexMacPromise = this.generateIndexMac(derivedKeys.indexKey, indexBytes);
56
- const encryptionKey = await importAesCbcKey(derivedKeys.valueEncryptionKey);
57
- const cipherText = await aesCbcEncrypt(encryptionKey, iv, encoded);
64
+ const indexMacPromise = this.generateIndexMac(derivedKeys.indexHmacKey, indexBytes);
65
+ const cipherText = await aesCbcEncrypt(derivedKeys.valueEncryptionAesKey, iv, encoded);
58
66
  const cipherWithIv = concatBytes([iv, cipherText]);
59
67
  const associatedData = this.generateAssociatedData(args.operation, args.keyId);
60
68
  const [valueMac, indexMac] = await Promise.all([
61
- this.generateValueMac(derivedKeys.valueMacKey, associatedData, cipherWithIv),
69
+ this.generateValueMac(derivedKeys.valueMacHmacKey, associatedData, cipherWithIv),
62
70
  indexMacPromise
63
71
  ]);
64
72
  return {
@@ -76,13 +84,14 @@ export class WaAppStateCrypto {
76
84
  const mac = args.valueBlob.subarray(args.valueBlob.byteLength - APP_STATE_VALUE_MAC_LENGTH);
77
85
  const cipherText = args.valueBlob.subarray(APP_STATE_IV_LENGTH, args.valueBlob.byteLength - APP_STATE_VALUE_MAC_LENGTH);
78
86
  const cipherWithIv = args.valueBlob.subarray(0, args.valueBlob.byteLength - APP_STATE_VALUE_MAC_LENGTH);
79
- const associatedData = this.generateAssociatedData(args.operation, args.keyId);
80
- const expectedMac = await this.generateValueMac(derivedKeys.valueMacKey, associatedData, cipherWithIv);
81
- if (!uint8Equal(mac, expectedMac)) {
82
- throw new Error('mutation value MAC mismatch');
87
+ if (!this.skipMacVerification) {
88
+ const associatedData = this.generateAssociatedData(args.operation, args.keyId);
89
+ const expectedMac = await this.generateValueMac(derivedKeys.valueMacHmacKey, associatedData, cipherWithIv);
90
+ if (!uint8TimingSafeEqual(mac, expectedMac)) {
91
+ throw new Error('mutation value MAC mismatch');
92
+ }
83
93
  }
84
- const decryptionKey = await importAesCbcKey(derivedKeys.valueEncryptionKey);
85
- const plaintext = await aesCbcDecrypt(decryptionKey, iv, cipherText);
94
+ const plaintext = await aesCbcDecrypt(derivedKeys.valueEncryptionAesKey, iv, cipherText);
86
95
  const syncActionData = proto.SyncActionData.decode(plaintext);
87
96
  if (!syncActionData.index) {
88
97
  throw new Error('missing sync action index');
@@ -90,9 +99,11 @@ export class WaAppStateCrypto {
90
99
  if (syncActionData.version === null || syncActionData.version === undefined) {
91
100
  throw new Error('missing sync action version');
92
101
  }
93
- const generatedIndexMac = await this.generateIndexMac(derivedKeys.indexKey, syncActionData.index);
94
- if (!uint8Equal(generatedIndexMac, args.indexMac)) {
95
- throw new Error('mutation index MAC mismatch');
102
+ if (!this.skipMacVerification) {
103
+ const generatedIndexMac = await this.generateIndexMac(derivedKeys.indexHmacKey, syncActionData.index);
104
+ if (!uint8TimingSafeEqual(generatedIndexMac, args.indexMac)) {
105
+ throw new Error('mutation index MAC mismatch');
106
+ }
96
107
  }
97
108
  return {
98
109
  index: TEXT_DECODER.decode(syncActionData.index),
@@ -109,8 +120,7 @@ export class WaAppStateCrypto {
109
120
  intToBytes(8, version),
110
121
  TEXT_ENCODER.encode(collectionName)
111
122
  ]);
112
- const key = await importHmacKey(derivedKeys.snapshotMacKey);
113
- return hmacSign(key, payload);
123
+ return hmacSign(derivedKeys.snapshotMacHmacKey, payload);
114
124
  }
115
125
  async generatePatchMac(keyData, snapshotMac, valueMacs, version, collectionName) {
116
126
  const derivedKeys = await this.deriveKeys(keyData);
@@ -120,8 +130,7 @@ export class WaAppStateCrypto {
120
130
  intToBytes(8, version),
121
131
  TEXT_ENCODER.encode(collectionName)
122
132
  ]);
123
- const key = await importHmacKey(derivedKeys.patchMacKey);
124
- return hmacSign(key, payload);
133
+ return hmacSign(derivedKeys.patchMacHmacKey, payload);
125
134
  }
126
135
  async ltHashAdd(base, addValues) {
127
136
  return this.ltHashApply(base, addValues, (left, right) => left + right);
@@ -175,11 +184,10 @@ export class WaAppStateCrypto {
175
184
  out.set(keyId, 1);
176
185
  return out;
177
186
  }
178
- async generateValueMac(valueMacKey, associatedData, cipherWithIv) {
187
+ async generateValueMac(valueMacHmacKey, associatedData, cipherWithIv) {
179
188
  const octetLength = new Uint8Array(APP_STATE_MAC_OCTET_LENGTH);
180
189
  octetLength[octetLength.length - 1] = associatedData.byteLength & 0xff;
181
- const key = await importHmacSha512Key(valueMacKey);
182
- const full = await hmacSign(key, concatBytes([associatedData, cipherWithIv, octetLength]));
190
+ const full = await hmacSign(valueMacHmacKey, concatBytes([associatedData, cipherWithIv, octetLength]));
183
191
  return full.subarray(0, APP_STATE_VALUE_MAC_LENGTH);
184
192
  }
185
193
  touchDerivedKeysCacheEntry(cacheKey, keys) {