diff --git a/src/chat.rs b/src/chat.rs index 9c8dbe289..dda3e3d98 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -292,7 +292,7 @@ impl ChatId { ChatIdBlocked::get_for_contact(context, contact_id, create_blocked) .await .map(|chat| chat.id)?; - Contact::scaleup_origin_by_id(context, contact_id, Origin::CreateChat).await?; + ContactId::scaleup_origin(context, &[contact_id], Origin::CreateChat).await?; chat_id } else { warn!( @@ -489,7 +489,7 @@ impl ChatId { // went to "contact requests" list rather than normal chatlist. for contact_id in get_chat_contacts(context, self).await? { if contact_id != ContactId::SELF { - Contact::scaleup_origin_by_id(context, contact_id, Origin::CreateChat) + ContactId::scaleup_origin(context, &[contact_id], Origin::CreateChat) .await?; } } diff --git a/src/contact.rs b/src/contact.rs index d8e77744b..da312dda2 100644 --- a/src/contact.rs +++ b/src/contact.rs @@ -120,6 +120,29 @@ impl ContactId { .await?; Ok(()) } + + /// Updates the origin of the contacts, but only if `origin` is higher than the current one. + pub(crate) async fn scaleup_origin( + context: &Context, + ids: &[Self], + origin: Origin, + ) -> Result<()> { + context + .sql + .execute( + &format!( + "UPDATE contacts SET origin=? WHERE id IN ({}) AND origin Result<()> { - context - .sql - .execute( - "UPDATE contacts SET origin=? WHERE id=? AND origin MimeFactory<'a> { }; let mut recipients = Vec::with_capacity(5); + let mut recipient_ids = HashSet::new(); let mut req_mdn = false; if chat.is_self_talk() { @@ -169,7 +170,7 @@ impl<'a> MimeFactory<'a> { context .sql .query_map( - "SELECT c.authname, c.addr \ + "SELECT c.authname, c.addr, c.id \ FROM chats_contacts cc \ LEFT JOIN contacts c ON cc.contact_id=c.id \ WHERE cc.chat_id=? AND cc.contact_id>9;", @@ -177,19 +178,23 @@ impl<'a> MimeFactory<'a> { |row| { let authname: String = row.get(0)?; let addr: String = row.get(1)?; - Ok((authname, addr)) + let id: ContactId = row.get(2)?; + Ok((authname, addr, id)) }, |rows| { for row in rows { - let (authname, addr) = row?; + let (authname, addr, id) = row?; if !recipients_contain_addr(&recipients, &addr) { recipients.push((authname, addr)); } + recipient_ids.insert(id); } Ok(()) }, ) .await?; + let recipient_ids: Vec<_> = recipient_ids.into_iter().collect(); + ContactId::scaleup_origin(context, &recipient_ids, Origin::OutgoingTo).await?; if !msg.is_system_message() && msg.param.get_int(Param::Reaction).unwrap_or_default() == 0 diff --git a/src/receive_imf.rs b/src/receive_imf.rs index 15ac680c3..28852a824 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -955,7 +955,7 @@ async fn add_parts( if create_blocked == Blocked::Request && parent.is_some() { // we do not want any chat to be created implicitly. Because of the origin-scale-up, // the contact requests will pop up and this should be just fine. - Contact::scaleup_origin_by_id(context, from_id, Origin::IncomingReplyTo) + ContactId::scaleup_origin(context, &[from_id], Origin::IncomingReplyTo) .await?; info!( context, diff --git a/src/securejoin.rs b/src/securejoin.rs index c8c37675c..a3db2ae82 100644 --- a/src/securejoin.rs +++ b/src/securejoin.rs @@ -447,7 +447,7 @@ pub(crate) async fn handle_securejoin_handshake( return Ok(HandshakeMessage::Ignore); } contact_id.regossip_keys(context).await?; - Contact::scaleup_origin_by_id(context, contact_id, Origin::SecurejoinInvited).await?; + ContactId::scaleup_origin(context, &[contact_id], Origin::SecurejoinInvited).await?; info!(context, "Auth verified.",); context.emit_event(EventType::ContactsChanged(Some(contact_id))); inviter_progress(context, contact_id, 600); diff --git a/src/securejoin/bobstate.rs b/src/securejoin/bobstate.rs index 264a66f64..e0538d65f 100644 --- a/src/securejoin/bobstate.rs +++ b/src/securejoin/bobstate.rs @@ -14,7 +14,7 @@ use super::qrinvite::QrInvite; use super::{encrypted_and_signed, verify_sender_by_fingerprint}; use crate::chat::{self, ChatId}; use crate::config::Config; -use crate::contact::{Contact, Origin}; +use crate::contact::{ContactId, Origin}; use crate::context::Context; use crate::events::EventType; use crate::headerdef::HeaderDef; @@ -326,8 +326,12 @@ impl BobState { Some(context.get_config_i64(Config::KeyId).await?).filter(|&id| id > 0); peerstate.save_to_db(&context.sql).await?; - Contact::scaleup_origin_by_id(context, self.invite.contact_id(), Origin::SecurejoinJoined) - .await?; + ContactId::scaleup_origin( + context, + &[self.invite.contact_id()], + Origin::SecurejoinJoined, + ) + .await?; context.emit_event(EventType::ContactsChanged(None)); self.update_next(&context.sql, SecureJoinStep::Completed)