improvements

This commit is contained in:
septias
2023-01-25 17:55:47 +01:00
parent fe11198dbc
commit 18dce04608
2 changed files with 114 additions and 116 deletions

View File

@@ -723,6 +723,8 @@ impl MimeMessage {
!self.signatures.is_empty() !self.signatures.is_empty()
} }
/// Returns whether the email contains a `chat-version` header.
/// This indicates that email is a DC-email from a chat.
pub(crate) fn has_chat_version(&self) -> bool { pub(crate) fn has_chat_version(&self) -> bool {
self.header.contains_key("chat-version") self.header.contains_key("chat-version")
} }

View File

@@ -1616,32 +1616,39 @@ async fn apply_group_changes(
to_ids: &[ContactId], to_ids: &[ContactId],
) -> Result<Option<String>> { ) -> Result<Option<String>> {
let mut chat = Chat::load_from_db(context, chat_id).await?; let mut chat = Chat::load_from_db(context, chat_id).await?;
if chat.typ != Chattype::Group { if chat.typ != Chattype::Group {
return Ok(None); return Ok(None);
} }
let mut recreate_member_list = match mime_parser.get_header(HeaderDef::InReplyTo) { let is_self_in_chat = chat::is_contact_in_chat(context, chat_id, ContactId::SELF).await?;
let mut send_event_chat_modified = false;
let mut removed_id = None;
let mut better_msg = None;
let mut recreate_member_list = if !mime_parser.has_chat_version() {
true
} else {
match mime_parser.get_header(HeaderDef::InReplyTo) {
Some(reply_to) if rfc724_mid_exists(context, reply_to).await?.is_none() => true, Some(reply_to) if rfc724_mid_exists(context, reply_to).await?.is_none() => true,
Some(_) => !is_contact_in_chat(context, chat_id, ContactId::SELF).await?, Some(_) => !is_self_in_chat,
None => true, _ => false,
}
}; };
let mut send_event_chat_modified = false;
let mut better_msg = None;
let removed_id;
if let Some(removed_addr) = mime_parser if let Some(removed_addr) = mime_parser
.get_header(HeaderDef::ChatGroupMemberRemoved) .get_header(HeaderDef::ChatGroupMemberRemoved)
.cloned() .cloned()
{ {
removed_id = Contact::lookup_id_by_addr(context, &removed_addr, Origin::Unknown).await?; removed_id = Contact::lookup_id_by_addr(context, &removed_addr, Origin::Unknown).await?;
match removed_id { if let Some(contact_id) = removed_id {
Some(contact_id) => { // remove a single member from the chat only if the received message is not outdated
if !recreate_member_list { if !recreate_member_list
chat::remove_from_chat_contacts_table(context, chat_id, contact_id).await?; && chat_id
chat_id
.update_timestamp(context, Param::MemberListTimestamp, sent_timestamp) .update_timestamp(context, Param::MemberListTimestamp, sent_timestamp)
.await?; .await?
{
chat::remove_from_chat_contacts_table(context, chat_id, contact_id).await?;
send_event_chat_modified = true; send_event_chat_modified = true;
} }
@@ -1651,30 +1658,31 @@ async fn apply_group_changes(
Some(stock_str::msg_del_member(context, &removed_addr, from_id).await) Some(stock_str::msg_del_member(context, &removed_addr, from_id).await)
}; };
} }
None => { } else if let Some(added_addr) = mime_parser
recreate_member_list = true;
warn!(context, "removed {:?} has no contact_id", removed_addr)
}
};
} else {
removed_id = None;
if let Some(added_member) = mime_parser
.get_header(HeaderDef::ChatGroupMemberAdded) .get_header(HeaderDef::ChatGroupMemberAdded)
.cloned() .cloned()
{ {
better_msg = Some(stock_str::msg_add_member(context, &added_member, from_id).await); better_msg = Some(stock_str::msg_add_member(context, &added_addr, from_id).await);
// If we got added to the group ourselves, we have to recreate the memberlist
if let Some(self_addr) = context.get_config(Config::Addr).await? {
if self_addr == added_addr {
recreate_member_list = true;
}
};
// add a single member to the chat only if the received message is not outdated
if !recreate_member_list { if !recreate_member_list {
if let Some(contact_id) = if let Some(contact_id) =
Contact::lookup_id_by_addr(context, &added_member, Origin::Unknown).await? Contact::lookup_id_by_addr(context, &added_addr, Origin::Unknown).await?
{
if chat_id
.update_timestamp(context, Param::MemberListTimestamp, sent_timestamp)
.await?
{ {
chat::add_to_chat_contacts_table(context, chat_id, &[contact_id]).await?; chat::add_to_chat_contacts_table(context, chat_id, &[contact_id]).await?;
chat_id
.update_timestamp(context, Param::MemberListTimestamp, sent_timestamp)
.await?;
send_event_chat_modified = true; send_event_chat_modified = true;
} else { }
recreate_member_list = true;
} }
} }
} else if let Some(old_name) = mime_parser } else if let Some(old_name) = mime_parser
@@ -1703,8 +1711,7 @@ async fn apply_group_changes(
send_event_chat_modified = true; send_event_chat_modified = true;
} }
better_msg = better_msg = Some(stock_str::msg_grp_name(context, old_name, grpname, from_id).await);
Some(stock_str::msg_grp_name(context, old_name, grpname, from_id).await);
} }
} else if let Some(value) = mime_parser.get_header(HeaderDef::ChatContent) { } else if let Some(value) = mime_parser.get_header(HeaderDef::ChatContent) {
if value == "group-avatar-changed" { if value == "group-avatar-changed" {
@@ -1722,13 +1729,6 @@ async fn apply_group_changes(
} }
} }
} }
}
if !mime_parser.has_chat_version() {
// If a classical MUA user adds someone to TO/CC, then the DC user shall
// see this addition and have the new recipient in the member list.
recreate_member_list = true;
}
if mime_parser.get_header(HeaderDef::ChatVerified).is_some() { if mime_parser.get_header(HeaderDef::ChatVerified).is_some() {
if let Err(err) = check_verified_properties(context, mime_parser, from_id, to_ids).await { if let Err(err) = check_verified_properties(context, mime_parser, from_id, to_ids).await {
@@ -1746,27 +1746,20 @@ async fn apply_group_changes(
} }
// add members to group/check members // add members to group/check members
if recreate_member_list { if recreate_member_list
if chat::is_contact_in_chat(context, chat_id, ContactId::SELF).await? && chat_id
&& !chat::is_contact_in_chat(context, chat_id, from_id).await? .update_timestamp(context, Param::MemberListTimestamp, sent_timestamp)
.await?
{ {
if is_self_in_chat && !chat::is_contact_in_chat(context, chat_id, from_id).await? {
warn!( warn!(
context, context,
"Contact {} attempts to modify group chat {} member list without being a member.", "Contact {} attempts to modify group chat {} member list without being a member.",
from_id, from_id,
chat_id chat_id
); );
} else if chat_id } else {
.update_timestamp(context, Param::MemberListTimestamp, sent_timestamp) // clear chat contacts
.await?
{
let mut members_to_add = vec![];
if removed_id.is_some()
|| !chat::is_contact_in_chat(context, chat_id, ContactId::SELF).await?
{
// Members could have been removed while we were
// absent. We can't use existing member list and need to
// start from scratch.
context context
.sql .sql
.execute( .execute(
@@ -1775,23 +1768,26 @@ async fn apply_group_changes(
) )
.await?; .await?;
members_to_add.push(ContactId::SELF); let mut members_to_add = HashSet::new();
} members_to_add.extend(to_ids);
members_to_add.insert(ContactId::SELF);
if !from_id.is_special() { if !from_id.is_special() {
members_to_add.push(from_id); members_to_add.insert(from_id);
} }
members_to_add.extend(to_ids);
if let Some(removed_id) = removed_id { if let Some(removed_id) = removed_id {
members_to_add.retain(|id| *id != removed_id); members_to_add.remove(&removed_id);
} }
members_to_add.dedup();
info!( info!(
context, context,
"adding {:?} to chat id={}", members_to_add, chat_id "adding {:?} to chat id={}", members_to_add, chat_id
); );
chat::add_to_chat_contacts_table(context, chat_id, &members_to_add).await?;
chat::add_to_chat_contacts_table(context, chat_id, &Vec::from_iter(members_to_add))
.await?;
send_event_chat_modified = true; send_event_chat_modified = true;
} }
} }