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
@@ -46,7 +46,7 @@ export function decodeSignalSignedPreKeyRow(row) {
46
46
  uploaded: toBoolOrUndef(row.uploaded)
47
47
  };
48
48
  }
49
- function encodeSignalSessionSnapshot(session) {
49
+ export function encodeSignalSessionSnapshot(session) {
50
50
  return {
51
51
  sessionVersion: 3,
52
52
  localRegistrationId: session.local.regId,
@@ -56,13 +56,7 @@ function encodeSignalSessionSnapshot(session) {
56
56
  rootKey: session.rootKey,
57
57
  previousCounter: session.prevSendChainHighestIndex,
58
58
  senderChain: encodeSignalSendChain(session.sendChain),
59
- receiverChains: (() => {
60
- const src = session.recvChains;
61
- const arr = new Array(src.length);
62
- for (let i = 0; i < src.length; i += 1)
63
- arr[i] = encodeSignalRecvChain(src[i]);
64
- return arr;
65
- })(),
59
+ receiverChains: session.recvChains,
66
60
  pendingPreKey: session.initialExchangeInfo
67
61
  ? {
68
62
  preKeyId: session.initialExchangeInfo.remoteOneTimeId ?? undefined,
@@ -84,30 +78,17 @@ function encodeSignalSendChain(chain) {
84
78
  messageKeys: []
85
79
  };
86
80
  }
87
- function encodeSignalRecvChain(chain) {
81
+ export function encodeSignalRecvChain(chain) {
88
82
  return {
89
83
  senderRatchetKey: chain.ratchetPubKey,
90
84
  chainKey: {
91
85
  index: chain.nextMsgIndex,
92
86
  key: chain.chainKey
93
87
  },
94
- messageKeys: (() => {
95
- const src = chain.unusedMsgKeys ?? [];
96
- const arr = new Array(src.length);
97
- for (let i = 0; i < src.length; i += 1) {
98
- const messageKey = src[i];
99
- arr[i] = {
100
- index: messageKey.index,
101
- cipherKey: messageKey.cipherKey,
102
- macKey: messageKey.macKey,
103
- iv: messageKey.iv
104
- };
105
- }
106
- return arr;
107
- })()
88
+ messageKeys: chain.unusedMsgKeys
108
89
  };
109
90
  }
110
- function decodeSignalMessageKey(messageKey, field) {
91
+ export function decodeSignalMessageKey(messageKey, field) {
111
92
  const cipherKey = asBytes(messageKey.cipherKey, `${field}.cipherKey`);
112
93
  assertByteLength(cipherKey, 32, `invalid ${field}.cipherKey length ${cipherKey.byteLength}`);
113
94
  const macKey = asBytes(messageKey.macKey, `${field}.macKey`);
@@ -121,7 +102,7 @@ function decodeSignalMessageKey(messageKey, field) {
121
102
  iv
122
103
  };
123
104
  }
124
- function decodeSignalRecvChain(chain, field) {
105
+ export function decodeSignalRecvChain(chain, field) {
125
106
  const chainKey = chain.chainKey;
126
107
  if (!chainKey) {
127
108
  throw new Error(`missing ${field}.chainKey`);
@@ -134,13 +115,7 @@ function decodeSignalRecvChain(chain, field) {
134
115
  ratchetPubKey,
135
116
  nextMsgIndex: asNumber(chainKey.index, `${field}.chainKey.index`),
136
117
  chainKey: chainKeyBytes,
137
- unusedMsgKeys: (() => {
138
- const src = chain.messageKeys ?? [];
139
- const arr = new Array(src.length);
140
- for (let i = 0; i < src.length; i += 1)
141
- arr[i] = decodeSignalMessageKey(src[i], `${field}.messageKeys[${i}]`);
142
- return arr;
143
- })()
118
+ unusedMsgKeys: chain.messageKeys ?? []
144
119
  };
145
120
  }
146
121
  function decodeSignalSendChain(chain, field) {
@@ -166,7 +141,7 @@ function decodeSignalSendChain(chain, field) {
166
141
  chainKey: chainKeyBytes
167
142
  };
168
143
  }
169
- function decodeSignalSessionSnapshot(session, field) {
144
+ export function decodeSignalSessionSnapshot(session, field) {
170
145
  const senderChain = session.senderChain;
171
146
  if (!senderChain) {
172
147
  throw new Error(`missing ${field}.senderChain`);
@@ -199,13 +174,7 @@ function decodeSignalSessionSnapshot(session, field) {
199
174
  },
200
175
  rootKey,
201
176
  sendChain: decodeSignalSendChain(senderChain, `${field}.senderChain`),
202
- recvChains: (() => {
203
- const src = session.receiverChains ?? [];
204
- const arr = new Array(src.length);
205
- for (let i = 0; i < src.length; i += 1)
206
- arr[i] = decodeSignalRecvChain(src[i], `${field}.receiverChains[${i}]`);
207
- return arr;
208
- })(),
177
+ recvChains: session.receiverChains ?? [],
209
178
  initialExchangeInfo: pendingPreKey
210
179
  ? {
211
180
  remoteOneTimeId: asOptionalNumber(pendingPreKey.preKeyId, `${field}.pendingPreKey.preKeyId`) ??
@@ -221,13 +190,7 @@ function decodeSignalSessionSnapshot(session, field) {
221
190
  export function encodeSignalSessionRecord(record) {
222
191
  return proto.RecordStructure.encode({
223
192
  currentSession: encodeSignalSessionSnapshot(record),
224
- previousSessions: (() => {
225
- const src = record.prevSessions;
226
- const arr = new Array(src.length);
227
- for (let i = 0; i < src.length; i += 1)
228
- arr[i] = encodeSignalSessionSnapshot(src[i]);
229
- return arr;
230
- })()
193
+ previousSessions: record.prevSessions
231
194
  }).finish();
232
195
  }
233
196
  export function decodeSignalSessionRecord(raw) {
@@ -238,13 +201,7 @@ export function decodeSignalSessionRecord(raw) {
238
201
  const current = decodeSignalSessionSnapshot(decoded.currentSession, 'signal_sessions.currentSession');
239
202
  return {
240
203
  ...current,
241
- prevSessions: (() => {
242
- const src = decoded.previousSessions ?? [];
243
- const arr = new Array(src.length);
244
- for (let i = 0; i < src.length; i += 1)
245
- arr[i] = decodeSignalSessionSnapshot(src[i], `signal_sessions.previousSessions[${i}]`);
246
- return arr;
247
- })()
204
+ prevSessions: decoded.previousSessions ?? []
248
205
  };
249
206
  }
250
207
  export function encodeSenderKeyRecord(record) {
@@ -1,9 +1,9 @@
1
- import { hkdf, importHmacKey, hmacSign } from '../../crypto/index.js';
1
+ import { hkdf, hmacSign, importHmacKey } from '../../crypto/index.js';
2
2
  import { CHAIN_KEY_LABEL, MAX_UNUSED_KEYS, MESSAGE_KEY_LABEL, SENDER_KEY_FUTURE_MESSAGES_MAX, WHISPER_GROUP_INFO } from '../constants.js';
3
3
  import { assertByteLength, removeAt } from '../../util/bytes.js';
4
- export async function selectMessageKey(senderKey, targetIteration) {
4
+ export async function selectMessageKey(senderKey, targetIteration, futureMessagesMax) {
5
5
  const delta = targetIteration - senderKey.iteration;
6
- if (delta > SENDER_KEY_FUTURE_MESSAGES_MAX) {
6
+ if (delta > (futureMessagesMax ?? SENDER_KEY_FUTURE_MESSAGES_MAX)) {
7
7
  throw new Error('sender key message is too far in future');
8
8
  }
9
9
  const currentUnused = senderKey.unusedMessageKeys ?? [];
@@ -2,7 +2,7 @@ import { readVersionedContent, toSerializedPubKey } from '../../crypto/index.js'
2
2
  import { proto } from '../../proto.js';
3
3
  import { SIGNAL_SIGNATURE_LENGTH } from '../api/constants.js';
4
4
  import { SIGNAL_GROUP_VERSION } from '../constants.js';
5
- import { assertByteLength, toBytesView } from '../../util/bytes.js';
5
+ import { assertByteLength } from '../../util/bytes.js';
6
6
  export function parseDistributionPayload(payload) {
7
7
  const body = readVersionedContent(payload, SIGNAL_GROUP_VERSION, 0);
8
8
  const decoded = proto.SenderKeyDistributionMessage.decode(body);
@@ -16,13 +16,12 @@ export function parseDistributionPayload(payload) {
16
16
  decoded.signingKey === undefined) {
17
17
  throw new Error('invalid sender key distribution message');
18
18
  }
19
- const chainKey = toBytesView(decoded.chainKey);
20
- assertByteLength(chainKey, 32, 'sender key distribution chainKey must be 32 bytes');
19
+ assertByteLength(decoded.chainKey, 32, 'sender key distribution chainKey must be 32 bytes');
21
20
  return {
22
21
  keyId: decoded.id,
23
22
  iteration: decoded.iteration,
24
- chainKey,
25
- signingPublicKey: toSerializedPubKey(toBytesView(decoded.signingKey))
23
+ chainKey: decoded.chainKey,
24
+ signingPublicKey: toSerializedPubKey(decoded.signingKey)
26
25
  };
27
26
  }
28
27
  export function parseSenderKeyMessage(versionContentMac) {
@@ -39,7 +38,7 @@ export function parseSenderKeyMessage(versionContentMac) {
39
38
  return {
40
39
  keyId: decoded.id,
41
40
  iteration: decoded.iteration,
42
- ciphertext: toBytesView(decoded.ciphertext),
41
+ ciphertext: decoded.ciphertext,
43
42
  versionContentMac
44
43
  };
45
44
  }
@@ -1,10 +1,9 @@
1
- import { aesCbcDecrypt, aesCbcEncrypt, importAesCbcKey, toSerializedPubKey, prependVersion, randomBytesAsync, randomIntAsync, X25519 } from '../../crypto/index.js';
1
+ import { aesCbcDecrypt, aesCbcEncrypt, importAesCbcKey, prependVersion, randomBytesAsync, randomIntAsync, toRawPubKey, toSerializedPubKey, X25519, xeddsaSign, xeddsaVerify } from '../../crypto/index.js';
2
2
  import { StoreLock } from '../../infra/perf/StoreLock.js';
3
3
  import { proto } from '../../proto.js';
4
4
  import { signalAddressKey } from '../../protocol/jid.js';
5
5
  import { SIGNAL_SIGNATURE_LENGTH } from '../api/constants.js';
6
6
  import { SIGNAL_GROUP_VERSION } from '../constants.js';
7
- import { signSignalMessage, verifySignalSignature } from '../crypto/WaAdvSignature.js';
8
7
  import { deriveSenderKeyMsgKey, selectMessageKey } from '../group/SenderKeyChain.js';
9
8
  import { parseDistributionPayload, parseSenderKeyMessage } from '../group/SenderKeyCodec.js';
10
9
  import { concatBytes } from '../../util/bytes.js';
@@ -26,9 +25,11 @@ async function aesCbcDecryptFromSeed(seed, ciphertext) {
26
25
  return aesCbcDecrypt(await importAesCbcKey(keyBytes), iv, ciphertext);
27
26
  }
28
27
  export class SenderKeyManager {
29
- constructor(store) {
28
+ constructor(store, options) {
30
29
  this.senderLock = new StoreLock();
31
30
  this.store = store;
31
+ this.getFutureMessagesMax = options?.getFutureMessagesMax;
32
+ this.skipSignatureVerification = options?.skipSignatureVerification === true;
32
33
  }
33
34
  async prepareGroupEncryption(groupId, sender, plaintext) {
34
35
  return this.runWithSenderLock(groupId, sender, async () => {
@@ -59,7 +60,7 @@ export class SenderKeyManager {
59
60
  ciphertext: messagePayload
60
61
  }).finish();
61
62
  const versionedContent = prependVersion(senderKeyMessage, SIGNAL_GROUP_VERSION);
62
- const signature = await signSignalMessage(senderKey.signingPrivateKey, versionedContent);
63
+ const signature = await xeddsaSign(senderKey.signingPrivateKey, versionedContent);
63
64
  if (signature.length !== SIGNAL_SIGNATURE_LENGTH) {
64
65
  throw new Error(`invalid sender key signature length ${signature.length}`);
65
66
  }
@@ -163,13 +164,15 @@ export class SenderKeyManager {
163
164
  parsed.iteration !== payload.iteration) {
164
165
  throw new Error('sender key iteration mismatch');
165
166
  }
166
- const signedContent = parsed.versionContentMac.subarray(0, parsed.versionContentMac.length - SIGNAL_SIGNATURE_LENGTH);
167
- const signature = parsed.versionContentMac.subarray(parsed.versionContentMac.length - SIGNAL_SIGNATURE_LENGTH);
168
- const validSignature = await verifySignalSignature(senderKey.signingPublicKey, signedContent, signature);
169
- if (!validSignature) {
170
- throw new Error('invalid sender key signature');
167
+ if (!this.skipSignatureVerification) {
168
+ const signedContent = parsed.versionContentMac.subarray(0, parsed.versionContentMac.length - SIGNAL_SIGNATURE_LENGTH);
169
+ const signature = parsed.versionContentMac.subarray(parsed.versionContentMac.length - SIGNAL_SIGNATURE_LENGTH);
170
+ const validSignature = await xeddsaVerify(toRawPubKey(senderKey.signingPublicKey), signedContent, signature);
171
+ if (!validSignature) {
172
+ throw new Error('invalid sender key signature');
173
+ }
171
174
  }
172
- const selected = await selectMessageKey(senderKey, parsed.iteration);
175
+ const selected = await selectMessageKey(senderKey, parsed.iteration, this.getFutureMessagesMax?.());
173
176
  // Keep decrypt + persist ordered: failed decrypt must not advance sender-key state.
174
177
  const plaintext = await aesCbcDecryptFromSeed(selected.messageKey.seed, parsed.ciphertext);
175
178
  await this.store.upsertSenderKey(selected.updatedRecord);
@@ -1,7 +1,6 @@
1
- import { randomIntAsync } from '../../crypto/index.js';
1
+ import { randomIntAsync, xeddsaSign } from '../../crypto/index.js';
2
2
  import { toSerializedPubKey } from '../../crypto/core/keys.js';
3
3
  import { X25519 } from '../../crypto/curves/X25519.js';
4
- import { signSignalMessage } from '../crypto/WaAdvSignature.js';
5
4
  export async function generateRegistrationInfo() {
6
5
  const [registrationId, identityKeyPair] = await Promise.all([
7
6
  generateRegistrationId(),
@@ -22,7 +21,7 @@ export async function generatePreKeyPair(keyId) {
22
21
  export async function generateSignedPreKey(keyId, signingPrivateKey) {
23
22
  const keyPair = await X25519.generateKeyPair();
24
23
  const serializedPubKey = toSerializedPubKey(keyPair.pubKey);
25
- const signature = await signSignalMessage(signingPrivateKey, serializedPubKey);
24
+ const signature = await xeddsaSign(signingPrivateKey, serializedPubKey);
26
25
  return {
27
26
  keyId,
28
27
  keyPair,
@@ -1,5 +1,5 @@
1
1
  import { generatePreKeyPair, generateRegistrationInfo, generateSignedPreKey } from '../registration/keygen.js';
2
- export async function createAndStoreInitialKeys(store) {
2
+ export async function createAndStoreInitialKeys(store, preKeyStore) {
3
3
  const [registrationInfo, firstPreKey] = await Promise.all([
4
4
  generateRegistrationInfo(),
5
5
  generatePreKeyPair(1)
@@ -8,7 +8,7 @@ export async function createAndStoreInitialKeys(store) {
8
8
  // Keep writes ordered so partial commit failures don't leave split registration bootstrap state.
9
9
  await store.setRegistrationInfo(registrationInfo);
10
10
  await store.setSignedPreKey(signedPreKey);
11
- await store.getOrGenSinglePreKey(async () => firstPreKey);
11
+ await preKeyStore.getOrGenSinglePreKey(async () => firstPreKey);
12
12
  return {
13
13
  registrationInfo,
14
14
  signedPreKey,
@@ -2,6 +2,7 @@ import { toSerializedPubKey } from '../../crypto/index.js';
2
2
  import { ConsoleLogger } from '../../infra/log/ConsoleLogger.js';
3
3
  import { StoreLock } from '../../infra/perf/StoreLock.js';
4
4
  import { MAX_PREV_SESSIONS } from '../constants.js';
5
+ import { encodeSignalSessionSnapshot } from '../encoding.js';
5
6
  import { decryptMsg, decryptMsgFromSession, encryptMsg } from '../session/SignalRatchet.js';
6
7
  import { deserializeMsg, deserializePkMsg, requirePreKey, requireSignedPreKey } from '../session/SignalSerializer.js';
7
8
  import { detachSession, findMatchingSession, generateSerializedKeyPair, initiateSessionIncoming, initiateSessionOutgoing, requireLocalIdentity, toSerializedKeyPair } from '../session/SignalSession.js';
@@ -13,15 +14,15 @@ function signalAddressLockKey(address) {
13
14
  return `signal:${signalAddressMapKey(address)}`;
14
15
  }
15
16
  export class SignalProtocol {
16
- constructor(store, logger = new ConsoleLogger('info')) {
17
- this.store = store;
17
+ constructor(stores, logger = new ConsoleLogger('info')) {
18
+ this.stores = stores;
18
19
  this.logger = logger;
19
20
  this.sessionMutationLock = new StoreLock();
20
21
  }
21
22
  async establishOutgoingSession(address, remoteBundle, options = {}) {
22
23
  return this.runWithAddressLock(address, async () => {
23
24
  if (options.reuseExisting) {
24
- const existing = await this.store.getSession(address);
25
+ const existing = await this.stores.session.getSession(address);
25
26
  if (existing) {
26
27
  const remoteIdentity = toSerializedPubKey(remoteBundle.identity);
27
28
  if (!uint8Equal(existing.remote.pubKey, remoteIdentity)) {
@@ -31,13 +32,13 @@ export class SignalProtocol {
31
32
  }
32
33
  }
33
34
  const [local, localOneTimeBase] = await Promise.all([
34
- requireLocalIdentity(this.store),
35
+ requireLocalIdentity(this.stores.signal),
35
36
  generateSerializedKeyPair()
36
37
  ]);
37
38
  const session = await initiateSessionOutgoing(local, remoteBundle, localOneTimeBase);
38
39
  // Keep writes ordered: a stored session without matching remote identity causes false mismatch checks.
39
- await this.store.setRemoteIdentity(address, session.remote.pubKey);
40
- await this.store.setSession(address, session);
40
+ await this.stores.identity.setRemoteIdentity(address, session.remote.pubKey);
41
+ await this.stores.session.setSession(address, session);
41
42
  return session;
42
43
  });
43
44
  }
@@ -85,7 +86,7 @@ export class SignalProtocol {
85
86
  }
86
87
  uniqueAddressKeys.length = uniqueAddressCount;
87
88
  uniqueAddresses.length = uniqueAddressCount;
88
- const currentSessions = await this.store.getSessionsBatch(uniqueAddresses);
89
+ const currentSessions = await this.stores.session.getSessionsBatch(uniqueAddresses);
89
90
  const latestSessionByAddress = new Map();
90
91
  for (let index = 0; index < uniqueAddressCount; index += 1) {
91
92
  const addressKey = uniqueAddressKeys[index];
@@ -139,7 +140,7 @@ export class SignalProtocol {
139
140
  identityUpdates[identityIndex] = update;
140
141
  identityIndex += 1;
141
142
  }
142
- await this.store.setRemoteIdentities(identityUpdates);
143
+ await this.stores.identity.setRemoteIdentities(identityUpdates);
143
144
  }
144
145
  const sessionUpdates = new Array(sessionUpdatesByAddress.size);
145
146
  let sessionIndex = 0;
@@ -147,13 +148,13 @@ export class SignalProtocol {
147
148
  sessionUpdates[sessionIndex] = update;
148
149
  sessionIndex += 1;
149
150
  }
150
- await this.store.setSessionsBatch(sessionUpdates);
151
+ await this.stores.session.setSessionsBatch(sessionUpdates);
151
152
  return results;
152
153
  });
153
154
  }
154
155
  async decryptMessage(address, envelope) {
155
156
  return this.runWithAddressLock(address, async () => {
156
- const currentSession = await this.store.getSession(address);
157
+ const currentSession = await this.stores.session.getSession(address);
157
158
  let outcome;
158
159
  if (envelope.type === 'pkmsg') {
159
160
  const parsedPk = deserializePkMsg(envelope.ciphertext);
@@ -172,9 +173,9 @@ export class SignalProtocol {
172
173
  const identityChanged = !currentSession || !uint8Equal(currentSession.remote.pubKey, nextRemoteIdentity);
173
174
  // Keep writes ordered for consistency with resolver identity checks.
174
175
  if (identityChanged) {
175
- await this.store.setRemoteIdentity(address, nextRemoteIdentity);
176
+ await this.stores.identity.setRemoteIdentity(address, nextRemoteIdentity);
176
177
  }
177
- await this.store.setSession(address, outcome.updatedSession);
178
+ await this.stores.session.setSession(address, outcome.updatedSession);
178
179
  return outcome.plaintext;
179
180
  });
180
181
  }
@@ -192,11 +193,11 @@ export class SignalProtocol {
192
193
  };
193
194
  }
194
195
  const [local, signedPreKey, oneTimePreKey] = await Promise.all([
195
- requireLocalIdentity(this.store),
196
- requireSignedPreKey(this.store, parsed.localSignedPreKeyId),
196
+ requireLocalIdentity(this.stores.signal),
197
+ requireSignedPreKey(this.stores.signal, parsed.localSignedPreKeyId),
197
198
  parsed.localOneTimeKeyId === null || parsed.localOneTimeKeyId === undefined
198
199
  ? Promise.resolve(null)
199
- : requirePreKey(this.store, parsed.localOneTimeKeyId)
200
+ : requirePreKey(this.stores.preKey, parsed.localOneTimeKeyId)
200
201
  ]);
201
202
  const incoming = await initiateSessionIncoming(local, parsed.remote, parsed.sessionBaseKey, {
202
203
  signed: toSerializedKeyPair(signedPreKey.keyPair),
@@ -210,7 +211,7 @@ export class SignalProtocol {
210
211
  ? {
211
212
  ...incoming,
212
213
  prevSessions: [
213
- detachSession(currentSession),
214
+ encodeSignalSessionSnapshot(detachSession(currentSession)),
214
215
  ...currentSession.prevSessions.slice(0, MAX_PREV_SESSIONS - 1)
215
216
  ]
216
217
  }
@@ -218,7 +219,7 @@ export class SignalProtocol {
218
219
  const [updatedSession, plaintext] = await decryptMsgFromSession(baseSession, parsed);
219
220
  // Only consume one-time prekeys after successful decrypt/session materialization.
220
221
  if (parsed.localOneTimeKeyId !== null && parsed.localOneTimeKeyId !== undefined) {
221
- await this.store.consumePreKeyById(parsed.localOneTimeKeyId);
222
+ await this.stores.preKey.consumePreKeyById(parsed.localOneTimeKeyId);
222
223
  }
223
224
  return {
224
225
  updatedSession,
@@ -1,7 +1,8 @@
1
- import { aesCbcDecrypt, aesCbcEncrypt, hkdf, importAesCbcKey, importHmacKey, hmacSign, prependVersion, toSerializedPubKey } from '../../crypto/index.js';
1
+ import { aesCbcDecrypt, aesCbcEncrypt, hkdf, hmacSign, importAesCbcKey, importHmacKey, prependVersion, toSerializedPubKey } from '../../crypto/index.js';
2
2
  import { proto } from '../../proto.js';
3
3
  import { CHAIN_KEY_LABEL, FUTURE_MESSAGES_MAX, MAX_UNUSED_KEYS, MESSAGE_KEY_LABEL, SIGNAL_MAC_SIZE, SIGNAL_VERSION } from '../constants.js';
4
- import { detachSession, calculateRatchet, generateSerializedKeyPair, snapshotToRecord } from '../session/SignalSession.js';
4
+ import { decodeSignalMessageKey, decodeSignalRecvChain, decodeSignalSessionSnapshot, encodeSignalRecvChain, encodeSignalSessionSnapshot } from '../encoding.js';
5
+ import { calculateRatchet, detachSession, generateSerializedKeyPair, snapshotToRecord } from '../session/SignalSession.js';
5
6
  import { concatBytes, removeAt, uint8Equal } from '../../util/bytes.js';
6
7
  import { toError } from '../../util/primitives.js';
7
8
  const MAX_TRACKED_RECV_CHAINS = 4;
@@ -35,7 +36,7 @@ export async function selectMessageKey(chain, targetCounter) {
35
36
  if (idx === -1) {
36
37
  throw new Error('duplicate message');
37
38
  }
38
- const messageKey = unused[idx];
39
+ const messageKey = decodeSignalMessageKey(unused[idx], `unusedMsgKeys[${idx}]`);
39
40
  const nextUnused = removeAt(unused, idx);
40
41
  return {
41
42
  messageKey,
@@ -73,7 +74,12 @@ export async function selectMessageKey(chain, targetCounter) {
73
74
  overflow -= 1;
74
75
  }
75
76
  else {
76
- nextUnused.push(currentMessageKey);
77
+ nextUnused.push({
78
+ index: currentMessageKey.index,
79
+ cipherKey: currentMessageKey.cipherKey,
80
+ macKey: currentMessageKey.macKey,
81
+ iv: currentMessageKey.iv
82
+ });
77
83
  }
78
84
  const derived = await deriveMsgKeyFromState(counter, chainState);
79
85
  currentMessageKey = derived.messageKey;
@@ -174,13 +180,14 @@ export async function decryptMsg(session, parsed, onPrevSessionDecryptError) {
174
180
  }
175
181
  catch (error) {
176
182
  for (let i = 0; i < session.prevSessions.length; i += 1) {
177
- const prevSession = snapshotToRecord(session.prevSessions[i]);
183
+ const decodedPrev = decodeSignalSessionSnapshot(session.prevSessions[i], `prevSessions[${i}]`);
184
+ const prevSession = snapshotToRecord(decodedPrev);
178
185
  try {
179
186
  const [updatedPrev, plaintext] = await decryptMsgFromSession(prevSession, parsed);
180
187
  const updatedSession = {
181
188
  ...updatedPrev,
182
189
  prevSessions: [
183
- detachSession(session),
190
+ encodeSignalSessionSnapshot(detachSession(session)),
184
191
  ...session.prevSessions.slice(0, i),
185
192
  ...session.prevSessions.slice(i + 1)
186
193
  ]
@@ -207,7 +214,10 @@ export async function decryptMsg(session, parsed, onPrevSessionDecryptError) {
207
214
  }
208
215
  export async function decryptMsgFromSession(session, message) {
209
216
  const ratchetPubKey = toSerializedPubKey(message.ratchetPubKey);
210
- const recvChainIndex = session.recvChains.findIndex((entry) => uint8Equal(entry.ratchetPubKey, ratchetPubKey));
217
+ const recvChainIndex = session.recvChains.findIndex((raw) => {
218
+ const key = raw.senderRatchetKey;
219
+ return key !== null && key !== undefined && uint8Equal(key, ratchetPubKey);
220
+ });
211
221
  let selectedMessageKey;
212
222
  let updatedSession;
213
223
  if (recvChainIndex === -1) {
@@ -225,7 +235,7 @@ export async function decryptMsgFromSession(session, message) {
225
235
  selectedMessageKey = selected.messageKey;
226
236
  const sendRatchet = await calculateRatchet(recvRatchet.rootKey, newSendRatchet, ratchetPubKey);
227
237
  const nextRecvChains = session.recvChains.slice(-MAX_TRACKED_RECV_CHAINS);
228
- nextRecvChains.push(selected.updatedChain);
238
+ nextRecvChains.push(encodeSignalRecvChain(selected.updatedChain));
229
239
  updatedSession = {
230
240
  ...session,
231
241
  rootKey: sendRatchet.rootKey,
@@ -240,10 +250,11 @@ export async function decryptMsgFromSession(session, message) {
240
250
  };
241
251
  }
242
252
  else {
243
- const selected = await selectMessageKey(session.recvChains[recvChainIndex], message.counter);
253
+ const decoded = decodeSignalRecvChain(session.recvChains[recvChainIndex], `recvChains[${recvChainIndex}]`);
254
+ const selected = await selectMessageKey(decoded, message.counter);
244
255
  selectedMessageKey = selected.messageKey;
245
256
  const nextRecvChains = session.recvChains.slice();
246
- nextRecvChains[recvChainIndex] = selected.updatedChain;
257
+ nextRecvChains[recvChainIndex] = encodeSignalRecvChain(selected.updatedChain);
247
258
  updatedSession = {
248
259
  ...session,
249
260
  recvChains: nextRecvChains
@@ -1,7 +1,6 @@
1
1
  import { readVersionedContent, toSerializedPubKey } from '../../crypto/index.js';
2
2
  import { proto } from '../../proto.js';
3
3
  import { SIGNAL_MAC_SIZE, SIGNAL_VERSION } from '../constants.js';
4
- import { toBytesView } from '../../util/bytes.js';
5
4
  export function deserializeMsg(versionContentMac) {
6
5
  const content = readVersionedContent(versionContentMac, SIGNAL_VERSION, SIGNAL_MAC_SIZE);
7
6
  const parsed = proto.SignalMessage.decode(content);
@@ -14,9 +13,9 @@ export function deserializeMsg(versionContentMac) {
14
13
  throw new Error('invalid signal message');
15
14
  }
16
15
  return {
17
- ratchetPubKey: toSerializedPubKey(toBytesView(parsed.ratchetKey)),
16
+ ratchetPubKey: toSerializedPubKey(parsed.ratchetKey),
18
17
  counter: parsed.counter,
19
- ciphertext: toBytesView(parsed.ciphertext),
18
+ ciphertext: parsed.ciphertext,
20
19
  versionContentMac
21
20
  };
22
21
  }
@@ -35,14 +34,14 @@ export function deserializePkMsg(versionContent) {
35
34
  parsed.message === undefined) {
36
35
  throw new Error('invalid prekey signal message');
37
36
  }
38
- const signal = deserializeMsg(toBytesView(parsed.message));
37
+ const signal = deserializeMsg(parsed.message);
39
38
  return {
40
39
  ...signal,
41
40
  remote: {
42
41
  regId: parsed.registrationId,
43
- pubKey: toSerializedPubKey(toBytesView(parsed.identityKey))
42
+ pubKey: toSerializedPubKey(parsed.identityKey)
44
43
  },
45
- sessionBaseKey: toSerializedPubKey(toBytesView(parsed.baseKey)),
44
+ sessionBaseKey: toSerializedPubKey(parsed.baseKey),
46
45
  localSignedPreKeyId: parsed.signedPreKeyId,
47
46
  localOneTimeKeyId: parsed.preKeyId ?? null
48
47
  };
@@ -1,5 +1,6 @@
1
1
  import { hkdfSplit, toRawPubKey, toSerializedPubKey, X25519 } from '../../crypto/index.js';
2
2
  import { SIGNAL_PREFIX } from '../constants.js';
3
+ import { decodeSignalSessionSnapshot, encodeSignalSessionSnapshot } from '../encoding.js';
3
4
  import { concatBytes, uint8Equal } from '../../util/bytes.js';
4
5
  export function snapshotToRecord(snapshot) {
5
6
  return {
@@ -21,19 +22,21 @@ export function findMatchingSession(session, sessionBaseKey) {
21
22
  return session;
22
23
  }
23
24
  for (let index = 0; index < session.prevSessions.length; index += 1) {
24
- const previousSession = session.prevSessions[index];
25
- if (!previousSession.aliceBaseKey ||
26
- !uint8Equal(previousSession.aliceBaseKey, serializedBaseKey)) {
25
+ const rawPrev = session.prevSessions[index];
26
+ if (!rawPrev.aliceBaseKey || !uint8Equal(rawPrev.aliceBaseKey, serializedBaseKey)) {
27
27
  continue;
28
28
  }
29
- const prevSessions = [detachSession(session)];
29
+ const decoded = decodeSignalSessionSnapshot(rawPrev, `prevSessions[${index}]`);
30
+ const prevSessions = [
31
+ encodeSignalSessionSnapshot(detachSession(session))
32
+ ];
30
33
  for (let i = 0; i < session.prevSessions.length; i += 1) {
31
34
  if (i !== index) {
32
35
  prevSessions.push(session.prevSessions[i]);
33
36
  }
34
37
  }
35
38
  return {
36
- ...previousSession,
39
+ ...decoded,
37
40
  prevSessions
38
41
  };
39
42
  }
@@ -73,10 +76,9 @@ export async function initiateSessionOutgoing(local, remoteBundle, localOneTimeB
73
76
  ]);
74
77
  const [rootKey, chainKey] = await hkdfSplit(secret, null, 'WhisperText');
75
78
  const recvChain = {
76
- ratchetPubKey: remoteRatchetKey,
77
- nextMsgIndex: 0,
78
- chainKey,
79
- unusedMsgKeys: []
79
+ senderRatchetKey: remoteRatchetKey,
80
+ chainKey: { index: 0, key: chainKey },
81
+ messageKeys: []
80
82
  };
81
83
  const sendRatchet = await generateSerializedKeyPair();
82
84
  const sendRatchetResult = await calculateRatchet(rootKey, sendRatchet, remoteRatchetKey);
@@ -4,7 +4,7 @@ import { normalizeDeviceJid, parseSignalAddressFromJid, signalAddressKey } from
4
4
  import { bytesToHex, uint8Equal } from '../../util/bytes.js';
5
5
  import { toError } from '../../util/primitives.js';
6
6
  export function createSignalSessionResolver(options) {
7
- const { signalProtocol, signalStore, signalIdentitySync, signalSessionSync, logger } = options;
7
+ const { signalProtocol, sessionStore, identityStore, signalIdentitySync, signalSessionSync, logger } = options;
8
8
  const dedup = new PromiseDedup();
9
9
  const ensureSessionInternal = async (address, jid, expectedIdentity, reasonIdentity = false, prefetchedBundle) => {
10
10
  const expectedSerializedIdentity = expectedIdentity
@@ -13,9 +13,9 @@ export function createSignalSessionResolver(options) {
13
13
  if (reasonIdentity) {
14
14
  await signalIdentitySync.syncIdentityKeys([jid]);
15
15
  }
16
- if (await signalStore.hasSession(address)) {
16
+ if (await sessionStore.hasSession(address)) {
17
17
  if (expectedSerializedIdentity) {
18
- const storedIdentity = await signalStore.getRemoteIdentity(address);
18
+ const storedIdentity = await identityStore.getRemoteIdentity(address);
19
19
  if (!storedIdentity || !uint8Equal(storedIdentity, expectedSerializedIdentity)) {
20
20
  throw new Error('identity mismatch');
21
21
  }
@@ -38,7 +38,7 @@ export function createSignalSessionResolver(options) {
38
38
  }
39
39
  const remoteIdentity = toSerializedPubKey(fetched.bundle.identity);
40
40
  if (reasonIdentity) {
41
- const storedIdentity = await signalStore.getRemoteIdentity(address);
41
+ const storedIdentity = await identityStore.getRemoteIdentity(address);
42
42
  if (storedIdentity && !uint8Equal(remoteIdentity, storedIdentity)) {
43
43
  throw new Error('identity mismatch');
44
44
  }
@@ -96,7 +96,7 @@ export function createSignalSessionResolver(options) {
96
96
  }
97
97
  }
98
98
  }
99
- const resolvedByIndex = (await signalStore.getSessionsBatch(normalizedTargetAddresses));
99
+ const resolvedByIndex = (await sessionStore.getSessionsBatch(normalizedTargetAddresses));
100
100
  const collectResolvedTargets = () => {
101
101
  const resolvedTargets = new Array(normalizedTargetJids.length);
102
102
  let resolvedTargetCount = 0;
@@ -199,7 +199,7 @@ export function createSignalSessionResolver(options) {
199
199
  for (let i = 0; i < fallbackIndices.length; i++) {
200
200
  fallbackAddresses[i] = normalizedTargetAddresses[fallbackIndices[i]];
201
201
  }
202
- const fallbackSessions = await signalStore.getSessionsBatch(fallbackAddresses);
202
+ const fallbackSessions = await sessionStore.getSessionsBatch(fallbackAddresses);
203
203
  for (let i = 0; i < fallbackIndices.length; i++) {
204
204
  const session = fallbackSessions[i];
205
205
  if (session) {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};