From 406fc58720dba9aa33e9b0fb23d49ffeb745ee39 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 21 Sep 2022 17:37:23 +0200 Subject: [PATCH] feat(crypto-js): Implement `OlmMachine.import_room_keys`. --- bindings/matrix-sdk-crypto-js/src/machine.rs | 43 +++++++++++++++++++- bindings/matrix-sdk-crypto-js/src/olm.rs | 1 + 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/bindings/matrix-sdk-crypto-js/src/machine.rs b/bindings/matrix-sdk-crypto-js/src/machine.rs index 225e3d9bc..7ed6c1091 100644 --- a/bindings/matrix-sdk-crypto-js/src/machine.rs +++ b/bindings/matrix-sdk-crypto-js/src/machine.rs @@ -4,7 +4,7 @@ use std::collections::BTreeMap; use js_sys::{Array, Function, Map, Promise, Set}; use ruma::{serde::Raw, DeviceKeyAlgorithm, OwnedTransactionId, UInt}; -use serde_json::Value as JsonValue; +use serde_json::{json, Value as JsonValue}; use wasm_bindgen::prelude::*; use crate::{ @@ -627,6 +627,12 @@ impl OlmMachine { })) } + /// Export the keys that match the given predicate. + /// + /// `predicate` is a closure that will be called for every known + /// `InboundGroupSession`, which represents a room key. If the closure + /// returns `true`, the `InboundGroupSession` will be included in the + /// export, otherwise it won't. #[wasm_bindgen(js_name = "exportRoomKeys")] pub fn export_room_keys(&self, predicate: Function) -> Promise { let me = self.inner.clone(); @@ -646,4 +652,39 @@ impl OlmMachine { )?) }) } + + /// Import the given room keys into our store. + /// + /// `exported_keys` is a list of previously exported keys that should be + /// imported into our store. If we already have a better version of a key, + /// the key will _not_ be imported. + #[wasm_bindgen(js_name = "importRoomKeys")] + pub fn import_room_keys( + &self, + exported_room_keys: &str, + progress_listener: Function, + ) -> Result { + let me = self.inner.clone(); + let exported_room_keys: Vec = + serde_json::from_str(exported_room_keys)?; + + Ok(future_to_promise(async move { + let matrix_sdk_crypto::RoomKeyImportResult { imported_count, total_count, keys } = me + .import_room_keys(exported_room_keys, false, |progress, total| { + let progress: u64 = progress.try_into().unwrap(); + let total: u64 = total.try_into().unwrap(); + + progress_listener + .call2(&JsValue::NULL, &JsValue::from(progress), &JsValue::from(total)) + .expect("Progress listener passed to `import_room_keys` failed"); + }) + .await?; + + Ok(serde_json::to_string(&json!({ + "imported_count": imported_count, + "total_count": total_count, + "keys": keys, + }))?) + })) + } } diff --git a/bindings/matrix-sdk-crypto-js/src/olm.rs b/bindings/matrix-sdk-crypto-js/src/olm.rs index 39fbbf57a..3d5084570 100644 --- a/bindings/matrix-sdk-crypto-js/src/olm.rs +++ b/bindings/matrix-sdk-crypto-js/src/olm.rs @@ -42,6 +42,7 @@ impl CrossSigningStatus { /// Inbound group sessions are used to exchange room messages between a group of /// participants. Inbound group sessions are used to decrypt the room messages. #[wasm_bindgen] +#[derive(Debug)] pub struct InboundGroupSession { inner: matrix_sdk_crypto::olm::InboundGroupSession, }