mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-19 06:04:31 -04:00
feat(base): Remember when a user explicitly accepted an invite
This commit is contained in:
@@ -6,6 +6,13 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
## [Unreleased] - ReleaseDate
|
||||
|
||||
### Features
|
||||
- The `RoomInfo` now remembers when an invite was explicitly accepted when the
|
||||
`BaseClient::room_joined()` method was called. A new getter for this
|
||||
timestamp exists, the `RoomInfo::invite_accepted_at()` method returns this
|
||||
timestamp.
|
||||
([#5333](https://github.com/matrix-org/matrix-rust-sdk/pull/5333))
|
||||
|
||||
### Refactor
|
||||
|
||||
- The cached `ServerCapabilities` has been renamed to `ServerInfo` and
|
||||
|
||||
@@ -459,12 +459,30 @@ impl BaseClient {
|
||||
let _sync_lock = self.sync_lock().lock().await;
|
||||
|
||||
let mut room_info = room.clone_info();
|
||||
|
||||
// If our previous state was an invite and we're now in the joined state, this
|
||||
// means that the user has explicitly accepted the invite. Let's
|
||||
// remember when this has happened.
|
||||
//
|
||||
// This is somewhat of a workaround for our lack of cryptographic membership.
|
||||
// Later on we will decide if historic room keys should be accepted
|
||||
// based on this info. If a user has accepted an invite and we receive a room
|
||||
// key bundle shortly after, we might accept it. If we don't do
|
||||
// this, the homeserver could trick us into accepting any historic room key
|
||||
// bundle.
|
||||
if room.state() == RoomState::Invited {
|
||||
room_info.set_invite_accepted_now();
|
||||
}
|
||||
|
||||
room_info.mark_as_joined();
|
||||
room_info.mark_state_partially_synced();
|
||||
room_info.mark_members_missing(); // the own member event changed
|
||||
|
||||
let mut changes = StateChanges::default();
|
||||
changes.add_room(room_info.clone());
|
||||
|
||||
self.state_store.save_changes(&changes).await?; // Update the store
|
||||
|
||||
room.set_room_info(room_info, RoomInfoNotableUpdateReasons::MEMBERSHIP);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@ use ruma::{
|
||||
},
|
||||
room::RoomType,
|
||||
serde::Raw,
|
||||
EventId, MxcUri, OwnedEventId, OwnedMxcUri, OwnedRoomAliasId, OwnedRoomId, OwnedUserId,
|
||||
RoomAliasId, RoomId, RoomVersionId, UserId,
|
||||
EventId, MilliSecondsSinceUnixEpoch, MxcUri, OwnedEventId, OwnedMxcUri, OwnedRoomAliasId,
|
||||
OwnedRoomId, OwnedUserId, RoomAliasId, RoomId, RoomVersionId, UserId,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::{debug, field::debug, info, instrument, warn};
|
||||
@@ -464,6 +464,14 @@ pub struct RoomInfo {
|
||||
/// more accurate than relying on the latest event.
|
||||
#[serde(default)]
|
||||
pub(crate) recency_stamp: Option<u64>,
|
||||
|
||||
/// A timestamp remembering when we observed the user accepting an invite on
|
||||
/// this current device.
|
||||
///
|
||||
/// This is useful to remember if the user accepted this a join on this
|
||||
/// specific client.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) invite_accepted_at: Option<MilliSecondsSinceUnixEpoch>,
|
||||
}
|
||||
|
||||
impl RoomInfo {
|
||||
@@ -486,6 +494,7 @@ impl RoomInfo {
|
||||
cached_display_name: None,
|
||||
cached_user_defined_notification_mode: None,
|
||||
recency_stamp: None,
|
||||
invite_accepted_at: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -749,6 +758,22 @@ impl RoomInfo {
|
||||
self.summary.invited_member_count = count;
|
||||
}
|
||||
|
||||
/// Mark that the user has accepted an invite and remember when this has
|
||||
/// happened using a timestamp set to [`MilliSecondsSinceUnixEpoch::now()`].
|
||||
pub(crate) fn set_invite_accepted_now(&mut self) {
|
||||
self.invite_accepted_at = Some(MilliSecondsSinceUnixEpoch::now());
|
||||
}
|
||||
|
||||
/// Returns the timestamp when an invite to this room has been accepted by
|
||||
/// this specific client.
|
||||
///
|
||||
/// # Returns
|
||||
/// - `Some` if the invite has been accepted by this specific client.
|
||||
/// - `None` if the invite has not been accepted
|
||||
pub fn invite_accepted_at(&self) -> Option<MilliSecondsSinceUnixEpoch> {
|
||||
self.invite_accepted_at
|
||||
}
|
||||
|
||||
/// Updates the room heroes.
|
||||
pub(crate) fn update_heroes(&mut self, heroes: Vec<RoomHero>) {
|
||||
self.summary.room_heroes = heroes;
|
||||
@@ -1173,6 +1198,7 @@ mod tests {
|
||||
owned_mxc_uri, owned_user_id, room_id, serde::Raw,
|
||||
};
|
||||
use serde_json::json;
|
||||
use similar_asserts::assert_eq;
|
||||
|
||||
use super::{BaseRoomInfo, RoomInfo, SyncInfo};
|
||||
use crate::{
|
||||
@@ -1221,6 +1247,7 @@ mod tests {
|
||||
cached_display_name: None,
|
||||
cached_user_defined_notification_mode: None,
|
||||
recency_stamp: Some(42),
|
||||
invite_accepted_at: None,
|
||||
};
|
||||
|
||||
let info_json = json!({
|
||||
|
||||
@@ -121,6 +121,7 @@ impl RoomInfoV1 {
|
||||
cached_display_name: None,
|
||||
cached_user_defined_notification_mode: None,
|
||||
recency_stamp: None,
|
||||
invite_accepted_at: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user