Skip to content

Commit b5c854a

Browse files
committed
feat(base): Remember when a user explicitly accepted an invite
1 parent 7394b34 commit b5c854a

File tree

4 files changed

+54
-2
lines changed

4 files changed

+54
-2
lines changed

crates/matrix-sdk-base/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ All notable changes to this project will be documented in this file.
66

77
## [Unreleased] - ReleaseDate
88

9+
### Features
10+
- The `RoomInfo` now remembers when an invite was explicitly accepted when the
11+
`BaseClient::room_joined()` method was called. A new getter for this
12+
timestamp exists, the `RoomInfo::invite_accepted_at()` method returns this
13+
timestamp.
14+
([#5333](https://github.com/matrix-org/matrix-rust-sdk/pull/5333))
15+
916
### Refactor
1017

1118
- The cached `ServerCapabilities` has been renamed to `ServerInfo` and

crates/matrix-sdk-base/src/client.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,12 +434,30 @@ impl BaseClient {
434434
let _sync_lock = self.sync_lock().lock().await;
435435

436436
let mut room_info = room.clone_info();
437+
438+
// If our previous state was an invite and we're now in the joined state, this
439+
// means that the user has explicitly accepted the invite. Let's
440+
// remember when this has happened.
441+
//
442+
// This is somewhat of a workaround for our lack of cryptographic membership.
443+
// Later on we will decide if historic room keys should be accepted
444+
// based on this info. If a user has accepted an invite and we receive a room
445+
// key bundle shortly after, we might accept it. If we don't do
446+
// this, the homeserver could trick us into accepting any historic room key
447+
// bundle.
448+
if room.state() == RoomState::Invited {
449+
room_info.set_invite_accepted_now();
450+
}
451+
437452
room_info.mark_as_joined();
438453
room_info.mark_state_partially_synced();
439454
room_info.mark_members_missing(); // the own member event changed
455+
440456
let mut changes = StateChanges::default();
441457
changes.add_room(room_info.clone());
458+
442459
self.state_store.save_changes(&changes).await?; // Update the store
460+
443461
room.set_room_info(room_info, RoomInfoNotableUpdateReasons::MEMBERSHIP);
444462
}
445463

crates/matrix-sdk-base/src/room/room_info.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ use ruma::{
4646
},
4747
room::RoomType,
4848
serde::Raw,
49-
EventId, MxcUri, OwnedEventId, OwnedMxcUri, OwnedRoomAliasId, OwnedRoomId, OwnedUserId,
50-
RoomAliasId, RoomId, RoomVersionId, UserId,
49+
EventId, MilliSecondsSinceUnixEpoch, MxcUri, OwnedEventId, OwnedMxcUri, OwnedRoomAliasId,
50+
OwnedRoomId, OwnedUserId, RoomAliasId, RoomId, RoomVersionId, UserId,
5151
};
5252
use serde::{Deserialize, Serialize};
5353
use tracing::{debug, field::debug, info, instrument, warn};
@@ -464,6 +464,13 @@ pub struct RoomInfo {
464464
/// more accurate than relying on the latest event.
465465
#[serde(default)]
466466
pub(crate) recency_stamp: Option<u64>,
467+
468+
/// A timestamp remembering when we observed the user accepting an invite on
469+
/// this current device.
470+
///
471+
/// This is useful to remember if the user accepted this a join on using
472+
/// this specific client.
473+
pub(crate) invite_accepted_at: Option<MilliSecondsSinceUnixEpoch>,
467474
}
468475

469476
impl RoomInfo {
@@ -486,6 +493,7 @@ impl RoomInfo {
486493
cached_display_name: None,
487494
cached_user_defined_notification_mode: None,
488495
recency_stamp: None,
496+
invite_accepted_at: None,
489497
}
490498
}
491499

@@ -749,6 +757,22 @@ impl RoomInfo {
749757
self.summary.invited_member_count = count;
750758
}
751759

760+
/// Mark that the user has accepted an invite and remember when this has
761+
/// happened using a timestamp set to [`MilliSecondsSinceUnixEpoch::now()`].
762+
pub(crate) fn set_invite_accepted_now(&mut self) {
763+
self.invite_accepted_at = Some(MilliSecondsSinceUnixEpoch::now());
764+
}
765+
766+
/// Returns the timestamp when an invite to this room has been accepted by
767+
/// this specific client.
768+
///
769+
/// # Returns
770+
/// - `Some` if the invite has been accepted by this specific client.
771+
/// - `None` if the invite has not been accepted
772+
pub fn invite_accepted_at(&self) -> Option<MilliSecondsSinceUnixEpoch> {
773+
self.invite_accepted_at
774+
}
775+
752776
/// Updates the room heroes.
753777
pub(crate) fn update_heroes(&mut self, heroes: Vec<RoomHero>) {
754778
self.summary.room_heroes = heroes;
@@ -1221,6 +1245,7 @@ mod tests {
12211245
cached_display_name: None,
12221246
cached_user_defined_notification_mode: None,
12231247
recency_stamp: Some(42),
1248+
invite_accepted_at: None,
12241249
};
12251250

12261251
let info_json = json!({
@@ -1277,6 +1302,7 @@ mod tests {
12771302
"pending": []
12781303
},
12791304
"recency_stamp": 42,
1305+
"invite_accepted_at": null,
12801306
});
12811307

12821308
assert_eq!(serde_json::to_value(info).unwrap(), info_json);

crates/matrix-sdk-base/src/store/migration_helpers.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ impl RoomInfoV1 {
121121
cached_display_name: None,
122122
cached_user_defined_notification_mode: None,
123123
recency_stamp: None,
124+
invite_accepted_at: None,
124125
}
125126
}
126127
}

0 commit comments

Comments
 (0)