fix: send device list updates when user is in no rooms
This commit is contained in:
parent
c824652de6
commit
ce460ea159
3 changed files with 80 additions and 19 deletions
|
@ -672,7 +672,11 @@ pub fn set_displayname_route(
|
||||||
displayname: body.displayname.clone(),
|
displayname: body.displayname.clone(),
|
||||||
..serde_json::from_value::<Raw<_>>(
|
..serde_json::from_value::<Raw<_>>(
|
||||||
db.rooms
|
db.rooms
|
||||||
.room_state_get(&room_id, &EventType::RoomMember, &sender_id.to_string())?
|
.room_state_get(
|
||||||
|
&room_id,
|
||||||
|
&EventType::RoomMember,
|
||||||
|
&sender_id.to_string(),
|
||||||
|
)?
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Error::bad_database(
|
Error::bad_database(
|
||||||
"Tried to send displayname update for user not in the room.",
|
"Tried to send displayname update for user not in the room.",
|
||||||
|
@ -770,7 +774,11 @@ pub fn set_avatar_url_route(
|
||||||
avatar_url: body.avatar_url.clone(),
|
avatar_url: body.avatar_url.clone(),
|
||||||
..serde_json::from_value::<Raw<_>>(
|
..serde_json::from_value::<Raw<_>>(
|
||||||
db.rooms
|
db.rooms
|
||||||
.room_state_get(&room_id, &EventType::RoomMember, &sender_id.to_string())?
|
.room_state_get(
|
||||||
|
&room_id,
|
||||||
|
&EventType::RoomMember,
|
||||||
|
&sender_id.to_string(),
|
||||||
|
)?
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Error::bad_database(
|
Error::bad_database(
|
||||||
"Tried to send avatar url update for user not in the room.",
|
"Tried to send avatar url update for user not in the room.",
|
||||||
|
@ -1884,12 +1892,11 @@ pub fn ban_user_route(
|
||||||
third_party_invite: None,
|
third_party_invite: None,
|
||||||
}),
|
}),
|
||||||
|event| {
|
|event| {
|
||||||
let mut event = serde_json::from_value::<Raw<member::MemberEventContent>>(
|
let mut event =
|
||||||
event.content,
|
serde_json::from_value::<Raw<member::MemberEventContent>>(event.content)
|
||||||
)
|
.expect("Raw::from_value always works")
|
||||||
.expect("Raw::from_value always works")
|
.deserialize()
|
||||||
.deserialize()
|
.map_err(|_| Error::bad_database("Invalid member event in database."))?;
|
||||||
.map_err(|_| Error::bad_database("Invalid member event in database."))?;
|
|
||||||
event.membership = ruma::events::room::member::MembershipState::Ban;
|
event.membership = ruma::events::room::member::MembershipState::Ban;
|
||||||
Ok(event)
|
Ok(event)
|
||||||
},
|
},
|
||||||
|
@ -2211,6 +2218,7 @@ pub async fn get_public_rooms_filtered_route(
|
||||||
Ok::<_, Error>(chunk)
|
Ok::<_, Error>(chunk)
|
||||||
})
|
})
|
||||||
.filter_map(|r| r.ok()) // Filter out buggy rooms
|
.filter_map(|r| r.ok()) // Filter out buggy rooms
|
||||||
|
// We need to collect all, so we can sort by member count
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
chunk.sort_by(|l, r| r.num_joined_members.cmp(&l.num_joined_members));
|
chunk.sort_by(|l, r| r.num_joined_members.cmp(&l.num_joined_members));
|
||||||
|
@ -2618,6 +2626,13 @@ pub async fn sync_events_route(
|
||||||
let mut presence_updates = HashMap::new();
|
let mut presence_updates = HashMap::new();
|
||||||
let mut device_list_updates = HashSet::new();
|
let mut device_list_updates = HashSet::new();
|
||||||
|
|
||||||
|
// Look for device list updates of this account
|
||||||
|
device_list_updates.extend(
|
||||||
|
db.users
|
||||||
|
.keys_changed(&sender_id.to_string(), since, None)
|
||||||
|
.filter_map(|r| r.ok()),
|
||||||
|
);
|
||||||
|
|
||||||
for room_id in db.rooms.rooms_joined(&sender_id) {
|
for room_id in db.rooms.rooms_joined(&sender_id) {
|
||||||
let room_id = room_id?;
|
let room_id = room_id?;
|
||||||
|
|
||||||
|
@ -2869,7 +2884,7 @@ pub async fn sync_events_route(
|
||||||
// Look for device list updates in this room
|
// Look for device list updates in this room
|
||||||
device_list_updates.extend(
|
device_list_updates.extend(
|
||||||
db.users
|
db.users
|
||||||
.keys_changed(&room_id, since, None)
|
.keys_changed(&room_id.to_string(), since, None)
|
||||||
.filter_map(|r| r.ok()),
|
.filter_map(|r| r.ok()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -3652,11 +3667,28 @@ pub fn get_key_changes_route(
|
||||||
let sender_id = body.sender_id.as_ref().expect("user is authenticated");
|
let sender_id = body.sender_id.as_ref().expect("user is authenticated");
|
||||||
|
|
||||||
let mut device_list_updates = HashSet::new();
|
let mut device_list_updates = HashSet::new();
|
||||||
|
|
||||||
|
device_list_updates.extend(
|
||||||
|
db.users
|
||||||
|
.keys_changed(
|
||||||
|
&sender_id.to_string(),
|
||||||
|
body.from
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid `from`."))?,
|
||||||
|
Some(
|
||||||
|
body.to
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid `to`."))?,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.filter_map(|r| r.ok()),
|
||||||
|
);
|
||||||
|
|
||||||
for room_id in db.rooms.rooms_joined(sender_id).filter_map(|r| r.ok()) {
|
for room_id in db.rooms.rooms_joined(sender_id).filter_map(|r| r.ok()) {
|
||||||
device_list_updates.extend(
|
device_list_updates.extend(
|
||||||
db.users
|
db.users
|
||||||
.keys_changed(
|
.keys_changed(
|
||||||
&room_id,
|
&room_id.to_string(),
|
||||||
body.from.parse().map_err(|_| {
|
body.from.parse().map_err(|_| {
|
||||||
Error::BadRequest(ErrorKind::InvalidParam, "Invalid `from`.")
|
Error::BadRequest(ErrorKind::InvalidParam, "Invalid `from`.")
|
||||||
})?,
|
})?,
|
||||||
|
|
|
@ -126,16 +126,17 @@ impl Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn watch(&self, user_id: &UserId, device_id: &DeviceId) {
|
pub async fn watch(&self, user_id: &UserId, device_id: &DeviceId) {
|
||||||
let mut userid_prefix = user_id.to_string().as_bytes().to_vec();
|
let userid_bytes = user_id.to_string().as_bytes().to_vec();
|
||||||
|
|
||||||
|
let mut userid_prefix = userid_bytes.clone();
|
||||||
userid_prefix.push(0xff);
|
userid_prefix.push(0xff);
|
||||||
|
|
||||||
let mut userdeviceid_prefix = userid_prefix.clone();
|
let mut userdeviceid_prefix = userid_prefix.clone();
|
||||||
userdeviceid_prefix.extend_from_slice(device_id.as_bytes());
|
userdeviceid_prefix.extend_from_slice(device_id.as_bytes());
|
||||||
userdeviceid_prefix.push(0xff);
|
userdeviceid_prefix.push(0xff);
|
||||||
|
|
||||||
let mut futures = futures::stream::FuturesUnordered::new();
|
let mut futures = futures::stream::FuturesUnordered::new();
|
||||||
|
|
||||||
futures.push(self.users.keychangeid_userid.watch_prefix(b""));
|
|
||||||
|
|
||||||
// Return when *any* user changed his key
|
// Return when *any* user changed his key
|
||||||
// TODO: only send for user they share a room with
|
// TODO: only send for user they share a room with
|
||||||
futures.push(
|
futures.push(
|
||||||
|
@ -171,6 +172,9 @@ impl Database {
|
||||||
.watch_prefix(&roomid_prefix),
|
.watch_prefix(&roomid_prefix),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Key changes
|
||||||
|
futures.push(self.users.keychangeid_userid.watch_prefix(&roomid_prefix));
|
||||||
|
|
||||||
// Room account data
|
// Room account data
|
||||||
let mut roomuser_prefix = roomid_prefix.clone();
|
let mut roomuser_prefix = roomid_prefix.clone();
|
||||||
roomuser_prefix.extend_from_slice(&userid_prefix);
|
roomuser_prefix.extend_from_slice(&userid_prefix);
|
||||||
|
@ -191,6 +195,16 @@ impl Database {
|
||||||
.watch_prefix(&globaluserdata_prefix),
|
.watch_prefix(&globaluserdata_prefix),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// More key changes (used when user is not joined to any rooms)
|
||||||
|
futures.push(self.users.keychangeid_userid.watch_prefix(&userid_prefix));
|
||||||
|
|
||||||
|
// One time keys
|
||||||
|
futures.push(
|
||||||
|
self.users
|
||||||
|
.userid_lastonetimekeyupdate
|
||||||
|
.watch_prefix(&userid_bytes),
|
||||||
|
);
|
||||||
|
|
||||||
// Wait until one of them finds something
|
// Wait until one of them finds something
|
||||||
futures.next().await;
|
futures.next().await;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use ruma::{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
events::{AnyToDeviceEvent, EventType},
|
events::{AnyToDeviceEvent, EventType},
|
||||||
DeviceId, Raw, RoomId, UserId,
|
DeviceId, Raw, UserId,
|
||||||
};
|
};
|
||||||
use std::{collections::BTreeMap, convert::TryFrom, mem, time::SystemTime};
|
use std::{collections::BTreeMap, convert::TryFrom, mem, time::SystemTime};
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ pub struct Users {
|
||||||
|
|
||||||
pub(super) onetimekeyid_onetimekeys: sled::Tree, // OneTimeKeyId = UserId + AlgorithmAndDeviceId
|
pub(super) onetimekeyid_onetimekeys: sled::Tree, // OneTimeKeyId = UserId + AlgorithmAndDeviceId
|
||||||
pub(super) userid_lastonetimekeyupdate: sled::Tree, // LastOneTimeKeyUpdate = Count
|
pub(super) userid_lastonetimekeyupdate: sled::Tree, // LastOneTimeKeyUpdate = Count
|
||||||
pub(super) keychangeid_userid: sled::Tree, // KeyChangeId = RoomId + Count
|
pub(super) keychangeid_userid: sled::Tree, // KeyChangeId = UserId/RoomId + Count
|
||||||
pub(super) keyid_key: sled::Tree, // KeyId = UserId + KeyId (depends on key type)
|
pub(super) keyid_key: sled::Tree, // KeyId = UserId + KeyId (depends on key type)
|
||||||
pub(super) userid_masterkeyid: sled::Tree,
|
pub(super) userid_masterkeyid: sled::Tree,
|
||||||
pub(super) userid_selfsigningkeyid: sled::Tree,
|
pub(super) userid_selfsigningkeyid: sled::Tree,
|
||||||
|
@ -305,8 +305,7 @@ impl Users {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn last_one_time_keys_update(&self, user_id: &UserId) -> Result<u64> {
|
pub fn last_one_time_keys_update(&self, user_id: &UserId) -> Result<u64> {
|
||||||
self
|
self.userid_lastonetimekeyupdate
|
||||||
.userid_lastonetimekeyupdate
|
|
||||||
.get(&user_id.to_string().as_bytes())?
|
.get(&user_id.to_string().as_bytes())?
|
||||||
.map(|bytes| {
|
.map(|bytes| {
|
||||||
utils::u64_from_bytes(&bytes).map_err(|_| {
|
utils::u64_from_bytes(&bytes).map_err(|_| {
|
||||||
|
@ -417,6 +416,11 @@ impl Users {
|
||||||
self.keychangeid_userid.insert(key, &*user_id.to_string())?;
|
self.keychangeid_userid.insert(key, &*user_id.to_string())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut key = user_id.to_string().as_bytes().to_vec();
|
||||||
|
key.push(0xff);
|
||||||
|
key.extend_from_slice(&count);
|
||||||
|
self.keychangeid_userid.insert(key, &*user_id.to_string())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,6 +528,11 @@ impl Users {
|
||||||
self.keychangeid_userid.insert(key, &*user_id.to_string())?;
|
self.keychangeid_userid.insert(key, &*user_id.to_string())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut key = user_id.to_string().as_bytes().to_vec();
|
||||||
|
key.push(0xff);
|
||||||
|
key.extend_from_slice(&count);
|
||||||
|
self.keychangeid_userid.insert(key, &*user_id.to_string())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,16 +585,22 @@ impl Users {
|
||||||
.insert(key, &*target_id.to_string())?;
|
.insert(key, &*target_id.to_string())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut key = target_id.to_string().as_bytes().to_vec();
|
||||||
|
key.push(0xff);
|
||||||
|
key.extend_from_slice(&count);
|
||||||
|
self.keychangeid_userid
|
||||||
|
.insert(key, &*target_id.to_string())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keys_changed(
|
pub fn keys_changed(
|
||||||
&self,
|
&self,
|
||||||
room_id: &RoomId,
|
user_or_room_id: &str,
|
||||||
from: u64,
|
from: u64,
|
||||||
to: Option<u64>,
|
to: Option<u64>,
|
||||||
) -> impl Iterator<Item = Result<UserId>> {
|
) -> impl Iterator<Item = Result<UserId>> {
|
||||||
let mut prefix = room_id.to_string().as_bytes().to_vec();
|
let mut prefix = user_or_room_id.as_bytes().to_vec();
|
||||||
prefix.push(0xff);
|
prefix.push(0xff);
|
||||||
|
|
||||||
let mut start = prefix.clone();
|
let mut start = prefix.clone();
|
||||||
|
|
Loading…
Reference in a new issue