zapo-js 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (366) hide show
  1. package/README.md +12 -7
  2. package/dist/appstate/WaAppStateCrypto.js +18 -25
  3. package/dist/appstate/WaAppStateSyncClient.js +181 -114
  4. package/dist/appstate/WaAppStateSyncResponseParser.js +16 -5
  5. package/dist/appstate/constants.js +4 -3
  6. package/dist/appstate/utils.js +10 -30
  7. package/dist/auth/WaAuthClient.js +48 -55
  8. package/dist/auth/flow/WaAuthCredentialsFlow.js +21 -14
  9. package/dist/auth/index.js +1 -3
  10. package/dist/auth/pairing/WaPairingFlow.js +21 -23
  11. package/dist/auth/pairing/WaQrFlow.js +37 -24
  12. package/dist/client/WaClient.js +103 -276
  13. package/dist/client/WaClientFactory.js +227 -110
  14. package/dist/client/connection/WaConnectionManager.js +292 -0
  15. package/dist/client/connection/WaKeyShareCoordinator.js +63 -0
  16. package/dist/client/connection/WaReceiptQueue.js +51 -0
  17. package/dist/client/coordinators/WaAppStateMutationCoordinator.js +471 -0
  18. package/dist/client/coordinators/WaGroupCoordinator.js +27 -17
  19. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +20 -27
  20. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +231 -686
  21. package/dist/client/coordinators/WaRetryCoordinator.js +70 -37
  22. package/dist/client/dirty.js +35 -29
  23. package/dist/client/events/chat.js +4 -3
  24. package/dist/client/events/group.js +59 -36
  25. package/dist/client/history-sync.js +53 -63
  26. package/dist/client/incoming.js +23 -20
  27. package/dist/client/mailbox.js +8 -8
  28. package/dist/client/messages.js +4 -4
  29. package/dist/client/messaging/fanout.js +189 -0
  30. package/dist/client/messaging/key-protocol.js +130 -0
  31. package/dist/client/messaging/participants.js +191 -0
  32. package/dist/crypto/core/hkdf.js +3 -8
  33. package/dist/crypto/core/index.js +1 -4
  34. package/dist/crypto/core/keys.js +2 -3
  35. package/dist/crypto/core/primitives.js +12 -15
  36. package/dist/crypto/core/random.js +7 -26
  37. package/dist/crypto/curves/Ed25519.js +7 -8
  38. package/dist/crypto/curves/X25519.js +13 -16
  39. package/dist/crypto/index.js +0 -5
  40. package/dist/esm/appstate/WaAppStateCrypto.js +6 -13
  41. package/dist/esm/appstate/WaAppStateSyncClient.js +174 -107
  42. package/dist/esm/appstate/WaAppStateSyncResponseParser.js +17 -6
  43. package/dist/esm/appstate/constants.js +3 -2
  44. package/dist/esm/appstate/utils.js +8 -27
  45. package/dist/esm/auth/WaAuthClient.js +48 -55
  46. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +21 -14
  47. package/dist/esm/auth/index.js +0 -1
  48. package/dist/esm/auth/pairing/WaPairingFlow.js +14 -16
  49. package/dist/esm/auth/pairing/WaQrFlow.js +37 -24
  50. package/dist/esm/client/WaClient.js +103 -276
  51. package/dist/esm/client/WaClientFactory.js +227 -110
  52. package/dist/esm/client/connection/WaConnectionManager.js +288 -0
  53. package/dist/esm/client/connection/WaKeyShareCoordinator.js +59 -0
  54. package/dist/esm/client/connection/WaReceiptQueue.js +47 -0
  55. package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +467 -0
  56. package/dist/esm/client/coordinators/WaGroupCoordinator.js +20 -10
  57. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +20 -27
  58. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +232 -687
  59. package/dist/esm/client/coordinators/WaRetryCoordinator.js +71 -38
  60. package/dist/esm/client/dirty.js +30 -24
  61. package/dist/esm/client/events/chat.js +4 -3
  62. package/dist/esm/client/events/group.js +50 -28
  63. package/dist/esm/client/history-sync.js +50 -60
  64. package/dist/esm/client/incoming.js +23 -20
  65. package/dist/esm/client/mailbox.js +8 -8
  66. package/dist/esm/client/messages.js +1 -1
  67. package/dist/esm/client/messaging/fanout.js +186 -0
  68. package/dist/esm/client/messaging/key-protocol.js +127 -0
  69. package/dist/esm/client/messaging/participants.js +188 -0
  70. package/dist/esm/crypto/core/hkdf.js +3 -8
  71. package/dist/esm/crypto/core/index.js +0 -1
  72. package/dist/esm/crypto/core/keys.js +2 -3
  73. package/dist/esm/crypto/core/primitives.js +12 -15
  74. package/dist/esm/crypto/core/random.js +6 -25
  75. package/dist/esm/crypto/curves/Ed25519.js +4 -5
  76. package/dist/esm/crypto/curves/X25519.js +10 -13
  77. package/dist/esm/crypto/index.js +0 -2
  78. package/dist/esm/infra/log/ConsoleLogger.js +18 -17
  79. package/dist/esm/infra/log/PinoLogger.js +15 -9
  80. package/dist/esm/infra/log/types.js +11 -1
  81. package/dist/esm/infra/perf/BoundedTaskQueue.js +13 -17
  82. package/dist/esm/media/WaMediaCrypto.js +2 -4
  83. package/dist/esm/media/WaMediaTransferClient.js +226 -58
  84. package/dist/esm/media/conn.js +10 -6
  85. package/dist/esm/media/constants.js +4 -1
  86. package/dist/esm/message/WaMessageClient.js +4 -13
  87. package/dist/esm/message/ack.js +6 -6
  88. package/dist/esm/message/addon-crypto.js +59 -0
  89. package/dist/esm/message/incoming.js +106 -111
  90. package/dist/esm/message/index.js +2 -0
  91. package/dist/esm/message/reporting-token.js +438 -0
  92. package/dist/esm/message/use-case-secret.js +49 -0
  93. package/dist/esm/protocol/appstate.js +58 -0
  94. package/dist/esm/protocol/constants.js +2 -1
  95. package/dist/esm/protocol/index.js +2 -10
  96. package/dist/esm/protocol/jid.js +63 -51
  97. package/dist/esm/protocol/media.js +3 -3
  98. package/dist/esm/protocol/nodes.js +2 -0
  99. package/dist/esm/protocol/usync.js +11 -0
  100. package/dist/esm/retry/index.js +1 -0
  101. package/dist/esm/retry/outbound.js +4 -5
  102. package/dist/esm/retry/parse.js +58 -76
  103. package/dist/esm/retry/replay.js +48 -49
  104. package/dist/esm/retry/tracker.js +56 -0
  105. package/dist/esm/signal/api/SignalDeviceSyncApi.js +249 -82
  106. package/dist/esm/signal/api/SignalDigestSyncApi.js +6 -1
  107. package/dist/esm/signal/api/SignalIdentitySyncApi.js +49 -34
  108. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +70 -62
  109. package/dist/esm/signal/api/SignalSessionSyncApi.js +23 -30
  110. package/dist/esm/signal/crypto/WaAdvSignature.js +3 -5
  111. package/dist/esm/signal/group/SenderKeyChain.js +28 -23
  112. package/dist/esm/signal/group/SenderKeyCodec.js +2 -4
  113. package/dist/esm/signal/group/SenderKeyManager.js +26 -16
  114. package/dist/esm/signal/index.js +1 -0
  115. package/dist/esm/signal/session/SignalProtocol.js +49 -14
  116. package/dist/esm/signal/session/SignalRatchet.js +24 -15
  117. package/dist/esm/signal/session/SignalSession.js +14 -9
  118. package/dist/esm/signal/session/resolver.js +186 -0
  119. package/dist/esm/signal/store/sqlite.js +16 -37
  120. package/dist/esm/store/createStore.js +16 -18
  121. package/dist/esm/store/noop.store.js +3 -6
  122. package/dist/esm/store/providers/memory/appstate.store.js +30 -6
  123. package/dist/esm/store/providers/memory/contact.store.js +5 -0
  124. package/dist/esm/store/providers/memory/device-list.store.js +3 -30
  125. package/dist/esm/store/providers/memory/message.store.js +11 -5
  126. package/dist/esm/store/providers/memory/participants.store.js +1 -8
  127. package/dist/esm/store/providers/memory/sender-key.store.js +5 -7
  128. package/dist/esm/store/providers/memory/signal.store.js +13 -1
  129. package/dist/esm/store/providers/memory/thread.store.js +5 -0
  130. package/dist/esm/store/providers/sqlite/appstate.store.js +82 -1
  131. package/dist/esm/store/providers/sqlite/connection.js +18 -13
  132. package/dist/esm/store/providers/sqlite/contact.store.js +31 -18
  133. package/dist/esm/store/providers/sqlite/device-list.store.js +7 -35
  134. package/dist/esm/store/providers/sqlite/message.store.js +45 -32
  135. package/dist/esm/store/providers/sqlite/migrations.js +1 -1
  136. package/dist/esm/store/providers/sqlite/participants.store.js +1 -9
  137. package/dist/esm/store/providers/sqlite/retry.store.js +8 -11
  138. package/dist/esm/store/providers/sqlite/sender-key.store.js +25 -30
  139. package/dist/esm/store/providers/sqlite/signal.store.js +104 -22
  140. package/dist/esm/store/providers/sqlite/table-names.js +107 -0
  141. package/dist/esm/store/providers/sqlite/thread.store.js +35 -22
  142. package/dist/esm/transport/WaComms.js +25 -23
  143. package/dist/esm/transport/WaWebSocket.js +115 -12
  144. package/dist/esm/transport/binary/decoder.js +4 -4
  145. package/dist/esm/transport/binary/encoder.js +12 -4
  146. package/dist/esm/transport/index.js +1 -0
  147. package/dist/esm/transport/keepalive/WaKeepAlive.js +2 -8
  148. package/dist/esm/transport/node/WaNodeOrchestrator.js +2 -4
  149. package/dist/esm/transport/node/WaNodeTransport.js +0 -3
  150. package/dist/esm/transport/node/builders/{accountSync.js → account-sync.js} +16 -36
  151. package/dist/esm/transport/node/builders/index.js +2 -1
  152. package/dist/esm/transport/node/builders/message.js +9 -0
  153. package/dist/esm/transport/node/builders/pairing.js +4 -5
  154. package/dist/esm/transport/node/builders/usync.js +41 -0
  155. package/dist/esm/transport/node/helpers.js +107 -5
  156. package/dist/esm/transport/node/usync.js +35 -0
  157. package/dist/esm/transport/noise/WaFrameCodec.js +48 -33
  158. package/dist/esm/transport/noise/WaNoiseCert.js +3 -6
  159. package/dist/esm/transport/noise/WaNoiseSession.js +17 -10
  160. package/dist/esm/transport/proxy.js +27 -0
  161. package/dist/esm/transport/stream/parse.js +13 -48
  162. package/dist/esm/util/bytes.js +50 -32
  163. package/dist/esm/util/coercion.js +6 -14
  164. package/dist/esm/util/primitives.js +39 -14
  165. package/dist/infra/log/ConsoleLogger.js +18 -17
  166. package/dist/infra/log/PinoLogger.js +15 -9
  167. package/dist/infra/log/types.js +12 -0
  168. package/dist/infra/perf/BoundedTaskQueue.js +13 -17
  169. package/dist/media/WaMediaCrypto.js +1 -3
  170. package/dist/media/WaMediaTransferClient.js +259 -58
  171. package/dist/media/conn.js +10 -6
  172. package/dist/media/constants.js +4 -1
  173. package/dist/message/WaMessageClient.js +5 -14
  174. package/dist/message/ack.js +6 -6
  175. package/dist/message/addon-crypto.js +65 -0
  176. package/dist/message/incoming.js +104 -109
  177. package/dist/message/index.js +2 -0
  178. package/dist/message/reporting-token.js +443 -0
  179. package/dist/message/use-case-secret.js +55 -0
  180. package/dist/protocol/appstate.js +59 -1
  181. package/dist/protocol/constants.js +7 -1
  182. package/dist/protocol/index.js +20 -42
  183. package/dist/protocol/jid.js +64 -51
  184. package/dist/protocol/media.js +3 -3
  185. package/dist/protocol/nodes.js +2 -0
  186. package/dist/protocol/usync.js +14 -0
  187. package/dist/retry/index.js +3 -1
  188. package/dist/retry/outbound.js +6 -7
  189. package/dist/retry/parse.js +57 -75
  190. package/dist/retry/replay.js +46 -47
  191. package/dist/retry/tracker.js +59 -0
  192. package/dist/signal/api/SignalDeviceSyncApi.js +247 -80
  193. package/dist/signal/api/SignalDigestSyncApi.js +6 -1
  194. package/dist/signal/api/SignalIdentitySyncApi.js +49 -34
  195. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +67 -59
  196. package/dist/signal/api/SignalSessionSyncApi.js +23 -30
  197. package/dist/signal/crypto/WaAdvSignature.js +2 -4
  198. package/dist/signal/group/SenderKeyChain.js +27 -22
  199. package/dist/signal/group/SenderKeyCodec.js +1 -3
  200. package/dist/signal/group/SenderKeyManager.js +26 -16
  201. package/dist/signal/index.js +3 -1
  202. package/dist/signal/session/SignalProtocol.js +49 -14
  203. package/dist/signal/session/SignalRatchet.js +24 -15
  204. package/dist/signal/session/SignalSession.js +14 -9
  205. package/dist/signal/session/resolver.js +189 -0
  206. package/dist/signal/store/sqlite.js +16 -37
  207. package/dist/store/createStore.js +16 -18
  208. package/dist/store/noop.store.js +3 -6
  209. package/dist/store/providers/memory/appstate.store.js +28 -4
  210. package/dist/store/providers/memory/contact.store.js +5 -0
  211. package/dist/store/providers/memory/device-list.store.js +3 -30
  212. package/dist/store/providers/memory/message.store.js +11 -5
  213. package/dist/store/providers/memory/participants.store.js +1 -8
  214. package/dist/store/providers/memory/sender-key.store.js +8 -10
  215. package/dist/store/providers/memory/signal.store.js +21 -9
  216. package/dist/store/providers/memory/thread.store.js +5 -0
  217. package/dist/store/providers/sqlite/appstate.store.js +81 -0
  218. package/dist/store/providers/sqlite/connection.js +18 -13
  219. package/dist/store/providers/sqlite/contact.store.js +31 -18
  220. package/dist/store/providers/sqlite/device-list.store.js +7 -35
  221. package/dist/store/providers/sqlite/message.store.js +45 -32
  222. package/dist/store/providers/sqlite/migrations.js +1 -1
  223. package/dist/store/providers/sqlite/participants.store.js +1 -9
  224. package/dist/store/providers/sqlite/retry.store.js +8 -11
  225. package/dist/store/providers/sqlite/sender-key.store.js +24 -29
  226. package/dist/store/providers/sqlite/signal.store.js +105 -23
  227. package/dist/store/providers/sqlite/table-names.js +113 -0
  228. package/dist/store/providers/sqlite/thread.store.js +35 -22
  229. package/dist/transport/WaComms.js +27 -25
  230. package/dist/transport/WaWebSocket.js +148 -12
  231. package/dist/transport/binary/decoder.js +4 -4
  232. package/dist/transport/binary/encoder.js +12 -4
  233. package/dist/transport/index.js +7 -1
  234. package/dist/transport/keepalive/WaKeepAlive.js +1 -7
  235. package/dist/transport/node/WaNodeOrchestrator.js +2 -4
  236. package/dist/transport/node/WaNodeTransport.js +0 -3
  237. package/dist/transport/node/builders/{accountSync.js → account-sync.js} +15 -35
  238. package/dist/transport/node/builders/index.js +12 -9
  239. package/dist/transport/node/builders/message.js +9 -0
  240. package/dist/transport/node/builders/pairing.js +4 -5
  241. package/dist/transport/node/builders/usync.js +45 -0
  242. package/dist/transport/node/helpers.js +112 -4
  243. package/dist/transport/node/usync.js +38 -0
  244. package/dist/transport/noise/WaFrameCodec.js +47 -32
  245. package/dist/transport/noise/WaNoiseCert.js +5 -8
  246. package/dist/transport/noise/WaNoiseSession.js +17 -10
  247. package/dist/transport/proxy.js +34 -0
  248. package/dist/transport/stream/parse.js +17 -53
  249. package/dist/types/appstate/WaAppStateCrypto.d.ts +0 -1
  250. package/dist/types/appstate/WaAppStateSyncClient.d.ts +5 -2
  251. package/dist/types/appstate/constants.d.ts +1 -0
  252. package/dist/types/appstate/store/sqlite.d.ts +4 -18
  253. package/dist/types/appstate/utils.d.ts +0 -1
  254. package/dist/types/auth/WaAuthClient.d.ts +10 -12
  255. package/dist/types/auth/index.d.ts +0 -2
  256. package/dist/types/auth/pairing/WaQrFlow.d.ts +1 -1
  257. package/dist/types/auth/types.d.ts +6 -9
  258. package/dist/types/client/WaClient.d.ts +27 -25
  259. package/dist/types/client/WaClientFactory.d.ts +22 -23
  260. package/dist/types/client/connection/WaConnectionManager.d.ts +64 -0
  261. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +14 -0
  262. package/dist/types/client/connection/WaReceiptQueue.d.ts +13 -0
  263. package/dist/types/client/coordinators/WaAppStateMutationCoordinator.d.ts +46 -0
  264. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +0 -1
  265. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +18 -41
  266. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +2 -0
  267. package/dist/types/client/dirty.d.ts +1 -0
  268. package/dist/types/client/events/group.d.ts +2 -1
  269. package/dist/types/client/index.d.ts +1 -1
  270. package/dist/types/client/messaging/fanout.d.ts +14 -0
  271. package/dist/types/client/messaging/key-protocol.d.ts +18 -0
  272. package/dist/types/client/messaging/participants.d.ts +13 -0
  273. package/dist/types/client/types.d.ts +24 -1
  274. package/dist/types/crypto/core/hkdf.d.ts +0 -6
  275. package/dist/types/crypto/core/index.d.ts +0 -1
  276. package/dist/types/crypto/core/random.d.ts +1 -7
  277. package/dist/types/crypto/index.d.ts +0 -2
  278. package/dist/types/index.d.ts +1 -1
  279. package/dist/types/infra/log/ConsoleLogger.d.ts +2 -1
  280. package/dist/types/infra/log/PinoLogger.d.ts +1 -1
  281. package/dist/types/infra/log/types.d.ts +1 -0
  282. package/dist/types/infra/perf/BoundedTaskQueue.d.ts +1 -1
  283. package/dist/types/media/WaMediaTransferClient.d.ts +13 -3
  284. package/dist/types/media/types.d.ts +5 -0
  285. package/dist/types/message/addon-crypto.d.ts +25 -0
  286. package/dist/types/message/index.d.ts +2 -0
  287. package/dist/types/message/reporting-token.d.ts +19 -0
  288. package/dist/types/message/use-case-secret.d.ts +20 -0
  289. package/dist/types/protocol/appstate.d.ts +58 -0
  290. package/dist/types/protocol/constants.d.ts +2 -1
  291. package/dist/types/protocol/index.d.ts +2 -10
  292. package/dist/types/protocol/jid.d.ts +3 -3
  293. package/dist/types/protocol/nodes.d.ts +2 -0
  294. package/dist/types/protocol/usync.d.ts +11 -0
  295. package/dist/types/retry/index.d.ts +1 -0
  296. package/dist/types/retry/replay.d.ts +0 -4
  297. package/dist/types/retry/tracker.d.ts +19 -0
  298. package/dist/types/retry/types.d.ts +4 -3
  299. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +13 -1
  300. package/dist/types/signal/group/SenderKeyCodec.d.ts +4 -6
  301. package/dist/types/signal/index.d.ts +1 -0
  302. package/dist/types/signal/session/SignalProtocol.d.ts +9 -0
  303. package/dist/types/signal/session/resolver.d.ts +17 -0
  304. package/dist/types/store/contracts/appstate.store.d.ts +3 -0
  305. package/dist/types/store/contracts/contact.store.d.ts +1 -0
  306. package/dist/types/store/contracts/device-list.store.d.ts +0 -3
  307. package/dist/types/store/contracts/message.store.d.ts +1 -0
  308. package/dist/types/store/contracts/participants.store.d.ts +0 -1
  309. package/dist/types/store/contracts/sender-key.store.d.ts +0 -1
  310. package/dist/types/store/contracts/signal.store.d.ts +6 -0
  311. package/dist/types/store/contracts/thread.store.d.ts +1 -0
  312. package/dist/types/store/index.d.ts +1 -1
  313. package/dist/types/store/providers/memory/appstate.store.d.ts +2 -0
  314. package/dist/types/store/providers/memory/contact.store.d.ts +1 -0
  315. package/dist/types/store/providers/memory/device-list.store.d.ts +0 -3
  316. package/dist/types/store/providers/memory/message.store.d.ts +1 -0
  317. package/dist/types/store/providers/memory/participants.store.d.ts +0 -1
  318. package/dist/types/store/providers/memory/sender-key.store.d.ts +0 -1
  319. package/dist/types/store/providers/memory/signal.store.d.ts +6 -0
  320. package/dist/types/store/providers/memory/thread.store.d.ts +1 -0
  321. package/dist/types/store/providers/sqlite/appstate.store.d.ts +2 -0
  322. package/dist/types/store/providers/sqlite/contact.store.d.ts +2 -0
  323. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -3
  324. package/dist/types/store/providers/sqlite/message.store.d.ts +2 -0
  325. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -1
  326. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -1
  327. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -1
  328. package/dist/types/store/providers/sqlite/signal.store.d.ts +7 -0
  329. package/dist/types/store/providers/sqlite/table-names.d.ts +5 -0
  330. package/dist/types/store/providers/sqlite/thread.store.d.ts +2 -0
  331. package/dist/types/store/types.d.ts +3 -0
  332. package/dist/types/transport/WaWebSocket.d.ts +3 -0
  333. package/dist/types/transport/index.d.ts +2 -1
  334. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +0 -1
  335. package/dist/types/transport/node/WaNodeTransport.d.ts +0 -9
  336. package/dist/types/transport/node/builders/group.d.ts +4 -6
  337. package/dist/types/transport/node/builders/index.d.ts +2 -1
  338. package/dist/types/transport/node/builders/message.d.ts +14 -25
  339. package/dist/types/transport/node/builders/retry.d.ts +2 -4
  340. package/dist/types/transport/node/builders/usync.d.ts +21 -0
  341. package/dist/types/transport/node/helpers.d.ts +8 -0
  342. package/dist/types/transport/node/usync.d.ts +2 -0
  343. package/dist/types/transport/noise/WaFrameCodec.d.ts +3 -0
  344. package/dist/types/transport/noise/WaNoiseSession.d.ts +1 -0
  345. package/dist/types/transport/proxy.d.ts +6 -0
  346. package/dist/types/transport/stream/parse.d.ts +0 -1
  347. package/dist/types/transport/types.d.ts +18 -1
  348. package/dist/types/util/bytes.d.ts +5 -0
  349. package/dist/types/util/primitives.d.ts +3 -0
  350. package/dist/util/bytes.js +55 -33
  351. package/dist/util/coercion.js +6 -14
  352. package/dist/util/primitives.js +42 -14
  353. package/package.json +27 -9
  354. package/proto/index.d.ts +1090 -1048
  355. package/proto/index.js +1 -1
  356. package/scripts/check-node-version.cjs +0 -1
  357. package/dist/crypto/core/encoding.js +0 -29
  358. package/dist/esm/crypto/core/encoding.js +0 -25
  359. package/dist/esm/util/base64.js +0 -18
  360. package/dist/esm/util/signal-address.js +0 -5
  361. package/dist/types/crypto/core/encoding.d.ts +0 -11
  362. package/dist/types/util/base64.d.ts +0 -4
  363. package/dist/types/util/signal-address.d.ts +0 -2
  364. package/dist/util/base64.js +0 -24
  365. package/dist/util/signal-address.js +0 -8
  366. /package/dist/types/transport/node/builders/{accountSync.d.ts → account-sync.d.ts} +0 -0
@@ -8,16 +8,6 @@ const constants_2 = require("../api/constants");
8
8
  const prekeys_1 = require("../api/prekeys");
9
9
  const helpers_1 = require("../../transport/node/helpers");
10
10
  const query_1 = require("../../transport/node/query");
11
- function parseDeviceId(value, field) {
12
- if (!value) {
13
- throw new Error(`${field} is missing`);
14
- }
15
- const parsed = Number.parseInt(value, 10);
16
- if (!Number.isSafeInteger(parsed) || parsed < 0) {
17
- throw new Error(`${field} is invalid`);
18
- }
19
- return parsed;
20
- }
21
11
  class SignalMissingPreKeysSyncApi {
22
12
  constructor(options) {
23
13
  this.logger = options.logger;
@@ -41,16 +31,7 @@ class SignalMissingPreKeysSyncApi {
41
31
  return parsed;
42
32
  }
43
33
  parseFetchMissingPreKeysResponse(node, requestedTargets) {
44
- if (node.tag !== constants_1.WA_NODE_TAGS.IQ) {
45
- throw new Error(`invalid missing prekeys response tag: ${node.tag}`);
46
- }
47
- if (node.attrs.type === constants_1.WA_IQ_TYPES.ERROR) {
48
- const error = (0, query_1.parseIqError)(node);
49
- throw new Error(`missing prekeys iq failed (${error.code}: ${error.text})`);
50
- }
51
- if (node.attrs.type !== constants_1.WA_IQ_TYPES.RESULT) {
52
- throw new Error(`invalid missing prekeys response type: ${node.attrs.type ?? 'unknown'}`);
53
- }
34
+ (0, query_1.assertIqResult)(node, 'missing prekeys');
54
35
  const listNode = (0, helpers_1.findNodeChild)(node, constants_1.WA_NODE_TAGS.LIST);
55
36
  if (!listNode) {
56
37
  throw new Error('missing prekeys response missing list node');
@@ -78,68 +59,95 @@ class SignalMissingPreKeysSyncApi {
78
59
  devices: this.parseUserDevices(userNode, userJid)
79
60
  });
80
61
  }
81
- return requestedTargets.map((target) => {
82
- return (parsedByJid.get(target.userJid) ?? {
62
+ const results = new Array(requestedTargets.length);
63
+ for (let index = 0; index < requestedTargets.length; index += 1) {
64
+ const target = requestedTargets[index];
65
+ results[index] = parsedByJid.get(target.userJid) ?? {
83
66
  userJid: target.userJid,
84
67
  errorText: 'missing user in key_fetch response'
85
- });
86
- });
68
+ };
69
+ }
70
+ return results;
87
71
  }
88
72
  parseUserDevices(node, userJid) {
89
73
  const { user, server } = (0, jid_1.splitJid)(userJid);
90
74
  const devices = (0, helpers_1.getNodeChildrenByTag)(node, constants_1.WA_NODE_TAGS.DEVICE);
91
- return devices.map((deviceNode, index) => {
92
- const deviceId = parseDeviceId(deviceNode.attrs.id, `missing prekeys user[${userJid}] device[${index}].id`);
93
- const registrationNode = (0, helpers_1.findNodeChild)(deviceNode, constants_1.WA_NODE_TAGS.REGISTRATION);
94
- const identityNode = (0, helpers_1.findNodeChild)(deviceNode, constants_1.WA_NODE_TAGS.IDENTITY);
95
- const signedKeyNode = (0, helpers_1.findNodeChild)(deviceNode, constants_1.WA_NODE_TAGS.SKEY);
75
+ const bundles = new Array(devices.length);
76
+ for (let index = 0; index < devices.length; index += 1) {
77
+ const deviceNode = devices[index];
78
+ const deviceIdValue = deviceNode.attrs.id;
79
+ if (!deviceIdValue) {
80
+ throw new Error(`missing prekeys device[${index}].id is missing`);
81
+ }
82
+ const deviceId = Number.parseInt(deviceIdValue, 10);
83
+ if (!Number.isSafeInteger(deviceId) || deviceId < 0) {
84
+ throw new Error(`missing prekeys device[${index}].id is invalid`);
85
+ }
86
+ const [registrationNode, identityNode, signedKeyNode, oneTimeNode, deviceIdentityNode] = (0, helpers_1.findNodeChildrenByTags)(deviceNode, [
87
+ constants_1.WA_NODE_TAGS.REGISTRATION,
88
+ constants_1.WA_NODE_TAGS.IDENTITY,
89
+ constants_1.WA_NODE_TAGS.SKEY,
90
+ constants_1.WA_NODE_TAGS.KEY,
91
+ constants_1.WA_NODE_TAGS.DEVICE_IDENTITY
92
+ ]);
96
93
  if (!registrationNode || !identityNode || !signedKeyNode) {
97
94
  throw new Error(`missing prekeys device payload is incomplete for ${userJid}`);
98
95
  }
99
- const signedKeyIdNode = (0, helpers_1.findNodeChild)(signedKeyNode, constants_1.WA_NODE_TAGS.ID);
100
- const signedKeyValueNode = (0, helpers_1.findNodeChild)(signedKeyNode, constants_1.WA_NODE_TAGS.VALUE);
101
- const signedKeySignatureNode = (0, helpers_1.findNodeChild)(signedKeyNode, constants_1.WA_NODE_TAGS.SIGNATURE);
96
+ const [signedKeyIdNode, signedKeyValueNode, signedKeySignatureNode] = (0, helpers_1.findNodeChildrenByTags)(signedKeyNode, [
97
+ constants_1.WA_NODE_TAGS.ID,
98
+ constants_1.WA_NODE_TAGS.VALUE,
99
+ constants_1.WA_NODE_TAGS.SIGNATURE
100
+ ]);
102
101
  if (!signedKeyIdNode || !signedKeyValueNode || !signedKeySignatureNode) {
103
102
  throw new Error(`missing prekeys signed pre-key is incomplete for ${userJid}`);
104
103
  }
105
- const oneTimeNode = (0, helpers_1.findNodeChild)(deviceNode, constants_1.WA_NODE_TAGS.KEY);
106
- const oneTimeIdNode = oneTimeNode
107
- ? (0, helpers_1.findNodeChild)(oneTimeNode, constants_1.WA_NODE_TAGS.ID)
108
- : undefined;
109
- const oneTimeValueNode = oneTimeNode
110
- ? (0, helpers_1.findNodeChild)(oneTimeNode, constants_1.WA_NODE_TAGS.VALUE)
111
- : undefined;
104
+ let oneTimeIdNode;
105
+ let oneTimeValueNode;
106
+ if (oneTimeNode) {
107
+ const oneTimeNodes = (0, helpers_1.findNodeChildrenByTags)(oneTimeNode, [
108
+ constants_1.WA_NODE_TAGS.ID,
109
+ constants_1.WA_NODE_TAGS.VALUE
110
+ ]);
111
+ oneTimeIdNode = oneTimeNodes[0];
112
+ oneTimeValueNode = oneTimeNodes[1];
113
+ }
112
114
  if (oneTimeNode && (!oneTimeIdNode || !oneTimeValueNode)) {
113
115
  throw new Error(`missing prekeys one-time key is incomplete for ${userJid}`);
114
116
  }
115
- const deviceIdentityNode = (0, helpers_1.findNodeChild)(deviceNode, constants_1.WA_NODE_TAGS.DEVICE_IDENTITY);
116
- const bundle = {
117
+ const baseBundle = {
117
118
  regId: (0, codec_1.parseUint)((0, codec_1.decodeExactLength)(registrationNode.content, 'missing prekeys device registration', constants_2.SIGNAL_REGISTRATION_ID_LENGTH), 'missing prekeys device registration'),
118
119
  identity: (0, codec_1.decodeExactLength)(identityNode.content, 'missing prekeys device identity', constants_2.SIGNAL_KEY_DATA_LENGTH),
119
120
  signedKey: {
120
121
  id: (0, codec_1.parseUint)((0, codec_1.decodeExactLength)(signedKeyIdNode.content, 'missing prekeys device skey.id', constants_2.SIGNAL_KEY_ID_LENGTH), 'missing prekeys device skey.id'),
121
122
  publicKey: (0, codec_1.decodeExactLength)(signedKeyValueNode.content, 'missing prekeys device skey.value', constants_2.SIGNAL_KEY_DATA_LENGTH),
122
123
  signature: (0, codec_1.decodeExactLength)(signedKeySignatureNode.content, 'missing prekeys device skey.signature', constants_2.SIGNAL_SIGNATURE_LENGTH)
123
- },
124
- ...(oneTimeIdNode && oneTimeValueNode
125
- ? {
126
- oneTimeKey: {
127
- id: (0, codec_1.parseUint)((0, codec_1.decodeExactLength)(oneTimeIdNode.content, 'missing prekeys device key.id', constants_2.SIGNAL_KEY_ID_LENGTH), 'missing prekeys device key.id'),
128
- publicKey: (0, codec_1.decodeExactLength)(oneTimeValueNode.content, 'missing prekeys device key.value', constants_2.SIGNAL_KEY_DATA_LENGTH)
129
- }
130
- }
131
- : {})
124
+ }
132
125
  };
133
- return {
134
- deviceJid: deviceId === 0 ? userJid : `${user}:${deviceId}@${server}`,
135
- bundle,
136
- ...(deviceIdentityNode
137
- ? {
138
- deviceIdentity: (0, helpers_1.decodeNodeContentBase64OrBytes)(deviceIdentityNode.content, 'missing prekeys device device-identity')
126
+ const bundle = oneTimeIdNode && oneTimeValueNode
127
+ ? {
128
+ ...baseBundle,
129
+ oneTimeKey: {
130
+ id: (0, codec_1.parseUint)((0, codec_1.decodeExactLength)(oneTimeIdNode.content, 'missing prekeys device key.id', constants_2.SIGNAL_KEY_ID_LENGTH), 'missing prekeys device key.id'),
131
+ publicKey: (0, codec_1.decodeExactLength)(oneTimeValueNode.content, 'missing prekeys device key.value', constants_2.SIGNAL_KEY_DATA_LENGTH)
139
132
  }
140
- : {})
141
- };
142
- });
133
+ }
134
+ : baseBundle;
135
+ let deviceIdentity;
136
+ if (deviceIdentityNode) {
137
+ deviceIdentity = (0, helpers_1.decodeNodeContentBase64OrBytes)(deviceIdentityNode.content, 'missing prekeys device device-identity');
138
+ }
139
+ bundles[index] = deviceIdentity
140
+ ? {
141
+ deviceJid: deviceId === 0 ? userJid : `${user}:${deviceId}@${server}`,
142
+ bundle,
143
+ deviceIdentity
144
+ }
145
+ : {
146
+ deviceJid: deviceId === 0 ? userJid : `${user}:${deviceId}@${server}`,
147
+ bundle
148
+ };
149
+ }
150
+ return bundles;
143
151
  }
144
152
  }
145
153
  exports.SignalMissingPreKeysSyncApi = SignalMissingPreKeysSyncApi;
@@ -5,6 +5,7 @@ const constants_1 = require("../../protocol/constants");
5
5
  const codec_1 = require("../api/codec");
6
6
  const constants_2 = require("../api/constants");
7
7
  const helpers_1 = require("../../transport/node/helpers");
8
+ const query_1 = require("../../transport/node/query");
8
9
  class SignalSessionSyncApi {
9
10
  constructor(options) {
10
11
  this.logger = options.logger;
@@ -43,7 +44,20 @@ class SignalSessionSyncApi {
43
44
  reasonIdentity: (previous?.reasonIdentity ?? false) || target.reasonIdentity === true
44
45
  });
45
46
  }
46
- const mergedTargets = [...targetByJid.values()];
47
+ const mergedTargets = [];
48
+ for (const target of targetByJid.values()) {
49
+ mergedTargets.push(target);
50
+ }
51
+ const userNodes = new Array(mergedTargets.length);
52
+ for (let index = 0; index < mergedTargets.length; index += 1) {
53
+ const target = mergedTargets[index];
54
+ userNodes[index] = {
55
+ tag: constants_1.WA_NODE_TAGS.USER,
56
+ attrs: target.reasonIdentity === true
57
+ ? { jid: target.jid, reason: 'identity' }
58
+ : { jid: target.jid }
59
+ };
60
+ }
47
61
  this.logger.debug('signal fetch key bundles request', {
48
62
  targets: mergedTargets.length,
49
63
  timeoutMs
@@ -59,34 +73,14 @@ class SignalSessionSyncApi {
59
73
  {
60
74
  tag: constants_1.WA_NODE_TAGS.KEY,
61
75
  attrs: {},
62
- content: mergedTargets.map((target) => ({
63
- tag: constants_1.WA_NODE_TAGS.USER,
64
- attrs: {
65
- jid: target.jid,
66
- ...(target.reasonIdentity === true ? { reason: 'identity' } : {})
67
- }
68
- }))
76
+ content: userNodes
69
77
  }
70
78
  ]
71
79
  }, timeoutMs);
72
80
  return this.parseFetchKeyBundleResponse(responseNode, mergedTargets);
73
81
  }
74
82
  parseFetchKeyBundleResponse(node, requestedTargets) {
75
- if (node.tag !== constants_1.WA_NODE_TAGS.IQ) {
76
- throw new Error(`invalid key bundle response tag: ${node.tag}`);
77
- }
78
- if (node.attrs.type === constants_1.WA_IQ_TYPES.ERROR) {
79
- const errorNode = (0, helpers_1.findNodeChild)(node, constants_1.WA_NODE_TAGS.ERROR);
80
- if (!errorNode) {
81
- throw new Error(`key bundle iq error for ${node.attrs.id ?? 'unknown id'}`);
82
- }
83
- const code = errorNode.attrs.code ?? 'unknown';
84
- const text = errorNode.attrs.text ?? errorNode.attrs.type ?? 'unknown';
85
- throw new Error(`key bundle iq error (${code} ${text})`);
86
- }
87
- if (node.attrs.type !== constants_1.WA_IQ_TYPES.RESULT) {
88
- throw new Error(`invalid key bundle response type: ${node.attrs.type ?? 'unknown'}`);
89
- }
83
+ (0, query_1.assertIqResult)(node, 'key bundle');
90
84
  const listNode = (0, helpers_1.findNodeChild)(node, constants_1.WA_NODE_TAGS.LIST);
91
85
  if (!listNode) {
92
86
  throw new Error('key bundle response missing list node');
@@ -118,16 +112,15 @@ class SignalSessionSyncApi {
118
112
  ...(parsed.deviceIdentity ? { deviceIdentity: parsed.deviceIdentity } : {})
119
113
  });
120
114
  }
121
- return requestedTargets.map((target) => {
122
- const parsed = parsedByJid.get(target.jid);
123
- if (parsed) {
124
- return parsed;
125
- }
126
- return {
115
+ const output = new Array(requestedTargets.length);
116
+ for (let index = 0; index < requestedTargets.length; index += 1) {
117
+ const target = requestedTargets[index];
118
+ output[index] = parsedByJid.get(target.jid) ?? {
127
119
  jid: target.jid,
128
120
  errorText: 'missing key bundle user in response'
129
121
  };
130
- });
122
+ }
123
+ return output;
131
124
  }
132
125
  parseUserKeyBundle(node) {
133
126
  const registrationNode = (0, helpers_1.findNodeChild)(node, constants_1.WA_NODE_TAGS.REGISTRATION);
@@ -19,7 +19,7 @@ Object.defineProperty(exports, "ADV_PREFIX_DEVICE_SIGNATURE", { enumerable: true
19
19
  Object.defineProperty(exports, "ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE", { enumerable: true, get: function () { return constants_2.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE; } });
20
20
  Object.defineProperty(exports, "ADV_PREFIX_HOSTED_DEVICE_SIGNATURE", { enumerable: true, get: function () { return constants_2.ADV_PREFIX_HOSTED_DEVICE_SIGNATURE; } });
21
21
  async function verifySignalSignature(publicKey, message, signature) {
22
- if (signature.length !== 64) {
22
+ if (!(0, bytes_1.assertByteLength)(signature, 64, 'invalid signal signature length', false)) {
23
23
  return false;
24
24
  }
25
25
  if ((signature[63] & 0x60) !== 0) {
@@ -33,9 +33,7 @@ async function verifySignalSignature(publicKey, message, signature) {
33
33
  return (0, _crypto_1.ed25519VerifyRaw)(edPublic, signalSignature, message);
34
34
  }
35
35
  async function signSignalMessage(privateKey, message) {
36
- if (privateKey.length !== 32) {
37
- throw new Error(`invalid curve25519 private key length ${privateKey.length}`);
38
- }
36
+ (0, bytes_1.assertByteLength)(privateKey, 32, `invalid curve25519 private key length ${privateKey.length}`);
39
37
  const clampedPrivateKey = (0, X25519_1.clampCurvePrivateKeyInPlace)(privateKey);
40
38
  const privateScalar = (0, le_1.bytesToBigIntLE)(clampedPrivateKey);
41
39
  const encodedPublic = (0, edwards_1.encodeExtendedPoint)((0, edwards_1.scalarMultBase)(privateScalar));
@@ -30,24 +30,33 @@ async function selectMessageKey(senderKey, targetIteration) {
30
30
  const firstDerived = await deriveSenderKeyMsgKeyFromState(senderKey.iteration, chainState);
31
31
  chainState = firstDerived.nextState;
32
32
  let messageKey = firstDerived.messageKey;
33
- let nextUnused = currentUnused.slice();
34
- if (delta > 0) {
35
- let overflow = delta + currentUnused.length - constants_1.MAX_UNUSED_KEYS;
33
+ if (delta === 0) {
34
+ return {
35
+ messageKey,
36
+ updatedRecord: {
37
+ ...senderKey,
38
+ iteration: targetIteration + 1,
39
+ chainKey: chainState.chainKey,
40
+ unusedMessageKeys: currentUnused
41
+ }
42
+ };
43
+ }
44
+ const nextUnused = currentUnused.slice();
45
+ let overflow = delta + currentUnused.length - constants_1.MAX_UNUSED_KEYS;
46
+ if (overflow > 0) {
47
+ nextUnused.splice(0, overflow);
48
+ overflow -= currentUnused.length;
49
+ }
50
+ for (let iteration = senderKey.iteration + 1; iteration <= targetIteration; iteration += 1) {
36
51
  if (overflow > 0) {
37
- nextUnused = nextUnused.slice(overflow);
38
- overflow -= currentUnused.length;
52
+ overflow -= 1;
39
53
  }
40
- for (let iteration = senderKey.iteration + 1; iteration <= targetIteration; iteration += 1) {
41
- if (overflow > 0) {
42
- overflow -= 1;
43
- }
44
- else {
45
- nextUnused.push(messageKey);
46
- }
47
- const derived = await deriveSenderKeyMsgKeyFromState(iteration, chainState);
48
- chainState = derived.nextState;
49
- messageKey = derived.messageKey;
54
+ else {
55
+ nextUnused.push(messageKey);
50
56
  }
57
+ const derived = await deriveSenderKeyMsgKeyFromState(iteration, chainState);
58
+ chainState = derived.nextState;
59
+ messageKey = derived.messageKey;
51
60
  }
52
61
  return {
53
62
  messageKey,
@@ -68,20 +77,16 @@ async function deriveSenderKeyMsgKey(iteration, chainKey) {
68
77
  };
69
78
  }
70
79
  async function createSenderChainState(chainKey) {
71
- if (chainKey.length !== 32) {
72
- throw new Error('sender key chainKey must be 32 bytes');
73
- }
80
+ (0, bytes_1.assertByteLength)(chainKey, 32, 'sender key chainKey must be 32 bytes');
74
81
  return {
75
82
  chainKey,
76
83
  hmacKey: await (0, _crypto_1.importHmacKey)(chainKey)
77
84
  };
78
85
  }
79
86
  async function deriveSenderKeyMsgKeyFromState(iteration, state) {
80
- const nextChainRawPromise = (0, _crypto_1.hmacSign)(state.hmacKey, constants_1.CHAIN_KEY_LABEL);
81
- const messageInputKeyPromise = (0, _crypto_1.hmacSign)(state.hmacKey, constants_1.MESSAGE_KEY_LABEL);
82
87
  const [nextChainRaw, messageInputKey] = await Promise.all([
83
- nextChainRawPromise,
84
- messageInputKeyPromise
88
+ (0, _crypto_1.hmacSign)(state.hmacKey, constants_1.CHAIN_KEY_LABEL),
89
+ (0, _crypto_1.hmacSign)(state.hmacKey, constants_1.MESSAGE_KEY_LABEL)
85
90
  ]);
86
91
  const nextChainKey = nextChainRaw.subarray(0, 32);
87
92
  const [nextHmacKey, messageSeed] = await Promise.all([
@@ -20,9 +20,7 @@ function parseDistributionPayload(payload) {
20
20
  throw new Error('invalid sender key distribution message');
21
21
  }
22
22
  const chainKey = (0, bytes_1.toBytesView)(decoded.chainKey);
23
- if (chainKey.length !== 32) {
24
- throw new Error('sender key distribution chainKey must be 32 bytes');
25
- }
23
+ (0, bytes_1.assertByteLength)(chainKey, 32, 'sender key distribution chainKey must be 32 bytes');
26
24
  return {
27
25
  keyId: decoded.id,
28
26
  iteration: decoded.iteration,
@@ -66,12 +66,16 @@ class SenderKeyManager {
66
66
  }
67
67
  const senderKey = await this.ensureSenderKey(groupId, sender);
68
68
  const timestampMs = Date.now();
69
- await this.store.upsertSenderKeyDistributions(participants.map((participant) => ({
70
- groupId,
71
- sender: participant,
72
- keyId: senderKey.keyId,
73
- timestampMs
74
- })));
69
+ const distributions = new Array(participants.length);
70
+ for (let index = 0; index < participants.length; index += 1) {
71
+ distributions[index] = {
72
+ groupId,
73
+ sender: participants[index],
74
+ keyId: senderKey.keyId,
75
+ timestampMs
76
+ };
77
+ }
78
+ await this.store.upsertSenderKeyDistributions(distributions);
75
79
  }
76
80
  async processSenderKeyDistributionPayload(groupId, sender, payload) {
77
81
  if (groupId.length === 0) {
@@ -87,13 +91,15 @@ class SenderKeyManager {
87
91
  signingPublicKey: parsed.signingPublicKey,
88
92
  unusedMessageKeys: []
89
93
  };
90
- await this.store.upsertSenderKey(record);
91
- await this.store.upsertSenderKeyDistribution({
92
- groupId,
93
- sender,
94
- keyId: parsed.keyId,
95
- timestampMs: Date.now()
96
- });
94
+ await Promise.all([
95
+ this.store.upsertSenderKey(record),
96
+ this.store.upsertSenderKeyDistribution({
97
+ groupId,
98
+ sender,
99
+ keyId: parsed.keyId,
100
+ timestampMs: Date.now()
101
+ })
102
+ ]);
97
103
  return record;
98
104
  }
99
105
  async encryptGroupMessage(groupId, sender, plaintext) {
@@ -162,13 +168,17 @@ class SenderKeyManager {
162
168
  if (existing) {
163
169
  return existing;
164
170
  }
165
- const signingKeyPair = await _crypto_1.X25519.generateKeyPair();
171
+ const [signingKeyPair, keyId, chainKey] = await Promise.all([
172
+ _crypto_1.X25519.generateKeyPair(),
173
+ (0, _crypto_1.randomIntAsync)(1, 2147483647),
174
+ (0, _crypto_1.randomBytesAsync)(32)
175
+ ]);
166
176
  const created = {
167
177
  groupId,
168
178
  sender,
169
- keyId: await (0, _crypto_1.randomIntAsync)(1, 2147483647),
179
+ keyId,
170
180
  iteration: 0,
171
- chainKey: await (0, _crypto_1.randomBytesAsync)(32),
181
+ chainKey,
172
182
  signingPublicKey: (0, _crypto_1.toSerializedPubKey)(signingKeyPair.pubKey),
173
183
  signingPrivateKey: signingKeyPair.privKey,
174
184
  unusedMessageKeys: []
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SignalProtocol = exports.createAndStoreInitialKeys = exports.SenderKeyManager = exports.SignalSessionSyncApi = exports.SignalRotateKeyApi = exports.SignalMissingPreKeysSyncApi = exports.SignalIdentitySyncApi = exports.SignalDeviceSyncApi = exports.SignalDigestSyncApi = exports.parsePreKeyUploadFailure = exports.buildPreKeyUploadIq = exports.generateSignedPreKey = exports.generateRegistrationInfo = exports.generateRegistrationId = exports.generatePreKeyPair = void 0;
3
+ exports.createSignalSessionResolver = exports.SignalProtocol = exports.createAndStoreInitialKeys = exports.SenderKeyManager = exports.SignalSessionSyncApi = exports.SignalRotateKeyApi = exports.SignalMissingPreKeysSyncApi = exports.SignalIdentitySyncApi = exports.SignalDeviceSyncApi = exports.SignalDigestSyncApi = exports.parsePreKeyUploadFailure = exports.buildPreKeyUploadIq = exports.generateSignedPreKey = exports.generateRegistrationInfo = exports.generateRegistrationId = exports.generatePreKeyPair = void 0;
4
4
  var keygen_1 = require("./registration/keygen");
5
5
  Object.defineProperty(exports, "generatePreKeyPair", { enumerable: true, get: function () { return keygen_1.generatePreKeyPair; } });
6
6
  Object.defineProperty(exports, "generateRegistrationId", { enumerable: true, get: function () { return keygen_1.generateRegistrationId; } });
@@ -27,3 +27,5 @@ var utils_1 = require("./registration/utils");
27
27
  Object.defineProperty(exports, "createAndStoreInitialKeys", { enumerable: true, get: function () { return utils_1.createAndStoreInitialKeys; } });
28
28
  var SignalProtocol_1 = require("./session/SignalProtocol");
29
29
  Object.defineProperty(exports, "SignalProtocol", { enumerable: true, get: function () { return SignalProtocol_1.SignalProtocol; } });
30
+ var resolver_1 = require("./session/resolver");
31
+ Object.defineProperty(exports, "createSignalSessionResolver", { enumerable: true, get: function () { return resolver_1.createSignalSessionResolver; } });
@@ -8,6 +8,9 @@ const SignalRatchet_1 = require("../session/SignalRatchet");
8
8
  const SignalSerializer_1 = require("../session/SignalSerializer");
9
9
  const SignalSession_1 = require("../session/SignalSession");
10
10
  const bytes_1 = require("../../util/bytes");
11
+ function signalAddressMapKey(address) {
12
+ return `${address.user}\u0001${address.server ?? ''}\u0001${address.device}`;
13
+ }
11
14
  class SignalProtocol {
12
15
  constructor(store, logger = new ConsoleLogger_1.ConsoleLogger('info')) {
13
16
  this.store = store;
@@ -30,23 +33,55 @@ class SignalProtocol {
30
33
  return session;
31
34
  }
32
35
  async encryptMessage(address, plaintext, expectedIdentity) {
33
- const session = await this.store.getSession(address);
34
- if (!session) {
35
- throw new Error('signal session not found');
36
+ const [encrypted] = await this.encryptMessagesBatch([
37
+ { address, plaintext, expectedIdentity }
38
+ ]);
39
+ return encrypted;
40
+ }
41
+ async encryptMessagesBatch(requests) {
42
+ if (requests.length === 0) {
43
+ return [];
36
44
  }
37
- if (expectedIdentity &&
38
- !(0, bytes_1.uint8Equal)((0, _crypto_1.toSerializedPubKey)(expectedIdentity), session.remote.pubKey)) {
39
- throw new Error('identity mismatch');
45
+ const addresses = requests.map((request) => request.address);
46
+ const storedSessions = await this.store.getSessionsBatch(addresses);
47
+ const latestSessionByAddress = new Map();
48
+ const sessionUpdatesByAddress = new Map();
49
+ const identityUpdatesByAddress = new Map();
50
+ const results = new Array(requests.length);
51
+ for (let index = 0; index < requests.length; index += 1) {
52
+ const request = requests[index];
53
+ const address = request.address;
54
+ const addressKey = signalAddressMapKey(address);
55
+ const session = latestSessionByAddress.get(addressKey) ?? storedSessions[index];
56
+ if (!session) {
57
+ throw new Error('signal session not found');
58
+ }
59
+ if (request.expectedIdentity &&
60
+ !(0, bytes_1.uint8Equal)((0, _crypto_1.toSerializedPubKey)(request.expectedIdentity), session.remote.pubKey)) {
61
+ throw new Error('identity mismatch');
62
+ }
63
+ const [updatedSession, encrypted] = await (0, SignalRatchet_1.encryptMsg)(session, request.plaintext);
64
+ latestSessionByAddress.set(addressKey, updatedSession);
65
+ sessionUpdatesByAddress.set(addressKey, {
66
+ address,
67
+ session: updatedSession
68
+ });
69
+ if (!(0, bytes_1.uint8Equal)(updatedSession.remote.pubKey, session.remote.pubKey)) {
70
+ identityUpdatesByAddress.set(addressKey, {
71
+ address,
72
+ identityKey: updatedSession.remote.pubKey
73
+ });
74
+ }
75
+ results[index] = {
76
+ ...encrypted,
77
+ baseKey: updatedSession.aliceBaseKey
78
+ };
40
79
  }
41
- const [updatedSession, encrypted] = await (0, SignalRatchet_1.encryptMsg)(session, plaintext);
42
- await this.store.setSession(address, updatedSession);
43
- if (!(0, bytes_1.uint8Equal)(updatedSession.remote.pubKey, session.remote.pubKey)) {
44
- await this.store.setRemoteIdentity(address, updatedSession.remote.pubKey);
80
+ await this.store.setSessionsBatch([...sessionUpdatesByAddress.values()]);
81
+ if (identityUpdatesByAddress.size > 0) {
82
+ await this.store.setRemoteIdentities([...identityUpdatesByAddress.values()]);
45
83
  }
46
- return {
47
- ...encrypted,
48
- baseKey: updatedSession.aliceBaseKey
49
- };
84
+ return results;
50
85
  }
51
86
  async decryptMessage(address, envelope) {
52
87
  const currentSession = await this.store.getSession(address);
@@ -59,24 +59,33 @@ async function selectMessageKey(chain, targetCounter) {
59
59
  const first = await deriveMsgKeyFromState(chain.nextMsgIndex, chainState);
60
60
  let currentMessageKey = first.messageKey;
61
61
  chainState = first.nextState;
62
- let nextUnused = unused.slice();
63
- if (delta > 0) {
64
- let overflow = delta + unused.length - constants_1.MAX_UNUSED_KEYS;
62
+ if (delta === 0) {
63
+ return {
64
+ messageKey: currentMessageKey,
65
+ updatedChain: {
66
+ ratchetPubKey: chain.ratchetPubKey,
67
+ nextMsgIndex: targetCounter + 1,
68
+ chainKey: chainState.chainKey,
69
+ unusedMsgKeys: unused
70
+ }
71
+ };
72
+ }
73
+ const nextUnused = unused.slice();
74
+ let overflow = delta + unused.length - constants_1.MAX_UNUSED_KEYS;
75
+ if (overflow > 0) {
76
+ nextUnused.splice(0, overflow);
77
+ overflow -= unused.length;
78
+ }
79
+ for (let counter = chain.nextMsgIndex + 1; counter <= targetCounter; counter += 1) {
65
80
  if (overflow > 0) {
66
- nextUnused = nextUnused.slice(overflow);
67
- overflow -= unused.length;
81
+ overflow -= 1;
68
82
  }
69
- for (let counter = chain.nextMsgIndex + 1; counter <= targetCounter; counter += 1) {
70
- if (overflow > 0) {
71
- overflow -= 1;
72
- }
73
- else {
74
- nextUnused.push(currentMessageKey);
75
- }
76
- const derived = await deriveMsgKeyFromState(counter, chainState);
77
- currentMessageKey = derived.messageKey;
78
- chainState = derived.nextState;
83
+ else {
84
+ nextUnused.push(currentMessageKey);
79
85
  }
86
+ const derived = await deriveMsgKeyFromState(counter, chainState);
87
+ currentMessageKey = derived.messageKey;
88
+ chainState = derived.nextState;
80
89
  }
81
90
  return {
82
91
  messageKey: currentMessageKey,
@@ -32,16 +32,21 @@ function findMatchingSession(session, sessionBaseKey) {
32
32
  if (session.aliceBaseKey && (0, bytes_1.uint8Equal)(session.aliceBaseKey, serializedBaseKey)) {
33
33
  return session;
34
34
  }
35
- const previousSessionIndex = session.prevSessions.findIndex((prev) => !!prev.aliceBaseKey && (0, bytes_1.uint8Equal)(prev.aliceBaseKey, serializedBaseKey));
36
- if (previousSessionIndex !== -1) {
37
- const promoted = snapshotToRecord(session.prevSessions[previousSessionIndex]);
35
+ for (let index = 0; index < session.prevSessions.length; index += 1) {
36
+ const previousSession = session.prevSessions[index];
37
+ if (!previousSession.aliceBaseKey ||
38
+ !(0, bytes_1.uint8Equal)(previousSession.aliceBaseKey, serializedBaseKey)) {
39
+ continue;
40
+ }
41
+ const prevSessions = [detachSession(session)];
42
+ for (let i = 0; i < session.prevSessions.length; i += 1) {
43
+ if (i !== index) {
44
+ prevSessions.push(session.prevSessions[i]);
45
+ }
46
+ }
38
47
  return {
39
- ...promoted,
40
- prevSessions: [
41
- detachSession(session),
42
- ...session.prevSessions.slice(0, previousSessionIndex),
43
- ...session.prevSessions.slice(previousSessionIndex + 1)
44
- ]
48
+ ...previousSession,
49
+ prevSessions
45
50
  };
46
51
  }
47
52
  return null;