diff --git a/CHANGELOG.md b/CHANGELOG.md index 68e31de..022d7eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,22 @@ **BREAKING CHANGES** -- Rename `OlmMachine.init_from_store` introduced in v3.6.0 to `OlmMachine.initFromStore`. +- Rename `OlmMachine.init_from_store` introduced in v3.6.0 to + `OlmMachine.initFromStore`. + ([#84](https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/84)) + +- Functions/methods that take a JavaScript `Array` as argument now invalidate the + items within that array so that they cannot be re-used as soon as + they are received by the functions/methods. See the patch for affected methods. + ([#82](https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/82/)) + +**Other changes** + +- Update `wasm-bindgen` to 0.2.89. It allows to remove the `downcast` method. + It fixes [#51](https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/51), + thus the resulting JavaScript code of `matrix-rust-sdk-crypto-wasm` can + be minified with no issue now. + ([#82](https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/82/)) # matrix-sdk-crypto-wasm v3.6.0 diff --git a/Cargo.lock b/Cargo.lock index e756f6a..a04519d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2020,9 +2020,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2030,9 +2030,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", @@ -2057,9 +2057,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2067,9 +2067,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", @@ -2080,9 +2080,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "web-sys" diff --git a/Cargo.toml b/Cargo.toml index 3c07f94..106931f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,8 +66,7 @@ serde_json = "1.0.91" serde-wasm-bindgen = "0.5.0" tracing = { version = "0.1.36", default-features = false, features = ["std"] } tracing-subscriber = { version = "0.3.14", default-features = false, features = ["registry", "std", "ansi"] } -# 0.2.88 causes breakage, per https://github.com/rustwasm/wasm-bindgen/issues/3685 -wasm-bindgen = "=0.2.87" +wasm-bindgen = "0.2.89" wasm-bindgen-futures = "0.4.33" zeroize = "1.6.0" diff --git a/src/device.rs b/src/device.rs index 35d9989..b1fb0a3 100644 --- a/src/device.rs +++ b/src/device.rs @@ -7,9 +7,7 @@ use crate::{ encryption::EncryptionAlgorithm, future::future_to_promise, identifiers::{self, DeviceId, UserId}, - impl_from_to_inner, - js::try_array_to_vec, - requests, types, verification, vodozemac, + impl_from_to_inner, requests, types, verification, vodozemac, }; /// A device represents a E2EE capable client of an user. @@ -25,13 +23,17 @@ impl_from_to_inner!(matrix_sdk_crypto::Device => Device); impl Device { /// Request an interactive verification with this device. /// + /// Items inside `methods` will be invalidated by this method. + /// /// Returns a Promise for a 2-element array `[VerificationRequest, /// ToDeviceRequest]`. #[wasm_bindgen(js_name = "requestVerification")] - pub fn request_verification(&self, methods: Option) -> Result { - let methods = - methods.map(try_array_to_vec::).transpose()?; + pub fn request_verification( + &self, + methods: Option>, + ) -> Result { let me = self.inner.clone(); + let methods = methods.map(|methods| methods.iter().map(Into::into).collect()); Ok(future_to_promise(async move { let tuple = Array::new(); diff --git a/src/encryption.rs b/src/encryption.rs index d496e3f..72cc1e4 100644 --- a/src/encryption.rs +++ b/src/encryption.rs @@ -86,17 +86,6 @@ pub enum EncryptionAlgorithm { MegolmV1AesSha2, } -impl From for JsValue { - fn from(value: EncryptionAlgorithm) -> Self { - use EncryptionAlgorithm::*; - - match value { - OlmV1Curve25519AesSha2 => JsValue::from(0), - MegolmV1AesSha2 => JsValue::from(1), - } - } -} - impl From for matrix_sdk_crypto::types::EventEncryptionAlgorithm { fn from(value: EncryptionAlgorithm) -> Self { use EncryptionAlgorithm::*; diff --git a/src/identifiers.rs b/src/identifiers.rs index 96f36ac..e090a73 100644 --- a/src/identifiers.rs +++ b/src/identifiers.rs @@ -53,6 +53,15 @@ impl UserId { pub fn to_string(&self) -> String { self.inner.as_str().to_owned() } + + /// Create a clone of this `UserId`. + /// + /// This can be useful when passing a `UserId` instance to methods such as + /// {@link OlmMachine.updateTrackedUsers} which destroy the instance. + #[wasm_bindgen(js_name = "clone")] + pub fn clone_me(&self) -> Self { + self.clone() + } } /// A Matrix key ID. diff --git a/src/identities.rs b/src/identities.rs index d2db7d7..ab67cfc 100644 --- a/src/identities.rs +++ b/src/identities.rs @@ -3,10 +3,7 @@ use js_sys::{Array, Promise}; use wasm_bindgen::prelude::*; -use crate::{ - future::future_to_promise, identifiers, impl_from_to_inner, js::try_array_to_vec, requests, - verification, -}; +use crate::{future::future_to_promise, identifiers, impl_from_to_inner, requests, verification}; pub(crate) struct UserIdentities { inner: matrix_sdk_crypto::UserIdentities, @@ -59,10 +56,14 @@ impl OwnUserIdentity { } /// Send a verification request to our other devices. + /// + /// Items inside `methods` will be invalidated by this method. #[wasm_bindgen(js_name = "requestVerification")] - pub fn request_verification(&self, methods: Option) -> Result { - let methods = - methods.map(try_array_to_vec::).transpose()?; + pub fn request_verification( + &self, + methods: Option>, + ) -> Result { + let methods = methods.map(|methods| methods.iter().map(Into::into).collect()); let me = self.inner.clone(); Ok(future_to_promise(async move { @@ -159,18 +160,19 @@ impl UserIdentity { /// Create a `VerificationRequest` object after the verification /// request content has been sent out. + /// + /// Items inside `methods` will be invalidated by this method. #[wasm_bindgen(js_name = "requestVerification")] pub fn request_verification( &self, room_id: &identifiers::RoomId, request_event_id: &identifiers::EventId, - methods: Option, + methods: Option>, ) -> Result { let me = self.inner.clone(); let room_id = room_id.inner.clone(); let request_event_id = request_event_id.inner.clone(); - let methods = - methods.map(try_array_to_vec::).transpose()?; + let methods = methods.map(|methods| methods.iter().map(Into::into).collect()); Ok(future_to_promise::<_, verification::VerificationRequest>(async move { Ok(me @@ -187,11 +189,15 @@ impl UserIdentity { /// /// After the content has been sent out a VerificationRequest can be started /// with the `request_verification` method. + /// + /// Items inside `methods` will be invalidated by this method. #[wasm_bindgen(js_name = "verificationRequestContent")] - pub fn verification_request_content(&self, methods: Option) -> Result { + pub fn verification_request_content( + &self, + methods: Option>, + ) -> Result { let me = self.inner.clone(); - let methods = - methods.map(try_array_to_vec::).transpose()?; + let methods = methods.map(|methods| methods.iter().map(Into::into).collect()); Ok(future_to_promise(async move { Ok(serde_json::to_string(&me.verification_request_content(methods).await)?) diff --git a/src/js.rs b/src/js.rs deleted file mode 100644 index 743708d..0000000 --- a/src/js.rs +++ /dev/null @@ -1,40 +0,0 @@ -use js_sys::{Array, Object, Reflect}; -use wasm_bindgen::{convert::RefFromWasmAbi, prelude::*}; - -/// A really hacky and dirty code to downcast a `JsValue` to `T: -/// RefFromWasmAbi`, inspired by -/// https://github.com/rustwasm/wasm-bindgen/issues/2231#issuecomment-656293288. -/// -/// The returned value is likely to be a `wasm_bindgen::__ref::Ref`. -pub(crate) fn downcast(value: &JsValue, classname: &str) -> Result -where - T: RefFromWasmAbi, -{ - let constructor_name = Object::get_prototype_of(value).constructor().name(); - - if constructor_name == classname { - let pointer = Reflect::get(value, &JsValue::from_str("__wbg_ptr")) - .map_err(|_| JsError::new("Failed to read the `JsValue` pointer"))?; - let pointer = pointer - .as_f64() - .ok_or_else(|| JsError::new("Failed to read the `JsValue` pointer as a `f64`"))? - as u32; - - Ok(unsafe { T::ref_from_abi(pointer) }) - } else { - Err(JsError::new(&format!( - "Expect an `{classname}` instance, received `{constructor_name}` instead", - ))) - } -} - -/// Transform a value `JS` from JavaScript to a Rust wrapper, to a -/// Rust wrapped type. -pub(crate) fn try_array_to_vec( - array: Array, -) -> Result, >::Error> -where - JS: TryFrom + Into, -{ - array.iter().map(|item| JS::try_from(item).map(Into::into)).collect() -} diff --git a/src/lib.rs b/src/lib.rs index 649601b..b2ccaf5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,7 +27,6 @@ pub mod events; mod future; pub mod identifiers; pub mod identities; -mod js; pub mod libolm_migration; pub mod machine; mod macros; diff --git a/src/libolm_migration.rs b/src/libolm_migration.rs index 0749ba6..4e86d4e 100644 --- a/src/libolm_migration.rs +++ b/src/libolm_migration.rs @@ -17,7 +17,7 @@ use std::{iter, time::Duration}; use anyhow::Context; -use js_sys::{Array, Date, Uint8Array}; +use js_sys::{Date, Uint8Array}; use matrix_sdk_common::ruma::{ DeviceKeyAlgorithm, MilliSecondsSinceUnixEpoch, SecondsSinceUnixEpoch, UInt, }; @@ -33,7 +33,6 @@ use wasm_bindgen::prelude::*; use crate::{ identifiers::{DeviceId, RoomId, UserId}, - js::downcast, store::StoreHandle, }; @@ -223,14 +222,15 @@ impl Migration { /// /// # Arguments /// - /// * `sessions` - An `Array` of {@link PickledSession}s to import. + /// * `sessions` - An `Array` of {@link PickledSession}s to import. Items + /// inside `sessions` are going to be invalidated by this method. /// * `pickle_key` - The libolm pickle key that was used to pickle the olm /// session objects. /// * `store_handle` - A connection to the CryptoStore which will be used to /// store the vodozemac data. #[wasm_bindgen(js_name = "migrateOlmSessions")] pub async fn migrate_olm_sessions( - sessions: Array, + sessions: Vec, pickle_key: Uint8Array, store_handle: &StoreHandle, ) -> Result { @@ -238,7 +238,7 @@ impl Migration { let rust_sessions = sessions .into_iter() - .map(|s| libolm_pickled_session_to_rust_pickled_session(s, &pickle_key)) + .map(|session| libolm_pickled_session_to_rust_pickled_session(session, &pickle_key)) .collect::>()?; import_olm_sessions_to_store(rust_sessions, store_handle.store.as_ref()) @@ -261,10 +261,9 @@ impl Default for PickledSession { } fn libolm_pickled_session_to_rust_pickled_session( - libolm_session: JsValue, + libolm_session: PickledSession, pickle_key: &[u8], ) -> Result { - let libolm_session = downcast::(&libolm_session, "PickledSession")?; let session = vodozemac::olm::Session::from_libolm_pickle(&libolm_session.pickle, &pickle_key)?; let creation_time = date_to_seconds_since_epoch(&libolm_session.creation_time) @@ -369,14 +368,15 @@ impl Migration { /// # Arguments /// /// * `sessions` - An `Array` of {@link PickledInboundGroupSession}s to - /// import. + /// import. Items inside `sessions` are going to be invalidated by this + /// method. /// * `pickle_key` - The libolm pickle key that was used to pickle the /// megolm session objects. /// * `store_handle` - A connection to the CryptoStore which will be used to /// store the vodozemac data. #[wasm_bindgen(js_name = "migrateMegolmSessions")] pub async fn migrate_megolm_sessions( - sessions: Array, + sessions: Vec, pickle_key: Uint8Array, store_handle: &StoreHandle, ) -> Result { @@ -384,7 +384,9 @@ impl Migration { let rust_sessions = sessions .into_iter() - .map(|s| libolm_pickled_megolm_session_to_rust_pickled_session(s, &pickle_key)) + .map(|session| { + libolm_pickled_megolm_session_to_rust_pickled_session(session, &pickle_key) + }) .collect::>()?; import_megolm_sessions_to_store(rust_sessions, store_handle.store.as_ref()) @@ -395,12 +397,9 @@ impl Migration { } fn libolm_pickled_megolm_session_to_rust_pickled_session( - libolm_session: JsValue, + libolm_session: PickledInboundGroupSession, pickle_key: &[u8], ) -> Result { - let libolm_session = - downcast::(&libolm_session, "PickledInboundGroupSession")?; - let pickle = vodozemac::megolm::InboundGroupSession::from_libolm_pickle( &libolm_session.pickle, pickle_key, diff --git a/src/machine.rs b/src/machine.rs index 2840185..b298ff8 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -18,7 +18,7 @@ use matrix_sdk_crypto::{ use serde_json::json; use serde_wasm_bindgen; use tracing::warn; -use wasm_bindgen::prelude::*; +use wasm_bindgen::{convert::TryFromJsValue, prelude::*}; use wasm_bindgen_futures::{spawn_local, JsFuture}; use crate::{ @@ -26,9 +26,7 @@ use crate::{ device, encryption, error::MegolmDecryptionError, future::{future_to_promise, future_to_promise_with_custom_error}, - identifiers, identities, - js::downcast, - olm, requests, + identifiers, identities, olm, requests, requests::{outgoing_request_to_js_value, CrossSigningBootstrapRequests, ToDeviceRequest}, responses::{self, response_from_string}, store, @@ -228,16 +226,19 @@ impl OlmMachine { /// "changed" notification for that user in the future. /// /// Users that were already in the list are unaffected. + /// + /// Items inside `users` will be invalidated by this method. Be careful not + /// to use the `UserId`s after this method has been called. #[wasm_bindgen(js_name = "updateTrackedUsers")] - pub fn update_tracked_users(&self, users: &Array) -> Result { - let users = user_ids_to_owned_user_ids(users)?; + pub fn update_tracked_users(&self, users: Vec) -> Promise { + let users = users.iter().map(|user| user.inner.clone()).collect::>(); let me = self.inner.clone(); - Ok(future_to_promise(async move { + future_to_promise(async move { me.update_tracked_users(users.iter().map(AsRef::as_ref)).await?; Ok(JsValue::UNDEFINED) - })) + }) } /// Handle to-device events and one-time key counts from a sync @@ -637,21 +638,24 @@ impl OlmMachine { /// time is in flight for the same room, e.g. using a lock. /// /// Returns an array of `ToDeviceRequest`s. + /// + /// Items inside `users` will be invalidated by this method. Be careful not + /// to use the `UserId`s after this method has been called. #[wasm_bindgen(js_name = "shareRoomKey")] pub fn share_room_key( &self, room_id: &identifiers::RoomId, - users: &Array, + users: Vec, encryption_settings: &encryption::EncryptionSettings, - ) -> Result { + ) -> Promise { let room_id = room_id.inner.clone(); - let users = user_ids_to_owned_user_ids(users)?; + let users = users.iter().map(|user| user.inner.clone()).collect::>(); let encryption_settings = matrix_sdk_crypto::olm::EncryptionSettings::from(encryption_settings); let me = self.inner.clone(); - Ok(future_to_promise(async move { + future_to_promise(async move { let to_device_requests = me .share_room_key(&room_id, users.iter().map(AsRef::as_ref), encryption_settings) .await?; @@ -665,7 +669,7 @@ impl OlmMachine { .into_iter() .map(|td| ToDeviceRequest::try_from(td.deref()).map(JsValue::from)) .collect::>()?) - })) + }) } /// Generate an "out-of-band" key query request for the given set of users. @@ -675,12 +679,15 @@ impl OlmMachine { /// /// Returns a `KeysQueryRequest` object. The response of the request should /// be passed to the `OlmMachine` with the `mark_request_as_sent`. + /// + /// Items inside `users` will be invalidated by this method. Be careful not + /// to use the `UserId`s after this method has been called. #[wasm_bindgen(js_name = "queryKeysForUsers")] pub fn query_keys_for_users( &self, - users: &Array, + users: Vec, ) -> Result { - let users = user_ids_to_owned_user_ids(users)?; + let users = users.iter().map(|user| user.inner.clone()).collect::>(); let (request_id, request) = self.inner.query_keys_for_users(users.iter().map(AsRef::as_ref)); @@ -713,13 +720,16 @@ impl OlmMachine { /// `users` represents the list of users that we should check if /// we lack a session with one of their devices. This can be an /// empty iterator when calling this method between sync requests. + /// + /// Items inside `users` will be invalidated by this method. Be careful not + /// to use the `UserId`s after this method has been called. #[wasm_bindgen(js_name = "getMissingSessions")] - pub fn get_missing_sessions(&self, users: &Array) -> Result { - let users = user_ids_to_owned_user_ids(users)?; + pub fn get_missing_sessions(&self, users: Vec) -> Promise { + let users = users.iter().map(|user| user.inner.clone()).collect::>(); let me = self.inner.clone(); - Ok(future_to_promise(async move { + future_to_promise(async move { match me.get_missing_sessions(users.iter().map(AsRef::as_ref)).await? { Some((transaction_id, keys_claim_request)) => { Ok(JsValue::from(requests::KeysClaimRequest::try_from(( @@ -730,7 +740,7 @@ impl OlmMachine { None => Ok(JsValue::NULL), } - })) + }) } /// Get a map holding all the devices of a user. @@ -953,25 +963,6 @@ impl OlmMachine { })) } - /// Shared helper for `import_exported_room_keys` and `import_room_keys`. - /// - /// Wraps the progress listener in a Rust closure and runs - /// `Store::import_exported_room_keys` - async fn import_exported_room_keys_helper( - inner: &matrix_sdk_crypto::OlmMachine, - exported_room_keys: Vec, - progress_listener: Function, - ) -> Result { - inner - .store() - .import_exported_room_keys(exported_room_keys, |progress, total| { - progress_listener - .call2(&JsValue::NULL, &JsValue::from(progress), &JsValue::from(total)) - .expect("Progress listener passed to `importExportedRoomKeys` failed"); - }) - .await - } - /// Import the given room keys into our store. /// /// # Arguments @@ -1004,8 +995,7 @@ impl OlmMachine { for backed_up_room_keys_entry in backed_up_room_keys.entries() { let backed_up_room_keys_entry: Array = backed_up_room_keys_entry?.dyn_into()?; let room_id = - &downcast::(&backed_up_room_keys_entry.get(0), "RoomId")? - .inner; + identifiers::RoomId::try_from_js_value(backed_up_room_keys_entry.get(0))?.inner; let room_room_keys: Map = backed_up_room_keys_entry.get(1).dyn_into()?; @@ -1398,6 +1388,31 @@ impl OlmMachine { pub fn close(self) {} } +impl OlmMachine { + /// Shared helper for `import_exported_room_keys` and `import_room_keys`. + /// + /// Wraps the progress listener in a Rust closure and runs + /// `Store::import_exported_room_keys` + /// + /// Items inside `exported_room_keys` will be invalidated by this method. Be + /// careful not to use the `ExportedRoomKey`s after this method has been + /// called. + async fn import_exported_room_keys_helper( + inner: &matrix_sdk_crypto::OlmMachine, + exported_room_keys: Vec, + progress_listener: Function, + ) -> Result { + inner + .store() + .import_exported_room_keys(exported_room_keys, |progress, total| { + progress_listener + .call2(&JsValue::NULL, &JsValue::from(progress), &JsValue::from(total)) + .expect("Progress listener passed to `importExportedRoomKeys` failed"); + }) + .await + } +} + // helper for register_room_key_received_callback: wraps the key info // into our own RoomKeyInfo struct, and passes it into the javascript // function @@ -1472,12 +1487,3 @@ pub(crate) async fn promise_result_to_future( } } } - -/// Helper function to take a Javascript array of `UserId`s and turn it into -/// a Rust `Vec` of `OwnedUserId`s -fn user_ids_to_owned_user_ids(users: &Array) -> Result, JsError> { - users - .iter() - .map(|user| Ok(downcast::(&user, "UserId")?.inner.clone())) - .collect() -} diff --git a/src/sync_events.rs b/src/sync_events.rs index a4d79b0..597ab39 100644 --- a/src/sync_events.rs +++ b/src/sync_events.rs @@ -1,10 +1,9 @@ //! `GET /_matrix/client/*/sync` -use js_sys::Array; use matrix_sdk_common::ruma; use wasm_bindgen::prelude::*; -use crate::{identifiers, js::downcast}; +use crate::identifiers; /// Information on E2E device updates. #[wasm_bindgen] @@ -18,21 +17,18 @@ impl DeviceLists { /// Create an empty `DeviceLists`. /// /// `changed` and `left` must be an array of `UserId`. + /// + /// Items inside `changed` and `left` will be invalidated by this method. Be + /// careful not to use the `UserId`s after this method has been called. #[wasm_bindgen(constructor)] - pub fn new(changed: Option, left: Option) -> Result { + pub fn new( + changed: Option>, + left: Option>, + ) -> Result { let mut inner = ruma::api::client::sync::sync_events::DeviceLists::default(); - inner.changed = changed - .unwrap_or_default() - .iter() - .map(|user| Ok(downcast::(&user, "UserId")?.inner.clone())) - .collect::, JsError>>()?; - - inner.left = left - .unwrap_or_default() - .iter() - .map(|user| Ok(downcast::(&user, "UserId")?.inner.clone())) - .collect::, JsError>>()?; + inner.changed = changed.unwrap_or_default().iter().map(|user| user.inner.clone()).collect(); + inner.left = left.unwrap_or_default().iter().map(|user| user.inner.clone()).collect(); Ok(Self { inner }) } @@ -47,24 +43,14 @@ impl DeviceLists { /// who now share an encrypted room with the client since the /// previous sync #[wasm_bindgen(getter)] - pub fn changed(&self) -> Array { - self.inner - .changed - .iter() - .map(|user| identifiers::UserId::from(user.clone())) - .map(JsValue::from) - .collect() + pub fn changed(&self) -> Vec { + self.inner.changed.iter().map(|user| identifiers::UserId::from(user.clone())).collect() } /// List of users who no longer share encrypted rooms since the /// previous sync response. #[wasm_bindgen(getter)] - pub fn left(&self) -> Array { - self.inner - .left - .iter() - .map(|user| identifiers::UserId::from(user.clone())) - .map(JsValue::from) - .collect() + pub fn left(&self) -> Vec { + self.inner.left.iter().map(|user| identifiers::UserId::from(user.clone())).collect() } } diff --git a/src/verification.rs b/src/verification.rs index f3575ba..44722e9 100644 --- a/src/verification.rs +++ b/src/verification.rs @@ -17,7 +17,6 @@ use crate::{ future::future_to_promise, identifiers::{DeviceId, RoomId, UserId}, impl_from_to_inner, - js::try_array_to_vec, machine::promise_result_to_future, requests, }; @@ -41,19 +40,6 @@ pub enum VerificationMethod { ReciprocateV1 = 3, } -impl From for JsValue { - fn from(value: VerificationMethod) -> Self { - use VerificationMethod::*; - - match value { - SasV1 => JsValue::from(0), - QrCodeScanV1 => JsValue::from(1), - QrCodeShowV1 => JsValue::from(2), - ReciprocateV1 => JsValue::from(3), - } - } -} - impl TryFrom for VerificationMethod { type Error = JsError; @@ -76,8 +62,8 @@ impl TryFrom for VerificationMethod { } } -impl From for RumaVerificationMethod { - fn from(value: VerificationMethod) -> Self { +impl From<&VerificationMethod> for RumaVerificationMethod { + fn from(value: &VerificationMethod) -> Self { use VerificationMethod::*; match value { @@ -331,15 +317,8 @@ impl Sas { /// /// Returns `undefined` if we can't yet present the short auth string, /// otherwise an array of seven `Emoji` objects. - pub fn emoji(&self) -> Option { - Some( - self.inner - .emoji()? - .iter() - .map(|emoji| Emoji::from(emoji.to_owned())) - .map(JsValue::from) - .collect(), - ) + pub fn emoji(&self) -> Option> { + Some(self.inner.emoji()?.iter().map(|emoji| Emoji::from(emoji.to_owned())).collect()) } /// Get the index of the emoji representing the short auth string @@ -350,8 +329,8 @@ impl Sas { /// relevant specification /// entry](https://spec.matrix.org/unstable/client-server-api/#sas-method-emoji). #[wasm_bindgen(js_name = "emojiIndex")] - pub fn emoji_index(&self) -> Option { - Some(self.inner.emoji_index()?.into_iter().map(JsValue::from).collect()) + pub fn emoji_index(&self) -> Option> { + Some(self.inner.emoji_index()?.into()) } /// Get the decimal version of the short auth string. @@ -359,15 +338,10 @@ impl Sas { /// Returns None if we can’t yet present the short auth string, /// otherwise a tuple containing three 4-digit integers that /// represent the short auth string. - pub fn decimals(&self) -> Option { + pub fn decimals(&self) -> Option> { let decimals = self.inner.decimals()?; - let out = Array::new_with_length(3); - out.set(0, JsValue::from(decimals.0)); - out.set(1, JsValue::from(decimals.1)); - out.set(2, JsValue::from(decimals.2)); - - Some(out) + Some(vec![decimals.0, decimals.1, decimals.2]) } /// Register a callback which will be called whenever there is an update to @@ -798,9 +772,9 @@ impl VerificationRequest { own_user_id: &UserId, own_device_id: &DeviceId, other_user_id: &UserId, - methods: Option, + methods: Option>, ) -> Result { - let methods = methods.map(try_array_to_vec::).transpose()?; + let methods = methods.map(|methods| methods.iter().map(Into::into).collect()); Ok(serde_json::to_string(&matrix_sdk_crypto::VerificationRequest::request( &own_user_id.inner, @@ -875,17 +849,12 @@ impl VerificationRequest { /// /// Will be present only if the other side requested the /// verification or if we’re in the ready state. - /// - /// It return a `Option>`. #[wasm_bindgen(getter, js_name = "theirSupportedMethods")] - pub fn their_supported_methods(&self) -> Result, JsError> { + pub fn their_supported_methods(&self) -> Result>, JsError> { self.inner .their_supported_methods() .map(|methods| { - methods - .into_iter() - .map(|method| VerificationMethod::try_from(method).map(JsValue::from)) - .collect::>() + methods.into_iter().map(|method| VerificationMethod::try_from(method)).collect() }) .transpose() } @@ -895,14 +864,11 @@ impl VerificationRequest { /// Will be present only we requested the verification or if we’re /// in the ready state. #[wasm_bindgen(getter, js_name = "ourSupportedMethods")] - pub fn our_supported_methods(&self) -> Result, JsError> { + pub fn our_supported_methods(&self) -> Result>, JsError> { self.inner .our_supported_methods() .map(|methods| { - methods - .into_iter() - .map(|method| VerificationMethod::try_from(method).map(JsValue::from)) - .collect::>() + methods.into_iter().map(|method| VerificationMethod::try_from(method)).collect() }) .transpose() } @@ -984,11 +950,16 @@ impl VerificationRequest { /// `methods` represents the methods that we should advertise as /// supported by us. /// + /// Items inside `methods` will be invalidated by this method. + /// /// It returns either a `ToDeviceRequest`, a `RoomMessageRequest` /// or `undefined`. #[wasm_bindgen(js_name = "acceptWithMethods")] - pub fn accept_with_methods(&self, methods: Array) -> Result { - let methods = try_array_to_vec::(methods)?; + pub fn accept_with_methods( + &self, + methods: Vec, + ) -> Result { + let methods = methods.iter().map(Into::into).collect(); self.inner .accept_with_methods(methods) diff --git a/tests/machine.test.ts b/tests/machine.test.ts index a7f1628..9cada0e 100644 --- a/tests/machine.test.ts +++ b/tests/machine.test.ts @@ -242,7 +242,7 @@ describe(OlmMachine.name, () => { test("can update tracked users", async () => { const m = await machine(); - expect(await m.updateTrackedUsers([user])).toStrictEqual(undefined); + expect(await m.updateTrackedUsers([user.clone()])).toStrictEqual(undefined); }); test("can receive sync changes", async () => { @@ -509,9 +509,9 @@ describe(OlmMachine.name, () => { }); test("can share a room key", async () => { - const otherUsers = [new UserId("@example:localhost")]; + const other_user_id = new UserId("@example:localhost"); - const requests = await m.shareRoomKey(room, otherUsers, new EncryptionSettings()); + const requests = await m.shareRoomKey(room, [other_user_id.clone()], new EncryptionSettings()); expect(requests).toHaveLength(1); expect(requests[0]).toBeInstanceOf(ToDeviceRequest); @@ -524,7 +524,12 @@ describe(OlmMachine.name, () => { expect(messageContent["org.matrix.msgid"]).toBeDefined(); await m.markRequestAsSent(requests[0].id, RequestType.ToDevice, "{}"); - const requestsAfterMarkedAsSent = await m.shareRoomKey(room, otherUsers, new EncryptionSettings()); + + const requestsAfterMarkedAsSent = await m.shareRoomKey( + room, + [other_user_id.clone()], + new EncryptionSettings(), + ); expect(requestsAfterMarkedAsSent).toHaveLength(0); });