diff --git a/bindings/matrix-sdk-ffi/CHANGELOG.md b/bindings/matrix-sdk-ffi/CHANGELOG.md index 075c4c9ac..c00e9b08a 100644 --- a/bindings/matrix-sdk-ffi/CHANGELOG.md +++ b/bindings/matrix-sdk-ffi/CHANGELOG.md @@ -19,6 +19,8 @@ Breaking changes: Additions: +- Add `ClientBuilder::enable_share_history_on_invite` to enable experimental support for sharing encrypted room history on invite, per [MSC4268](https://github.com/matrix-org/matrix-spec-proposals/pull/4268). + ([#5141](https://github.com/matrix-org/matrix-rust-sdk/pull/5141)) - Support for adding a Sentry layer to the FFI bindings has been added. Only `tracing` statements with the field `sentry=true` will be forwarded to Sentry, in addition to default Sentry filters. - Add room topic string to `StateEventContent` diff --git a/bindings/matrix-sdk-ffi/src/client_builder.rs b/bindings/matrix-sdk-ffi/src/client_builder.rs index 929229876..e1a9282df 100644 --- a/bindings/matrix-sdk-ffi/src/client_builder.rs +++ b/bindings/matrix-sdk-ffi/src/client_builder.rs @@ -287,6 +287,7 @@ pub struct ClientBuilder { encryption_settings: EncryptionSettings, room_key_recipient_strategy: CollectStrategy, decryption_trust_requirement: TrustRequirement, + enable_share_history_on_invite: bool, request_config: Option, } @@ -321,6 +322,7 @@ impl ClientBuilder { }, room_key_recipient_strategy: Default::default(), decryption_trust_requirement: TrustRequirement::Untrusted, + enable_share_history_on_invite: false, request_config: Default::default(), }) } @@ -552,6 +554,19 @@ impl ClientBuilder { Arc::new(builder) } + /// Set whether to enable the experimental support for sending and receiving + /// encrypted room history on invite, per [MSC4268]. + /// + /// [MSC4268]: https://github.com/matrix-org/matrix-spec-proposals/pull/4268 + pub fn enable_share_history_on_invite( + self: Arc, + enable_share_history_on_invite: bool, + ) -> Arc { + let mut builder = unwrap_or_clone_arc(self); + builder.enable_share_history_on_invite = enable_share_history_on_invite; + Arc::new(builder) + } + /// Add a default request config to this client. pub fn request_config(self: Arc, config: RequestConfig) -> Arc { let mut builder = unwrap_or_clone_arc(self); @@ -680,7 +695,8 @@ impl ClientBuilder { inner_builder = inner_builder .with_encryption_settings(builder.encryption_settings) .with_room_key_recipient_strategy(builder.room_key_recipient_strategy) - .with_decryption_trust_requirement(builder.decryption_trust_requirement); + .with_decryption_trust_requirement(builder.decryption_trust_requirement) + .with_enable_share_history_on_invite(builder.enable_share_history_on_invite); match builder.sliding_sync_version_builder { SlidingSyncVersionBuilder::None => { diff --git a/crates/matrix-sdk/CHANGELOG.md b/crates/matrix-sdk/CHANGELOG.md index 0501e14df..8c54f4d10 100644 --- a/crates/matrix-sdk/CHANGELOG.md +++ b/crates/matrix-sdk/CHANGELOG.md @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. ### Features +- Add `ClientBuilder::with_enable_share_history_on_invite` to enable experimental support for sharing encrypted room history on invite, per [MSC4268](https://github.com/matrix-org/matrix-spec-proposals/pull/4268). + ([#5141](https://github.com/matrix-org/matrix-rust-sdk/pull/5141)) - `Room::list_threads()` is a new method to list all the threads in a room. ([#4972](https://github.com/matrix-org/matrix-rust-sdk/pull/4972)) - `Room::relations()` is a new method to list all the events related to another event diff --git a/crates/matrix-sdk/Cargo.toml b/crates/matrix-sdk/Cargo.toml index 223efd11a..80ca95085 100644 --- a/crates/matrix-sdk/Cargo.toml +++ b/crates/matrix-sdk/Cargo.toml @@ -58,7 +58,6 @@ uniffi = ["dep:uniffi", "matrix-sdk-base/uniffi", "dep:matrix-sdk-ffi-macros"] experimental-widgets = ["dep:uuid"] docsrs = ["e2e-encryption", "sqlite", "indexeddb", "sso-login", "qrcode"] -experimental-share-history-on-invite = [] # Add support for inline media galleries via msgtypes unstable-msc4274 = ["ruma/unstable-msc4274", "matrix-sdk-base/unstable-msc4274"] diff --git a/crates/matrix-sdk/src/client/builder/mod.rs b/crates/matrix-sdk/src/client/builder/mod.rs index f7e5aca48..dfcf30852 100644 --- a/crates/matrix-sdk/src/client/builder/mod.rs +++ b/crates/matrix-sdk/src/client/builder/mod.rs @@ -105,6 +105,8 @@ pub struct ClientBuilder { room_key_recipient_strategy: CollectStrategy, #[cfg(feature = "e2e-encryption")] decryption_trust_requirement: TrustRequirement, + #[cfg(feature = "e2e-encryption")] + enable_share_history_on_invite: bool, cross_process_store_locks_holder_name: String, } @@ -130,6 +132,8 @@ impl ClientBuilder { room_key_recipient_strategy: Default::default(), #[cfg(feature = "e2e-encryption")] decryption_trust_requirement: TrustRequirement::Untrusted, + #[cfg(feature = "e2e-encryption")] + enable_share_history_on_invite: false, cross_process_store_locks_holder_name: Self::DEFAULT_CROSS_PROCESS_STORE_LOCKS_HOLDER_NAME.to_owned(), } @@ -444,6 +448,19 @@ impl ClientBuilder { self } + /// Whether to enable the experimental support for sending and receiving + /// encrypted room history on invite, per [MSC4268]. + /// + /// [MSC4268]: https://github.com/matrix-org/matrix-spec-proposals/pull/4268 + #[cfg(feature = "e2e-encryption")] + pub fn with_enable_share_history_on_invite( + mut self, + enable_share_history_on_invite: bool, + ) -> Self { + self.enable_share_history_on_invite = enable_share_history_on_invite; + self + } + /// Set the cross-process store locks holder name. /// /// The SDK provides cross-process store locks (see @@ -562,6 +579,8 @@ impl ClientBuilder { send_queue, #[cfg(feature = "e2e-encryption")] self.encryption_settings, + #[cfg(feature = "e2e-encryption")] + self.enable_share_history_on_invite, self.cross_process_store_locks_holder_name, ) .await; diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index f5af8ec35..183c42c75 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -325,6 +325,13 @@ pub(crate) struct ClientInner { #[cfg(feature = "e2e-encryption")] pub(crate) verification_state: SharedObservable, + /// Whether to enable the experimental support for sending and receiving + /// encrypted room history on invite, per [MSC4268]. + /// + /// [MSC4268]: https://github.com/matrix-org/matrix-spec-proposals/pull/4268 + #[cfg(feature = "e2e-encryption")] + pub(crate) enable_share_history_on_invite: bool, + /// Data related to the [`SendQueue`]. /// /// [`SendQueue`]: crate::send_queue::SendQueue @@ -350,6 +357,7 @@ impl ClientInner { event_cache: OnceCell, send_queue: Arc, #[cfg(feature = "e2e-encryption")] encryption_settings: EncryptionSettings, + #[cfg(feature = "e2e-encryption")] enable_share_history_on_invite: bool, cross_process_store_locks_holder_name: String, ) -> Arc { let caches = ClientCaches { @@ -382,6 +390,8 @@ impl ClientInner { e2ee: EncryptionData::new(encryption_settings), #[cfg(feature = "e2e-encryption")] verification_state: SharedObservable::new(VerificationState::Unknown), + #[cfg(feature = "e2e-encryption")] + enable_share_history_on_invite, }; #[allow(clippy::let_and_return)] @@ -2493,6 +2503,8 @@ impl Client { self.inner.send_queue_data.clone(), #[cfg(feature = "e2e-encryption")] self.inner.e2ee.encryption_settings, + #[cfg(feature = "e2e-encryption")] + self.inner.enable_share_history_on_invite, cross_process_store_locks_holder_name, ) .await, diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 654a9868c..35787daf7 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -385,7 +385,6 @@ impl Room { )))); } - #[cfg(all(feature = "experimental-share-history-on-invite", feature = "e2e-encryption"))] let inviter = if prev_room_state == RoomState::Invited { match self.invite_details().await { Ok(details) => details.inviter, @@ -400,11 +399,17 @@ impl Room { self.client.join_room_by_id(self.room_id()).await?; - #[cfg(all(feature = "experimental-share-history-on-invite", feature = "e2e-encryption"))] - if let Some(inviter) = inviter { - shared_room_history::maybe_accept_key_bundle(self, inviter.user_id()).await?; + #[cfg(feature = "e2e-encryption")] + if self.client.inner.enable_share_history_on_invite { + if let Some(inviter) = inviter { + shared_room_history::maybe_accept_key_bundle(self, inviter.user_id()).await?; + } } + #[cfg(not(feature = "e2e-encryption"))] + // Suppress "unused variable" lint + let _inviter = inviter; + Ok(()) } @@ -1611,8 +1616,8 @@ impl Room { /// * `user_id` - The `UserId` of the user to invite to the room. #[instrument(skip_all)] pub async fn invite_user_by_id(&self, user_id: &UserId) -> Result<()> { - #[cfg(all(feature = "experimental-share-history-on-invite", feature = "e2e-encryption"))] - { + #[cfg(feature = "e2e-encryption")] + if self.client.inner.enable_share_history_on_invite { shared_room_history::share_room_history(self, user_id.to_owned()).await?; } diff --git a/labs/multiverse/Cargo.toml b/labs/multiverse/Cargo.toml index 41182f834..3db8a69eb 100644 --- a/labs/multiverse/Cargo.toml +++ b/labs/multiverse/Cargo.toml @@ -19,7 +19,7 @@ crossterm = "0.28.1" futures-util.workspace = true imbl.workspace = true itertools.workspace = true -matrix-sdk = { path = "../../crates/matrix-sdk", features = ["sso-login", "experimental-share-history-on-invite"] } +matrix-sdk = { path = "../../crates/matrix-sdk", features = ["sso-login"] } matrix-sdk-base = { path = "../../crates/matrix-sdk-base" } matrix-sdk-common = { path = "../../crates/matrix-sdk-common" } matrix-sdk-ui = { path = "../../crates/matrix-sdk-ui" } diff --git a/labs/multiverse/src/main.rs b/labs/multiverse/src/main.rs index dde64d145..9c49279f9 100644 --- a/labs/multiverse/src/main.rs +++ b/labs/multiverse/src/main.rs @@ -518,7 +518,8 @@ async fn configure_client(cli: Cli) -> Result { auto_enable_cross_signing: true, backup_download_strategy: BackupDownloadStrategy::AfterDecryptionFailure, auto_enable_backups: true, - }); + }) + .with_enable_share_history_on_invite(true); if let Some(proxy_url) = proxy { client_builder = client_builder.proxy(proxy_url).disable_ssl_verification(); diff --git a/testing/matrix-sdk-integration-testing/Cargo.toml b/testing/matrix-sdk-integration-testing/Cargo.toml index c6966cf5c..5d66f4af0 100644 --- a/testing/matrix-sdk-integration-testing/Cargo.toml +++ b/testing/matrix-sdk-integration-testing/Cargo.toml @@ -21,7 +21,7 @@ futures-core.workspace = true futures-util.workspace = true http.workspace = true json-structural-diff = "0.1.0" -matrix-sdk = { workspace = true, default-features = true, features = ["testing", "qrcode", "experimental-share-history-on-invite"] } +matrix-sdk = { workspace = true, default-features = true, features = ["testing", "qrcode"] } matrix-sdk-base = { workspace = true, default-features = true, features = ["testing", "qrcode"] } matrix-sdk-test.workspace = true matrix-sdk-ui = { workspace = true, default-features = true } diff --git a/testing/matrix-sdk-integration-testing/src/helpers.rs b/testing/matrix-sdk-integration-testing/src/helpers.rs index c564446de..83dc8ac33 100644 --- a/testing/matrix-sdk-integration-testing/src/helpers.rs +++ b/testing/matrix-sdk-integration-testing/src/helpers.rs @@ -40,6 +40,7 @@ pub struct TestClientBuilder { username: String, use_sqlite_dir: Option, encryption_settings: EncryptionSettings, + enable_share_history_on_invite: bool, http_proxy: Option, cross_process_store_locks_holder_name: Option, } @@ -56,6 +57,7 @@ impl TestClientBuilder { username, use_sqlite_dir: None, encryption_settings: Default::default(), + enable_share_history_on_invite: false, http_proxy: None, cross_process_store_locks_holder_name: None, } @@ -80,6 +82,11 @@ impl TestClientBuilder { self } + pub fn enable_share_history_on_invite(mut self, enable_share_history_on_invite: bool) -> Self { + self.enable_share_history_on_invite = enable_share_history_on_invite; + self + } + pub fn http_proxy(mut self, url: String) -> Self { self.http_proxy = Some(url); self @@ -99,6 +106,7 @@ impl TestClientBuilder { .homeserver_url(homeserver_url) .sliding_sync_version_builder(VersionBuilder::Native) .with_encryption_settings(self.encryption_settings) + .with_enable_share_history_on_invite(self.enable_share_history_on_invite) .request_config(RequestConfig::short_retry()); if let Some(holder_name) = &self.cross_process_store_locks_holder_name { diff --git a/testing/matrix-sdk-integration-testing/src/tests/e2ee/shared_history.rs b/testing/matrix-sdk-integration-testing/src/tests/e2ee/shared_history.rs index 1ff315e11..989a573b3 100644 --- a/testing/matrix-sdk-integration-testing/src/tests/e2ee/shared_history.rs +++ b/testing/matrix-sdk-integration-testing/src/tests/e2ee/shared_history.rs @@ -27,6 +27,7 @@ async fn test_history_share_on_invite() -> Result<()> { let alice = TestClientBuilder::new("alice") .use_sqlite() .encryption_settings(encryption_settings) + .enable_share_history_on_invite(true) .build() .await?; @@ -41,7 +42,11 @@ async fn test_history_share_on_invite() -> Result<()> { alice_sync_service.start().await; let bob = SyncTokenAwareClient::new( - TestClientBuilder::new("bob").encryption_settings(encryption_settings).build().await?, + TestClientBuilder::new("bob") + .encryption_settings(encryption_settings) + .enable_share_history_on_invite(true) + .build() + .await?, ); // Alice creates a room ...