@unwanted/matrix-sdk-mini 34.12.0-2 → 34.12.0-3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (467) hide show
  1. package/git-revision.txt +1 -1
  2. package/lib/@types/global.d.js +0 -2
  3. package/lib/@types/global.d.js.map +1 -1
  4. package/lib/browser-index.d.ts.map +1 -1
  5. package/lib/browser-index.js +0 -11
  6. package/lib/browser-index.js.map +1 -1
  7. package/lib/client.d.ts +2 -1176
  8. package/lib/client.d.ts.map +1 -1
  9. package/lib/client.js +346 -2717
  10. package/lib/client.js.map +1 -1
  11. package/lib/embedded.d.ts +0 -22
  12. package/lib/embedded.d.ts.map +1 -1
  13. package/lib/embedded.js +24 -166
  14. package/lib/embedded.js.map +1 -1
  15. package/lib/event-mapper.d.ts.map +1 -1
  16. package/lib/event-mapper.js +0 -4
  17. package/lib/event-mapper.js.map +1 -1
  18. package/lib/matrix.d.ts +0 -19
  19. package/lib/matrix.d.ts.map +1 -1
  20. package/lib/matrix.js +1 -26
  21. package/lib/matrix.js.map +1 -1
  22. package/lib/models/MSC3089Branch.d.ts.map +1 -1
  23. package/lib/models/MSC3089Branch.js +0 -3
  24. package/lib/models/MSC3089Branch.js.map +1 -1
  25. package/lib/models/event.d.ts +0 -94
  26. package/lib/models/event.d.ts.map +1 -1
  27. package/lib/models/event.js +0 -274
  28. package/lib/models/event.js.map +1 -1
  29. package/lib/models/poll.d.ts.map +1 -1
  30. package/lib/models/poll.js +1 -5
  31. package/lib/models/poll.js.map +1 -1
  32. package/lib/models/relations-container.d.ts.map +1 -1
  33. package/lib/models/relations-container.js +1 -7
  34. package/lib/models/relations-container.js.map +1 -1
  35. package/lib/models/relations.d.ts +0 -1
  36. package/lib/models/relations.d.ts.map +1 -1
  37. package/lib/models/relations.js +0 -8
  38. package/lib/models/relations.js.map +1 -1
  39. package/lib/models/room-state.d.ts.map +1 -1
  40. package/lib/models/room-state.js +10 -26
  41. package/lib/models/room-state.js.map +1 -1
  42. package/lib/models/room.d.ts +0 -18
  43. package/lib/models/room.d.ts.map +1 -1
  44. package/lib/models/room.js +94 -148
  45. package/lib/models/room.js.map +1 -1
  46. package/lib/models/thread.d.ts.map +1 -1
  47. package/lib/models/thread.js +0 -1
  48. package/lib/models/thread.js.map +1 -1
  49. package/lib/sliding-sync-sdk.d.ts +2 -3
  50. package/lib/sliding-sync-sdk.d.ts.map +1 -1
  51. package/lib/sliding-sync-sdk.js +41 -90
  52. package/lib/sliding-sync-sdk.js.map +1 -1
  53. package/lib/sync.d.ts +0 -12
  54. package/lib/sync.d.ts.map +1 -1
  55. package/lib/sync.js +1 -73
  56. package/lib/sync.js.map +1 -1
  57. package/lib/testing.d.ts +0 -48
  58. package/lib/testing.d.ts.map +1 -1
  59. package/lib/testing.js +0 -105
  60. package/lib/testing.js.map +1 -1
  61. package/package.json +1 -3
  62. package/src/@types/global.d.ts +0 -3
  63. package/src/browser-index.ts +0 -11
  64. package/src/client.ts +57 -2732
  65. package/src/embedded.ts +3 -130
  66. package/src/event-mapper.ts +0 -4
  67. package/src/matrix.ts +0 -28
  68. package/src/models/MSC3089Branch.ts +0 -3
  69. package/src/models/event.ts +0 -289
  70. package/src/models/poll.ts +0 -6
  71. package/src/models/relations-container.ts +1 -8
  72. package/src/models/relations.ts +0 -8
  73. package/src/models/room-state.ts +2 -8
  74. package/src/models/room.ts +0 -62
  75. package/src/models/thread.ts +0 -1
  76. package/src/sliding-sync-sdk.ts +2 -72
  77. package/src/sync.ts +1 -98
  78. package/src/testing.ts +0 -108
  79. package/lib/@types/crypto.d.ts +0 -47
  80. package/lib/@types/crypto.d.ts.map +0 -1
  81. package/lib/@types/crypto.js +0 -1
  82. package/lib/@types/crypto.js.map +0 -1
  83. package/lib/@types/matrix-sdk-crypto-wasm.d.js +0 -1
  84. package/lib/@types/matrix-sdk-crypto-wasm.d.js.map +0 -1
  85. package/lib/common-crypto/CryptoBackend.d.ts +0 -240
  86. package/lib/common-crypto/CryptoBackend.d.ts.map +0 -1
  87. package/lib/common-crypto/CryptoBackend.js +0 -73
  88. package/lib/common-crypto/CryptoBackend.js.map +0 -1
  89. package/lib/common-crypto/key-passphrase.d.ts +0 -14
  90. package/lib/common-crypto/key-passphrase.d.ts.map +0 -1
  91. package/lib/common-crypto/key-passphrase.js +0 -33
  92. package/lib/common-crypto/key-passphrase.js.map +0 -1
  93. package/lib/crypto/CrossSigning.d.ts +0 -184
  94. package/lib/crypto/CrossSigning.d.ts.map +0 -1
  95. package/lib/crypto/CrossSigning.js +0 -718
  96. package/lib/crypto/CrossSigning.js.map +0 -1
  97. package/lib/crypto/DeviceList.d.ts +0 -216
  98. package/lib/crypto/DeviceList.d.ts.map +0 -1
  99. package/lib/crypto/DeviceList.js +0 -892
  100. package/lib/crypto/DeviceList.js.map +0 -1
  101. package/lib/crypto/EncryptionSetup.d.ts +0 -152
  102. package/lib/crypto/EncryptionSetup.d.ts.map +0 -1
  103. package/lib/crypto/EncryptionSetup.js +0 -356
  104. package/lib/crypto/EncryptionSetup.js.map +0 -1
  105. package/lib/crypto/OlmDevice.d.ts +0 -457
  106. package/lib/crypto/OlmDevice.d.ts.map +0 -1
  107. package/lib/crypto/OlmDevice.js +0 -1241
  108. package/lib/crypto/OlmDevice.js.map +0 -1
  109. package/lib/crypto/OutgoingRoomKeyRequestManager.d.ts +0 -109
  110. package/lib/crypto/OutgoingRoomKeyRequestManager.d.ts.map +0 -1
  111. package/lib/crypto/OutgoingRoomKeyRequestManager.js +0 -415
  112. package/lib/crypto/OutgoingRoomKeyRequestManager.js.map +0 -1
  113. package/lib/crypto/RoomList.d.ts +0 -26
  114. package/lib/crypto/RoomList.d.ts.map +0 -1
  115. package/lib/crypto/RoomList.js +0 -71
  116. package/lib/crypto/RoomList.js.map +0 -1
  117. package/lib/crypto/SecretSharing.d.ts +0 -24
  118. package/lib/crypto/SecretSharing.d.ts.map +0 -1
  119. package/lib/crypto/SecretSharing.js +0 -194
  120. package/lib/crypto/SecretSharing.js.map +0 -1
  121. package/lib/crypto/SecretStorage.d.ts +0 -55
  122. package/lib/crypto/SecretStorage.d.ts.map +0 -1
  123. package/lib/crypto/SecretStorage.js +0 -118
  124. package/lib/crypto/SecretStorage.js.map +0 -1
  125. package/lib/crypto/aes.d.ts +0 -6
  126. package/lib/crypto/aes.d.ts.map +0 -1
  127. package/lib/crypto/aes.js +0 -24
  128. package/lib/crypto/aes.js.map +0 -1
  129. package/lib/crypto/algorithms/base.d.ts +0 -156
  130. package/lib/crypto/algorithms/base.d.ts.map +0 -1
  131. package/lib/crypto/algorithms/base.js +0 -187
  132. package/lib/crypto/algorithms/base.js.map +0 -1
  133. package/lib/crypto/algorithms/index.d.ts +0 -4
  134. package/lib/crypto/algorithms/index.d.ts.map +0 -1
  135. package/lib/crypto/algorithms/index.js +0 -20
  136. package/lib/crypto/algorithms/index.js.map +0 -1
  137. package/lib/crypto/algorithms/megolm.d.ts +0 -385
  138. package/lib/crypto/algorithms/megolm.d.ts.map +0 -1
  139. package/lib/crypto/algorithms/megolm.js +0 -1822
  140. package/lib/crypto/algorithms/megolm.js.map +0 -1
  141. package/lib/crypto/algorithms/olm.d.ts +0 -5
  142. package/lib/crypto/algorithms/olm.d.ts.map +0 -1
  143. package/lib/crypto/algorithms/olm.js +0 -299
  144. package/lib/crypto/algorithms/olm.js.map +0 -1
  145. package/lib/crypto/api.d.ts +0 -32
  146. package/lib/crypto/api.d.ts.map +0 -1
  147. package/lib/crypto/api.js +0 -22
  148. package/lib/crypto/api.js.map +0 -1
  149. package/lib/crypto/backup.d.ts +0 -227
  150. package/lib/crypto/backup.d.ts.map +0 -1
  151. package/lib/crypto/backup.js +0 -824
  152. package/lib/crypto/backup.js.map +0 -1
  153. package/lib/crypto/crypto.d.ts +0 -3
  154. package/lib/crypto/crypto.d.ts.map +0 -1
  155. package/lib/crypto/crypto.js +0 -19
  156. package/lib/crypto/crypto.js.map +0 -1
  157. package/lib/crypto/dehydration.d.ts +0 -34
  158. package/lib/crypto/dehydration.d.ts.map +0 -1
  159. package/lib/crypto/dehydration.js +0 -252
  160. package/lib/crypto/dehydration.js.map +0 -1
  161. package/lib/crypto/device-converter.d.ts +0 -9
  162. package/lib/crypto/device-converter.d.ts.map +0 -1
  163. package/lib/crypto/device-converter.js +0 -42
  164. package/lib/crypto/device-converter.js.map +0 -1
  165. package/lib/crypto/deviceinfo.d.ts +0 -99
  166. package/lib/crypto/deviceinfo.d.ts.map +0 -1
  167. package/lib/crypto/deviceinfo.js +0 -148
  168. package/lib/crypto/deviceinfo.js.map +0 -1
  169. package/lib/crypto/index.d.ts +0 -1209
  170. package/lib/crypto/index.d.ts.map +0 -1
  171. package/lib/crypto/index.js +0 -4097
  172. package/lib/crypto/index.js.map +0 -1
  173. package/lib/crypto/key_passphrase.d.ts +0 -14
  174. package/lib/crypto/key_passphrase.d.ts.map +0 -1
  175. package/lib/crypto/key_passphrase.js +0 -44
  176. package/lib/crypto/key_passphrase.js.map +0 -1
  177. package/lib/crypto/keybackup.d.ts +0 -18
  178. package/lib/crypto/keybackup.d.ts.map +0 -1
  179. package/lib/crypto/keybackup.js +0 -1
  180. package/lib/crypto/keybackup.js.map +0 -1
  181. package/lib/crypto/olmlib.d.ts +0 -129
  182. package/lib/crypto/olmlib.d.ts.map +0 -1
  183. package/lib/crypto/olmlib.js +0 -492
  184. package/lib/crypto/olmlib.js.map +0 -1
  185. package/lib/crypto/recoverykey.d.ts +0 -2
  186. package/lib/crypto/recoverykey.d.ts.map +0 -1
  187. package/lib/crypto/recoverykey.js +0 -19
  188. package/lib/crypto/recoverykey.js.map +0 -1
  189. package/lib/crypto/store/base.d.ts +0 -252
  190. package/lib/crypto/store/base.d.ts.map +0 -1
  191. package/lib/crypto/store/base.js +0 -64
  192. package/lib/crypto/store/base.js.map +0 -1
  193. package/lib/crypto/store/indexeddb-crypto-store-backend.d.ts +0 -187
  194. package/lib/crypto/store/indexeddb-crypto-store-backend.d.ts.map +0 -1
  195. package/lib/crypto/store/indexeddb-crypto-store-backend.js +0 -1145
  196. package/lib/crypto/store/indexeddb-crypto-store-backend.js.map +0 -1
  197. package/lib/crypto/store/indexeddb-crypto-store.d.ts +0 -432
  198. package/lib/crypto/store/indexeddb-crypto-store.d.ts.map +0 -1
  199. package/lib/crypto/store/indexeddb-crypto-store.js +0 -728
  200. package/lib/crypto/store/indexeddb-crypto-store.js.map +0 -1
  201. package/lib/crypto/store/localStorage-crypto-store.d.ts +0 -119
  202. package/lib/crypto/store/localStorage-crypto-store.d.ts.map +0 -1
  203. package/lib/crypto/store/localStorage-crypto-store.js +0 -531
  204. package/lib/crypto/store/localStorage-crypto-store.js.map +0 -1
  205. package/lib/crypto/store/memory-crypto-store.d.ts +0 -215
  206. package/lib/crypto/store/memory-crypto-store.d.ts.map +0 -1
  207. package/lib/crypto/store/memory-crypto-store.js +0 -622
  208. package/lib/crypto/store/memory-crypto-store.js.map +0 -1
  209. package/lib/crypto/verification/Base.d.ts +0 -105
  210. package/lib/crypto/verification/Base.d.ts.map +0 -1
  211. package/lib/crypto/verification/Base.js +0 -372
  212. package/lib/crypto/verification/Base.js.map +0 -1
  213. package/lib/crypto/verification/Error.d.ts +0 -35
  214. package/lib/crypto/verification/Error.d.ts.map +0 -1
  215. package/lib/crypto/verification/Error.js +0 -86
  216. package/lib/crypto/verification/Error.js.map +0 -1
  217. package/lib/crypto/verification/IllegalMethod.d.ts +0 -15
  218. package/lib/crypto/verification/IllegalMethod.d.ts.map +0 -1
  219. package/lib/crypto/verification/IllegalMethod.js +0 -43
  220. package/lib/crypto/verification/IllegalMethod.js.map +0 -1
  221. package/lib/crypto/verification/QRCode.d.ts +0 -51
  222. package/lib/crypto/verification/QRCode.d.ts.map +0 -1
  223. package/lib/crypto/verification/QRCode.js +0 -277
  224. package/lib/crypto/verification/QRCode.js.map +0 -1
  225. package/lib/crypto/verification/SAS.d.ts +0 -27
  226. package/lib/crypto/verification/SAS.d.ts.map +0 -1
  227. package/lib/crypto/verification/SAS.js +0 -485
  228. package/lib/crypto/verification/SAS.js.map +0 -1
  229. package/lib/crypto/verification/SASDecimal.d.ts +0 -8
  230. package/lib/crypto/verification/SASDecimal.d.ts.map +0 -1
  231. package/lib/crypto/verification/SASDecimal.js +0 -34
  232. package/lib/crypto/verification/SASDecimal.js.map +0 -1
  233. package/lib/crypto/verification/request/Channel.d.ts +0 -18
  234. package/lib/crypto/verification/request/Channel.d.ts.map +0 -1
  235. package/lib/crypto/verification/request/Channel.js +0 -1
  236. package/lib/crypto/verification/request/Channel.js.map +0 -1
  237. package/lib/crypto/verification/request/InRoomChannel.d.ts +0 -113
  238. package/lib/crypto/verification/request/InRoomChannel.d.ts.map +0 -1
  239. package/lib/crypto/verification/request/InRoomChannel.js +0 -351
  240. package/lib/crypto/verification/request/InRoomChannel.js.map +0 -1
  241. package/lib/crypto/verification/request/ToDeviceChannel.d.ts +0 -105
  242. package/lib/crypto/verification/request/ToDeviceChannel.d.ts.map +0 -1
  243. package/lib/crypto/verification/request/ToDeviceChannel.js +0 -328
  244. package/lib/crypto/verification/request/ToDeviceChannel.js.map +0 -1
  245. package/lib/crypto/verification/request/VerificationRequest.d.ts +0 -227
  246. package/lib/crypto/verification/request/VerificationRequest.d.ts.map +0 -1
  247. package/lib/crypto/verification/request/VerificationRequest.js +0 -937
  248. package/lib/crypto/verification/request/VerificationRequest.js.map +0 -1
  249. package/lib/crypto-api/CryptoEvent.d.ts +0 -69
  250. package/lib/crypto-api/CryptoEvent.d.ts.map +0 -1
  251. package/lib/crypto-api/CryptoEvent.js +0 -33
  252. package/lib/crypto-api/CryptoEvent.js.map +0 -1
  253. package/lib/crypto-api/CryptoEventHandlerMap.d.ts +0 -16
  254. package/lib/crypto-api/CryptoEventHandlerMap.d.ts.map +0 -1
  255. package/lib/crypto-api/CryptoEventHandlerMap.js +0 -22
  256. package/lib/crypto-api/CryptoEventHandlerMap.js.map +0 -1
  257. package/lib/crypto-api/index.d.ts +0 -978
  258. package/lib/crypto-api/index.d.ts.map +0 -1
  259. package/lib/crypto-api/index.js +0 -304
  260. package/lib/crypto-api/index.js.map +0 -1
  261. package/lib/crypto-api/key-passphrase.d.ts +0 -11
  262. package/lib/crypto-api/key-passphrase.d.ts.map +0 -1
  263. package/lib/crypto-api/key-passphrase.js +0 -51
  264. package/lib/crypto-api/key-passphrase.js.map +0 -1
  265. package/lib/crypto-api/keybackup.d.ts +0 -88
  266. package/lib/crypto-api/keybackup.d.ts.map +0 -1
  267. package/lib/crypto-api/keybackup.js +0 -1
  268. package/lib/crypto-api/keybackup.js.map +0 -1
  269. package/lib/crypto-api/recovery-key.d.ts +0 -11
  270. package/lib/crypto-api/recovery-key.d.ts.map +0 -1
  271. package/lib/crypto-api/recovery-key.js +0 -65
  272. package/lib/crypto-api/recovery-key.js.map +0 -1
  273. package/lib/crypto-api/verification.d.ts +0 -344
  274. package/lib/crypto-api/verification.d.ts.map +0 -1
  275. package/lib/crypto-api/verification.js +0 -91
  276. package/lib/crypto-api/verification.js.map +0 -1
  277. package/lib/rendezvous/MSC4108SignInWithQR.d.ts +0 -112
  278. package/lib/rendezvous/MSC4108SignInWithQR.d.ts.map +0 -1
  279. package/lib/rendezvous/MSC4108SignInWithQR.js +0 -392
  280. package/lib/rendezvous/MSC4108SignInWithQR.js.map +0 -1
  281. package/lib/rendezvous/RendezvousChannel.d.ts +0 -27
  282. package/lib/rendezvous/RendezvousChannel.d.ts.map +0 -1
  283. package/lib/rendezvous/RendezvousChannel.js +0 -1
  284. package/lib/rendezvous/RendezvousChannel.js.map +0 -1
  285. package/lib/rendezvous/RendezvousCode.d.ts +0 -9
  286. package/lib/rendezvous/RendezvousCode.d.ts.map +0 -1
  287. package/lib/rendezvous/RendezvousCode.js +0 -1
  288. package/lib/rendezvous/RendezvousCode.js.map +0 -1
  289. package/lib/rendezvous/RendezvousError.d.ts +0 -6
  290. package/lib/rendezvous/RendezvousError.d.ts.map +0 -1
  291. package/lib/rendezvous/RendezvousError.js +0 -23
  292. package/lib/rendezvous/RendezvousError.js.map +0 -1
  293. package/lib/rendezvous/RendezvousFailureReason.d.ts +0 -31
  294. package/lib/rendezvous/RendezvousFailureReason.d.ts.map +0 -1
  295. package/lib/rendezvous/RendezvousFailureReason.js +0 -38
  296. package/lib/rendezvous/RendezvousFailureReason.js.map +0 -1
  297. package/lib/rendezvous/RendezvousIntent.d.ts +0 -5
  298. package/lib/rendezvous/RendezvousIntent.d.ts.map +0 -1
  299. package/lib/rendezvous/RendezvousIntent.js +0 -22
  300. package/lib/rendezvous/RendezvousIntent.js.map +0 -1
  301. package/lib/rendezvous/RendezvousTransport.d.ts +0 -36
  302. package/lib/rendezvous/RendezvousTransport.d.ts.map +0 -1
  303. package/lib/rendezvous/RendezvousTransport.js +0 -1
  304. package/lib/rendezvous/RendezvousTransport.js.map +0 -1
  305. package/lib/rendezvous/channels/MSC4108SecureChannel.d.ts +0 -58
  306. package/lib/rendezvous/channels/MSC4108SecureChannel.d.ts.map +0 -1
  307. package/lib/rendezvous/channels/MSC4108SecureChannel.js +0 -246
  308. package/lib/rendezvous/channels/MSC4108SecureChannel.js.map +0 -1
  309. package/lib/rendezvous/channels/index.d.ts +0 -2
  310. package/lib/rendezvous/channels/index.d.ts.map +0 -1
  311. package/lib/rendezvous/channels/index.js +0 -18
  312. package/lib/rendezvous/channels/index.js.map +0 -1
  313. package/lib/rendezvous/index.d.ts +0 -10
  314. package/lib/rendezvous/index.d.ts.map +0 -1
  315. package/lib/rendezvous/index.js +0 -23
  316. package/lib/rendezvous/index.js.map +0 -1
  317. package/lib/rendezvous/transports/MSC4108RendezvousSession.d.ts +0 -61
  318. package/lib/rendezvous/transports/MSC4108RendezvousSession.d.ts.map +0 -1
  319. package/lib/rendezvous/transports/MSC4108RendezvousSession.js +0 -253
  320. package/lib/rendezvous/transports/MSC4108RendezvousSession.js.map +0 -1
  321. package/lib/rendezvous/transports/index.d.ts +0 -2
  322. package/lib/rendezvous/transports/index.d.ts.map +0 -1
  323. package/lib/rendezvous/transports/index.js +0 -18
  324. package/lib/rendezvous/transports/index.js.map +0 -1
  325. package/lib/rust-crypto/CrossSigningIdentity.d.ts +0 -33
  326. package/lib/rust-crypto/CrossSigningIdentity.d.ts.map +0 -1
  327. package/lib/rust-crypto/CrossSigningIdentity.js +0 -157
  328. package/lib/rust-crypto/CrossSigningIdentity.js.map +0 -1
  329. package/lib/rust-crypto/DehydratedDeviceManager.d.ts +0 -98
  330. package/lib/rust-crypto/DehydratedDeviceManager.d.ts.map +0 -1
  331. package/lib/rust-crypto/DehydratedDeviceManager.js +0 -285
  332. package/lib/rust-crypto/DehydratedDeviceManager.js.map +0 -1
  333. package/lib/rust-crypto/KeyClaimManager.d.ts +0 -33
  334. package/lib/rust-crypto/KeyClaimManager.d.ts.map +0 -1
  335. package/lib/rust-crypto/KeyClaimManager.js +0 -82
  336. package/lib/rust-crypto/KeyClaimManager.js.map +0 -1
  337. package/lib/rust-crypto/OutgoingRequestProcessor.d.ts +0 -43
  338. package/lib/rust-crypto/OutgoingRequestProcessor.d.ts.map +0 -1
  339. package/lib/rust-crypto/OutgoingRequestProcessor.js +0 -195
  340. package/lib/rust-crypto/OutgoingRequestProcessor.js.map +0 -1
  341. package/lib/rust-crypto/OutgoingRequestsManager.d.ts +0 -47
  342. package/lib/rust-crypto/OutgoingRequestsManager.d.ts.map +0 -1
  343. package/lib/rust-crypto/OutgoingRequestsManager.js +0 -148
  344. package/lib/rust-crypto/OutgoingRequestsManager.js.map +0 -1
  345. package/lib/rust-crypto/PerSessionKeyBackupDownloader.d.ts +0 -120
  346. package/lib/rust-crypto/PerSessionKeyBackupDownloader.d.ts.map +0 -1
  347. package/lib/rust-crypto/PerSessionKeyBackupDownloader.js +0 -467
  348. package/lib/rust-crypto/PerSessionKeyBackupDownloader.js.map +0 -1
  349. package/lib/rust-crypto/RoomEncryptor.d.ts +0 -98
  350. package/lib/rust-crypto/RoomEncryptor.d.ts.map +0 -1
  351. package/lib/rust-crypto/RoomEncryptor.js +0 -299
  352. package/lib/rust-crypto/RoomEncryptor.js.map +0 -1
  353. package/lib/rust-crypto/backup.d.ts +0 -254
  354. package/lib/rust-crypto/backup.d.ts.map +0 -1
  355. package/lib/rust-crypto/backup.js +0 -837
  356. package/lib/rust-crypto/backup.js.map +0 -1
  357. package/lib/rust-crypto/constants.d.ts +0 -3
  358. package/lib/rust-crypto/constants.d.ts.map +0 -1
  359. package/lib/rust-crypto/constants.js +0 -19
  360. package/lib/rust-crypto/constants.js.map +0 -1
  361. package/lib/rust-crypto/device-converter.d.ts +0 -28
  362. package/lib/rust-crypto/device-converter.d.ts.map +0 -1
  363. package/lib/rust-crypto/device-converter.js +0 -123
  364. package/lib/rust-crypto/device-converter.js.map +0 -1
  365. package/lib/rust-crypto/index.d.ts +0 -61
  366. package/lib/rust-crypto/index.d.ts.map +0 -1
  367. package/lib/rust-crypto/index.js +0 -152
  368. package/lib/rust-crypto/index.js.map +0 -1
  369. package/lib/rust-crypto/libolm_migration.d.ts +0 -81
  370. package/lib/rust-crypto/libolm_migration.d.ts.map +0 -1
  371. package/lib/rust-crypto/libolm_migration.js +0 -459
  372. package/lib/rust-crypto/libolm_migration.js.map +0 -1
  373. package/lib/rust-crypto/rust-crypto.d.ts +0 -556
  374. package/lib/rust-crypto/rust-crypto.d.ts.map +0 -1
  375. package/lib/rust-crypto/rust-crypto.js +0 -2016
  376. package/lib/rust-crypto/rust-crypto.js.map +0 -1
  377. package/lib/rust-crypto/secret-storage.d.ts +0 -22
  378. package/lib/rust-crypto/secret-storage.d.ts.map +0 -1
  379. package/lib/rust-crypto/secret-storage.js +0 -63
  380. package/lib/rust-crypto/secret-storage.js.map +0 -1
  381. package/lib/rust-crypto/verification.d.ts +0 -319
  382. package/lib/rust-crypto/verification.d.ts.map +0 -1
  383. package/lib/rust-crypto/verification.js +0 -816
  384. package/lib/rust-crypto/verification.js.map +0 -1
  385. package/lib/secret-storage.d.ts +0 -370
  386. package/lib/secret-storage.d.ts.map +0 -1
  387. package/lib/secret-storage.js +0 -466
  388. package/lib/secret-storage.js.map +0 -1
  389. package/src/@types/crypto.ts +0 -73
  390. package/src/@types/matrix-sdk-crypto-wasm.d.ts +0 -44
  391. package/src/common-crypto/CryptoBackend.ts +0 -302
  392. package/src/common-crypto/README.md +0 -4
  393. package/src/common-crypto/key-passphrase.ts +0 -43
  394. package/src/crypto/CrossSigning.ts +0 -773
  395. package/src/crypto/DeviceList.ts +0 -989
  396. package/src/crypto/EncryptionSetup.ts +0 -351
  397. package/src/crypto/OlmDevice.ts +0 -1500
  398. package/src/crypto/OutgoingRoomKeyRequestManager.ts +0 -485
  399. package/src/crypto/RoomList.ts +0 -70
  400. package/src/crypto/SecretSharing.ts +0 -240
  401. package/src/crypto/SecretStorage.ts +0 -136
  402. package/src/crypto/aes.ts +0 -23
  403. package/src/crypto/algorithms/base.ts +0 -236
  404. package/src/crypto/algorithms/index.ts +0 -20
  405. package/src/crypto/algorithms/megolm.ts +0 -2216
  406. package/src/crypto/algorithms/olm.ts +0 -381
  407. package/src/crypto/api.ts +0 -70
  408. package/src/crypto/backup.ts +0 -922
  409. package/src/crypto/crypto.ts +0 -18
  410. package/src/crypto/dehydration.ts +0 -272
  411. package/src/crypto/device-converter.ts +0 -45
  412. package/src/crypto/deviceinfo.ts +0 -158
  413. package/src/crypto/index.ts +0 -4414
  414. package/src/crypto/key_passphrase.ts +0 -42
  415. package/src/crypto/keybackup.ts +0 -47
  416. package/src/crypto/olmlib.ts +0 -539
  417. package/src/crypto/recoverykey.ts +0 -18
  418. package/src/crypto/store/base.ts +0 -348
  419. package/src/crypto/store/indexeddb-crypto-store-backend.ts +0 -1250
  420. package/src/crypto/store/indexeddb-crypto-store.ts +0 -845
  421. package/src/crypto/store/localStorage-crypto-store.ts +0 -579
  422. package/src/crypto/store/memory-crypto-store.ts +0 -680
  423. package/src/crypto/verification/Base.ts +0 -409
  424. package/src/crypto/verification/Error.ts +0 -76
  425. package/src/crypto/verification/IllegalMethod.ts +0 -50
  426. package/src/crypto/verification/QRCode.ts +0 -310
  427. package/src/crypto/verification/SAS.ts +0 -494
  428. package/src/crypto/verification/SASDecimal.ts +0 -37
  429. package/src/crypto/verification/request/Channel.ts +0 -34
  430. package/src/crypto/verification/request/InRoomChannel.ts +0 -371
  431. package/src/crypto/verification/request/ToDeviceChannel.ts +0 -354
  432. package/src/crypto/verification/request/VerificationRequest.ts +0 -976
  433. package/src/crypto-api/CryptoEvent.ts +0 -93
  434. package/src/crypto-api/CryptoEventHandlerMap.ts +0 -32
  435. package/src/crypto-api/index.ts +0 -1175
  436. package/src/crypto-api/key-passphrase.ts +0 -58
  437. package/src/crypto-api/keybackup.ts +0 -115
  438. package/src/crypto-api/recovery-key.ts +0 -69
  439. package/src/crypto-api/verification.ts +0 -408
  440. package/src/rendezvous/MSC4108SignInWithQR.ts +0 -444
  441. package/src/rendezvous/RendezvousChannel.ts +0 -48
  442. package/src/rendezvous/RendezvousCode.ts +0 -25
  443. package/src/rendezvous/RendezvousError.ts +0 -26
  444. package/src/rendezvous/RendezvousFailureReason.ts +0 -49
  445. package/src/rendezvous/RendezvousIntent.ts +0 -20
  446. package/src/rendezvous/RendezvousTransport.ts +0 -58
  447. package/src/rendezvous/channels/MSC4108SecureChannel.ts +0 -270
  448. package/src/rendezvous/channels/index.ts +0 -17
  449. package/src/rendezvous/index.ts +0 -25
  450. package/src/rendezvous/transports/MSC4108RendezvousSession.ts +0 -270
  451. package/src/rendezvous/transports/index.ts +0 -17
  452. package/src/rust-crypto/CrossSigningIdentity.ts +0 -183
  453. package/src/rust-crypto/DehydratedDeviceManager.ts +0 -306
  454. package/src/rust-crypto/KeyClaimManager.ts +0 -86
  455. package/src/rust-crypto/OutgoingRequestProcessor.ts +0 -236
  456. package/src/rust-crypto/OutgoingRequestsManager.ts +0 -143
  457. package/src/rust-crypto/PerSessionKeyBackupDownloader.ts +0 -501
  458. package/src/rust-crypto/RoomEncryptor.ts +0 -352
  459. package/src/rust-crypto/backup.ts +0 -881
  460. package/src/rust-crypto/constants.ts +0 -18
  461. package/src/rust-crypto/device-converter.ts +0 -128
  462. package/src/rust-crypto/index.ts +0 -237
  463. package/src/rust-crypto/libolm_migration.ts +0 -530
  464. package/src/rust-crypto/rust-crypto.ts +0 -2205
  465. package/src/rust-crypto/secret-storage.ts +0 -60
  466. package/src/rust-crypto/verification.ts +0 -830
  467. package/src/secret-storage.ts +0 -693
@@ -1,4097 +0,0 @@
1
- import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
- /*
6
- Copyright 2016 OpenMarket Ltd
7
- Copyright 2017 Vector Creations Ltd
8
- Copyright 2018-2019 New Vector Ltd
9
- Copyright 2019-2021 The Matrix.org Foundation C.I.C.
10
-
11
- Licensed under the Apache License, Version 2.0 (the "License");
12
- you may not use this file except in compliance with the License.
13
- You may obtain a copy of the License at
14
-
15
- http://www.apache.org/licenses/LICENSE-2.0
16
-
17
- Unless required by applicable law or agreed to in writing, software
18
- distributed under the License is distributed on an "AS IS" BASIS,
19
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
- See the License for the specific language governing permissions and
21
- limitations under the License.
22
- */
23
-
24
- import anotherjson from "another-json";
25
- import { v4 as uuidv4 } from "uuid";
26
- import { EventType, ToDeviceMessageId } from "../@types/event.js";
27
- import { TypedReEmitter } from "../ReEmitter.js";
28
- import { logger } from "../logger.js";
29
- import { OlmDevice } from "./OlmDevice.js";
30
- import * as olmlib from "./olmlib.js";
31
- import { DeviceList } from "./DeviceList.js";
32
- import { DeviceInfo } from "./deviceinfo.js";
33
- import * as algorithms from "./algorithms/index.js";
34
- import { createCryptoStoreCacheCallbacks, CrossSigningInfo, DeviceTrustLevel, UserTrustLevel } from "./CrossSigning.js";
35
- import { EncryptionSetupBuilder } from "./EncryptionSetup.js";
36
- import { SecretStorage as LegacySecretStorage } from "./SecretStorage.js";
37
- import { CrossSigningKey } from "./api.js";
38
- import { OutgoingRoomKeyRequestManager } from "./OutgoingRoomKeyRequestManager.js";
39
- import { IndexedDBCryptoStore } from "./store/indexeddb-crypto-store.js";
40
- import { ReciprocateQRCode, SCAN_QR_CODE_METHOD, SHOW_QR_CODE_METHOD } from "./verification/QRCode.js";
41
- import { SAS as SASVerification } from "./verification/SAS.js";
42
- import { keyFromPassphrase } from "./key_passphrase.js";
43
- import { VerificationRequest } from "./verification/request/VerificationRequest.js";
44
- import { InRoomChannel, InRoomRequests } from "./verification/request/InRoomChannel.js";
45
- import { ToDeviceChannel, ToDeviceRequests } from "./verification/request/ToDeviceChannel.js";
46
- import { IllegalMethod } from "./verification/IllegalMethod.js";
47
- import { KeySignatureUploadError } from "../errors.js";
48
- import { DehydrationManager } from "./dehydration.js";
49
- import { BackupManager, LibOlmBackupDecryptor, backupTrustInfoFromLegacyTrustInfo } from "./backup.js";
50
- import { RoomEvent } from "../models/room.js";
51
- import { RoomMemberEvent } from "../models/room-member.js";
52
- import { EventStatus, MatrixEvent, MatrixEventEvent } from "../models/event.js";
53
- import { ClientEvent, MatrixClient } from "../client.js";
54
- import { RoomList } from "./RoomList.js";
55
- import { TypedEventEmitter } from "../models/typed-event-emitter.js";
56
- import { DecryptionError } from "../common-crypto/CryptoBackend.js";
57
- import { RoomStateEvent } from "../models/room-state.js";
58
- import { MapWithDefault, recursiveMapToObject } from "../utils.js";
59
- import { calculateKeyCheck, SECRET_STORAGE_ALGORITHM_V1_AES, ServerSideSecretStorageImpl } from "../secret-storage.js";
60
- import { decodeRecoveryKey, DecryptionFailureCode, encodeRecoveryKey, EventShieldColour, EventShieldReason, CryptoEvent as CryptoApiCryptoEvent } from "../crypto-api/index.js";
61
- import { deviceInfoToDevice } from "./device-converter.js";
62
- import { ClientPrefix, MatrixError, Method } from "../http-api/index.js";
63
- import { decodeBase64, encodeBase64 } from "../base64.js";
64
- import { KnownMembership } from "../@types/membership.js";
65
- import decryptAESSecretStorageItem from "../utils/decryptAESSecretStorageItem.js";
66
- import encryptAESSecretStorageItem from "../utils/encryptAESSecretStorageItem.js";
67
-
68
- /* re-exports for backwards compatibility */
69
-
70
- var DeviceVerification = DeviceInfo.DeviceVerification;
71
- var defaultVerificationMethods = {
72
- [ReciprocateQRCode.NAME]: ReciprocateQRCode,
73
- [SASVerification.NAME]: SASVerification,
74
- // These two can't be used for actual verification, but we do
75
- // need to be able to define them here for the verification flows
76
- // to start.
77
- [SHOW_QR_CODE_METHOD]: IllegalMethod,
78
- [SCAN_QR_CODE_METHOD]: IllegalMethod
79
- };
80
-
81
- /**
82
- * verification method names
83
- */
84
- // legacy export identifier
85
- export var verificationMethods = {
86
- RECIPROCATE_QR_CODE: ReciprocateQRCode.NAME,
87
- SAS: SASVerification.NAME
88
- };
89
- // minimum time between attempting to unwedge an Olm session, if we succeeded
90
- // in creating a new session
91
- var MIN_FORCE_SESSION_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
92
- // minimum time between attempting to unwedge an Olm session, if we failed
93
- // to create a new session
94
- var FORCE_SESSION_RETRY_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes
95
-
96
- /* eslint-disable camelcase */
97
-
98
- /**
99
- * The parameters of a room key request. The details of the request may
100
- * vary with the crypto algorithm, but the management and storage layers for
101
- * outgoing requests expect it to have 'room_id' and 'session_id' properties.
102
- */
103
-
104
- /* eslint-enable camelcase */
105
-
106
- /* eslint-disable camelcase */
107
-
108
- /* eslint-enable camelcase */
109
-
110
- export var CryptoEvent = function (CryptoEvent) {
111
- CryptoEvent["DeviceVerificationChanged"] = "deviceVerificationChanged";
112
- CryptoEvent[CryptoEvent["UserTrustStatusChanged"] = CryptoApiCryptoEvent.UserTrustStatusChanged] = "UserTrustStatusChanged";
113
- CryptoEvent["UserCrossSigningUpdated"] = "userCrossSigningUpdated";
114
- CryptoEvent["RoomKeyRequest"] = "crypto.roomKeyRequest";
115
- CryptoEvent["RoomKeyRequestCancellation"] = "crypto.roomKeyRequestCancellation";
116
- CryptoEvent[CryptoEvent["KeyBackupStatus"] = CryptoApiCryptoEvent.KeyBackupStatus] = "KeyBackupStatus";
117
- CryptoEvent[CryptoEvent["KeyBackupFailed"] = CryptoApiCryptoEvent.KeyBackupFailed] = "KeyBackupFailed";
118
- CryptoEvent[CryptoEvent["KeyBackupSessionsRemaining"] = CryptoApiCryptoEvent.KeyBackupSessionsRemaining] = "KeyBackupSessionsRemaining";
119
- CryptoEvent[CryptoEvent["KeyBackupDecryptionKeyCached"] = CryptoApiCryptoEvent.KeyBackupDecryptionKeyCached] = "KeyBackupDecryptionKeyCached";
120
- CryptoEvent["KeySignatureUploadFailure"] = "crypto.keySignatureUploadFailure";
121
- CryptoEvent["VerificationRequest"] = "crypto.verification.request";
122
- CryptoEvent[CryptoEvent["VerificationRequestReceived"] = CryptoApiCryptoEvent.VerificationRequestReceived] = "VerificationRequestReceived";
123
- CryptoEvent["Warning"] = "crypto.warning";
124
- CryptoEvent[CryptoEvent["WillUpdateDevices"] = CryptoApiCryptoEvent.WillUpdateDevices] = "WillUpdateDevices";
125
- CryptoEvent[CryptoEvent["DevicesUpdated"] = CryptoApiCryptoEvent.DevicesUpdated] = "DevicesUpdated";
126
- CryptoEvent[CryptoEvent["KeysChanged"] = CryptoApiCryptoEvent.KeysChanged] = "KeysChanged";
127
- CryptoEvent[CryptoEvent["LegacyCryptoStoreMigrationProgress"] = CryptoApiCryptoEvent.LegacyCryptoStoreMigrationProgress] = "LegacyCryptoStoreMigrationProgress";
128
- return CryptoEvent;
129
- }({});
130
- export class Crypto extends TypedEventEmitter {
131
- /**
132
- * @returns The version of Olm.
133
- */
134
- static getOlmVersion() {
135
- return OlmDevice.getOlmVersion();
136
- }
137
- /**
138
- * Cryptography bits
139
- *
140
- * This module is internal to the js-sdk; the public API is via MatrixClient.
141
- *
142
- * @internal
143
- *
144
- * @param baseApis - base matrix api interface
145
- *
146
- * @param userId - The user ID for the local user
147
- *
148
- * @param deviceId - The identifier for this device.
149
- *
150
- * @param clientStore - the MatrixClient data store.
151
- *
152
- * @param cryptoStore - storage for the crypto layer.
153
- *
154
- * @param verificationMethods - Array of verification methods to use.
155
- * Each element can either be a string from MatrixClient.verificationMethods
156
- * or a class that implements a verification method.
157
- */
158
- constructor(baseApis, userId, deviceId, clientStore, cryptoStore, verificationMethods) {
159
- var _this;
160
- super();
161
- _this = this;
162
- this.baseApis = baseApis;
163
- this.userId = userId;
164
- this.deviceId = deviceId;
165
- this.clientStore = clientStore;
166
- this.cryptoStore = cryptoStore;
167
- _defineProperty(this, "backupManager", void 0);
168
- _defineProperty(this, "crossSigningInfo", void 0);
169
- _defineProperty(this, "olmDevice", void 0);
170
- _defineProperty(this, "deviceList", void 0);
171
- _defineProperty(this, "dehydrationManager", void 0);
172
- _defineProperty(this, "secretStorage", void 0);
173
- _defineProperty(this, "roomList", void 0);
174
- _defineProperty(this, "reEmitter", void 0);
175
- _defineProperty(this, "verificationMethods", void 0);
176
- _defineProperty(this, "supportedAlgorithms", void 0);
177
- _defineProperty(this, "outgoingRoomKeyRequestManager", void 0);
178
- _defineProperty(this, "toDeviceVerificationRequests", void 0);
179
- _defineProperty(this, "inRoomVerificationRequests", void 0);
180
- _defineProperty(this, "trustCrossSignedDevices", true);
181
- // the last time we did a check for the number of one-time-keys on the server.
182
- _defineProperty(this, "lastOneTimeKeyCheck", null);
183
- _defineProperty(this, "oneTimeKeyCheckInProgress", false);
184
- // EncryptionAlgorithm instance for each room
185
- _defineProperty(this, "roomEncryptors", new Map());
186
- // map from algorithm to DecryptionAlgorithm instance, for each room
187
- _defineProperty(this, "roomDecryptors", new Map());
188
- _defineProperty(this, "deviceKeys", {});
189
- // type: key
190
- _defineProperty(this, "globalBlacklistUnverifiedDevices", false);
191
- _defineProperty(this, "globalErrorOnUnknownDevices", true);
192
- // list of IncomingRoomKeyRequests/IncomingRoomKeyRequestCancellations
193
- // we received in the current sync.
194
- _defineProperty(this, "receivedRoomKeyRequests", []);
195
- _defineProperty(this, "receivedRoomKeyRequestCancellations", []);
196
- // true if we are currently processing received room key requests
197
- _defineProperty(this, "processingRoomKeyRequests", false);
198
- // controls whether device tracking is delayed
199
- // until calling encryptEvent or trackRoomDevices,
200
- // or done immediately upon enabling room encryption.
201
- _defineProperty(this, "lazyLoadMembers", false);
202
- // in case lazyLoadMembers is true,
203
- // track if an initial tracking of all the room members
204
- // has happened for a given room. This is delayed
205
- // to avoid loading room members as long as possible.
206
- _defineProperty(this, "roomDeviceTrackingState", {});
207
- // The timestamp of the minimum time at which we will retry forcing establishment
208
- // of a new session for each device, in milliseconds.
209
- // {
210
- // userId: {
211
- // deviceId: 1234567890000,
212
- // },
213
- // }
214
- // Map: user Id → device Id → timestamp
215
- _defineProperty(this, "forceNewSessionRetryTime", new MapWithDefault(() => new MapWithDefault(() => 0)));
216
- // This flag will be unset whilst the client processes a sync response
217
- // so that we don't start requesting keys until we've actually finished
218
- // processing the response.
219
- _defineProperty(this, "sendKeyRequestsImmediately", false);
220
- _defineProperty(this, "oneTimeKeyCount", void 0);
221
- _defineProperty(this, "needsNewFallback", void 0);
222
- _defineProperty(this, "fallbackCleanup", void 0);
223
- /*
224
- * Event handler for DeviceList's userNewDevices event
225
- */
226
- _defineProperty(this, "onDeviceListUserCrossSigningUpdated", /*#__PURE__*/function () {
227
- var _ref = _asyncToGenerator(function* (userId) {
228
- if (userId === _this.userId) {
229
- // An update to our own cross-signing key.
230
- // Get the new key first:
231
- var newCrossSigning = _this.deviceList.getStoredCrossSigningForUser(userId);
232
- var seenPubkey = newCrossSigning ? newCrossSigning.getId() : null;
233
- var currentPubkey = _this.crossSigningInfo.getId();
234
- var changed = currentPubkey !== seenPubkey;
235
- if (currentPubkey && seenPubkey && !changed) {
236
- // If it's not changed, just make sure everything is up to date
237
- yield _this.checkOwnCrossSigningTrust();
238
- } else {
239
- // We'll now be in a state where cross-signing on the account is not trusted
240
- // because our locally stored cross-signing keys will not match the ones
241
- // on the server for our account. So we clear our own stored cross-signing keys,
242
- // effectively disabling cross-signing until the user gets verified by the device
243
- // that reset the keys
244
- _this.storeTrustedSelfKeys(null);
245
- // emit cross-signing has been disabled
246
- _this.emit(CryptoEvent.KeysChanged, {});
247
- // as the trust for our own user has changed,
248
- // also emit an event for this
249
- _this.emit(CryptoEvent.UserTrustStatusChanged, _this.userId, _this.checkUserTrust(userId));
250
- }
251
- } else {
252
- yield _this.checkDeviceVerifications(userId);
253
-
254
- // Update verified before latch using the current state and save the new
255
- // latch value in the device list store.
256
- var crossSigning = _this.deviceList.getStoredCrossSigningForUser(userId);
257
- if (crossSigning) {
258
- crossSigning.updateCrossSigningVerifiedBefore(_this.checkUserTrust(userId).isCrossSigningVerified());
259
- _this.deviceList.setRawStoredCrossSigningForUser(userId, crossSigning.toStorage());
260
- }
261
- _this.emit(CryptoEvent.UserTrustStatusChanged, userId, _this.checkUserTrust(userId));
262
- }
263
- });
264
- return function (_x) {
265
- return _ref.apply(this, arguments);
266
- };
267
- }());
268
- _defineProperty(this, "onMembership", (event, member, oldMembership) => {
269
- try {
270
- this.onRoomMembership(event, member, oldMembership);
271
- } catch (e) {
272
- logger.error("Error handling membership change:", e);
273
- }
274
- });
275
- _defineProperty(this, "onToDeviceEvent", event => {
276
- try {
277
- logger.log("received to-device ".concat(event.getType(), " from: ") + "".concat(event.getSender(), " id: ").concat(event.getContent()[ToDeviceMessageId]));
278
- if (event.getType() == "m.room_key" || event.getType() == "m.forwarded_room_key") {
279
- this.onRoomKeyEvent(event);
280
- } else if (event.getType() == "m.room_key_request") {
281
- this.onRoomKeyRequestEvent(event);
282
- } else if (event.getType() === "m.secret.request") {
283
- this.secretStorage.onRequestReceived(event);
284
- } else if (event.getType() === "m.secret.send") {
285
- this.secretStorage.onSecretReceived(event);
286
- } else if (event.getType() === "m.room_key.withheld") {
287
- this.onRoomKeyWithheldEvent(event);
288
- } else if (event.getContent().transaction_id) {
289
- this.onKeyVerificationMessage(event);
290
- } else if (event.getContent().msgtype === "m.bad.encrypted") {
291
- this.onToDeviceBadEncrypted(event);
292
- } else if (event.isBeingDecrypted() || event.shouldAttemptDecryption()) {
293
- if (!event.isBeingDecrypted()) {
294
- event.attemptDecryption(this);
295
- }
296
- // once the event has been decrypted, try again
297
- event.once(MatrixEventEvent.Decrypted, ev => {
298
- this.onToDeviceEvent(ev);
299
- });
300
- }
301
- } catch (e) {
302
- logger.error("Error handling toDeviceEvent:", e);
303
- }
304
- });
305
- /**
306
- * Handle key verification requests sent as timeline events
307
- *
308
- * @internal
309
- * @param event - the timeline event
310
- * @param room - not used
311
- * @param atStart - not used
312
- * @param removed - not used
313
- * @param whether - this is a live event
314
- */
315
- _defineProperty(this, "onTimelineEvent", function (event, room, atStart, removed) {
316
- var {
317
- liveEvent = true
318
- } = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
319
- if (!InRoomChannel.validateEvent(event, _this.baseApis)) {
320
- return;
321
- }
322
- var createRequest = event => {
323
- var channel = new InRoomChannel(_this.baseApis, event.getRoomId());
324
- return new VerificationRequest(channel, _this.verificationMethods, _this.baseApis);
325
- };
326
- _this.handleVerificationEvent(event, _this.inRoomVerificationRequests, createRequest, liveEvent);
327
- });
328
- logger.debug("Crypto: initialising roomlist...");
329
- this.roomList = new RoomList(cryptoStore);
330
- this.reEmitter = new TypedReEmitter(this);
331
- if (verificationMethods) {
332
- this.verificationMethods = new Map();
333
- for (var method of verificationMethods) {
334
- if (typeof method === "string") {
335
- if (defaultVerificationMethods[method]) {
336
- this.verificationMethods.set(method, defaultVerificationMethods[method]);
337
- }
338
- } else if (method["NAME"]) {
339
- this.verificationMethods.set(method["NAME"], method);
340
- } else {
341
- logger.warn("Excluding unknown verification method ".concat(method));
342
- }
343
- }
344
- } else {
345
- this.verificationMethods = new Map(Object.entries(defaultVerificationMethods));
346
- }
347
- this.backupManager = new BackupManager(baseApis, /*#__PURE__*/_asyncToGenerator(function* () {
348
- // try to get key from cache
349
- var cachedKey = yield _this.getSessionBackupPrivateKey();
350
- if (cachedKey) {
351
- return cachedKey;
352
- }
353
-
354
- // try to get key from secret storage
355
- var storedKey = yield _this.secretStorage.get("m.megolm_backup.v1");
356
- if (storedKey) {
357
- // ensure that the key is in the right format. If not, fix the key and
358
- // store the fixed version
359
- var fixedKey = fixBackupKey(storedKey);
360
- if (fixedKey) {
361
- var keys = yield _this.secretStorage.getKey();
362
- yield _this.secretStorage.store("m.megolm_backup.v1", fixedKey, [keys[0]]);
363
- }
364
- return decodeBase64(fixedKey || storedKey);
365
- }
366
-
367
- // try to get key from app
368
- if (_this.baseApis.cryptoCallbacks && _this.baseApis.cryptoCallbacks.getBackupKey) {
369
- return _this.baseApis.cryptoCallbacks.getBackupKey();
370
- }
371
- throw new Error("Unable to get private key");
372
- }));
373
- this.olmDevice = new OlmDevice(cryptoStore);
374
- this.deviceList = new DeviceList(baseApis, cryptoStore, this.olmDevice);
375
-
376
- // XXX: This isn't removed at any point, but then none of the event listeners
377
- // this class sets seem to be removed at any point... :/
378
- this.deviceList.on(CryptoEvent.UserCrossSigningUpdated, this.onDeviceListUserCrossSigningUpdated);
379
- this.reEmitter.reEmit(this.deviceList, [CryptoEvent.DevicesUpdated, CryptoEvent.WillUpdateDevices]);
380
- this.supportedAlgorithms = Array.from(algorithms.DECRYPTION_CLASSES.keys());
381
- this.outgoingRoomKeyRequestManager = new OutgoingRoomKeyRequestManager(baseApis, this.deviceId, this.cryptoStore);
382
- this.toDeviceVerificationRequests = new ToDeviceRequests();
383
- this.inRoomVerificationRequests = new InRoomRequests();
384
- var cryptoCallbacks = this.baseApis.cryptoCallbacks || {};
385
- var cacheCallbacks = createCryptoStoreCacheCallbacks(cryptoStore, this.olmDevice);
386
- this.crossSigningInfo = new CrossSigningInfo(userId, cryptoCallbacks, cacheCallbacks);
387
- // Yes, we pass the client twice here: see SecretStorage
388
- this.secretStorage = new LegacySecretStorage(baseApis, cryptoCallbacks, baseApis);
389
- this.dehydrationManager = new DehydrationManager(this);
390
-
391
- // Assuming no app-supplied callback, default to getting from SSSS.
392
- if (!cryptoCallbacks.getCrossSigningKey && cryptoCallbacks.getSecretStorageKey) {
393
- cryptoCallbacks.getCrossSigningKey = /*#__PURE__*/function () {
394
- var _ref3 = _asyncToGenerator(function* (type) {
395
- return CrossSigningInfo.getFromSecretStorage(type, _this.secretStorage);
396
- });
397
- return function (_x2) {
398
- return _ref3.apply(this, arguments);
399
- };
400
- }();
401
- }
402
- }
403
-
404
- /**
405
- * Initialise the crypto module so that it is ready for use
406
- *
407
- * Returns a promise which resolves once the crypto module is ready for use.
408
- *
409
- * @param exportedOlmDevice - (Optional) data from exported device
410
- * that must be re-created.
411
- */
412
- init() {
413
- var _arguments = arguments,
414
- _this2 = this;
415
- return _asyncToGenerator(function* () {
416
- var {
417
- exportedOlmDevice,
418
- pickleKey
419
- } = _arguments.length > 0 && _arguments[0] !== undefined ? _arguments[0] : {};
420
- logger.log("Crypto: initialising Olm...");
421
- yield globalThis.Olm.init();
422
- logger.log(exportedOlmDevice ? "Crypto: initialising Olm device from exported device..." : "Crypto: initialising Olm device...");
423
- yield _this2.olmDevice.init({
424
- fromExportedDevice: exportedOlmDevice,
425
- pickleKey
426
- });
427
- logger.log("Crypto: loading device list...");
428
- yield _this2.deviceList.load();
429
-
430
- // build our device keys: these will later be uploaded
431
- _this2.deviceKeys["ed25519:" + _this2.deviceId] = _this2.olmDevice.deviceEd25519Key;
432
- _this2.deviceKeys["curve25519:" + _this2.deviceId] = _this2.olmDevice.deviceCurve25519Key;
433
- logger.log("Crypto: fetching own devices...");
434
- var myDevices = _this2.deviceList.getRawStoredDevicesForUser(_this2.userId);
435
- if (!myDevices) {
436
- myDevices = {};
437
- }
438
- if (!myDevices[_this2.deviceId]) {
439
- // add our own deviceinfo to the cryptoStore
440
- logger.log("Crypto: adding this device to the store...");
441
- var deviceInfo = {
442
- keys: _this2.deviceKeys,
443
- algorithms: _this2.supportedAlgorithms,
444
- verified: DeviceVerification.VERIFIED,
445
- known: true
446
- };
447
- myDevices[_this2.deviceId] = deviceInfo;
448
- _this2.deviceList.storeDevicesForUser(_this2.userId, myDevices);
449
- _this2.deviceList.saveIfDirty();
450
- }
451
- yield _this2.cryptoStore.doTxn("readonly", [IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
452
- _this2.cryptoStore.getCrossSigningKeys(txn, keys => {
453
- // can be an empty object after resetting cross-signing keys, see storeTrustedSelfKeys
454
- if (keys && Object.keys(keys).length !== 0) {
455
- logger.log("Loaded cross-signing public keys from crypto store");
456
- _this2.crossSigningInfo.setKeys(keys);
457
- }
458
- });
459
- });
460
- // make sure we are keeping track of our own devices
461
- // (this is important for key backups & things)
462
- _this2.deviceList.startTrackingDeviceList(_this2.userId);
463
- logger.debug("Crypto: initialising roomlist...");
464
- yield _this2.roomList.init();
465
- logger.log("Crypto: checking for key backup...");
466
- _this2.backupManager.checkAndStart();
467
- })();
468
- }
469
-
470
- /**
471
- * Implementation of {@link Crypto.CryptoApi#setDeviceIsolationMode}.
472
- */
473
- setDeviceIsolationMode(isolationMode) {
474
- throw new Error("Not supported");
475
- }
476
- /**
477
- * Implementation of {@link Crypto.CryptoApi#getVersion}.
478
- */
479
- getVersion() {
480
- var olmVersionTuple = Crypto.getOlmVersion();
481
- return "Olm ".concat(olmVersionTuple[0], ".").concat(olmVersionTuple[1], ".").concat(olmVersionTuple[2]);
482
- }
483
-
484
- /**
485
- * Whether to trust a others users signatures of their devices.
486
- * If false, devices will only be considered 'verified' if we have
487
- * verified that device individually (effectively disabling cross-signing).
488
- *
489
- * Default: true
490
- *
491
- * @returns True if trusting cross-signed devices
492
- */
493
- getTrustCrossSignedDevices() {
494
- return this.trustCrossSignedDevices;
495
- }
496
-
497
- /**
498
- * @deprecated Use {@link Crypto.CryptoApi#getTrustCrossSignedDevices}.
499
- */
500
- getCryptoTrustCrossSignedDevices() {
501
- return this.trustCrossSignedDevices;
502
- }
503
-
504
- /**
505
- * See getCryptoTrustCrossSignedDevices
506
- *
507
- * @param val - True to trust cross-signed devices
508
- */
509
- setTrustCrossSignedDevices(val) {
510
- this.trustCrossSignedDevices = val;
511
- for (var _userId of this.deviceList.getKnownUserIds()) {
512
- var devices = this.deviceList.getRawStoredDevicesForUser(_userId);
513
- for (var _deviceId of Object.keys(devices)) {
514
- var deviceTrust = this.checkDeviceTrust(_userId, _deviceId);
515
- // If the device is locally verified then isVerified() is always true,
516
- // so this will only have caused the value to change if the device is
517
- // cross-signing verified but not locally verified
518
- if (!deviceTrust.isLocallyVerified() && deviceTrust.isCrossSigningVerified()) {
519
- var deviceObj = this.deviceList.getStoredDevice(_userId, _deviceId);
520
- this.emit(CryptoEvent.DeviceVerificationChanged, _userId, _deviceId, deviceObj);
521
- }
522
- }
523
- }
524
- }
525
-
526
- /**
527
- * @deprecated Use {@link Crypto.CryptoApi#setTrustCrossSignedDevices}.
528
- */
529
- setCryptoTrustCrossSignedDevices(val) {
530
- this.setTrustCrossSignedDevices(val);
531
- }
532
-
533
- /**
534
- * Create a recovery key from a user-supplied passphrase.
535
- *
536
- * @param password - Passphrase string that can be entered by the user
537
- * when restoring the backup as an alternative to entering the recovery key.
538
- * Optional.
539
- * @returns Object with public key metadata, encoded private
540
- * recovery key which should be disposed of after displaying to the user,
541
- * and raw private key to avoid round tripping if needed.
542
- */
543
- createRecoveryKeyFromPassphrase(password) {
544
- return _asyncToGenerator(function* () {
545
- var decryption = new globalThis.Olm.PkDecryption();
546
- try {
547
- if (password) {
548
- var derivation = yield keyFromPassphrase(password);
549
- decryption.init_with_private_key(derivation.key);
550
- var privateKey = decryption.get_private_key();
551
- return {
552
- keyInfo: {
553
- passphrase: {
554
- algorithm: "m.pbkdf2",
555
- iterations: derivation.iterations,
556
- salt: derivation.salt
557
- }
558
- },
559
- privateKey: privateKey,
560
- encodedPrivateKey: encodeRecoveryKey(privateKey)
561
- };
562
- } else {
563
- decryption.generate_key();
564
- var _privateKey = decryption.get_private_key();
565
- return {
566
- privateKey: _privateKey,
567
- encodedPrivateKey: encodeRecoveryKey(_privateKey)
568
- };
569
- }
570
- } finally {
571
- decryption === null || decryption === void 0 || decryption.free();
572
- }
573
- })();
574
- }
575
-
576
- /**
577
- * Checks if the user has previously published cross-signing keys
578
- *
579
- * This means downloading the devicelist for the user and checking if the list includes
580
- * the cross-signing pseudo-device.
581
- *
582
- * @internal
583
- */
584
- userHasCrossSigningKeys() {
585
- var _arguments2 = arguments,
586
- _this3 = this;
587
- return _asyncToGenerator(function* () {
588
- var userId = _arguments2.length > 0 && _arguments2[0] !== undefined ? _arguments2[0] : _this3.userId;
589
- yield _this3.downloadKeys([userId]);
590
- return _this3.deviceList.getStoredCrossSigningForUser(userId) !== null;
591
- })();
592
- }
593
-
594
- /**
595
- * Checks whether cross signing:
596
- * - is enabled on this account and trusted by this device
597
- * - has private keys either cached locally or stored in secret storage
598
- *
599
- * If this function returns false, bootstrapCrossSigning() can be used
600
- * to fix things such that it returns true. That is to say, after
601
- * bootstrapCrossSigning() completes successfully, this function should
602
- * return true.
603
- *
604
- * The cross-signing API is currently UNSTABLE and may change without notice.
605
- *
606
- * @returns True if cross-signing is ready to be used on this device
607
- */
608
- isCrossSigningReady() {
609
- var _this4 = this;
610
- return _asyncToGenerator(function* () {
611
- var publicKeysOnDevice = _this4.crossSigningInfo.getId();
612
- var privateKeysExistSomewhere = (yield _this4.crossSigningInfo.isStoredInKeyCache()) || (yield _this4.crossSigningInfo.isStoredInSecretStorage(_this4.secretStorage));
613
- return !!(publicKeysOnDevice && privateKeysExistSomewhere);
614
- })();
615
- }
616
-
617
- /**
618
- * Checks whether secret storage:
619
- * - is enabled on this account
620
- * - is storing cross-signing private keys
621
- * - is storing session backup key (if enabled)
622
- *
623
- * If this function returns false, bootstrapSecretStorage() can be used
624
- * to fix things such that it returns true. That is to say, after
625
- * bootstrapSecretStorage() completes successfully, this function should
626
- * return true.
627
- *
628
- * The Secure Secret Storage API is currently UNSTABLE and may change without notice.
629
- *
630
- * @returns True if secret storage is ready to be used on this device
631
- */
632
- isSecretStorageReady() {
633
- var _this5 = this;
634
- return _asyncToGenerator(function* () {
635
- var secretStorageKeyInAccount = yield _this5.secretStorage.hasKey();
636
- var privateKeysInStorage = yield _this5.crossSigningInfo.isStoredInSecretStorage(_this5.secretStorage);
637
- var sessionBackupInStorage = !_this5.backupManager.getKeyBackupEnabled() || (yield _this5.baseApis.isKeyBackupKeyStored());
638
- return !!(secretStorageKeyInAccount && privateKeysInStorage && sessionBackupInStorage);
639
- })();
640
- }
641
-
642
- /**
643
- * Implementation of {@link Crypto.CryptoApi#getCrossSigningStatus}
644
- */
645
- getCrossSigningStatus() {
646
- var _this6 = this;
647
- return _asyncToGenerator(function* () {
648
- var _cacheCallbacks$getCr, _cacheCallbacks$getCr2, _cacheCallbacks$getCr3;
649
- var publicKeysOnDevice = Boolean(_this6.crossSigningInfo.getId());
650
- var privateKeysInSecretStorage = Boolean(yield _this6.crossSigningInfo.isStoredInSecretStorage(_this6.secretStorage));
651
- var cacheCallbacks = _this6.crossSigningInfo.getCacheCallbacks();
652
- var masterKey = Boolean(yield (_cacheCallbacks$getCr = cacheCallbacks.getCrossSigningKeyCache) === null || _cacheCallbacks$getCr === void 0 ? void 0 : _cacheCallbacks$getCr.call(cacheCallbacks, "master"));
653
- var selfSigningKey = Boolean(yield (_cacheCallbacks$getCr2 = cacheCallbacks.getCrossSigningKeyCache) === null || _cacheCallbacks$getCr2 === void 0 ? void 0 : _cacheCallbacks$getCr2.call(cacheCallbacks, "self_signing"));
654
- var userSigningKey = Boolean(yield (_cacheCallbacks$getCr3 = cacheCallbacks.getCrossSigningKeyCache) === null || _cacheCallbacks$getCr3 === void 0 ? void 0 : _cacheCallbacks$getCr3.call(cacheCallbacks, "user_signing"));
655
- return {
656
- publicKeysOnDevice,
657
- privateKeysInSecretStorage,
658
- privateKeysCachedLocally: {
659
- masterKey,
660
- selfSigningKey,
661
- userSigningKey
662
- }
663
- };
664
- })();
665
- }
666
-
667
- /**
668
- * Bootstrap cross-signing by creating keys if needed. If everything is already
669
- * set up, then no changes are made, so this is safe to run to ensure
670
- * cross-signing is ready for use.
671
- *
672
- * This function:
673
- * - creates new cross-signing keys if they are not found locally cached nor in
674
- * secret storage (if it has been setup)
675
- *
676
- * The cross-signing API is currently UNSTABLE and may change without notice.
677
- */
678
- bootstrapCrossSigning() {
679
- var _arguments3 = arguments,
680
- _this7 = this;
681
- return _asyncToGenerator(function* () {
682
- var {
683
- authUploadDeviceSigningKeys,
684
- setupNewCrossSigning
685
- } = _arguments3.length > 0 && _arguments3[0] !== undefined ? _arguments3[0] : {};
686
- logger.log("Bootstrapping cross-signing");
687
- var delegateCryptoCallbacks = _this7.baseApis.cryptoCallbacks;
688
- var builder = new EncryptionSetupBuilder(_this7.baseApis.store.accountData, delegateCryptoCallbacks);
689
- var crossSigningInfo = new CrossSigningInfo(_this7.userId, builder.crossSigningCallbacks, builder.crossSigningCallbacks);
690
-
691
- // Reset the cross-signing keys
692
- var resetCrossSigning = /*#__PURE__*/function () {
693
- var _ref4 = _asyncToGenerator(function* () {
694
- crossSigningInfo.resetKeys();
695
- // Sign master key with device key
696
- yield _this7.signObject(crossSigningInfo.keys.master);
697
-
698
- // Store auth flow helper function, as we need to call it when uploading
699
- // to ensure we handle auth errors properly.
700
- builder.addCrossSigningKeys(authUploadDeviceSigningKeys, crossSigningInfo.keys);
701
-
702
- // Cross-sign own device
703
- var device = _this7.deviceList.getStoredDevice(_this7.userId, _this7.deviceId);
704
- var deviceSignature = yield crossSigningInfo.signDevice(_this7.userId, device);
705
- builder.addKeySignature(_this7.userId, _this7.deviceId, deviceSignature);
706
-
707
- // Sign message key backup with cross-signing master key
708
- if (_this7.backupManager.backupInfo) {
709
- yield crossSigningInfo.signObject(_this7.backupManager.backupInfo.auth_data, "master");
710
- builder.addSessionBackup(_this7.backupManager.backupInfo);
711
- }
712
- });
713
- return function resetCrossSigning() {
714
- return _ref4.apply(this, arguments);
715
- };
716
- }();
717
- var publicKeysOnDevice = _this7.crossSigningInfo.getId();
718
- var privateKeysInCache = yield _this7.crossSigningInfo.isStoredInKeyCache();
719
- var privateKeysInStorage = yield _this7.crossSigningInfo.isStoredInSecretStorage(_this7.secretStorage);
720
- var privateKeysExistSomewhere = privateKeysInCache || privateKeysInStorage;
721
-
722
- // Log all relevant state for easier parsing of debug logs.
723
- logger.log({
724
- setupNewCrossSigning,
725
- publicKeysOnDevice,
726
- privateKeysInCache,
727
- privateKeysInStorage,
728
- privateKeysExistSomewhere
729
- });
730
- if (!privateKeysExistSomewhere || setupNewCrossSigning) {
731
- logger.log("Cross-signing private keys not found locally or in secret storage, " + "creating new keys");
732
- // If a user has multiple devices, it important to only call bootstrap
733
- // as part of some UI flow (and not silently during startup), as they
734
- // may have setup cross-signing on a platform which has not saved keys
735
- // to secret storage, and this would reset them. In such a case, you
736
- // should prompt the user to verify any existing devices first (and
737
- // request private keys from those devices) before calling bootstrap.
738
- yield resetCrossSigning();
739
- } else if (publicKeysOnDevice && privateKeysInCache) {
740
- logger.log("Cross-signing public keys trusted and private keys found locally");
741
- } else if (privateKeysInStorage) {
742
- logger.log("Cross-signing private keys not found locally, but they are available " + "in secret storage, reading storage and caching locally");
743
- yield _this7.checkOwnCrossSigningTrust({
744
- allowPrivateKeyRequests: true
745
- });
746
- }
747
-
748
- // Assuming no app-supplied callback, default to storing new private keys in
749
- // secret storage if it exists. If it does not, it is assumed this will be
750
- // done as part of setting up secret storage later.
751
- var crossSigningPrivateKeys = builder.crossSigningCallbacks.privateKeys;
752
- if (crossSigningPrivateKeys.size && !_this7.baseApis.cryptoCallbacks.saveCrossSigningKeys) {
753
- var secretStorage = new ServerSideSecretStorageImpl(builder.accountDataClientAdapter, builder.ssssCryptoCallbacks);
754
- if (yield secretStorage.hasKey()) {
755
- logger.log("Storing new cross-signing private keys in secret storage");
756
- // This is writing to in-memory account data in
757
- // builder.accountDataClientAdapter so won't fail
758
- yield CrossSigningInfo.storeInSecretStorage(crossSigningPrivateKeys, secretStorage);
759
- }
760
- }
761
- var operation = builder.buildOperation();
762
- yield operation.apply(_this7);
763
- // This persists private keys and public keys as trusted,
764
- // only do this if apply succeeded for now as retry isn't in place yet
765
- yield builder.persist(_this7);
766
- logger.log("Cross-signing ready");
767
- })();
768
- }
769
-
770
- /**
771
- * Bootstrap Secure Secret Storage if needed by creating a default key. If everything is
772
- * already set up, then no changes are made, so this is safe to run to ensure secret
773
- * storage is ready for use.
774
- *
775
- * This function
776
- * - creates a new Secure Secret Storage key if no default key exists
777
- * - if a key backup exists, it is migrated to store the key in the Secret
778
- * Storage
779
- * - creates a backup if none exists, and one is requested
780
- * - migrates Secure Secret Storage to use the latest algorithm, if an outdated
781
- * algorithm is found
782
- *
783
- * The Secure Secret Storage API is currently UNSTABLE and may change without notice.
784
- *
785
- * Returns:
786
- * A promise which resolves to key creation data for
787
- * SecretStorage#addKey: an object with `passphrase` etc fields.
788
- */
789
- // TODO this does not resolve with what it says it does
790
- bootstrapSecretStorage() {
791
- var _arguments4 = arguments,
792
- _this8 = this;
793
- return _asyncToGenerator(function* () {
794
- var {
795
- createSecretStorageKey = /*#__PURE__*/_asyncToGenerator(function* () {
796
- return {};
797
- }),
798
- keyBackupInfo,
799
- setupNewKeyBackup,
800
- setupNewSecretStorage,
801
- getKeyBackupPassphrase
802
- } = _arguments4.length > 0 && _arguments4[0] !== undefined ? _arguments4[0] : {};
803
- logger.log("Bootstrapping Secure Secret Storage");
804
- var delegateCryptoCallbacks = _this8.baseApis.cryptoCallbacks;
805
- var builder = new EncryptionSetupBuilder(_this8.baseApis.store.accountData, delegateCryptoCallbacks);
806
- var secretStorage = new ServerSideSecretStorageImpl(builder.accountDataClientAdapter, builder.ssssCryptoCallbacks);
807
-
808
- // the ID of the new SSSS key, if we create one
809
- var newKeyId = null;
810
-
811
- // create a new SSSS key and set it as default
812
- var createSSSS = /*#__PURE__*/function () {
813
- var _ref6 = _asyncToGenerator(function* (opts) {
814
- var {
815
- keyId,
816
- keyInfo
817
- } = yield secretStorage.addKey(SECRET_STORAGE_ALGORITHM_V1_AES, opts);
818
-
819
- // make the private key available to encrypt 4S secrets
820
- builder.ssssCryptoCallbacks.addPrivateKey(keyId, keyInfo, opts.key);
821
- yield secretStorage.setDefaultKeyId(keyId);
822
- return keyId;
823
- });
824
- return function createSSSS(_x3) {
825
- return _ref6.apply(this, arguments);
826
- };
827
- }();
828
- var ensureCanCheckPassphrase = /*#__PURE__*/function () {
829
- var _ref7 = _asyncToGenerator(function* (keyId, keyInfo) {
830
- if (!keyInfo.mac) {
831
- var _this8$baseApis$crypt, _this8$baseApis$crypt2;
832
- var key = yield (_this8$baseApis$crypt = (_this8$baseApis$crypt2 = _this8.baseApis.cryptoCallbacks).getSecretStorageKey) === null || _this8$baseApis$crypt === void 0 ? void 0 : _this8$baseApis$crypt.call(_this8$baseApis$crypt2, {
833
- keys: {
834
- [keyId]: keyInfo
835
- }
836
- }, "");
837
- if (key) {
838
- var privateKey = key[1];
839
- builder.ssssCryptoCallbacks.addPrivateKey(keyId, keyInfo, privateKey);
840
- var {
841
- iv,
842
- mac
843
- } = yield calculateKeyCheck(privateKey);
844
- keyInfo.iv = iv;
845
- keyInfo.mac = mac;
846
- yield builder.setAccountData("m.secret_storage.key.".concat(keyId), keyInfo);
847
- }
848
- }
849
- });
850
- return function ensureCanCheckPassphrase(_x4, _x5) {
851
- return _ref7.apply(this, arguments);
852
- };
853
- }();
854
- var signKeyBackupWithCrossSigning = /*#__PURE__*/function () {
855
- var _ref8 = _asyncToGenerator(function* (keyBackupAuthData) {
856
- if (_this8.crossSigningInfo.getId() && (yield _this8.crossSigningInfo.isStoredInKeyCache("master"))) {
857
- try {
858
- logger.log("Adding cross-signing signature to key backup");
859
- yield _this8.crossSigningInfo.signObject(keyBackupAuthData, "master");
860
- } catch (e) {
861
- // This step is not critical (just helpful), so we catch here
862
- // and continue if it fails.
863
- logger.error("Signing key backup with cross-signing keys failed", e);
864
- }
865
- } else {
866
- logger.warn("Cross-signing keys not available, skipping signature on key backup");
867
- }
868
- });
869
- return function signKeyBackupWithCrossSigning(_x6) {
870
- return _ref8.apply(this, arguments);
871
- };
872
- }();
873
- var oldSSSSKey = yield _this8.secretStorage.getKey();
874
- var [oldKeyId, oldKeyInfo] = oldSSSSKey || [null, null];
875
- var storageExists = !setupNewSecretStorage && oldKeyInfo && oldKeyInfo.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES;
876
-
877
- // Log all relevant state for easier parsing of debug logs.
878
- logger.log({
879
- keyBackupInfo,
880
- setupNewKeyBackup,
881
- setupNewSecretStorage,
882
- storageExists,
883
- oldKeyInfo
884
- });
885
- if (!storageExists && !keyBackupInfo) {
886
- // either we don't have anything, or we've been asked to restart
887
- // from scratch
888
- logger.log("Secret storage does not exist, creating new storage key");
889
-
890
- // if we already have a usable default SSSS key and aren't resetting
891
- // SSSS just use it. otherwise, create a new one
892
- // Note: we leave the old SSSS key in place: there could be other
893
- // secrets using it, in theory. We could move them to the new key but a)
894
- // that would mean we'd need to prompt for the old passphrase, and b)
895
- // it's not clear that would be the right thing to do anyway.
896
- var {
897
- keyInfo,
898
- privateKey
899
- } = yield createSecretStorageKey();
900
- newKeyId = yield createSSSS({
901
- passphrase: keyInfo === null || keyInfo === void 0 ? void 0 : keyInfo.passphrase,
902
- key: privateKey,
903
- name: keyInfo === null || keyInfo === void 0 ? void 0 : keyInfo.name
904
- });
905
- } else if (!storageExists && keyBackupInfo) {
906
- // we have an existing backup, but no SSSS
907
- logger.log("Secret storage does not exist, using key backup key");
908
-
909
- // if we have the backup key already cached, use it; otherwise use the
910
- // callback to prompt for the key
911
- var backupKey = (yield _this8.getSessionBackupPrivateKey()) || (yield getKeyBackupPassphrase === null || getKeyBackupPassphrase === void 0 ? void 0 : getKeyBackupPassphrase());
912
-
913
- // create a new SSSS key and use the backup key as the new SSSS key
914
- var opts = {
915
- key: backupKey
916
- };
917
- if (keyBackupInfo.auth_data.private_key_salt && keyBackupInfo.auth_data.private_key_iterations) {
918
- // FIXME: ???
919
- opts.passphrase = {
920
- algorithm: "m.pbkdf2",
921
- iterations: keyBackupInfo.auth_data.private_key_iterations,
922
- salt: keyBackupInfo.auth_data.private_key_salt,
923
- bits: 256
924
- };
925
- }
926
- newKeyId = yield createSSSS(opts);
927
-
928
- // store the backup key in secret storage
929
- yield secretStorage.store("m.megolm_backup.v1", encodeBase64(backupKey), [newKeyId]);
930
-
931
- // The backup is trusted because the user provided the private key.
932
- // Sign the backup with the cross-signing key so the key backup can
933
- // be trusted via cross-signing.
934
- yield signKeyBackupWithCrossSigning(keyBackupInfo.auth_data);
935
- builder.addSessionBackup(keyBackupInfo);
936
- } else {
937
- // 4S is already set up
938
- logger.log("Secret storage exists");
939
- if (oldKeyInfo && oldKeyInfo.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) {
940
- // make sure that the default key has the information needed to
941
- // check the passphrase
942
- yield ensureCanCheckPassphrase(oldKeyId, oldKeyInfo);
943
- }
944
- }
945
-
946
- // If we have cross-signing private keys cached, store them in secret
947
- // storage if they are not there already.
948
- if (!_this8.baseApis.cryptoCallbacks.saveCrossSigningKeys && (yield _this8.isCrossSigningReady()) && (newKeyId || !(yield _this8.crossSigningInfo.isStoredInSecretStorage(secretStorage)))) {
949
- logger.log("Copying cross-signing private keys from cache to secret storage");
950
- var crossSigningPrivateKeys = yield _this8.crossSigningInfo.getCrossSigningKeysFromCache();
951
- // This is writing to in-memory account data in
952
- // builder.accountDataClientAdapter so won't fail
953
- yield CrossSigningInfo.storeInSecretStorage(crossSigningPrivateKeys, secretStorage);
954
- }
955
- if (setupNewKeyBackup && !keyBackupInfo) {
956
- logger.log("Creating new message key backup version");
957
- var info = yield _this8.baseApis.prepareKeyBackupVersion(null /* random key */,
958
- // don't write to secret storage, as it will write to this.secretStorage.
959
- // Here, we want to capture all the side-effects of bootstrapping,
960
- // and want to write to the local secretStorage object
961
- {
962
- secureSecretStorage: false
963
- });
964
- // write the key to 4S
965
- var _privateKey2 = decodeRecoveryKey(info.recovery_key);
966
- yield secretStorage.store("m.megolm_backup.v1", encodeBase64(_privateKey2));
967
-
968
- // create keyBackupInfo object to add to builder
969
- var data = {
970
- algorithm: info.algorithm,
971
- auth_data: info.auth_data
972
- };
973
-
974
- // Sign with cross-signing master key
975
- yield signKeyBackupWithCrossSigning(data.auth_data);
976
-
977
- // sign with the device fingerprint
978
- yield _this8.signObject(data.auth_data);
979
- builder.addSessionBackup(data);
980
- }
981
-
982
- // Cache the session backup key
983
- var sessionBackupKey = yield secretStorage.get("m.megolm_backup.v1");
984
- if (sessionBackupKey) {
985
- logger.info("Got session backup key from secret storage: caching");
986
- // fix up the backup key if it's in the wrong format, and replace
987
- // in secret storage
988
- var fixedBackupKey = fixBackupKey(sessionBackupKey);
989
- if (fixedBackupKey) {
990
- var keyId = newKeyId || oldKeyId;
991
- yield secretStorage.store("m.megolm_backup.v1", fixedBackupKey, keyId ? [keyId] : null);
992
- }
993
- var decodedBackupKey = new Uint8Array(decodeBase64(fixedBackupKey || sessionBackupKey));
994
- builder.addSessionBackupPrivateKeyToCache(decodedBackupKey);
995
- } else if (_this8.backupManager.getKeyBackupEnabled()) {
996
- // key backup is enabled but we don't have a session backup key in SSSS: see if we have one in
997
- // the cache or the user can provide one, and if so, write it to SSSS
998
- var _backupKey = (yield _this8.getSessionBackupPrivateKey()) || (yield getKeyBackupPassphrase === null || getKeyBackupPassphrase === void 0 ? void 0 : getKeyBackupPassphrase());
999
- if (!_backupKey) {
1000
- // This will require user intervention to recover from since we don't have the key
1001
- // backup key anywhere. The user should probably just set up a new key backup and
1002
- // the key for the new backup will be stored. If we hit this scenario in the wild
1003
- // with any frequency, we should do more than just log an error.
1004
- logger.error("Key backup is enabled but couldn't get key backup key!");
1005
- return;
1006
- }
1007
- logger.info("Got session backup key from cache/user that wasn't in SSSS: saving to SSSS");
1008
- yield secretStorage.store("m.megolm_backup.v1", encodeBase64(_backupKey));
1009
- }
1010
- var operation = builder.buildOperation();
1011
- yield operation.apply(_this8);
1012
- // this persists private keys and public keys as trusted,
1013
- // only do this if apply succeeded for now as retry isn't in place yet
1014
- yield builder.persist(_this8);
1015
- logger.log("Secure Secret Storage ready");
1016
- })();
1017
- }
1018
-
1019
- /**
1020
- * Implementation of {@link Crypto.CryptoApi#resetKeyBackup}.
1021
- */
1022
- resetKeyBackup() {
1023
- var _this9 = this;
1024
- return _asyncToGenerator(function* () {
1025
- // Delete existing ones
1026
- // There is no use case for having several key backup version live server side.
1027
- // Even if not deleted it would be lost as the key to restore is lost.
1028
- // There should be only one backup at a time.
1029
- yield _this9.backupManager.deleteAllKeyBackupVersions();
1030
- var info = yield _this9.backupManager.prepareKeyBackupVersion();
1031
- yield _this9.signObject(info.auth_data);
1032
-
1033
- // add new key backup
1034
- var {
1035
- version
1036
- } = yield _this9.baseApis.http.authedRequest(Method.Post, "/room_keys/version", undefined, info, {
1037
- prefix: ClientPrefix.V3
1038
- });
1039
- logger.log("Created backup version ".concat(version));
1040
-
1041
- // write the key to 4S
1042
- var privateKey = info.privateKey;
1043
- yield _this9.secretStorage.store("m.megolm_backup.v1", encodeBase64(privateKey));
1044
- yield _this9.storeSessionBackupPrivateKey(privateKey);
1045
- yield _this9.backupManager.checkAndStart();
1046
- yield _this9.backupManager.scheduleAllGroupSessionsForBackup();
1047
- })();
1048
- }
1049
-
1050
- /**
1051
- * Implementation of {@link Crypto.CryptoApi#deleteKeyBackupVersion}.
1052
- */
1053
- deleteKeyBackupVersion(version) {
1054
- var _this10 = this;
1055
- return _asyncToGenerator(function* () {
1056
- yield _this10.backupManager.deleteKeyBackupVersion(version);
1057
- })();
1058
- }
1059
-
1060
- /**
1061
- * @deprecated Use {@link MatrixClient#secretStorage} and {@link SecretStorage.ServerSideSecretStorage#addKey}.
1062
- */
1063
- addSecretStorageKey(algorithm, opts, keyID) {
1064
- return this.secretStorage.addKey(algorithm, opts, keyID);
1065
- }
1066
-
1067
- /**
1068
- * @deprecated Use {@link MatrixClient#secretStorage} and {@link SecretStorage.ServerSideSecretStorage#hasKey}.
1069
- */
1070
- hasSecretStorageKey(keyID) {
1071
- return this.secretStorage.hasKey(keyID);
1072
- }
1073
-
1074
- /**
1075
- * @deprecated Use {@link MatrixClient#secretStorage} and {@link SecretStorage.ServerSideSecretStorage#getKey}.
1076
- */
1077
- getSecretStorageKey(keyID) {
1078
- return this.secretStorage.getKey(keyID);
1079
- }
1080
-
1081
- /**
1082
- * @deprecated Use {@link MatrixClient#secretStorage} and {@link SecretStorage.ServerSideSecretStorage#store}.
1083
- */
1084
- storeSecret(name, secret, keys) {
1085
- return this.secretStorage.store(name, secret, keys);
1086
- }
1087
-
1088
- /**
1089
- * @deprecated Use {@link MatrixClient#secretStorage} and {@link SecretStorage.ServerSideSecretStorage#get}.
1090
- */
1091
- getSecret(name) {
1092
- return this.secretStorage.get(name);
1093
- }
1094
-
1095
- /**
1096
- * @deprecated Use {@link MatrixClient#secretStorage} and {@link SecretStorage.ServerSideSecretStorage#isStored}.
1097
- */
1098
- isSecretStored(name) {
1099
- return this.secretStorage.isStored(name);
1100
- }
1101
- requestSecret(name, devices) {
1102
- if (!devices) {
1103
- devices = Object.keys(this.deviceList.getRawStoredDevicesForUser(this.userId));
1104
- }
1105
- return this.secretStorage.request(name, devices);
1106
- }
1107
-
1108
- /**
1109
- * @deprecated Use {@link MatrixClient#secretStorage} and {@link SecretStorage.ServerSideSecretStorage#getDefaultKeyId}.
1110
- */
1111
- getDefaultSecretStorageKeyId() {
1112
- return this.secretStorage.getDefaultKeyId();
1113
- }
1114
-
1115
- /**
1116
- * @deprecated Use {@link MatrixClient#secretStorage} and {@link SecretStorage.ServerSideSecretStorage#setDefaultKeyId}.
1117
- */
1118
- setDefaultSecretStorageKeyId(k) {
1119
- return this.secretStorage.setDefaultKeyId(k);
1120
- }
1121
-
1122
- /**
1123
- * @deprecated Use {@link MatrixClient#secretStorage} and {@link SecretStorage.ServerSideSecretStorage#checkKey}.
1124
- */
1125
- checkSecretStorageKey(key, info) {
1126
- return this.secretStorage.checkKey(key, info);
1127
- }
1128
-
1129
- /**
1130
- * Checks that a given secret storage private key matches a given public key.
1131
- * This can be used by the getSecretStorageKey callback to verify that the
1132
- * private key it is about to supply is the one that was requested.
1133
- *
1134
- * @param privateKey - The private key
1135
- * @param expectedPublicKey - The public key
1136
- * @returns true if the key matches, otherwise false
1137
- */
1138
- checkSecretStoragePrivateKey(privateKey, expectedPublicKey) {
1139
- var decryption = null;
1140
- try {
1141
- decryption = new globalThis.Olm.PkDecryption();
1142
- var gotPubkey = decryption.init_with_private_key(privateKey);
1143
- // make sure it agrees with the given pubkey
1144
- return gotPubkey === expectedPublicKey;
1145
- } finally {
1146
- var _decryption;
1147
- (_decryption = decryption) === null || _decryption === void 0 || _decryption.free();
1148
- }
1149
- }
1150
-
1151
- /**
1152
- * Fetches the backup private key, if cached
1153
- * @returns the key, if any, or null
1154
- */
1155
- getSessionBackupPrivateKey() {
1156
- var _this11 = this;
1157
- return _asyncToGenerator(function* () {
1158
- var encodedKey = yield new Promise(resolve => {
1159
- _this11.cryptoStore.doTxn("readonly", [IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
1160
- _this11.cryptoStore.getSecretStorePrivateKey(txn, resolve, "m.megolm_backup.v1");
1161
- });
1162
- });
1163
- var key = null;
1164
-
1165
- // make sure we have a Uint8Array, rather than a string
1166
- if (typeof encodedKey === "string") {
1167
- key = new Uint8Array(decodeBase64(fixBackupKey(encodedKey) || encodedKey));
1168
- yield _this11.storeSessionBackupPrivateKey(key);
1169
- }
1170
- if (encodedKey && typeof encodedKey === "object" && "ciphertext" in encodedKey) {
1171
- var pickleKey = Buffer.from(_this11.olmDevice.pickleKey);
1172
- var decrypted = yield decryptAESSecretStorageItem(encodedKey, pickleKey, "m.megolm_backup.v1");
1173
- key = decodeBase64(decrypted);
1174
- }
1175
- return key;
1176
- })();
1177
- }
1178
-
1179
- /**
1180
- * Stores the session backup key to the cache
1181
- * @param key - the private key
1182
- * @returns a promise so you can catch failures
1183
- */
1184
- storeSessionBackupPrivateKey(key, version) {
1185
- var _this12 = this;
1186
- return _asyncToGenerator(function* () {
1187
- if (!(key instanceof Uint8Array)) {
1188
- // eslint-disable-next-line @typescript-eslint/no-base-to-string
1189
- throw new Error("storeSessionBackupPrivateKey expects Uint8Array, got ".concat(key));
1190
- }
1191
- var pickleKey = Buffer.from(_this12.olmDevice.pickleKey);
1192
- var encryptedKey = yield encryptAESSecretStorageItem(encodeBase64(key), pickleKey, "m.megolm_backup.v1");
1193
- return _this12.cryptoStore.doTxn("readwrite", [IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
1194
- _this12.cryptoStore.storeSecretStorePrivateKey(txn, "m.megolm_backup.v1", encryptedKey);
1195
- });
1196
- })();
1197
- }
1198
-
1199
- /**
1200
- * Implementation of {@link Crypto.loadSessionBackupPrivateKeyFromSecretStorage}.
1201
- */
1202
- loadSessionBackupPrivateKeyFromSecretStorage() {
1203
- throw new Error("Not implmeented");
1204
- }
1205
-
1206
- /**
1207
- * Get the current status of key backup.
1208
- *
1209
- * Implementation of {@link Crypto.CryptoApi.getActiveSessionBackupVersion}.
1210
- */
1211
- getActiveSessionBackupVersion() {
1212
- var _this13 = this;
1213
- return _asyncToGenerator(function* () {
1214
- if (_this13.backupManager.getKeyBackupEnabled()) {
1215
- var _this13$backupManager;
1216
- return (_this13$backupManager = _this13.backupManager.version) !== null && _this13$backupManager !== void 0 ? _this13$backupManager : null;
1217
- }
1218
- return null;
1219
- })();
1220
- }
1221
-
1222
- /**
1223
- * Implementation of {@link Crypto.CryptoApi#getKeyBackupInfo}.
1224
- */
1225
- getKeyBackupInfo() {
1226
- return _asyncToGenerator(function* () {
1227
- throw new Error("Not implemented");
1228
- })();
1229
- }
1230
-
1231
- /**
1232
- * Determine if a key backup can be trusted.
1233
- *
1234
- * Implementation of {@link Crypto.CryptoApi.isKeyBackupTrusted}.
1235
- */
1236
- isKeyBackupTrusted(info) {
1237
- var _this14 = this;
1238
- return _asyncToGenerator(function* () {
1239
- var trustInfo = yield _this14.backupManager.isKeyBackupTrusted(info);
1240
- return backupTrustInfoFromLegacyTrustInfo(trustInfo);
1241
- })();
1242
- }
1243
-
1244
- /**
1245
- * Force a re-check of the key backup and enable/disable it as appropriate.
1246
- *
1247
- * Implementation of {@link Crypto.CryptoApi.checkKeyBackupAndEnable}.
1248
- */
1249
- checkKeyBackupAndEnable() {
1250
- var _this15 = this;
1251
- return _asyncToGenerator(function* () {
1252
- var checkResult = yield _this15.backupManager.checkKeyBackup();
1253
- if (!checkResult || !checkResult.backupInfo) return null;
1254
- return {
1255
- backupInfo: checkResult.backupInfo,
1256
- trustInfo: backupTrustInfoFromLegacyTrustInfo(checkResult.trustInfo)
1257
- };
1258
- })();
1259
- }
1260
-
1261
- /**
1262
- * Checks that a given cross-signing private key matches a given public key.
1263
- * This can be used by the getCrossSigningKey callback to verify that the
1264
- * private key it is about to supply is the one that was requested.
1265
- *
1266
- * @param privateKey - The private key
1267
- * @param expectedPublicKey - The public key
1268
- * @returns true if the key matches, otherwise false
1269
- */
1270
- checkCrossSigningPrivateKey(privateKey, expectedPublicKey) {
1271
- var signing = null;
1272
- try {
1273
- signing = new globalThis.Olm.PkSigning();
1274
- var gotPubkey = signing.init_with_seed(privateKey);
1275
- // make sure it agrees with the given pubkey
1276
- return gotPubkey === expectedPublicKey;
1277
- } finally {
1278
- var _signing;
1279
- (_signing = signing) === null || _signing === void 0 || _signing.free();
1280
- }
1281
- }
1282
-
1283
- /**
1284
- * Run various follow-up actions after cross-signing keys have changed locally
1285
- * (either by resetting the keys for the account or by getting them from secret
1286
- * storage), such as signing the current device, upgrading device
1287
- * verifications, etc.
1288
- */
1289
- afterCrossSigningLocalKeyChange() {
1290
- var _this16 = this;
1291
- return _asyncToGenerator(function* () {
1292
- logger.info("Starting cross-signing key change post-processing");
1293
-
1294
- // sign the current device with the new key, and upload to the server
1295
- var device = _this16.deviceList.getStoredDevice(_this16.userId, _this16.deviceId);
1296
- var signedDevice = yield _this16.crossSigningInfo.signDevice(_this16.userId, device);
1297
- logger.info("Starting background key sig upload for ".concat(_this16.deviceId));
1298
- var upload = _ref9 => {
1299
- var {
1300
- shouldEmit = false
1301
- } = _ref9;
1302
- return _this16.baseApis.uploadKeySignatures({
1303
- [_this16.userId]: {
1304
- [_this16.deviceId]: signedDevice
1305
- }
1306
- }).then(response => {
1307
- var {
1308
- failures
1309
- } = response || {};
1310
- if (Object.keys(failures || []).length > 0) {
1311
- if (shouldEmit) {
1312
- _this16.baseApis.emit(CryptoEvent.KeySignatureUploadFailure, failures, "afterCrossSigningLocalKeyChange", upload // continuation
1313
- );
1314
- }
1315
- throw new KeySignatureUploadError("Key upload failed", {
1316
- failures
1317
- });
1318
- }
1319
- logger.info("Finished background key sig upload for ".concat(_this16.deviceId));
1320
- }).catch(e => {
1321
- logger.error("Error during background key sig upload for ".concat(_this16.deviceId), e);
1322
- });
1323
- };
1324
- upload({
1325
- shouldEmit: true
1326
- });
1327
- var shouldUpgradeCb = _this16.baseApis.cryptoCallbacks.shouldUpgradeDeviceVerifications;
1328
- if (shouldUpgradeCb) {
1329
- logger.info("Starting device verification upgrade");
1330
-
1331
- // Check all users for signatures if upgrade callback present
1332
- // FIXME: do this in batches
1333
- var users = {};
1334
- for (var [_userId2, crossSigningInfo] of Object.entries(_this16.deviceList.crossSigningInfo)) {
1335
- var upgradeInfo = yield _this16.checkForDeviceVerificationUpgrade(_userId2, CrossSigningInfo.fromStorage(crossSigningInfo, _userId2));
1336
- if (upgradeInfo) {
1337
- users[_userId2] = upgradeInfo;
1338
- }
1339
- }
1340
- if (Object.keys(users).length > 0) {
1341
- logger.info("Found ".concat(Object.keys(users).length, " verif users to upgrade"));
1342
- try {
1343
- var usersToUpgrade = yield shouldUpgradeCb({
1344
- users: users
1345
- });
1346
- if (usersToUpgrade) {
1347
- for (var _userId3 of usersToUpgrade) {
1348
- if (_userId3 in users) {
1349
- yield _this16.baseApis.setDeviceVerified(_userId3, users[_userId3].crossSigningInfo.getId());
1350
- }
1351
- }
1352
- }
1353
- } catch (e) {
1354
- logger.log("shouldUpgradeDeviceVerifications threw an error: not upgrading", e);
1355
- }
1356
- }
1357
- logger.info("Finished device verification upgrade");
1358
- }
1359
- logger.info("Finished cross-signing key change post-processing");
1360
- })();
1361
- }
1362
-
1363
- /**
1364
- * Check if a user's cross-signing key is a candidate for upgrading from device
1365
- * verification.
1366
- *
1367
- * @param userId - the user whose cross-signing information is to be checked
1368
- * @param crossSigningInfo - the cross-signing information to check
1369
- */
1370
- checkForDeviceVerificationUpgrade(userId, crossSigningInfo) {
1371
- var _this17 = this;
1372
- return _asyncToGenerator(function* () {
1373
- // only upgrade if this is the first cross-signing key that we've seen for
1374
- // them, and if their cross-signing key isn't already verified
1375
- var trustLevel = _this17.crossSigningInfo.checkUserTrust(crossSigningInfo);
1376
- if (crossSigningInfo.firstUse && !trustLevel.isVerified()) {
1377
- var devices = _this17.deviceList.getRawStoredDevicesForUser(userId);
1378
- var deviceIds = yield _this17.checkForValidDeviceSignature(userId, crossSigningInfo.keys.master, devices);
1379
- if (deviceIds.length) {
1380
- return {
1381
- devices: deviceIds.map(deviceId => DeviceInfo.fromStorage(devices[deviceId], deviceId)),
1382
- crossSigningInfo
1383
- };
1384
- }
1385
- }
1386
- })();
1387
- }
1388
-
1389
- /**
1390
- * Check if the cross-signing key is signed by a verified device.
1391
- *
1392
- * @param userId - the user ID whose key is being checked
1393
- * @param key - the key that is being checked
1394
- * @param devices - the user's devices. Should be a map from device ID
1395
- * to device info
1396
- */
1397
- checkForValidDeviceSignature(userId, key, devices) {
1398
- var _this18 = this;
1399
- return _asyncToGenerator(function* () {
1400
- var deviceIds = [];
1401
- if (devices && key.signatures && key.signatures[userId]) {
1402
- for (var signame of Object.keys(key.signatures[userId])) {
1403
- var [, _deviceId2] = signame.split(":", 2);
1404
- if (_deviceId2 in devices && devices[_deviceId2].verified === DeviceVerification.VERIFIED) {
1405
- try {
1406
- yield olmlib.verifySignature(_this18.olmDevice, key, userId, _deviceId2, devices[_deviceId2].keys[signame]);
1407
- deviceIds.push(_deviceId2);
1408
- } catch (_unused) {}
1409
- }
1410
- }
1411
- }
1412
- return deviceIds;
1413
- })();
1414
- }
1415
-
1416
- /**
1417
- * Get the user's cross-signing key ID.
1418
- *
1419
- * @param type - The type of key to get the ID of. One of
1420
- * "master", "self_signing", or "user_signing". Defaults to "master".
1421
- *
1422
- * @returns the key ID
1423
- */
1424
- getCrossSigningKeyId() {
1425
- var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : CrossSigningKey.Master;
1426
- return Promise.resolve(this.getCrossSigningId(type));
1427
- }
1428
-
1429
- // old name, for backwards compatibility
1430
- getCrossSigningId(type) {
1431
- return this.crossSigningInfo.getId(type);
1432
- }
1433
-
1434
- /**
1435
- * Get the cross signing information for a given user.
1436
- *
1437
- * @param userId - the user ID to get the cross-signing info for.
1438
- *
1439
- * @returns the cross signing information for the user.
1440
- */
1441
- getStoredCrossSigningForUser(userId) {
1442
- return this.deviceList.getStoredCrossSigningForUser(userId);
1443
- }
1444
-
1445
- /**
1446
- * Check whether a given user is trusted.
1447
- *
1448
- * @param userId - The ID of the user to check.
1449
- *
1450
- * @returns
1451
- */
1452
- checkUserTrust(userId) {
1453
- var userCrossSigning = this.deviceList.getStoredCrossSigningForUser(userId);
1454
- if (!userCrossSigning) {
1455
- return new UserTrustLevel(false, false, false);
1456
- }
1457
- return this.crossSigningInfo.checkUserTrust(userCrossSigning);
1458
- }
1459
-
1460
- /**
1461
- * Implementation of {@link Crypto.CryptoApi.getUserVerificationStatus}.
1462
- */
1463
- getUserVerificationStatus(userId) {
1464
- var _this19 = this;
1465
- return _asyncToGenerator(function* () {
1466
- return _this19.checkUserTrust(userId);
1467
- })();
1468
- }
1469
-
1470
- /**
1471
- * Implementation of {@link Crypto.CryptoApi.pinCurrentUserIdentity}.
1472
- */
1473
- pinCurrentUserIdentity(userId) {
1474
- return _asyncToGenerator(function* () {
1475
- throw new Error("not implemented");
1476
- })();
1477
- }
1478
-
1479
- /**
1480
- * Check whether a given device is trusted.
1481
- *
1482
- * @param userId - The ID of the user whose device is to be checked.
1483
- * @param deviceId - The ID of the device to check
1484
- */
1485
- getDeviceVerificationStatus(userId, deviceId) {
1486
- var _this20 = this;
1487
- return _asyncToGenerator(function* () {
1488
- var device = _this20.deviceList.getStoredDevice(userId, deviceId);
1489
- if (!device) {
1490
- return null;
1491
- }
1492
- return _this20.checkDeviceInfoTrust(userId, device);
1493
- })();
1494
- }
1495
-
1496
- /**
1497
- * @deprecated Use {@link Crypto.CryptoApi.getDeviceVerificationStatus}.
1498
- */
1499
- checkDeviceTrust(userId, deviceId) {
1500
- var device = this.deviceList.getStoredDevice(userId, deviceId);
1501
- return this.checkDeviceInfoTrust(userId, device);
1502
- }
1503
-
1504
- /**
1505
- * Check whether a given deviceinfo is trusted.
1506
- *
1507
- * @param userId - The ID of the user whose devices is to be checked.
1508
- * @param device - The device info object to check
1509
- *
1510
- * @deprecated Use {@link Crypto.CryptoApi.getDeviceVerificationStatus}.
1511
- */
1512
- checkDeviceInfoTrust(userId, device) {
1513
- var trustedLocally = !!(device !== null && device !== void 0 && device.isVerified());
1514
- var userCrossSigning = this.deviceList.getStoredCrossSigningForUser(userId);
1515
- if (device && userCrossSigning) {
1516
- // The trustCrossSignedDevices only affects trust of other people's cross-signing
1517
- // signatures
1518
- var trustCrossSig = this.trustCrossSignedDevices || userId === this.userId;
1519
- return this.crossSigningInfo.checkDeviceTrust(userCrossSigning, device, trustedLocally, trustCrossSig);
1520
- } else {
1521
- return new DeviceTrustLevel(false, false, trustedLocally, false);
1522
- }
1523
- }
1524
-
1525
- /**
1526
- * Check whether one of our own devices is cross-signed by our
1527
- * user's stored keys, regardless of whether we trust those keys yet.
1528
- *
1529
- * @param deviceId - The ID of the device to check
1530
- *
1531
- * @returns true if the device is cross-signed
1532
- */
1533
- checkIfOwnDeviceCrossSigned(deviceId) {
1534
- var _userCrossSigning$che;
1535
- var device = this.deviceList.getStoredDevice(this.userId, deviceId);
1536
- if (!device) return false;
1537
- var userCrossSigning = this.deviceList.getStoredCrossSigningForUser(this.userId);
1538
- return (_userCrossSigning$che = userCrossSigning === null || userCrossSigning === void 0 ? void 0 : userCrossSigning.checkDeviceTrust(userCrossSigning, device, false, true).isCrossSigningVerified()) !== null && _userCrossSigning$che !== void 0 ? _userCrossSigning$che : false;
1539
- }
1540
- /**
1541
- * Check the copy of our cross-signing key that we have in the device list and
1542
- * see if we can get the private key. If so, mark it as trusted.
1543
- */
1544
- checkOwnCrossSigningTrust() {
1545
- var _arguments5 = arguments,
1546
- _this21 = this;
1547
- return _asyncToGenerator(function* () {
1548
- var {
1549
- allowPrivateKeyRequests = false
1550
- } = _arguments5.length > 0 && _arguments5[0] !== undefined ? _arguments5[0] : {};
1551
- var userId = _this21.userId;
1552
-
1553
- // Before proceeding, ensure our cross-signing public keys have been
1554
- // downloaded via the device list.
1555
- yield _this21.downloadKeys([_this21.userId]);
1556
-
1557
- // Also check which private keys are locally cached.
1558
- var crossSigningPrivateKeys = yield _this21.crossSigningInfo.getCrossSigningKeysFromCache();
1559
-
1560
- // If we see an update to our own master key, check it against the master
1561
- // key we have and, if it matches, mark it as verified
1562
-
1563
- // First, get the new cross-signing info
1564
- var newCrossSigning = _this21.deviceList.getStoredCrossSigningForUser(userId);
1565
- if (!newCrossSigning) {
1566
- logger.error("Got cross-signing update event for user " + userId + " but no new cross-signing information found!");
1567
- return;
1568
- }
1569
- var seenPubkey = newCrossSigning.getId();
1570
- var masterChanged = _this21.crossSigningInfo.getId() !== seenPubkey;
1571
- var masterExistsNotLocallyCached = newCrossSigning.getId() && !crossSigningPrivateKeys.has("master");
1572
- if (masterChanged) {
1573
- logger.info("Got new master public key", seenPubkey);
1574
- }
1575
- if (allowPrivateKeyRequests && (masterChanged || masterExistsNotLocallyCached)) {
1576
- logger.info("Attempting to retrieve cross-signing master private key");
1577
- var signing = null;
1578
- // It's important for control flow that we leave any errors alone for
1579
- // higher levels to handle so that e.g. cancelling access properly
1580
- // aborts any larger operation as well.
1581
- try {
1582
- var ret = yield _this21.crossSigningInfo.getCrossSigningKey("master", seenPubkey);
1583
- signing = ret[1];
1584
- logger.info("Got cross-signing master private key");
1585
- } finally {
1586
- var _signing2;
1587
- (_signing2 = signing) === null || _signing2 === void 0 || _signing2.free();
1588
- }
1589
- }
1590
- var oldSelfSigningId = _this21.crossSigningInfo.getId("self_signing");
1591
- var oldUserSigningId = _this21.crossSigningInfo.getId("user_signing");
1592
-
1593
- // Update the version of our keys in our cross-signing object and the local store
1594
- _this21.storeTrustedSelfKeys(newCrossSigning.keys);
1595
- var selfSigningChanged = oldSelfSigningId !== newCrossSigning.getId("self_signing");
1596
- var userSigningChanged = oldUserSigningId !== newCrossSigning.getId("user_signing");
1597
- var selfSigningExistsNotLocallyCached = newCrossSigning.getId("self_signing") && !crossSigningPrivateKeys.has("self_signing");
1598
- var userSigningExistsNotLocallyCached = newCrossSigning.getId("user_signing") && !crossSigningPrivateKeys.has("user_signing");
1599
- var keySignatures = {};
1600
- if (selfSigningChanged) {
1601
- logger.info("Got new self-signing key", newCrossSigning.getId("self_signing"));
1602
- }
1603
- if (allowPrivateKeyRequests && (selfSigningChanged || selfSigningExistsNotLocallyCached)) {
1604
- logger.info("Attempting to retrieve cross-signing self-signing private key");
1605
- var _signing3 = null;
1606
- try {
1607
- var _ret = yield _this21.crossSigningInfo.getCrossSigningKey("self_signing", newCrossSigning.getId("self_signing"));
1608
- _signing3 = _ret[1];
1609
- logger.info("Got cross-signing self-signing private key");
1610
- } finally {
1611
- var _signing4;
1612
- (_signing4 = _signing3) === null || _signing4 === void 0 || _signing4.free();
1613
- }
1614
- var device = _this21.deviceList.getStoredDevice(_this21.userId, _this21.deviceId);
1615
- var signedDevice = yield _this21.crossSigningInfo.signDevice(_this21.userId, device);
1616
- keySignatures[_this21.deviceId] = signedDevice;
1617
- }
1618
- if (userSigningChanged) {
1619
- logger.info("Got new user-signing key", newCrossSigning.getId("user_signing"));
1620
- }
1621
- if (allowPrivateKeyRequests && (userSigningChanged || userSigningExistsNotLocallyCached)) {
1622
- logger.info("Attempting to retrieve cross-signing user-signing private key");
1623
- var _signing5 = null;
1624
- try {
1625
- var _ret2 = yield _this21.crossSigningInfo.getCrossSigningKey("user_signing", newCrossSigning.getId("user_signing"));
1626
- _signing5 = _ret2[1];
1627
- logger.info("Got cross-signing user-signing private key");
1628
- } finally {
1629
- var _signing6;
1630
- (_signing6 = _signing5) === null || _signing6 === void 0 || _signing6.free();
1631
- }
1632
- }
1633
- if (masterChanged) {
1634
- var masterKey = _this21.crossSigningInfo.keys.master;
1635
- yield _this21.signObject(masterKey);
1636
- var deviceSig = masterKey.signatures[_this21.userId]["ed25519:" + _this21.deviceId];
1637
- // Include only the _new_ device signature in the upload.
1638
- // We may have existing signatures from deleted devices, which will cause
1639
- // the entire upload to fail.
1640
- keySignatures[_this21.crossSigningInfo.getId()] = Object.assign({}, masterKey, {
1641
- signatures: {
1642
- [_this21.userId]: {
1643
- ["ed25519:" + _this21.deviceId]: deviceSig
1644
- }
1645
- }
1646
- });
1647
- }
1648
- var keysToUpload = Object.keys(keySignatures);
1649
- if (keysToUpload.length) {
1650
- var upload = _ref10 => {
1651
- var {
1652
- shouldEmit = false
1653
- } = _ref10;
1654
- logger.info("Starting background key sig upload for ".concat(keysToUpload));
1655
- return _this21.baseApis.uploadKeySignatures({
1656
- [_this21.userId]: keySignatures
1657
- }).then(response => {
1658
- var {
1659
- failures
1660
- } = response || {};
1661
- logger.info("Finished background key sig upload for ".concat(keysToUpload));
1662
- if (Object.keys(failures || []).length > 0) {
1663
- if (shouldEmit) {
1664
- _this21.baseApis.emit(CryptoEvent.KeySignatureUploadFailure, failures, "checkOwnCrossSigningTrust", upload);
1665
- }
1666
- throw new KeySignatureUploadError("Key upload failed", {
1667
- failures
1668
- });
1669
- }
1670
- }).catch(e => {
1671
- logger.error("Error during background key sig upload for ".concat(keysToUpload), e);
1672
- });
1673
- };
1674
- upload({
1675
- shouldEmit: true
1676
- });
1677
- }
1678
- _this21.emit(CryptoEvent.UserTrustStatusChanged, userId, _this21.checkUserTrust(userId));
1679
- if (masterChanged) {
1680
- _this21.emit(CryptoEvent.KeysChanged, {});
1681
- yield _this21.afterCrossSigningLocalKeyChange();
1682
- }
1683
-
1684
- // Now we may be able to trust our key backup
1685
- yield _this21.backupManager.checkKeyBackup();
1686
- // FIXME: if we previously trusted the backup, should we automatically sign
1687
- // the backup with the new key (if not already signed)?
1688
- })();
1689
- }
1690
-
1691
- /**
1692
- * Implementation of {@link CryptoBackend#getBackupDecryptor}.
1693
- */
1694
- getBackupDecryptor(backupInfo, privKey) {
1695
- return _asyncToGenerator(function* () {
1696
- if (!(privKey instanceof Uint8Array)) {
1697
- throw new Error("getBackupDecryptor expects Uint8Array");
1698
- }
1699
- var algorithm = yield BackupManager.makeAlgorithm(backupInfo, /*#__PURE__*/_asyncToGenerator(function* () {
1700
- return privKey;
1701
- }));
1702
-
1703
- // If the pubkey computed from the private data we've been given
1704
- // doesn't match the one in the auth_data, the user has entered
1705
- // a different recovery key / the wrong passphrase.
1706
- if (!(yield algorithm.keyMatches(privKey))) {
1707
- return Promise.reject(new MatrixError({
1708
- errcode: MatrixClient.RESTORE_BACKUP_ERROR_BAD_KEY
1709
- }));
1710
- }
1711
- return new LibOlmBackupDecryptor(algorithm);
1712
- })();
1713
- }
1714
-
1715
- /**
1716
- * Implementation of {@link CryptoBackend#importBackedUpRoomKeys}.
1717
- */
1718
- importBackedUpRoomKeys(keys, backupVersion) {
1719
- var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1720
- opts.source = "backup";
1721
- return this.importRoomKeys(keys, opts);
1722
- }
1723
-
1724
- /**
1725
- * Store a set of keys as our own, trusted, cross-signing keys.
1726
- *
1727
- * @param keys - The new trusted set of keys
1728
- */
1729
- storeTrustedSelfKeys(keys) {
1730
- var _this22 = this;
1731
- return _asyncToGenerator(function* () {
1732
- if (keys) {
1733
- _this22.crossSigningInfo.setKeys(keys);
1734
- } else {
1735
- _this22.crossSigningInfo.clearKeys();
1736
- }
1737
- yield _this22.cryptoStore.doTxn("readwrite", [IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
1738
- _this22.cryptoStore.storeCrossSigningKeys(txn, _this22.crossSigningInfo.keys);
1739
- });
1740
- })();
1741
- }
1742
-
1743
- /**
1744
- * Check if the master key is signed by a verified device, and if so, prompt
1745
- * the application to mark it as verified.
1746
- *
1747
- * @param userId - the user ID whose key should be checked
1748
- */
1749
- checkDeviceVerifications(userId) {
1750
- var _this23 = this;
1751
- return _asyncToGenerator(function* () {
1752
- var shouldUpgradeCb = _this23.baseApis.cryptoCallbacks.shouldUpgradeDeviceVerifications;
1753
- if (!shouldUpgradeCb) {
1754
- // Upgrading skipped when callback is not present.
1755
- return;
1756
- }
1757
- logger.info("Starting device verification upgrade for ".concat(userId));
1758
- if (_this23.crossSigningInfo.keys.user_signing) {
1759
- var crossSigningInfo = _this23.deviceList.getStoredCrossSigningForUser(userId);
1760
- if (crossSigningInfo) {
1761
- var upgradeInfo = yield _this23.checkForDeviceVerificationUpgrade(userId, crossSigningInfo);
1762
- if (upgradeInfo) {
1763
- var usersToUpgrade = yield shouldUpgradeCb({
1764
- users: {
1765
- [userId]: upgradeInfo
1766
- }
1767
- });
1768
- if (usersToUpgrade.includes(userId)) {
1769
- yield _this23.baseApis.setDeviceVerified(userId, crossSigningInfo.getId());
1770
- }
1771
- }
1772
- }
1773
- }
1774
- logger.info("Finished device verification upgrade for ".concat(userId));
1775
- })();
1776
- }
1777
-
1778
- /**
1779
- */
1780
- enableLazyLoading() {
1781
- this.lazyLoadMembers = true;
1782
- }
1783
-
1784
- /**
1785
- * Tell the crypto module to register for MatrixClient events which it needs to
1786
- * listen for
1787
- *
1788
- * @param eventEmitter - event source where we can register
1789
- * for event notifications
1790
- */
1791
- registerEventHandlers(eventEmitter) {
1792
- eventEmitter.on(RoomMemberEvent.Membership, this.onMembership);
1793
- eventEmitter.on(ClientEvent.ToDeviceEvent, this.onToDeviceEvent);
1794
- eventEmitter.on(RoomEvent.Timeline, this.onTimelineEvent);
1795
- eventEmitter.on(MatrixEventEvent.Decrypted, this.onTimelineEvent);
1796
- }
1797
-
1798
- /**
1799
- * @deprecated this does nothing and will be removed in a future version
1800
- */
1801
- start() {
1802
- logger.warn("MatrixClient.crypto.start() is deprecated");
1803
- }
1804
-
1805
- /** Stop background processes related to crypto */
1806
- stop() {
1807
- this.outgoingRoomKeyRequestManager.stop();
1808
- this.deviceList.stop();
1809
- this.dehydrationManager.stop();
1810
- this.backupManager.stop();
1811
- }
1812
-
1813
- /**
1814
- * Get the Ed25519 key for this device
1815
- *
1816
- * @returns base64-encoded ed25519 key.
1817
- *
1818
- * @deprecated Use {@link Crypto.CryptoApi#getOwnDeviceKeys}.
1819
- */
1820
- getDeviceEd25519Key() {
1821
- return this.olmDevice.deviceEd25519Key;
1822
- }
1823
-
1824
- /**
1825
- * Get the Curve25519 key for this device
1826
- *
1827
- * @returns base64-encoded curve25519 key.
1828
- *
1829
- * @deprecated Use {@link Crypto.CryptoApi#getOwnDeviceKeys}
1830
- */
1831
- getDeviceCurve25519Key() {
1832
- return this.olmDevice.deviceCurve25519Key;
1833
- }
1834
-
1835
- /**
1836
- * Implementation of {@link Crypto.CryptoApi#getOwnDeviceKeys}.
1837
- */
1838
- getOwnDeviceKeys() {
1839
- var _this24 = this;
1840
- return _asyncToGenerator(function* () {
1841
- if (!_this24.olmDevice.deviceCurve25519Key) {
1842
- throw new Error("Curve25519 key not yet created");
1843
- }
1844
- if (!_this24.olmDevice.deviceEd25519Key) {
1845
- throw new Error("Ed25519 key not yet created");
1846
- }
1847
- return {
1848
- ed25519: _this24.olmDevice.deviceEd25519Key,
1849
- curve25519: _this24.olmDevice.deviceCurve25519Key
1850
- };
1851
- })();
1852
- }
1853
-
1854
- /**
1855
- * Set the global override for whether the client should ever send encrypted
1856
- * messages to unverified devices. This provides the default for rooms which
1857
- * do not specify a value.
1858
- *
1859
- * @param value - whether to blacklist all unverified devices by default
1860
- *
1861
- * @deprecated Set {@link Crypto.CryptoApi#globalBlacklistUnverifiedDevices | CryptoApi.globalBlacklistUnverifiedDevices} directly.
1862
- */
1863
- setGlobalBlacklistUnverifiedDevices(value) {
1864
- this.globalBlacklistUnverifiedDevices = value;
1865
- }
1866
-
1867
- /**
1868
- * @returns whether to blacklist all unverified devices by default
1869
- *
1870
- * @deprecated Reference {@link Crypto.CryptoApi#globalBlacklistUnverifiedDevices | CryptoApi.globalBlacklistUnverifiedDevices} directly.
1871
- */
1872
- getGlobalBlacklistUnverifiedDevices() {
1873
- return this.globalBlacklistUnverifiedDevices;
1874
- }
1875
-
1876
- /**
1877
- * Upload the device keys to the homeserver.
1878
- * @returns A promise that will resolve when the keys are uploaded.
1879
- */
1880
- uploadDeviceKeys() {
1881
- var deviceKeys = {
1882
- algorithms: this.supportedAlgorithms,
1883
- device_id: this.deviceId,
1884
- keys: this.deviceKeys,
1885
- user_id: this.userId
1886
- };
1887
- return this.signObject(deviceKeys).then(() => {
1888
- return this.baseApis.uploadKeysRequest({
1889
- device_keys: deviceKeys
1890
- });
1891
- });
1892
- }
1893
- getNeedsNewFallback() {
1894
- return !!this.needsNewFallback;
1895
- }
1896
-
1897
- // check if it's time to upload one-time keys, and do so if so.
1898
- maybeUploadOneTimeKeys() {
1899
- var _this25 = this;
1900
- // frequency with which to check & upload one-time keys
1901
- var uploadPeriod = 1000 * 60; // one minute
1902
-
1903
- // max number of keys to upload at once
1904
- // Creating keys can be an expensive operation so we limit the
1905
- // number we generate in one go to avoid blocking the application
1906
- // for too long.
1907
- var maxKeysPerCycle = 5;
1908
- if (this.oneTimeKeyCheckInProgress) {
1909
- return;
1910
- }
1911
- var now = Date.now();
1912
- if (this.lastOneTimeKeyCheck !== null && now - this.lastOneTimeKeyCheck < uploadPeriod) {
1913
- // we've done a key upload recently.
1914
- return;
1915
- }
1916
- this.lastOneTimeKeyCheck = now;
1917
-
1918
- // We need to keep a pool of one time public keys on the server so that
1919
- // other devices can start conversations with us. But we can only store
1920
- // a finite number of private keys in the olm Account object.
1921
- // To complicate things further then can be a delay between a device
1922
- // claiming a public one time key from the server and it sending us a
1923
- // message. We need to keep the corresponding private key locally until
1924
- // we receive the message.
1925
- // But that message might never arrive leaving us stuck with duff
1926
- // private keys clogging up our local storage.
1927
- // So we need some kind of engineering compromise to balance all of
1928
- // these factors.
1929
-
1930
- // Check how many keys we can store in the Account object.
1931
- var maxOneTimeKeys = this.olmDevice.maxNumberOfOneTimeKeys();
1932
- // Try to keep at most half that number on the server. This leaves the
1933
- // rest of the slots free to hold keys that have been claimed from the
1934
- // server but we haven't received a message for.
1935
- // If we run out of slots when generating new keys then olm will
1936
- // discard the oldest private keys first. This will eventually clean
1937
- // out stale private keys that won't receive a message.
1938
- var keyLimit = Math.floor(maxOneTimeKeys / 2);
1939
- var uploadLoop = /*#__PURE__*/function () {
1940
- var _ref12 = _asyncToGenerator(function* (keyCount) {
1941
- while (keyLimit > keyCount || _this25.getNeedsNewFallback()) {
1942
- // Ask olm to generate new one time keys, then upload them to synapse.
1943
- if (keyLimit > keyCount) {
1944
- logger.info("generating oneTimeKeys");
1945
- var keysThisLoop = Math.min(keyLimit - keyCount, maxKeysPerCycle);
1946
- yield _this25.olmDevice.generateOneTimeKeys(keysThisLoop);
1947
- }
1948
- if (_this25.getNeedsNewFallback()) {
1949
- var fallbackKeys = yield _this25.olmDevice.getFallbackKey();
1950
- // if fallbackKeys is non-empty, we've already generated a
1951
- // fallback key, but it hasn't been published yet, so we
1952
- // can use that instead of generating a new one
1953
- if (!fallbackKeys.curve25519 || Object.keys(fallbackKeys.curve25519).length == 0) {
1954
- logger.info("generating fallback key");
1955
- if (_this25.fallbackCleanup) {
1956
- // cancel any pending fallback cleanup because generating
1957
- // a new fallback key will already drop the old fallback
1958
- // that would have been dropped, and we don't want to kill
1959
- // the current key
1960
- clearTimeout(_this25.fallbackCleanup);
1961
- delete _this25.fallbackCleanup;
1962
- }
1963
- yield _this25.olmDevice.generateFallbackKey();
1964
- }
1965
- }
1966
- logger.info("calling uploadOneTimeKeys");
1967
- var res = yield _this25.uploadOneTimeKeys();
1968
- if (res.one_time_key_counts && res.one_time_key_counts.signed_curve25519) {
1969
- // if the response contains a more up to date value use this
1970
- // for the next loop
1971
- keyCount = res.one_time_key_counts.signed_curve25519;
1972
- } else {
1973
- throw new Error("response for uploading keys does not contain " + "one_time_key_counts.signed_curve25519");
1974
- }
1975
- }
1976
- });
1977
- return function uploadLoop(_x7) {
1978
- return _ref12.apply(this, arguments);
1979
- };
1980
- }();
1981
- this.oneTimeKeyCheckInProgress = true;
1982
- Promise.resolve().then(() => {
1983
- if (this.oneTimeKeyCount !== undefined) {
1984
- // We already have the current one_time_key count from a /sync response.
1985
- // Use this value instead of asking the server for the current key count.
1986
- return Promise.resolve(this.oneTimeKeyCount);
1987
- }
1988
- // ask the server how many keys we have
1989
- return this.baseApis.uploadKeysRequest({}).then(res => {
1990
- return res.one_time_key_counts.signed_curve25519 || 0;
1991
- });
1992
- }).then(keyCount => {
1993
- // Start the uploadLoop with the current keyCount. The function checks if
1994
- // we need to upload new keys or not.
1995
- // If there are too many keys on the server then we don't need to
1996
- // create any more keys.
1997
- return uploadLoop(keyCount);
1998
- }).catch(e => {
1999
- logger.error("Error uploading one-time keys", e.stack || e);
2000
- }).finally(() => {
2001
- // reset oneTimeKeyCount to prevent start uploading based on old data.
2002
- // it will be set again on the next /sync-response
2003
- this.oneTimeKeyCount = undefined;
2004
- this.oneTimeKeyCheckInProgress = false;
2005
- });
2006
- }
2007
-
2008
- // returns a promise which resolves to the response
2009
- uploadOneTimeKeys() {
2010
- var _this26 = this;
2011
- return _asyncToGenerator(function* () {
2012
- var promises = [];
2013
- var fallbackJson;
2014
- if (_this26.getNeedsNewFallback()) {
2015
- fallbackJson = {};
2016
- var fallbackKeys = yield _this26.olmDevice.getFallbackKey();
2017
- for (var [keyId, key] of Object.entries(fallbackKeys.curve25519)) {
2018
- var k = {
2019
- key,
2020
- fallback: true
2021
- };
2022
- fallbackJson["signed_curve25519:" + keyId] = k;
2023
- promises.push(_this26.signObject(k));
2024
- }
2025
- _this26.needsNewFallback = false;
2026
- }
2027
- var oneTimeKeys = yield _this26.olmDevice.getOneTimeKeys();
2028
- var oneTimeJson = {};
2029
- for (var _keyId in oneTimeKeys.curve25519) {
2030
- if (oneTimeKeys.curve25519.hasOwnProperty(_keyId)) {
2031
- var _k = {
2032
- key: oneTimeKeys.curve25519[_keyId]
2033
- };
2034
- oneTimeJson["signed_curve25519:" + _keyId] = _k;
2035
- promises.push(_this26.signObject(_k));
2036
- }
2037
- }
2038
- yield Promise.all(promises);
2039
- var requestBody = {
2040
- one_time_keys: oneTimeJson
2041
- };
2042
- if (fallbackJson) {
2043
- requestBody["org.matrix.msc2732.fallback_keys"] = fallbackJson;
2044
- requestBody["fallback_keys"] = fallbackJson;
2045
- }
2046
- var res = yield _this26.baseApis.uploadKeysRequest(requestBody);
2047
- if (fallbackJson) {
2048
- _this26.fallbackCleanup = setTimeout(() => {
2049
- delete _this26.fallbackCleanup;
2050
- _this26.olmDevice.forgetOldFallbackKey();
2051
- }, 60 * 60 * 1000);
2052
- }
2053
- yield _this26.olmDevice.markKeysAsPublished();
2054
- return res;
2055
- })();
2056
- }
2057
-
2058
- /**
2059
- * Download the keys for a list of users and stores the keys in the session
2060
- * store.
2061
- * @param userIds - The users to fetch.
2062
- * @param forceDownload - Always download the keys even if cached.
2063
- *
2064
- * @returns A promise which resolves to a map `userId->deviceId->{@link DeviceInfo}`.
2065
- */
2066
- downloadKeys(userIds, forceDownload) {
2067
- return this.deviceList.downloadKeys(userIds, !!forceDownload);
2068
- }
2069
-
2070
- /**
2071
- * Get the stored device keys for a user id
2072
- *
2073
- * @param userId - the user to list keys for.
2074
- *
2075
- * @returns list of devices, or null if we haven't
2076
- * managed to get a list of devices for this user yet.
2077
- */
2078
- getStoredDevicesForUser(userId) {
2079
- return this.deviceList.getStoredDevicesForUser(userId);
2080
- }
2081
-
2082
- /**
2083
- * Get the device information for the given list of users.
2084
- *
2085
- * @param userIds - The users to fetch.
2086
- * @param downloadUncached - If true, download the device list for users whose device list we are not
2087
- * currently tracking. Defaults to false, in which case such users will not appear at all in the result map.
2088
- *
2089
- * @returns A map `{@link DeviceMap}`.
2090
- */
2091
- getUserDeviceInfo(userIds) {
2092
- var _arguments6 = arguments,
2093
- _this27 = this;
2094
- return _asyncToGenerator(function* () {
2095
- var downloadUncached = _arguments6.length > 1 && _arguments6[1] !== undefined ? _arguments6[1] : false;
2096
- var deviceMapByUserId = new Map();
2097
- // Keep the users without device to download theirs keys
2098
- var usersWithoutDeviceInfo = [];
2099
- var _loop = function* _loop(_userId4) {
2100
- var deviceInfos = yield _this27.getStoredDevicesForUser(_userId4);
2101
- // If there are device infos for a userId, we transform it into a map
2102
- // Else, the keys will be downloaded after
2103
- if (deviceInfos) {
2104
- var deviceMap = new Map(
2105
- // Convert DeviceInfo to Device
2106
- deviceInfos.map(deviceInfo => [deviceInfo.deviceId, deviceInfoToDevice(deviceInfo, _userId4)]));
2107
- deviceMapByUserId.set(_userId4, deviceMap);
2108
- } else {
2109
- usersWithoutDeviceInfo.push(_userId4);
2110
- }
2111
- };
2112
- for (var _userId4 of userIds) {
2113
- yield* _loop(_userId4);
2114
- }
2115
-
2116
- // Download device info for users without device infos
2117
- if (downloadUncached && usersWithoutDeviceInfo.length > 0) {
2118
- var newDeviceInfoMap = yield _this27.downloadKeys(usersWithoutDeviceInfo);
2119
- newDeviceInfoMap.forEach((deviceInfoMap, userId) => {
2120
- var deviceMap = new Map();
2121
- // Convert DeviceInfo to Device
2122
- deviceInfoMap.forEach((deviceInfo, deviceId) => deviceMap.set(deviceId, deviceInfoToDevice(deviceInfo, userId)));
2123
-
2124
- // Put the new device infos into the returned map
2125
- deviceMapByUserId.set(userId, deviceMap);
2126
- });
2127
- }
2128
- return deviceMapByUserId;
2129
- })();
2130
- }
2131
-
2132
- /**
2133
- * Get the stored keys for a single device
2134
- *
2135
- *
2136
- * @returns device, or undefined
2137
- * if we don't know about this device
2138
- */
2139
- getStoredDevice(userId, deviceId) {
2140
- return this.deviceList.getStoredDevice(userId, deviceId);
2141
- }
2142
-
2143
- /**
2144
- * Save the device list, if necessary
2145
- *
2146
- * @param delay - Time in ms before which the save actually happens.
2147
- * By default, the save is delayed for a short period in order to batch
2148
- * multiple writes, but this behaviour can be disabled by passing 0.
2149
- *
2150
- * @returns true if the data was saved, false if
2151
- * it was not (eg. because no changes were pending). The promise
2152
- * will only resolve once the data is saved, so may take some time
2153
- * to resolve.
2154
- */
2155
- saveDeviceList(delay) {
2156
- return this.deviceList.saveIfDirty(delay);
2157
- }
2158
-
2159
- /**
2160
- * Mark the given device as locally verified.
2161
- *
2162
- * Implementation of {@link Crypto.CryptoApi#setDeviceVerified}.
2163
- */
2164
- setDeviceVerified(userId, deviceId) {
2165
- var _arguments7 = arguments,
2166
- _this28 = this;
2167
- return _asyncToGenerator(function* () {
2168
- var verified = _arguments7.length > 2 && _arguments7[2] !== undefined ? _arguments7[2] : true;
2169
- yield _this28.setDeviceVerification(userId, deviceId, verified);
2170
- })();
2171
- }
2172
-
2173
- /**
2174
- * Blindly cross-sign one of our other devices.
2175
- *
2176
- * Implementation of {@link Crypto.CryptoApi#crossSignDevice}.
2177
- */
2178
- crossSignDevice(deviceId) {
2179
- var _this29 = this;
2180
- return _asyncToGenerator(function* () {
2181
- yield _this29.setDeviceVerified(_this29.userId, deviceId, true);
2182
- })();
2183
- }
2184
-
2185
- /**
2186
- * Update the blocked/verified state of the given device
2187
- *
2188
- * @param userId - owner of the device
2189
- * @param deviceId - unique identifier for the device or user's
2190
- * cross-signing public key ID.
2191
- *
2192
- * @param verified - whether to mark the device as verified. Null to
2193
- * leave unchanged.
2194
- *
2195
- * @param blocked - whether to mark the device as blocked. Null to
2196
- * leave unchanged.
2197
- *
2198
- * @param known - whether to mark that the user has been made aware of
2199
- * the existence of this device. Null to leave unchanged
2200
- *
2201
- * @param keys - The list of keys that was present
2202
- * during the device verification. This will be double checked with the list
2203
- * of keys the given device has currently.
2204
- *
2205
- * @returns updated DeviceInfo
2206
- */
2207
- setDeviceVerification(userId, deviceId) {
2208
- var _arguments8 = arguments,
2209
- _this30 = this;
2210
- return _asyncToGenerator(function* () {
2211
- var verified = _arguments8.length > 2 && _arguments8[2] !== undefined ? _arguments8[2] : null;
2212
- var blocked = _arguments8.length > 3 && _arguments8[3] !== undefined ? _arguments8[3] : null;
2213
- var known = _arguments8.length > 4 && _arguments8[4] !== undefined ? _arguments8[4] : null;
2214
- var keys = _arguments8.length > 5 ? _arguments8[5] : undefined;
2215
- // Check if the 'device' is actually a cross signing key
2216
- // The js-sdk's verification treats cross-signing keys as devices
2217
- // and so uses this method to mark them verified.
2218
- var xsk = _this30.deviceList.getStoredCrossSigningForUser(userId);
2219
- if ((xsk === null || xsk === void 0 ? void 0 : xsk.getId()) === deviceId) {
2220
- if (blocked !== null || known !== null) {
2221
- throw new Error("Cannot set blocked or known for a cross-signing key");
2222
- }
2223
- if (!verified) {
2224
- throw new Error("Cannot set a cross-signing key as unverified");
2225
- }
2226
- var gotKeyId = keys ? Object.values(keys)[0] : null;
2227
- if (keys && (Object.values(keys).length !== 1 || gotKeyId !== xsk.getId())) {
2228
- throw new Error("Key did not match expected value: expected ".concat(xsk.getId(), ", got ").concat(gotKeyId));
2229
- }
2230
- if (!_this30.crossSigningInfo.getId() && userId === _this30.crossSigningInfo.userId) {
2231
- _this30.storeTrustedSelfKeys(xsk.keys);
2232
- // This will cause our own user trust to change, so emit the event
2233
- _this30.emit(CryptoEvent.UserTrustStatusChanged, _this30.userId, _this30.checkUserTrust(userId));
2234
- }
2235
-
2236
- // Now sign the master key with our user signing key (unless it's ourself)
2237
- if (userId !== _this30.userId) {
2238
- logger.info("Master key " + xsk.getId() + " for " + userId + " marked verified. Signing...");
2239
- var device = yield _this30.crossSigningInfo.signUser(xsk);
2240
- if (device) {
2241
- var _upload = /*#__PURE__*/function () {
2242
- var _ref14 = _asyncToGenerator(function* (_ref13) {
2243
- var {
2244
- shouldEmit = false
2245
- } = _ref13;
2246
- logger.info("Uploading signature for " + userId + "...");
2247
- var response = yield _this30.baseApis.uploadKeySignatures({
2248
- [userId]: {
2249
- [deviceId]: device
2250
- }
2251
- });
2252
- var {
2253
- failures
2254
- } = response || {};
2255
- if (Object.keys(failures || []).length > 0) {
2256
- if (shouldEmit) {
2257
- _this30.baseApis.emit(CryptoEvent.KeySignatureUploadFailure, failures, "setDeviceVerification", _upload);
2258
- }
2259
- /* Throwing here causes the process to be cancelled and the other
2260
- * user to be notified */
2261
- throw new KeySignatureUploadError("Key upload failed", {
2262
- failures
2263
- });
2264
- }
2265
- });
2266
- return function upload(_x8) {
2267
- return _ref14.apply(this, arguments);
2268
- };
2269
- }();
2270
- yield _upload({
2271
- shouldEmit: true
2272
- });
2273
-
2274
- // This will emit events when it comes back down the sync
2275
- // (we could do local echo to speed things up)
2276
- }
2277
- return device;
2278
- } else {
2279
- return xsk;
2280
- }
2281
- }
2282
- var devices = _this30.deviceList.getRawStoredDevicesForUser(userId);
2283
- if (!devices || !devices[deviceId]) {
2284
- throw new Error("Unknown device " + userId + ":" + deviceId);
2285
- }
2286
- var dev = devices[deviceId];
2287
- var verificationStatus = dev.verified;
2288
- if (verified) {
2289
- if (keys) {
2290
- for (var [keyId, key] of Object.entries(keys)) {
2291
- if (dev.keys[keyId] !== key) {
2292
- throw new Error("Key did not match expected value: expected ".concat(key, ", got ").concat(dev.keys[keyId]));
2293
- }
2294
- }
2295
- }
2296
- verificationStatus = DeviceVerification.VERIFIED;
2297
- } else if (verified !== null && verificationStatus == DeviceVerification.VERIFIED) {
2298
- verificationStatus = DeviceVerification.UNVERIFIED;
2299
- }
2300
- if (blocked) {
2301
- verificationStatus = DeviceVerification.BLOCKED;
2302
- } else if (blocked !== null && verificationStatus == DeviceVerification.BLOCKED) {
2303
- verificationStatus = DeviceVerification.UNVERIFIED;
2304
- }
2305
- var knownStatus = dev.known;
2306
- if (known !== null) {
2307
- knownStatus = known;
2308
- }
2309
- if (dev.verified !== verificationStatus || dev.known !== knownStatus) {
2310
- dev.verified = verificationStatus;
2311
- dev.known = knownStatus;
2312
- _this30.deviceList.storeDevicesForUser(userId, devices);
2313
- _this30.deviceList.saveIfDirty();
2314
- }
2315
-
2316
- // do cross-signing
2317
- if (verified && userId === _this30.userId) {
2318
- logger.info("Own device " + deviceId + " marked verified: signing");
2319
-
2320
- // Signing only needed if other device not already signed
2321
- var _device;
2322
- var deviceTrust = _this30.checkDeviceTrust(userId, deviceId);
2323
- if (deviceTrust.isCrossSigningVerified()) {
2324
- logger.log("Own device ".concat(deviceId, " already cross-signing verified"));
2325
- } else {
2326
- _device = yield _this30.crossSigningInfo.signDevice(userId, DeviceInfo.fromStorage(dev, deviceId));
2327
- }
2328
- if (_device) {
2329
- var _upload2 = /*#__PURE__*/function () {
2330
- var _ref16 = _asyncToGenerator(function* (_ref15) {
2331
- var {
2332
- shouldEmit = false
2333
- } = _ref15;
2334
- logger.info("Uploading signature for " + deviceId);
2335
- var response = yield _this30.baseApis.uploadKeySignatures({
2336
- [userId]: {
2337
- [deviceId]: _device
2338
- }
2339
- });
2340
- var {
2341
- failures
2342
- } = response || {};
2343
- if (Object.keys(failures || []).length > 0) {
2344
- if (shouldEmit) {
2345
- _this30.baseApis.emit(CryptoEvent.KeySignatureUploadFailure, failures, "setDeviceVerification", _upload2 // continuation
2346
- );
2347
- }
2348
- throw new KeySignatureUploadError("Key upload failed", {
2349
- failures
2350
- });
2351
- }
2352
- });
2353
- return function upload(_x9) {
2354
- return _ref16.apply(this, arguments);
2355
- };
2356
- }();
2357
- yield _upload2({
2358
- shouldEmit: true
2359
- });
2360
- // XXX: we'll need to wait for the device list to be updated
2361
- }
2362
- }
2363
- var deviceObj = DeviceInfo.fromStorage(dev, deviceId);
2364
- _this30.emit(CryptoEvent.DeviceVerificationChanged, userId, deviceId, deviceObj);
2365
- return deviceObj;
2366
- })();
2367
- }
2368
- findVerificationRequestDMInProgress(roomId, userId) {
2369
- return this.inRoomVerificationRequests.findRequestInProgress(roomId, userId);
2370
- }
2371
- getVerificationRequestsToDeviceInProgress(userId) {
2372
- return this.toDeviceVerificationRequests.getRequestsInProgress(userId);
2373
- }
2374
- requestVerificationDM(userId, roomId) {
2375
- var existingRequest = this.inRoomVerificationRequests.findRequestInProgress(roomId);
2376
- if (existingRequest) {
2377
- return Promise.resolve(existingRequest);
2378
- }
2379
- var channel = new InRoomChannel(this.baseApis, roomId, userId);
2380
- return this.requestVerificationWithChannel(userId, channel, this.inRoomVerificationRequests);
2381
- }
2382
-
2383
- /** @deprecated Use `requestOwnUserVerificationToDevice` or `requestDeviceVerification` */
2384
- requestVerification(userId, devices) {
2385
- if (!devices) {
2386
- devices = Object.keys(this.deviceList.getRawStoredDevicesForUser(userId));
2387
- }
2388
- var existingRequest = this.toDeviceVerificationRequests.findRequestInProgress(userId, devices);
2389
- if (existingRequest) {
2390
- return Promise.resolve(existingRequest);
2391
- }
2392
- var channel = new ToDeviceChannel(this.baseApis, userId, devices, ToDeviceChannel.makeTransactionId());
2393
- return this.requestVerificationWithChannel(userId, channel, this.toDeviceVerificationRequests);
2394
- }
2395
- requestOwnUserVerification() {
2396
- return this.requestVerification(this.userId);
2397
- }
2398
- requestDeviceVerification(userId, deviceId) {
2399
- return this.requestVerification(userId, [deviceId]);
2400
- }
2401
- requestVerificationWithChannel(userId, channel, requestsMap) {
2402
- var _this31 = this;
2403
- return _asyncToGenerator(function* () {
2404
- var request = new VerificationRequest(channel, _this31.verificationMethods, _this31.baseApis);
2405
- // if transaction id is already known, add request
2406
- if (channel.transactionId) {
2407
- requestsMap.setRequestByChannel(channel, request);
2408
- }
2409
- yield request.sendRequest();
2410
- // don't replace the request created by a racing remote echo
2411
- var racingRequest = requestsMap.getRequestByChannel(channel);
2412
- if (racingRequest) {
2413
- request = racingRequest;
2414
- } else {
2415
- logger.log("Crypto: adding new request to " + "requestsByTxnId with id ".concat(channel.transactionId, " ").concat(channel.roomId));
2416
- requestsMap.setRequestByChannel(channel, request);
2417
- }
2418
- return request;
2419
- })();
2420
- }
2421
- beginKeyVerification(method, userId, deviceId) {
2422
- var transactionId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
2423
- var request;
2424
- if (transactionId) {
2425
- request = this.toDeviceVerificationRequests.getRequestBySenderAndTxnId(userId, transactionId);
2426
- if (!request) {
2427
- throw new Error("No request found for user ".concat(userId, " with ") + "transactionId ".concat(transactionId));
2428
- }
2429
- } else {
2430
- transactionId = ToDeviceChannel.makeTransactionId();
2431
- var _channel = new ToDeviceChannel(this.baseApis, userId, [deviceId], transactionId, deviceId);
2432
- request = new VerificationRequest(_channel, this.verificationMethods, this.baseApis);
2433
- this.toDeviceVerificationRequests.setRequestBySenderAndTxnId(userId, transactionId, request);
2434
- }
2435
- return request.beginKeyVerification(method, {
2436
- userId,
2437
- deviceId
2438
- });
2439
- }
2440
- legacyDeviceVerification(userId, deviceId, method) {
2441
- var _this32 = this;
2442
- return _asyncToGenerator(function* () {
2443
- var transactionId = ToDeviceChannel.makeTransactionId();
2444
- var channel = new ToDeviceChannel(_this32.baseApis, userId, [deviceId], transactionId, deviceId);
2445
- var request = new VerificationRequest(channel, _this32.verificationMethods, _this32.baseApis);
2446
- _this32.toDeviceVerificationRequests.setRequestBySenderAndTxnId(userId, transactionId, request);
2447
- var verifier = request.beginKeyVerification(method, {
2448
- userId,
2449
- deviceId
2450
- });
2451
- // either reject by an error from verify() while sending .start
2452
- // or resolve when the request receives the
2453
- // local (fake remote) echo for sending the .start event
2454
- yield Promise.race([verifier.verify(), request.waitFor(r => r.started)]);
2455
- return request;
2456
- })();
2457
- }
2458
-
2459
- /**
2460
- * Get information on the active olm sessions with a user
2461
- * <p>
2462
- * Returns a map from device id to an object with keys 'deviceIdKey' (the
2463
- * device's curve25519 identity key) and 'sessions' (an array of objects in the
2464
- * same format as that returned by
2465
- * {@link OlmDevice#getSessionInfoForDevice}).
2466
- * <p>
2467
- * This method is provided for debugging purposes.
2468
- *
2469
- * @param userId - id of user to inspect
2470
- */
2471
- getOlmSessionsForUser(userId) {
2472
- var _this33 = this;
2473
- return _asyncToGenerator(function* () {
2474
- var devices = _this33.getStoredDevicesForUser(userId) || [];
2475
- var result = {};
2476
- for (var device of devices) {
2477
- var deviceKey = device.getIdentityKey();
2478
- var sessions = yield _this33.olmDevice.getSessionInfoForDevice(deviceKey);
2479
- result[device.deviceId] = {
2480
- deviceIdKey: deviceKey,
2481
- sessions: sessions
2482
- };
2483
- }
2484
- return result;
2485
- })();
2486
- }
2487
-
2488
- /**
2489
- * Get the device which sent an event
2490
- *
2491
- * @param event - event to be checked
2492
- */
2493
- getEventSenderDeviceInfo(event) {
2494
- var senderKey = event.getSenderKey();
2495
- var algorithm = event.getWireContent().algorithm;
2496
- if (!senderKey || !algorithm) {
2497
- return null;
2498
- }
2499
- if (event.isKeySourceUntrusted()) {
2500
- // we got the key for this event from a source that we consider untrusted
2501
- return null;
2502
- }
2503
-
2504
- // senderKey is the Curve25519 identity key of the device which the event
2505
- // was sent from. In the case of Megolm, it's actually the Curve25519
2506
- // identity key of the device which set up the Megolm session.
2507
-
2508
- var device = this.deviceList.getDeviceByIdentityKey(algorithm, senderKey);
2509
- if (device === null) {
2510
- // we haven't downloaded the details of this device yet.
2511
- return null;
2512
- }
2513
-
2514
- // so far so good, but now we need to check that the sender of this event
2515
- // hadn't advertised someone else's Curve25519 key as their own. We do that
2516
- // by checking the Ed25519 claimed by the event (or, in the case of megolm,
2517
- // the event which set up the megolm session), to check that it matches the
2518
- // fingerprint of the purported sending device.
2519
- //
2520
- // (see https://github.com/vector-im/vector-web/issues/2215)
2521
-
2522
- var claimedKey = event.getClaimedEd25519Key();
2523
- if (!claimedKey) {
2524
- logger.warn("Event " + event.getId() + " claims no ed25519 key: " + "cannot verify sending device");
2525
- return null;
2526
- }
2527
- if (claimedKey !== device.getFingerprint()) {
2528
- logger.warn("Event " + event.getId() + " claims ed25519 key " + claimedKey + " but sender device has key " + device.getFingerprint());
2529
- return null;
2530
- }
2531
- return device;
2532
- }
2533
-
2534
- /**
2535
- * Get information about the encryption of an event
2536
- *
2537
- * @param event - event to be checked
2538
- *
2539
- * @returns An object with the fields:
2540
- * - encrypted: whether the event is encrypted (if not encrypted, some of the
2541
- * other properties may not be set)
2542
- * - senderKey: the sender's key
2543
- * - algorithm: the algorithm used to encrypt the event
2544
- * - authenticated: whether we can be sure that the owner of the senderKey
2545
- * sent the event
2546
- * - sender: the sender's device information, if available
2547
- * - mismatchedSender: if the event's ed25519 and curve25519 keys don't match
2548
- * (only meaningful if `sender` is set)
2549
- */
2550
- getEventEncryptionInfo(event) {
2551
- var _event$getSenderKey, _this$deviceList$getD;
2552
- var ret = {};
2553
- ret.senderKey = (_event$getSenderKey = event.getSenderKey()) !== null && _event$getSenderKey !== void 0 ? _event$getSenderKey : undefined;
2554
- ret.algorithm = event.getWireContent().algorithm;
2555
- if (!ret.senderKey || !ret.algorithm) {
2556
- ret.encrypted = false;
2557
- return ret;
2558
- }
2559
- ret.encrypted = true;
2560
- if (event.isKeySourceUntrusted()) {
2561
- // we got the key this event from somewhere else
2562
- // TODO: check if we can trust the forwarders.
2563
- ret.authenticated = false;
2564
- } else {
2565
- ret.authenticated = true;
2566
- }
2567
-
2568
- // senderKey is the Curve25519 identity key of the device which the event
2569
- // was sent from. In the case of Megolm, it's actually the Curve25519
2570
- // identity key of the device which set up the Megolm session.
2571
-
2572
- ret.sender = (_this$deviceList$getD = this.deviceList.getDeviceByIdentityKey(ret.algorithm, ret.senderKey)) !== null && _this$deviceList$getD !== void 0 ? _this$deviceList$getD : undefined;
2573
-
2574
- // so far so good, but now we need to check that the sender of this event
2575
- // hadn't advertised someone else's Curve25519 key as their own. We do that
2576
- // by checking the Ed25519 claimed by the event (or, in the case of megolm,
2577
- // the event which set up the megolm session), to check that it matches the
2578
- // fingerprint of the purported sending device.
2579
- //
2580
- // (see https://github.com/vector-im/vector-web/issues/2215)
2581
-
2582
- var claimedKey = event.getClaimedEd25519Key();
2583
- if (!claimedKey) {
2584
- logger.warn("Event " + event.getId() + " claims no ed25519 key: " + "cannot verify sending device");
2585
- ret.mismatchedSender = true;
2586
- }
2587
- if (ret.sender && claimedKey !== ret.sender.getFingerprint()) {
2588
- logger.warn("Event " + event.getId() + " claims ed25519 key " + claimedKey + "but sender device has key " + ret.sender.getFingerprint());
2589
- ret.mismatchedSender = true;
2590
- }
2591
- return ret;
2592
- }
2593
-
2594
- /**
2595
- * Implementation of {@link Crypto.CryptoApi.getEncryptionInfoForEvent}.
2596
- */
2597
- getEncryptionInfoForEvent(event) {
2598
- var _this34 = this;
2599
- return _asyncToGenerator(function* () {
2600
- var encryptionInfo = _this34.getEventEncryptionInfo(event);
2601
- if (!encryptionInfo.encrypted) {
2602
- return null;
2603
- }
2604
- var senderId = event.getSender();
2605
- if (!senderId || encryptionInfo.mismatchedSender) {
2606
- // something definitely wrong is going on here
2607
-
2608
- // previously: E2EState.Warning -> E2ePadlockUnverified -> Red/"Encrypted by an unverified session"
2609
- return {
2610
- shieldColour: EventShieldColour.RED,
2611
- shieldReason: EventShieldReason.MISMATCHED_SENDER_KEY
2612
- };
2613
- }
2614
- var userTrust = _this34.checkUserTrust(senderId);
2615
- if (!userTrust.isCrossSigningVerified()) {
2616
- // If the message is unauthenticated, then display a grey
2617
- // shield, otherwise if the user isn't cross-signed then
2618
- // nothing's needed
2619
- if (!encryptionInfo.authenticated) {
2620
- // previously: E2EState.Unauthenticated -> E2ePadlockUnauthenticated -> Grey/"The authenticity of this encrypted message can't be guaranteed on this device."
2621
- return {
2622
- shieldColour: EventShieldColour.GREY,
2623
- shieldReason: EventShieldReason.AUTHENTICITY_NOT_GUARANTEED
2624
- };
2625
- } else {
2626
- // previously: E2EState.Normal -> no icon
2627
- return {
2628
- shieldColour: EventShieldColour.NONE,
2629
- shieldReason: null
2630
- };
2631
- }
2632
- }
2633
- var eventSenderTrust = senderId && encryptionInfo.sender && (yield _this34.getDeviceVerificationStatus(senderId, encryptionInfo.sender.deviceId));
2634
- if (!eventSenderTrust) {
2635
- // previously: E2EState.Unknown -> E2ePadlockUnknown -> Grey/"Encrypted by a deleted session"
2636
- return {
2637
- shieldColour: EventShieldColour.GREY,
2638
- shieldReason: EventShieldReason.UNKNOWN_DEVICE
2639
- };
2640
- }
2641
- if (!eventSenderTrust.isVerified()) {
2642
- // previously: E2EState.Warning -> E2ePadlockUnverified -> Red/"Encrypted by an unverified session"
2643
- return {
2644
- shieldColour: EventShieldColour.RED,
2645
- shieldReason: EventShieldReason.UNSIGNED_DEVICE
2646
- };
2647
- }
2648
- if (!encryptionInfo.authenticated) {
2649
- // previously: E2EState.Unauthenticated -> E2ePadlockUnauthenticated -> Grey/"The authenticity of this encrypted message can't be guaranteed on this device."
2650
- return {
2651
- shieldColour: EventShieldColour.GREY,
2652
- shieldReason: EventShieldReason.AUTHENTICITY_NOT_GUARANTEED
2653
- };
2654
- }
2655
-
2656
- // previously: E2EState.Verified -> no icon
2657
- return {
2658
- shieldColour: EventShieldColour.NONE,
2659
- shieldReason: null
2660
- };
2661
- })();
2662
- }
2663
-
2664
- /**
2665
- * Forces the current outbound group session to be discarded such
2666
- * that another one will be created next time an event is sent.
2667
- *
2668
- * @param roomId - The ID of the room to discard the session for
2669
- *
2670
- * This should not normally be necessary.
2671
- */
2672
- forceDiscardSession(roomId) {
2673
- var alg = this.roomEncryptors.get(roomId);
2674
- if (alg === undefined) throw new Error("Room not encrypted");
2675
- if (alg.forceDiscardSession === undefined) {
2676
- throw new Error("Room encryption algorithm doesn't support session discarding");
2677
- }
2678
- alg.forceDiscardSession();
2679
- return Promise.resolve();
2680
- }
2681
-
2682
- /**
2683
- * Configure a room to use encryption (ie, save a flag in the cryptoStore).
2684
- *
2685
- * @param roomId - The room ID to enable encryption in.
2686
- *
2687
- * @param config - The encryption config for the room.
2688
- *
2689
- * @param inhibitDeviceQuery - true to suppress device list query for
2690
- * users in the room (for now). In case lazy loading is enabled,
2691
- * the device query is always inhibited as the members are not tracked.
2692
- *
2693
- * @deprecated It is normally incorrect to call this method directly. Encryption
2694
- * is enabled by receiving an `m.room.encryption` event (which we may have sent
2695
- * previously).
2696
- */
2697
- setRoomEncryption(roomId, config, inhibitDeviceQuery) {
2698
- var _this35 = this;
2699
- return _asyncToGenerator(function* () {
2700
- var room = _this35.clientStore.getRoom(roomId);
2701
- if (!room) {
2702
- throw new Error("Unable to enable encryption tracking devices in unknown room ".concat(roomId));
2703
- }
2704
- yield _this35.setRoomEncryptionImpl(room, config);
2705
- if (!_this35.lazyLoadMembers && !inhibitDeviceQuery) {
2706
- _this35.deviceList.refreshOutdatedDeviceLists();
2707
- }
2708
- })();
2709
- }
2710
-
2711
- /**
2712
- * Set up encryption for a room.
2713
- *
2714
- * This is called when an <tt>m.room.encryption</tt> event is received. It saves a flag
2715
- * for the room in the cryptoStore (if it wasn't already set), sets up an "encryptor" for
2716
- * the room, and enables device-list tracking for the room.
2717
- *
2718
- * It does <em>not</em> initiate a device list query for the room. That is normally
2719
- * done once we finish processing the sync, in onSyncCompleted.
2720
- *
2721
- * @param room - The room to enable encryption in.
2722
- * @param config - The encryption config for the room.
2723
- */
2724
- setRoomEncryptionImpl(room, config) {
2725
- var _this36 = this;
2726
- return _asyncToGenerator(function* () {
2727
- var roomId = room.roomId;
2728
-
2729
- // ignore crypto events with no algorithm defined
2730
- // This will happen if a crypto event is redacted before we fetch the room state
2731
- // It would otherwise just throw later as an unknown algorithm would, but we may
2732
- // as well catch this here
2733
- if (!config.algorithm) {
2734
- logger.log("Ignoring setRoomEncryption with no algorithm");
2735
- return;
2736
- }
2737
-
2738
- // if state is being replayed from storage, we might already have a configuration
2739
- // for this room as they are persisted as well.
2740
- // We just need to make sure the algorithm is initialized in this case.
2741
- // However, if the new config is different,
2742
- // we should bail out as room encryption can't be changed once set.
2743
- var existingConfig = _this36.roomList.getRoomEncryption(roomId);
2744
- if (existingConfig) {
2745
- if (JSON.stringify(existingConfig) != JSON.stringify(config)) {
2746
- logger.error("Ignoring m.room.encryption event which requests " + "a change of config in " + roomId);
2747
- return;
2748
- }
2749
- }
2750
- // if we already have encryption in this room, we should ignore this event,
2751
- // as it would reset the encryption algorithm.
2752
- // This is at least expected to be called twice, as sync calls onCryptoEvent
2753
- // for both the timeline and state sections in the /sync response,
2754
- // the encryption event would appear in both.
2755
- // If it's called more than twice though,
2756
- // it signals a bug on client or server.
2757
- var existingAlg = _this36.roomEncryptors.get(roomId);
2758
- if (existingAlg) {
2759
- return;
2760
- }
2761
-
2762
- // _roomList.getRoomEncryption will not race with _roomList.setRoomEncryption
2763
- // because it first stores in memory. We should await the promise only
2764
- // after all the in-memory state (roomEncryptors and _roomList) has been updated
2765
- // to avoid races when calling this method multiple times. Hence keep a hold of the promise.
2766
- var storeConfigPromise = null;
2767
- if (!existingConfig) {
2768
- storeConfigPromise = _this36.roomList.setRoomEncryption(roomId, config);
2769
- }
2770
- var AlgClass = algorithms.ENCRYPTION_CLASSES.get(config.algorithm);
2771
- if (!AlgClass) {
2772
- throw new Error("Unable to encrypt with " + config.algorithm);
2773
- }
2774
- var alg = new AlgClass({
2775
- userId: _this36.userId,
2776
- deviceId: _this36.deviceId,
2777
- crypto: _this36,
2778
- olmDevice: _this36.olmDevice,
2779
- baseApis: _this36.baseApis,
2780
- roomId,
2781
- config
2782
- });
2783
- _this36.roomEncryptors.set(roomId, alg);
2784
- if (storeConfigPromise) {
2785
- yield storeConfigPromise;
2786
- }
2787
- logger.log("Enabling encryption in ".concat(roomId));
2788
-
2789
- // we don't want to force a download of the full membership list of this room, but as soon as we have that
2790
- // list we can start tracking the device list.
2791
- if (room.membersLoaded()) {
2792
- yield _this36.trackRoomDevicesImpl(room);
2793
- } else {
2794
- // wait for the membership list to be loaded
2795
- var onState = _state => {
2796
- room.off(RoomStateEvent.Update, onState);
2797
- if (room.membersLoaded()) {
2798
- _this36.trackRoomDevicesImpl(room).catch(e => {
2799
- logger.error("Error enabling device tracking in ".concat(roomId), e);
2800
- });
2801
- }
2802
- };
2803
- room.on(RoomStateEvent.Update, onState);
2804
- }
2805
- })();
2806
- }
2807
-
2808
- /**
2809
- * Make sure we are tracking the device lists for all users in this room.
2810
- *
2811
- * @param roomId - The room ID to start tracking devices in.
2812
- * @returns when all devices for the room have been fetched and marked to track
2813
- * @deprecated there's normally no need to call this function: device list tracking
2814
- * will be enabled as soon as we have the full membership list.
2815
- */
2816
- trackRoomDevices(roomId) {
2817
- var room = this.clientStore.getRoom(roomId);
2818
- if (!room) {
2819
- throw new Error("Unable to start tracking devices in unknown room ".concat(roomId));
2820
- }
2821
- return this.trackRoomDevicesImpl(room);
2822
- }
2823
-
2824
- /**
2825
- * Make sure we are tracking the device lists for all users in this room.
2826
- *
2827
- * This is normally called when we are about to send an encrypted event, to make sure
2828
- * we have all the devices in the room; but it is also called when processing an
2829
- * m.room.encryption state event (if lazy-loading is disabled), or when members are
2830
- * loaded (if lazy-loading is enabled), to prepare the device list.
2831
- *
2832
- * @param room - Room to enable device-list tracking in
2833
- */
2834
- trackRoomDevicesImpl(room) {
2835
- var _this37 = this;
2836
- var roomId = room.roomId;
2837
- var trackMembers = /*#__PURE__*/function () {
2838
- var _ref17 = _asyncToGenerator(function* () {
2839
- // not an encrypted room
2840
- if (!_this37.roomEncryptors.has(roomId)) {
2841
- return;
2842
- }
2843
- logger.log("Starting to track devices for room ".concat(roomId, " ..."));
2844
- var members = yield room.getEncryptionTargetMembers();
2845
- members.forEach(m => {
2846
- _this37.deviceList.startTrackingDeviceList(m.userId);
2847
- });
2848
- });
2849
- return function trackMembers() {
2850
- return _ref17.apply(this, arguments);
2851
- };
2852
- }();
2853
- var promise = this.roomDeviceTrackingState[roomId];
2854
- if (!promise) {
2855
- promise = trackMembers();
2856
- this.roomDeviceTrackingState[roomId] = promise.catch(err => {
2857
- delete this.roomDeviceTrackingState[roomId];
2858
- throw err;
2859
- });
2860
- }
2861
- return promise;
2862
- }
2863
-
2864
- /**
2865
- * Try to make sure we have established olm sessions for all known devices for
2866
- * the given users.
2867
- *
2868
- * @param users - list of user ids
2869
- * @param force - If true, force a new Olm session to be created. Default false.
2870
- *
2871
- * @returns resolves once the sessions are complete, to
2872
- * an Object mapping from userId to deviceId to
2873
- * `IOlmSessionResult`
2874
- */
2875
- ensureOlmSessionsForUsers(users, force) {
2876
- // map user Id → DeviceInfo[]
2877
- var devicesByUser = new Map();
2878
- for (var _userId5 of users) {
2879
- var userDevices = [];
2880
- devicesByUser.set(_userId5, userDevices);
2881
- var devices = this.getStoredDevicesForUser(_userId5) || [];
2882
- for (var deviceInfo of devices) {
2883
- var key = deviceInfo.getIdentityKey();
2884
- if (key == this.olmDevice.deviceCurve25519Key) {
2885
- // don't bother setting up session to ourself
2886
- continue;
2887
- }
2888
- if (deviceInfo.verified == DeviceVerification.BLOCKED) {
2889
- // don't bother setting up sessions with blocked users
2890
- continue;
2891
- }
2892
- userDevices.push(deviceInfo);
2893
- }
2894
- }
2895
- return olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, devicesByUser, force);
2896
- }
2897
-
2898
- /**
2899
- * Get a list containing all of the room keys
2900
- *
2901
- * @returns a list of session export objects
2902
- */
2903
- exportRoomKeys() {
2904
- var _this38 = this;
2905
- return _asyncToGenerator(function* () {
2906
- var exportedSessions = [];
2907
- yield _this38.cryptoStore.doTxn("readonly", [IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS], txn => {
2908
- _this38.cryptoStore.getAllEndToEndInboundGroupSessions(txn, s => {
2909
- if (s === null) return;
2910
- var sess = _this38.olmDevice.exportInboundGroupSession(s.senderKey, s.sessionId, s.sessionData);
2911
- delete sess.first_known_index;
2912
- sess.algorithm = olmlib.MEGOLM_ALGORITHM;
2913
- exportedSessions.push(sess);
2914
- });
2915
- });
2916
- return exportedSessions;
2917
- })();
2918
- }
2919
-
2920
- /**
2921
- * Get a JSON list containing all of the room keys
2922
- *
2923
- * @returns a JSON string encoding a list of session
2924
- * export objects, each of which is an IMegolmSessionData
2925
- */
2926
- exportRoomKeysAsJson() {
2927
- var _this39 = this;
2928
- return _asyncToGenerator(function* () {
2929
- return JSON.stringify(yield _this39.exportRoomKeys());
2930
- })();
2931
- }
2932
-
2933
- /**
2934
- * Import a list of room keys previously exported by exportRoomKeys
2935
- *
2936
- * @param keys - a list of session export objects
2937
- * @returns a promise which resolves once the keys have been imported
2938
- */
2939
- importRoomKeys(keys) {
2940
- var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2941
- var successes = 0;
2942
- var failures = 0;
2943
- var total = keys.length;
2944
- function updateProgress() {
2945
- var _opts$progressCallbac;
2946
- (_opts$progressCallbac = opts.progressCallback) === null || _opts$progressCallbac === void 0 || _opts$progressCallbac.call(opts, {
2947
- stage: "load_keys",
2948
- successes,
2949
- failures,
2950
- total
2951
- });
2952
- }
2953
- return Promise.all(keys.map(key => {
2954
- if (!key.room_id || !key.algorithm) {
2955
- logger.warn("ignoring room key entry with missing fields", key);
2956
- failures++;
2957
- if (opts.progressCallback) {
2958
- updateProgress();
2959
- }
2960
- return null;
2961
- }
2962
- var alg = this.getRoomDecryptor(key.room_id, key.algorithm);
2963
- return alg.importRoomKey(key, opts).finally(() => {
2964
- successes++;
2965
- if (opts.progressCallback) {
2966
- updateProgress();
2967
- }
2968
- });
2969
- })).then();
2970
- }
2971
-
2972
- /**
2973
- * Import a JSON string encoding a list of room keys previously
2974
- * exported by exportRoomKeysAsJson
2975
- *
2976
- * @param keys - a JSON string encoding a list of session export
2977
- * objects, each of which is an IMegolmSessionData
2978
- * @param opts - options object
2979
- * @returns a promise which resolves once the keys have been imported
2980
- */
2981
- importRoomKeysAsJson(keys, opts) {
2982
- var _this40 = this;
2983
- return _asyncToGenerator(function* () {
2984
- return yield _this40.importRoomKeys(JSON.parse(keys));
2985
- })();
2986
- }
2987
-
2988
- /**
2989
- * Counts the number of end to end session keys that are waiting to be backed up
2990
- * @returns Promise which resolves to the number of sessions requiring backup
2991
- */
2992
- countSessionsNeedingBackup() {
2993
- return this.backupManager.countSessionsNeedingBackup();
2994
- }
2995
-
2996
- /**
2997
- * Perform any background tasks that can be done before a message is ready to
2998
- * send, in order to speed up sending of the message.
2999
- *
3000
- * @param room - the room the event is in
3001
- */
3002
- prepareToEncrypt(room) {
3003
- var alg = this.roomEncryptors.get(room.roomId);
3004
- if (alg) {
3005
- alg.prepareToEncrypt(room);
3006
- }
3007
- }
3008
-
3009
- /**
3010
- * Encrypt an event according to the configuration of the room.
3011
- *
3012
- * @param event - event to be sent
3013
- *
3014
- * @param room - destination room.
3015
- *
3016
- * @returns Promise which resolves when the event has been
3017
- * encrypted, or null if nothing was needed
3018
- */
3019
- encryptEvent(event, room) {
3020
- var _this41 = this;
3021
- return _asyncToGenerator(function* () {
3022
- var roomId = event.getRoomId();
3023
- var alg = _this41.roomEncryptors.get(roomId);
3024
- if (!alg) {
3025
- // MatrixClient has already checked that this room should be encrypted,
3026
- // so this is an unexpected situation.
3027
- throw new Error("Room " + roomId + " was previously configured to use encryption, but is " + "no longer. Perhaps the homeserver is hiding the " + "configuration event.");
3028
- }
3029
-
3030
- // wait for all the room devices to be loaded
3031
- yield _this41.trackRoomDevicesImpl(room);
3032
- var content = event.getContent();
3033
- // If event has an m.relates_to then we need
3034
- // to put this on the wrapping event instead
3035
- var mRelatesTo = content["m.relates_to"];
3036
- if (mRelatesTo) {
3037
- // Clone content here so we don't remove `m.relates_to` from the local-echo
3038
- content = Object.assign({}, content);
3039
- delete content["m.relates_to"];
3040
- }
3041
-
3042
- // Treat element's performance metrics the same as `m.relates_to` (when present)
3043
- var elementPerfMetrics = content["io.element.performance_metrics"];
3044
- if (elementPerfMetrics) {
3045
- content = Object.assign({}, content);
3046
- delete content["io.element.performance_metrics"];
3047
- }
3048
- var encryptedContent = yield alg.encryptMessage(room, event.getType(), content);
3049
- if (mRelatesTo) {
3050
- encryptedContent["m.relates_to"] = mRelatesTo;
3051
- }
3052
- if (elementPerfMetrics) {
3053
- encryptedContent["io.element.performance_metrics"] = elementPerfMetrics;
3054
- }
3055
- event.makeEncrypted("m.room.encrypted", encryptedContent, _this41.olmDevice.deviceCurve25519Key, _this41.olmDevice.deviceEd25519Key);
3056
- })();
3057
- }
3058
-
3059
- /**
3060
- * Decrypt a received event
3061
- *
3062
- *
3063
- * @returns resolves once we have
3064
- * finished decrypting. Rejects with an `algorithms.DecryptionError` if there
3065
- * is a problem decrypting the event.
3066
- */
3067
- decryptEvent(event) {
3068
- var _this42 = this;
3069
- return _asyncToGenerator(function* () {
3070
- if (event.isRedacted()) {
3071
- // Try to decrypt the redaction event, to support encrypted
3072
- // redaction reasons. If we can't decrypt, just fall back to using
3073
- // the original redacted_because.
3074
- var redactionEvent = new MatrixEvent(_objectSpread({
3075
- room_id: event.getRoomId()
3076
- }, event.getUnsigned().redacted_because));
3077
- var redactedBecause = event.getUnsigned().redacted_because;
3078
- if (redactionEvent.isEncrypted()) {
3079
- try {
3080
- var decryptedEvent = yield _this42.decryptEvent(redactionEvent);
3081
- redactedBecause = decryptedEvent.clearEvent;
3082
- } catch (e) {
3083
- logger.warn("Decryption of redaction failed. Falling back to unencrypted event.", e);
3084
- }
3085
- }
3086
- return {
3087
- clearEvent: {
3088
- room_id: event.getRoomId(),
3089
- type: "m.room.message",
3090
- content: {},
3091
- unsigned: {
3092
- redacted_because: redactedBecause
3093
- }
3094
- }
3095
- };
3096
- } else {
3097
- var content = event.getWireContent();
3098
- var alg = _this42.getRoomDecryptor(event.getRoomId(), content.algorithm);
3099
- return alg.decryptEvent(event);
3100
- }
3101
- })();
3102
- }
3103
-
3104
- /**
3105
- * Handle the notification from /sync that device lists have
3106
- * been changed.
3107
- *
3108
- * @param deviceLists - device_lists field from /sync
3109
- */
3110
- processDeviceLists(deviceLists) {
3111
- var _this43 = this;
3112
- return _asyncToGenerator(function* () {
3113
- // Here, we're relying on the fact that we only ever save the sync data after
3114
- // sucessfully saving the device list data, so we're guaranteed that the device
3115
- // list store is at least as fresh as the sync token from the sync store, ie.
3116
- // any device changes received in sync tokens prior to the 'next' token here
3117
- // have been processed and are reflected in the current device list.
3118
- // If we didn't make this assumption, we'd have to use the /keys/changes API
3119
- // to get key changes between the sync token in the device list and the 'old'
3120
- // sync token used here to make sure we didn't miss any.
3121
- yield _this43.evalDeviceListChanges(deviceLists);
3122
- })();
3123
- }
3124
-
3125
- /**
3126
- * Send a request for some room keys, if we have not already done so
3127
- *
3128
- * @param resend - whether to resend the key request if there is
3129
- * already one
3130
- *
3131
- * @returns a promise that resolves when the key request is queued
3132
- */
3133
- requestRoomKey(requestBody, recipients) {
3134
- var resend = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
3135
- return this.outgoingRoomKeyRequestManager.queueRoomKeyRequest(requestBody, recipients, resend).then(() => {
3136
- if (this.sendKeyRequestsImmediately) {
3137
- this.outgoingRoomKeyRequestManager.sendQueuedRequests();
3138
- }
3139
- }).catch(e => {
3140
- // this normally means we couldn't talk to the store
3141
- logger.error("Error requesting key for event", e);
3142
- });
3143
- }
3144
-
3145
- /**
3146
- * Cancel any earlier room key request
3147
- *
3148
- * @param requestBody - parameters to match for cancellation
3149
- */
3150
- cancelRoomKeyRequest(requestBody) {
3151
- this.outgoingRoomKeyRequestManager.cancelRoomKeyRequest(requestBody).catch(e => {
3152
- logger.warn("Error clearing pending room key requests", e);
3153
- });
3154
- }
3155
-
3156
- /**
3157
- * Re-send any outgoing key requests, eg after verification
3158
- * @returns
3159
- */
3160
- cancelAndResendAllOutgoingKeyRequests() {
3161
- var _this44 = this;
3162
- return _asyncToGenerator(function* () {
3163
- yield _this44.outgoingRoomKeyRequestManager.cancelAndResendAllOutgoingRequests();
3164
- })();
3165
- }
3166
-
3167
- /**
3168
- * handle an m.room.encryption event
3169
- *
3170
- * @param room - in which the event was received
3171
- * @param event - encryption event to be processed
3172
- */
3173
- onCryptoEvent(room, event) {
3174
- var _this45 = this;
3175
- return _asyncToGenerator(function* () {
3176
- var content = event.getContent();
3177
- yield _this45.setRoomEncryptionImpl(room, content);
3178
- })();
3179
- }
3180
-
3181
- /**
3182
- * Called before the result of a sync is processed
3183
- *
3184
- * @param syncData - the data from the 'MatrixClient.sync' event
3185
- */
3186
- onSyncWillProcess(syncData) {
3187
- var _this46 = this;
3188
- return _asyncToGenerator(function* () {
3189
- if (!syncData.oldSyncToken) {
3190
- // If there is no old sync token, we start all our tracking from
3191
- // scratch, so mark everything as untracked. onCryptoEvent will
3192
- // be called for all e2e rooms during the processing of the sync,
3193
- // at which point we'll start tracking all the users of that room.
3194
- logger.log("Initial sync performed - resetting device tracking state");
3195
- _this46.deviceList.stopTrackingAllDeviceLists();
3196
- // we always track our own device list (for key backups etc)
3197
- _this46.deviceList.startTrackingDeviceList(_this46.userId);
3198
- _this46.roomDeviceTrackingState = {};
3199
- }
3200
- _this46.sendKeyRequestsImmediately = false;
3201
- })();
3202
- }
3203
-
3204
- /**
3205
- * handle the completion of a /sync
3206
- *
3207
- * This is called after the processing of each successful /sync response.
3208
- * It is an opportunity to do a batch process on the information received.
3209
- *
3210
- * @param syncData - the data from the 'MatrixClient.sync' event
3211
- */
3212
- onSyncCompleted(syncData) {
3213
- var _this47 = this;
3214
- return _asyncToGenerator(function* () {
3215
- var _syncData$nextSyncTok;
3216
- _this47.deviceList.setSyncToken((_syncData$nextSyncTok = syncData.nextSyncToken) !== null && _syncData$nextSyncTok !== void 0 ? _syncData$nextSyncTok : null);
3217
- _this47.deviceList.saveIfDirty();
3218
-
3219
- // we always track our own device list (for key backups etc)
3220
- _this47.deviceList.startTrackingDeviceList(_this47.userId);
3221
- _this47.deviceList.refreshOutdatedDeviceLists();
3222
-
3223
- // we don't start uploading one-time keys until we've caught up with
3224
- // to-device messages, to help us avoid throwing away one-time-keys that we
3225
- // are about to receive messages for
3226
- // (https://github.com/vector-im/element-web/issues/2782).
3227
- if (!syncData.catchingUp) {
3228
- _this47.maybeUploadOneTimeKeys();
3229
- _this47.processReceivedRoomKeyRequests();
3230
-
3231
- // likewise don't start requesting keys until we've caught up
3232
- // on to_device messages, otherwise we'll request keys that we're
3233
- // just about to get.
3234
- _this47.outgoingRoomKeyRequestManager.sendQueuedRequests();
3235
-
3236
- // Sync has finished so send key requests straight away.
3237
- _this47.sendKeyRequestsImmediately = true;
3238
- }
3239
- })();
3240
- }
3241
-
3242
- /**
3243
- * Trigger the appropriate invalidations and removes for a given
3244
- * device list
3245
- *
3246
- * @param deviceLists - device_lists field from /sync, or response from
3247
- * /keys/changes
3248
- */
3249
- evalDeviceListChanges(deviceLists) {
3250
- var _this48 = this;
3251
- return _asyncToGenerator(function* () {
3252
- if (Array.isArray(deviceLists === null || deviceLists === void 0 ? void 0 : deviceLists.changed)) {
3253
- deviceLists.changed.forEach(u => {
3254
- _this48.deviceList.invalidateUserDeviceList(u);
3255
- });
3256
- }
3257
- if (Array.isArray(deviceLists === null || deviceLists === void 0 ? void 0 : deviceLists.left) && deviceLists.left.length) {
3258
- // Check we really don't share any rooms with these users
3259
- // any more: the server isn't required to give us the
3260
- // exact correct set.
3261
- var e2eUserIds = new Set(yield _this48.getTrackedE2eUsers());
3262
- deviceLists.left.forEach(u => {
3263
- if (!e2eUserIds.has(u)) {
3264
- _this48.deviceList.stopTrackingDeviceList(u);
3265
- }
3266
- });
3267
- }
3268
- })();
3269
- }
3270
-
3271
- /**
3272
- * Get a list of all the IDs of users we share an e2e room with
3273
- * for which we are tracking devices already
3274
- *
3275
- * @returns List of user IDs
3276
- */
3277
- getTrackedE2eUsers() {
3278
- var _this49 = this;
3279
- return _asyncToGenerator(function* () {
3280
- var e2eUserIds = [];
3281
- for (var room of _this49.getTrackedE2eRooms()) {
3282
- var members = yield room.getEncryptionTargetMembers();
3283
- for (var member of members) {
3284
- e2eUserIds.push(member.userId);
3285
- }
3286
- }
3287
- return e2eUserIds;
3288
- })();
3289
- }
3290
-
3291
- /**
3292
- * Get a list of the e2e-enabled rooms we are members of,
3293
- * and for which we are already tracking the devices
3294
- *
3295
- * @returns
3296
- */
3297
- getTrackedE2eRooms() {
3298
- return this.clientStore.getRooms().filter(room => {
3299
- // check for rooms with encryption enabled
3300
- var alg = this.roomEncryptors.get(room.roomId);
3301
- if (!alg) {
3302
- return false;
3303
- }
3304
- if (!this.roomDeviceTrackingState[room.roomId]) {
3305
- return false;
3306
- }
3307
-
3308
- // ignore any rooms which we have left
3309
- var myMembership = room.getMyMembership();
3310
- return myMembership === KnownMembership.Join || myMembership === KnownMembership.Invite;
3311
- });
3312
- }
3313
-
3314
- /**
3315
- * Encrypts and sends a given object via Olm to-device messages to a given
3316
- * set of devices.
3317
- * @param userDeviceInfoArr - the devices to send to
3318
- * @param payload - fields to include in the encrypted payload
3319
- * @returns Promise which
3320
- * resolves once the message has been encrypted and sent to the given
3321
- * userDeviceMap, and returns the `{ contentMap, deviceInfoByDeviceId }`
3322
- * of the successfully sent messages.
3323
- *
3324
- * @deprecated Instead use {@link encryptToDeviceMessages} followed by {@link MatrixClient.queueToDevice}.
3325
- */
3326
- encryptAndSendToDevices(userDeviceInfoArr, payload) {
3327
- var _this50 = this;
3328
- return _asyncToGenerator(function* () {
3329
- try {
3330
- var toDeviceBatch = yield _this50.prepareToDeviceBatch(userDeviceInfoArr, payload);
3331
- try {
3332
- yield _this50.baseApis.queueToDevice(toDeviceBatch);
3333
- } catch (e) {
3334
- logger.error("sendToDevice failed", e);
3335
- throw e;
3336
- }
3337
- } catch (e) {
3338
- logger.error("encryptAndSendToDevices promises failed", e);
3339
- throw e;
3340
- }
3341
- })();
3342
- }
3343
- prepareToDeviceBatch(userDeviceInfoArr, payload) {
3344
- var _this51 = this;
3345
- return _asyncToGenerator(function* () {
3346
- var toDeviceBatch = {
3347
- eventType: EventType.RoomMessageEncrypted,
3348
- batch: []
3349
- };
3350
- yield Promise.all(userDeviceInfoArr.map(/*#__PURE__*/function () {
3351
- var _ref19 = _asyncToGenerator(function* (_ref18) {
3352
- var {
3353
- userId,
3354
- deviceInfo
3355
- } = _ref18;
3356
- var deviceId = deviceInfo.deviceId;
3357
- var encryptedContent = {
3358
- algorithm: olmlib.OLM_ALGORITHM,
3359
- sender_key: _this51.olmDevice.deviceCurve25519Key,
3360
- ciphertext: {},
3361
- [ToDeviceMessageId]: uuidv4()
3362
- };
3363
- toDeviceBatch.batch.push({
3364
- userId,
3365
- deviceId,
3366
- payload: encryptedContent
3367
- });
3368
- yield olmlib.ensureOlmSessionsForDevices(_this51.olmDevice, _this51.baseApis, new Map([[userId, [deviceInfo]]]));
3369
- yield olmlib.encryptMessageForDevice(encryptedContent.ciphertext, _this51.userId, _this51.deviceId, _this51.olmDevice, userId, deviceInfo, payload);
3370
- });
3371
- return function (_x10) {
3372
- return _ref19.apply(this, arguments);
3373
- };
3374
- }()));
3375
-
3376
- // prune out any devices that encryptMessageForDevice could not encrypt for,
3377
- // in which case it will have just not added anything to the ciphertext object.
3378
- // There's no point sending messages to devices if we couldn't encrypt to them,
3379
- // since that's effectively a blank message.
3380
- toDeviceBatch.batch = toDeviceBatch.batch.filter(msg => {
3381
- if (Object.keys(msg.payload.ciphertext).length > 0) {
3382
- return true;
3383
- } else {
3384
- logger.log("No ciphertext for device ".concat(msg.userId, ":").concat(msg.deviceId, ": pruning"));
3385
- return false;
3386
- }
3387
- });
3388
- return toDeviceBatch;
3389
- })();
3390
- }
3391
-
3392
- /**
3393
- * Implementation of {@link Crypto.CryptoApi#encryptToDeviceMessages}.
3394
- */
3395
- encryptToDeviceMessages(eventType, devices, payload) {
3396
- var _this52 = this;
3397
- return _asyncToGenerator(function* () {
3398
- var userIds = new Set(devices.map(_ref20 => {
3399
- var {
3400
- userId
3401
- } = _ref20;
3402
- return userId;
3403
- }));
3404
- var deviceInfoMap = yield _this52.downloadKeys(Array.from(userIds), false);
3405
- var userDeviceInfoArr = [];
3406
- devices.forEach(_ref21 => {
3407
- var {
3408
- userId,
3409
- deviceId
3410
- } = _ref21;
3411
- var devices = deviceInfoMap.get(userId);
3412
- if (!devices) {
3413
- logger.warn("No devices found for user ".concat(userId));
3414
- return;
3415
- }
3416
- if (devices.has(deviceId)) {
3417
- // Send the message to a specific device
3418
- userDeviceInfoArr.push({
3419
- userId,
3420
- deviceInfo: devices.get(deviceId)
3421
- });
3422
- } else {
3423
- logger.warn("No device found for user ".concat(userId, " with id ").concat(deviceId));
3424
- }
3425
- });
3426
- return _this52.prepareToDeviceBatch(userDeviceInfoArr, payload);
3427
- })();
3428
- }
3429
- preprocessToDeviceMessages(events) {
3430
- return _asyncToGenerator(function* () {
3431
- // all we do here is filter out encrypted to-device messages with the wrong algorithm. Decryption
3432
- // happens later in decryptEvent, via the EventMapper
3433
- return events.filter(toDevice => {
3434
- var _toDevice$content;
3435
- if (toDevice.type === EventType.RoomMessageEncrypted && !["m.olm.v1.curve25519-aes-sha2"].includes((_toDevice$content = toDevice.content) === null || _toDevice$content === void 0 ? void 0 : _toDevice$content.algorithm)) {
3436
- logger.log("Ignoring invalid encrypted to-device event from " + toDevice.sender);
3437
- return false;
3438
- }
3439
- return true;
3440
- });
3441
- })();
3442
- }
3443
-
3444
- /**
3445
- * Stores the current one_time_key count which will be handled later (in a call of
3446
- * onSyncCompleted).
3447
- *
3448
- * @param currentCount - The current count of one_time_keys to be stored
3449
- */
3450
- updateOneTimeKeyCount(currentCount) {
3451
- if (isFinite(currentCount)) {
3452
- this.oneTimeKeyCount = currentCount;
3453
- } else {
3454
- throw new TypeError("Parameter for updateOneTimeKeyCount has to be a number");
3455
- }
3456
- }
3457
- processKeyCounts(oneTimeKeysCounts, unusedFallbackKeys) {
3458
- if (oneTimeKeysCounts !== undefined) {
3459
- this.updateOneTimeKeyCount(oneTimeKeysCounts["signed_curve25519"] || 0);
3460
- }
3461
- if (unusedFallbackKeys !== undefined) {
3462
- // If `unusedFallbackKeys` is defined, that means `device_unused_fallback_key_types`
3463
- // is present in the sync response, which indicates that the server supports fallback keys.
3464
- //
3465
- // If there's no unused signed_curve25519 fallback key, we need a new one.
3466
- this.needsNewFallback = !unusedFallbackKeys.includes("signed_curve25519");
3467
- }
3468
- return Promise.resolve();
3469
- }
3470
- /**
3471
- * Handle a key event
3472
- *
3473
- * @internal
3474
- * @param event - key event
3475
- */
3476
- onRoomKeyEvent(event) {
3477
- var content = event.getContent();
3478
- if (!content.room_id || !content.algorithm) {
3479
- logger.error("key event is missing fields");
3480
- return;
3481
- }
3482
- if (!this.backupManager.checkedForBackup) {
3483
- // don't bother awaiting on this - the important thing is that we retry if we
3484
- // haven't managed to check before
3485
- this.backupManager.checkAndStart();
3486
- }
3487
- var alg = this.getRoomDecryptor(content.room_id, content.algorithm);
3488
- alg.onRoomKeyEvent(event);
3489
- }
3490
-
3491
- /**
3492
- * Handle a key withheld event
3493
- *
3494
- * @internal
3495
- * @param event - key withheld event
3496
- */
3497
- onRoomKeyWithheldEvent(event) {
3498
- var content = event.getContent();
3499
- if (content.code !== "m.no_olm" && (!content.room_id || !content.session_id) || !content.algorithm || !content.sender_key) {
3500
- logger.error("key withheld event is missing fields");
3501
- return;
3502
- }
3503
- logger.info("Got room key withheld event from ".concat(event.getSender(), " ") + "for ".concat(content.algorithm, " session ").concat(content.sender_key, "|").concat(content.session_id, " ") + "in room ".concat(content.room_id, " with code ").concat(content.code, " (").concat(content.reason, ")"));
3504
- var alg = this.getRoomDecryptor(content.room_id, content.algorithm);
3505
- if (alg.onRoomKeyWithheldEvent) {
3506
- alg.onRoomKeyWithheldEvent(event);
3507
- }
3508
- if (!content.room_id) {
3509
- // retry decryption for all events sent by the sender_key. This will
3510
- // update the events to show a message indicating that the olm session was
3511
- // wedged.
3512
- var roomDecryptors = this.getRoomDecryptors(content.algorithm);
3513
- for (var decryptor of roomDecryptors) {
3514
- decryptor.retryDecryptionFromSender(content.sender_key);
3515
- }
3516
- }
3517
- }
3518
-
3519
- /**
3520
- * Handle a general key verification event.
3521
- *
3522
- * @internal
3523
- * @param event - verification start event
3524
- */
3525
- onKeyVerificationMessage(event) {
3526
- if (!ToDeviceChannel.validateEvent(event, this.baseApis)) {
3527
- return;
3528
- }
3529
- var createRequest = event => {
3530
- if (!ToDeviceChannel.canCreateRequest(ToDeviceChannel.getEventType(event))) {
3531
- return;
3532
- }
3533
- var content = event.getContent();
3534
- var deviceId = content && content.from_device;
3535
- if (!deviceId) {
3536
- return;
3537
- }
3538
- var userId = event.getSender();
3539
- var channel = new ToDeviceChannel(this.baseApis, userId, [deviceId]);
3540
- return new VerificationRequest(channel, this.verificationMethods, this.baseApis);
3541
- };
3542
- this.handleVerificationEvent(event, this.toDeviceVerificationRequests, createRequest);
3543
- }
3544
- handleVerificationEvent(event, requestsMap, createRequest) {
3545
- var _arguments9 = arguments,
3546
- _this53 = this;
3547
- return _asyncToGenerator(function* () {
3548
- var isLiveEvent = _arguments9.length > 3 && _arguments9[3] !== undefined ? _arguments9[3] : true;
3549
- // Wait for event to get its final ID with pendingEventOrdering: "chronological", since DM channels depend on it.
3550
- if (event.isSending() && event.status != EventStatus.SENT) {
3551
- var eventIdListener;
3552
- var statusListener;
3553
- try {
3554
- yield new Promise((resolve, reject) => {
3555
- eventIdListener = resolve;
3556
- statusListener = () => {
3557
- if (event.status == EventStatus.CANCELLED) {
3558
- reject(new Error("Event status set to CANCELLED."));
3559
- }
3560
- };
3561
- event.once(MatrixEventEvent.LocalEventIdReplaced, eventIdListener);
3562
- event.on(MatrixEventEvent.Status, statusListener);
3563
- });
3564
- } catch (err) {
3565
- logger.error("error while waiting for the verification event to be sent: ", err);
3566
- return;
3567
- } finally {
3568
- event.removeListener(MatrixEventEvent.LocalEventIdReplaced, eventIdListener);
3569
- event.removeListener(MatrixEventEvent.Status, statusListener);
3570
- }
3571
- }
3572
- var request = requestsMap.getRequest(event);
3573
- var isNewRequest = false;
3574
- if (!request) {
3575
- request = createRequest(event);
3576
- // a request could not be made from this event, so ignore event
3577
- if (!request) {
3578
- logger.log("Crypto: could not find VerificationRequest for " + "".concat(event.getType(), ", and could not create one, so ignoring."));
3579
- return;
3580
- }
3581
- isNewRequest = true;
3582
- requestsMap.setRequest(event, request);
3583
- }
3584
- event.setVerificationRequest(request);
3585
- try {
3586
- yield request.channel.handleEvent(event, request, isLiveEvent);
3587
- } catch (err) {
3588
- logger.error("error while handling verification event", err);
3589
- }
3590
- var shouldEmit = isNewRequest && !request.initiatedByMe && !request.invalid &&
3591
- // check it has enough events to pass the UNSENT stage
3592
- !request.observeOnly;
3593
- if (shouldEmit) {
3594
- _this53.baseApis.emit(CryptoEvent.VerificationRequest, request);
3595
- _this53.baseApis.emit(CryptoEvent.VerificationRequestReceived, request);
3596
- }
3597
- })();
3598
- }
3599
-
3600
- /**
3601
- * Handle a toDevice event that couldn't be decrypted
3602
- *
3603
- * @internal
3604
- * @param event - undecryptable event
3605
- */
3606
- onToDeviceBadEncrypted(event) {
3607
- var _this54 = this;
3608
- return _asyncToGenerator(function* () {
3609
- var content = event.getWireContent();
3610
- var sender = event.getSender();
3611
- var algorithm = content.algorithm;
3612
- var deviceKey = content.sender_key;
3613
- _this54.baseApis.emit(ClientEvent.UndecryptableToDeviceEvent, event);
3614
-
3615
- // retry decryption for all events sent by the sender_key. This will
3616
- // update the events to show a message indicating that the olm session was
3617
- // wedged.
3618
- var retryDecryption = () => {
3619
- var roomDecryptors = _this54.getRoomDecryptors(olmlib.MEGOLM_ALGORITHM);
3620
- for (var decryptor of roomDecryptors) {
3621
- decryptor.retryDecryptionFromSender(deviceKey);
3622
- }
3623
- };
3624
- if (sender === undefined || deviceKey === undefined || deviceKey === undefined) {
3625
- return;
3626
- }
3627
-
3628
- // check when we can force a new session with this device: if we've already done so
3629
- // recently, don't do it again.
3630
- var forceNewSessionRetryTimeDevices = _this54.forceNewSessionRetryTime.getOrCreate(sender);
3631
- var forceNewSessionRetryTime = forceNewSessionRetryTimeDevices.getOrCreate(deviceKey);
3632
- if (forceNewSessionRetryTime > Date.now()) {
3633
- logger.debug("New session already forced with device ".concat(sender, ":").concat(deviceKey, ": ") + "not forcing another until at least ".concat(new Date(forceNewSessionRetryTime).toUTCString()));
3634
- yield _this54.olmDevice.recordSessionProblem(deviceKey, "wedged", true);
3635
- retryDecryption();
3636
- return;
3637
- }
3638
-
3639
- // make sure we don't retry to unwedge too soon even if we fail to create a new session
3640
- forceNewSessionRetryTimeDevices.set(deviceKey, Date.now() + FORCE_SESSION_RETRY_INTERVAL_MS);
3641
-
3642
- // establish a new olm session with this device since we're failing to decrypt messages
3643
- // on a current session.
3644
- // Note that an undecryptable message from another device could easily be spoofed -
3645
- // is there anything we can do to mitigate this?
3646
- var device = _this54.deviceList.getDeviceByIdentityKey(algorithm, deviceKey);
3647
- if (!device) {
3648
- // if we don't know about the device, fetch the user's devices again
3649
- // and retry before giving up
3650
- yield _this54.downloadKeys([sender], false);
3651
- device = _this54.deviceList.getDeviceByIdentityKey(algorithm, deviceKey);
3652
- if (!device) {
3653
- logger.info("Couldn't find device for identity key " + deviceKey + ": not re-establishing session");
3654
- yield _this54.olmDevice.recordSessionProblem(deviceKey, "wedged", false);
3655
- retryDecryption();
3656
- return;
3657
- }
3658
- }
3659
- var devicesByUser = new Map([[sender, [device]]]);
3660
- yield olmlib.ensureOlmSessionsForDevices(_this54.olmDevice, _this54.baseApis, devicesByUser, true);
3661
- forceNewSessionRetryTimeDevices.set(deviceKey, Date.now() + MIN_FORCE_SESSION_INTERVAL_MS);
3662
-
3663
- // Now send a blank message on that session so the other side knows about it.
3664
- // (The keyshare request is sent in the clear so that won't do)
3665
- // We send this first such that, as long as the toDevice messages arrive in the
3666
- // same order we sent them, the other end will get this first, set up the new session,
3667
- // then get the keyshare request and send the key over this new session (because it
3668
- // is the session it has most recently received a message on).
3669
- var encryptedContent = {
3670
- algorithm: olmlib.OLM_ALGORITHM,
3671
- sender_key: _this54.olmDevice.deviceCurve25519Key,
3672
- ciphertext: {},
3673
- [ToDeviceMessageId]: uuidv4()
3674
- };
3675
- yield olmlib.encryptMessageForDevice(encryptedContent.ciphertext, _this54.userId, _this54.deviceId, _this54.olmDevice, sender, device, {
3676
- type: "m.dummy"
3677
- });
3678
- yield _this54.olmDevice.recordSessionProblem(deviceKey, "wedged", true);
3679
- retryDecryption();
3680
- yield _this54.baseApis.sendToDevice("m.room.encrypted", new Map([[sender, new Map([[device.deviceId, encryptedContent]])]]));
3681
-
3682
- // Most of the time this probably won't be necessary since we'll have queued up a key request when
3683
- // we failed to decrypt the message and will be waiting a bit for the key to arrive before sending
3684
- // it. This won't always be the case though so we need to re-send any that have already been sent
3685
- // to avoid races.
3686
- var requestsToResend = yield _this54.outgoingRoomKeyRequestManager.getOutgoingSentRoomKeyRequest(sender, device.deviceId);
3687
- for (var keyReq of requestsToResend) {
3688
- _this54.requestRoomKey(keyReq.requestBody, keyReq.recipients, true);
3689
- }
3690
- })();
3691
- }
3692
-
3693
- /**
3694
- * Handle a change in the membership state of a member of a room
3695
- *
3696
- * @internal
3697
- * @param event - event causing the change
3698
- * @param member - user whose membership changed
3699
- * @param oldMembership - previous membership
3700
- */
3701
- onRoomMembership(event, member, oldMembership) {
3702
- // this event handler is registered on the *client* (as opposed to the room
3703
- // member itself), which means it is only called on changes to the *live*
3704
- // membership state (ie, it is not called when we back-paginate, nor when
3705
- // we load the state in the initialsync).
3706
- //
3707
- // Further, it is automatically registered and called when new members
3708
- // arrive in the room.
3709
-
3710
- var roomId = member.roomId;
3711
- var alg = this.roomEncryptors.get(roomId);
3712
- if (!alg) {
3713
- // not encrypting in this room
3714
- return;
3715
- }
3716
- // only mark users in this room as tracked if we already started tracking in this room
3717
- // this way we don't start device queries after sync on behalf of this room which we won't use
3718
- // the result of anyway, as we'll need to do a query again once all the members are fetched
3719
- // by calling _trackRoomDevices
3720
- if (roomId in this.roomDeviceTrackingState) {
3721
- var _this$clientStore$get;
3722
- if (member.membership == KnownMembership.Join) {
3723
- logger.log("Join event for " + member.userId + " in " + roomId);
3724
- // make sure we are tracking the deviceList for this user
3725
- this.deviceList.startTrackingDeviceList(member.userId);
3726
- } else if (member.membership == KnownMembership.Invite && (_this$clientStore$get = this.clientStore.getRoom(roomId)) !== null && _this$clientStore$get !== void 0 && _this$clientStore$get.shouldEncryptForInvitedMembers()) {
3727
- logger.log("Invite event for " + member.userId + " in " + roomId);
3728
- this.deviceList.startTrackingDeviceList(member.userId);
3729
- }
3730
- }
3731
- alg.onRoomMembership(event, member, oldMembership);
3732
- }
3733
-
3734
- /**
3735
- * Called when we get an m.room_key_request event.
3736
- *
3737
- * @internal
3738
- * @param event - key request event
3739
- */
3740
- onRoomKeyRequestEvent(event) {
3741
- var content = event.getContent();
3742
- if (content.action === "request") {
3743
- // Queue it up for now, because they tend to arrive before the room state
3744
- // events at initial sync, and we want to see if we know anything about the
3745
- // room before passing them on to the app.
3746
- var req = new IncomingRoomKeyRequest(event);
3747
- this.receivedRoomKeyRequests.push(req);
3748
- } else if (content.action === "request_cancellation") {
3749
- var _req = new IncomingRoomKeyRequestCancellation(event);
3750
- this.receivedRoomKeyRequestCancellations.push(_req);
3751
- }
3752
- }
3753
-
3754
- /**
3755
- * Process any m.room_key_request events which were queued up during the
3756
- * current sync.
3757
- *
3758
- * @internal
3759
- */
3760
- processReceivedRoomKeyRequests() {
3761
- var _this55 = this;
3762
- return _asyncToGenerator(function* () {
3763
- if (_this55.processingRoomKeyRequests) {
3764
- // we're still processing last time's requests; keep queuing new ones
3765
- // up for now.
3766
- return;
3767
- }
3768
- _this55.processingRoomKeyRequests = true;
3769
- try {
3770
- // we need to grab and clear the queues in the synchronous bit of this method,
3771
- // so that we don't end up racing with the next /sync.
3772
- var requests = _this55.receivedRoomKeyRequests;
3773
- _this55.receivedRoomKeyRequests = [];
3774
- var cancellations = _this55.receivedRoomKeyRequestCancellations;
3775
- _this55.receivedRoomKeyRequestCancellations = [];
3776
-
3777
- // Process all of the requests, *then* all of the cancellations.
3778
- //
3779
- // This makes sure that if we get a request and its cancellation in the
3780
- // same /sync result, then we process the request before the
3781
- // cancellation (and end up with a cancelled request), rather than the
3782
- // cancellation before the request (and end up with an outstanding
3783
- // request which should have been cancelled.)
3784
- yield Promise.all(requests.map(req => _this55.processReceivedRoomKeyRequest(req)));
3785
- yield Promise.all(cancellations.map(cancellation => _this55.processReceivedRoomKeyRequestCancellation(cancellation)));
3786
- } catch (e) {
3787
- logger.error("Error processing room key requsts: ".concat(e));
3788
- } finally {
3789
- _this55.processingRoomKeyRequests = false;
3790
- }
3791
- })();
3792
- }
3793
-
3794
- /**
3795
- * Helper for processReceivedRoomKeyRequests
3796
- *
3797
- */
3798
- processReceivedRoomKeyRequest(req) {
3799
- var _this56 = this;
3800
- return _asyncToGenerator(function* () {
3801
- var userId = req.userId;
3802
- var deviceId = req.deviceId;
3803
- var body = req.requestBody;
3804
- var roomId = body.room_id;
3805
- var alg = body.algorithm;
3806
- logger.log("m.room_key_request from ".concat(userId, ":").concat(deviceId) + " for ".concat(roomId, " / ").concat(body.session_id, " (id ").concat(req.requestId, ")"));
3807
- if (userId !== _this56.userId) {
3808
- if (!_this56.roomEncryptors.get(roomId)) {
3809
- logger.debug("room key request for unencrypted room ".concat(roomId));
3810
- return;
3811
- }
3812
- var encryptor = _this56.roomEncryptors.get(roomId);
3813
- var device = _this56.deviceList.getStoredDevice(userId, deviceId);
3814
- if (!device) {
3815
- logger.debug("Ignoring keyshare for unknown device ".concat(userId, ":").concat(deviceId));
3816
- return;
3817
- }
3818
- try {
3819
- yield encryptor.reshareKeyWithDevice(body.sender_key, body.session_id, userId, device);
3820
- } catch (e) {
3821
- logger.warn("Failed to re-share keys for session " + body.session_id + " with device " + userId + ":" + device.deviceId, e);
3822
- }
3823
- return;
3824
- }
3825
- if (deviceId === _this56.deviceId) {
3826
- // We'll always get these because we send room key requests to
3827
- // '*' (ie. 'all devices') which includes the sending device,
3828
- // so ignore requests from ourself because apart from it being
3829
- // very silly, it won't work because an Olm session cannot send
3830
- // messages to itself.
3831
- // The log here is probably superfluous since we know this will
3832
- // always happen, but let's log anyway for now just in case it
3833
- // causes issues.
3834
- logger.log("Ignoring room key request from ourselves");
3835
- return;
3836
- }
3837
-
3838
- // todo: should we queue up requests we don't yet have keys for,
3839
- // in case they turn up later?
3840
-
3841
- // if we don't have a decryptor for this room/alg, we don't have
3842
- // the keys for the requested events, and can drop the requests.
3843
- if (!_this56.roomDecryptors.has(roomId)) {
3844
- logger.log("room key request for unencrypted room ".concat(roomId));
3845
- return;
3846
- }
3847
- var decryptor = _this56.roomDecryptors.get(roomId).get(alg);
3848
- if (!decryptor) {
3849
- logger.log("room key request for unknown alg ".concat(alg, " in room ").concat(roomId));
3850
- return;
3851
- }
3852
- if (!(yield decryptor.hasKeysForKeyRequest(req))) {
3853
- logger.log("room key request for unknown session ".concat(roomId, " / ") + body.session_id);
3854
- return;
3855
- }
3856
- req.share = () => {
3857
- decryptor.shareKeysWithDevice(req);
3858
- };
3859
-
3860
- // if the device is verified already, share the keys
3861
- if (_this56.checkDeviceTrust(userId, deviceId).isVerified()) {
3862
- logger.log("device is already verified: sharing keys");
3863
- req.share();
3864
- return;
3865
- }
3866
- _this56.emit(CryptoEvent.RoomKeyRequest, req);
3867
- })();
3868
- }
3869
-
3870
- /**
3871
- * Helper for processReceivedRoomKeyRequests
3872
- *
3873
- */
3874
- processReceivedRoomKeyRequestCancellation(cancellation) {
3875
- var _this57 = this;
3876
- return _asyncToGenerator(function* () {
3877
- logger.log("m.room_key_request cancellation for ".concat(cancellation.userId, ":") + "".concat(cancellation.deviceId, " (id ").concat(cancellation.requestId, ")"));
3878
-
3879
- // we should probably only notify the app of cancellations we told it
3880
- // about, but we don't currently have a record of that, so we just pass
3881
- // everything through.
3882
- _this57.emit(CryptoEvent.RoomKeyRequestCancellation, cancellation);
3883
- })();
3884
- }
3885
-
3886
- /**
3887
- * Get a decryptor for a given room and algorithm.
3888
- *
3889
- * If we already have a decryptor for the given room and algorithm, return
3890
- * it. Otherwise try to instantiate it.
3891
- *
3892
- * @internal
3893
- *
3894
- * @param roomId - room id for decryptor. If undefined, a temporary
3895
- * decryptor is instantiated.
3896
- *
3897
- * @param algorithm - crypto algorithm
3898
- *
3899
- * @throws `DecryptionError` if the algorithm is unknown
3900
- */
3901
- getRoomDecryptor(roomId, algorithm) {
3902
- var decryptors;
3903
- var alg;
3904
- if (roomId) {
3905
- decryptors = this.roomDecryptors.get(roomId);
3906
- if (!decryptors) {
3907
- decryptors = new Map();
3908
- this.roomDecryptors.set(roomId, decryptors);
3909
- }
3910
- alg = decryptors.get(algorithm);
3911
- if (alg) {
3912
- return alg;
3913
- }
3914
- }
3915
- var AlgClass = algorithms.DECRYPTION_CLASSES.get(algorithm);
3916
- if (!AlgClass) {
3917
- throw new DecryptionError(DecryptionFailureCode.UNKNOWN_ENCRYPTION_ALGORITHM, 'Unknown encryption algorithm "' + algorithm + '".');
3918
- }
3919
- alg = new AlgClass({
3920
- userId: this.userId,
3921
- crypto: this,
3922
- olmDevice: this.olmDevice,
3923
- baseApis: this.baseApis,
3924
- roomId: roomId !== null && roomId !== void 0 ? roomId : undefined
3925
- });
3926
- if (decryptors) {
3927
- decryptors.set(algorithm, alg);
3928
- }
3929
- return alg;
3930
- }
3931
-
3932
- /**
3933
- * Get all the room decryptors for a given encryption algorithm.
3934
- *
3935
- * @param algorithm - The encryption algorithm
3936
- *
3937
- * @returns An array of room decryptors
3938
- */
3939
- getRoomDecryptors(algorithm) {
3940
- var decryptors = [];
3941
- for (var d of this.roomDecryptors.values()) {
3942
- if (d.has(algorithm)) {
3943
- decryptors.push(d.get(algorithm));
3944
- }
3945
- }
3946
- return decryptors;
3947
- }
3948
-
3949
- /**
3950
- * sign the given object with our ed25519 key
3951
- *
3952
- * @param obj - Object to which we will add a 'signatures' property
3953
- */
3954
- signObject(obj) {
3955
- var _this58 = this;
3956
- return _asyncToGenerator(function* () {
3957
- var sigs = new Map(Object.entries(obj.signatures || {}));
3958
- var unsigned = obj.unsigned;
3959
- delete obj.signatures;
3960
- delete obj.unsigned;
3961
- var userSignatures = sigs.get(_this58.userId) || {};
3962
- sigs.set(_this58.userId, userSignatures);
3963
- userSignatures["ed25519:" + _this58.deviceId] = yield _this58.olmDevice.sign(anotherjson.stringify(obj));
3964
- obj.signatures = recursiveMapToObject(sigs);
3965
- if (unsigned !== undefined) obj.unsigned = unsigned;
3966
- })();
3967
- }
3968
-
3969
- /**
3970
- * @returns true if the room with the supplied ID is encrypted. False if the
3971
- * room is not encrypted, or is unknown to us.
3972
- */
3973
- isRoomEncrypted(roomId) {
3974
- return this.roomList.isRoomEncrypted(roomId);
3975
- }
3976
-
3977
- /**
3978
- * Implementation of {@link Crypto.CryptoApi#isEncryptionEnabledInRoom}.
3979
- */
3980
- isEncryptionEnabledInRoom(roomId) {
3981
- var _this59 = this;
3982
- return _asyncToGenerator(function* () {
3983
- return _this59.isRoomEncrypted(roomId);
3984
- })();
3985
- }
3986
-
3987
- /**
3988
- * @returns information about the encryption on the room with the supplied
3989
- * ID, or null if the room is not encrypted or unknown to us.
3990
- */
3991
- getRoomEncryption(roomId) {
3992
- return this.roomList.getRoomEncryption(roomId);
3993
- }
3994
-
3995
- /**
3996
- * Returns whether dehydrated devices are supported by the crypto backend
3997
- * and by the server.
3998
- */
3999
- isDehydrationSupported() {
4000
- return _asyncToGenerator(function* () {
4001
- return false;
4002
- })();
4003
- }
4004
-
4005
- /**
4006
- * Stub function -- dehydration is not implemented here, so throw error
4007
- */
4008
- startDehydration(createNewKey) {
4009
- return _asyncToGenerator(function* () {
4010
- throw new Error("Not implemented");
4011
- })();
4012
- }
4013
-
4014
- /**
4015
- * Stub function -- restoreKeyBackup is not implemented here, so throw error
4016
- */
4017
- restoreKeyBackup(opts) {
4018
- throw new Error("Not implemented");
4019
- }
4020
-
4021
- /**
4022
- * Stub function -- restoreKeyBackupWithPassphrase is not implemented here, so throw error
4023
- */
4024
- restoreKeyBackupWithPassphrase(passphrase, opts) {
4025
- throw new Error("Not implemented");
4026
- }
4027
- }
4028
-
4029
- /**
4030
- * Fix up the backup key, that may be in the wrong format due to a bug in a
4031
- * migration step. Some backup keys were stored as a comma-separated list of
4032
- * integers, rather than a base64-encoded byte array. If this function is
4033
- * passed a string that looks like a list of integers rather than a base64
4034
- * string, it will attempt to convert it to the right format.
4035
- *
4036
- * @param key - the key to check
4037
- * @returns If the key is in the wrong format, then the fixed
4038
- * key will be returned. Otherwise null will be returned.
4039
- *
4040
- */
4041
- export function fixBackupKey(key) {
4042
- if (typeof key !== "string" || key.indexOf(",") < 0) {
4043
- return null;
4044
- }
4045
- var fixedKey = Uint8Array.from(key.split(","), x => parseInt(x));
4046
- return encodeBase64(fixedKey);
4047
- }
4048
-
4049
- /**
4050
- * Represents a received m.room_key_request event
4051
- */
4052
- export class IncomingRoomKeyRequest {
4053
- constructor(event) {
4054
- /** user requesting the key */
4055
- _defineProperty(this, "userId", void 0);
4056
- /** device requesting the key */
4057
- _defineProperty(this, "deviceId", void 0);
4058
- /** unique id for the request */
4059
- _defineProperty(this, "requestId", void 0);
4060
- _defineProperty(this, "requestBody", void 0);
4061
- /**
4062
- * callback which, when called, will ask
4063
- * the relevant crypto algorithm implementation to share the keys for
4064
- * this request.
4065
- */
4066
- _defineProperty(this, "share", void 0);
4067
- var content = event.getContent();
4068
- this.userId = event.getSender();
4069
- this.deviceId = content.requesting_device_id;
4070
- this.requestId = content.request_id;
4071
- this.requestBody = content.body || {};
4072
- this.share = () => {
4073
- throw new Error("don't know how to share keys for this request yet");
4074
- };
4075
- }
4076
- }
4077
-
4078
- /**
4079
- * Represents a received m.room_key_request cancellation
4080
- */
4081
- class IncomingRoomKeyRequestCancellation {
4082
- constructor(event) {
4083
- /** user requesting the cancellation */
4084
- _defineProperty(this, "userId", void 0);
4085
- /** device requesting the cancellation */
4086
- _defineProperty(this, "deviceId", void 0);
4087
- /** unique id for the request to be cancelled */
4088
- _defineProperty(this, "requestId", void 0);
4089
- var content = event.getContent();
4090
- this.userId = event.getSender();
4091
- this.deviceId = content.requesting_device_id;
4092
- this.requestId = content.request_id;
4093
- }
4094
- }
4095
-
4096
- // a number of types are re-exported for backwards compatibility, in case any applications are referencing it.
4097
- //# sourceMappingURL=index.js.map