|
|
|
@ -100,47 +100,61 @@ pub async fn sync_events_route( |
|
|
|
limited = true; |
|
|
|
limited = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Database queries:
|
|
|
|
let encrypted_room = db |
|
|
|
let encrypted_room = db |
|
|
|
.rooms |
|
|
|
.rooms |
|
|
|
.room_state_get(&room_id, &EventType::RoomEncryption, "")? |
|
|
|
.room_state_get(&room_id, &EventType::RoomEncryption, "")? |
|
|
|
.is_some(); |
|
|
|
.is_some(); |
|
|
|
|
|
|
|
|
|
|
|
// Database queries:
|
|
|
|
// These type is Option<Option<_>>. The outer Option is None when there is no event between
|
|
|
|
|
|
|
|
// since and the current room state, meaning there should be no updates.
|
|
|
|
|
|
|
|
// The inner Option is None when there is an event, but there is no state hash associated
|
|
|
|
|
|
|
|
// with it. This can happen for the RoomCreate event, so all updates should arrive.
|
|
|
|
let since_state_hash = db |
|
|
|
let since_state_hash = db |
|
|
|
.rooms |
|
|
|
.rooms |
|
|
|
.pdus_until(sender_id, &room_id, since) |
|
|
|
.pdus_after(sender_id, &room_id, since) // - 1 So we can get the event at since
|
|
|
|
.next() |
|
|
|
.next() |
|
|
|
.and_then(|pdu| pdu.ok()) |
|
|
|
.map(|pdu| db.rooms.pdu_state_hash(&pdu.ok()?.0).ok()?); |
|
|
|
.and_then(|pdu| db.rooms.pdu_state_hash(&pdu.0).ok()?); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let since_members = since_state_hash |
|
|
|
let since_members = since_state_hash.as_ref().map(|state_hash| { |
|
|
|
.as_ref() |
|
|
|
state_hash.as_ref().and_then(|state_hash| { |
|
|
|
.and_then(|state_hash| db.rooms.state_type(state_hash, &EventType::RoomMember).ok()); |
|
|
|
db.rooms |
|
|
|
|
|
|
|
.state_type(&state_hash, &EventType::RoomMember) |
|
|
|
|
|
|
|
.ok() |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
let since_encryption = since_state_hash.as_ref().and_then(|state_hash| { |
|
|
|
let since_encryption = since_state_hash.as_ref().map(|state_hash| { |
|
|
|
db.rooms |
|
|
|
state_hash.as_ref().and_then(|state_hash| { |
|
|
|
.state_get(&state_hash, &EventType::RoomEncryption, "") |
|
|
|
db.rooms |
|
|
|
.ok() |
|
|
|
.state_get(&state_hash, &EventType::RoomEncryption, "") |
|
|
|
|
|
|
|
.ok() |
|
|
|
|
|
|
|
}) |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
let current_members = db.rooms.room_state_type(&room_id, &EventType::RoomMember)?; |
|
|
|
let current_members = db.rooms.room_state_type(&room_id, &EventType::RoomMember)?; |
|
|
|
|
|
|
|
|
|
|
|
// Calculations:
|
|
|
|
// Calculations:
|
|
|
|
let new_encrypted_room = encrypted_room && since_encryption.is_none(); |
|
|
|
let new_encrypted_room = |
|
|
|
|
|
|
|
encrypted_room && since_encryption.map_or(false, |encryption| encryption.is_none()); |
|
|
|
|
|
|
|
|
|
|
|
let send_member_count = since_members.as_ref().map_or(true, |since_members| { |
|
|
|
let send_member_count = since_members.as_ref().map_or(false, |since_members| { |
|
|
|
current_members.len() != since_members.len() |
|
|
|
since_members.as_ref().map_or(true, |since_members| { |
|
|
|
|
|
|
|
current_members.len() != since_members.len() |
|
|
|
|
|
|
|
}) |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
let since_sender_member = since_members.as_ref().and_then(|members| { |
|
|
|
let since_sender_member = since_members.as_ref().map(|since_members| { |
|
|
|
members.get(sender_id.as_str()).and_then(|pdu| { |
|
|
|
since_members.as_ref().and_then(|members| { |
|
|
|
serde_json::from_value::<Raw<ruma::events::room::member::MemberEventContent>>( |
|
|
|
members.get(sender_id.as_str()).and_then(|pdu| { |
|
|
|
pdu.content.clone(), |
|
|
|
serde_json::from_value::<Raw<ruma::events::room::member::MemberEventContent>>( |
|
|
|
) |
|
|
|
pdu.content.clone(), |
|
|
|
.expect("Raw::from_value always works") |
|
|
|
) |
|
|
|
.deserialize() |
|
|
|
.expect("Raw::from_value always works") |
|
|
|
.map_err(|_| Error::bad_database("Invalid PDU in database.")) |
|
|
|
.deserialize() |
|
|
|
.ok() |
|
|
|
.map_err(|_| Error::bad_database("Invalid PDU in database.")) |
|
|
|
|
|
|
|
.ok() |
|
|
|
|
|
|
|
}) |
|
|
|
}) |
|
|
|
}) |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
@ -154,20 +168,29 @@ pub async fn sync_events_route( |
|
|
|
.map_err(|_| Error::bad_database("Invalid PDU in database."))? |
|
|
|
.map_err(|_| Error::bad_database("Invalid PDU in database."))? |
|
|
|
.membership; |
|
|
|
.membership; |
|
|
|
|
|
|
|
|
|
|
|
let since_membership = since_members |
|
|
|
let since_membership = |
|
|
|
.as_ref() |
|
|
|
since_members |
|
|
|
.and_then(|members| { |
|
|
|
.as_ref() |
|
|
|
members.get(&user_id).and_then(|since_member| { |
|
|
|
.map_or(MembershipState::Join, |members| { |
|
|
|
serde_json::from_value::< |
|
|
|
members |
|
|
|
Raw<ruma::events::room::member::MemberEventContent>, |
|
|
|
.as_ref() |
|
|
|
>(since_member.content.clone()) |
|
|
|
.and_then(|members| { |
|
|
|
.expect("Raw::from_value always works") |
|
|
|
members.get(&user_id).and_then(|since_member| { |
|
|
|
.deserialize() |
|
|
|
serde_json::from_value::< |
|
|
|
.map_err(|_| Error::bad_database("Invalid PDU in database.")) |
|
|
|
Raw<ruma::events::room::member::MemberEventContent>, |
|
|
|
.ok() |
|
|
|
>( |
|
|
|
}) |
|
|
|
since_member.content.clone() |
|
|
|
}) |
|
|
|
) |
|
|
|
.map_or(MembershipState::Leave, |member| member.membership); |
|
|
|
.expect("Raw::from_value always works") |
|
|
|
|
|
|
|
.deserialize() |
|
|
|
|
|
|
|
.map_err(|_| { |
|
|
|
|
|
|
|
Error::bad_database("Invalid PDU in database.") |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
.ok() |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
.map_or(MembershipState::Leave, |member| member.membership) |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
let user_id = UserId::try_from(user_id) |
|
|
|
let user_id = UserId::try_from(user_id) |
|
|
|
.map_err(|_| Error::bad_database("Invalid UserId in member PDU."))?; |
|
|
|
.map_err(|_| Error::bad_database("Invalid UserId in member PDU."))?; |
|
|
|
@ -188,8 +211,9 @@ pub async fn sync_events_route( |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let joined_since_last_sync = |
|
|
|
let joined_since_last_sync = since_sender_member.map_or(false, |member| { |
|
|
|
since_sender_member.map_or(true, |member| member.membership != MembershipState::Join); |
|
|
|
member.map_or(true, |member| member.membership != MembershipState::Join) |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
if joined_since_last_sync && encrypted_room || new_encrypted_room { |
|
|
|
if joined_since_last_sync && encrypted_room || new_encrypted_room { |
|
|
|
// If the user is in a new encrypted room, give them all joined users
|
|
|
|
// If the user is in a new encrypted room, give them all joined users
|
|
|
|
@ -434,7 +458,7 @@ pub async fn sync_events_route( |
|
|
|
|
|
|
|
|
|
|
|
let since_member = db |
|
|
|
let since_member = db |
|
|
|
.rooms |
|
|
|
.rooms |
|
|
|
.pdus_until(sender_id, &room_id, since) |
|
|
|
.pdus_after(sender_id, &room_id, since) |
|
|
|
.next() |
|
|
|
.next() |
|
|
|
.and_then(|pdu| pdu.ok()) |
|
|
|
.and_then(|pdu| pdu.ok()) |
|
|
|
.and_then(|pdu| { |
|
|
|
.and_then(|pdu| { |
|
|
|
@ -581,7 +605,7 @@ pub async fn sync_events_route( |
|
|
|
changed: device_list_updates.into_iter().collect(), |
|
|
|
changed: device_list_updates.into_iter().collect(), |
|
|
|
left: device_list_left.into_iter().collect(), |
|
|
|
left: device_list_left.into_iter().collect(), |
|
|
|
}, |
|
|
|
}, |
|
|
|
device_one_time_keys_count: if db.users.last_one_time_keys_update(sender_id)? > since { |
|
|
|
device_one_time_keys_count: if db.users.last_one_time_keys_update(sender_id)? > since || since == 0 { |
|
|
|
db.users.count_one_time_keys(sender_id, device_id)? |
|
|
|
db.users.count_one_time_keys(sender_id, device_id)? |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
BTreeMap::new() |
|
|
|
BTreeMap::new() |
|
|
|
|