@unwanted/matrix-sdk-mini 34.12.0-1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (1203) hide show
  1. package/CHANGELOG.md +5910 -0
  2. package/LICENSE +177 -0
  3. package/README.md +459 -0
  4. package/git-revision.txt +1 -0
  5. package/lib/@types/AESEncryptedSecretStoragePayload.d.ts +14 -0
  6. package/lib/@types/AESEncryptedSecretStoragePayload.d.ts.map +1 -0
  7. package/lib/@types/AESEncryptedSecretStoragePayload.js +1 -0
  8. package/lib/@types/AESEncryptedSecretStoragePayload.js.map +1 -0
  9. package/lib/@types/IIdentityServerProvider.d.ts +9 -0
  10. package/lib/@types/IIdentityServerProvider.d.ts.map +1 -0
  11. package/lib/@types/IIdentityServerProvider.js +1 -0
  12. package/lib/@types/IIdentityServerProvider.js.map +1 -0
  13. package/lib/@types/PushRules.d.ts +140 -0
  14. package/lib/@types/PushRules.d.ts.map +1 -0
  15. package/lib/@types/PushRules.js +94 -0
  16. package/lib/@types/PushRules.js.map +1 -0
  17. package/lib/@types/another-json.d.js +0 -0
  18. package/lib/@types/another-json.d.js.map +1 -0
  19. package/lib/@types/auth.d.ts +208 -0
  20. package/lib/@types/auth.d.ts.map +1 -0
  21. package/lib/@types/auth.js +99 -0
  22. package/lib/@types/auth.js.map +1 -0
  23. package/lib/@types/beacon.d.ts +106 -0
  24. package/lib/@types/beacon.d.ts.map +1 -0
  25. package/lib/@types/beacon.js +119 -0
  26. package/lib/@types/beacon.js.map +1 -0
  27. package/lib/@types/common.d.ts +9 -0
  28. package/lib/@types/common.d.ts.map +1 -0
  29. package/lib/@types/common.js +1 -0
  30. package/lib/@types/common.js.map +1 -0
  31. package/lib/@types/crypto.d.ts +47 -0
  32. package/lib/@types/crypto.d.ts.map +1 -0
  33. package/lib/@types/crypto.js +1 -0
  34. package/lib/@types/crypto.js.map +1 -0
  35. package/lib/@types/event.d.ts +258 -0
  36. package/lib/@types/event.d.ts.map +1 -0
  37. package/lib/@types/event.js +239 -0
  38. package/lib/@types/event.js.map +1 -0
  39. package/lib/@types/events.d.ts +92 -0
  40. package/lib/@types/events.d.ts.map +1 -0
  41. package/lib/@types/events.js +1 -0
  42. package/lib/@types/events.js.map +1 -0
  43. package/lib/@types/extensible_events.d.ts +98 -0
  44. package/lib/@types/extensible_events.d.ts.map +1 -0
  45. package/lib/@types/extensible_events.js +116 -0
  46. package/lib/@types/extensible_events.js.map +1 -0
  47. package/lib/@types/global.d.js +20 -0
  48. package/lib/@types/global.d.js.map +1 -0
  49. package/lib/@types/local_notifications.d.ts +4 -0
  50. package/lib/@types/local_notifications.d.ts.map +1 -0
  51. package/lib/@types/local_notifications.js +1 -0
  52. package/lib/@types/local_notifications.js.map +1 -0
  53. package/lib/@types/location.d.ts +60 -0
  54. package/lib/@types/location.d.ts.map +1 -0
  55. package/lib/@types/location.js +67 -0
  56. package/lib/@types/location.js.map +1 -0
  57. package/lib/@types/matrix-sdk-crypto-wasm.d.js +1 -0
  58. package/lib/@types/matrix-sdk-crypto-wasm.d.js.map +1 -0
  59. package/lib/@types/media.d.ts +220 -0
  60. package/lib/@types/media.d.ts.map +1 -0
  61. package/lib/@types/media.js +1 -0
  62. package/lib/@types/media.js.map +1 -0
  63. package/lib/@types/membership.d.ts +41 -0
  64. package/lib/@types/membership.d.ts.map +1 -0
  65. package/lib/@types/membership.js +37 -0
  66. package/lib/@types/membership.js.map +1 -0
  67. package/lib/@types/oidc-client-ts.d.js +18 -0
  68. package/lib/@types/oidc-client-ts.d.js.map +1 -0
  69. package/lib/@types/partials.d.ts +39 -0
  70. package/lib/@types/partials.d.ts.map +1 -0
  71. package/lib/@types/partials.js +53 -0
  72. package/lib/@types/partials.js.map +1 -0
  73. package/lib/@types/polls.d.ts +88 -0
  74. package/lib/@types/polls.d.ts.map +1 -0
  75. package/lib/@types/polls.js +86 -0
  76. package/lib/@types/polls.js.map +1 -0
  77. package/lib/@types/read_receipts.d.ts +36 -0
  78. package/lib/@types/read_receipts.d.ts.map +1 -0
  79. package/lib/@types/read_receipts.js +27 -0
  80. package/lib/@types/read_receipts.js.map +1 -0
  81. package/lib/@types/registration.d.ts +85 -0
  82. package/lib/@types/registration.d.ts.map +1 -0
  83. package/lib/@types/registration.js +1 -0
  84. package/lib/@types/registration.js.map +1 -0
  85. package/lib/@types/requests.d.ts +241 -0
  86. package/lib/@types/requests.d.ts.map +1 -0
  87. package/lib/@types/requests.js +28 -0
  88. package/lib/@types/requests.js.map +1 -0
  89. package/lib/@types/search.d.ts +90 -0
  90. package/lib/@types/search.d.ts.map +1 -0
  91. package/lib/@types/search.js +30 -0
  92. package/lib/@types/search.js.map +1 -0
  93. package/lib/@types/signed.d.ts +9 -0
  94. package/lib/@types/signed.d.ts.map +1 -0
  95. package/lib/@types/signed.js +1 -0
  96. package/lib/@types/signed.js.map +1 -0
  97. package/lib/@types/spaces.d.ts +16 -0
  98. package/lib/@types/spaces.d.ts.map +1 -0
  99. package/lib/@types/spaces.js +1 -0
  100. package/lib/@types/spaces.js.map +1 -0
  101. package/lib/@types/state_events.d.ts +116 -0
  102. package/lib/@types/state_events.d.ts.map +1 -0
  103. package/lib/@types/state_events.js +1 -0
  104. package/lib/@types/state_events.js.map +1 -0
  105. package/lib/@types/synapse.d.ts +19 -0
  106. package/lib/@types/synapse.d.ts.map +1 -0
  107. package/lib/@types/synapse.js +1 -0
  108. package/lib/@types/synapse.js.map +1 -0
  109. package/lib/@types/sync.d.ts +8 -0
  110. package/lib/@types/sync.d.ts.map +1 -0
  111. package/lib/@types/sync.js +25 -0
  112. package/lib/@types/sync.js.map +1 -0
  113. package/lib/@types/threepids.d.ts +12 -0
  114. package/lib/@types/threepids.d.ts.map +1 -0
  115. package/lib/@types/threepids.js +24 -0
  116. package/lib/@types/threepids.js.map +1 -0
  117. package/lib/@types/topic.d.ts +48 -0
  118. package/lib/@types/topic.d.ts.map +1 -0
  119. package/lib/@types/topic.js +57 -0
  120. package/lib/@types/topic.js.map +1 -0
  121. package/lib/@types/uia.d.ts +12 -0
  122. package/lib/@types/uia.d.ts.map +1 -0
  123. package/lib/@types/uia.js +1 -0
  124. package/lib/@types/uia.js.map +1 -0
  125. package/lib/NamespacedValue.d.ts +33 -0
  126. package/lib/NamespacedValue.d.ts.map +1 -0
  127. package/lib/NamespacedValue.js +113 -0
  128. package/lib/NamespacedValue.js.map +1 -0
  129. package/lib/ReEmitter.d.ts +15 -0
  130. package/lib/ReEmitter.d.ts.map +1 -0
  131. package/lib/ReEmitter.js +87 -0
  132. package/lib/ReEmitter.js.map +1 -0
  133. package/lib/ToDeviceMessageQueue.d.ts +28 -0
  134. package/lib/ToDeviceMessageQueue.d.ts.map +1 -0
  135. package/lib/ToDeviceMessageQueue.js +135 -0
  136. package/lib/ToDeviceMessageQueue.js.map +1 -0
  137. package/lib/autodiscovery.d.ts +136 -0
  138. package/lib/autodiscovery.d.ts.map +1 -0
  139. package/lib/autodiscovery.js +464 -0
  140. package/lib/autodiscovery.js.map +1 -0
  141. package/lib/base64.d.ts +28 -0
  142. package/lib/base64.d.ts.map +1 -0
  143. package/lib/base64.js +88 -0
  144. package/lib/base64.js.map +1 -0
  145. package/lib/browser-index.d.ts +8 -0
  146. package/lib/browser-index.d.ts.map +1 -0
  147. package/lib/browser-index.js +35 -0
  148. package/lib/browser-index.js.map +1 -0
  149. package/lib/client.d.ts +4232 -0
  150. package/lib/client.d.ts.map +1 -0
  151. package/lib/client.js +8622 -0
  152. package/lib/client.js.map +1 -0
  153. package/lib/common-crypto/CryptoBackend.d.ts +240 -0
  154. package/lib/common-crypto/CryptoBackend.d.ts.map +1 -0
  155. package/lib/common-crypto/CryptoBackend.js +73 -0
  156. package/lib/common-crypto/CryptoBackend.js.map +1 -0
  157. package/lib/common-crypto/key-passphrase.d.ts +14 -0
  158. package/lib/common-crypto/key-passphrase.d.ts.map +1 -0
  159. package/lib/common-crypto/key-passphrase.js +33 -0
  160. package/lib/common-crypto/key-passphrase.js.map +1 -0
  161. package/lib/content-helpers.d.ts +90 -0
  162. package/lib/content-helpers.d.ts.map +1 -0
  163. package/lib/content-helpers.js +250 -0
  164. package/lib/content-helpers.js.map +1 -0
  165. package/lib/content-repo.d.ts +24 -0
  166. package/lib/content-repo.d.ts.map +1 -0
  167. package/lib/content-repo.js +104 -0
  168. package/lib/content-repo.js.map +1 -0
  169. package/lib/crypto/CrossSigning.d.ts +184 -0
  170. package/lib/crypto/CrossSigning.d.ts.map +1 -0
  171. package/lib/crypto/CrossSigning.js +718 -0
  172. package/lib/crypto/CrossSigning.js.map +1 -0
  173. package/lib/crypto/DeviceList.d.ts +216 -0
  174. package/lib/crypto/DeviceList.d.ts.map +1 -0
  175. package/lib/crypto/DeviceList.js +892 -0
  176. package/lib/crypto/DeviceList.js.map +1 -0
  177. package/lib/crypto/EncryptionSetup.d.ts +152 -0
  178. package/lib/crypto/EncryptionSetup.d.ts.map +1 -0
  179. package/lib/crypto/EncryptionSetup.js +356 -0
  180. package/lib/crypto/EncryptionSetup.js.map +1 -0
  181. package/lib/crypto/OlmDevice.d.ts +457 -0
  182. package/lib/crypto/OlmDevice.d.ts.map +1 -0
  183. package/lib/crypto/OlmDevice.js +1241 -0
  184. package/lib/crypto/OlmDevice.js.map +1 -0
  185. package/lib/crypto/OutgoingRoomKeyRequestManager.d.ts +109 -0
  186. package/lib/crypto/OutgoingRoomKeyRequestManager.d.ts.map +1 -0
  187. package/lib/crypto/OutgoingRoomKeyRequestManager.js +415 -0
  188. package/lib/crypto/OutgoingRoomKeyRequestManager.js.map +1 -0
  189. package/lib/crypto/RoomList.d.ts +26 -0
  190. package/lib/crypto/RoomList.d.ts.map +1 -0
  191. package/lib/crypto/RoomList.js +71 -0
  192. package/lib/crypto/RoomList.js.map +1 -0
  193. package/lib/crypto/SecretSharing.d.ts +24 -0
  194. package/lib/crypto/SecretSharing.d.ts.map +1 -0
  195. package/lib/crypto/SecretSharing.js +194 -0
  196. package/lib/crypto/SecretSharing.js.map +1 -0
  197. package/lib/crypto/SecretStorage.d.ts +55 -0
  198. package/lib/crypto/SecretStorage.d.ts.map +1 -0
  199. package/lib/crypto/SecretStorage.js +118 -0
  200. package/lib/crypto/SecretStorage.js.map +1 -0
  201. package/lib/crypto/aes.d.ts +6 -0
  202. package/lib/crypto/aes.d.ts.map +1 -0
  203. package/lib/crypto/aes.js +24 -0
  204. package/lib/crypto/aes.js.map +1 -0
  205. package/lib/crypto/algorithms/base.d.ts +156 -0
  206. package/lib/crypto/algorithms/base.d.ts.map +1 -0
  207. package/lib/crypto/algorithms/base.js +187 -0
  208. package/lib/crypto/algorithms/base.js.map +1 -0
  209. package/lib/crypto/algorithms/index.d.ts +4 -0
  210. package/lib/crypto/algorithms/index.d.ts.map +1 -0
  211. package/lib/crypto/algorithms/index.js +20 -0
  212. package/lib/crypto/algorithms/index.js.map +1 -0
  213. package/lib/crypto/algorithms/megolm.d.ts +385 -0
  214. package/lib/crypto/algorithms/megolm.d.ts.map +1 -0
  215. package/lib/crypto/algorithms/megolm.js +1822 -0
  216. package/lib/crypto/algorithms/megolm.js.map +1 -0
  217. package/lib/crypto/algorithms/olm.d.ts +5 -0
  218. package/lib/crypto/algorithms/olm.d.ts.map +1 -0
  219. package/lib/crypto/algorithms/olm.js +299 -0
  220. package/lib/crypto/algorithms/olm.js.map +1 -0
  221. package/lib/crypto/api.d.ts +32 -0
  222. package/lib/crypto/api.d.ts.map +1 -0
  223. package/lib/crypto/api.js +22 -0
  224. package/lib/crypto/api.js.map +1 -0
  225. package/lib/crypto/backup.d.ts +227 -0
  226. package/lib/crypto/backup.d.ts.map +1 -0
  227. package/lib/crypto/backup.js +824 -0
  228. package/lib/crypto/backup.js.map +1 -0
  229. package/lib/crypto/crypto.d.ts +3 -0
  230. package/lib/crypto/crypto.d.ts.map +1 -0
  231. package/lib/crypto/crypto.js +19 -0
  232. package/lib/crypto/crypto.js.map +1 -0
  233. package/lib/crypto/dehydration.d.ts +34 -0
  234. package/lib/crypto/dehydration.d.ts.map +1 -0
  235. package/lib/crypto/dehydration.js +252 -0
  236. package/lib/crypto/dehydration.js.map +1 -0
  237. package/lib/crypto/device-converter.d.ts +9 -0
  238. package/lib/crypto/device-converter.d.ts.map +1 -0
  239. package/lib/crypto/device-converter.js +42 -0
  240. package/lib/crypto/device-converter.js.map +1 -0
  241. package/lib/crypto/deviceinfo.d.ts +99 -0
  242. package/lib/crypto/deviceinfo.d.ts.map +1 -0
  243. package/lib/crypto/deviceinfo.js +148 -0
  244. package/lib/crypto/deviceinfo.js.map +1 -0
  245. package/lib/crypto/index.d.ts +1209 -0
  246. package/lib/crypto/index.d.ts.map +1 -0
  247. package/lib/crypto/index.js +4097 -0
  248. package/lib/crypto/index.js.map +1 -0
  249. package/lib/crypto/key_passphrase.d.ts +14 -0
  250. package/lib/crypto/key_passphrase.d.ts.map +1 -0
  251. package/lib/crypto/key_passphrase.js +44 -0
  252. package/lib/crypto/key_passphrase.js.map +1 -0
  253. package/lib/crypto/keybackup.d.ts +18 -0
  254. package/lib/crypto/keybackup.d.ts.map +1 -0
  255. package/lib/crypto/keybackup.js +1 -0
  256. package/lib/crypto/keybackup.js.map +1 -0
  257. package/lib/crypto/olmlib.d.ts +129 -0
  258. package/lib/crypto/olmlib.d.ts.map +1 -0
  259. package/lib/crypto/olmlib.js +492 -0
  260. package/lib/crypto/olmlib.js.map +1 -0
  261. package/lib/crypto/recoverykey.d.ts +2 -0
  262. package/lib/crypto/recoverykey.d.ts.map +1 -0
  263. package/lib/crypto/recoverykey.js +19 -0
  264. package/lib/crypto/recoverykey.js.map +1 -0
  265. package/lib/crypto/store/base.d.ts +252 -0
  266. package/lib/crypto/store/base.d.ts.map +1 -0
  267. package/lib/crypto/store/base.js +64 -0
  268. package/lib/crypto/store/base.js.map +1 -0
  269. package/lib/crypto/store/indexeddb-crypto-store-backend.d.ts +187 -0
  270. package/lib/crypto/store/indexeddb-crypto-store-backend.d.ts.map +1 -0
  271. package/lib/crypto/store/indexeddb-crypto-store-backend.js +1145 -0
  272. package/lib/crypto/store/indexeddb-crypto-store-backend.js.map +1 -0
  273. package/lib/crypto/store/indexeddb-crypto-store.d.ts +432 -0
  274. package/lib/crypto/store/indexeddb-crypto-store.d.ts.map +1 -0
  275. package/lib/crypto/store/indexeddb-crypto-store.js +728 -0
  276. package/lib/crypto/store/indexeddb-crypto-store.js.map +1 -0
  277. package/lib/crypto/store/localStorage-crypto-store.d.ts +119 -0
  278. package/lib/crypto/store/localStorage-crypto-store.d.ts.map +1 -0
  279. package/lib/crypto/store/localStorage-crypto-store.js +531 -0
  280. package/lib/crypto/store/localStorage-crypto-store.js.map +1 -0
  281. package/lib/crypto/store/memory-crypto-store.d.ts +215 -0
  282. package/lib/crypto/store/memory-crypto-store.d.ts.map +1 -0
  283. package/lib/crypto/store/memory-crypto-store.js +622 -0
  284. package/lib/crypto/store/memory-crypto-store.js.map +1 -0
  285. package/lib/crypto/verification/Base.d.ts +105 -0
  286. package/lib/crypto/verification/Base.d.ts.map +1 -0
  287. package/lib/crypto/verification/Base.js +372 -0
  288. package/lib/crypto/verification/Base.js.map +1 -0
  289. package/lib/crypto/verification/Error.d.ts +35 -0
  290. package/lib/crypto/verification/Error.d.ts.map +1 -0
  291. package/lib/crypto/verification/Error.js +86 -0
  292. package/lib/crypto/verification/Error.js.map +1 -0
  293. package/lib/crypto/verification/IllegalMethod.d.ts +15 -0
  294. package/lib/crypto/verification/IllegalMethod.d.ts.map +1 -0
  295. package/lib/crypto/verification/IllegalMethod.js +43 -0
  296. package/lib/crypto/verification/IllegalMethod.js.map +1 -0
  297. package/lib/crypto/verification/QRCode.d.ts +51 -0
  298. package/lib/crypto/verification/QRCode.d.ts.map +1 -0
  299. package/lib/crypto/verification/QRCode.js +277 -0
  300. package/lib/crypto/verification/QRCode.js.map +1 -0
  301. package/lib/crypto/verification/SAS.d.ts +27 -0
  302. package/lib/crypto/verification/SAS.d.ts.map +1 -0
  303. package/lib/crypto/verification/SAS.js +485 -0
  304. package/lib/crypto/verification/SAS.js.map +1 -0
  305. package/lib/crypto/verification/SASDecimal.d.ts +8 -0
  306. package/lib/crypto/verification/SASDecimal.d.ts.map +1 -0
  307. package/lib/crypto/verification/SASDecimal.js +34 -0
  308. package/lib/crypto/verification/SASDecimal.js.map +1 -0
  309. package/lib/crypto/verification/request/Channel.d.ts +18 -0
  310. package/lib/crypto/verification/request/Channel.d.ts.map +1 -0
  311. package/lib/crypto/verification/request/Channel.js +1 -0
  312. package/lib/crypto/verification/request/Channel.js.map +1 -0
  313. package/lib/crypto/verification/request/InRoomChannel.d.ts +113 -0
  314. package/lib/crypto/verification/request/InRoomChannel.d.ts.map +1 -0
  315. package/lib/crypto/verification/request/InRoomChannel.js +351 -0
  316. package/lib/crypto/verification/request/InRoomChannel.js.map +1 -0
  317. package/lib/crypto/verification/request/ToDeviceChannel.d.ts +105 -0
  318. package/lib/crypto/verification/request/ToDeviceChannel.d.ts.map +1 -0
  319. package/lib/crypto/verification/request/ToDeviceChannel.js +328 -0
  320. package/lib/crypto/verification/request/ToDeviceChannel.js.map +1 -0
  321. package/lib/crypto/verification/request/VerificationRequest.d.ts +227 -0
  322. package/lib/crypto/verification/request/VerificationRequest.d.ts.map +1 -0
  323. package/lib/crypto/verification/request/VerificationRequest.js +937 -0
  324. package/lib/crypto/verification/request/VerificationRequest.js.map +1 -0
  325. package/lib/crypto-api/CryptoEvent.d.ts +69 -0
  326. package/lib/crypto-api/CryptoEvent.d.ts.map +1 -0
  327. package/lib/crypto-api/CryptoEvent.js +33 -0
  328. package/lib/crypto-api/CryptoEvent.js.map +1 -0
  329. package/lib/crypto-api/CryptoEventHandlerMap.d.ts +16 -0
  330. package/lib/crypto-api/CryptoEventHandlerMap.d.ts.map +1 -0
  331. package/lib/crypto-api/CryptoEventHandlerMap.js +22 -0
  332. package/lib/crypto-api/CryptoEventHandlerMap.js.map +1 -0
  333. package/lib/crypto-api/index.d.ts +978 -0
  334. package/lib/crypto-api/index.d.ts.map +1 -0
  335. package/lib/crypto-api/index.js +304 -0
  336. package/lib/crypto-api/index.js.map +1 -0
  337. package/lib/crypto-api/key-passphrase.d.ts +11 -0
  338. package/lib/crypto-api/key-passphrase.d.ts.map +1 -0
  339. package/lib/crypto-api/key-passphrase.js +51 -0
  340. package/lib/crypto-api/key-passphrase.js.map +1 -0
  341. package/lib/crypto-api/keybackup.d.ts +88 -0
  342. package/lib/crypto-api/keybackup.d.ts.map +1 -0
  343. package/lib/crypto-api/keybackup.js +1 -0
  344. package/lib/crypto-api/keybackup.js.map +1 -0
  345. package/lib/crypto-api/recovery-key.d.ts +11 -0
  346. package/lib/crypto-api/recovery-key.d.ts.map +1 -0
  347. package/lib/crypto-api/recovery-key.js +65 -0
  348. package/lib/crypto-api/recovery-key.js.map +1 -0
  349. package/lib/crypto-api/verification.d.ts +344 -0
  350. package/lib/crypto-api/verification.d.ts.map +1 -0
  351. package/lib/crypto-api/verification.js +91 -0
  352. package/lib/crypto-api/verification.js.map +1 -0
  353. package/lib/digest.d.ts +10 -0
  354. package/lib/digest.d.ts.map +1 -0
  355. package/lib/digest.js +40 -0
  356. package/lib/digest.js.map +1 -0
  357. package/lib/embedded.d.ts +143 -0
  358. package/lib/embedded.d.ts.map +1 -0
  359. package/lib/embedded.js +567 -0
  360. package/lib/embedded.js.map +1 -0
  361. package/lib/errors.d.ts +24 -0
  362. package/lib/errors.d.ts.map +1 -0
  363. package/lib/errors.js +51 -0
  364. package/lib/errors.js.map +1 -0
  365. package/lib/event-mapper.d.ts +10 -0
  366. package/lib/event-mapper.d.ts.map +1 -0
  367. package/lib/event-mapper.js +81 -0
  368. package/lib/event-mapper.js.map +1 -0
  369. package/lib/extensible_events_v1/ExtensibleEvent.d.ts +38 -0
  370. package/lib/extensible_events_v1/ExtensibleEvent.d.ts.map +1 -0
  371. package/lib/extensible_events_v1/ExtensibleEvent.js +57 -0
  372. package/lib/extensible_events_v1/ExtensibleEvent.js.map +1 -0
  373. package/lib/extensible_events_v1/InvalidEventError.d.ts +7 -0
  374. package/lib/extensible_events_v1/InvalidEventError.d.ts.map +1 -0
  375. package/lib/extensible_events_v1/InvalidEventError.js +25 -0
  376. package/lib/extensible_events_v1/InvalidEventError.js.map +1 -0
  377. package/lib/extensible_events_v1/MessageEvent.d.ts +45 -0
  378. package/lib/extensible_events_v1/MessageEvent.d.ts.map +1 -0
  379. package/lib/extensible_events_v1/MessageEvent.js +134 -0
  380. package/lib/extensible_events_v1/MessageEvent.js.map +1 -0
  381. package/lib/extensible_events_v1/PollEndEvent.d.ts +33 -0
  382. package/lib/extensible_events_v1/PollEndEvent.d.ts.map +1 -0
  383. package/lib/extensible_events_v1/PollEndEvent.js +88 -0
  384. package/lib/extensible_events_v1/PollEndEvent.js.map +1 -0
  385. package/lib/extensible_events_v1/PollResponseEvent.d.ts +49 -0
  386. package/lib/extensible_events_v1/PollResponseEvent.d.ts.map +1 -0
  387. package/lib/extensible_events_v1/PollResponseEvent.js +135 -0
  388. package/lib/extensible_events_v1/PollResponseEvent.js.map +1 -0
  389. package/lib/extensible_events_v1/PollStartEvent.d.ts +71 -0
  390. package/lib/extensible_events_v1/PollStartEvent.d.ts.map +1 -0
  391. package/lib/extensible_events_v1/PollStartEvent.js +185 -0
  392. package/lib/extensible_events_v1/PollStartEvent.js.map +1 -0
  393. package/lib/extensible_events_v1/utilities.d.ts +14 -0
  394. package/lib/extensible_events_v1/utilities.d.ts.map +1 -0
  395. package/lib/extensible_events_v1/utilities.js +34 -0
  396. package/lib/extensible_events_v1/utilities.js.map +1 -0
  397. package/lib/feature.d.ts +20 -0
  398. package/lib/feature.d.ts.map +1 -0
  399. package/lib/feature.js +85 -0
  400. package/lib/feature.js.map +1 -0
  401. package/lib/filter-component.d.ts +64 -0
  402. package/lib/filter-component.d.ts.map +1 -0
  403. package/lib/filter-component.js +167 -0
  404. package/lib/filter-component.js.map +1 -0
  405. package/lib/filter.d.ts +97 -0
  406. package/lib/filter.d.ts.map +1 -0
  407. package/lib/filter.js +207 -0
  408. package/lib/filter.js.map +1 -0
  409. package/lib/http-api/errors.d.ts +80 -0
  410. package/lib/http-api/errors.d.ts.map +1 -0
  411. package/lib/http-api/errors.js +185 -0
  412. package/lib/http-api/errors.js.map +1 -0
  413. package/lib/http-api/fetch.d.ts +114 -0
  414. package/lib/http-api/fetch.d.ts.map +1 -0
  415. package/lib/http-api/fetch.js +346 -0
  416. package/lib/http-api/fetch.js.map +1 -0
  417. package/lib/http-api/index.d.ts +33 -0
  418. package/lib/http-api/index.d.ts.map +1 -0
  419. package/lib/http-api/index.js +180 -0
  420. package/lib/http-api/index.js.map +1 -0
  421. package/lib/http-api/interface.d.ts +142 -0
  422. package/lib/http-api/interface.d.ts.map +1 -0
  423. package/lib/http-api/interface.js +35 -0
  424. package/lib/http-api/interface.js.map +1 -0
  425. package/lib/http-api/method.d.ts +10 -0
  426. package/lib/http-api/method.d.ts.map +1 -0
  427. package/lib/http-api/method.js +27 -0
  428. package/lib/http-api/method.js.map +1 -0
  429. package/lib/http-api/prefix.d.ts +31 -0
  430. package/lib/http-api/prefix.d.ts.map +1 -0
  431. package/lib/http-api/prefix.js +32 -0
  432. package/lib/http-api/prefix.js.map +1 -0
  433. package/lib/http-api/utils.d.ts +37 -0
  434. package/lib/http-api/utils.d.ts.map +1 -0
  435. package/lib/http-api/utils.js +178 -0
  436. package/lib/http-api/utils.js.map +1 -0
  437. package/lib/index.d.ts +4 -0
  438. package/lib/index.d.ts.map +1 -0
  439. package/lib/index.js +24 -0
  440. package/lib/index.js.map +1 -0
  441. package/lib/indexeddb-helpers.d.ts +10 -0
  442. package/lib/indexeddb-helpers.d.ts.map +1 -0
  443. package/lib/indexeddb-helpers.js +51 -0
  444. package/lib/indexeddb-helpers.js.map +1 -0
  445. package/lib/indexeddb-worker.d.ts +7 -0
  446. package/lib/indexeddb-worker.d.ts.map +1 -0
  447. package/lib/indexeddb-worker.js +25 -0
  448. package/lib/indexeddb-worker.js.map +1 -0
  449. package/lib/interactive-auth.d.ts +337 -0
  450. package/lib/interactive-auth.d.ts.map +1 -0
  451. package/lib/interactive-auth.js +557 -0
  452. package/lib/interactive-auth.js.map +1 -0
  453. package/lib/logger.d.ts +81 -0
  454. package/lib/logger.d.ts.map +1 -0
  455. package/lib/logger.js +139 -0
  456. package/lib/logger.js.map +1 -0
  457. package/lib/matrix.d.ts +118 -0
  458. package/lib/matrix.d.ts.map +1 -0
  459. package/lib/matrix.js +146 -0
  460. package/lib/matrix.js.map +1 -0
  461. package/lib/matrixrtc/CallMembership.d.ts +66 -0
  462. package/lib/matrixrtc/CallMembership.d.ts.map +1 -0
  463. package/lib/matrixrtc/CallMembership.js +197 -0
  464. package/lib/matrixrtc/CallMembership.js.map +1 -0
  465. package/lib/matrixrtc/LivekitFocus.d.ts +16 -0
  466. package/lib/matrixrtc/LivekitFocus.d.ts.map +1 -0
  467. package/lib/matrixrtc/LivekitFocus.js +20 -0
  468. package/lib/matrixrtc/LivekitFocus.js.map +1 -0
  469. package/lib/matrixrtc/MatrixRTCSession.d.ts +295 -0
  470. package/lib/matrixrtc/MatrixRTCSession.d.ts.map +1 -0
  471. package/lib/matrixrtc/MatrixRTCSession.js +1043 -0
  472. package/lib/matrixrtc/MatrixRTCSession.js.map +1 -0
  473. package/lib/matrixrtc/MatrixRTCSessionManager.d.ts +40 -0
  474. package/lib/matrixrtc/MatrixRTCSessionManager.d.ts.map +1 -0
  475. package/lib/matrixrtc/MatrixRTCSessionManager.js +146 -0
  476. package/lib/matrixrtc/MatrixRTCSessionManager.js.map +1 -0
  477. package/lib/matrixrtc/focus.d.ts +10 -0
  478. package/lib/matrixrtc/focus.d.ts.map +1 -0
  479. package/lib/matrixrtc/focus.js +1 -0
  480. package/lib/matrixrtc/focus.js.map +1 -0
  481. package/lib/matrixrtc/index.d.ts +7 -0
  482. package/lib/matrixrtc/index.d.ts.map +1 -0
  483. package/lib/matrixrtc/index.js +21 -0
  484. package/lib/matrixrtc/index.js.map +1 -0
  485. package/lib/matrixrtc/types.d.ts +19 -0
  486. package/lib/matrixrtc/types.d.ts.map +1 -0
  487. package/lib/matrixrtc/types.js +1 -0
  488. package/lib/matrixrtc/types.js.map +1 -0
  489. package/lib/models/MSC3089Branch.d.ts +98 -0
  490. package/lib/models/MSC3089Branch.d.ts.map +1 -0
  491. package/lib/models/MSC3089Branch.js +240 -0
  492. package/lib/models/MSC3089Branch.js.map +1 -0
  493. package/lib/models/MSC3089TreeSpace.d.ts +165 -0
  494. package/lib/models/MSC3089TreeSpace.d.ts.map +1 -0
  495. package/lib/models/MSC3089TreeSpace.js +520 -0
  496. package/lib/models/MSC3089TreeSpace.js.map +1 -0
  497. package/lib/models/ToDeviceMessage.d.ts +17 -0
  498. package/lib/models/ToDeviceMessage.d.ts.map +1 -0
  499. package/lib/models/ToDeviceMessage.js +1 -0
  500. package/lib/models/ToDeviceMessage.js.map +1 -0
  501. package/lib/models/beacon.d.ts +53 -0
  502. package/lib/models/beacon.d.ts.map +1 -0
  503. package/lib/models/beacon.js +174 -0
  504. package/lib/models/beacon.js.map +1 -0
  505. package/lib/models/compare-event-ordering.d.ts +24 -0
  506. package/lib/models/compare-event-ordering.d.ts.map +1 -0
  507. package/lib/models/compare-event-ordering.js +120 -0
  508. package/lib/models/compare-event-ordering.js.map +1 -0
  509. package/lib/models/device.d.ts +45 -0
  510. package/lib/models/device.d.ts.map +1 -0
  511. package/lib/models/device.js +77 -0
  512. package/lib/models/device.js.map +1 -0
  513. package/lib/models/event-context.d.ts +62 -0
  514. package/lib/models/event-context.d.ts.map +1 -0
  515. package/lib/models/event-context.js +113 -0
  516. package/lib/models/event-context.js.map +1 -0
  517. package/lib/models/event-status.d.ts +19 -0
  518. package/lib/models/event-status.d.ts.map +1 -0
  519. package/lib/models/event-status.js +30 -0
  520. package/lib/models/event-status.js.map +1 -0
  521. package/lib/models/event-timeline-set.d.ts +312 -0
  522. package/lib/models/event-timeline-set.d.ts.map +1 -0
  523. package/lib/models/event-timeline-set.js +813 -0
  524. package/lib/models/event-timeline-set.js.map +1 -0
  525. package/lib/models/event-timeline.d.ts +219 -0
  526. package/lib/models/event-timeline.d.ts.map +1 -0
  527. package/lib/models/event-timeline.js +455 -0
  528. package/lib/models/event-timeline.js.map +1 -0
  529. package/lib/models/event.d.ts +811 -0
  530. package/lib/models/event.d.ts.map +1 -0
  531. package/lib/models/event.js +1520 -0
  532. package/lib/models/event.js.map +1 -0
  533. package/lib/models/invites-ignorer.d.ts +136 -0
  534. package/lib/models/invites-ignorer.d.ts.map +1 -0
  535. package/lib/models/invites-ignorer.js +382 -0
  536. package/lib/models/invites-ignorer.js.map +1 -0
  537. package/lib/models/poll.d.ts +67 -0
  538. package/lib/models/poll.d.ts.map +1 -0
  539. package/lib/models/poll.js +241 -0
  540. package/lib/models/poll.js.map +1 -0
  541. package/lib/models/profile-keys.d.ts +8 -0
  542. package/lib/models/profile-keys.d.ts.map +1 -0
  543. package/lib/models/profile-keys.js +8 -0
  544. package/lib/models/profile-keys.js.map +1 -0
  545. package/lib/models/read-receipt.d.ts +115 -0
  546. package/lib/models/read-receipt.d.ts.map +1 -0
  547. package/lib/models/read-receipt.js +366 -0
  548. package/lib/models/read-receipt.js.map +1 -0
  549. package/lib/models/related-relations.d.ts +11 -0
  550. package/lib/models/related-relations.d.ts.map +1 -0
  551. package/lib/models/related-relations.js +33 -0
  552. package/lib/models/related-relations.js.map +1 -0
  553. package/lib/models/relations-container.d.ts +44 -0
  554. package/lib/models/relations-container.d.ts.map +1 -0
  555. package/lib/models/relations-container.js +132 -0
  556. package/lib/models/relations-container.js.map +1 -0
  557. package/lib/models/relations.d.ts +114 -0
  558. package/lib/models/relations.d.ts.map +1 -0
  559. package/lib/models/relations.js +354 -0
  560. package/lib/models/relations.js.map +1 -0
  561. package/lib/models/room-member.d.ts +204 -0
  562. package/lib/models/room-member.d.ts.map +1 -0
  563. package/lib/models/room-member.js +360 -0
  564. package/lib/models/room-member.js.map +1 -0
  565. package/lib/models/room-receipts.d.ts +39 -0
  566. package/lib/models/room-receipts.d.ts.map +1 -0
  567. package/lib/models/room-receipts.js +392 -0
  568. package/lib/models/room-receipts.js.map +1 -0
  569. package/lib/models/room-state.d.ts +468 -0
  570. package/lib/models/room-state.d.ts.map +1 -0
  571. package/lib/models/room-state.js +984 -0
  572. package/lib/models/room-state.js.map +1 -0
  573. package/lib/models/room-summary.d.ts +29 -0
  574. package/lib/models/room-summary.d.ts.map +1 -0
  575. package/lib/models/room-summary.js +28 -0
  576. package/lib/models/room-summary.js.map +1 -0
  577. package/lib/models/room.d.ts +1203 -0
  578. package/lib/models/room.d.ts.map +1 -0
  579. package/lib/models/room.js +3336 -0
  580. package/lib/models/room.js.map +1 -0
  581. package/lib/models/search-result.d.ts +20 -0
  582. package/lib/models/search-result.d.ts.map +1 -0
  583. package/lib/models/search-result.js +52 -0
  584. package/lib/models/search-result.js.map +1 -0
  585. package/lib/models/thread.d.ts +246 -0
  586. package/lib/models/thread.d.ts.map +1 -0
  587. package/lib/models/thread.js +861 -0
  588. package/lib/models/thread.js.map +1 -0
  589. package/lib/models/typed-event-emitter.d.ts +157 -0
  590. package/lib/models/typed-event-emitter.d.ts.map +1 -0
  591. package/lib/models/typed-event-emitter.js +227 -0
  592. package/lib/models/typed-event-emitter.js.map +1 -0
  593. package/lib/models/user.d.ts +195 -0
  594. package/lib/models/user.d.ts.map +1 -0
  595. package/lib/models/user.js +218 -0
  596. package/lib/models/user.js.map +1 -0
  597. package/lib/oidc/authorize.d.ts +90 -0
  598. package/lib/oidc/authorize.d.ts.map +1 -0
  599. package/lib/oidc/authorize.js +278 -0
  600. package/lib/oidc/authorize.js.map +1 -0
  601. package/lib/oidc/discovery.d.ts +14 -0
  602. package/lib/oidc/discovery.d.ts.map +1 -0
  603. package/lib/oidc/discovery.js +66 -0
  604. package/lib/oidc/discovery.js.map +1 -0
  605. package/lib/oidc/error.d.ts +18 -0
  606. package/lib/oidc/error.d.ts.map +1 -0
  607. package/lib/oidc/error.js +35 -0
  608. package/lib/oidc/error.js.map +1 -0
  609. package/lib/oidc/index.d.ts +17 -0
  610. package/lib/oidc/index.d.ts.map +1 -0
  611. package/lib/oidc/index.js +29 -0
  612. package/lib/oidc/index.js.map +1 -0
  613. package/lib/oidc/register.d.ts +43 -0
  614. package/lib/oidc/register.d.ts.map +1 -0
  615. package/lib/oidc/register.js +96 -0
  616. package/lib/oidc/register.js.map +1 -0
  617. package/lib/oidc/tokenRefresher.d.ts +69 -0
  618. package/lib/oidc/tokenRefresher.d.ts.map +1 -0
  619. package/lib/oidc/tokenRefresher.js +148 -0
  620. package/lib/oidc/tokenRefresher.js.map +1 -0
  621. package/lib/oidc/validate.d.ts +90 -0
  622. package/lib/oidc/validate.d.ts.map +1 -0
  623. package/lib/oidc/validate.js +194 -0
  624. package/lib/oidc/validate.js.map +1 -0
  625. package/lib/pushprocessor.d.ts +128 -0
  626. package/lib/pushprocessor.d.ts.map +1 -0
  627. package/lib/pushprocessor.js +685 -0
  628. package/lib/pushprocessor.js.map +1 -0
  629. package/lib/randomstring.d.ts +5 -0
  630. package/lib/randomstring.d.ts.map +1 -0
  631. package/lib/randomstring.js +43 -0
  632. package/lib/randomstring.js.map +1 -0
  633. package/lib/realtime-callbacks.d.ts +18 -0
  634. package/lib/realtime-callbacks.d.ts.map +1 -0
  635. package/lib/realtime-callbacks.js +177 -0
  636. package/lib/realtime-callbacks.js.map +1 -0
  637. package/lib/receipt-accumulator.d.ts +51 -0
  638. package/lib/receipt-accumulator.d.ts.map +1 -0
  639. package/lib/receipt-accumulator.js +164 -0
  640. package/lib/receipt-accumulator.js.map +1 -0
  641. package/lib/rendezvous/MSC4108SignInWithQR.d.ts +112 -0
  642. package/lib/rendezvous/MSC4108SignInWithQR.d.ts.map +1 -0
  643. package/lib/rendezvous/MSC4108SignInWithQR.js +392 -0
  644. package/lib/rendezvous/MSC4108SignInWithQR.js.map +1 -0
  645. package/lib/rendezvous/RendezvousChannel.d.ts +27 -0
  646. package/lib/rendezvous/RendezvousChannel.d.ts.map +1 -0
  647. package/lib/rendezvous/RendezvousChannel.js +1 -0
  648. package/lib/rendezvous/RendezvousChannel.js.map +1 -0
  649. package/lib/rendezvous/RendezvousCode.d.ts +9 -0
  650. package/lib/rendezvous/RendezvousCode.d.ts.map +1 -0
  651. package/lib/rendezvous/RendezvousCode.js +1 -0
  652. package/lib/rendezvous/RendezvousCode.js.map +1 -0
  653. package/lib/rendezvous/RendezvousError.d.ts +6 -0
  654. package/lib/rendezvous/RendezvousError.d.ts.map +1 -0
  655. package/lib/rendezvous/RendezvousError.js +23 -0
  656. package/lib/rendezvous/RendezvousError.js.map +1 -0
  657. package/lib/rendezvous/RendezvousFailureReason.d.ts +31 -0
  658. package/lib/rendezvous/RendezvousFailureReason.d.ts.map +1 -0
  659. package/lib/rendezvous/RendezvousFailureReason.js +38 -0
  660. package/lib/rendezvous/RendezvousFailureReason.js.map +1 -0
  661. package/lib/rendezvous/RendezvousIntent.d.ts +5 -0
  662. package/lib/rendezvous/RendezvousIntent.d.ts.map +1 -0
  663. package/lib/rendezvous/RendezvousIntent.js +22 -0
  664. package/lib/rendezvous/RendezvousIntent.js.map +1 -0
  665. package/lib/rendezvous/RendezvousTransport.d.ts +36 -0
  666. package/lib/rendezvous/RendezvousTransport.d.ts.map +1 -0
  667. package/lib/rendezvous/RendezvousTransport.js +1 -0
  668. package/lib/rendezvous/RendezvousTransport.js.map +1 -0
  669. package/lib/rendezvous/channels/MSC4108SecureChannel.d.ts +58 -0
  670. package/lib/rendezvous/channels/MSC4108SecureChannel.d.ts.map +1 -0
  671. package/lib/rendezvous/channels/MSC4108SecureChannel.js +246 -0
  672. package/lib/rendezvous/channels/MSC4108SecureChannel.js.map +1 -0
  673. package/lib/rendezvous/channels/index.d.ts +2 -0
  674. package/lib/rendezvous/channels/index.d.ts.map +1 -0
  675. package/lib/rendezvous/channels/index.js +18 -0
  676. package/lib/rendezvous/channels/index.js.map +1 -0
  677. package/lib/rendezvous/index.d.ts +10 -0
  678. package/lib/rendezvous/index.d.ts.map +1 -0
  679. package/lib/rendezvous/index.js +23 -0
  680. package/lib/rendezvous/index.js.map +1 -0
  681. package/lib/rendezvous/transports/MSC4108RendezvousSession.d.ts +61 -0
  682. package/lib/rendezvous/transports/MSC4108RendezvousSession.d.ts.map +1 -0
  683. package/lib/rendezvous/transports/MSC4108RendezvousSession.js +253 -0
  684. package/lib/rendezvous/transports/MSC4108RendezvousSession.js.map +1 -0
  685. package/lib/rendezvous/transports/index.d.ts +2 -0
  686. package/lib/rendezvous/transports/index.d.ts.map +1 -0
  687. package/lib/rendezvous/transports/index.js +18 -0
  688. package/lib/rendezvous/transports/index.js.map +1 -0
  689. package/lib/room-hierarchy.d.ts +35 -0
  690. package/lib/room-hierarchy.d.ts.map +1 -0
  691. package/lib/room-hierarchy.js +136 -0
  692. package/lib/room-hierarchy.js.map +1 -0
  693. package/lib/rust-crypto/CrossSigningIdentity.d.ts +33 -0
  694. package/lib/rust-crypto/CrossSigningIdentity.d.ts.map +1 -0
  695. package/lib/rust-crypto/CrossSigningIdentity.js +157 -0
  696. package/lib/rust-crypto/CrossSigningIdentity.js.map +1 -0
  697. package/lib/rust-crypto/DehydratedDeviceManager.d.ts +98 -0
  698. package/lib/rust-crypto/DehydratedDeviceManager.d.ts.map +1 -0
  699. package/lib/rust-crypto/DehydratedDeviceManager.js +285 -0
  700. package/lib/rust-crypto/DehydratedDeviceManager.js.map +1 -0
  701. package/lib/rust-crypto/KeyClaimManager.d.ts +33 -0
  702. package/lib/rust-crypto/KeyClaimManager.d.ts.map +1 -0
  703. package/lib/rust-crypto/KeyClaimManager.js +82 -0
  704. package/lib/rust-crypto/KeyClaimManager.js.map +1 -0
  705. package/lib/rust-crypto/OutgoingRequestProcessor.d.ts +43 -0
  706. package/lib/rust-crypto/OutgoingRequestProcessor.d.ts.map +1 -0
  707. package/lib/rust-crypto/OutgoingRequestProcessor.js +195 -0
  708. package/lib/rust-crypto/OutgoingRequestProcessor.js.map +1 -0
  709. package/lib/rust-crypto/OutgoingRequestsManager.d.ts +47 -0
  710. package/lib/rust-crypto/OutgoingRequestsManager.d.ts.map +1 -0
  711. package/lib/rust-crypto/OutgoingRequestsManager.js +148 -0
  712. package/lib/rust-crypto/OutgoingRequestsManager.js.map +1 -0
  713. package/lib/rust-crypto/PerSessionKeyBackupDownloader.d.ts +120 -0
  714. package/lib/rust-crypto/PerSessionKeyBackupDownloader.d.ts.map +1 -0
  715. package/lib/rust-crypto/PerSessionKeyBackupDownloader.js +467 -0
  716. package/lib/rust-crypto/PerSessionKeyBackupDownloader.js.map +1 -0
  717. package/lib/rust-crypto/RoomEncryptor.d.ts +98 -0
  718. package/lib/rust-crypto/RoomEncryptor.d.ts.map +1 -0
  719. package/lib/rust-crypto/RoomEncryptor.js +299 -0
  720. package/lib/rust-crypto/RoomEncryptor.js.map +1 -0
  721. package/lib/rust-crypto/backup.d.ts +254 -0
  722. package/lib/rust-crypto/backup.d.ts.map +1 -0
  723. package/lib/rust-crypto/backup.js +837 -0
  724. package/lib/rust-crypto/backup.js.map +1 -0
  725. package/lib/rust-crypto/constants.d.ts +3 -0
  726. package/lib/rust-crypto/constants.d.ts.map +1 -0
  727. package/lib/rust-crypto/constants.js +19 -0
  728. package/lib/rust-crypto/constants.js.map +1 -0
  729. package/lib/rust-crypto/device-converter.d.ts +28 -0
  730. package/lib/rust-crypto/device-converter.d.ts.map +1 -0
  731. package/lib/rust-crypto/device-converter.js +123 -0
  732. package/lib/rust-crypto/device-converter.js.map +1 -0
  733. package/lib/rust-crypto/index.d.ts +61 -0
  734. package/lib/rust-crypto/index.d.ts.map +1 -0
  735. package/lib/rust-crypto/index.js +152 -0
  736. package/lib/rust-crypto/index.js.map +1 -0
  737. package/lib/rust-crypto/libolm_migration.d.ts +81 -0
  738. package/lib/rust-crypto/libolm_migration.d.ts.map +1 -0
  739. package/lib/rust-crypto/libolm_migration.js +459 -0
  740. package/lib/rust-crypto/libolm_migration.js.map +1 -0
  741. package/lib/rust-crypto/rust-crypto.d.ts +556 -0
  742. package/lib/rust-crypto/rust-crypto.d.ts.map +1 -0
  743. package/lib/rust-crypto/rust-crypto.js +2016 -0
  744. package/lib/rust-crypto/rust-crypto.js.map +1 -0
  745. package/lib/rust-crypto/secret-storage.d.ts +22 -0
  746. package/lib/rust-crypto/secret-storage.d.ts.map +1 -0
  747. package/lib/rust-crypto/secret-storage.js +63 -0
  748. package/lib/rust-crypto/secret-storage.js.map +1 -0
  749. package/lib/rust-crypto/verification.d.ts +319 -0
  750. package/lib/rust-crypto/verification.d.ts.map +1 -0
  751. package/lib/rust-crypto/verification.js +816 -0
  752. package/lib/rust-crypto/verification.js.map +1 -0
  753. package/lib/scheduler.d.ts +132 -0
  754. package/lib/scheduler.d.ts.map +1 -0
  755. package/lib/scheduler.js +259 -0
  756. package/lib/scheduler.js.map +1 -0
  757. package/lib/secret-storage.d.ts +370 -0
  758. package/lib/secret-storage.d.ts.map +1 -0
  759. package/lib/secret-storage.js +466 -0
  760. package/lib/secret-storage.js.map +1 -0
  761. package/lib/serverCapabilities.d.ts +72 -0
  762. package/lib/serverCapabilities.d.ts.map +1 -0
  763. package/lib/serverCapabilities.js +105 -0
  764. package/lib/serverCapabilities.js.map +1 -0
  765. package/lib/service-types.d.ts +5 -0
  766. package/lib/service-types.d.ts.map +1 -0
  767. package/lib/service-types.js +22 -0
  768. package/lib/service-types.js.map +1 -0
  769. package/lib/sliding-sync-sdk.d.ts +107 -0
  770. package/lib/sliding-sync-sdk.d.ts.map +1 -0
  771. package/lib/sliding-sync-sdk.js +903 -0
  772. package/lib/sliding-sync-sdk.js.map +1 -0
  773. package/lib/sliding-sync.d.ts +343 -0
  774. package/lib/sliding-sync.d.ts.map +1 -0
  775. package/lib/sliding-sync.js +817 -0
  776. package/lib/sliding-sync.js.map +1 -0
  777. package/lib/store/index.d.ts +201 -0
  778. package/lib/store/index.d.ts.map +1 -0
  779. package/lib/store/index.js +1 -0
  780. package/lib/store/index.js.map +1 -0
  781. package/lib/store/indexeddb-backend.d.ts +24 -0
  782. package/lib/store/indexeddb-backend.d.ts.map +1 -0
  783. package/lib/store/indexeddb-backend.js +1 -0
  784. package/lib/store/indexeddb-backend.js.map +1 -0
  785. package/lib/store/indexeddb-local-backend.d.ts +129 -0
  786. package/lib/store/indexeddb-local-backend.d.ts.map +1 -0
  787. package/lib/store/indexeddb-local-backend.js +597 -0
  788. package/lib/store/indexeddb-local-backend.js.map +1 -0
  789. package/lib/store/indexeddb-remote-backend.d.ts +79 -0
  790. package/lib/store/indexeddb-remote-backend.d.ts.map +1 -0
  791. package/lib/store/indexeddb-remote-backend.js +210 -0
  792. package/lib/store/indexeddb-remote-backend.js.map +1 -0
  793. package/lib/store/indexeddb-store-worker.d.ts +35 -0
  794. package/lib/store/indexeddb-store-worker.d.ts.map +1 -0
  795. package/lib/store/indexeddb-store-worker.js +146 -0
  796. package/lib/store/indexeddb-store-worker.js.map +1 -0
  797. package/lib/store/indexeddb.d.ts +142 -0
  798. package/lib/store/indexeddb.d.ts.map +1 -0
  799. package/lib/store/indexeddb.js +347 -0
  800. package/lib/store/indexeddb.js.map +1 -0
  801. package/lib/store/local-storage-events-emitter.d.ts +30 -0
  802. package/lib/store/local-storage-events-emitter.d.ts.map +1 -0
  803. package/lib/store/local-storage-events-emitter.js +37 -0
  804. package/lib/store/local-storage-events-emitter.js.map +1 -0
  805. package/lib/store/memory.d.ts +209 -0
  806. package/lib/store/memory.d.ts.map +1 -0
  807. package/lib/store/memory.js +432 -0
  808. package/lib/store/memory.js.map +1 -0
  809. package/lib/store/stub.d.ts +161 -0
  810. package/lib/store/stub.d.ts.map +1 -0
  811. package/lib/store/stub.js +268 -0
  812. package/lib/store/stub.js.map +1 -0
  813. package/lib/sync-accumulator.d.ts +172 -0
  814. package/lib/sync-accumulator.d.ts.map +1 -0
  815. package/lib/sync-accumulator.js +532 -0
  816. package/lib/sync-accumulator.js.map +1 -0
  817. package/lib/sync.d.ts +260 -0
  818. package/lib/sync.d.ts.map +1 -0
  819. package/lib/sync.js +1686 -0
  820. package/lib/sync.js.map +1 -0
  821. package/lib/testing.d.ts +81 -0
  822. package/lib/testing.d.ts.map +1 -0
  823. package/lib/testing.js +162 -0
  824. package/lib/testing.js.map +1 -0
  825. package/lib/thread-utils.d.ts +10 -0
  826. package/lib/thread-utils.d.ts.map +1 -0
  827. package/lib/thread-utils.js +31 -0
  828. package/lib/thread-utils.js.map +1 -0
  829. package/lib/timeline-window.d.ts +168 -0
  830. package/lib/timeline-window.d.ts.map +1 -0
  831. package/lib/timeline-window.js +494 -0
  832. package/lib/timeline-window.js.map +1 -0
  833. package/lib/types.d.ts +33 -0
  834. package/lib/types.d.ts.map +1 -0
  835. package/lib/types.js +33 -0
  836. package/lib/types.js.map +1 -0
  837. package/lib/utils/decryptAESSecretStorageItem.d.ts +12 -0
  838. package/lib/utils/decryptAESSecretStorageItem.d.ts.map +1 -0
  839. package/lib/utils/decryptAESSecretStorageItem.js +50 -0
  840. package/lib/utils/decryptAESSecretStorageItem.js.map +1 -0
  841. package/lib/utils/encryptAESSecretStorageItem.d.ts +16 -0
  842. package/lib/utils/encryptAESSecretStorageItem.d.ts.map +1 -0
  843. package/lib/utils/encryptAESSecretStorageItem.js +68 -0
  844. package/lib/utils/encryptAESSecretStorageItem.js.map +1 -0
  845. package/lib/utils/internal/deriveKeys.d.ts +10 -0
  846. package/lib/utils/internal/deriveKeys.d.ts.map +1 -0
  847. package/lib/utils/internal/deriveKeys.js +60 -0
  848. package/lib/utils/internal/deriveKeys.js.map +1 -0
  849. package/lib/utils.d.ts +267 -0
  850. package/lib/utils.d.ts.map +1 -0
  851. package/lib/utils.js +749 -0
  852. package/lib/utils.js.map +1 -0
  853. package/lib/version-support.d.ts +19 -0
  854. package/lib/version-support.d.ts.map +1 -0
  855. package/lib/version-support.js +37 -0
  856. package/lib/version-support.js.map +1 -0
  857. package/lib/webrtc/audioContext.d.ts +15 -0
  858. package/lib/webrtc/audioContext.d.ts.map +1 -0
  859. package/lib/webrtc/audioContext.js +46 -0
  860. package/lib/webrtc/audioContext.js.map +1 -0
  861. package/lib/webrtc/call.d.ts +560 -0
  862. package/lib/webrtc/call.d.ts.map +1 -0
  863. package/lib/webrtc/call.js +2541 -0
  864. package/lib/webrtc/call.js.map +1 -0
  865. package/lib/webrtc/callEventHandler.d.ts +37 -0
  866. package/lib/webrtc/callEventHandler.d.ts.map +1 -0
  867. package/lib/webrtc/callEventHandler.js +344 -0
  868. package/lib/webrtc/callEventHandler.js.map +1 -0
  869. package/lib/webrtc/callEventTypes.d.ts +73 -0
  870. package/lib/webrtc/callEventTypes.d.ts.map +1 -0
  871. package/lib/webrtc/callEventTypes.js +13 -0
  872. package/lib/webrtc/callEventTypes.js.map +1 -0
  873. package/lib/webrtc/callFeed.d.ts +128 -0
  874. package/lib/webrtc/callFeed.d.ts.map +1 -0
  875. package/lib/webrtc/callFeed.js +289 -0
  876. package/lib/webrtc/callFeed.js.map +1 -0
  877. package/lib/webrtc/groupCall.d.ts +323 -0
  878. package/lib/webrtc/groupCall.d.ts.map +1 -0
  879. package/lib/webrtc/groupCall.js +1337 -0
  880. package/lib/webrtc/groupCall.js.map +1 -0
  881. package/lib/webrtc/groupCallEventHandler.d.ts +31 -0
  882. package/lib/webrtc/groupCallEventHandler.d.ts.map +1 -0
  883. package/lib/webrtc/groupCallEventHandler.js +178 -0
  884. package/lib/webrtc/groupCallEventHandler.js.map +1 -0
  885. package/lib/webrtc/mediaHandler.d.ts +89 -0
  886. package/lib/webrtc/mediaHandler.d.ts.map +1 -0
  887. package/lib/webrtc/mediaHandler.js +437 -0
  888. package/lib/webrtc/mediaHandler.js.map +1 -0
  889. package/lib/webrtc/stats/callFeedStatsReporter.d.ts +8 -0
  890. package/lib/webrtc/stats/callFeedStatsReporter.d.ts.map +1 -0
  891. package/lib/webrtc/stats/callFeedStatsReporter.js +82 -0
  892. package/lib/webrtc/stats/callFeedStatsReporter.js.map +1 -0
  893. package/lib/webrtc/stats/callStatsReportGatherer.d.ts +25 -0
  894. package/lib/webrtc/stats/callStatsReportGatherer.d.ts.map +1 -0
  895. package/lib/webrtc/stats/callStatsReportGatherer.js +199 -0
  896. package/lib/webrtc/stats/callStatsReportGatherer.js.map +1 -0
  897. package/lib/webrtc/stats/callStatsReportSummary.d.ts +17 -0
  898. package/lib/webrtc/stats/callStatsReportSummary.d.ts.map +1 -0
  899. package/lib/webrtc/stats/callStatsReportSummary.js +1 -0
  900. package/lib/webrtc/stats/callStatsReportSummary.js.map +1 -0
  901. package/lib/webrtc/stats/connectionStats.d.ts +28 -0
  902. package/lib/webrtc/stats/connectionStats.d.ts.map +1 -0
  903. package/lib/webrtc/stats/connectionStats.js +26 -0
  904. package/lib/webrtc/stats/connectionStats.js.map +1 -0
  905. package/lib/webrtc/stats/connectionStatsBuilder.d.ts +5 -0
  906. package/lib/webrtc/stats/connectionStatsBuilder.d.ts.map +1 -0
  907. package/lib/webrtc/stats/connectionStatsBuilder.js +27 -0
  908. package/lib/webrtc/stats/connectionStatsBuilder.js.map +1 -0
  909. package/lib/webrtc/stats/connectionStatsReportBuilder.d.ts +7 -0
  910. package/lib/webrtc/stats/connectionStatsReportBuilder.d.ts.map +1 -0
  911. package/lib/webrtc/stats/connectionStatsReportBuilder.js +121 -0
  912. package/lib/webrtc/stats/connectionStatsReportBuilder.js.map +1 -0
  913. package/lib/webrtc/stats/groupCallStats.d.ts +22 -0
  914. package/lib/webrtc/stats/groupCallStats.d.ts.map +1 -0
  915. package/lib/webrtc/stats/groupCallStats.js +78 -0
  916. package/lib/webrtc/stats/groupCallStats.js.map +1 -0
  917. package/lib/webrtc/stats/media/mediaSsrcHandler.d.ts +10 -0
  918. package/lib/webrtc/stats/media/mediaSsrcHandler.d.ts.map +1 -0
  919. package/lib/webrtc/stats/media/mediaSsrcHandler.js +57 -0
  920. package/lib/webrtc/stats/media/mediaSsrcHandler.js.map +1 -0
  921. package/lib/webrtc/stats/media/mediaTrackHandler.d.ts +12 -0
  922. package/lib/webrtc/stats/media/mediaTrackHandler.d.ts.map +1 -0
  923. package/lib/webrtc/stats/media/mediaTrackHandler.js +62 -0
  924. package/lib/webrtc/stats/media/mediaTrackHandler.js.map +1 -0
  925. package/lib/webrtc/stats/media/mediaTrackStats.d.ts +86 -0
  926. package/lib/webrtc/stats/media/mediaTrackStats.d.ts.map +1 -0
  927. package/lib/webrtc/stats/media/mediaTrackStats.js +142 -0
  928. package/lib/webrtc/stats/media/mediaTrackStats.js.map +1 -0
  929. package/lib/webrtc/stats/media/mediaTrackStatsHandler.d.ts +22 -0
  930. package/lib/webrtc/stats/media/mediaTrackStatsHandler.d.ts.map +1 -0
  931. package/lib/webrtc/stats/media/mediaTrackStatsHandler.js +76 -0
  932. package/lib/webrtc/stats/media/mediaTrackStatsHandler.js.map +1 -0
  933. package/lib/webrtc/stats/statsReport.d.ts +99 -0
  934. package/lib/webrtc/stats/statsReport.d.ts.map +1 -0
  935. package/lib/webrtc/stats/statsReport.js +32 -0
  936. package/lib/webrtc/stats/statsReport.js.map +1 -0
  937. package/lib/webrtc/stats/statsReportEmitter.d.ts +15 -0
  938. package/lib/webrtc/stats/statsReportEmitter.d.ts.map +1 -0
  939. package/lib/webrtc/stats/statsReportEmitter.js +33 -0
  940. package/lib/webrtc/stats/statsReportEmitter.js.map +1 -0
  941. package/lib/webrtc/stats/summaryStatsReportGatherer.d.ts +16 -0
  942. package/lib/webrtc/stats/summaryStatsReportGatherer.d.ts.map +1 -0
  943. package/lib/webrtc/stats/summaryStatsReportGatherer.js +116 -0
  944. package/lib/webrtc/stats/summaryStatsReportGatherer.js.map +1 -0
  945. package/lib/webrtc/stats/trackStatsBuilder.d.ts +19 -0
  946. package/lib/webrtc/stats/trackStatsBuilder.d.ts.map +1 -0
  947. package/lib/webrtc/stats/trackStatsBuilder.js +168 -0
  948. package/lib/webrtc/stats/trackStatsBuilder.js.map +1 -0
  949. package/lib/webrtc/stats/transportStats.d.ts +11 -0
  950. package/lib/webrtc/stats/transportStats.d.ts.map +1 -0
  951. package/lib/webrtc/stats/transportStats.js +1 -0
  952. package/lib/webrtc/stats/transportStats.js.map +1 -0
  953. package/lib/webrtc/stats/transportStatsBuilder.d.ts +5 -0
  954. package/lib/webrtc/stats/transportStatsBuilder.d.ts.map +1 -0
  955. package/lib/webrtc/stats/transportStatsBuilder.js +34 -0
  956. package/lib/webrtc/stats/transportStatsBuilder.js.map +1 -0
  957. package/lib/webrtc/stats/valueFormatter.d.ts +4 -0
  958. package/lib/webrtc/stats/valueFormatter.d.ts.map +1 -0
  959. package/lib/webrtc/stats/valueFormatter.js +25 -0
  960. package/lib/webrtc/stats/valueFormatter.js.map +1 -0
  961. package/package.json +134 -0
  962. package/src/@types/AESEncryptedSecretStoragePayload.ts +29 -0
  963. package/src/@types/IIdentityServerProvider.ts +24 -0
  964. package/src/@types/PushRules.ts +209 -0
  965. package/src/@types/another-json.d.ts +19 -0
  966. package/src/@types/auth.ts +252 -0
  967. package/src/@types/beacon.ts +140 -0
  968. package/src/@types/common.ts +22 -0
  969. package/src/@types/crypto.ts +73 -0
  970. package/src/@types/event.ts +370 -0
  971. package/src/@types/events.ts +119 -0
  972. package/src/@types/extensible_events.ts +150 -0
  973. package/src/@types/global.d.ts +70 -0
  974. package/src/@types/local_notifications.ts +19 -0
  975. package/src/@types/location.ts +92 -0
  976. package/src/@types/matrix-sdk-crypto-wasm.d.ts +44 -0
  977. package/src/@types/media.ts +245 -0
  978. package/src/@types/membership.ts +57 -0
  979. package/src/@types/oidc-client-ts.d.ts +24 -0
  980. package/src/@types/partials.ts +67 -0
  981. package/src/@types/polls.ts +119 -0
  982. package/src/@types/read_receipts.ts +61 -0
  983. package/src/@types/registration.ts +102 -0
  984. package/src/@types/requests.ts +314 -0
  985. package/src/@types/search.ts +119 -0
  986. package/src/@types/signed.ts +25 -0
  987. package/src/@types/spaces.ts +37 -0
  988. package/src/@types/state_events.ts +147 -0
  989. package/src/@types/synapse.ts +40 -0
  990. package/src/@types/sync.ts +27 -0
  991. package/src/@types/threepids.ts +29 -0
  992. package/src/@types/topic.ts +63 -0
  993. package/src/@types/uia.ts +29 -0
  994. package/src/NamespacedValue.ts +123 -0
  995. package/src/ReEmitter.ts +93 -0
  996. package/src/ToDeviceMessageQueue.ts +153 -0
  997. package/src/autodiscovery.ts +505 -0
  998. package/src/base64.ts +88 -0
  999. package/src/browser-index.ts +44 -0
  1000. package/src/client.ts +10474 -0
  1001. package/src/common-crypto/CryptoBackend.ts +302 -0
  1002. package/src/common-crypto/README.md +4 -0
  1003. package/src/common-crypto/key-passphrase.ts +43 -0
  1004. package/src/content-helpers.ts +288 -0
  1005. package/src/content-repo.ts +117 -0
  1006. package/src/crypto/CrossSigning.ts +773 -0
  1007. package/src/crypto/DeviceList.ts +989 -0
  1008. package/src/crypto/EncryptionSetup.ts +351 -0
  1009. package/src/crypto/OlmDevice.ts +1500 -0
  1010. package/src/crypto/OutgoingRoomKeyRequestManager.ts +485 -0
  1011. package/src/crypto/RoomList.ts +70 -0
  1012. package/src/crypto/SecretSharing.ts +240 -0
  1013. package/src/crypto/SecretStorage.ts +136 -0
  1014. package/src/crypto/aes.ts +23 -0
  1015. package/src/crypto/algorithms/base.ts +236 -0
  1016. package/src/crypto/algorithms/index.ts +20 -0
  1017. package/src/crypto/algorithms/megolm.ts +2216 -0
  1018. package/src/crypto/algorithms/olm.ts +381 -0
  1019. package/src/crypto/api.ts +70 -0
  1020. package/src/crypto/backup.ts +922 -0
  1021. package/src/crypto/crypto.ts +18 -0
  1022. package/src/crypto/dehydration.ts +272 -0
  1023. package/src/crypto/device-converter.ts +45 -0
  1024. package/src/crypto/deviceinfo.ts +158 -0
  1025. package/src/crypto/index.ts +4414 -0
  1026. package/src/crypto/key_passphrase.ts +42 -0
  1027. package/src/crypto/keybackup.ts +47 -0
  1028. package/src/crypto/olmlib.ts +539 -0
  1029. package/src/crypto/recoverykey.ts +18 -0
  1030. package/src/crypto/store/base.ts +348 -0
  1031. package/src/crypto/store/indexeddb-crypto-store-backend.ts +1250 -0
  1032. package/src/crypto/store/indexeddb-crypto-store.ts +845 -0
  1033. package/src/crypto/store/localStorage-crypto-store.ts +579 -0
  1034. package/src/crypto/store/memory-crypto-store.ts +680 -0
  1035. package/src/crypto/verification/Base.ts +409 -0
  1036. package/src/crypto/verification/Error.ts +76 -0
  1037. package/src/crypto/verification/IllegalMethod.ts +50 -0
  1038. package/src/crypto/verification/QRCode.ts +310 -0
  1039. package/src/crypto/verification/SAS.ts +494 -0
  1040. package/src/crypto/verification/SASDecimal.ts +37 -0
  1041. package/src/crypto/verification/request/Channel.ts +34 -0
  1042. package/src/crypto/verification/request/InRoomChannel.ts +371 -0
  1043. package/src/crypto/verification/request/ToDeviceChannel.ts +354 -0
  1044. package/src/crypto/verification/request/VerificationRequest.ts +976 -0
  1045. package/src/crypto-api/CryptoEvent.ts +93 -0
  1046. package/src/crypto-api/CryptoEventHandlerMap.ts +32 -0
  1047. package/src/crypto-api/index.ts +1175 -0
  1048. package/src/crypto-api/key-passphrase.ts +58 -0
  1049. package/src/crypto-api/keybackup.ts +115 -0
  1050. package/src/crypto-api/recovery-key.ts +69 -0
  1051. package/src/crypto-api/verification.ts +408 -0
  1052. package/src/digest.ts +34 -0
  1053. package/src/embedded.ts +631 -0
  1054. package/src/errors.ts +54 -0
  1055. package/src/event-mapper.ts +97 -0
  1056. package/src/extensible_events_v1/ExtensibleEvent.ts +58 -0
  1057. package/src/extensible_events_v1/InvalidEventError.ts +24 -0
  1058. package/src/extensible_events_v1/MessageEvent.ts +145 -0
  1059. package/src/extensible_events_v1/PollEndEvent.ts +97 -0
  1060. package/src/extensible_events_v1/PollResponseEvent.ts +148 -0
  1061. package/src/extensible_events_v1/PollStartEvent.ts +207 -0
  1062. package/src/extensible_events_v1/utilities.ts +35 -0
  1063. package/src/feature.ts +87 -0
  1064. package/src/filter-component.ts +207 -0
  1065. package/src/filter.ts +245 -0
  1066. package/src/http-api/errors.ts +199 -0
  1067. package/src/http-api/fetch.ts +383 -0
  1068. package/src/http-api/index.ts +191 -0
  1069. package/src/http-api/interface.ts +178 -0
  1070. package/src/http-api/method.ts +25 -0
  1071. package/src/http-api/prefix.ts +48 -0
  1072. package/src/http-api/utils.ts +200 -0
  1073. package/src/index.ts +25 -0
  1074. package/src/indexeddb-helpers.ts +50 -0
  1075. package/src/indexeddb-worker.ts +24 -0
  1076. package/src/interactive-auth.ts +694 -0
  1077. package/src/logger.ts +185 -0
  1078. package/src/matrix.ts +177 -0
  1079. package/src/matrixrtc/CallMembership.ts +247 -0
  1080. package/src/matrixrtc/LivekitFocus.ts +39 -0
  1081. package/src/matrixrtc/MatrixRTCSession.ts +1319 -0
  1082. package/src/matrixrtc/MatrixRTCSessionManager.ts +166 -0
  1083. package/src/matrixrtc/focus.ts +25 -0
  1084. package/src/matrixrtc/index.ts +22 -0
  1085. package/src/matrixrtc/types.ts +36 -0
  1086. package/src/models/MSC3089Branch.ts +272 -0
  1087. package/src/models/MSC3089TreeSpace.ts +565 -0
  1088. package/src/models/ToDeviceMessage.ts +38 -0
  1089. package/src/models/beacon.ts +214 -0
  1090. package/src/models/compare-event-ordering.ts +139 -0
  1091. package/src/models/device.ts +85 -0
  1092. package/src/models/event-context.ts +110 -0
  1093. package/src/models/event-status.ts +39 -0
  1094. package/src/models/event-timeline-set.ts +979 -0
  1095. package/src/models/event-timeline.ts +476 -0
  1096. package/src/models/event.ts +1751 -0
  1097. package/src/models/invites-ignorer.ts +376 -0
  1098. package/src/models/poll.ts +285 -0
  1099. package/src/models/profile-keys.ts +7 -0
  1100. package/src/models/read-receipt.ts +422 -0
  1101. package/src/models/related-relations.ts +39 -0
  1102. package/src/models/relations-container.ts +149 -0
  1103. package/src/models/relations.ts +368 -0
  1104. package/src/models/room-member.ts +457 -0
  1105. package/src/models/room-receipts.ts +439 -0
  1106. package/src/models/room-state.ts +1130 -0
  1107. package/src/models/room-summary.ts +47 -0
  1108. package/src/models/room.ts +3822 -0
  1109. package/src/models/search-result.ts +57 -0
  1110. package/src/models/thread.ts +923 -0
  1111. package/src/models/typed-event-emitter.ts +246 -0
  1112. package/src/models/user.ts +302 -0
  1113. package/src/oidc/authorize.ts +274 -0
  1114. package/src/oidc/discovery.ts +60 -0
  1115. package/src/oidc/error.ts +33 -0
  1116. package/src/oidc/index.ts +34 -0
  1117. package/src/oidc/register.ts +123 -0
  1118. package/src/oidc/tokenRefresher.ts +149 -0
  1119. package/src/oidc/validate.ts +282 -0
  1120. package/src/pushprocessor.ts +837 -0
  1121. package/src/randomstring.ts +51 -0
  1122. package/src/realtime-callbacks.ts +191 -0
  1123. package/src/receipt-accumulator.ts +189 -0
  1124. package/src/rendezvous/MSC4108SignInWithQR.ts +444 -0
  1125. package/src/rendezvous/RendezvousChannel.ts +48 -0
  1126. package/src/rendezvous/RendezvousCode.ts +25 -0
  1127. package/src/rendezvous/RendezvousError.ts +26 -0
  1128. package/src/rendezvous/RendezvousFailureReason.ts +49 -0
  1129. package/src/rendezvous/RendezvousIntent.ts +20 -0
  1130. package/src/rendezvous/RendezvousTransport.ts +58 -0
  1131. package/src/rendezvous/channels/MSC4108SecureChannel.ts +270 -0
  1132. package/src/rendezvous/channels/index.ts +17 -0
  1133. package/src/rendezvous/index.ts +25 -0
  1134. package/src/rendezvous/transports/MSC4108RendezvousSession.ts +270 -0
  1135. package/src/rendezvous/transports/index.ts +17 -0
  1136. package/src/room-hierarchy.ts +152 -0
  1137. package/src/rust-crypto/CrossSigningIdentity.ts +183 -0
  1138. package/src/rust-crypto/DehydratedDeviceManager.ts +306 -0
  1139. package/src/rust-crypto/KeyClaimManager.ts +86 -0
  1140. package/src/rust-crypto/OutgoingRequestProcessor.ts +236 -0
  1141. package/src/rust-crypto/OutgoingRequestsManager.ts +143 -0
  1142. package/src/rust-crypto/PerSessionKeyBackupDownloader.ts +501 -0
  1143. package/src/rust-crypto/RoomEncryptor.ts +352 -0
  1144. package/src/rust-crypto/backup.ts +881 -0
  1145. package/src/rust-crypto/constants.ts +18 -0
  1146. package/src/rust-crypto/device-converter.ts +128 -0
  1147. package/src/rust-crypto/index.ts +237 -0
  1148. package/src/rust-crypto/libolm_migration.ts +530 -0
  1149. package/src/rust-crypto/rust-crypto.ts +2205 -0
  1150. package/src/rust-crypto/secret-storage.ts +60 -0
  1151. package/src/rust-crypto/verification.ts +830 -0
  1152. package/src/scheduler.ts +309 -0
  1153. package/src/secret-storage.ts +693 -0
  1154. package/src/serverCapabilities.ts +139 -0
  1155. package/src/service-types.ts +20 -0
  1156. package/src/sliding-sync-sdk.ts +1026 -0
  1157. package/src/sliding-sync.ts +965 -0
  1158. package/src/store/index.ts +261 -0
  1159. package/src/store/indexeddb-backend.ts +41 -0
  1160. package/src/store/indexeddb-local-backend.ts +610 -0
  1161. package/src/store/indexeddb-remote-backend.ts +213 -0
  1162. package/src/store/indexeddb-store-worker.ts +157 -0
  1163. package/src/store/indexeddb.ts +397 -0
  1164. package/src/store/local-storage-events-emitter.ts +46 -0
  1165. package/src/store/memory.ts +448 -0
  1166. package/src/store/stub.ts +280 -0
  1167. package/src/sync-accumulator.ts +689 -0
  1168. package/src/sync.ts +1920 -0
  1169. package/src/testing.ts +191 -0
  1170. package/src/thread-utils.ts +31 -0
  1171. package/src/timeline-window.ts +536 -0
  1172. package/src/types.ts +59 -0
  1173. package/src/utils/decryptAESSecretStorageItem.ts +54 -0
  1174. package/src/utils/encryptAESSecretStorageItem.ts +73 -0
  1175. package/src/utils/internal/deriveKeys.ts +63 -0
  1176. package/src/utils.ts +763 -0
  1177. package/src/version-support.ts +36 -0
  1178. package/src/webrtc/audioContext.ts +44 -0
  1179. package/src/webrtc/call.ts +3074 -0
  1180. package/src/webrtc/callEventHandler.ts +425 -0
  1181. package/src/webrtc/callEventTypes.ts +93 -0
  1182. package/src/webrtc/callFeed.ts +364 -0
  1183. package/src/webrtc/groupCall.ts +1735 -0
  1184. package/src/webrtc/groupCallEventHandler.ts +234 -0
  1185. package/src/webrtc/mediaHandler.ts +484 -0
  1186. package/src/webrtc/stats/callFeedStatsReporter.ts +94 -0
  1187. package/src/webrtc/stats/callStatsReportGatherer.ts +219 -0
  1188. package/src/webrtc/stats/callStatsReportSummary.ts +30 -0
  1189. package/src/webrtc/stats/connectionStats.ts +47 -0
  1190. package/src/webrtc/stats/connectionStatsBuilder.ts +28 -0
  1191. package/src/webrtc/stats/connectionStatsReportBuilder.ts +140 -0
  1192. package/src/webrtc/stats/groupCallStats.ts +93 -0
  1193. package/src/webrtc/stats/media/mediaSsrcHandler.ts +57 -0
  1194. package/src/webrtc/stats/media/mediaTrackHandler.ts +76 -0
  1195. package/src/webrtc/stats/media/mediaTrackStats.ts +176 -0
  1196. package/src/webrtc/stats/media/mediaTrackStatsHandler.ts +90 -0
  1197. package/src/webrtc/stats/statsReport.ts +133 -0
  1198. package/src/webrtc/stats/statsReportEmitter.ts +49 -0
  1199. package/src/webrtc/stats/summaryStatsReportGatherer.ts +148 -0
  1200. package/src/webrtc/stats/trackStatsBuilder.ts +207 -0
  1201. package/src/webrtc/stats/transportStats.ts +26 -0
  1202. package/src/webrtc/stats/transportStatsBuilder.ts +48 -0
  1203. package/src/webrtc/stats/valueFormatter.ts +27 -0
@@ -0,0 +1,2216 @@
1
+ /*
2
+ Copyright 2015 - 2021, 2023 The Matrix.org Foundation C.I.C.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Defines m.olm encryption/decryption
19
+ */
20
+
21
+ import { v4 as uuidv4 } from "uuid";
22
+
23
+ import type { IEventDecryptionResult, IMegolmSessionData } from "../../@types/crypto.ts";
24
+ import { logger, Logger } from "../../logger.ts";
25
+ import * as olmlib from "../olmlib.ts";
26
+ import {
27
+ DecryptionAlgorithm,
28
+ DecryptionClassParams,
29
+ EncryptionAlgorithm,
30
+ IParams,
31
+ registerAlgorithm,
32
+ UnknownDeviceError,
33
+ } from "./base.ts";
34
+ import { IDecryptedGroupMessage, WITHHELD_MESSAGES } from "../OlmDevice.ts";
35
+ import { Room } from "../../models/room.ts";
36
+ import { DeviceInfo } from "../deviceinfo.ts";
37
+ import { IOlmSessionResult } from "../olmlib.ts";
38
+ import { DeviceInfoMap } from "../DeviceList.ts";
39
+ import { IContent, MatrixEvent } from "../../models/event.ts";
40
+ import { EventType, MsgType, ToDeviceMessageId } from "../../@types/event.ts";
41
+ import { IMegolmEncryptedContent, IncomingRoomKeyRequest, IEncryptedContent } from "../index.ts";
42
+ import { RoomKeyRequestState } from "../OutgoingRoomKeyRequestManager.ts";
43
+ import { OlmGroupSessionExtraData } from "../../@types/crypto.ts";
44
+ import { MatrixError } from "../../http-api/index.ts";
45
+ import { immediate, MapWithDefault } from "../../utils.ts";
46
+ import { KnownMembership } from "../../@types/membership.ts";
47
+ import { DecryptionFailureCode } from "../../crypto-api/index.ts";
48
+ import { DecryptionError } from "../../common-crypto/CryptoBackend.ts";
49
+
50
+ // determine whether the key can be shared with invitees
51
+ export function isRoomSharedHistory(room: Room): boolean {
52
+ const visibilityEvent = room?.currentState?.getStateEvents("m.room.history_visibility", "");
53
+ // NOTE: if the room visibility is unset, it would normally default to
54
+ // "world_readable".
55
+ // (https://spec.matrix.org/unstable/client-server-api/#server-behaviour-5)
56
+ // But we will be paranoid here, and treat it as a situation where the room
57
+ // is not shared-history
58
+ const visibility = visibilityEvent?.getContent()?.history_visibility;
59
+ return ["world_readable", "shared"].includes(visibility);
60
+ }
61
+
62
+ interface IBlockedDevice {
63
+ code: string;
64
+ reason: string;
65
+ deviceInfo: DeviceInfo;
66
+ }
67
+
68
+ // map user Id → device Id → IBlockedDevice
69
+ type BlockedMap = Map<string, Map<string, IBlockedDevice>>;
70
+
71
+ export interface IOlmDevice<T = DeviceInfo> {
72
+ userId: string;
73
+ deviceInfo: T;
74
+ }
75
+
76
+ /**
77
+ * Tests whether an encrypted content has a ciphertext.
78
+ * Ciphertext can be a string or object depending on the content type {@link IEncryptedContent}.
79
+ *
80
+ * @param content - Encrypted content
81
+ * @returns true: has ciphertext, else false
82
+ */
83
+ const hasCiphertext = (content: IEncryptedContent): boolean => {
84
+ return typeof content.ciphertext === "string"
85
+ ? !!content.ciphertext.length
86
+ : !!Object.keys(content.ciphertext).length;
87
+ };
88
+
89
+ /** The result of parsing the an `m.room_key` or `m.forwarded_room_key` to-device event */
90
+ interface RoomKey {
91
+ /**
92
+ * The Curve25519 key of the megolm session creator.
93
+ *
94
+ * For `m.room_key`, this is also the sender of the `m.room_key` to-device event.
95
+ * For `m.forwarded_room_key`, the two are different (and the key of the sender of the
96
+ * `m.forwarded_room_key` event is included in `forwardingKeyChain`)
97
+ */
98
+ senderKey: string;
99
+ sessionId: string;
100
+ sessionKey: string;
101
+ exportFormat: boolean;
102
+ roomId: string;
103
+ algorithm: string;
104
+ /**
105
+ * A list of the curve25519 keys of the users involved in forwarding this key, most recent last.
106
+ * For `m.room_key` events, this is empty.
107
+ */
108
+ forwardingKeyChain: string[];
109
+ keysClaimed: Partial<Record<"ed25519", string>>;
110
+ extraSessionData: OlmGroupSessionExtraData;
111
+ }
112
+
113
+ export interface IOutboundGroupSessionKey {
114
+ chain_index: number;
115
+ key: string;
116
+ }
117
+
118
+ interface IMessage {
119
+ type: string;
120
+ content: {
121
+ "algorithm": string;
122
+ "room_id": string;
123
+ "sender_key"?: string;
124
+ "sender_claimed_ed25519_key"?: string;
125
+ "session_id": string;
126
+ "session_key": string;
127
+ "chain_index": number;
128
+ "forwarding_curve25519_key_chain"?: string[];
129
+ "org.matrix.msc3061.shared_history": boolean;
130
+ };
131
+ }
132
+
133
+ interface IKeyForwardingMessage extends IMessage {
134
+ type: "m.forwarded_room_key";
135
+ }
136
+
137
+ interface IPayload extends Partial<IMessage> {
138
+ code?: string;
139
+ reason?: string;
140
+ room_id?: string;
141
+ session_id?: string;
142
+ algorithm?: string;
143
+ sender_key?: string;
144
+ }
145
+
146
+ interface SharedWithData {
147
+ // The identity key of the device we shared with
148
+ deviceKey: string;
149
+ // The message index of the ratchet we shared with that device
150
+ messageIndex: number;
151
+ }
152
+
153
+ /**
154
+ * @internal
155
+ */
156
+ class OutboundSessionInfo {
157
+ /** number of times this session has been used */
158
+ public useCount = 0;
159
+ /** when the session was created (ms since the epoch) */
160
+ public creationTime: number;
161
+ /** devices with which we have shared the session key `userId -> {deviceId -> SharedWithData}` */
162
+ public sharedWithDevices: MapWithDefault<string, Map<string, SharedWithData>> = new MapWithDefault(() => new Map());
163
+ public blockedDevicesNotified: MapWithDefault<string, Map<string, boolean>> = new MapWithDefault(() => new Map());
164
+
165
+ /**
166
+ * @param sharedHistory - whether the session can be freely shared with
167
+ * other group members, according to the room history visibility settings
168
+ */
169
+ public constructor(
170
+ public readonly sessionId: string,
171
+ public readonly sharedHistory = false,
172
+ ) {
173
+ this.creationTime = new Date().getTime();
174
+ }
175
+
176
+ /**
177
+ * Check if it's time to rotate the session
178
+ */
179
+ public needsRotation(rotationPeriodMsgs: number, rotationPeriodMs: number): boolean {
180
+ const sessionLifetime = new Date().getTime() - this.creationTime;
181
+
182
+ if (this.useCount >= rotationPeriodMsgs || sessionLifetime >= rotationPeriodMs) {
183
+ logger.log("Rotating megolm session after " + this.useCount + " messages, " + sessionLifetime + "ms");
184
+ return true;
185
+ }
186
+
187
+ return false;
188
+ }
189
+
190
+ public markSharedWithDevice(userId: string, deviceId: string, deviceKey: string, chainIndex: number): void {
191
+ this.sharedWithDevices.getOrCreate(userId).set(deviceId, { deviceKey, messageIndex: chainIndex });
192
+ }
193
+
194
+ public markNotifiedBlockedDevice(userId: string, deviceId: string): void {
195
+ this.blockedDevicesNotified.getOrCreate(userId).set(deviceId, true);
196
+ }
197
+
198
+ /**
199
+ * Determine if this session has been shared with devices which it shouldn't
200
+ * have been.
201
+ *
202
+ * @param devicesInRoom - `userId -> {deviceId -> object}`
203
+ * devices we should shared the session with.
204
+ *
205
+ * @returns true if we have shared the session with devices which aren't
206
+ * in devicesInRoom.
207
+ */
208
+ public sharedWithTooManyDevices(devicesInRoom: DeviceInfoMap): boolean {
209
+ for (const [userId, devices] of this.sharedWithDevices) {
210
+ if (!devicesInRoom.has(userId)) {
211
+ logger.log("Starting new megolm session because we shared with " + userId);
212
+ return true;
213
+ }
214
+
215
+ for (const [deviceId] of devices) {
216
+ if (!devicesInRoom.get(userId)?.get(deviceId)) {
217
+ logger.log("Starting new megolm session because we shared with " + userId + ":" + deviceId);
218
+ return true;
219
+ }
220
+ }
221
+ }
222
+
223
+ return false;
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Megolm encryption implementation
229
+ *
230
+ * @param params - parameters, as per {@link EncryptionAlgorithm}
231
+ */
232
+ export class MegolmEncryption extends EncryptionAlgorithm {
233
+ // the most recent attempt to set up a session. This is used to serialise
234
+ // the session setups, so that we have a race-free view of which session we
235
+ // are using, and which devices we have shared the keys with. It resolves
236
+ // with an OutboundSessionInfo (or undefined, for the first message in the
237
+ // room).
238
+ private setupPromise = Promise.resolve<OutboundSessionInfo | null>(null);
239
+
240
+ // Map of outbound sessions by sessions ID. Used if we need a particular
241
+ // session (the session we're currently using to send is always obtained
242
+ // using setupPromise).
243
+ private outboundSessions: Record<string, OutboundSessionInfo> = {};
244
+
245
+ private readonly sessionRotationPeriodMsgs: number;
246
+ private readonly sessionRotationPeriodMs: number;
247
+ private encryptionPreparation?: {
248
+ promise: Promise<void>;
249
+ startTime: number;
250
+ cancel: () => void;
251
+ };
252
+
253
+ protected readonly roomId: string;
254
+ private readonly prefixedLogger: Logger;
255
+
256
+ public constructor(params: IParams & Required<Pick<IParams, "roomId">>) {
257
+ super(params);
258
+ this.roomId = params.roomId;
259
+ this.prefixedLogger = logger.getChild(`[${this.roomId} encryption]`);
260
+
261
+ this.sessionRotationPeriodMsgs = params.config?.rotation_period_msgs ?? 100;
262
+ this.sessionRotationPeriodMs = params.config?.rotation_period_ms ?? 7 * 24 * 3600 * 1000;
263
+ }
264
+
265
+ /**
266
+ * @internal
267
+ *
268
+ * @param devicesInRoom - The devices in this room, indexed by user ID
269
+ * @param blocked - The devices that are blocked, indexed by user ID
270
+ * @param singleOlmCreationPhase - Only perform one round of olm
271
+ * session creation
272
+ *
273
+ * This method updates the setupPromise field of the class by chaining a new
274
+ * call on top of the existing promise, and then catching and discarding any
275
+ * errors that might happen while setting up the outbound group session. This
276
+ * is done to ensure that `setupPromise` always resolves to `null` or the
277
+ * `OutboundSessionInfo`.
278
+ *
279
+ * Using `>>=` to represent the promise chaining operation, it does the
280
+ * following:
281
+ *
282
+ * ```
283
+ * setupPromise = previousSetupPromise >>= setup >>= discardErrors
284
+ * ```
285
+ *
286
+ * The initial value for the `setupPromise` is a promise that resolves to
287
+ * `null`. The forceDiscardSession() resets setupPromise to this initial
288
+ * promise.
289
+ *
290
+ * @returns Promise which resolves to the
291
+ * OutboundSessionInfo when setup is complete.
292
+ */
293
+ private async ensureOutboundSession(
294
+ room: Room,
295
+ devicesInRoom: DeviceInfoMap,
296
+ blocked: BlockedMap,
297
+ singleOlmCreationPhase = false,
298
+ ): Promise<OutboundSessionInfo> {
299
+ // takes the previous OutboundSessionInfo, and considers whether to create
300
+ // a new one. Also shares the key with any (new) devices in the room.
301
+ //
302
+ // returns a promise which resolves once the keyshare is successful.
303
+ const setup = async (oldSession: OutboundSessionInfo | null): Promise<OutboundSessionInfo> => {
304
+ const sharedHistory = isRoomSharedHistory(room);
305
+ const session = await this.prepareSession(devicesInRoom, sharedHistory, oldSession);
306
+
307
+ await this.shareSession(devicesInRoom, sharedHistory, singleOlmCreationPhase, blocked, session);
308
+
309
+ return session;
310
+ };
311
+
312
+ // first wait for the previous share to complete
313
+ const fallible = this.setupPromise.then(setup);
314
+
315
+ // Ensure any failures are logged for debugging and make sure that the
316
+ // promise chain remains unbroken
317
+ //
318
+ // setupPromise resolves to `null` or the `OutboundSessionInfo` whether
319
+ // or not the share succeeds
320
+ this.setupPromise = fallible.catch((e) => {
321
+ this.prefixedLogger.error(`Failed to setup outbound session`, e);
322
+ return null;
323
+ });
324
+
325
+ // but we return a promise which only resolves if the share was successful.
326
+ return fallible;
327
+ }
328
+
329
+ private async prepareSession(
330
+ devicesInRoom: DeviceInfoMap,
331
+ sharedHistory: boolean,
332
+ session: OutboundSessionInfo | null,
333
+ ): Promise<OutboundSessionInfo> {
334
+ // history visibility changed
335
+ if (session && sharedHistory !== session.sharedHistory) {
336
+ session = null;
337
+ }
338
+
339
+ // need to make a brand new session?
340
+ if (session?.needsRotation(this.sessionRotationPeriodMsgs, this.sessionRotationPeriodMs)) {
341
+ this.prefixedLogger.debug("Starting new megolm session because we need to rotate.");
342
+ session = null;
343
+ }
344
+
345
+ // determine if we have shared with anyone we shouldn't have
346
+ if (session?.sharedWithTooManyDevices(devicesInRoom)) {
347
+ session = null;
348
+ }
349
+
350
+ if (!session) {
351
+ this.prefixedLogger.debug("Starting new megolm session");
352
+ session = await this.prepareNewSession(sharedHistory);
353
+ this.prefixedLogger.debug(`Started new megolm session ${session.sessionId}`);
354
+ this.outboundSessions[session.sessionId] = session;
355
+ }
356
+
357
+ return session;
358
+ }
359
+
360
+ private async shareSession(
361
+ devicesInRoom: DeviceInfoMap,
362
+ sharedHistory: boolean,
363
+ singleOlmCreationPhase: boolean,
364
+ blocked: BlockedMap,
365
+ session: OutboundSessionInfo,
366
+ ): Promise<void> {
367
+ // now check if we need to share with any devices
368
+ const shareMap: Record<string, DeviceInfo[]> = {};
369
+
370
+ for (const [userId, userDevices] of devicesInRoom) {
371
+ for (const [deviceId, deviceInfo] of userDevices) {
372
+ const key = deviceInfo.getIdentityKey();
373
+ if (key == this.olmDevice.deviceCurve25519Key) {
374
+ // don't bother sending to ourself
375
+ continue;
376
+ }
377
+
378
+ if (!session.sharedWithDevices.get(userId)?.get(deviceId)) {
379
+ shareMap[userId] = shareMap[userId] || [];
380
+ shareMap[userId].push(deviceInfo);
381
+ }
382
+ }
383
+ }
384
+
385
+ const key = this.olmDevice.getOutboundGroupSessionKey(session.sessionId);
386
+ const payload: IPayload = {
387
+ type: "m.room_key",
388
+ content: {
389
+ "algorithm": olmlib.MEGOLM_ALGORITHM,
390
+ "room_id": this.roomId,
391
+ "session_id": session.sessionId,
392
+ "session_key": key.key,
393
+ "chain_index": key.chain_index,
394
+ "org.matrix.msc3061.shared_history": sharedHistory,
395
+ },
396
+ };
397
+ const [devicesWithoutSession, olmSessions] = await olmlib.getExistingOlmSessions(
398
+ this.olmDevice,
399
+ this.baseApis,
400
+ shareMap,
401
+ );
402
+
403
+ await Promise.all([
404
+ (async (): Promise<void> => {
405
+ // share keys with devices that we already have a session for
406
+ const olmSessionList = Array.from(olmSessions.entries())
407
+ .map(([userId, sessionsByUser]) =>
408
+ Array.from(sessionsByUser.entries()).map(
409
+ ([deviceId, session]) => `${userId}/${deviceId}: ${session.sessionId}`,
410
+ ),
411
+ )
412
+ .flat(1);
413
+ this.prefixedLogger.debug("Sharing keys with devices with existing Olm sessions:", olmSessionList);
414
+ await this.shareKeyWithOlmSessions(session, key, payload, olmSessions);
415
+ this.prefixedLogger.debug("Shared keys with existing Olm sessions");
416
+ })(),
417
+ (async (): Promise<void> => {
418
+ const deviceList = Array.from(devicesWithoutSession.entries())
419
+ .map(([userId, devicesByUser]) => devicesByUser.map((device) => `${userId}/${device.deviceId}`))
420
+ .flat(1);
421
+ this.prefixedLogger.debug(
422
+ "Sharing keys (start phase 1) with devices without existing Olm sessions:",
423
+ deviceList,
424
+ );
425
+ const errorDevices: IOlmDevice[] = [];
426
+
427
+ // meanwhile, establish olm sessions for devices that we don't
428
+ // already have a session for, and share keys with them. If
429
+ // we're doing two phases of olm session creation, use a
430
+ // shorter timeout when fetching one-time keys for the first
431
+ // phase.
432
+ const start = Date.now();
433
+ const failedServers: string[] = [];
434
+ await this.shareKeyWithDevices(
435
+ session,
436
+ key,
437
+ payload,
438
+ devicesWithoutSession,
439
+ errorDevices,
440
+ singleOlmCreationPhase ? 10000 : 2000,
441
+ failedServers,
442
+ );
443
+ this.prefixedLogger.debug("Shared keys (end phase 1) with devices without existing Olm sessions");
444
+
445
+ if (!singleOlmCreationPhase && Date.now() - start < 10000) {
446
+ // perform the second phase of olm session creation if requested,
447
+ // and if the first phase didn't take too long
448
+ (async (): Promise<void> => {
449
+ // Retry sending keys to devices that we were unable to establish
450
+ // an olm session for. This time, we use a longer timeout, but we
451
+ // do this in the background and don't block anything else while we
452
+ // do this. We only need to retry users from servers that didn't
453
+ // respond the first time.
454
+ const retryDevices: MapWithDefault<string, DeviceInfo[]> = new MapWithDefault(() => []);
455
+ const failedServerMap = new Set();
456
+ for (const server of failedServers) {
457
+ failedServerMap.add(server);
458
+ }
459
+ const failedDevices: IOlmDevice[] = [];
460
+ for (const { userId, deviceInfo } of errorDevices) {
461
+ const userHS = userId.slice(userId.indexOf(":") + 1);
462
+ if (failedServerMap.has(userHS)) {
463
+ retryDevices.getOrCreate(userId).push(deviceInfo);
464
+ } else {
465
+ // if we aren't going to retry, then handle it
466
+ // as a failed device
467
+ failedDevices.push({ userId, deviceInfo });
468
+ }
469
+ }
470
+
471
+ const retryDeviceList = Array.from(retryDevices.entries())
472
+ .map(([userId, devicesByUser]) =>
473
+ devicesByUser.map((device) => `${userId}/${device.deviceId}`),
474
+ )
475
+ .flat(1);
476
+
477
+ if (retryDeviceList.length > 0) {
478
+ this.prefixedLogger.debug(
479
+ "Sharing keys (start phase 2) with devices without existing Olm sessions:",
480
+ retryDeviceList,
481
+ );
482
+ await this.shareKeyWithDevices(session, key, payload, retryDevices, failedDevices, 30000);
483
+ this.prefixedLogger.debug(
484
+ "Shared keys (end phase 2) with devices without existing Olm sessions",
485
+ );
486
+ }
487
+
488
+ await this.notifyFailedOlmDevices(session, key, failedDevices);
489
+ })();
490
+ } else {
491
+ await this.notifyFailedOlmDevices(session, key, errorDevices);
492
+ }
493
+ })(),
494
+ (async (): Promise<void> => {
495
+ this.prefixedLogger.debug(
496
+ `There are ${blocked.size} blocked devices:`,
497
+ Array.from(blocked.entries())
498
+ .map(([userId, blockedByUser]) =>
499
+ Array.from(blockedByUser.entries()).map(
500
+ ([deviceId, _deviceInfo]) => `${userId}/${deviceId}`,
501
+ ),
502
+ )
503
+ .flat(1),
504
+ );
505
+
506
+ // also, notify newly blocked devices that they're blocked
507
+ const blockedMap: MapWithDefault<string, Map<string, { device: IBlockedDevice }>> = new MapWithDefault(
508
+ () => new Map(),
509
+ );
510
+ let blockedCount = 0;
511
+ for (const [userId, userBlockedDevices] of blocked) {
512
+ for (const [deviceId, device] of userBlockedDevices) {
513
+ if (session.blockedDevicesNotified.get(userId)?.get(deviceId) === undefined) {
514
+ blockedMap.getOrCreate(userId).set(deviceId, { device });
515
+ blockedCount++;
516
+ }
517
+ }
518
+ }
519
+
520
+ if (blockedCount) {
521
+ this.prefixedLogger.debug(
522
+ `Notifying ${blockedCount} newly blocked devices:`,
523
+ Array.from(blockedMap.entries())
524
+ .map(([userId, blockedByUser]) =>
525
+ Object.entries(blockedByUser).map(([deviceId, _deviceInfo]) => `${userId}/${deviceId}`),
526
+ )
527
+ .flat(1),
528
+ );
529
+ await this.notifyBlockedDevices(session, blockedMap);
530
+ this.prefixedLogger.debug(`Notified ${blockedCount} newly blocked devices`);
531
+ }
532
+ })(),
533
+ ]);
534
+ }
535
+
536
+ /**
537
+ * @internal
538
+ *
539
+ *
540
+ * @returns session
541
+ */
542
+ private async prepareNewSession(sharedHistory: boolean): Promise<OutboundSessionInfo> {
543
+ const sessionId = this.olmDevice.createOutboundGroupSession();
544
+ const key = this.olmDevice.getOutboundGroupSessionKey(sessionId);
545
+
546
+ await this.olmDevice.addInboundGroupSession(
547
+ this.roomId,
548
+ this.olmDevice.deviceCurve25519Key!,
549
+ [],
550
+ sessionId,
551
+ key.key,
552
+ { ed25519: this.olmDevice.deviceEd25519Key! },
553
+ false,
554
+ { sharedHistory },
555
+ );
556
+
557
+ // don't wait for it to complete
558
+ this.crypto.backupManager.backupGroupSession(this.olmDevice.deviceCurve25519Key!, sessionId);
559
+
560
+ return new OutboundSessionInfo(sessionId, sharedHistory);
561
+ }
562
+
563
+ /**
564
+ * Determines what devices in devicesByUser don't have an olm session as given
565
+ * in devicemap.
566
+ *
567
+ * @internal
568
+ *
569
+ * @param deviceMap - the devices that have olm sessions, as returned by
570
+ * olmlib.ensureOlmSessionsForDevices.
571
+ * @param devicesByUser - a map of user IDs to array of deviceInfo
572
+ * @param noOlmDevices - an array to fill with devices that don't have
573
+ * olm sessions
574
+ *
575
+ * @returns an array of devices that don't have olm sessions. If
576
+ * noOlmDevices is specified, then noOlmDevices will be returned.
577
+ */
578
+ private getDevicesWithoutSessions(
579
+ deviceMap: Map<string, Map<string, IOlmSessionResult>>,
580
+ devicesByUser: Map<string, DeviceInfo[]>,
581
+ noOlmDevices: IOlmDevice[] = [],
582
+ ): IOlmDevice[] {
583
+ for (const [userId, devicesToShareWith] of devicesByUser) {
584
+ const sessionResults = deviceMap.get(userId);
585
+
586
+ for (const deviceInfo of devicesToShareWith) {
587
+ const deviceId = deviceInfo.deviceId;
588
+
589
+ const sessionResult = sessionResults?.get(deviceId);
590
+ if (!sessionResult?.sessionId) {
591
+ // no session with this device, probably because there
592
+ // were no one-time keys.
593
+
594
+ noOlmDevices.push({ userId, deviceInfo });
595
+ sessionResults?.delete(deviceId);
596
+
597
+ // ensureOlmSessionsForUsers has already done the logging,
598
+ // so just skip it.
599
+ continue;
600
+ }
601
+ }
602
+ }
603
+
604
+ return noOlmDevices;
605
+ }
606
+
607
+ /**
608
+ * Splits the user device map into multiple chunks to reduce the number of
609
+ * devices we encrypt to per API call.
610
+ *
611
+ * @internal
612
+ *
613
+ * @param devicesByUser - map from userid to list of devices
614
+ *
615
+ * @returns the blocked devices, split into chunks
616
+ */
617
+ private splitDevices<T extends DeviceInfo | IBlockedDevice>(
618
+ devicesByUser: Map<string, Map<string, { device: T }>>,
619
+ ): IOlmDevice<T>[][] {
620
+ const maxDevicesPerRequest = 20;
621
+
622
+ // use an array where the slices of a content map gets stored
623
+ let currentSlice: IOlmDevice<T>[] = [];
624
+ const mapSlices = [currentSlice];
625
+
626
+ for (const [userId, userDevices] of devicesByUser) {
627
+ for (const deviceInfo of userDevices.values()) {
628
+ currentSlice.push({
629
+ userId: userId,
630
+ deviceInfo: deviceInfo.device,
631
+ });
632
+ }
633
+
634
+ // We do this in the per-user loop as we prefer that all messages to the
635
+ // same user end up in the same API call to make it easier for the
636
+ // server (e.g. only have to send one EDU if a remote user, etc). This
637
+ // does mean that if a user has many devices we may go over the desired
638
+ // limit, but its not a hard limit so that is fine.
639
+ if (currentSlice.length > maxDevicesPerRequest) {
640
+ // the current slice is filled up. Start inserting into the next slice
641
+ currentSlice = [];
642
+ mapSlices.push(currentSlice);
643
+ }
644
+ }
645
+ if (currentSlice.length === 0) {
646
+ mapSlices.pop();
647
+ }
648
+ return mapSlices;
649
+ }
650
+
651
+ /**
652
+ * @internal
653
+ *
654
+ *
655
+ * @param chainIndex - current chain index
656
+ *
657
+ * @param userDeviceMap - mapping from userId to deviceInfo
658
+ *
659
+ * @param payload - fields to include in the encrypted payload
660
+ *
661
+ * @returns Promise which resolves once the key sharing
662
+ * for the given userDeviceMap is generated and has been sent.
663
+ */
664
+ private encryptAndSendKeysToDevices(
665
+ session: OutboundSessionInfo,
666
+ chainIndex: number,
667
+ devices: IOlmDevice[],
668
+ payload: IPayload,
669
+ ): Promise<void> {
670
+ return this.crypto
671
+ .encryptAndSendToDevices(devices, payload)
672
+ .then(() => {
673
+ // store that we successfully uploaded the keys of the current slice
674
+ for (const device of devices) {
675
+ session.markSharedWithDevice(
676
+ device.userId,
677
+ device.deviceInfo.deviceId,
678
+ device.deviceInfo.getIdentityKey(),
679
+ chainIndex,
680
+ );
681
+ }
682
+ })
683
+ .catch((error) => {
684
+ this.prefixedLogger.error("failed to encryptAndSendToDevices", error);
685
+ throw error;
686
+ });
687
+ }
688
+
689
+ /**
690
+ * @internal
691
+ *
692
+ *
693
+ * @param userDeviceMap - list of blocked devices to notify
694
+ *
695
+ * @param payload - fields to include in the notification payload
696
+ *
697
+ * @returns Promise which resolves once the notifications
698
+ * for the given userDeviceMap is generated and has been sent.
699
+ */
700
+ private async sendBlockedNotificationsToDevices(
701
+ session: OutboundSessionInfo,
702
+ userDeviceMap: IOlmDevice<IBlockedDevice>[],
703
+ payload: IPayload,
704
+ ): Promise<void> {
705
+ const contentMap: MapWithDefault<string, Map<string, IPayload>> = new MapWithDefault(() => new Map());
706
+
707
+ for (const val of userDeviceMap) {
708
+ const userId = val.userId;
709
+ const blockedInfo = val.deviceInfo;
710
+ const deviceInfo = blockedInfo.deviceInfo;
711
+ const deviceId = deviceInfo.deviceId;
712
+
713
+ const message = {
714
+ ...payload,
715
+ code: blockedInfo.code,
716
+ reason: blockedInfo.reason,
717
+ [ToDeviceMessageId]: uuidv4(),
718
+ };
719
+
720
+ if (message.code === "m.no_olm") {
721
+ delete message.room_id;
722
+ delete message.session_id;
723
+ }
724
+
725
+ contentMap.getOrCreate(userId).set(deviceId, message);
726
+ }
727
+
728
+ await this.baseApis.sendToDevice("m.room_key.withheld", contentMap);
729
+
730
+ // record the fact that we notified these blocked devices
731
+ for (const [userId, userDeviceMap] of contentMap) {
732
+ for (const deviceId of userDeviceMap.keys()) {
733
+ session.markNotifiedBlockedDevice(userId, deviceId);
734
+ }
735
+ }
736
+ }
737
+
738
+ /**
739
+ * Re-shares a megolm session key with devices if the key has already been
740
+ * sent to them.
741
+ *
742
+ * @param senderKey - The key of the originating device for the session
743
+ * @param sessionId - ID of the outbound session to share
744
+ * @param userId - ID of the user who owns the target device
745
+ * @param device - The target device
746
+ */
747
+ public async reshareKeyWithDevice(
748
+ senderKey: string,
749
+ sessionId: string,
750
+ userId: string,
751
+ device: DeviceInfo,
752
+ ): Promise<void> {
753
+ const obSessionInfo = this.outboundSessions[sessionId];
754
+ if (!obSessionInfo) {
755
+ this.prefixedLogger.debug(`megolm session ${senderKey}|${sessionId} not found: not re-sharing keys`);
756
+ return;
757
+ }
758
+
759
+ // The chain index of the key we previously sent this device
760
+ if (!obSessionInfo.sharedWithDevices.has(userId)) {
761
+ this.prefixedLogger.debug(`megolm session ${senderKey}|${sessionId} never shared with user ${userId}`);
762
+ return;
763
+ }
764
+ const sessionSharedData = obSessionInfo.sharedWithDevices.get(userId)?.get(device.deviceId);
765
+ if (sessionSharedData === undefined) {
766
+ this.prefixedLogger.debug(
767
+ `megolm session ${senderKey}|${sessionId} never shared with device ${userId}:${device.deviceId}`,
768
+ );
769
+ return;
770
+ }
771
+
772
+ if (sessionSharedData.deviceKey !== device.getIdentityKey()) {
773
+ this.prefixedLogger.warn(
774
+ `Megolm session ${senderKey}|${sessionId} has been shared with device ${device.deviceId} but ` +
775
+ `with identity key ${sessionSharedData.deviceKey}. Key is now ${device.getIdentityKey()}!`,
776
+ );
777
+ return;
778
+ }
779
+
780
+ // get the key from the inbound session: the outbound one will already
781
+ // have been ratcheted to the next chain index.
782
+ const key = await this.olmDevice.getInboundGroupSessionKey(
783
+ this.roomId,
784
+ senderKey,
785
+ sessionId,
786
+ sessionSharedData.messageIndex,
787
+ );
788
+
789
+ if (!key) {
790
+ this.prefixedLogger.warn(
791
+ `No inbound session key found for megolm session ${senderKey}|${sessionId}: not re-sharing keys`,
792
+ );
793
+ return;
794
+ }
795
+
796
+ await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, new Map([[userId, [device]]]));
797
+
798
+ const payload = {
799
+ type: "m.forwarded_room_key",
800
+ content: {
801
+ "algorithm": olmlib.MEGOLM_ALGORITHM,
802
+ "room_id": this.roomId,
803
+ "session_id": sessionId,
804
+ "session_key": key.key,
805
+ "chain_index": key.chain_index,
806
+ "sender_key": senderKey,
807
+ "sender_claimed_ed25519_key": key.sender_claimed_ed25519_key,
808
+ "forwarding_curve25519_key_chain": key.forwarding_curve25519_key_chain,
809
+ "org.matrix.msc3061.shared_history": key.shared_history || false,
810
+ },
811
+ };
812
+
813
+ const encryptedContent: IEncryptedContent = {
814
+ algorithm: olmlib.OLM_ALGORITHM,
815
+ sender_key: this.olmDevice.deviceCurve25519Key!,
816
+ ciphertext: {},
817
+ [ToDeviceMessageId]: uuidv4(),
818
+ };
819
+ await olmlib.encryptMessageForDevice(
820
+ encryptedContent.ciphertext,
821
+ this.userId,
822
+ this.deviceId,
823
+ this.olmDevice,
824
+ userId,
825
+ device,
826
+ payload,
827
+ );
828
+
829
+ await this.baseApis.sendToDevice(
830
+ "m.room.encrypted",
831
+ new Map([[userId, new Map([[device.deviceId, encryptedContent]])]]),
832
+ );
833
+ this.prefixedLogger.debug(
834
+ `Re-shared key for megolm session ${senderKey}|${sessionId} with ${userId}:${device.deviceId}`,
835
+ );
836
+ }
837
+
838
+ /**
839
+ * @internal
840
+ *
841
+ *
842
+ * @param key - the session key as returned by
843
+ * OlmDevice.getOutboundGroupSessionKey
844
+ *
845
+ * @param payload - the base to-device message payload for sharing keys
846
+ *
847
+ * @param devicesByUser - map from userid to list of devices
848
+ *
849
+ * @param errorDevices - array that will be populated with the devices that we can't get an
850
+ * olm session for
851
+ *
852
+ * @param otkTimeout - The timeout in milliseconds when requesting
853
+ * one-time keys for establishing new olm sessions.
854
+ *
855
+ * @param failedServers - An array to fill with remote servers that
856
+ * failed to respond to one-time-key requests.
857
+ */
858
+ private async shareKeyWithDevices(
859
+ session: OutboundSessionInfo,
860
+ key: IOutboundGroupSessionKey,
861
+ payload: IPayload,
862
+ devicesByUser: Map<string, DeviceInfo[]>,
863
+ errorDevices: IOlmDevice[],
864
+ otkTimeout: number,
865
+ failedServers?: string[],
866
+ ): Promise<void> {
867
+ const devicemap = await olmlib.ensureOlmSessionsForDevices(
868
+ this.olmDevice,
869
+ this.baseApis,
870
+ devicesByUser,
871
+ false,
872
+ otkTimeout,
873
+ failedServers,
874
+ this.prefixedLogger,
875
+ );
876
+ this.getDevicesWithoutSessions(devicemap, devicesByUser, errorDevices);
877
+ await this.shareKeyWithOlmSessions(session, key, payload, devicemap);
878
+ }
879
+
880
+ private async shareKeyWithOlmSessions(
881
+ session: OutboundSessionInfo,
882
+ key: IOutboundGroupSessionKey,
883
+ payload: IPayload,
884
+ deviceMap: Map<string, Map<string, IOlmSessionResult>>,
885
+ ): Promise<void> {
886
+ const userDeviceMaps = this.splitDevices(deviceMap);
887
+
888
+ for (let i = 0; i < userDeviceMaps.length; i++) {
889
+ const taskDetail = `megolm keys for ${session.sessionId} (slice ${i + 1}/${userDeviceMaps.length})`;
890
+ try {
891
+ this.prefixedLogger.debug(
892
+ `Sharing ${taskDetail}`,
893
+ userDeviceMaps[i].map((d) => `${d.userId}/${d.deviceInfo.deviceId}`),
894
+ );
895
+ await this.encryptAndSendKeysToDevices(session, key.chain_index, userDeviceMaps[i], payload);
896
+ this.prefixedLogger.debug(`Shared ${taskDetail}`);
897
+ } catch (e) {
898
+ this.prefixedLogger.error(`Failed to share ${taskDetail}`);
899
+ throw e;
900
+ }
901
+ }
902
+ }
903
+
904
+ /**
905
+ * Notify devices that we weren't able to create olm sessions.
906
+ *
907
+ *
908
+ *
909
+ * @param failedDevices - the devices that we were unable to
910
+ * create olm sessions for, as returned by shareKeyWithDevices
911
+ */
912
+ private async notifyFailedOlmDevices(
913
+ session: OutboundSessionInfo,
914
+ key: IOutboundGroupSessionKey,
915
+ failedDevices: IOlmDevice[],
916
+ ): Promise<void> {
917
+ this.prefixedLogger.debug(`Notifying ${failedDevices.length} devices we failed to create Olm sessions`);
918
+
919
+ // mark the devices that failed as "handled" because we don't want to try
920
+ // to claim a one-time-key for dead devices on every message.
921
+ for (const { userId, deviceInfo } of failedDevices) {
922
+ const deviceId = deviceInfo.deviceId;
923
+
924
+ session.markSharedWithDevice(userId, deviceId, deviceInfo.getIdentityKey(), key.chain_index);
925
+ }
926
+
927
+ const unnotifiedFailedDevices = await this.olmDevice.filterOutNotifiedErrorDevices(failedDevices);
928
+ this.prefixedLogger.debug(
929
+ `Need to notify ${unnotifiedFailedDevices.length} failed devices which haven't been notified before`,
930
+ );
931
+ const blockedMap: MapWithDefault<string, Map<string, { device: IBlockedDevice }>> = new MapWithDefault(
932
+ () => new Map(),
933
+ );
934
+ for (const { userId, deviceInfo } of unnotifiedFailedDevices) {
935
+ // we use a similar format to what
936
+ // olmlib.ensureOlmSessionsForDevices returns, so that
937
+ // we can use the same function to split
938
+ blockedMap.getOrCreate(userId).set(deviceInfo.deviceId, {
939
+ device: {
940
+ code: "m.no_olm",
941
+ reason: WITHHELD_MESSAGES["m.no_olm"],
942
+ deviceInfo,
943
+ },
944
+ });
945
+ }
946
+
947
+ // send the notifications
948
+ await this.notifyBlockedDevices(session, blockedMap);
949
+ this.prefixedLogger.debug(
950
+ `Notified ${unnotifiedFailedDevices.length} devices we failed to create Olm sessions`,
951
+ );
952
+ }
953
+
954
+ /**
955
+ * Notify blocked devices that they have been blocked.
956
+ *
957
+ *
958
+ * @param devicesByUser - map from userid to device ID to blocked data
959
+ */
960
+ private async notifyBlockedDevices(
961
+ session: OutboundSessionInfo,
962
+ devicesByUser: Map<string, Map<string, { device: IBlockedDevice }>>,
963
+ ): Promise<void> {
964
+ const payload: IPayload = {
965
+ room_id: this.roomId,
966
+ session_id: session.sessionId,
967
+ algorithm: olmlib.MEGOLM_ALGORITHM,
968
+ sender_key: this.olmDevice.deviceCurve25519Key!,
969
+ };
970
+
971
+ const userDeviceMaps = this.splitDevices(devicesByUser);
972
+
973
+ for (let i = 0; i < userDeviceMaps.length; i++) {
974
+ try {
975
+ await this.sendBlockedNotificationsToDevices(session, userDeviceMaps[i], payload);
976
+ this.prefixedLogger.debug(
977
+ `Completed blacklist notification for ${session.sessionId} ` +
978
+ `(slice ${i + 1}/${userDeviceMaps.length})`,
979
+ );
980
+ } catch (e) {
981
+ this.prefixedLogger.debug(
982
+ `blacklist notification for ${session.sessionId} ` +
983
+ `(slice ${i + 1}/${userDeviceMaps.length}) failed`,
984
+ );
985
+
986
+ throw e;
987
+ }
988
+ }
989
+ }
990
+
991
+ /**
992
+ * Perform any background tasks that can be done before a message is ready to
993
+ * send, in order to speed up sending of the message.
994
+ *
995
+ * @param room - the room the event is in
996
+ * @returns A function that, when called, will stop the preparation
997
+ */
998
+ public prepareToEncrypt(room: Room): () => void {
999
+ if (room.roomId !== this.roomId) {
1000
+ throw new Error("MegolmEncryption.prepareToEncrypt called on unexpected room");
1001
+ }
1002
+
1003
+ if (this.encryptionPreparation != null) {
1004
+ // We're already preparing something, so don't do anything else.
1005
+ const elapsedTime = Date.now() - this.encryptionPreparation.startTime;
1006
+ this.prefixedLogger.debug(
1007
+ `Already started preparing to encrypt for this room ${elapsedTime}ms ago, skipping`,
1008
+ );
1009
+ return this.encryptionPreparation.cancel;
1010
+ }
1011
+
1012
+ this.prefixedLogger.debug("Preparing to encrypt events");
1013
+
1014
+ let cancelled = false;
1015
+ const isCancelled = (): boolean => cancelled;
1016
+
1017
+ this.encryptionPreparation = {
1018
+ startTime: Date.now(),
1019
+ promise: (async (): Promise<void> => {
1020
+ try {
1021
+ // Attempt to enumerate the devices in room, and gracefully
1022
+ // handle cancellation if it occurs.
1023
+ const getDevicesResult = await this.getDevicesInRoom(room, false, isCancelled);
1024
+ if (getDevicesResult === null) return;
1025
+ const [devicesInRoom, blocked] = getDevicesResult;
1026
+
1027
+ if (this.crypto.globalErrorOnUnknownDevices) {
1028
+ // Drop unknown devices for now. When the message gets sent, we'll
1029
+ // throw an error, but we'll still be prepared to send to the known
1030
+ // devices.
1031
+ this.removeUnknownDevices(devicesInRoom);
1032
+ }
1033
+
1034
+ this.prefixedLogger.debug("Ensuring outbound megolm session");
1035
+ await this.ensureOutboundSession(room, devicesInRoom, blocked, true);
1036
+
1037
+ this.prefixedLogger.debug("Ready to encrypt events");
1038
+ } catch (e) {
1039
+ this.prefixedLogger.error("Failed to prepare to encrypt events", e);
1040
+ } finally {
1041
+ delete this.encryptionPreparation;
1042
+ }
1043
+ })(),
1044
+
1045
+ cancel: (): void => {
1046
+ // The caller has indicated that the process should be cancelled,
1047
+ // so tell the promise that we'd like to halt, and reset the preparation state.
1048
+ cancelled = true;
1049
+ delete this.encryptionPreparation;
1050
+ },
1051
+ };
1052
+
1053
+ return this.encryptionPreparation.cancel;
1054
+ }
1055
+
1056
+ /**
1057
+ * @param content - plaintext event content
1058
+ *
1059
+ * @returns Promise which resolves to the new event body
1060
+ */
1061
+ public async encryptMessage(room: Room, eventType: string, content: IContent): Promise<IMegolmEncryptedContent> {
1062
+ this.prefixedLogger.debug("Starting to encrypt event");
1063
+
1064
+ if (this.encryptionPreparation != null) {
1065
+ // If we started sending keys, wait for it to be done.
1066
+ // FIXME: check if we need to cancel
1067
+ // (https://github.com/matrix-org/matrix-js-sdk/issues/1255)
1068
+ try {
1069
+ await this.encryptionPreparation.promise;
1070
+ } catch {
1071
+ // ignore any errors -- if the preparation failed, we'll just
1072
+ // restart everything here
1073
+ }
1074
+ }
1075
+
1076
+ /**
1077
+ * When using in-room messages and the room has encryption enabled,
1078
+ * clients should ensure that encryption does not hinder the verification.
1079
+ */
1080
+ const forceDistributeToUnverified = this.isVerificationEvent(eventType, content);
1081
+ const [devicesInRoom, blocked] = await this.getDevicesInRoom(room, forceDistributeToUnverified);
1082
+
1083
+ // check if any of these devices are not yet known to the user.
1084
+ // if so, warn the user so they can verify or ignore.
1085
+ if (this.crypto.globalErrorOnUnknownDevices) {
1086
+ this.checkForUnknownDevices(devicesInRoom);
1087
+ }
1088
+
1089
+ const session = await this.ensureOutboundSession(room, devicesInRoom, blocked);
1090
+ const payloadJson = {
1091
+ room_id: this.roomId,
1092
+ type: eventType,
1093
+ content: content,
1094
+ };
1095
+
1096
+ const ciphertext = this.olmDevice.encryptGroupMessage(session.sessionId, JSON.stringify(payloadJson));
1097
+ const encryptedContent: IEncryptedContent = {
1098
+ algorithm: olmlib.MEGOLM_ALGORITHM,
1099
+ sender_key: this.olmDevice.deviceCurve25519Key!,
1100
+ ciphertext: ciphertext,
1101
+ session_id: session.sessionId,
1102
+ // Include our device ID so that recipients can send us a
1103
+ // m.new_device message if they don't have our session key.
1104
+ // XXX: Do we still need this now that m.new_device messages
1105
+ // no longer exist since #483?
1106
+ device_id: this.deviceId,
1107
+ };
1108
+
1109
+ session.useCount++;
1110
+ return encryptedContent;
1111
+ }
1112
+
1113
+ private isVerificationEvent(eventType: string, content: IContent): boolean {
1114
+ switch (eventType) {
1115
+ case EventType.KeyVerificationCancel:
1116
+ case EventType.KeyVerificationDone:
1117
+ case EventType.KeyVerificationMac:
1118
+ case EventType.KeyVerificationStart:
1119
+ case EventType.KeyVerificationKey:
1120
+ case EventType.KeyVerificationReady:
1121
+ case EventType.KeyVerificationAccept: {
1122
+ return true;
1123
+ }
1124
+ case EventType.RoomMessage: {
1125
+ return content["msgtype"] === MsgType.KeyVerificationRequest;
1126
+ }
1127
+ default: {
1128
+ return false;
1129
+ }
1130
+ }
1131
+ }
1132
+
1133
+ /**
1134
+ * Forces the current outbound group session to be discarded such
1135
+ * that another one will be created next time an event is sent.
1136
+ *
1137
+ * This should not normally be necessary.
1138
+ */
1139
+ public forceDiscardSession(): void {
1140
+ this.setupPromise = this.setupPromise.then(() => null);
1141
+ }
1142
+
1143
+ /**
1144
+ * Checks the devices we're about to send to and see if any are entirely
1145
+ * unknown to the user. If so, warn the user, and mark them as known to
1146
+ * give the user a chance to go verify them before re-sending this message.
1147
+ *
1148
+ * @param devicesInRoom - `userId -> {deviceId -> object}`
1149
+ * devices we should shared the session with.
1150
+ */
1151
+ private checkForUnknownDevices(devicesInRoom: DeviceInfoMap): void {
1152
+ const unknownDevices: MapWithDefault<string, Map<string, DeviceInfo>> = new MapWithDefault(() => new Map());
1153
+
1154
+ for (const [userId, userDevices] of devicesInRoom) {
1155
+ for (const [deviceId, device] of userDevices) {
1156
+ if (device.isUnverified() && !device.isKnown()) {
1157
+ unknownDevices.getOrCreate(userId).set(deviceId, device);
1158
+ }
1159
+ }
1160
+ }
1161
+
1162
+ if (unknownDevices.size) {
1163
+ // it'd be kind to pass unknownDevices up to the user in this error
1164
+ throw new UnknownDeviceError(
1165
+ "This room contains unknown devices which have not been verified. " +
1166
+ "We strongly recommend you verify them before continuing.",
1167
+ unknownDevices,
1168
+ );
1169
+ }
1170
+ }
1171
+
1172
+ /**
1173
+ * Remove unknown devices from a set of devices. The devicesInRoom parameter
1174
+ * will be modified.
1175
+ *
1176
+ * @param devicesInRoom - `userId -> {deviceId -> object}`
1177
+ * devices we should shared the session with.
1178
+ */
1179
+ private removeUnknownDevices(devicesInRoom: DeviceInfoMap): void {
1180
+ for (const [userId, userDevices] of devicesInRoom) {
1181
+ for (const [deviceId, device] of userDevices) {
1182
+ if (device.isUnverified() && !device.isKnown()) {
1183
+ userDevices.delete(deviceId);
1184
+ }
1185
+ }
1186
+
1187
+ if (userDevices.size === 0) {
1188
+ devicesInRoom.delete(userId);
1189
+ }
1190
+ }
1191
+ }
1192
+
1193
+ /**
1194
+ * Get the list of unblocked devices for all users in the room
1195
+ *
1196
+ * @param forceDistributeToUnverified - if set to true will include the unverified devices
1197
+ * even if setting is set to block them (useful for verification)
1198
+ * @param isCancelled - will cause the procedure to abort early if and when it starts
1199
+ * returning `true`. If omitted, cancellation won't happen.
1200
+ *
1201
+ * @returns Promise which resolves to `null`, or an array whose
1202
+ * first element is a {@link DeviceInfoMap} indicating
1203
+ * the devices that messages should be encrypted to, and whose second
1204
+ * element is a map from userId to deviceId to data indicating the devices
1205
+ * that are in the room but that have been blocked.
1206
+ * If `isCancelled` is provided and returns `true` while processing, `null`
1207
+ * will be returned.
1208
+ * If `isCancelled` is not provided, the Promise will never resolve to `null`.
1209
+ */
1210
+ private async getDevicesInRoom(
1211
+ room: Room,
1212
+ forceDistributeToUnverified?: boolean,
1213
+ ): Promise<[DeviceInfoMap, BlockedMap]>;
1214
+ private async getDevicesInRoom(
1215
+ room: Room,
1216
+ forceDistributeToUnverified?: boolean,
1217
+ isCancelled?: () => boolean,
1218
+ ): Promise<null | [DeviceInfoMap, BlockedMap]>;
1219
+ private async getDevicesInRoom(
1220
+ room: Room,
1221
+ forceDistributeToUnverified = false,
1222
+ isCancelled?: () => boolean,
1223
+ ): Promise<null | [DeviceInfoMap, BlockedMap]> {
1224
+ const members = await room.getEncryptionTargetMembers();
1225
+ this.prefixedLogger.debug(
1226
+ `Encrypting for users (shouldEncryptForInvitedMembers: ${room.shouldEncryptForInvitedMembers()}):`,
1227
+ members.map((u) => `${u.userId} (${u.membership})`),
1228
+ );
1229
+
1230
+ const roomMembers = members.map(function (u) {
1231
+ return u.userId;
1232
+ });
1233
+
1234
+ // The global value is treated as a default for when rooms don't specify a value.
1235
+ let isBlacklisting = this.crypto.globalBlacklistUnverifiedDevices;
1236
+ const isRoomBlacklisting = room.getBlacklistUnverifiedDevices();
1237
+ if (typeof isRoomBlacklisting === "boolean") {
1238
+ isBlacklisting = isRoomBlacklisting;
1239
+ }
1240
+
1241
+ // We are happy to use a cached version here: we assume that if we already
1242
+ // have a list of the user's devices, then we already share an e2e room
1243
+ // with them, which means that they will have announced any new devices via
1244
+ // device_lists in their /sync response. This cache should then be maintained
1245
+ // using all the device_lists changes and left fields.
1246
+ // See https://github.com/vector-im/element-web/issues/2305 for details.
1247
+ const devices = await this.crypto.downloadKeys(roomMembers, false);
1248
+
1249
+ if (isCancelled?.() === true) {
1250
+ return null;
1251
+ }
1252
+
1253
+ const blocked = new MapWithDefault<string, Map<string, IBlockedDevice>>(() => new Map());
1254
+ // remove any blocked devices
1255
+ for (const [userId, userDevices] of devices) {
1256
+ for (const [deviceId, userDevice] of userDevices) {
1257
+ // Yield prior to checking each device so that we don't block
1258
+ // updating/rendering for too long.
1259
+ // See https://github.com/vector-im/element-web/issues/21612
1260
+ if (isCancelled !== undefined) await immediate();
1261
+ if (isCancelled?.() === true) return null;
1262
+ const deviceTrust = this.crypto.checkDeviceTrust(userId, deviceId);
1263
+
1264
+ if (
1265
+ userDevice.isBlocked() ||
1266
+ (!deviceTrust.isVerified() && isBlacklisting && !forceDistributeToUnverified)
1267
+ ) {
1268
+ const blockedDevices = blocked.getOrCreate(userId);
1269
+ const isBlocked = userDevice.isBlocked();
1270
+ blockedDevices.set(deviceId, {
1271
+ code: isBlocked ? "m.blacklisted" : "m.unverified",
1272
+ reason: WITHHELD_MESSAGES[isBlocked ? "m.blacklisted" : "m.unverified"],
1273
+ deviceInfo: userDevice,
1274
+ });
1275
+ userDevices.delete(deviceId);
1276
+ }
1277
+ }
1278
+ }
1279
+
1280
+ return [devices, blocked];
1281
+ }
1282
+ }
1283
+
1284
+ /**
1285
+ * Megolm decryption implementation
1286
+ *
1287
+ * @param params - parameters, as per {@link DecryptionAlgorithm}
1288
+ */
1289
+ export class MegolmDecryption extends DecryptionAlgorithm {
1290
+ // events which we couldn't decrypt due to unknown sessions /
1291
+ // indexes, or which we could only decrypt with untrusted keys:
1292
+ // map from senderKey|sessionId to Set of MatrixEvents
1293
+ private pendingEvents = new Map<string, Map<string, Set<MatrixEvent>>>();
1294
+
1295
+ // this gets stubbed out by the unit tests.
1296
+ private olmlib = olmlib;
1297
+
1298
+ protected readonly roomId: string;
1299
+ private readonly prefixedLogger: Logger;
1300
+
1301
+ public constructor(params: DecryptionClassParams<IParams & Required<Pick<IParams, "roomId">>>) {
1302
+ super(params);
1303
+ this.roomId = params.roomId;
1304
+ this.prefixedLogger = logger.getChild(`[${this.roomId} decryption]`);
1305
+ }
1306
+
1307
+ /**
1308
+ * returns a promise which resolves to a
1309
+ * {@link EventDecryptionResult} once we have finished
1310
+ * decrypting, or rejects with an `algorithms.DecryptionError` if there is a
1311
+ * problem decrypting the event.
1312
+ */
1313
+ public async decryptEvent(event: MatrixEvent): Promise<IEventDecryptionResult> {
1314
+ const content = event.getWireContent();
1315
+
1316
+ if (!content.sender_key || !content.session_id || !content.ciphertext) {
1317
+ throw new DecryptionError(DecryptionFailureCode.MEGOLM_MISSING_FIELDS, "Missing fields in input");
1318
+ }
1319
+
1320
+ // we add the event to the pending list *before* we start decryption.
1321
+ //
1322
+ // then, if the key turns up while decryption is in progress (and
1323
+ // decryption fails), we will schedule a retry.
1324
+ // (fixes https://github.com/vector-im/element-web/issues/5001)
1325
+ this.addEventToPendingList(event);
1326
+
1327
+ let res: IDecryptedGroupMessage | null;
1328
+ try {
1329
+ res = await this.olmDevice.decryptGroupMessage(
1330
+ event.getRoomId()!,
1331
+ content.sender_key,
1332
+ content.session_id,
1333
+ content.ciphertext,
1334
+ event.getId()!,
1335
+ event.getTs(),
1336
+ );
1337
+ } catch (e) {
1338
+ if ((<Error>e).name === "DecryptionError") {
1339
+ // re-throw decryption errors as-is
1340
+ throw e;
1341
+ }
1342
+
1343
+ let errorCode = DecryptionFailureCode.OLM_DECRYPT_GROUP_MESSAGE_ERROR;
1344
+
1345
+ if ((<MatrixError>e)?.message === "OLM.UNKNOWN_MESSAGE_INDEX") {
1346
+ this.requestKeysForEvent(event);
1347
+
1348
+ errorCode = DecryptionFailureCode.OLM_UNKNOWN_MESSAGE_INDEX;
1349
+ }
1350
+
1351
+ throw new DecryptionError(errorCode, e instanceof Error ? e.message : "Unknown Error: Error is undefined", {
1352
+ session: content.sender_key + "|" + content.session_id,
1353
+ });
1354
+ }
1355
+
1356
+ if (res === null) {
1357
+ // We've got a message for a session we don't have.
1358
+ // try and get the missing key from the backup first
1359
+ this.crypto.backupManager.queryKeyBackupRateLimited(event.getRoomId(), content.session_id).catch(() => {});
1360
+
1361
+ // (XXX: We might actually have received this key since we started
1362
+ // decrypting, in which case we'll have scheduled a retry, and this
1363
+ // request will be redundant. We could probably check to see if the
1364
+ // event is still in the pending list; if not, a retry will have been
1365
+ // scheduled, so we needn't send out the request here.)
1366
+ this.requestKeysForEvent(event);
1367
+
1368
+ // See if there was a problem with the olm session at the time the
1369
+ // event was sent. Use a fuzz factor of 2 minutes.
1370
+ const problem = await this.olmDevice.sessionMayHaveProblems(content.sender_key, event.getTs() - 120000);
1371
+ if (problem) {
1372
+ this.prefixedLogger.info(
1373
+ `When handling UISI from ${event.getSender()} (sender key ${content.sender_key}): ` +
1374
+ `recent session problem with that sender:`,
1375
+ problem,
1376
+ );
1377
+ let problemDescription = PROBLEM_DESCRIPTIONS[problem.type as "no_olm"] || PROBLEM_DESCRIPTIONS.unknown;
1378
+ if (problem.fixed) {
1379
+ problemDescription += " Trying to create a new secure channel and re-requesting the keys.";
1380
+ }
1381
+ throw new DecryptionError(DecryptionFailureCode.MEGOLM_UNKNOWN_INBOUND_SESSION_ID, problemDescription, {
1382
+ session: content.sender_key + "|" + content.session_id,
1383
+ });
1384
+ }
1385
+
1386
+ throw new DecryptionError(
1387
+ DecryptionFailureCode.MEGOLM_UNKNOWN_INBOUND_SESSION_ID,
1388
+ "The sender's device has not sent us the keys for this message.",
1389
+ {
1390
+ session: content.sender_key + "|" + content.session_id,
1391
+ },
1392
+ );
1393
+ }
1394
+
1395
+ // Success. We can remove the event from the pending list, if
1396
+ // that hasn't already happened. However, if the event was
1397
+ // decrypted with an untrusted key, leave it on the pending
1398
+ // list so it will be retried if we find a trusted key later.
1399
+ if (!res.untrusted) {
1400
+ this.removeEventFromPendingList(event);
1401
+ }
1402
+
1403
+ const payload = JSON.parse(res.result);
1404
+
1405
+ // belt-and-braces check that the room id matches that indicated by the HS
1406
+ // (this is somewhat redundant, since the megolm session is scoped to the
1407
+ // room, so neither the sender nor a MITM can lie about the room_id).
1408
+ if (payload.room_id !== event.getRoomId()) {
1409
+ throw new DecryptionError(
1410
+ DecryptionFailureCode.MEGOLM_BAD_ROOM,
1411
+ "Message intended for room " + payload.room_id,
1412
+ );
1413
+ }
1414
+
1415
+ return {
1416
+ clearEvent: payload,
1417
+ senderCurve25519Key: res.senderKey,
1418
+ claimedEd25519Key: res.keysClaimed.ed25519,
1419
+ forwardingCurve25519KeyChain: res.forwardingCurve25519KeyChain,
1420
+ untrusted: res.untrusted,
1421
+ };
1422
+ }
1423
+
1424
+ private requestKeysForEvent(event: MatrixEvent): void {
1425
+ const wireContent = event.getWireContent();
1426
+
1427
+ const recipients = event.getKeyRequestRecipients(this.userId);
1428
+
1429
+ this.crypto.requestRoomKey(
1430
+ {
1431
+ room_id: event.getRoomId()!,
1432
+ algorithm: wireContent.algorithm,
1433
+ sender_key: wireContent.sender_key,
1434
+ session_id: wireContent.session_id,
1435
+ },
1436
+ recipients,
1437
+ );
1438
+ }
1439
+
1440
+ /**
1441
+ * Add an event to the list of those awaiting their session keys.
1442
+ *
1443
+ * @internal
1444
+ *
1445
+ */
1446
+ private addEventToPendingList(event: MatrixEvent): void {
1447
+ const content = event.getWireContent();
1448
+ const senderKey = content.sender_key;
1449
+ const sessionId = content.session_id;
1450
+ if (!this.pendingEvents.has(senderKey)) {
1451
+ this.pendingEvents.set(senderKey, new Map<string, Set<MatrixEvent>>());
1452
+ }
1453
+ const senderPendingEvents = this.pendingEvents.get(senderKey)!;
1454
+ if (!senderPendingEvents.has(sessionId)) {
1455
+ senderPendingEvents.set(sessionId, new Set());
1456
+ }
1457
+ senderPendingEvents.get(sessionId)?.add(event);
1458
+ }
1459
+
1460
+ /**
1461
+ * Remove an event from the list of those awaiting their session keys.
1462
+ *
1463
+ * @internal
1464
+ *
1465
+ */
1466
+ private removeEventFromPendingList(event: MatrixEvent): void {
1467
+ const content = event.getWireContent();
1468
+ const senderKey = content.sender_key;
1469
+ const sessionId = content.session_id;
1470
+ const senderPendingEvents = this.pendingEvents.get(senderKey);
1471
+ const pendingEvents = senderPendingEvents?.get(sessionId);
1472
+ if (!pendingEvents) {
1473
+ return;
1474
+ }
1475
+
1476
+ pendingEvents.delete(event);
1477
+ if (pendingEvents.size === 0) {
1478
+ senderPendingEvents!.delete(sessionId);
1479
+ }
1480
+ if (senderPendingEvents!.size === 0) {
1481
+ this.pendingEvents.delete(senderKey);
1482
+ }
1483
+ }
1484
+
1485
+ /**
1486
+ * Parse a RoomKey out of an `m.room_key` event.
1487
+ *
1488
+ * @param event - the event containing the room key.
1489
+ *
1490
+ * @returns The `RoomKey` if it could be successfully parsed out of the
1491
+ * event.
1492
+ *
1493
+ * @internal
1494
+ *
1495
+ */
1496
+ private roomKeyFromEvent(event: MatrixEvent): RoomKey | undefined {
1497
+ const senderKey = event.getSenderKey()!;
1498
+ const content = event.getContent<Partial<IMessage["content"]>>();
1499
+ const extraSessionData: OlmGroupSessionExtraData = {};
1500
+
1501
+ if (!content.room_id || !content.session_key || !content.session_id || !content.algorithm) {
1502
+ this.prefixedLogger.error("key event is missing fields");
1503
+ return;
1504
+ }
1505
+
1506
+ if (!olmlib.isOlmEncrypted(event)) {
1507
+ this.prefixedLogger.error("key event not properly encrypted");
1508
+ return;
1509
+ }
1510
+
1511
+ if (content["org.matrix.msc3061.shared_history"]) {
1512
+ extraSessionData.sharedHistory = true;
1513
+ }
1514
+
1515
+ const roomKey: RoomKey = {
1516
+ senderKey: senderKey,
1517
+ sessionId: content.session_id,
1518
+ sessionKey: content.session_key,
1519
+ extraSessionData,
1520
+ exportFormat: false,
1521
+ roomId: content.room_id,
1522
+ algorithm: content.algorithm,
1523
+ forwardingKeyChain: [],
1524
+ keysClaimed: event.getKeysClaimed(),
1525
+ };
1526
+
1527
+ return roomKey;
1528
+ }
1529
+
1530
+ /**
1531
+ * Parse a RoomKey out of an `m.forwarded_room_key` event.
1532
+ *
1533
+ * @param event - the event containing the forwarded room key.
1534
+ *
1535
+ * @returns The `RoomKey` if it could be successfully parsed out of the
1536
+ * event.
1537
+ *
1538
+ * @internal
1539
+ *
1540
+ */
1541
+ private forwardedRoomKeyFromEvent(event: MatrixEvent): RoomKey | undefined {
1542
+ // the properties in m.forwarded_room_key are a superset of those in m.room_key, so
1543
+ // start by parsing the m.room_key fields.
1544
+ const roomKey = this.roomKeyFromEvent(event);
1545
+
1546
+ if (!roomKey) {
1547
+ return;
1548
+ }
1549
+
1550
+ const senderKey = event.getSenderKey()!;
1551
+ const content = event.getContent<Partial<IMessage["content"]>>();
1552
+
1553
+ const senderKeyUser = this.baseApis.crypto!.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, senderKey);
1554
+
1555
+ // We received this to-device event from event.getSenderKey(), but the original
1556
+ // creator of the room key is claimed in the content.
1557
+ const claimedCurve25519Key = content.sender_key;
1558
+ const claimedEd25519Key = content.sender_claimed_ed25519_key;
1559
+
1560
+ let forwardingKeyChain = Array.isArray(content.forwarding_curve25519_key_chain)
1561
+ ? content.forwarding_curve25519_key_chain
1562
+ : [];
1563
+
1564
+ // copy content before we modify it
1565
+ forwardingKeyChain = forwardingKeyChain.slice();
1566
+ forwardingKeyChain.push(senderKey);
1567
+
1568
+ // Check if we have all the fields we need.
1569
+ if (senderKeyUser !== event.getSender()) {
1570
+ this.prefixedLogger.error("sending device does not belong to the user it claims to be from");
1571
+ return;
1572
+ }
1573
+
1574
+ if (!claimedCurve25519Key) {
1575
+ this.prefixedLogger.error("forwarded_room_key event is missing sender_key field");
1576
+ return;
1577
+ }
1578
+
1579
+ if (!claimedEd25519Key) {
1580
+ this.prefixedLogger.error(`forwarded_room_key_event is missing sender_claimed_ed25519_key field`);
1581
+ return;
1582
+ }
1583
+
1584
+ const keysClaimed = {
1585
+ ed25519: claimedEd25519Key,
1586
+ };
1587
+
1588
+ // FIXME: We're reusing the same field to track both:
1589
+ //
1590
+ // 1. The Olm identity we've received this room key from.
1591
+ // 2. The Olm identity deduced (in the trusted case) or claiming (in the
1592
+ // untrusted case) to be the original creator of this room key.
1593
+ //
1594
+ // We now overwrite the value tracking usage 1 with the value tracking usage 2.
1595
+ roomKey.senderKey = claimedCurve25519Key;
1596
+ // Replace our keysClaimed as well.
1597
+ roomKey.keysClaimed = keysClaimed;
1598
+ roomKey.exportFormat = true;
1599
+ roomKey.forwardingKeyChain = forwardingKeyChain;
1600
+ // forwarded keys are always untrusted
1601
+ roomKey.extraSessionData.untrusted = true;
1602
+
1603
+ return roomKey;
1604
+ }
1605
+
1606
+ /**
1607
+ * Determine if we should accept the forwarded room key that was found in the given
1608
+ * event.
1609
+ *
1610
+ * @param event - An `m.forwarded_room_key` event.
1611
+ * @param roomKey - The room key that was found in the event.
1612
+ *
1613
+ * @returns promise that will resolve to a boolean telling us if it's ok to
1614
+ * accept the given forwarded room key.
1615
+ *
1616
+ * @internal
1617
+ *
1618
+ */
1619
+ private async shouldAcceptForwardedKey(event: MatrixEvent, roomKey: RoomKey): Promise<boolean> {
1620
+ const senderKey = event.getSenderKey()!;
1621
+
1622
+ const sendingDevice =
1623
+ this.crypto.deviceList.getDeviceByIdentityKey(olmlib.OLM_ALGORITHM, senderKey) ?? undefined;
1624
+ const deviceTrust = this.crypto.checkDeviceInfoTrust(event.getSender()!, sendingDevice);
1625
+
1626
+ // Using the plaintext sender here is fine since we checked that the
1627
+ // sender matches to the user id in the device keys when this event was
1628
+ // originally decrypted. This can obviously only happen if the device
1629
+ // keys have been downloaded, but if they haven't the
1630
+ // `deviceTrust.isVerified()` flag would be false as well.
1631
+ //
1632
+ // It would still be far nicer if the `sendingDevice` had a user ID
1633
+ // attached to it that went through signature checks.
1634
+ const fromUs = event.getSender() === this.baseApis.getUserId();
1635
+ const keyFromOurVerifiedDevice = deviceTrust.isVerified() && fromUs;
1636
+ const weRequested = await this.wasRoomKeyRequested(event, roomKey);
1637
+ const fromInviter = this.wasRoomKeyForwardedByInviter(event, roomKey);
1638
+ const sharedAsHistory = this.wasRoomKeyForwardedAsHistory(roomKey);
1639
+
1640
+ return (weRequested && keyFromOurVerifiedDevice) || (fromInviter && sharedAsHistory);
1641
+ }
1642
+
1643
+ /**
1644
+ * Did we ever request the given room key from the event sender and its
1645
+ * accompanying device.
1646
+ *
1647
+ * @param event - An `m.forwarded_room_key` event.
1648
+ * @param roomKey - The room key that was found in the event.
1649
+ *
1650
+ * @internal
1651
+ *
1652
+ */
1653
+ private async wasRoomKeyRequested(event: MatrixEvent, roomKey: RoomKey): Promise<boolean> {
1654
+ // We send the `m.room_key_request` out as a wildcard to-device request,
1655
+ // otherwise we would have to duplicate the same content for each
1656
+ // device. This is why we need to pass in "*" as the device id here.
1657
+ const outgoingRequests = await this.crypto.cryptoStore.getOutgoingRoomKeyRequestsByTarget(
1658
+ event.getSender()!,
1659
+ "*",
1660
+ [RoomKeyRequestState.Sent],
1661
+ );
1662
+
1663
+ return outgoingRequests.some(
1664
+ (req) => req.requestBody.room_id === roomKey.roomId && req.requestBody.session_id === roomKey.sessionId,
1665
+ );
1666
+ }
1667
+
1668
+ private wasRoomKeyForwardedByInviter(event: MatrixEvent, roomKey: RoomKey): boolean {
1669
+ // TODO: This is supposed to have a time limit. We should only accept
1670
+ // such keys if we happen to receive them for a recently joined room.
1671
+ const room = this.baseApis.getRoom(roomKey.roomId);
1672
+ const senderKey = event.getSenderKey();
1673
+
1674
+ if (!senderKey) {
1675
+ return false;
1676
+ }
1677
+
1678
+ const senderKeyUser = this.crypto.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, senderKey);
1679
+
1680
+ if (!senderKeyUser) {
1681
+ return false;
1682
+ }
1683
+
1684
+ const memberEvent = room?.getMember(this.userId)?.events.member;
1685
+ const fromInviter =
1686
+ memberEvent?.getSender() === senderKeyUser ||
1687
+ (memberEvent?.getUnsigned()?.prev_sender === senderKeyUser &&
1688
+ memberEvent?.getPrevContent()?.membership === KnownMembership.Invite);
1689
+
1690
+ if (room && fromInviter) {
1691
+ return true;
1692
+ } else {
1693
+ return false;
1694
+ }
1695
+ }
1696
+
1697
+ private wasRoomKeyForwardedAsHistory(roomKey: RoomKey): boolean {
1698
+ const room = this.baseApis.getRoom(roomKey.roomId);
1699
+
1700
+ // If the key is not for a known room, then something fishy is going on,
1701
+ // so we reject the key out of caution. In practice, this is a bit moot
1702
+ // because we'll only accept shared_history forwarded by the inviter, and
1703
+ // we won't know who was the inviter for an unknown room, so we'll reject
1704
+ // it anyway.
1705
+ if (room && roomKey.extraSessionData.sharedHistory) {
1706
+ return true;
1707
+ } else {
1708
+ return false;
1709
+ }
1710
+ }
1711
+
1712
+ /**
1713
+ * Check if a forwarded room key should be parked.
1714
+ *
1715
+ * A forwarded room key should be parked if it's a key for a room we're not
1716
+ * in. We park the forwarded room key in case *this sender* invites us to
1717
+ * that room later.
1718
+ */
1719
+ private shouldParkForwardedKey(roomKey: RoomKey): boolean {
1720
+ const room = this.baseApis.getRoom(roomKey.roomId);
1721
+
1722
+ if (!room && roomKey.extraSessionData.sharedHistory) {
1723
+ return true;
1724
+ } else {
1725
+ return false;
1726
+ }
1727
+ }
1728
+
1729
+ /**
1730
+ * Park the given room key to our store.
1731
+ *
1732
+ * @param event - An `m.forwarded_room_key` event.
1733
+ * @param roomKey - The room key that was found in the event.
1734
+ *
1735
+ * @internal
1736
+ *
1737
+ */
1738
+ private async parkForwardedKey(event: MatrixEvent, roomKey: RoomKey): Promise<void> {
1739
+ const parkedData = {
1740
+ senderId: event.getSender()!,
1741
+ senderKey: roomKey.senderKey,
1742
+ sessionId: roomKey.sessionId,
1743
+ sessionKey: roomKey.sessionKey,
1744
+ keysClaimed: roomKey.keysClaimed,
1745
+ forwardingCurve25519KeyChain: roomKey.forwardingKeyChain,
1746
+ };
1747
+ await this.crypto.cryptoStore.doTxn(
1748
+ "readwrite",
1749
+ ["parked_shared_history"],
1750
+ (txn) => this.crypto.cryptoStore.addParkedSharedHistory(roomKey.roomId, parkedData, txn),
1751
+ logger.getChild("[addParkedSharedHistory]"),
1752
+ );
1753
+ }
1754
+
1755
+ /**
1756
+ * Add the given room key to our store.
1757
+ *
1758
+ * @param roomKey - The room key that should be added to the store.
1759
+ *
1760
+ * @internal
1761
+ *
1762
+ */
1763
+ private async addRoomKey(roomKey: RoomKey): Promise<void> {
1764
+ try {
1765
+ await this.olmDevice.addInboundGroupSession(
1766
+ roomKey.roomId,
1767
+ roomKey.senderKey,
1768
+ roomKey.forwardingKeyChain,
1769
+ roomKey.sessionId,
1770
+ roomKey.sessionKey,
1771
+ roomKey.keysClaimed,
1772
+ roomKey.exportFormat,
1773
+ roomKey.extraSessionData,
1774
+ );
1775
+
1776
+ // have another go at decrypting events sent with this session.
1777
+ if (await this.retryDecryption(roomKey.senderKey, roomKey.sessionId, !roomKey.extraSessionData.untrusted)) {
1778
+ // cancel any outstanding room key requests for this session.
1779
+ // Only do this if we managed to decrypt every message in the
1780
+ // session, because if we didn't, we leave the other key
1781
+ // requests in the hopes that someone sends us a key that
1782
+ // includes an earlier index.
1783
+ this.crypto.cancelRoomKeyRequest({
1784
+ algorithm: roomKey.algorithm,
1785
+ room_id: roomKey.roomId,
1786
+ session_id: roomKey.sessionId,
1787
+ sender_key: roomKey.senderKey,
1788
+ });
1789
+ }
1790
+
1791
+ // don't wait for the keys to be backed up for the server
1792
+ await this.crypto.backupManager.backupGroupSession(roomKey.senderKey, roomKey.sessionId);
1793
+ } catch (e) {
1794
+ this.prefixedLogger.error(`Error handling m.room_key_event: ${e}`);
1795
+ }
1796
+ }
1797
+
1798
+ /**
1799
+ * Handle room keys that have been forwarded to us as an
1800
+ * `m.forwarded_room_key` event.
1801
+ *
1802
+ * Forwarded room keys need special handling since we have no way of knowing
1803
+ * who the original creator of the room key was. This naturally means that
1804
+ * forwarded room keys are always untrusted and should only be accepted in
1805
+ * some cases.
1806
+ *
1807
+ * @param event - An `m.forwarded_room_key` event.
1808
+ *
1809
+ * @internal
1810
+ *
1811
+ */
1812
+ private async onForwardedRoomKey(event: MatrixEvent): Promise<void> {
1813
+ const roomKey = this.forwardedRoomKeyFromEvent(event);
1814
+
1815
+ if (!roomKey) {
1816
+ return;
1817
+ }
1818
+
1819
+ if (await this.shouldAcceptForwardedKey(event, roomKey)) {
1820
+ await this.addRoomKey(roomKey);
1821
+ } else if (this.shouldParkForwardedKey(roomKey)) {
1822
+ await this.parkForwardedKey(event, roomKey);
1823
+ }
1824
+ }
1825
+
1826
+ public async onRoomKeyEvent(event: MatrixEvent): Promise<void> {
1827
+ if (event.getType() == "m.forwarded_room_key") {
1828
+ await this.onForwardedRoomKey(event);
1829
+ } else {
1830
+ const roomKey = this.roomKeyFromEvent(event);
1831
+
1832
+ if (!roomKey) {
1833
+ return;
1834
+ }
1835
+
1836
+ await this.addRoomKey(roomKey);
1837
+ }
1838
+ }
1839
+
1840
+ /**
1841
+ * @param event - key event
1842
+ */
1843
+ public async onRoomKeyWithheldEvent(event: MatrixEvent): Promise<void> {
1844
+ const content = event.getContent();
1845
+ const senderKey = content.sender_key;
1846
+
1847
+ if (content.code === "m.no_olm") {
1848
+ await this.onNoOlmWithheldEvent(event);
1849
+ } else if (content.code === "m.unavailable") {
1850
+ // this simply means that the other device didn't have the key, which isn't very useful information. Don't
1851
+ // record it in the storage
1852
+ } else {
1853
+ await this.olmDevice.addInboundGroupSessionWithheld(
1854
+ content.room_id,
1855
+ senderKey,
1856
+ content.session_id,
1857
+ content.code,
1858
+ content.reason,
1859
+ );
1860
+ }
1861
+
1862
+ // Having recorded the problem, retry decryption on any affected messages.
1863
+ // It's unlikely we'll be able to decrypt sucessfully now, but this will
1864
+ // update the error message.
1865
+ //
1866
+ if (content.session_id) {
1867
+ await this.retryDecryption(senderKey, content.session_id);
1868
+ } else {
1869
+ // no_olm messages aren't specific to a given megolm session, so
1870
+ // we trigger retrying decryption for all the messages from the sender's
1871
+ // key, so that we can update the error message to indicate the olm
1872
+ // session problem.
1873
+ await this.retryDecryptionFromSender(senderKey);
1874
+ }
1875
+ }
1876
+
1877
+ private async onNoOlmWithheldEvent(event: MatrixEvent): Promise<void> {
1878
+ const content = event.getContent();
1879
+ const senderKey = content.sender_key;
1880
+ const sender = event.getSender()!;
1881
+ this.prefixedLogger.warn(`${sender}:${senderKey} was unable to establish an olm session with us`);
1882
+ // if the sender says that they haven't been able to establish an olm
1883
+ // session, let's proactively establish one
1884
+
1885
+ if (await this.olmDevice.getSessionIdForDevice(senderKey)) {
1886
+ // a session has already been established, so we don't need to
1887
+ // create a new one.
1888
+ this.prefixedLogger.debug("New session already created. Not creating a new one.");
1889
+ await this.olmDevice.recordSessionProblem(senderKey, "no_olm", true);
1890
+ return;
1891
+ }
1892
+ let device = this.crypto.deviceList.getDeviceByIdentityKey(content.algorithm, senderKey);
1893
+ if (!device) {
1894
+ // if we don't know about the device, fetch the user's devices again
1895
+ // and retry before giving up
1896
+ await this.crypto.downloadKeys([sender], false);
1897
+ device = this.crypto.deviceList.getDeviceByIdentityKey(content.algorithm, senderKey);
1898
+ if (!device) {
1899
+ this.prefixedLogger.info(
1900
+ "Couldn't find device for identity key " + senderKey + ": not establishing session",
1901
+ );
1902
+ await this.olmDevice.recordSessionProblem(senderKey, "no_olm", false);
1903
+ return;
1904
+ }
1905
+ }
1906
+
1907
+ // XXX: switch this to use encryptAndSendToDevices() rather than duplicating it?
1908
+
1909
+ await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, new Map([[sender, [device]]]), false);
1910
+ const encryptedContent: IEncryptedContent = {
1911
+ algorithm: olmlib.OLM_ALGORITHM,
1912
+ sender_key: this.olmDevice.deviceCurve25519Key!,
1913
+ ciphertext: {},
1914
+ [ToDeviceMessageId]: uuidv4(),
1915
+ };
1916
+ await olmlib.encryptMessageForDevice(
1917
+ encryptedContent.ciphertext,
1918
+ this.userId,
1919
+ undefined,
1920
+ this.olmDevice,
1921
+ sender,
1922
+ device,
1923
+ { type: "m.dummy" },
1924
+ );
1925
+
1926
+ await this.olmDevice.recordSessionProblem(senderKey, "no_olm", true);
1927
+
1928
+ await this.baseApis.sendToDevice(
1929
+ "m.room.encrypted",
1930
+ new Map([[sender, new Map([[device.deviceId, encryptedContent]])]]),
1931
+ );
1932
+ }
1933
+
1934
+ public hasKeysForKeyRequest(keyRequest: IncomingRoomKeyRequest): Promise<boolean> {
1935
+ const body = keyRequest.requestBody;
1936
+
1937
+ return this.olmDevice.hasInboundSessionKeys(
1938
+ body.room_id,
1939
+ body.sender_key,
1940
+ body.session_id,
1941
+ // TODO: ratchet index
1942
+ );
1943
+ }
1944
+
1945
+ public shareKeysWithDevice(keyRequest: IncomingRoomKeyRequest): void {
1946
+ const userId = keyRequest.userId;
1947
+ const deviceId = keyRequest.deviceId;
1948
+ const deviceInfo = this.crypto.getStoredDevice(userId, deviceId)!;
1949
+ const body = keyRequest.requestBody;
1950
+
1951
+ // XXX: switch this to use encryptAndSendToDevices()?
1952
+
1953
+ this.olmlib
1954
+ .ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, new Map([[userId, [deviceInfo]]]))
1955
+ .then((devicemap) => {
1956
+ const olmSessionResult = devicemap.get(userId)?.get(deviceId);
1957
+ if (!olmSessionResult?.sessionId) {
1958
+ // no session with this device, probably because there
1959
+ // were no one-time keys.
1960
+ //
1961
+ // ensureOlmSessionsForUsers has already done the logging,
1962
+ // so just skip it.
1963
+ return null;
1964
+ }
1965
+
1966
+ this.prefixedLogger.debug(
1967
+ "sharing keys for session " +
1968
+ body.sender_key +
1969
+ "|" +
1970
+ body.session_id +
1971
+ " with device " +
1972
+ userId +
1973
+ ":" +
1974
+ deviceId,
1975
+ );
1976
+
1977
+ return this.buildKeyForwardingMessage(body.room_id, body.sender_key, body.session_id);
1978
+ })
1979
+ .then((payload) => {
1980
+ const encryptedContent: IEncryptedContent = {
1981
+ algorithm: olmlib.OLM_ALGORITHM,
1982
+ sender_key: this.olmDevice.deviceCurve25519Key!,
1983
+ ciphertext: {},
1984
+ [ToDeviceMessageId]: uuidv4(),
1985
+ };
1986
+
1987
+ return this.olmlib
1988
+ .encryptMessageForDevice(
1989
+ encryptedContent.ciphertext,
1990
+ this.userId,
1991
+ undefined,
1992
+ this.olmDevice,
1993
+ userId,
1994
+ deviceInfo,
1995
+ payload!,
1996
+ )
1997
+ .then(() => {
1998
+ // TODO: retries
1999
+ return this.baseApis.sendToDevice(
2000
+ "m.room.encrypted",
2001
+ new Map([[userId, new Map([[deviceId, encryptedContent]])]]),
2002
+ );
2003
+ });
2004
+ });
2005
+ }
2006
+
2007
+ private async buildKeyForwardingMessage(
2008
+ roomId: string,
2009
+ senderKey: string,
2010
+ sessionId: string,
2011
+ ): Promise<IKeyForwardingMessage> {
2012
+ const key = await this.olmDevice.getInboundGroupSessionKey(roomId, senderKey, sessionId);
2013
+
2014
+ return {
2015
+ type: "m.forwarded_room_key",
2016
+ content: {
2017
+ "algorithm": olmlib.MEGOLM_ALGORITHM,
2018
+ "room_id": roomId,
2019
+ "sender_key": senderKey,
2020
+ "sender_claimed_ed25519_key": key!.sender_claimed_ed25519_key!,
2021
+ "session_id": sessionId,
2022
+ "session_key": key!.key,
2023
+ "chain_index": key!.chain_index,
2024
+ "forwarding_curve25519_key_chain": key!.forwarding_curve25519_key_chain,
2025
+ "org.matrix.msc3061.shared_history": key!.shared_history || false,
2026
+ },
2027
+ };
2028
+ }
2029
+
2030
+ /**
2031
+ * @param untrusted - whether the key should be considered as untrusted
2032
+ * @param source - where the key came from
2033
+ */
2034
+ public importRoomKey(
2035
+ session: IMegolmSessionData,
2036
+ { untrusted, source }: { untrusted?: boolean; source?: string } = {},
2037
+ ): Promise<void> {
2038
+ const extraSessionData: OlmGroupSessionExtraData = {};
2039
+ if (untrusted || session.untrusted) {
2040
+ extraSessionData.untrusted = true;
2041
+ }
2042
+ if (session["org.matrix.msc3061.shared_history"]) {
2043
+ extraSessionData.sharedHistory = true;
2044
+ }
2045
+ return this.olmDevice
2046
+ .addInboundGroupSession(
2047
+ session.room_id,
2048
+ session.sender_key,
2049
+ session.forwarding_curve25519_key_chain,
2050
+ session.session_id,
2051
+ session.session_key,
2052
+ session.sender_claimed_keys,
2053
+ true,
2054
+ extraSessionData,
2055
+ )
2056
+ .then(() => {
2057
+ if (source !== "backup") {
2058
+ // don't wait for it to complete
2059
+ this.crypto.backupManager.backupGroupSession(session.sender_key, session.session_id).catch((e) => {
2060
+ // This throws if the upload failed, but this is fine
2061
+ // since it will have written it to the db and will retry.
2062
+ this.prefixedLogger.debug("Failed to back up megolm session", e);
2063
+ });
2064
+ }
2065
+ // have another go at decrypting events sent with this session.
2066
+ this.retryDecryption(session.sender_key, session.session_id, !extraSessionData.untrusted);
2067
+ });
2068
+ }
2069
+
2070
+ /**
2071
+ * Have another go at decrypting events after we receive a key. Resolves once
2072
+ * decryption has been re-attempted on all events.
2073
+ *
2074
+ * @internal
2075
+ * @param forceRedecryptIfUntrusted - whether messages that were already
2076
+ * successfully decrypted using untrusted keys should be re-decrypted
2077
+ *
2078
+ * @returns whether all messages were successfully
2079
+ * decrypted with trusted keys
2080
+ */
2081
+ private async retryDecryption(
2082
+ senderKey: string,
2083
+ sessionId: string,
2084
+ forceRedecryptIfUntrusted?: boolean,
2085
+ ): Promise<boolean> {
2086
+ const senderPendingEvents = this.pendingEvents.get(senderKey);
2087
+ if (!senderPendingEvents) {
2088
+ return true;
2089
+ }
2090
+
2091
+ const pending = senderPendingEvents.get(sessionId);
2092
+ if (!pending) {
2093
+ return true;
2094
+ }
2095
+
2096
+ const pendingList = [...pending];
2097
+ this.prefixedLogger.debug(
2098
+ "Retrying decryption on events:",
2099
+ pendingList.map((e) => `${e.getId()}`),
2100
+ );
2101
+
2102
+ await Promise.all(
2103
+ pendingList.map(async (ev) => {
2104
+ try {
2105
+ await ev.attemptDecryption(this.crypto, { isRetry: true, forceRedecryptIfUntrusted });
2106
+ } catch {
2107
+ // don't die if something goes wrong
2108
+ }
2109
+ }),
2110
+ );
2111
+
2112
+ // If decrypted successfully with trusted keys, they'll have
2113
+ // been removed from pendingEvents
2114
+ return !this.pendingEvents.get(senderKey)?.has(sessionId);
2115
+ }
2116
+
2117
+ public async retryDecryptionFromSender(senderKey: string): Promise<boolean> {
2118
+ const senderPendingEvents = this.pendingEvents.get(senderKey);
2119
+ if (!senderPendingEvents) {
2120
+ return true;
2121
+ }
2122
+
2123
+ this.pendingEvents.delete(senderKey);
2124
+
2125
+ await Promise.all(
2126
+ [...senderPendingEvents].map(async ([_sessionId, pending]) => {
2127
+ await Promise.all(
2128
+ [...pending].map(async (ev) => {
2129
+ try {
2130
+ await ev.attemptDecryption(this.crypto);
2131
+ } catch {
2132
+ // don't die if something goes wrong
2133
+ }
2134
+ }),
2135
+ );
2136
+ }),
2137
+ );
2138
+
2139
+ return !this.pendingEvents.has(senderKey);
2140
+ }
2141
+
2142
+ public async sendSharedHistoryInboundSessions(devicesByUser: Map<string, DeviceInfo[]>): Promise<void> {
2143
+ await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, devicesByUser);
2144
+
2145
+ const sharedHistorySessions = await this.olmDevice.getSharedHistoryInboundGroupSessions(this.roomId);
2146
+ this.prefixedLogger.debug(
2147
+ `Sharing history in with users ${Array.from(devicesByUser.keys())}`,
2148
+ sharedHistorySessions.map(([senderKey, sessionId]) => `${senderKey}|${sessionId}`),
2149
+ );
2150
+ for (const [senderKey, sessionId] of sharedHistorySessions) {
2151
+ const payload = await this.buildKeyForwardingMessage(this.roomId, senderKey, sessionId);
2152
+
2153
+ // FIXME: use encryptAndSendToDevices() rather than duplicating it here.
2154
+ const promises: Promise<unknown>[] = [];
2155
+ const contentMap: Map<string, Map<string, IEncryptedContent>> = new Map();
2156
+ for (const [userId, devices] of devicesByUser) {
2157
+ const deviceMessages = new Map();
2158
+ contentMap.set(userId, deviceMessages);
2159
+ for (const deviceInfo of devices) {
2160
+ const encryptedContent: IEncryptedContent = {
2161
+ algorithm: olmlib.OLM_ALGORITHM,
2162
+ sender_key: this.olmDevice.deviceCurve25519Key!,
2163
+ ciphertext: {},
2164
+ [ToDeviceMessageId]: uuidv4(),
2165
+ };
2166
+ deviceMessages.set(deviceInfo.deviceId, encryptedContent);
2167
+ promises.push(
2168
+ olmlib.encryptMessageForDevice(
2169
+ encryptedContent.ciphertext,
2170
+ this.userId,
2171
+ undefined,
2172
+ this.olmDevice,
2173
+ userId,
2174
+ deviceInfo,
2175
+ payload,
2176
+ ),
2177
+ );
2178
+ }
2179
+ }
2180
+ await Promise.all(promises);
2181
+
2182
+ // prune out any devices that encryptMessageForDevice could not encrypt for,
2183
+ // in which case it will have just not added anything to the ciphertext object.
2184
+ // There's no point sending messages to devices if we couldn't encrypt to them,
2185
+ // since that's effectively a blank message.
2186
+ for (const [userId, deviceMessages] of contentMap) {
2187
+ for (const [deviceId, content] of deviceMessages) {
2188
+ if (!hasCiphertext(content)) {
2189
+ this.prefixedLogger.debug("No ciphertext for device " + userId + ":" + deviceId + ": pruning");
2190
+ deviceMessages.delete(deviceId);
2191
+ }
2192
+ }
2193
+ // No devices left for that user? Strip that too.
2194
+ if (deviceMessages.size === 0) {
2195
+ this.prefixedLogger.debug("Pruned all devices for user " + userId);
2196
+ contentMap.delete(userId);
2197
+ }
2198
+ }
2199
+
2200
+ // Is there anything left?
2201
+ if (contentMap.size === 0) {
2202
+ this.prefixedLogger.debug("No users left to send to: aborting");
2203
+ return;
2204
+ }
2205
+
2206
+ await this.baseApis.sendToDevice("m.room.encrypted", contentMap);
2207
+ }
2208
+ }
2209
+ }
2210
+
2211
+ const PROBLEM_DESCRIPTIONS = {
2212
+ no_olm: "The sender was unable to establish a secure channel.",
2213
+ unknown: "The secure channel with the sender was corrupted.",
2214
+ };
2215
+
2216
+ registerAlgorithm(olmlib.MEGOLM_ALGORITHM, MegolmEncryption, MegolmDecryption);