From d4cd8710a4c05976c8c62c7078e38b3af1731889 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 27 Oct 2022 10:45:05 +0300 Subject: [PATCH 01/37] Refactor the SessionVerification flows and get them working through sliding sync --- bindings/matrix-sdk-ffi/src/client.rs | 104 ++++-------------- bindings/matrix-sdk-ffi/src/lib.rs | 2 - .../src/session_verification.rs | 98 +++++++++-------- 3 files changed, 70 insertions(+), 134 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index 28f2e961c..6c267808e 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -2,23 +2,20 @@ use std::sync::{Arc, RwLock}; use anyhow::{anyhow, Context}; use matrix_sdk::{ - config::SyncSettings, media::{MediaFormat, MediaRequest, MediaThumbnailSize}, ruma::{ api::client::{ account::whoami, - error::ErrorKind, - filter::{FilterDefinition, LazyLoadOptions, RoomEventFilter, RoomFilter}, media::get_content_thumbnail::v3::Method, session::get_login_types, - sync::sync_events::v3::Filter, }, - events::room::MediaSource, + events::{room::MediaSource, AnyToDeviceEvent}, serde::Raw, TransactionId, UInt, }, - Client as MatrixClient, Error, LoopCtrl, RumaApiError, Session, + Client as MatrixClient, Session, }; +use tracing::warn; use super::{ room::Room, session_verification::SessionVerificationController, ClientState, RestoreToken, @@ -49,11 +46,27 @@ pub struct Client { impl Client { pub fn new(client: MatrixClient, state: ClientState) -> Self { + let session_verification_controller: Arc< + matrix_sdk::locks::RwLock>, + > = Default::default(); + let ctrl = session_verification_controller.clone(); + + client.add_event_handler(move |ev: AnyToDeviceEvent| { + let ctrl = ctrl.clone(); + async move { + if let Some(session_verification_controller) = &*ctrl.clone().read().await { + session_verification_controller.process_to_device_message(ev).await; + } else { + warn!("received to-device message, but verification controller isn't ready"); + } + } + }); + Client { client, state: Arc::new(RwLock::new(state)), delegate: Arc::new(RwLock::new(None)), - session_verification_controller: Arc::new(matrix_sdk::locks::RwLock::new(None)), + session_verification_controller, } } @@ -234,7 +247,6 @@ impl Client { { return Ok(Arc::new(session_verification_controller.clone())); } - let user_id = self.client.user_id().context("Failed retrieving current user_id")?; let user_identity = self .client @@ -261,22 +273,6 @@ impl Client { } }) } - - /// Process a sync error and return loop control accordingly - fn process_sync_error(&self, sync_error: Error) -> LoopCtrl { - let mut control = LoopCtrl::Continue; - if let Some(RumaApiError::ClientApi(error)) = sync_error.as_ruma_api_error() { - if let ErrorKind::UnknownToken { soft_logout } = error.kind { - self.state.write().unwrap().is_soft_logout = soft_logout; - if let Some(delegate) = &*self.delegate.read().unwrap() { - delegate.did_update_restore_token(); - delegate.did_receive_auth_error(soft_logout); - } - control = LoopCtrl::Break - } - } - control - } } #[uniffi::export] @@ -310,66 +306,6 @@ impl Client { pub fn rooms(&self) -> Vec> { self.client.rooms().into_iter().map(|room| Arc::new(Room::new(room))).collect() } - - pub fn start_sync(&self, timeline_limit: Option) { - let client = self.client.clone(); - let state = self.state.clone(); - let delegate = self.delegate.clone(); - let session_verification_controller = self.session_verification_controller.clone(); - let local_self = self.clone(); - RUNTIME.spawn(async move { - let mut filter = FilterDefinition::default(); - let mut room_filter = RoomFilter::default(); - let mut event_filter = RoomEventFilter::default(); - let mut timeline_filter = RoomEventFilter::default(); - - event_filter.lazy_load_options = - LazyLoadOptions::Enabled { include_redundant_members: false }; - room_filter.state = event_filter; - filter.room = room_filter; - - timeline_filter.limit = timeline_limit.map(|limit| limit.into()); - filter.room.timeline = timeline_filter; - - let filter_id = client.get_or_upload_filter("sync", filter).await.unwrap(); - - let sync_settings = SyncSettings::new().filter(Filter::FilterId(&filter_id)); - - client - .sync_with_result_callback(sync_settings, |result| async { - Ok(if let Ok(sync_response) = result { - if !state.read().unwrap().has_first_synced { - state.write().unwrap().has_first_synced = true; - } - - if state.read().unwrap().should_stop_syncing { - state.write().unwrap().is_syncing = false; - return Ok(LoopCtrl::Break); - } else if !state.read().unwrap().is_syncing { - state.write().unwrap().is_syncing = true; - } - - if let Some(delegate) = &*delegate.read().unwrap() { - delegate.did_receive_sync_update() - } - - if let Some(session_verification_controller) = - &*session_verification_controller.read().await - { - session_verification_controller - .process_to_device_messages(sync_response.to_device_events) - .await; - } - - LoopCtrl::Continue - } else { - local_self.process_sync_error(result.err().unwrap()) - }) - }) - .await - .unwrap(); - }); - } } #[uniffi::export] diff --git a/bindings/matrix-sdk-ffi/src/lib.rs b/bindings/matrix-sdk-ffi/src/lib.rs index fbc927c2c..989ed33e7 100644 --- a/bindings/matrix-sdk-ffi/src/lib.rs +++ b/bindings/matrix-sdk-ffi/src/lib.rs @@ -58,8 +58,6 @@ pub use self::{ pub struct ClientState { is_guest: bool, has_first_synced: bool, - is_syncing: bool, - should_stop_syncing: bool, is_soft_logout: bool, } diff --git a/bindings/matrix-sdk-ffi/src/session_verification.rs b/bindings/matrix-sdk-ffi/src/session_verification.rs index 9db8f5c4c..155d70cc1 100644 --- a/bindings/matrix-sdk-ffi/src/session_verification.rs +++ b/bindings/matrix-sdk-ffi/src/session_verification.rs @@ -106,64 +106,66 @@ impl SessionVerificationController { }) } - pub async fn process_to_device_messages(&self, to_device_events: Vec>) { - let sas_verification = self.sas_verification.clone(); - - for event in to_device_events.into_iter().filter_map(|e| e.deserialize().ok()) { - match event { - AnyToDeviceEvent::KeyVerificationReady(event) => { - if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) { - return; - } - self.start_sas_verification().await; + pub async fn process_to_device_message(&self, event: AnyToDeviceEvent) { + match event { + AnyToDeviceEvent::KeyVerificationReady(event) => { + if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) { + return; } - AnyToDeviceEvent::KeyVerificationCancel(event) => { - if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) { - return; - } - - if let Some(delegate) = &*self.delegate.read().unwrap() { - delegate.did_cancel() - } + self.start_sas_verification().await; + } + AnyToDeviceEvent::KeyVerificationCancel(event) => { + if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) { + return; } - AnyToDeviceEvent::KeyVerificationKey(event) => { - if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) { - return; - } - if let Some(sas_verification) = &*sas_verification.read().unwrap() { - if let Some(emojis) = sas_verification.emoji() { - if let Some(delegate) = &*self.delegate.read().unwrap() { - let emojis = emojis - .iter() - .map(|e| { - Arc::new(SessionVerificationEmoji { - symbol: e.symbol.to_owned(), - description: e.description.to_owned(), - }) + if let Some(delegate) = &*self.delegate.read().unwrap() { + delegate.did_cancel() + } + } + AnyToDeviceEvent::KeyVerificationKey(event) => { + if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) { + return; + } + + if let Some(sas_verification) = &*self.sas_verification.read().unwrap() { + if let Some(emojis) = sas_verification.emoji() { + if let Some(delegate) = &*self.delegate.read().unwrap() { + let emojis = emojis + .iter() + .map(|e| { + Arc::new(SessionVerificationEmoji { + symbol: e.symbol.to_owned(), + description: e.description.to_owned(), }) - .collect::>(); + }) + .collect::>(); - delegate.did_receive_verification_data(emojis); - } - } else if let Some(delegate) = &*self.delegate.read().unwrap() { - delegate.did_fail() + delegate.did_receive_verification_data(emojis); } } else if let Some(delegate) = &*self.delegate.read().unwrap() { delegate.did_fail() } + } else if let Some(delegate) = &*self.delegate.read().unwrap() { + delegate.did_fail() } - AnyToDeviceEvent::KeyVerificationDone(event) => { - if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) { - return; - } - - if let Some(delegate) = &*self.delegate.read().unwrap() { - delegate.did_finish() - } - } - _ => (), } + AnyToDeviceEvent::KeyVerificationDone(event) => { + if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) { + return; + } + + if let Some(delegate) = &*self.delegate.read().unwrap() { + delegate.did_finish() + } + } + _ => (), + } + } + + pub async fn process_to_device_messages(&self, to_device_events: Vec>) { + for event in to_device_events.into_iter().filter_map(|e| e.deserialize().ok()) { + self.process_to_device_message(event).await; } } @@ -190,4 +192,4 @@ impl SessionVerificationController { } } } -} +} \ No newline at end of file From eddf202a765d7a0e0ee80d43b20f614e4cc1b1c2 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 27 Oct 2022 11:27:28 +0200 Subject: [PATCH 02/37] chore: Upgrade UniFFI --- .github/workflows/bindings_ci.yml | 2 +- Cargo.lock | 17 +++++++++-------- Cargo.toml | 8 ++++---- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.github/workflows/bindings_ci.yml b/.github/workflows/bindings_ci.yml index 5c877ffd2..4faccc924 100644 --- a/.github/workflows/bindings_ci.yml +++ b/.github/workflows/bindings_ci.yml @@ -157,7 +157,7 @@ jobs: with: command: install # keep in sync with uniffi dependency in root Cargo.toml - args: uniffi_bindgen --git https://github.com/mozilla/uniffi-rs --rev fdb769b567865d9c5c7c682a18d0c1301a039c85 + args: uniffi_bindgen --git https://github.com/mozilla/uniffi-rs --rev 89b9dd835b470abb339b1bd492c19f7a08ad872f - name: Build library & bindings run: cargo xtask swift build-library diff --git a/Cargo.lock b/Cargo.lock index 0096903f5..169848545 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -528,15 +528,16 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.14.2" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" +checksum = "406c859255d568f4f742b3146d51851f3bfd49f734a2c289d9107c4395ee0062" dependencies = [ "camino", "cargo-platform", "semver", "serde", "serde_json", + "thiserror", ] [[package]] @@ -4998,7 +4999,7 @@ checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" [[package]] name = "uniffi" version = "0.21.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=fdb769b567865d9c5c7c682a18d0c1301a039c85#fdb769b567865d9c5c7c682a18d0c1301a039c85" +source = "git+https://github.com/mozilla/uniffi-rs?rev=89b9dd835b470abb339b1bd492c19f7a08ad872f#89b9dd835b470abb339b1bd492c19f7a08ad872f" dependencies = [ "anyhow", "bytes", @@ -5014,7 +5015,7 @@ dependencies = [ [[package]] name = "uniffi_bindgen" version = "0.21.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=fdb769b567865d9c5c7c682a18d0c1301a039c85#fdb769b567865d9c5c7c682a18d0c1301a039c85" +source = "git+https://github.com/mozilla/uniffi-rs?rev=89b9dd835b470abb339b1bd492c19f7a08ad872f#89b9dd835b470abb339b1bd492c19f7a08ad872f" dependencies = [ "anyhow", "askama", @@ -5036,7 +5037,7 @@ dependencies = [ [[package]] name = "uniffi_build" version = "0.21.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=fdb769b567865d9c5c7c682a18d0c1301a039c85#fdb769b567865d9c5c7c682a18d0c1301a039c85" +source = "git+https://github.com/mozilla/uniffi-rs?rev=89b9dd835b470abb339b1bd492c19f7a08ad872f#89b9dd835b470abb339b1bd492c19f7a08ad872f" dependencies = [ "anyhow", "camino", @@ -5046,7 +5047,7 @@ dependencies = [ [[package]] name = "uniffi_macros" version = "0.21.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=fdb769b567865d9c5c7c682a18d0c1301a039c85#fdb769b567865d9c5c7c682a18d0c1301a039c85" +source = "git+https://github.com/mozilla/uniffi-rs?rev=89b9dd835b470abb339b1bd492c19f7a08ad872f#89b9dd835b470abb339b1bd492c19f7a08ad872f" dependencies = [ "bincode", "camino", @@ -5064,7 +5065,7 @@ dependencies = [ [[package]] name = "uniffi_meta" version = "0.21.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=fdb769b567865d9c5c7c682a18d0c1301a039c85#fdb769b567865d9c5c7c682a18d0c1301a039c85" +source = "git+https://github.com/mozilla/uniffi-rs?rev=89b9dd835b470abb339b1bd492c19f7a08ad872f#89b9dd835b470abb339b1bd492c19f7a08ad872f" dependencies = [ "serde", ] @@ -5373,7 +5374,7 @@ dependencies = [ [[package]] name = "weedle2" version = "4.0.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=fdb769b567865d9c5c7c682a18d0c1301a039c85#fdb769b567865d9c5c7c682a18d0c1301a039c85" +source = "git+https://github.com/mozilla/uniffi-rs?rev=89b9dd835b470abb339b1bd492c19f7a08ad872f#89b9dd835b470abb339b1bd492c19f7a08ad872f" dependencies = [ "nom", ] diff --git a/Cargo.toml b/Cargo.toml index a5f5618f7..225be9866 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,10 +18,10 @@ resolver = "2" [workspace.dependencies] ruma = { version = "0.7.4", features = ["client-api-c"] } tracing = { version = "0.1.36", default-features = false, features = ["std"] } -uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "fdb769b567865d9c5c7c682a18d0c1301a039c85" } -uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "fdb769b567865d9c5c7c682a18d0c1301a039c85" } -uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs", rev = "fdb769b567865d9c5c7c682a18d0c1301a039c85" } -uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "fdb769b567865d9c5c7c682a18d0c1301a039c85", features = ["builtin-bindgen"] } +uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "89b9dd835b470abb339b1bd492c19f7a08ad872f" } +uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "89b9dd835b470abb339b1bd492c19f7a08ad872f" } +uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs", rev = "89b9dd835b470abb339b1bd492c19f7a08ad872f" } +uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "89b9dd835b470abb339b1bd492c19f7a08ad872f", features = ["builtin-bindgen"] } vodozemac = "0.3.0" zeroize = "1.3.0" From 426f60a6a2550422d63b8596511f7a259f3f04da Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Tue, 25 Oct 2022 20:42:06 +0200 Subject: [PATCH 03/37] ci: Add bindings check to xtask --- xtask/src/ci.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/xtask/src/ci.rs b/xtask/src/ci.rs index d7911f1bc..c6119a55f 100644 --- a/xtask/src/ci.rs +++ b/xtask/src/ci.rs @@ -18,31 +18,43 @@ const WASM_TIMEOUT_VALUE: &str = "120"; enum CiCommand { /// Check style Style, + /// Check for typos Typos, + /// Check clippy lints Clippy, + /// Check documentation Docs, + /// Run tests with a specific feature set TestFeatures { #[clap(subcommand)] cmd: Option, }, + /// Run tests for the appservice crate TestAppservice, + /// Run checks for the wasm target Wasm { #[clap(subcommand)] cmd: Option, }, + /// Run wasm-pack tests WasmPack { #[clap(subcommand)] cmd: Option, }, + /// Run tests for the different crypto crate features TestCrypto, + + /// Check that bindings can be generated + Bindings, + /// Check that the examples compile Examples, } @@ -91,6 +103,7 @@ impl CiArgs { CiCommand::Wasm { cmd } => run_wasm_checks(cmd), CiCommand::WasmPack { cmd } => run_wasm_pack_tests(cmd), CiCommand::TestCrypto => run_crypto_tests(), + CiCommand::Bindings => check_bindings(), CiCommand::Examples => check_examples(), }, None => { @@ -110,6 +123,34 @@ impl CiArgs { } } +fn check_bindings() -> Result<()> { + cmd!("rustup run stable cargo build -p matrix-sdk-crypto-ffi -p matrix-sdk-ffi").run()?; + cmd!( + " + uniffi-bindgen generate + --language kotlin + --language swift + --lib-file target/debug/libmatrix_sdk_ffi.a + --out-dir target/generated-bindings + bindings/matrix-sdk-ffi/src/api.udl + " + ) + .run()?; + cmd!( + " + uniffi-bindgen generate + --language kotlin + --language swift + --lib-file target/debug/libmatrix_sdk_crypto_ffi.a + --out-dir target/generated-bindings + bindings/matrix-sdk-crypto-ffi/src/olm.udl + " + ) + .run()?; + + Ok(()) +} + fn check_examples() -> Result<()> { cmd!("rustup run stable cargo check -p example-*").run()?; Ok(()) From 41be4c520976afb45695b52ec8536f3334bab868 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 27 Oct 2022 09:58:02 +0200 Subject: [PATCH 04/37] ci: Test bindings generation --- .github/workflows/bindings_ci.yml | 33 +++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bindings_ci.yml b/.github/workflows/bindings_ci.yml index 4faccc924..2dc0e8c09 100644 --- a/.github/workflows/bindings_ci.yml +++ b/.github/workflows/bindings_ci.yml @@ -16,8 +16,38 @@ env: CARGO_TERM_COLOR: always MATRIX_SDK_CRYPTO_NODEJS_PATH: bindings/matrix-sdk-crypto-nodejs MATRIX_SDK_CRYPTO_JS_PATH: bindings/matrix-sdk-crypto-js + # keep in sync with uniffi dependency in root Cargo.toml + UNIFFI_REV: 89b9dd835b470abb339b1bd492c19f7a08ad872f jobs: + test-uniffi-codegen: + name: Test UniFFI bindings generation + if: github.event_name == 'push' || !github.event.pull_request.draft + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v1 + + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + profile: minimal + override: true + + - name: Load cache + uses: Swatinem/rust-cache@v1 + + - name: Install Uniffi + uses: actions-rs/cargo@v1 + with: + command: install + args: uniffi_bindgen --git https://github.com/mozilla/uniffi-rs --rev ${{ env.UNIFFI_REV }} + + - name: Build library & generate bindings + run: cargo xtask ci bindings + test-matrix-sdk-crypto-nodejs: name: ${{ matrix.os-name }} [m]-crypto-nodejs, v${{ matrix.node-version }} if: github.event_name == 'push' || !github.event.pull_request.draft @@ -156,8 +186,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: install - # keep in sync with uniffi dependency in root Cargo.toml - args: uniffi_bindgen --git https://github.com/mozilla/uniffi-rs --rev 89b9dd835b470abb339b1bd492c19f7a08ad872f + args: uniffi_bindgen --git https://github.com/mozilla/uniffi-rs --rev ${{ env.UNIFFI_REV }} - name: Build library & bindings run: cargo xtask swift build-library From c9c4473cd458a82e2d922e1843f7385e6742ba60 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 27 Oct 2022 10:01:35 +0200 Subject: [PATCH 05/37] ci: Cache xtask for bindings checks --- .github/workflows/bindings_ci.yml | 74 ++++++++++++++++++++++++++++++- xtask/Cargo.toml | 2 +- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/.github/workflows/bindings_ci.yml b/.github/workflows/bindings_ci.yml index 2dc0e8c09..235e62d77 100644 --- a/.github/workflows/bindings_ci.yml +++ b/.github/workflows/bindings_ci.yml @@ -20,8 +20,37 @@ env: UNIFFI_REV: 89b9dd835b470abb339b1bd492c19f7a08ad872f jobs: + xtask-linux: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v2 + + - name: Check xtask cache + uses: actions/cache@v3 + id: xtask-cache + with: + path: target/debug/xtask + key: xtask-linux-${{ hashFiles('Cargo.toml', 'xtask/**') }} + + - name: Install rust stable toolchain + if: steps.xtask-cache.outputs.cache-hit != 'true' + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: Build + if: steps.xtask-cache.outputs.cache-hit != 'true' + uses: actions-rs/cargo@v1 + with: + command: build + args: -p xtask + test-uniffi-codegen: name: Test UniFFI bindings generation + needs: xtask-linux if: github.event_name == 'push' || !github.event.pull_request.draft runs-on: ubuntu-latest @@ -39,6 +68,12 @@ jobs: - name: Load cache uses: Swatinem/rust-cache@v1 + - name: Get xtask + uses: actions/cache@v3 + with: + path: target/debug/xtask + key: xtask-linux-${{ hashFiles('Cargo.toml', 'xtask/**') }} + - name: Install Uniffi uses: actions-rs/cargo@v1 with: @@ -46,7 +81,7 @@ jobs: args: uniffi_bindgen --git https://github.com/mozilla/uniffi-rs --rev ${{ env.UNIFFI_REV }} - name: Build library & generate bindings - run: cargo xtask ci bindings + run: target/debug/xtask ci bindings test-matrix-sdk-crypto-nodejs: name: ${{ matrix.os-name }} [m]-crypto-nodejs, v${{ matrix.node-version }} @@ -163,8 +198,37 @@ jobs: working-directory: ${{ env.MATRIX_SDK_CRYPTO_JS_PATH }} run: npm run doc + xtask-macos: + runs-on: macos-12 + steps: + - name: Checkout repo + uses: actions/checkout@v2 + + - name: Check xtask cache + uses: actions/cache@v3 + id: xtask-cache + with: + path: target/debug/xtask + key: xtask-macos-${{ hashFiles('Cargo.toml', 'xtask/**') }} + + - name: Install rust stable toolchain + if: steps.xtask-cache.outputs.cache-hit != 'true' + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: Build + if: steps.xtask-cache.outputs.cache-hit != 'true' + uses: actions-rs/cargo@v1 + with: + command: build + args: -p xtask + test-apple: name: matrix-rust-components-swift + needs: xtask-macos runs-on: macos-12 if: github.event_name == 'push' || !github.event.pull_request.draft @@ -182,6 +246,12 @@ jobs: - name: Load cache uses: Swatinem/rust-cache@v1 + - name: Get xtask + uses: actions/cache@v3 + with: + path: target/debug/xtask + key: xtask-macos-${{ hashFiles('Cargo.toml', 'xtask/**') }} + - name: Install Uniffi uses: actions-rs/cargo@v1 with: @@ -189,7 +259,7 @@ jobs: args: uniffi_bindgen --git https://github.com/mozilla/uniffi-rs --rev ${{ env.UNIFFI_REV }} - name: Build library & bindings - run: cargo xtask swift build-library + run: target/debug/xtask swift build-library - name: Run XCTests working-directory: bindings/apple diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 013ba4161..2ebac234c 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -13,5 +13,5 @@ camino = "1.0.8" clap = { version = "3.2.4", features = ["derive"] } serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.79" -uniffi_bindgen = { workspace = true } +uniffi_bindgen = { workspace = true } xshell = "0.1.17" From e1ecc9de0da1b2fb80a6af0eaacf0b615c328934 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 27 Oct 2022 11:38:44 +0200 Subject: [PATCH 06/37] chore: Bump versions of matrix-sdk, matrix-sdk-base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … to bring them up to the released ones from the v0.6.x branch. All changes from those versions are already present on main. --- Cargo.lock | 4 ++-- crates/matrix-sdk-base/Cargo.toml | 2 +- crates/matrix-sdk/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 169848545..2587e13ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2441,7 +2441,7 @@ checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" [[package]] name = "matrix-sdk" -version = "0.6.0" +version = "0.6.2" dependencies = [ "anyhow", "anymap2", @@ -2520,7 +2520,7 @@ dependencies = [ [[package]] name = "matrix-sdk-base" -version = "0.6.0" +version = "0.6.1" dependencies = [ "assign", "async-stream", diff --git a/crates/matrix-sdk-base/Cargo.toml b/crates/matrix-sdk-base/Cargo.toml index d7bc4acef..2b9df17a2 100644 --- a/crates/matrix-sdk-base/Cargo.toml +++ b/crates/matrix-sdk-base/Cargo.toml @@ -9,7 +9,7 @@ name = "matrix-sdk-base" readme = "README.md" repository = "https://github.com/matrix-org/matrix-rust-sdk" rust-version = "1.62" -version = "0.6.0" +version = "0.6.1" [package.metadata.docs.rs] all-features = true diff --git a/crates/matrix-sdk/Cargo.toml b/crates/matrix-sdk/Cargo.toml index 5ec0ee230..0c4d62f5c 100644 --- a/crates/matrix-sdk/Cargo.toml +++ b/crates/matrix-sdk/Cargo.toml @@ -9,7 +9,7 @@ name = "matrix-sdk" readme = "README.md" repository = "https://github.com/matrix-org/matrix-rust-sdk" rust-version = "1.62" -version = "0.6.0" +version = "0.6.2" [package.metadata.docs.rs] features = ["docsrs"] From 324411201eb3b68667f792fee515054496bb3aa4 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 27 Oct 2022 11:53:34 +0200 Subject: [PATCH 07/37] fix(sdk): Enable required ruma features for experimental-timeline --- crates/matrix-sdk/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/matrix-sdk/Cargo.toml b/crates/matrix-sdk/Cargo.toml index 0c4d62f5c..2cd83f39e 100644 --- a/crates/matrix-sdk/Cargo.toml +++ b/crates/matrix-sdk/Cargo.toml @@ -43,7 +43,7 @@ image-proc = ["dep:image"] image-rayon = ["image-proc", "image?/jpeg_rayon"] experimental-room-preview = [] -experimental-timeline = [] +experimental-timeline = ["ruma/unstable-msc2676", "ruma/unstable-msc2677"] sliding-sync = [ "matrix-sdk-base/sliding-sync", From afc33e616c2f7b754c1b1dc4deb162e4350b5c66 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Thu, 27 Oct 2022 12:06:06 +0100 Subject: [PATCH 08/37] revert start_sync removal --- bindings/matrix-sdk-ffi/src/client.rs | 87 ++++++++++++++++++- bindings/matrix-sdk-ffi/src/lib.rs | 2 + .../src/session_verification.rs | 2 +- 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index 6c267808e..56f16b097 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -2,20 +2,23 @@ use std::sync::{Arc, RwLock}; use anyhow::{anyhow, Context}; use matrix_sdk::{ + config::SyncSettings, media::{MediaFormat, MediaRequest, MediaThumbnailSize}, ruma::{ api::client::{ account::whoami, + error::ErrorKind, + filter::{FilterDefinition, LazyLoadOptions, RoomEventFilter, RoomFilter}, media::get_content_thumbnail::v3::Method, session::get_login_types, + sync::sync_events::v3::Filter, }, events::{room::MediaSource, AnyToDeviceEvent}, serde::Raw, TransactionId, UInt, }, - Client as MatrixClient, Session, + Client as MatrixClient, Error, LoopCtrl, RumaApiError, Session, }; -use tracing::warn; use super::{ room::Room, session_verification::SessionVerificationController, ClientState, RestoreToken, @@ -57,7 +60,9 @@ impl Client { if let Some(session_verification_controller) = &*ctrl.clone().read().await { session_verification_controller.process_to_device_message(ev).await; } else { - warn!("received to-device message, but verification controller isn't ready"); + tracing::warn!( + "received to-device message, but verification controller isn't ready" + ); } } }); @@ -273,6 +278,22 @@ impl Client { } }) } + + /// Process a sync error and return loop control accordingly + fn process_sync_error(&self, sync_error: Error) -> LoopCtrl { + let mut control = LoopCtrl::Continue; + if let Some(RumaApiError::ClientApi(error)) = sync_error.as_ruma_api_error() { + if let ErrorKind::UnknownToken { soft_logout } = error.kind { + self.state.write().unwrap().is_soft_logout = soft_logout; + if let Some(delegate) = &*self.delegate.read().unwrap() { + delegate.did_update_restore_token(); + delegate.did_receive_auth_error(soft_logout); + } + control = LoopCtrl::Break + } + } + control + } } #[uniffi::export] @@ -306,6 +327,66 @@ impl Client { pub fn rooms(&self) -> Vec> { self.client.rooms().into_iter().map(|room| Arc::new(Room::new(room))).collect() } + + pub fn start_sync(&self, timeline_limit: Option) { + let client = self.client.clone(); + let state = self.state.clone(); + let delegate = self.delegate.clone(); + let session_verification_controller = self.session_verification_controller.clone(); + let local_self = self.clone(); + RUNTIME.spawn(async move { + let mut filter = FilterDefinition::default(); + let mut room_filter = RoomFilter::default(); + let mut event_filter = RoomEventFilter::default(); + let mut timeline_filter = RoomEventFilter::default(); + + event_filter.lazy_load_options = + LazyLoadOptions::Enabled { include_redundant_members: false }; + room_filter.state = event_filter; + filter.room = room_filter; + + timeline_filter.limit = timeline_limit.map(|limit| limit.into()); + filter.room.timeline = timeline_filter; + + let filter_id = client.get_or_upload_filter("sync", filter).await.unwrap(); + + let sync_settings = SyncSettings::new().filter(Filter::FilterId(&filter_id)); + + client + .sync_with_result_callback(sync_settings, |result| async { + Ok(if let Ok(sync_response) = result { + if !state.read().unwrap().has_first_synced { + state.write().unwrap().has_first_synced = true; + } + + if state.read().unwrap().should_stop_syncing { + state.write().unwrap().is_syncing = false; + return Ok(LoopCtrl::Break); + } else if !state.read().unwrap().is_syncing { + state.write().unwrap().is_syncing = true; + } + + if let Some(delegate) = &*delegate.read().unwrap() { + delegate.did_receive_sync_update() + } + + if let Some(session_verification_controller) = + &*session_verification_controller.read().await + { + session_verification_controller + .process_to_device_messages(sync_response.to_device_events) + .await; + } + + LoopCtrl::Continue + } else { + local_self.process_sync_error(result.err().unwrap()) + }) + }) + .await + .unwrap(); + }); + } } #[uniffi::export] diff --git a/bindings/matrix-sdk-ffi/src/lib.rs b/bindings/matrix-sdk-ffi/src/lib.rs index 989ed33e7..fbc927c2c 100644 --- a/bindings/matrix-sdk-ffi/src/lib.rs +++ b/bindings/matrix-sdk-ffi/src/lib.rs @@ -58,6 +58,8 @@ pub use self::{ pub struct ClientState { is_guest: bool, has_first_synced: bool, + is_syncing: bool, + should_stop_syncing: bool, is_soft_logout: bool, } diff --git a/bindings/matrix-sdk-ffi/src/session_verification.rs b/bindings/matrix-sdk-ffi/src/session_verification.rs index 155d70cc1..0dde10eea 100644 --- a/bindings/matrix-sdk-ffi/src/session_verification.rs +++ b/bindings/matrix-sdk-ffi/src/session_verification.rs @@ -192,4 +192,4 @@ impl SessionVerificationController { } } } -} \ No newline at end of file +} From 120d5edb03bbb98d3cdbdfa07b66159735bcca2c Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Thu, 27 Oct 2022 12:32:05 +0100 Subject: [PATCH 09/37] feat(sliding-sync): Replace anyhow with proper Error type --- crates/matrix-sdk/Cargo.toml | 1 - crates/matrix-sdk/src/error.rs | 5 ++ crates/matrix-sdk/src/sliding_sync.rs | 92 +++++++++++++++++++++------ 3 files changed, 76 insertions(+), 22 deletions(-) diff --git a/crates/matrix-sdk/Cargo.toml b/crates/matrix-sdk/Cargo.toml index 5ec0ee230..2e28a6315 100644 --- a/crates/matrix-sdk/Cargo.toml +++ b/crates/matrix-sdk/Cargo.toml @@ -47,7 +47,6 @@ experimental-timeline = [] sliding-sync = [ "matrix-sdk-base/sliding-sync", - "anyhow", "dep:derive_builder", ] diff --git a/crates/matrix-sdk/src/error.rs b/crates/matrix-sdk/src/error.rs index e1e6c565d..dda3fef16 100644 --- a/crates/matrix-sdk/src/error.rs +++ b/crates/matrix-sdk/src/error.rs @@ -193,6 +193,11 @@ pub enum Error { #[error(transparent)] ImageError(#[from] ImageError), + /// An error occurred during decryption. + #[cfg(feature = "sliding-sync")] + #[error(transparent)] + SlidingSync(#[from] crate::sliding_sync::Error), + /// An other error was raised /// this might happen because encryption was enabled on the base-crate /// but not here and that raised. diff --git a/crates/matrix-sdk/src/sliding_sync.rs b/crates/matrix-sdk/src/sliding_sync.rs index 4ba3afe12..b7666fdec 100644 --- a/crates/matrix-sdk/src/sliding_sync.rs +++ b/crates/matrix-sdk/src/sliding_sync.rs @@ -15,7 +15,6 @@ use std::{fmt::Debug, sync::Arc}; -use anyhow::{bail, Context}; use futures_core::stream::Stream; use futures_signals::signal::Mutable; use matrix_sdk_base::deserialized_responses::{SyncResponse, SyncTimelineEvent}; @@ -27,10 +26,21 @@ use ruma::{ events::RoomEventType, OwnedRoomId, RoomId, UInt, }; +use thiserror::Error; use url::Url; use crate::{Client, Result}; +/// Internal representation of errors in Sliding Sync +#[derive(Error, Debug)] +#[non_exhaustive] +pub enum Error { + #[error("Received response for {found} lists, yet we have {expected}.")] + BadViewsCount { found: usize, expected: usize }, + #[error("The sliding sync response could not be handled: {0}")] + BadResponse(String), +} + /// The state the [`SlidingSyncView`] is in. /// /// The lifetime of a SlidingSync usually starts at a `Preload`, getting a fast @@ -442,13 +452,15 @@ impl SlidingSync { &self, resp: v4::Response, views: &[SlidingSyncView], - ) -> anyhow::Result { + ) -> Result { let mut processed = self.client.process_sliding_sync(resp.clone()).await?; tracing::info!("main client processed."); self.pos.replace(Some(resp.pos)); let mut updated_views = Vec::new(); if resp.lists.len() != views.len() { - bail!("Received response for {} lists, yet we have {}", resp.lists.len(), views.len()); + return Err( + Error::BadViewsCount { found: resp.lists.len(), expected: views.len() }.into() + ); } for (view, updates) in std::iter::zip(views, &resp.lists) { @@ -497,7 +509,7 @@ impl SlidingSync { /// Run this stream to receive new updates from the server. pub async fn stream<'a>( &self, - ) -> anyhow::Result> + '_> { + ) -> Result> + '_, crate::Error> { let views = self.views.lock_ref().to_vec(); let extensions = self.extensions.clone(); let client = self.client.clone(); @@ -878,7 +890,7 @@ impl SlidingSyncView { } #[tracing::instrument(skip(self, ops))] - fn room_ops(&self, ops: &Vec) -> anyhow::Result<()> { + fn room_ops(&self, ops: &Vec) -> Result<(), Error> { let mut rooms_list = self.rooms_list.lock_mut(); let _rooms_map = self.rooms.lock_mut(); for op in ops { @@ -886,9 +898,16 @@ impl SlidingSyncView { v4::SlidingOp::Sync => { let start: u32 = op .range - .context("`range` must be present for Sync and Update operation")? + .ok_or_else(|| { + Error::BadResponse( + "`range` must be present for Sync and Update operation".to_owned(), + ) + })? .0 - .try_into()?; + .try_into() + .map_err(|e| { + Error::BadResponse(format!("`range` not a valid int: {:}", e)) + })?; let room_ids = op.room_ids.clone(); room_ids .into_iter() @@ -902,21 +921,41 @@ impl SlidingSyncView { v4::SlidingOp::Delete => { let pos: u32 = op .index - .context("`index` must be present for DELETE operation")? - .try_into()?; + .ok_or_else(|| { + Error::BadResponse( + "`index` must be present for DELETE operation".to_owned(), + ) + })? + .try_into() + .map_err(|e| { + Error::BadResponse(format!( + "`index` not a valid int for DELETE: {:}", + e + )) + })?; rooms_list.set_cloned(pos as usize, RoomListEntry::Empty); } v4::SlidingOp::Insert => { let pos: usize = op .index - .context("`index` must be present for INSERT operation")? - .try_into()?; + .ok_or_else(|| { + Error::BadResponse( + "`index` must be present for INSERT operation".to_owned(), + ) + })? + .try_into() + .map_err(|e| { + Error::BadResponse(format!( + "`index` not a valid int for INSERT: {:}", + e + )) + })?; let sliced = rooms_list.as_slice(); - let room = RoomListEntry::Filled( - op.room_id - .clone() - .context("`room_id` must be present for INSERT operation")?, - ); + let room = RoomListEntry::Filled(op.room_id.clone().ok_or_else(|| { + Error::BadResponse( + "`room_id` must be present for INSERT operation".to_owned(), + ) + })?); let mut dif = 0usize; loop { // find the next empty slot and drop it @@ -925,7 +964,7 @@ impl SlidingSyncView { let (next_p, overflown) = pos.overflowing_add(dif); let check_after = !overflown && next_p < sliced.len(); if !check_prev && !check_after { - bail!("We were asked to insert but could not find any direction to shift to"); + return Err(Error::BadResponse("We were asked to insert but could not find any direction to shift to".to_owned())); } if check_prev && sliced[prev_p].empty_or_invalidated() { @@ -945,13 +984,24 @@ impl SlidingSyncView { v4::SlidingOp::Invalidate => { let max_len = rooms_list.len(); let (mut pos, end): (u32, u32) = if let Some(range) = op.range { - (range.0.try_into()?, range.1.try_into()?) + ( + range.0.try_into().map_err(|e| { + Error::BadResponse(format!("`range.0` not a valid int: {:}", e)) + })?, + range.1.try_into().map_err(|e| { + Error::BadResponse(format!("`range.1` not a valid int: {:}", e)) + })?, + ) } else { - bail!("`range` must be given on `Invalidate` operation") + return Err(Error::BadResponse( + "`range` must be given on `Invalidate` operation".to_owned(), + )); }; if pos > end { - bail!("Invalid invalidation, end smaller than start"); + return Err(Error::BadResponse( + "Invalid invalidation, end smaller than start".to_owned(), + )); } while pos < end { @@ -983,7 +1033,7 @@ impl SlidingSyncView { } #[tracing::instrument(skip(self, ops))] - fn handle_response(&self, rooms_count: u32, ops: &Vec) -> anyhow::Result { + fn handle_response(&self, rooms_count: u32, ops: &Vec) -> Result { let mut missing = rooms_count.checked_sub(self.rooms_list.lock_ref().len() as u32).unwrap_or_default(); let mut changed = false; From 0e59078211cef40eb99b1fe5880bfd9d5ed9997c Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Thu, 27 Oct 2022 12:32:49 +0100 Subject: [PATCH 10/37] fix(ffi): call process_sync_error of client for sliding-sync errors. break if wnated --- bindings/matrix-sdk-ffi/src/client.rs | 9 +++++---- bindings/matrix-sdk-ffi/src/sliding_sync.rs | 11 +++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index 56f16b097..8644246f1 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -280,8 +280,7 @@ impl Client { } /// Process a sync error and return loop control accordingly - fn process_sync_error(&self, sync_error: Error) -> LoopCtrl { - let mut control = LoopCtrl::Continue; + pub(crate) fn process_sync_error(&self, sync_error: Error) -> LoopCtrl { if let Some(RumaApiError::ClientApi(error)) = sync_error.as_ruma_api_error() { if let ErrorKind::UnknownToken { soft_logout } = error.kind { self.state.write().unwrap().is_soft_logout = soft_logout; @@ -289,10 +288,12 @@ impl Client { delegate.did_update_restore_token(); delegate.did_receive_auth_error(soft_logout); } - control = LoopCtrl::Break + return LoopCtrl::Break; } } - control + + tracing::warn!("Ignoring sync error: {:?}", sync_error); + LoopCtrl::Continue } } diff --git a/bindings/matrix-sdk-ffi/src/sliding_sync.rs b/bindings/matrix-sdk-ffi/src/sliding_sync.rs index 97eda7b9e..4673affc9 100644 --- a/bindings/matrix-sdk-ffi/src/sliding_sync.rs +++ b/bindings/matrix-sdk-ffi/src/sliding_sync.rs @@ -17,7 +17,7 @@ use matrix_sdk::ruma::{ assign, IdParseError, OwnedRoomId, }; pub use matrix_sdk::{ - Client as MatrixClient, RoomListEntry as MatrixRoomEntry, + Client as MatrixClient, LoopCtrl, RoomListEntry as MatrixRoomEntry, SlidingSyncBuilder as MatrixSlidingSyncBuilder, SlidingSyncMode, SlidingSyncState, }; use tokio::task::JoinHandle; @@ -516,6 +516,7 @@ impl SlidingSync { let inner_spawn = spawn.clone(); { let mut sync_handle = self.sync_handle.write().unwrap(); + let client = self.client.clone(); if let Some(handle) = sync_handle.take() { handle.abort(); @@ -528,9 +529,11 @@ impl SlidingSync { let update = match stream.next().await { Some(Ok(u)) => u, Some(Err(e)) => { - // FIXME: send this over the FFI - tracing::warn!("Sliding Sync failure: {:?}", e); - continue; + if client.process_sync_error(e.into()) == LoopCtrl::Break { + break; + } else { + continue; + } } None => { tracing::debug!("No update from loop, cancelled"); From d164165c7c06dc81e1b9d0ebee9b5a494ef865ca Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Thu, 27 Oct 2022 15:29:13 +0100 Subject: [PATCH 11/37] fix(ffi): remove extra to-device processing --- bindings/matrix-sdk-ffi/src/client.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index 8644246f1..e8e86d6ab 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -333,7 +333,6 @@ impl Client { let client = self.client.clone(); let state = self.state.clone(); let delegate = self.delegate.clone(); - let session_verification_controller = self.session_verification_controller.clone(); let local_self = self.clone(); RUNTIME.spawn(async move { let mut filter = FilterDefinition::default(); @@ -355,7 +354,7 @@ impl Client { client .sync_with_result_callback(sync_settings, |result| async { - Ok(if let Ok(sync_response) = result { + Ok(if result.is_ok() { if !state.read().unwrap().has_first_synced { state.write().unwrap().has_first_synced = true; } @@ -371,14 +370,6 @@ impl Client { delegate.did_receive_sync_update() } - if let Some(session_verification_controller) = - &*session_verification_controller.read().await - { - session_verification_controller - .process_to_device_messages(sync_response.to_device_events) - .await; - } - LoopCtrl::Continue } else { local_self.process_sync_error(result.err().unwrap()) From 278c6059ae7fcd511e72a1d87f99b51bb8048333 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Thu, 27 Oct 2022 15:59:02 +0100 Subject: [PATCH 12/37] perf(sliding-sync): run outgoing e2ee requests and sync in parallel. And continue the loop if even we hit an error in between --- crates/matrix-sdk/src/sliding_sync.rs | 42 ++++++++++++++++++++------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/crates/matrix-sdk/src/sliding_sync.rs b/crates/matrix-sdk/src/sliding_sync.rs index b7666fdec..066d677f9 100644 --- a/crates/matrix-sdk/src/sliding_sync.rs +++ b/crates/matrix-sdk/src/sliding_sync.rs @@ -514,18 +514,13 @@ impl SlidingSync { let extensions = self.extensions.clone(); let client = self.client.clone(); - Ok(async_stream::try_stream! { + Ok(async_stream::stream! { let mut remaining_views = views.clone(); let mut remaining_generators: Vec> = views .iter() .map(SlidingSyncView::request_generator) .collect(); loop { - #[cfg(feature = "e2e-encryption")] - if let Err(e) = client.send_outgoing_requests().await { - tracing::error!(error = ?e, "Error while sending outgoing E2EE requests"); - } - let mut requests = Vec::new(); let mut new_remaining_generators = Vec::new(); let mut new_remaining_views = Vec::new(); @@ -562,14 +557,39 @@ impl SlidingSync { extensions: extensions.lock_mut().take().unwrap_or_default(), // extensions are sticky, we pop them here once }); tracing::debug!("requesting"); - let resp = client - .send_with_homeserver(req, None, self.homeserver.as_ref().map(ToString::to_string)) - .await?; + + let req = client.send_with_homeserver(req, None, self.homeserver.as_ref().map(ToString::to_string)); + + #[cfg(feature = "e2e-encryption")] + let resp_res = { + let (e2ee_uploads, resp) = futures_util::join!(client.send_outgoing_requests(), req); + if let Err(e) = e2ee_uploads { + tracing::error!(error = ?e, "Error while sending outgoing E2EE requests"); + }; + resp + }; + #[cfg(not(feature = "e2e-encryption"))] + let resp_res = req.await; + + let resp = match resp_res { + Ok(r) => r, + Err(e) => { + yield Err(e.into()); + continue + } + }; + tracing::debug!("received"); - let updates = self.handle_response(resp, &remaining_views).await?; + let updates = match self.handle_response(resp, &remaining_views).await { + Ok(r) => r, + Err(e) => { + yield Err(e.into()); + continue + } + }; tracing::debug!("handled"); - yield updates; + yield Ok(updates); } }) } From 01cc896dabb411ee8cfaf182211ee85b9c269905 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 27 Oct 2022 13:22:52 +0200 Subject: [PATCH 13/37] refactor(bindings): Use uniffi proc-macros a little more in sdk-ffi --- bindings/matrix-sdk-ffi/src/api.udl | 63 ------------------- bindings/matrix-sdk-ffi/src/lib.rs | 13 ++-- bindings/matrix-sdk-ffi/src/room.rs | 17 ++--- .../src/session_verification.rs | 11 ++-- bindings/matrix-sdk-ffi/src/sliding_sync.rs | 52 ++++++++------- bindings/matrix-sdk-ffi/src/timeline.rs | 43 +++++++------ 6 files changed, 77 insertions(+), 122 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/api.udl b/bindings/matrix-sdk-ffi/src/api.udl index 61b7da5ee..a6bfbc4be 100644 --- a/bindings/matrix-sdk-ffi/src/api.udl +++ b/bindings/matrix-sdk-ffi/src/api.udl @@ -30,7 +30,6 @@ dictionary UpdateSummary { sequence rooms; }; - callback interface SlidingSyncObserver { void did_receive_sync_update(UpdateSummary summary); }; @@ -101,27 +100,9 @@ callback interface SlidingSyncViewRoomItemsObserver { interface SlidingSyncViewBuilder { constructor(); - [Self=ByArc] - SlidingSyncViewBuilder timeline_limit(u32 limit); - [Self=ByArc] SlidingSyncViewBuilder sync_mode(SlidingSyncMode mode); - [Self=ByArc] - SlidingSyncViewBuilder batch_size(u32 size); - - [Self=ByArc] - SlidingSyncViewBuilder name(string name); - - [Self=ByArc] - SlidingSyncViewBuilder sort(sequence sort); - - [Self=ByArc] - SlidingSyncViewBuilder add_range(u32 from, u32 to); - - [Self=ByArc] - SlidingSyncViewBuilder reset_ranges(); - [Self=ByArc] SlidingSyncViewBuilder required_state(sequence required_state); @@ -166,18 +147,6 @@ interface SlidingSyncBuilder { [Throws=ClientError, Self=ByArc] SlidingSyncBuilder homeserver(string url); - [Self=ByArc] - SlidingSyncBuilder add_fullsync_view(); - - [Self=ByArc] - SlidingSyncBuilder no_views(); - - [Self=ByArc] - SlidingSyncBuilder add_view(SlidingSyncView view); - - [Self=ByArc] - SlidingSyncBuilder with_common_extensions(); - [Throws=ClientError, Self=ByArc] SlidingSync build(); }; @@ -228,15 +197,7 @@ interface Client { void logout(); }; -enum Membership { - "Invited", - "Joined", - "Left", -}; - interface Room { - Membership membership(); - [Throws=ClientError] string display_name(); @@ -269,8 +230,6 @@ callback interface TimelineListener { }; interface TimelineDiff { - TimelineChange change(); - [Self=ByArc] sequence? replace(); [Self=ByArc] @@ -283,17 +242,6 @@ interface TimelineDiff { TimelineItem? push(); }; -enum TimelineChange { - "Replace", - "InsertAt", - "UpdateAt", - "RemoveAt", - "Move", - "Push", - "Pop", - "Clear", -}; - dictionary InsertAtData { u32 index; TimelineItem item; @@ -312,16 +260,9 @@ dictionary MoveData { interface TimelineItem {}; interface EventTimelineItem { - TimelineKey key(); sequence reactions(); }; -[Enum] -interface TimelineKey { - TransactionId(string txn_id); - EventId(string event_id); -}; - // Other methods defined via proc-macro interface Message { MessageType? msgtype(); @@ -389,8 +330,6 @@ dictionary Reaction { // senders to come }; -interface VirtualTimelineItem {}; - dictionary PaginationOutcome { // Whether there's more messages to be paginated. boolean more_messages; @@ -434,8 +373,6 @@ callback interface SessionVerificationControllerDelegate { interface SessionVerificationController { void set_delegate(SessionVerificationControllerDelegate? delegate); - boolean is_verified(); - [Throws=ClientError] void request_verification(); diff --git a/bindings/matrix-sdk-ffi/src/lib.rs b/bindings/matrix-sdk-ffi/src/lib.rs index fbc927c2c..a52aa71e3 100644 --- a/bindings/matrix-sdk-ffi/src/lib.rs +++ b/bindings/matrix-sdk-ffi/src/lib.rs @@ -99,14 +99,17 @@ mod uniffi_types { authentication_service::{AuthenticationService, HomeserverLoginDetails}, client::Client, client_builder::ClientBuilder, - room::Room, - session_verification::SessionVerificationEmoji, + room::{Membership, Room}, + session_verification::{SessionVerificationController, SessionVerificationEmoji}, sliding_sync::{ - SlidingSync, SlidingSyncBuilder, SlidingSyncRoom, SlidingSyncView, StoppableSpawn, - UnreadNotificationsCount, + RequiredState, RoomListEntry, SlidingSync, SlidingSyncBuilder, SlidingSyncRoom, + SlidingSyncView, SlidingSyncViewBuilder, StoppableSpawn, UnreadNotificationsCount, }, timeline::{ - EventTimelineItem, Message, TimelineItem, TimelineItemContent, VirtualTimelineItem, + EmoteMessageContent, EventTimelineItem, FormattedBody, ImageInfo, ImageMessageContent, + InsertAtData, Message, MessageType, NoticeMessageContent, Reaction, TextMessageContent, + ThumbnailInfo, TimelineChange, TimelineDiff, TimelineItem, TimelineItemContent, + TimelineKey, UpdateAtData, VirtualTimelineItem, }, }; } diff --git a/bindings/matrix-sdk-ffi/src/room.rs b/bindings/matrix-sdk-ffi/src/room.rs index ea77f0177..f39991bd2 100644 --- a/bindings/matrix-sdk-ffi/src/room.rs +++ b/bindings/matrix-sdk-ffi/src/room.rs @@ -20,6 +20,7 @@ use tracing::error; use super::RUNTIME; use crate::{TimelineDiff, TimelineListener}; +#[derive(uniffi::Enum)] pub enum Membership { Invited, Joined, @@ -69,6 +70,14 @@ impl Room { self.room.is_tombstoned() } + pub fn membership(&self) -> Membership { + match &self.room { + SdkRoom::Invited(_) => Membership::Invited, + SdkRoom::Joined(_) => Membership::Joined, + SdkRoom::Left(_) => Membership::Left, + } + } + /// Removes the timeline. /// /// Timeline items cached in memory as well as timeline listeners are @@ -110,14 +119,6 @@ impl Room { }) } - pub fn membership(&self) -> Membership { - match &self.room { - SdkRoom::Invited(_) => Membership::Invited, - SdkRoom::Joined(_) => Membership::Joined, - SdkRoom::Left(_) => Membership::Left, - } - } - pub fn add_timeline_listener(&self, listener: Box) { let timeline_signal = self .timeline diff --git a/bindings/matrix-sdk-ffi/src/session_verification.rs b/bindings/matrix-sdk-ffi/src/session_verification.rs index 9db8f5c4c..0bf723626 100644 --- a/bindings/matrix-sdk-ffi/src/session_verification.rs +++ b/bindings/matrix-sdk-ffi/src/session_verification.rs @@ -44,6 +44,13 @@ pub struct SessionVerificationController { sas_verification: Arc>>, } +#[uniffi::export] +impl SessionVerificationController { + pub fn is_verified(&self) -> bool { + self.user_identity.is_verified() + } +} + impl SessionVerificationController { pub fn new(user_identity: UserIdentity) -> Self { SessionVerificationController { @@ -58,10 +65,6 @@ impl SessionVerificationController { *self.delegate.write().unwrap() = delegate; } - pub fn is_verified(&self) -> bool { - self.user_identity.is_verified() - } - pub fn request_verification(&self) -> anyhow::Result<()> { RUNTIME.block_on(async move { let methods = vec![VerificationMethod::SasV1]; diff --git a/bindings/matrix-sdk-ffi/src/sliding_sync.rs b/bindings/matrix-sdk-ffi/src/sliding_sync.rs index 97eda7b9e..57d7e0ff8 100644 --- a/bindings/matrix-sdk-ffi/src/sliding_sync.rs +++ b/bindings/matrix-sdk-ffi/src/sliding_sync.rs @@ -154,6 +154,7 @@ pub struct UpdateSummary { pub rooms: Vec, } +#[derive(uniffi::Record)] pub struct RequiredState { pub key: String, pub value: String, @@ -241,6 +242,7 @@ impl From<&MatrixRoomEntry> for RoomListEntry { } } } + pub trait SlidingSyncViewRoomItemsObserver: Sync + Send { fn did_receive_update(&self); } @@ -272,12 +274,6 @@ impl SlidingSyncViewBuilder { Arc::new(builder) } - pub fn sort(self: Arc, sort: Vec) -> Arc { - let mut builder = unwrap_or_clone_arc(self); - builder.inner = builder.inner.sort(sort); - Arc::new(builder) - } - pub fn required_state(self: Arc, required_state: Vec) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.inner = builder @@ -286,6 +282,26 @@ impl SlidingSyncViewBuilder { Arc::new(builder) } + pub fn ranges(self: Arc, ranges: Vec<(u32, u32)>) -> Arc { + let mut builder = unwrap_or_clone_arc(self); + builder.inner = builder.inner.ranges(ranges); + Arc::new(builder) + } + + pub fn build(self: Arc) -> anyhow::Result> { + let builder = unwrap_or_clone_arc(self); + Ok(Arc::new(builder.inner.build()?.into())) + } +} + +#[uniffi::export] +impl SlidingSyncViewBuilder { + pub fn sort(self: Arc, sort: Vec) -> Arc { + let mut builder = unwrap_or_clone_arc(self); + builder.inner = builder.inner.sort(sort); + Arc::new(builder) + } + pub fn batch_size(self: Arc, batch_size: u32) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.inner = builder.inner.batch_size(batch_size); @@ -310,12 +326,6 @@ impl SlidingSyncViewBuilder { Arc::new(builder) } - pub fn ranges(self: Arc, ranges: Vec<(u32, u32)>) -> Arc { - let mut builder = unwrap_or_clone_arc(self); - builder.inner = builder.inner.ranges(ranges); - Arc::new(builder) - } - pub fn add_range(self: Arc, from: u32, to: u32) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.inner = builder.inner.add_range(from, to); @@ -327,11 +337,6 @@ impl SlidingSyncViewBuilder { builder.inner = builder.inner.reset_ranges(); Arc::new(builder) } - - pub fn build(self: Arc) -> anyhow::Result> { - let builder = unwrap_or_clone_arc(self); - Ok(Arc::new(builder.inner.build()?.into())) - } } #[derive(Clone)] @@ -566,6 +571,14 @@ impl SlidingSyncBuilder { Ok(Arc::new(builder)) } + pub fn build(self: Arc) -> anyhow::Result> { + let builder = unwrap_or_clone_arc(self); + Ok(Arc::new(SlidingSync::new(builder.inner.build()?, builder.client))) + } +} + +#[uniffi::export] +impl SlidingSyncBuilder { pub fn add_fullsync_view(self: Arc) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.inner = builder.inner.add_fullsync_view(); @@ -590,11 +603,6 @@ impl SlidingSyncBuilder { builder.inner = builder.inner.with_common_extensions(); Arc::new(builder) } - - pub fn build(self: Arc) -> anyhow::Result> { - let builder = unwrap_or_clone_arc(self); - Ok(Arc::new(SlidingSync::new(builder.inner.build()?, builder.client))) - } } impl Client { diff --git a/bindings/matrix-sdk-ffi/src/timeline.rs b/bindings/matrix-sdk-ffi/src/timeline.rs index 7179d18ff..17686f7d9 100644 --- a/bindings/matrix-sdk-ffi/src/timeline.rs +++ b/bindings/matrix-sdk-ffi/src/timeline.rs @@ -45,19 +45,6 @@ impl TimelineDiff { }) } - pub fn change(&self) -> TimelineChange { - match &self.0 { - VecDiff::Replace { .. } => TimelineChange::Replace, - VecDiff::InsertAt { .. } => TimelineChange::InsertAt, - VecDiff::UpdateAt { .. } => TimelineChange::UpdateAt, - VecDiff::RemoveAt { .. } => TimelineChange::RemoveAt, - VecDiff::Move { .. } => TimelineChange::Move, - VecDiff::Push { .. } => TimelineChange::Push, - VecDiff::Pop {} => TimelineChange::Pop, - VecDiff::Clear {} => TimelineChange::Clear, - } - } - pub fn replace(self: Arc) -> Option>> { unwrap_or_clone_arc_into_variant!(self, .0, VecDiff::Replace { values } => values) } @@ -96,6 +83,22 @@ impl TimelineDiff { } } +#[uniffi::export] +impl TimelineDiff { + pub fn change(&self) -> TimelineChange { + match &self.0 { + VecDiff::Replace { .. } => TimelineChange::Replace, + VecDiff::InsertAt { .. } => TimelineChange::InsertAt, + VecDiff::UpdateAt { .. } => TimelineChange::UpdateAt, + VecDiff::RemoveAt { .. } => TimelineChange::RemoveAt, + VecDiff::Move { .. } => TimelineChange::Move, + VecDiff::Push { .. } => TimelineChange::Push, + VecDiff::Pop {} => TimelineChange::Pop, + VecDiff::Clear {} => TimelineChange::Clear, + } + } +} + pub struct InsertAtData { pub index: u32, pub item: Arc, @@ -111,7 +114,7 @@ pub struct MoveData { pub new_index: u32, } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, uniffi::Enum)] pub enum TimelineChange { Replace, InsertAt, @@ -155,10 +158,6 @@ impl TimelineItem { pub struct EventTimelineItem(pub(crate) matrix_sdk::room::timeline::EventTimelineItem); impl EventTimelineItem { - pub fn key(&self) -> TimelineKey { - self.0.key().into() - } - pub fn reactions(&self) -> Vec { self.0 .reactions() @@ -170,6 +169,10 @@ impl EventTimelineItem { #[uniffi::export] impl EventTimelineItem { + pub fn key(&self) -> TimelineKey { + self.0.key().into() + } + pub fn event_id(&self) -> Option { self.0.event_id().map(ToString::to_string) } @@ -374,7 +377,7 @@ pub struct ReactionDetails { pub sender: String, } -#[derive(Clone)] +#[derive(Clone, uniffi::Enum)] pub enum TimelineKey { TransactionId { txn_id: String }, EventId { event_id: String }, @@ -391,7 +394,7 @@ impl From<&matrix_sdk::room::timeline::TimelineKey> for TimelineKey { } } -#[derive(Clone)] +#[derive(Clone, uniffi::Object)] pub struct VirtualTimelineItem(matrix_sdk::room::timeline::VirtualTimelineItem); #[extension_trait] From f2ea72224db80a08fd308da3ed8d3c118a347bc3 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 27 Oct 2022 16:20:21 +0200 Subject: [PATCH 14/37] feat(bindings): Add {TimelineItem,EventTimelineItem}::fmt_debug --- bindings/matrix-sdk-ffi/src/timeline.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bindings/matrix-sdk-ffi/src/timeline.rs b/bindings/matrix-sdk-ffi/src/timeline.rs index 17686f7d9..f52221245 100644 --- a/bindings/matrix-sdk-ffi/src/timeline.rs +++ b/bindings/matrix-sdk-ffi/src/timeline.rs @@ -153,6 +153,10 @@ impl TimelineItem { Arc::new(VirtualTimelineItem(vt)) }) } + + pub fn fmt_debug(&self) -> String { + format!("{:#?}", self.0) + } } pub struct EventTimelineItem(pub(crate) matrix_sdk::room::timeline::EventTimelineItem); @@ -196,6 +200,10 @@ impl EventTimelineItem { pub fn raw(&self) -> Option { self.0.raw().map(|r| r.json().get().to_owned()) } + + pub fn fmt_debug(&self) -> String { + format!("{:#?}", self.0) + } } #[derive(Clone, uniffi::Object)] From 0d84cf7b74b4a84d8af2e4d42edc79280ca7b8f2 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 27 Oct 2022 17:05:33 +0200 Subject: [PATCH 15/37] refactor(sdk): Make Debug format of EventTimelineItem less noisy --- .../src/room/timeline/event_item.rs | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/matrix-sdk/src/room/timeline/event_item.rs b/crates/matrix-sdk/src/room/timeline/event_item.rs index c532aa7de..20f03a02b 100644 --- a/crates/matrix-sdk/src/room/timeline/event_item.rs +++ b/crates/matrix-sdk/src/room/timeline/event_item.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::fmt; + use indexmap::IndexMap; use matrix_sdk_base::deserialized_responses::EncryptionInfo; #[cfg(feature = "experimental-room-preview")] @@ -32,7 +34,7 @@ use ruma::{ /// There is always one main event that gives the `EventTimelineItem` its /// identity (see [key](Self::key)) but in many cases, additional events like /// reactions and edits are also part of the item. -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct EventTimelineItem { pub(super) key: TimelineKey, // If this item is a local echo that has been acknowledged by the server @@ -49,6 +51,22 @@ pub struct EventTimelineItem { pub(super) raw: Option>, } +impl fmt::Debug for EventTimelineItem { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("EventTimelineItem") + .field("key", &self.key) + .field("event_id", &self.event_id) + .field("sender", &self.sender) + .field("content", &self.content) + .field("reactions", &self.reactions) + .field("origin_server_ts", &self.origin_server_ts) + .field("is_own", &self.is_own) + .field("encryption_info", &self.encryption_info) + // skip raw, too noisy + .finish_non_exhaustive() + } +} + macro_rules! build { ( $ty:ident { From 0cb34f7c86724f1dd85b9b4da9560c626566ec73 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 28 Oct 2022 11:01:54 +0200 Subject: [PATCH 16/37] fix: style fixes --- bindings/matrix-sdk-ffi/src/sliding_sync.rs | 2 +- crates/matrix-sdk/src/error.rs | 2 +- crates/matrix-sdk/src/sliding_sync.rs | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/sliding_sync.rs b/bindings/matrix-sdk-ffi/src/sliding_sync.rs index 4673affc9..41ceb3f52 100644 --- a/bindings/matrix-sdk-ffi/src/sliding_sync.rs +++ b/bindings/matrix-sdk-ffi/src/sliding_sync.rs @@ -529,7 +529,7 @@ impl SlidingSync { let update = match stream.next().await { Some(Ok(u)) => u, Some(Err(e)) => { - if client.process_sync_error(e.into()) == LoopCtrl::Break { + if client.process_sync_error(e) == LoopCtrl::Break { break; } else { continue; diff --git a/crates/matrix-sdk/src/error.rs b/crates/matrix-sdk/src/error.rs index dda3fef16..2d2f0a4ac 100644 --- a/crates/matrix-sdk/src/error.rs +++ b/crates/matrix-sdk/src/error.rs @@ -193,7 +193,7 @@ pub enum Error { #[error(transparent)] ImageError(#[from] ImageError), - /// An error occurred during decryption. + /// An error occurred within sliding-sync #[cfg(feature = "sliding-sync")] #[error(transparent)] SlidingSync(#[from] crate::sliding_sync::Error), diff --git a/crates/matrix-sdk/src/sliding_sync.rs b/crates/matrix-sdk/src/sliding_sync.rs index 066d677f9..f7563119a 100644 --- a/crates/matrix-sdk/src/sliding_sync.rs +++ b/crates/matrix-sdk/src/sliding_sync.rs @@ -565,7 +565,7 @@ impl SlidingSync { let (e2ee_uploads, resp) = futures_util::join!(client.send_outgoing_requests(), req); if let Err(e) = e2ee_uploads { tracing::error!(error = ?e, "Error while sending outgoing E2EE requests"); - }; + } resp }; #[cfg(not(feature = "e2e-encryption"))] @@ -926,7 +926,7 @@ impl SlidingSyncView { .0 .try_into() .map_err(|e| { - Error::BadResponse(format!("`range` not a valid int: {:}", e)) + Error::BadResponse(format!("`range` not a valid int: {e:}")) })?; let room_ids = op.room_ids.clone(); room_ids @@ -1006,10 +1006,10 @@ impl SlidingSyncView { let (mut pos, end): (u32, u32) = if let Some(range) = op.range { ( range.0.try_into().map_err(|e| { - Error::BadResponse(format!("`range.0` not a valid int: {:}", e)) + Error::BadResponse(format!("`range.0` not a valid int: {e:}")) })?, range.1.try_into().map_err(|e| { - Error::BadResponse(format!("`range.1` not a valid int: {:}", e)) + Error::BadResponse(format!("`range.1` not a valid int: {e:}")) })?, ) } else { From 6ce23b17a63f007e50166b0e572f69929d9ac0fb Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 27 Oct 2022 17:25:38 +0200 Subject: [PATCH 17/37] refactor(sdk): Update tracing event for local echo not being found --- crates/matrix-sdk/src/room/timeline/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/matrix-sdk/src/room/timeline/mod.rs b/crates/matrix-sdk/src/room/timeline/mod.rs index 210466656..775f83390 100644 --- a/crates/matrix-sdk/src/room/timeline/mod.rs +++ b/crates/matrix-sdk/src/room/timeline/mod.rs @@ -29,7 +29,7 @@ use ruma::{ events::{reaction::Relation as AnnotationRelation, AnyMessageLikeEventContent}, OwnedEventId, OwnedUserId, TransactionId, UInt, }; -use tracing::{debug, error, instrument}; +use tracing::{error, instrument, warn}; use super::{Joined, Room}; use crate::{ @@ -236,6 +236,6 @@ fn add_event_id(items: &TimelineInner, txn_id: &TransactionId, event_id: OwnedEv } } } else { - debug!(%txn_id, "Timeline item not found, can't mark as sent"); + warn!(%txn_id, "Timeline item not found, can't add event ID"); } } From 333c4f0644b529a5ecf6d652f8b4e7adeffc0b85 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 27 Oct 2022 17:35:36 +0200 Subject: [PATCH 18/37] refactor(sdk): Move timeline event origin_server_ts and raw_event fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … from TimelineEventMetadata to Flow because they always exist for remote events, and never for local echoes. --- .../src/room/timeline/event_handler.rs | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/crates/matrix-sdk/src/room/timeline/event_handler.rs b/crates/matrix-sdk/src/room/timeline/event_handler.rs index f7ced1e72..947ebd1a2 100644 --- a/crates/matrix-sdk/src/room/timeline/event_handler.rs +++ b/crates/matrix-sdk/src/room/timeline/event_handler.rs @@ -58,8 +58,6 @@ impl TimelineInner { ) { let meta = TimelineEventMetadata { sender: own_user_id.to_owned(), - origin_server_ts: None, - raw_event: None, is_own_event: true, relations: None, // FIXME: Should we supply something here for encrypted rooms? @@ -100,15 +98,15 @@ impl TimelineInner { let is_own_event = sender == own_user_id; let meta = TimelineEventMetadata { - raw_event: Some(raw), sender, - origin_server_ts: Some(event.origin_server_ts()), is_own_event, relations: event.relations().cloned(), encryption_info, }; let flow = Flow::Remote { event_id: event.event_id().to_owned(), + origin_server_ts: event.origin_server_ts(), + raw_event: raw, txn_id: event.transaction_id().map(ToOwned::to_owned), position, }; @@ -124,6 +122,8 @@ enum Flow { Remote { event_id: OwnedEventId, txn_id: Option, + origin_server_ts: MilliSecondsSinceUnixEpoch, + raw_event: Raw, position: TimelineItemPosition, }, } @@ -135,12 +135,24 @@ impl Flow { Self::Local { txn_id } => TimelineKey::TransactionId(txn_id.to_owned()), } } + + fn origin_server_ts(&self) -> Option { + match self { + Flow::Local { .. } => None, + Flow::Remote { origin_server_ts, .. } => Some(*origin_server_ts), + } + } + + fn raw_event(&self) -> Option<&Raw> { + match self { + Flow::Local { .. } => None, + Flow::Remote { raw_event, .. } => Some(raw_event), + } + } } struct TimelineEventMetadata { - raw_event: Option>, sender: OwnedUserId, - origin_server_ts: Option, is_own_event: bool, relations: Option, encryption_info: Option, @@ -382,10 +394,10 @@ impl<'a> TimelineEventHandler<'a> { sender: self.meta.sender.to_owned(), content, reactions, - origin_server_ts: self.meta.origin_server_ts, + origin_server_ts: self.flow.origin_server_ts(), is_own: self.meta.is_own_event, encryption_info: self.meta.encryption_info.clone(), - raw: self.meta.raw_event.clone(), + raw: self.flow.raw_event().cloned(), }; let item = Arc::new(TimelineItem::Event(item)); @@ -398,7 +410,7 @@ impl<'a> TimelineEventHandler<'a> { Flow::Remote { position: TimelineItemPosition::Start, txn_id: None, .. } => { lock.insert_cloned(0, item); } - Flow::Remote { txn_id: Some(txn_id), event_id, position } => { + Flow::Remote { txn_id: Some(txn_id), event_id, position, .. } => { if let Some((idx, _old_item)) = find_event(&lock, txn_id) { // TODO: Check whether anything is different about the old and new item? lock.set_cloned(idx, item); From 6ad7d293646032017d61372a74dd8d7169ab4a58 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 27 Oct 2022 17:38:37 +0200 Subject: [PATCH 19/37] refactor(sdk): When processing remote events, check for duplicates --- .../src/room/timeline/event_handler.rs | 50 ++++++++++++------- .../src/room/timeline/event_item.rs | 6 +++ 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/crates/matrix-sdk/src/room/timeline/event_handler.rs b/crates/matrix-sdk/src/room/timeline/event_handler.rs index 947ebd1a2..9e02f6393 100644 --- a/crates/matrix-sdk/src/room/timeline/event_handler.rs +++ b/crates/matrix-sdk/src/room/timeline/event_handler.rs @@ -403,27 +403,43 @@ impl<'a> TimelineEventHandler<'a> { let item = Arc::new(TimelineItem::Event(item)); let mut lock = self.timeline.items.lock_mut(); match &self.flow { - Flow::Local { .. } - | Flow::Remote { position: TimelineItemPosition::End, txn_id: None, .. } => { + Flow::Local { .. } => { lock.push_cloned(item); } - Flow::Remote { position: TimelineItemPosition::Start, txn_id: None, .. } => { - lock.insert_cloned(0, item); - } - Flow::Remote { txn_id: Some(txn_id), event_id, position, .. } => { - if let Some((idx, _old_item)) = find_event(&lock, txn_id) { - // TODO: Check whether anything is different about the old and new item? - lock.set_cloned(idx, item); - } else { - debug!( - %txn_id, %event_id, - "Received event with transaction ID, but didn't find matching timeline item" + Flow::Remote { txn_id, event_id, position, raw_event, .. } => { + if let Some(txn_id) = txn_id { + if let Some((idx, _old_item)) = find_event(&lock, txn_id) { + // TODO: Check whether anything is different about the + // old and new item? + lock.set_cloned(idx, item); + return; + } else { + warn!( + %txn_id, %event_id, + "Received event with transaction ID, but didn't \ + find matching timeline item" + ); + } + } + + if let Some((idx, old_item)) = find_event(&lock, event_id) { + warn!( + ?item, + ?old_item, + raw = raw_event.json().get(), + "Received event with an ID we already have a timeline item for" ); - match position { - TimelineItemPosition::Start => lock.insert_cloned(0, item), - TimelineItemPosition::End => lock.push_cloned(item), - } + // With /messages and /sync sometimes disagreeing on order + // of messages, we might want to change the position in some + // circumstances, but for now this should be good enough. + lock.set_cloned(idx, item); + return; + } + + match position { + TimelineItemPosition::Start => lock.insert_cloned(0, item), + TimelineItemPosition::End => lock.push_cloned(item), } } } diff --git a/crates/matrix-sdk/src/room/timeline/event_item.rs b/crates/matrix-sdk/src/room/timeline/event_item.rs index 20f03a02b..9b50b1560 100644 --- a/crates/matrix-sdk/src/room/timeline/event_item.rs +++ b/crates/matrix-sdk/src/room/timeline/event_item.rs @@ -252,6 +252,12 @@ impl PartialEq for &EventId { } } +impl PartialEq for &OwnedEventId { + fn eq(&self, key: &TimelineKey) -> bool { + matches!(key, TimelineKey::EventId(event_id) if event_id == *self) + } +} + /// Some details of an [`EventTimelineItem`] that may require server requests /// other than just the regular /// [`sync_events`][ruma::api::client::sync::sync_events]. From cacb20e3ef8ce54e35dc7219036d6d7b2e5f0c3a Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 28 Oct 2022 13:38:21 +0200 Subject: [PATCH 20/37] fix(ffi): Remove duplicate RequireState definition, left over after #1151 (#1155) --- bindings/matrix-sdk-ffi/src/sliding_sync.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/sliding_sync.rs b/bindings/matrix-sdk-ffi/src/sliding_sync.rs index ee94ca0e7..5567c75a8 100644 --- a/bindings/matrix-sdk-ffi/src/sliding_sync.rs +++ b/bindings/matrix-sdk-ffi/src/sliding_sync.rs @@ -153,8 +153,6 @@ pub struct UpdateSummary { pub views: Vec, pub rooms: Vec, } - -#[derive(uniffi::Record)] pub struct RequiredState { pub key: String, pub value: String, From a07f89e3401cd672131edde797384d7fc61a2671 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 28 Oct 2022 20:35:04 +0200 Subject: [PATCH 21/37] feat(crypto-js): `OlmMachine.initialize` is the new constructor. While technically a type constructor can return a `Promise`, it's not considered as idiomatic JavaScript to do that. We are changing `new OlmMachine` to `OlmMachine.initialize`. The rest of the code is strictly the same. --- bindings/matrix-sdk-crypto-js/src/machine.rs | 14 +++++++++++--- bindings/matrix-sdk-crypto-js/tests/device.test.js | 4 ++-- .../matrix-sdk-crypto-js/tests/machine.test.js | 12 ++++++------ .../matrix-sdk-crypto-js/tests/tracing.test.js | 2 +- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/bindings/matrix-sdk-crypto-js/src/machine.rs b/bindings/matrix-sdk-crypto-js/src/machine.rs index 3133d7331..31025e8bf 100644 --- a/bindings/matrix-sdk-crypto-js/src/machine.rs +++ b/bindings/matrix-sdk-crypto-js/src/machine.rs @@ -28,6 +28,16 @@ pub struct OlmMachine { #[wasm_bindgen] impl OlmMachine { + /// Constructor will always fail. To create a new `OlmMachine`, please use + /// the `initialize` method. + /// + /// Why this pattern? `initialize` returns a `Promise`. Returning a + // `Promise` from a constructor is not idiomatic in JavaScript. + #[wasm_bindgen(constructor)] + pub fn new() -> Result { + Err(JsError::new("To build an `OlmMachine`, please use the `initialize` method")) + } + /// Create a new memory based `OlmMachine`. /// /// The created machine will keep the encryption keys either in a IndexedDB @@ -49,9 +59,7 @@ impl OlmMachine { /// /// * `store_passphrase` - The passphrase that should be used to encrypt the /// IndexedDB based - #[wasm_bindgen(constructor)] - #[allow(clippy::new_ret_no_self)] - pub fn new( + pub fn initialize( user_id: &identifiers::UserId, device_id: &identifiers::DeviceId, store_name: Option, diff --git a/bindings/matrix-sdk-crypto-js/tests/device.test.js b/bindings/matrix-sdk-crypto-js/tests/device.test.js index ec01a664e..7f8d8fe6a 100644 --- a/bindings/matrix-sdk-crypto-js/tests/device.test.js +++ b/bindings/matrix-sdk-crypto-js/tests/device.test.js @@ -53,7 +53,7 @@ describe(OlmMachine.name, () => { const room = new RoomId('!baz:matrix.org'); function machine(new_user, new_device) { - return new OlmMachine(new_user || user, new_device || device); + return OlmMachine.initialize(new_user || user, new_device || device); } test('can read user devices', async () => { @@ -116,7 +116,7 @@ describe('Key Verification', () => { const deviceId2 = new DeviceId('bob_device'); function machine(new_user, new_device) { - return new OlmMachine(new_user || userId1, new_device || deviceId1); + return OlmMachine.initialize(new_user || userId1, new_device || deviceId1); } describe('SAS', () => { diff --git a/bindings/matrix-sdk-crypto-js/tests/machine.test.js b/bindings/matrix-sdk-crypto-js/tests/machine.test.js index c375015dd..4509f1515 100644 --- a/bindings/matrix-sdk-crypto-js/tests/machine.test.js +++ b/bindings/matrix-sdk-crypto-js/tests/machine.test.js @@ -25,7 +25,7 @@ require('fake-indexeddb/auto'); describe(OlmMachine.name, () => { test('can be instantiated with the async initializer', async () => { - expect(await new OlmMachine(new UserId('@foo:bar.org'), new DeviceId('baz'))).toBeInstanceOf(OlmMachine); + expect(await OlmMachine.initialize(new UserId('@foo:bar.org'), new DeviceId('baz'))).toBeInstanceOf(OlmMachine); }); test('can be instantiated with a store', async () => { @@ -36,7 +36,7 @@ describe(OlmMachine.name, () => { let store_passphrase = 'world'; // Creating a new Olm machine. - expect(await new OlmMachine(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase)).toBeInstanceOf(OlmMachine); + expect(await OlmMachine.initialize(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase)).toBeInstanceOf(OlmMachine); // Oh, there is 2 databases now, prefixed by `store_name`. let databases = await indexedDB.databases(); @@ -48,7 +48,7 @@ describe(OlmMachine.name, () => { ]); // Creating a new Olm machine, with the stored state. - expect(await new OlmMachine(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase)).toBeInstanceOf(OlmMachine); + expect(await OlmMachine.initialize(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase)).toBeInstanceOf(OlmMachine); // Same number of databases. expect(await indexedDB.databases()).toHaveLength(2); @@ -62,7 +62,7 @@ describe(OlmMachine.name, () => { let err = null; try { - await new OlmMachine(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase); + await OlmMachine.initialize(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase); } catch (error) { err = error; } @@ -77,7 +77,7 @@ describe(OlmMachine.name, () => { let err = null; try { - await new OlmMachine(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase); + await OlmMachine.initialize(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase); } catch (error) { err = error; } @@ -91,7 +91,7 @@ describe(OlmMachine.name, () => { const room = new RoomId('!baz:matrix.org'); function machine(new_user, new_device) { - return new OlmMachine(new_user || user, new_device || device); + return OlmMachine.initialize(new_user || user, new_device || device); } test('can read user ID', async () => { diff --git a/bindings/matrix-sdk-crypto-js/tests/tracing.test.js b/bindings/matrix-sdk-crypto-js/tests/tracing.test.js index ecb7276f9..a37383f24 100644 --- a/bindings/matrix-sdk-crypto-js/tests/tracing.test.js +++ b/bindings/matrix-sdk-crypto-js/tests/tracing.test.js @@ -68,7 +68,7 @@ describe(Tracing.name, () => { }; // Do something that emits a `DEBUG` log. - await new OlmMachine(new UserId('@alice:example.org'), new DeviceId('foo')); + await OlmMachine.initialize(new UserId('@alice:example.org'), new DeviceId('foo')); console.debug = originalConsoleDebug; testPostState(); From 3441c6cf9a31103f7ed10fe6af5776ef913cbc5f Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 28 Oct 2022 20:57:04 +0200 Subject: [PATCH 22/37] feat(crypto-js): Use `WeakRef` to avoid calling `free` manually. By asking `wasm-bindgen` to generate JS glue code for `WeakRef` support, it removes the need to call `free` manually to free objects, thus we reduce potential memory leaks inside Rust. See https:// rustwasm.github.io/docs/wasm- bindgen/reference/weak-references.html to learn more. It uses [`FinalizationRegistry`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry) under the hood, I reckon it's quite common and fits into Matrix's clients needs in terms of browser support. --- bindings/matrix-sdk-crypto-js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/matrix-sdk-crypto-js/package.json b/bindings/matrix-sdk-crypto-js/package.json index 726466786..70c2a428a 100644 --- a/bindings/matrix-sdk-crypto-js/package.json +++ b/bindings/matrix-sdk-crypto-js/package.json @@ -37,7 +37,7 @@ "node": ">= 10" }, "scripts": { - "build": "cross-env RUSTFLAGS='-C opt-level=z' wasm-pack build --release --target nodejs --scope matrix-org --out-dir ./pkg", + "build": "cross-env RUSTFLAGS='-C opt-level=z' WASM_BINDGEN_WEAKREF=1 wasm-pack build --release --target nodejs --scope matrix-org --out-dir ./pkg", "test": "jest --verbose", "doc": "typedoc --tsconfig .", "prepack": "npm run build && npm run test", From bdf460cd9162f73a728a1b3f4d672034ab36490f Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 31 Oct 2022 11:07:21 +0100 Subject: [PATCH 23/37] doc(crypto-js): Rephase something. Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- bindings/matrix-sdk-crypto-js/src/machine.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/matrix-sdk-crypto-js/src/machine.rs b/bindings/matrix-sdk-crypto-js/src/machine.rs index 31025e8bf..84bd5befb 100644 --- a/bindings/matrix-sdk-crypto-js/src/machine.rs +++ b/bindings/matrix-sdk-crypto-js/src/machine.rs @@ -38,7 +38,7 @@ impl OlmMachine { Err(JsError::new("To build an `OlmMachine`, please use the `initialize` method")) } - /// Create a new memory based `OlmMachine`. + /// Create a new `OlmMachine`. /// /// The created machine will keep the encryption keys either in a IndexedDB /// based store, or in a memory store and once the objects is dropped, From e4964b92a249b5347cc1e2b1b0b895a2173a2b36 Mon Sep 17 00:00:00 2001 From: Andy Uhnak Date: Thu, 27 Oct 2022 22:33:00 +0100 Subject: [PATCH 24/37] Local trust --- bindings/apple/MatrixSDKCrypto.podspec | 2 +- bindings/matrix-sdk-crypto-ffi/src/lib.rs | 5 +++++ bindings/matrix-sdk-crypto-ffi/src/machine.rs | 1 + bindings/matrix-sdk-crypto-ffi/src/olm.udl | 7 +++++++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/bindings/apple/MatrixSDKCrypto.podspec b/bindings/apple/MatrixSDKCrypto.podspec index 6c2426b5d..b4b1f9713 100644 --- a/bindings/apple/MatrixSDKCrypto.podspec +++ b/bindings/apple/MatrixSDKCrypto.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "MatrixSDKCrypto" - s.version = "0.1.2" + s.version = "0.1.5" s.summary = "Uniffi based bindings for the Rust SDK crypto crate." s.homepage = "https://github.com/matrix-org/matrix-rust-sdk" s.license = { :type => "Apache License, Version 2.0", :file => "LICENSE" } diff --git a/bindings/matrix-sdk-crypto-ffi/src/lib.rs b/bindings/matrix-sdk-crypto-ffi/src/lib.rs index b619c88fe..cc6c7e57c 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/lib.rs +++ b/bindings/matrix-sdk-crypto-ffi/src/lib.rs @@ -28,6 +28,7 @@ pub use error::{ use js_int::UInt; pub use logger::{set_logger, Logger}; pub use machine::{KeyRequestPair, OlmMachine}; +use matrix_sdk_common::deserialized_responses::VerificationState; use matrix_sdk_crypto::{ types::{EventEncryptionAlgorithm as RustEventEncryptionAlgorithm, SigningKey}, EncryptionSettings as RustEncryptionSettings, LocalTrust, @@ -458,6 +459,10 @@ pub struct DecryptedEvent { /// key to us. Is empty if the key came directly from the sender of the /// event. pub forwarding_curve25519_chain: Vec, + /// The verification state of the device that sent us the event, note this + /// is the state of the device at the time of decryption. It may change in + /// the future if a device gets verified or deleted. + pub verification_state: VerificationState, } /// Struct representing the state of our private cross signing keys, it shows diff --git a/bindings/matrix-sdk-crypto-ffi/src/machine.rs b/bindings/matrix-sdk-crypto-ffi/src/machine.rs index a859b432e..b36ffcd69 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/machine.rs +++ b/bindings/matrix-sdk-crypto-ffi/src/machine.rs @@ -629,6 +629,7 @@ impl OlmMachine { .get(&DeviceKeyAlgorithm::Ed25519) .cloned(), forwarding_curve25519_chain: vec![], + verification_state: encryption_info.verification_state, } } }) diff --git a/bindings/matrix-sdk-crypto-ffi/src/olm.udl b/bindings/matrix-sdk-crypto-ffi/src/olm.udl index 9044d09ec..59397eda0 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/olm.udl +++ b/bindings/matrix-sdk-crypto-ffi/src/olm.udl @@ -82,6 +82,7 @@ dictionary DecryptedEvent { string sender_curve25519_key; string? claimed_ed25519_key; sequence forwarding_curve25519_chain; + VerificationState verification_state; }; dictionary Device { @@ -254,6 +255,12 @@ enum LocalTrust { "Unset", }; +enum VerificationState { + "Trusted", + "Untrusted", + "UnknownDevice", +}; + enum EventEncryptionAlgorithm { "OlmV1Curve25519AesSha2", "MegolmV1AesSha2", From 6c975b01b5a3bec6a8a325b203399d826f55877a Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Mon, 31 Oct 2022 12:03:23 +0100 Subject: [PATCH 25/37] Revert #1151 This reverts the commits - cacb20e3ef8ce54e35dc7219036d6d7b2e5f0c3a - 01cc896dabb411ee8cfaf182211ee85b9c269905 --- bindings/matrix-sdk-ffi/src/api.udl | 63 +++++++++++++++++++ bindings/matrix-sdk-ffi/src/lib.rs | 13 ++-- bindings/matrix-sdk-ffi/src/room.rs | 17 +++-- .../src/session_verification.rs | 11 ++-- bindings/matrix-sdk-ffi/src/sliding_sync.rs | 52 +++++++-------- bindings/matrix-sdk-ffi/src/timeline.rs | 43 ++++++------- 6 files changed, 123 insertions(+), 76 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/api.udl b/bindings/matrix-sdk-ffi/src/api.udl index a6bfbc4be..61b7da5ee 100644 --- a/bindings/matrix-sdk-ffi/src/api.udl +++ b/bindings/matrix-sdk-ffi/src/api.udl @@ -30,6 +30,7 @@ dictionary UpdateSummary { sequence rooms; }; + callback interface SlidingSyncObserver { void did_receive_sync_update(UpdateSummary summary); }; @@ -100,9 +101,27 @@ callback interface SlidingSyncViewRoomItemsObserver { interface SlidingSyncViewBuilder { constructor(); + [Self=ByArc] + SlidingSyncViewBuilder timeline_limit(u32 limit); + [Self=ByArc] SlidingSyncViewBuilder sync_mode(SlidingSyncMode mode); + [Self=ByArc] + SlidingSyncViewBuilder batch_size(u32 size); + + [Self=ByArc] + SlidingSyncViewBuilder name(string name); + + [Self=ByArc] + SlidingSyncViewBuilder sort(sequence sort); + + [Self=ByArc] + SlidingSyncViewBuilder add_range(u32 from, u32 to); + + [Self=ByArc] + SlidingSyncViewBuilder reset_ranges(); + [Self=ByArc] SlidingSyncViewBuilder required_state(sequence required_state); @@ -147,6 +166,18 @@ interface SlidingSyncBuilder { [Throws=ClientError, Self=ByArc] SlidingSyncBuilder homeserver(string url); + [Self=ByArc] + SlidingSyncBuilder add_fullsync_view(); + + [Self=ByArc] + SlidingSyncBuilder no_views(); + + [Self=ByArc] + SlidingSyncBuilder add_view(SlidingSyncView view); + + [Self=ByArc] + SlidingSyncBuilder with_common_extensions(); + [Throws=ClientError, Self=ByArc] SlidingSync build(); }; @@ -197,7 +228,15 @@ interface Client { void logout(); }; +enum Membership { + "Invited", + "Joined", + "Left", +}; + interface Room { + Membership membership(); + [Throws=ClientError] string display_name(); @@ -230,6 +269,8 @@ callback interface TimelineListener { }; interface TimelineDiff { + TimelineChange change(); + [Self=ByArc] sequence? replace(); [Self=ByArc] @@ -242,6 +283,17 @@ interface TimelineDiff { TimelineItem? push(); }; +enum TimelineChange { + "Replace", + "InsertAt", + "UpdateAt", + "RemoveAt", + "Move", + "Push", + "Pop", + "Clear", +}; + dictionary InsertAtData { u32 index; TimelineItem item; @@ -260,9 +312,16 @@ dictionary MoveData { interface TimelineItem {}; interface EventTimelineItem { + TimelineKey key(); sequence reactions(); }; +[Enum] +interface TimelineKey { + TransactionId(string txn_id); + EventId(string event_id); +}; + // Other methods defined via proc-macro interface Message { MessageType? msgtype(); @@ -330,6 +389,8 @@ dictionary Reaction { // senders to come }; +interface VirtualTimelineItem {}; + dictionary PaginationOutcome { // Whether there's more messages to be paginated. boolean more_messages; @@ -373,6 +434,8 @@ callback interface SessionVerificationControllerDelegate { interface SessionVerificationController { void set_delegate(SessionVerificationControllerDelegate? delegate); + boolean is_verified(); + [Throws=ClientError] void request_verification(); diff --git a/bindings/matrix-sdk-ffi/src/lib.rs b/bindings/matrix-sdk-ffi/src/lib.rs index a52aa71e3..fbc927c2c 100644 --- a/bindings/matrix-sdk-ffi/src/lib.rs +++ b/bindings/matrix-sdk-ffi/src/lib.rs @@ -99,17 +99,14 @@ mod uniffi_types { authentication_service::{AuthenticationService, HomeserverLoginDetails}, client::Client, client_builder::ClientBuilder, - room::{Membership, Room}, - session_verification::{SessionVerificationController, SessionVerificationEmoji}, + room::Room, + session_verification::SessionVerificationEmoji, sliding_sync::{ - RequiredState, RoomListEntry, SlidingSync, SlidingSyncBuilder, SlidingSyncRoom, - SlidingSyncView, SlidingSyncViewBuilder, StoppableSpawn, UnreadNotificationsCount, + SlidingSync, SlidingSyncBuilder, SlidingSyncRoom, SlidingSyncView, StoppableSpawn, + UnreadNotificationsCount, }, timeline::{ - EmoteMessageContent, EventTimelineItem, FormattedBody, ImageInfo, ImageMessageContent, - InsertAtData, Message, MessageType, NoticeMessageContent, Reaction, TextMessageContent, - ThumbnailInfo, TimelineChange, TimelineDiff, TimelineItem, TimelineItemContent, - TimelineKey, UpdateAtData, VirtualTimelineItem, + EventTimelineItem, Message, TimelineItem, TimelineItemContent, VirtualTimelineItem, }, }; } diff --git a/bindings/matrix-sdk-ffi/src/room.rs b/bindings/matrix-sdk-ffi/src/room.rs index f39991bd2..ea77f0177 100644 --- a/bindings/matrix-sdk-ffi/src/room.rs +++ b/bindings/matrix-sdk-ffi/src/room.rs @@ -20,7 +20,6 @@ use tracing::error; use super::RUNTIME; use crate::{TimelineDiff, TimelineListener}; -#[derive(uniffi::Enum)] pub enum Membership { Invited, Joined, @@ -70,14 +69,6 @@ impl Room { self.room.is_tombstoned() } - pub fn membership(&self) -> Membership { - match &self.room { - SdkRoom::Invited(_) => Membership::Invited, - SdkRoom::Joined(_) => Membership::Joined, - SdkRoom::Left(_) => Membership::Left, - } - } - /// Removes the timeline. /// /// Timeline items cached in memory as well as timeline listeners are @@ -119,6 +110,14 @@ impl Room { }) } + pub fn membership(&self) -> Membership { + match &self.room { + SdkRoom::Invited(_) => Membership::Invited, + SdkRoom::Joined(_) => Membership::Joined, + SdkRoom::Left(_) => Membership::Left, + } + } + pub fn add_timeline_listener(&self, listener: Box) { let timeline_signal = self .timeline diff --git a/bindings/matrix-sdk-ffi/src/session_verification.rs b/bindings/matrix-sdk-ffi/src/session_verification.rs index d2d175bc8..0dde10eea 100644 --- a/bindings/matrix-sdk-ffi/src/session_verification.rs +++ b/bindings/matrix-sdk-ffi/src/session_verification.rs @@ -44,13 +44,6 @@ pub struct SessionVerificationController { sas_verification: Arc>>, } -#[uniffi::export] -impl SessionVerificationController { - pub fn is_verified(&self) -> bool { - self.user_identity.is_verified() - } -} - impl SessionVerificationController { pub fn new(user_identity: UserIdentity) -> Self { SessionVerificationController { @@ -65,6 +58,10 @@ impl SessionVerificationController { *self.delegate.write().unwrap() = delegate; } + pub fn is_verified(&self) -> bool { + self.user_identity.is_verified() + } + pub fn request_verification(&self) -> anyhow::Result<()> { RUNTIME.block_on(async move { let methods = vec![VerificationMethod::SasV1]; diff --git a/bindings/matrix-sdk-ffi/src/sliding_sync.rs b/bindings/matrix-sdk-ffi/src/sliding_sync.rs index 5567c75a8..41ceb3f52 100644 --- a/bindings/matrix-sdk-ffi/src/sliding_sync.rs +++ b/bindings/matrix-sdk-ffi/src/sliding_sync.rs @@ -153,6 +153,7 @@ pub struct UpdateSummary { pub views: Vec, pub rooms: Vec, } + pub struct RequiredState { pub key: String, pub value: String, @@ -240,7 +241,6 @@ impl From<&MatrixRoomEntry> for RoomListEntry { } } } - pub trait SlidingSyncViewRoomItemsObserver: Sync + Send { fn did_receive_update(&self); } @@ -272,6 +272,12 @@ impl SlidingSyncViewBuilder { Arc::new(builder) } + pub fn sort(self: Arc, sort: Vec) -> Arc { + let mut builder = unwrap_or_clone_arc(self); + builder.inner = builder.inner.sort(sort); + Arc::new(builder) + } + pub fn required_state(self: Arc, required_state: Vec) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.inner = builder @@ -280,26 +286,6 @@ impl SlidingSyncViewBuilder { Arc::new(builder) } - pub fn ranges(self: Arc, ranges: Vec<(u32, u32)>) -> Arc { - let mut builder = unwrap_or_clone_arc(self); - builder.inner = builder.inner.ranges(ranges); - Arc::new(builder) - } - - pub fn build(self: Arc) -> anyhow::Result> { - let builder = unwrap_or_clone_arc(self); - Ok(Arc::new(builder.inner.build()?.into())) - } -} - -#[uniffi::export] -impl SlidingSyncViewBuilder { - pub fn sort(self: Arc, sort: Vec) -> Arc { - let mut builder = unwrap_or_clone_arc(self); - builder.inner = builder.inner.sort(sort); - Arc::new(builder) - } - pub fn batch_size(self: Arc, batch_size: u32) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.inner = builder.inner.batch_size(batch_size); @@ -324,6 +310,12 @@ impl SlidingSyncViewBuilder { Arc::new(builder) } + pub fn ranges(self: Arc, ranges: Vec<(u32, u32)>) -> Arc { + let mut builder = unwrap_or_clone_arc(self); + builder.inner = builder.inner.ranges(ranges); + Arc::new(builder) + } + pub fn add_range(self: Arc, from: u32, to: u32) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.inner = builder.inner.add_range(from, to); @@ -335,6 +327,11 @@ impl SlidingSyncViewBuilder { builder.inner = builder.inner.reset_ranges(); Arc::new(builder) } + + pub fn build(self: Arc) -> anyhow::Result> { + let builder = unwrap_or_clone_arc(self); + Ok(Arc::new(builder.inner.build()?.into())) + } } #[derive(Clone)] @@ -572,14 +569,6 @@ impl SlidingSyncBuilder { Ok(Arc::new(builder)) } - pub fn build(self: Arc) -> anyhow::Result> { - let builder = unwrap_or_clone_arc(self); - Ok(Arc::new(SlidingSync::new(builder.inner.build()?, builder.client))) - } -} - -#[uniffi::export] -impl SlidingSyncBuilder { pub fn add_fullsync_view(self: Arc) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.inner = builder.inner.add_fullsync_view(); @@ -604,6 +593,11 @@ impl SlidingSyncBuilder { builder.inner = builder.inner.with_common_extensions(); Arc::new(builder) } + + pub fn build(self: Arc) -> anyhow::Result> { + let builder = unwrap_or_clone_arc(self); + Ok(Arc::new(SlidingSync::new(builder.inner.build()?, builder.client))) + } } impl Client { diff --git a/bindings/matrix-sdk-ffi/src/timeline.rs b/bindings/matrix-sdk-ffi/src/timeline.rs index f52221245..fe38333b9 100644 --- a/bindings/matrix-sdk-ffi/src/timeline.rs +++ b/bindings/matrix-sdk-ffi/src/timeline.rs @@ -45,6 +45,19 @@ impl TimelineDiff { }) } + pub fn change(&self) -> TimelineChange { + match &self.0 { + VecDiff::Replace { .. } => TimelineChange::Replace, + VecDiff::InsertAt { .. } => TimelineChange::InsertAt, + VecDiff::UpdateAt { .. } => TimelineChange::UpdateAt, + VecDiff::RemoveAt { .. } => TimelineChange::RemoveAt, + VecDiff::Move { .. } => TimelineChange::Move, + VecDiff::Push { .. } => TimelineChange::Push, + VecDiff::Pop {} => TimelineChange::Pop, + VecDiff::Clear {} => TimelineChange::Clear, + } + } + pub fn replace(self: Arc) -> Option>> { unwrap_or_clone_arc_into_variant!(self, .0, VecDiff::Replace { values } => values) } @@ -83,22 +96,6 @@ impl TimelineDiff { } } -#[uniffi::export] -impl TimelineDiff { - pub fn change(&self) -> TimelineChange { - match &self.0 { - VecDiff::Replace { .. } => TimelineChange::Replace, - VecDiff::InsertAt { .. } => TimelineChange::InsertAt, - VecDiff::UpdateAt { .. } => TimelineChange::UpdateAt, - VecDiff::RemoveAt { .. } => TimelineChange::RemoveAt, - VecDiff::Move { .. } => TimelineChange::Move, - VecDiff::Push { .. } => TimelineChange::Push, - VecDiff::Pop {} => TimelineChange::Pop, - VecDiff::Clear {} => TimelineChange::Clear, - } - } -} - pub struct InsertAtData { pub index: u32, pub item: Arc, @@ -114,7 +111,7 @@ pub struct MoveData { pub new_index: u32, } -#[derive(Clone, Copy, uniffi::Enum)] +#[derive(Clone, Copy)] pub enum TimelineChange { Replace, InsertAt, @@ -162,6 +159,10 @@ impl TimelineItem { pub struct EventTimelineItem(pub(crate) matrix_sdk::room::timeline::EventTimelineItem); impl EventTimelineItem { + pub fn key(&self) -> TimelineKey { + self.0.key().into() + } + pub fn reactions(&self) -> Vec { self.0 .reactions() @@ -173,10 +174,6 @@ impl EventTimelineItem { #[uniffi::export] impl EventTimelineItem { - pub fn key(&self) -> TimelineKey { - self.0.key().into() - } - pub fn event_id(&self) -> Option { self.0.event_id().map(ToString::to_string) } @@ -385,7 +382,7 @@ pub struct ReactionDetails { pub sender: String, } -#[derive(Clone, uniffi::Enum)] +#[derive(Clone)] pub enum TimelineKey { TransactionId { txn_id: String }, EventId { event_id: String }, @@ -402,7 +399,7 @@ impl From<&matrix_sdk::room::timeline::TimelineKey> for TimelineKey { } } -#[derive(Clone, uniffi::Object)] +#[derive(Clone)] pub struct VirtualTimelineItem(matrix_sdk::room::timeline::VirtualTimelineItem); #[extension_trait] From 717f86332fc31119046bed0ec53516a3d392337a Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Mon, 31 Oct 2022 12:39:23 +0000 Subject: [PATCH 26/37] Disable keepalive to prevent hanging connections --- bindings/matrix-sdk-crypto-nodejs/download-lib.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/bindings/matrix-sdk-crypto-nodejs/download-lib.js b/bindings/matrix-sdk-crypto-nodejs/download-lib.js index ec7c157e3..58f73a479 100644 --- a/bindings/matrix-sdk-crypto-nodejs/download-lib.js +++ b/bindings/matrix-sdk-crypto-nodejs/download-lib.js @@ -1,3 +1,6 @@ + +const { Agent } = require('https'); +const { whyIsNodeStillRunning } = require('why-is-node-still-running'); const { DownloaderHelper } = require('node-downloader-helper'); const { version } = require("./package.json"); const { platform, arch } = process @@ -22,10 +25,17 @@ function download_lib(libname) { console.info(`Downloading lib ${libname} from ${url}`); const dl = new DownloaderHelper(url, __dirname, { override: true, + httpsRequestOptions: { + // Disable keepalive to prevent the process hanging open. + // https://github.com/matrix-org/matrix-rust-sdk/issues/1160 + agent: new Agent({ keepAlive: false }), + }, }); dl.on('end', () => console.info('Download Completed')); dl.on('error', (err) => console.info('Download Failed', err)); + dl.on('stateChanged', (err) => console.info('Download state', err)); + dl.on('timeout', (err) => console.info('Download timeout', err)); dl.on('progress', stats => { const progress = stats.progress.toFixed(1); const speed = byteHelper(stats.speed); @@ -35,7 +45,7 @@ function download_lib(libname) { // print every one second (`progress.throttled` can be used instead) const currentTime = new Date(); const elaspsedTime = currentTime - startTime; - if (elaspsedTime > 1000) { + if (elaspsedTime > 1000 || stats.progress === 100) { startTime = currentTime; console.info(`${speed}/s - ${progress}% [${downloaded}/${total}]`); } @@ -110,4 +120,4 @@ switch (platform) { break default: throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) -} +} \ No newline at end of file From 546dc9a6523026328e1f7386aca5c8bbc9334ea5 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Mon, 31 Oct 2022 13:04:05 +0000 Subject: [PATCH 27/37] Run CI against 19 --- .github/workflows/bindings_ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bindings_ci.yml b/.github/workflows/bindings_ci.yml index 235e62d77..128eeebac 100644 --- a/.github/workflows/bindings_ci.yml +++ b/.github/workflows/bindings_ci.yml @@ -92,7 +92,7 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest] - node-version: [14.0, 16.0, 18.0] + node-version: [14.0, 16.0, 18.0, 19.0] include: - os: ubuntu-latest os-name: 🐧 From c009f54ba9f4b4cc99f3e64287ba97a67321f6b5 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Mon, 31 Oct 2022 13:17:48 +0000 Subject: [PATCH 28/37] Tidy --- bindings/matrix-sdk-crypto-nodejs/download-lib.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/bindings/matrix-sdk-crypto-nodejs/download-lib.js b/bindings/matrix-sdk-crypto-nodejs/download-lib.js index 58f73a479..e6ea74935 100644 --- a/bindings/matrix-sdk-crypto-nodejs/download-lib.js +++ b/bindings/matrix-sdk-crypto-nodejs/download-lib.js @@ -1,6 +1,5 @@ const { Agent } = require('https'); -const { whyIsNodeStillRunning } = require('why-is-node-still-running'); const { DownloaderHelper } = require('node-downloader-helper'); const { version } = require("./package.json"); const { platform, arch } = process @@ -34,8 +33,6 @@ function download_lib(libname) { dl.on('end', () => console.info('Download Completed')); dl.on('error', (err) => console.info('Download Failed', err)); - dl.on('stateChanged', (err) => console.info('Download state', err)); - dl.on('timeout', (err) => console.info('Download timeout', err)); dl.on('progress', stats => { const progress = stats.progress.toFixed(1); const speed = byteHelper(stats.speed); @@ -45,7 +42,7 @@ function download_lib(libname) { // print every one second (`progress.throttled` can be used instead) const currentTime = new Date(); const elaspsedTime = currentTime - startTime; - if (elaspsedTime > 1000 || stats.progress === 100) { + if (elaspsedTime > 1000) { startTime = currentTime; console.info(`${speed}/s - ${progress}% [${downloaded}/${total}]`); } @@ -120,4 +117,4 @@ switch (platform) { break default: throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) -} \ No newline at end of file +} From f4f3ca4b25d2b0d6e86a3a120a7e90c9f7766eaf Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Mon, 31 Oct 2022 13:18:16 +0000 Subject: [PATCH 29/37] A newline --- bindings/matrix-sdk-crypto-nodejs/download-lib.js | 1 - 1 file changed, 1 deletion(-) diff --git a/bindings/matrix-sdk-crypto-nodejs/download-lib.js b/bindings/matrix-sdk-crypto-nodejs/download-lib.js index e6ea74935..d0aec7d78 100644 --- a/bindings/matrix-sdk-crypto-nodejs/download-lib.js +++ b/bindings/matrix-sdk-crypto-nodejs/download-lib.js @@ -1,4 +1,3 @@ - const { Agent } = require('https'); const { DownloaderHelper } = require('node-downloader-helper'); const { version } = require("./package.json"); From 9c489b398dfe6ea50c9899fd78978057dad7a237 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Tue, 1 Nov 2022 08:06:14 +0100 Subject: [PATCH 30/37] chore: Upgrade clap dependency of xtask --- Cargo.lock | 16 ++++++++-------- xtask/Cargo.toml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2587e13ef..ab5df05c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -678,13 +678,13 @@ dependencies = [ [[package]] name = "clap" -version = "4.0.16" +version = "4.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ef582e2c00a63a0c0aa1fb4a4870781c4f5729f51196d3537fa7c1c1992eaa3" +checksum = "335867764ed2de42325fafe6d18b8af74ba97ee0c590fa016f157535b42ab04b" dependencies = [ "atty", "bitflags", - "clap_derive 4.0.13", + "clap_derive 4.0.18", "clap_lex 0.3.0", "once_cell", "strsim 0.10.0", @@ -706,9 +706,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.0.13" +version = "4.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f169caba89a7d512b5418b09864543eeb4d497416c917d7137863bd2076ad" +checksum = "16a1b0f6422af32d5da0c58e2703320f379216ee70198241c84173a8c5ac28f3" dependencies = [ "heck 0.4.0", "proc-macro-error", @@ -1442,7 +1442,7 @@ name = "example-emoji-verification" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.0.16", + "clap 4.0.18", "futures", "matrix-sdk", "tokio", @@ -1500,7 +1500,7 @@ name = "example-timeline" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.0.16", + "clap 4.0.18", "futures", "futures-signals", "matrix-sdk", @@ -5537,7 +5537,7 @@ name = "xtask" version = "0.1.0" dependencies = [ "camino", - "clap 3.2.22", + "clap 4.0.18", "serde", "serde_json", "uniffi_bindgen", diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 2ebac234c..1a2065f8c 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -10,7 +10,7 @@ test = false [dependencies] camino = "1.0.8" -clap = { version = "3.2.4", features = ["derive"] } +clap = { version = "4.0.18", features = ["derive"] } serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.79" uniffi_bindgen = { workspace = true } From 36444cd3a055da60b2064f4cd1f0e8ffe8c364ab Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Tue, 1 Nov 2022 08:06:44 +0100 Subject: [PATCH 31/37] chore: Clean up TOML formatting --- labs/jack-in/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/labs/jack-in/Cargo.toml b/labs/jack-in/Cargo.toml index 47a5acb98..05ab5c49b 100644 --- a/labs/jack-in/Cargo.toml +++ b/labs/jack-in/Cargo.toml @@ -22,10 +22,10 @@ serde_json = "1.0.85" structopt = "0.3" tokio = { version = "1", features = ["rt-multi-thread", "sync", "macros"] } tracing-flame = "0.2" -tracing-subscriber = "0.3.15" +tracing-subscriber = "0.3.15" tui-logger = "0.8.0" tuirealm = "~1.7.1" # file-logging specials tracing = { version = "0.1.35", features = ["log"] } -log4rs = { version = " 1.1.1", default-features = false, features = ["file_appender"], optional = true } +log4rs = { version = "1.1.1", default-features = false, features = ["file_appender"], optional = true } From f227f583e092f9632c34d32885ad3715785f021b Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Tue, 1 Nov 2022 08:26:54 +0100 Subject: [PATCH 32/37] chore: Upgrade ruma-client-api --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab5df05c0..a83c1e53f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3862,9 +3862,9 @@ dependencies = [ [[package]] name = "ruma-client-api" -version = "0.15.1" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bcfd3a3853ffdd151fc228441dd9c9e3d835ac85560dface7abda50b3888791" +checksum = "d1e72bc731b4dc8b569aa83915f13e419144b67110d858c65bb74aa05e2dc4b7" dependencies = [ "assign", "bytes", @@ -3879,9 +3879,9 @@ dependencies = [ [[package]] name = "ruma-common" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e629a01f359234798531a99ba83997abd4c15a65b5bcb8354c4171b59c25be" +checksum = "716889595f4edc3cfeb94d9f122e413f73e37d7d80ea1c14196e1004241a3889" dependencies = [ "base64", "bytes", @@ -3932,9 +3932,9 @@ dependencies = [ [[package]] name = "ruma-macros" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7cd8cf8771aaca36042fb7659f4647b05e74a2058d843474dde5e51a56cd85" +checksum = "0f82e91eb61cd86d9287303133ee55b54618eccb75a522cc22a42c15f5bda340" dependencies = [ "once_cell", "proc-macro-crate", From 726e4b9aa01245feaa983a05988408aaf844fef7 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Mon, 24 Oct 2022 16:15:15 +0200 Subject: [PATCH 33/37] fix(appservice): Fix nesting of AppServiceRouter in axum::Router --- crates/matrix-sdk-appservice/src/webserver.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/matrix-sdk-appservice/src/webserver.rs b/crates/matrix-sdk-appservice/src/webserver.rs index a021745fd..d14d19280 100644 --- a/crates/matrix-sdk-appservice/src/webserver.rs +++ b/crates/matrix-sdk-appservice/src/webserver.rs @@ -102,7 +102,12 @@ where self.0.poll_ready(cx) } - fn call(&mut self, req: http::Request) -> Self::Future { + fn call(&mut self, mut req: http::Request) -> Self::Future { + // When the AppServiceRouter is nested inside another axum Router under + // a path that includes path parameters, those should not be received by + // the Path extractor used inside the `handlers` module. + req.extensions_mut().clear(); + AppServiceRouteFuture(self.0.call(req)) } } From 2b4f4b17c3c1c7b620adff5ab744441ac657a239 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 2 Nov 2022 08:59:21 +0100 Subject: [PATCH 34/37] chore: Update `wasm-bindgen`'s ecosystem to latest versions. --- Cargo.lock | 52 +++++++++++++++--------- bindings/matrix-sdk-crypto-js/Cargo.toml | 4 +- crates/matrix-sdk-base/Cargo.toml | 2 +- crates/matrix-sdk-common/Cargo.toml | 4 +- crates/matrix-sdk/Cargo.toml | 2 +- examples/wasm_command_bot/Cargo.toml | 6 +-- testing/matrix-sdk-test/Cargo.toml | 2 +- 7 files changed, 42 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a83c1e53f..b1bbf972e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1826,6 +1826,19 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +[[package]] +name = "gloo-utils" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40913a05c8297adca04392f707b1e73b12ba7b8eab7244a4961580b1fd34063c" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "goblin" version = "0.5.4" @@ -2284,9 +2297,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.59" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] @@ -2712,6 +2725,7 @@ dependencies = [ "dashmap", "derive_builder", "getrandom 0.2.7", + "gloo-utils", "indexed_db_futures 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "indexed_db_futures 0.2.3 (git+https://github.com/Hywan/rust-indexed-db?branch=feat-factory-nodejs)", "js-sys", @@ -5224,21 +5238,19 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", - "serde", - "serde_json", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", "log", @@ -5251,9 +5263,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" dependencies = [ "cfg-if", "js-sys", @@ -5263,9 +5275,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5273,9 +5285,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -5286,15 +5298,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "wasm-bindgen-test" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "513df541345bb9fcc07417775f3d51bbb677daf307d8035c0afafd87dc2e6599" +checksum = "09d2fff962180c3fadf677438054b1db62bee4aa32af26a45388af07d1287e1d" dependencies = [ "console_error_panic_hook", "js-sys", @@ -5306,9 +5318,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6150d36a03e90a3cf6c12650be10626a9902d70c5270fd47d7a47e5389a10d56" +checksum = "4683da3dfc016f704c9f82cf401520c4f1cb3ee440f7f52b3d6ac29506a49ca7" dependencies = [ "proc-macro2", "quote", diff --git a/bindings/matrix-sdk-crypto-js/Cargo.toml b/bindings/matrix-sdk-crypto-js/Cargo.toml index 17b62cd99..c17a6d9be 100644 --- a/bindings/matrix-sdk-crypto-js/Cargo.toml +++ b/bindings/matrix-sdk-crypto-js/Cargo.toml @@ -33,8 +33,8 @@ matrix-sdk-indexeddb = { version = "0.2.0", path = "../../crates/matrix-sdk-inde matrix-sdk-qrcode = { version = "0.4.0", path = "../../crates/matrix-sdk-qrcode", optional = true } ruma = { workspace = true, features = ["js", "rand", "unstable-msc2676", "unstable-msc2677"] } vodozemac = { workspace = true, features = ["js"] } -wasm-bindgen = "0.2.80" -wasm-bindgen-futures = "0.4.30" +wasm-bindgen = "0.2.83" +wasm-bindgen-futures = "0.4.33" js-sys = "0.3.49" console_error_panic_hook = "0.1.7" serde_json = "1.0.79" diff --git a/crates/matrix-sdk-base/Cargo.toml b/crates/matrix-sdk-base/Cargo.toml index 2b9df17a2..7836c1993 100644 --- a/crates/matrix-sdk-base/Cargo.toml +++ b/crates/matrix-sdk-base/Cargo.toml @@ -58,4 +58,4 @@ tracing-subscriber = { version = "0.3.11", features = ["env-filter"] } tokio = { version = "1.17.0", default-features = false, features = ["rt-multi-thread", "macros"] } [target.'cfg(target_arch = "wasm32")'.dev-dependencies] -wasm-bindgen-test = "0.3.30" +wasm-bindgen-test = "0.3.33" diff --git a/crates/matrix-sdk-common/Cargo.toml b/crates/matrix-sdk-common/Cargo.toml index 678a2e110..fabb6b406 100644 --- a/crates/matrix-sdk-common/Cargo.toml +++ b/crates/matrix-sdk-common/Cargo.toml @@ -27,7 +27,7 @@ serde = "1.0.136" [target.'cfg(target_arch = "wasm32")'.dependencies] async-lock = "2.5.0" futures-util = { version = "0.3.21", default-features = false, features = ["channel"] } -wasm-bindgen-futures = { version = "0.4.30", optional = true } +wasm-bindgen-futures = { version = "0.4.33", optional = true } wasm-timer = "0.2.5" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] @@ -35,4 +35,4 @@ tokio = { version = "1.17.0", default-features = false, features = ["rt", "sync" [dev-dependencies] matrix-sdk-test = { path = "../../testing/matrix-sdk-test/", version= "0.6.0"} -wasm-bindgen-test = "0.3.30" +wasm-bindgen-test = "0.3.33" diff --git a/crates/matrix-sdk/Cargo.toml b/crates/matrix-sdk/Cargo.toml index 86ea8b5bb..ba0f77787 100644 --- a/crates/matrix-sdk/Cargo.toml +++ b/crates/matrix-sdk/Cargo.toml @@ -133,7 +133,7 @@ tracing-subscriber = { version = "0.3.11", features = ["env-filter"] } [target.'cfg(target_arch = "wasm32")'.dev-dependencies] getrandom = { version = "0.2.6", default-features = false, features = ["js"] } -wasm-bindgen-test = "0.3.30" +wasm-bindgen-test = "0.3.33" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] ctor = "0.1.23" diff --git a/examples/wasm_command_bot/Cargo.toml b/examples/wasm_command_bot/Cargo.toml index d2e2bb057..42c3c634b 100644 --- a/examples/wasm_command_bot/Cargo.toml +++ b/examples/wasm_command_bot/Cargo.toml @@ -13,8 +13,8 @@ test = false [dependencies] url = "2.2.2" -wasm-bindgen = { version = "0.2.74", features = ["serde-serialize"] } -wasm-bindgen-futures = "0.4.24" +wasm-bindgen = { version = "0.2.83" } +wasm-bindgen-futures = "0.4.33" console_error_panic_hook = "0.1.6" web-sys = { version = "0.3.51", features = ["console"] } @@ -25,4 +25,4 @@ default-features = false features = ["js", "native-tls", "e2e-encryption", "indexeddb"] [dev-dependencies] -wasm-bindgen-test = "0.3.29" +wasm-bindgen-test = "0.3.33" diff --git a/testing/matrix-sdk-test/Cargo.toml b/testing/matrix-sdk-test/Cargo.toml index 1719d2b8c..07677ed57 100644 --- a/testing/matrix-sdk-test/Cargo.toml +++ b/testing/matrix-sdk-test/Cargo.toml @@ -30,4 +30,4 @@ serde_json = "1.0.79" tokio = { version = "1.17.0", default-features = false, features = ["rt", "macros"] } [target.'cfg(target_arch = "wasm32")'.dependencies] -wasm-bindgen-test = "0.3.30" +wasm-bindgen-test = "0.3.33" From da93cf7dc4a026d037ea9d70198b465a96d4d64a Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 2 Nov 2022 08:59:37 +0100 Subject: [PATCH 35/37] fix(indexeddb): Fix `wasm_bindgen::JsValue::(from|to)_serde` warnings. `wasm_bindgen::JsValue::(from|to)_serde` now emit warnings because of a circular dependency. To solve this problem, this patch now uses `gloo-utils`, see https://rustwasm.github.io/wasm-bindgen/reference/arbitrary-data-with-serde.html#an-alternative-approach---using-json. Ideally, we would like to use `serde_wasm_bindgen` but the behaviour isn't the same. `gloo-utils` serializes and deserialized through JSON, whilst `serde_wasm_bindgen` manipulates the `JsValue` directly which can be better or worst dependending of the case. This patch conserves the JSON approach as it was the previous and tested one. --- crates/matrix-sdk-indexeddb/Cargo.toml | 5 +++-- crates/matrix-sdk-indexeddb/src/crypto_store.rs | 1 + crates/matrix-sdk-indexeddb/src/state_store.rs | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/matrix-sdk-indexeddb/Cargo.toml b/crates/matrix-sdk-indexeddb/Cargo.toml index 4b796b6b4..09af3fac1 100644 --- a/crates/matrix-sdk-indexeddb/Cargo.toml +++ b/crates/matrix-sdk-indexeddb/Cargo.toml @@ -35,7 +35,8 @@ serde = "1.0.136" serde_json = "1.0.79" thiserror = "1.0.30" tracing = { workspace = true } -wasm-bindgen = { version = "0.2.80", features = ["serde-serialize"] } +wasm-bindgen = "0.2.83" +gloo-utils = { version = "0.1", features = ["serde"] } web-sys = { version = "0.3.57", features = ["IdbKeyRange"] } [target.'cfg(target_arch = "wasm32")'.dependencies] @@ -48,4 +49,4 @@ matrix-sdk-common = { path = "../matrix-sdk-common", features = ["js"] } matrix-sdk-crypto = { path = "../matrix-sdk-crypto", features = ["js", "testing"] } matrix-sdk-test = { path = "../../testing/matrix-sdk-test" } uuid = "1.0.0" -wasm-bindgen-test = "0.3.30" +wasm-bindgen-test = "0.3.33" diff --git a/crates/matrix-sdk-indexeddb/src/crypto_store.rs b/crates/matrix-sdk-indexeddb/src/crypto_store.rs index b0d469359..fbd0caf58 100644 --- a/crates/matrix-sdk-indexeddb/src/crypto_store.rs +++ b/crates/matrix-sdk-indexeddb/src/crypto_store.rs @@ -19,6 +19,7 @@ use std::{ use async_trait::async_trait; use dashmap::DashSet; +use gloo_utils::format::JsValueSerdeExt; use matrix_sdk_base::locks::Mutex; use matrix_sdk_crypto::{ olm::{ diff --git a/crates/matrix-sdk-indexeddb/src/state_store.rs b/crates/matrix-sdk-indexeddb/src/state_store.rs index 62a8890d0..e2b610c1e 100644 --- a/crates/matrix-sdk-indexeddb/src/state_store.rs +++ b/crates/matrix-sdk-indexeddb/src/state_store.rs @@ -23,6 +23,7 @@ use std::{ use anyhow::anyhow; use async_trait::async_trait; use derive_builder::Builder; +use gloo_utils::format::JsValueSerdeExt; use js_sys::Date as JsDate; use matrix_sdk_base::{ deserialized_responses::MemberEvent, From a6ca114bac0afa7e207dca7454ee561e43b6ee22 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 2 Nov 2022 14:02:59 +0100 Subject: [PATCH 36/37] chore: Upgrade UniFFI --- .github/workflows/bindings_ci.yml | 2 +- Cargo.lock | 12 ++++++------ Cargo.toml | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/bindings_ci.yml b/.github/workflows/bindings_ci.yml index 128eeebac..8698e81bb 100644 --- a/.github/workflows/bindings_ci.yml +++ b/.github/workflows/bindings_ci.yml @@ -17,7 +17,7 @@ env: MATRIX_SDK_CRYPTO_NODEJS_PATH: bindings/matrix-sdk-crypto-nodejs MATRIX_SDK_CRYPTO_JS_PATH: bindings/matrix-sdk-crypto-js # keep in sync with uniffi dependency in root Cargo.toml - UNIFFI_REV: 89b9dd835b470abb339b1bd492c19f7a08ad872f + UNIFFI_REV: 6ee61a46f59736f93b912f3cf45481f005c63115 jobs: xtask-linux: diff --git a/Cargo.lock b/Cargo.lock index a83c1e53f..3f1ece921 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4999,7 +4999,7 @@ checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" [[package]] name = "uniffi" version = "0.21.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=89b9dd835b470abb339b1bd492c19f7a08ad872f#89b9dd835b470abb339b1bd492c19f7a08ad872f" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6ee61a46f59736f93b912f3cf45481f005c63115#6ee61a46f59736f93b912f3cf45481f005c63115" dependencies = [ "anyhow", "bytes", @@ -5015,7 +5015,7 @@ dependencies = [ [[package]] name = "uniffi_bindgen" version = "0.21.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=89b9dd835b470abb339b1bd492c19f7a08ad872f#89b9dd835b470abb339b1bd492c19f7a08ad872f" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6ee61a46f59736f93b912f3cf45481f005c63115#6ee61a46f59736f93b912f3cf45481f005c63115" dependencies = [ "anyhow", "askama", @@ -5037,7 +5037,7 @@ dependencies = [ [[package]] name = "uniffi_build" version = "0.21.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=89b9dd835b470abb339b1bd492c19f7a08ad872f#89b9dd835b470abb339b1bd492c19f7a08ad872f" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6ee61a46f59736f93b912f3cf45481f005c63115#6ee61a46f59736f93b912f3cf45481f005c63115" dependencies = [ "anyhow", "camino", @@ -5047,7 +5047,7 @@ dependencies = [ [[package]] name = "uniffi_macros" version = "0.21.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=89b9dd835b470abb339b1bd492c19f7a08ad872f#89b9dd835b470abb339b1bd492c19f7a08ad872f" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6ee61a46f59736f93b912f3cf45481f005c63115#6ee61a46f59736f93b912f3cf45481f005c63115" dependencies = [ "bincode", "camino", @@ -5065,7 +5065,7 @@ dependencies = [ [[package]] name = "uniffi_meta" version = "0.21.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=89b9dd835b470abb339b1bd492c19f7a08ad872f#89b9dd835b470abb339b1bd492c19f7a08ad872f" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6ee61a46f59736f93b912f3cf45481f005c63115#6ee61a46f59736f93b912f3cf45481f005c63115" dependencies = [ "serde", ] @@ -5374,7 +5374,7 @@ dependencies = [ [[package]] name = "weedle2" version = "4.0.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=89b9dd835b470abb339b1bd492c19f7a08ad872f#89b9dd835b470abb339b1bd492c19f7a08ad872f" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6ee61a46f59736f93b912f3cf45481f005c63115#6ee61a46f59736f93b912f3cf45481f005c63115" dependencies = [ "nom", ] diff --git a/Cargo.toml b/Cargo.toml index 225be9866..d0a218884 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,10 +18,10 @@ resolver = "2" [workspace.dependencies] ruma = { version = "0.7.4", features = ["client-api-c"] } tracing = { version = "0.1.36", default-features = false, features = ["std"] } -uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "89b9dd835b470abb339b1bd492c19f7a08ad872f" } -uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "89b9dd835b470abb339b1bd492c19f7a08ad872f" } -uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs", rev = "89b9dd835b470abb339b1bd492c19f7a08ad872f" } -uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "89b9dd835b470abb339b1bd492c19f7a08ad872f", features = ["builtin-bindgen"] } +uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "6ee61a46f59736f93b912f3cf45481f005c63115" } +uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "6ee61a46f59736f93b912f3cf45481f005c63115" } +uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs", rev = "6ee61a46f59736f93b912f3cf45481f005c63115" } +uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "6ee61a46f59736f93b912f3cf45481f005c63115", features = ["builtin-bindgen"] } vodozemac = "0.3.0" zeroize = "1.3.0" From 4cd8a8400f97073e20fe0ef606b46e6ff09c9d07 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 2 Nov 2022 16:38:01 +0100 Subject: [PATCH 37/37] chore: Reorder dep names. --- crates/matrix-sdk-indexeddb/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/matrix-sdk-indexeddb/Cargo.toml b/crates/matrix-sdk-indexeddb/Cargo.toml index 09af3fac1..5b0ef4f4b 100644 --- a/crates/matrix-sdk-indexeddb/Cargo.toml +++ b/crates/matrix-sdk-indexeddb/Cargo.toml @@ -24,19 +24,19 @@ async-trait = "0.1.53" base64 = "0.13.0" dashmap = { version = "5.2.0", optional = true } derive_builder = "0.11.2" +gloo-utils = { version = "0.1", features = ["serde"] } +indexed_db_futures = "0.2.3" +indexed_db_futures_nodejs = { version = "0.2.3", package = "indexed_db_futures", git = "https://github.com/Hywan/rust-indexed-db", branch = "feat-factory-nodejs", optional = true } js-sys = { version = "0.3.58" } matrix-sdk-base = { version = "0.6.0", path = "../matrix-sdk-base", features = ["js"] } matrix-sdk-crypto = { version = "0.6.0", path = "../matrix-sdk-crypto", features = ["js"], optional = true } matrix-sdk-store-encryption = { version = "0.2.0", path = "../matrix-sdk-store-encryption" } -indexed_db_futures = "0.2.3" -indexed_db_futures_nodejs = { version = "0.2.3", package = "indexed_db_futures", git = "https://github.com/Hywan/rust-indexed-db", branch = "feat-factory-nodejs", optional = true } ruma = { workspace = true } serde = "1.0.136" serde_json = "1.0.79" thiserror = "1.0.30" tracing = { workspace = true } wasm-bindgen = "0.2.83" -gloo-utils = { version = "0.1", features = ["serde"] } web-sys = { version = "0.3.57", features = ["IdbKeyRange"] } [target.'cfg(target_arch = "wasm32")'.dependencies]