Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions crates/matrix-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file.

### Features

- `Room::enable_encryption` and `Room::enable_encryption_with_state_event_encryption` will poll
the encryption state for up to 3 seconds, rather than checking once after a single sync has
completed.
([#5559](https://github.com/matrix-org/matrix-rust-sdk/pull/5559))
- Add `Room::enable_encryption_with_state` to enable E2E encryption with encrypted state event
support, gated behind the `experimental-encrypted-state-events` feature.
([#5557](https://github.com/matrix-org/matrix-rust-sdk/pull/5557))
Expand Down
48 changes: 33 additions & 15 deletions crates/matrix-sdk/src/room/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1908,29 +1908,47 @@ impl Room {
}
self.send_state_event(content).await?;

// Spin on the sync beat event, since the first sync we receive might not
// include the encryption event.
//
// TODO do we want to return an error here if we time out? This
// could be quite useful if someone wants to enable encryption and
// send a message right after it's enabled.
_ = timeout(self.client.inner.sync_beat.listen(), SYNC_WAIT_TIME).await;
let res = timeout(
async {
loop {
// Listen for sync events, then check if the encryption state has been set.
self.client.inner.sync_beat.listen().await;
let _sync_lock = self.client.base_client().sync_lock().lock().await;
if self.inner.encryption_state().is_encrypted() {
break;
}
}
},
SYNC_WAIT_TIME,
)
.await;

// If encryption was enabled, return.
if res.is_ok() {
debug!("room successfully marked as encrypted");
return Ok(());
}

// If after waiting for a sync, we don't have the encryption state we expect,
// assume the local encryption state is incorrect; this will cause
// the SDK to re-request it later for confirmation, instead of
// If after waiting for multiple syncs, we don't have the encryption state we
// expect, assume the local encryption state is incorrect; this will
// cause the SDK to re-request it later for confirmation, instead of
// assuming it's sync'd and correct (and not encrypted).
let _sync_lock = self.client.base_client().sync_lock().lock().await;
if !self.inner.encryption_state().is_encrypted() {
debug!("still not marked as encrypted, marking encryption state as missing");
debug!("still not marked as encrypted, marking encryption state as missing");

let mut room_info = self.clone_info();
room_info.mark_encryption_state_missing();
let mut changes = StateChanges::default();
changes.add_room(room_info.clone());
let mut room_info = self.clone_info();
room_info.mark_encryption_state_missing();
let mut changes = StateChanges::default();
changes.add_room(room_info.clone());

self.client.state_store().save_changes(&changes).await?;
self.set_room_info(room_info, RoomInfoNotableUpdateReasons::empty());
} else {
debug!("room successfully marked as encrypted");
}
self.client.state_store().save_changes(&changes).await?;
self.set_room_info(room_info, RoomInfoNotableUpdateReasons::empty());
}

Ok(())
Expand Down
Loading