diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index b2d8e2fd6..07e2f1f13 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -12,6 +12,7 @@ use crate::context::Context; use crate::dc_tools::*; use crate::error::Result; use crate::events::Event; +use crate::headerdef::HeaderDef; use crate::job::*; use crate::location; use crate::message::{self, MessageState, MsgId}; @@ -60,9 +61,9 @@ pub fn dc_receive_imf( mime_parser.unwrap() }; - if mime_parser.header.is_empty() { - // Error - even adding an empty record won't help as we do not know the message ID - warn!(context, "No header."); + if mime_parser.get(HeaderDef::From_).is_none() { + // Error - even adding an empty record won't help as we do not know the sender + warn!(context, "No From header."); return; } @@ -114,7 +115,7 @@ pub fn dc_receive_imf( } }; - if let Some(value) = mime_parser.lookup_field("Date") { + if let Some(value) = mime_parser.get(HeaderDef::Date) { // is not yet checked against bad times! we do this later if we have the database information. sent_timestamp = mailparse::dateparse(value).unwrap_or_default(); } @@ -122,7 +123,7 @@ pub fn dc_receive_imf( // get From: and check if it is known (for known From:'s we add the other To:/Cc: in the 3rd pass) // or if From: is equal to SELF (in this case, it is any outgoing messages, // we do not check Return-Path any more as this is unreliable, see issue #150 - if let Some(field_from) = mime_parser.lookup_field("From") { + if let Some(field_from) = mime_parser.get(HeaderDef::From_) { let mut check_self = false; let mut from_list = Vec::with_capacity(16); dc_add_or_lookup_contacts_by_address_list( @@ -147,7 +148,7 @@ pub fn dc_receive_imf( } // Make sure, to_ids starts with the first To:-address (Cc: is added in the loop below pass) - if let Some(field) = mime_parser.lookup_field("To") { + if let Some(field) = mime_parser.get(HeaderDef::To) { dc_add_or_lookup_contacts_by_address_list( context, &field, @@ -307,7 +308,7 @@ fn add_parts( // collect the rest information, CC: is added to the to-list, BCC: is ignored // (we should not add BCC to groups as this would split groups. We could add them as "known contacts", // however, the benefit is very small and this may leak data that is expected to be hidden) - if let Some(fld_cc) = mime_parser.lookup_field("Cc") { + if let Some(fld_cc) = mime_parser.get(HeaderDef::Cc) { dc_add_or_lookup_contacts_by_address_list( context, fld_cc, @@ -372,7 +373,7 @@ fn add_parts( // handshake messages must be processed _before_ chats are created // (eg. contacs may be marked as verified) - if mime_parser.lookup_field("Secure-Join").is_some() { + if mime_parser.get(HeaderDef::SecureJoin).is_some() { // avoid discarding by show_emails setting msgrmsg = 1; *chat_id = 0; @@ -581,11 +582,11 @@ fn add_parts( // if the mime-headers should be saved, find out its size // (the mime-header ends with an empty line) let save_mime_headers = context.get_config_bool(Config::SaveMimeHeaders); - if let Some(raw) = mime_parser.lookup_field("In-Reply-To") { + if let Some(raw) = mime_parser.get(HeaderDef::InReplyTo) { mime_in_reply_to = raw.clone(); } - if let Some(raw) = mime_parser.lookup_field("References") { + if let Some(raw) = mime_parser.get(HeaderDef::References) { mime_references = raw.clone(); } @@ -797,7 +798,6 @@ fn create_or_lookup_group( to_ids: &[u32], ) -> Result<(u32, Blocked)> { let mut chat_id_blocked = Blocked::Not; - let mut grpname = None; let to_ids_cnt = to_ids.len(); let mut recreate_member_list = false; let mut send_EVENT_CHAT_MODIFIED = false; @@ -814,20 +814,21 @@ fn create_or_lookup_group( set_better_msg(mime_parser, &better_msg); let mut grpid = "".to_string(); - if let Some(optional_field) = mime_parser.lookup_field("Chat-Group-ID") { + if let Some(optional_field) = mime_parser.get(HeaderDef::ChatGroupId) { grpid = optional_field.clone(); } if grpid.is_empty() { - if let Some(value) = mime_parser.lookup_field("Message-ID") { + if let Some(value) = mime_parser.get(HeaderDef::MessageId) { if let Some(extracted_grpid) = dc_extract_grpid_from_rfc724_mid(&value) { grpid = extracted_grpid.to_string(); } } if grpid.is_empty() { - if let Some(extracted_grpid) = get_grpid_from_list(mime_parser, "In-Reply-To") { + if let Some(extracted_grpid) = extract_grpid(mime_parser, HeaderDef::InReplyTo) { grpid = extracted_grpid; - } else if let Some(extracted_grpid) = get_grpid_from_list(mime_parser, "References") { + } else if let Some(extracted_grpid) = extract_grpid(mime_parser, HeaderDef::References) + { grpid = extracted_grpid; } else { return create_or_lookup_adhoc_group( @@ -846,13 +847,9 @@ fn create_or_lookup_group( } } - if let Some(optional_field) = mime_parser.lookup_field("Chat-Group-Name").cloned() { - grpname = Some(optional_field); - } - let field = mime_parser - .lookup_field("Chat-Group-Member-Removed") - .cloned(); - if let Some(optional_field) = field { + let grpname = mime_parser.get(HeaderDef::ChatGroupName).cloned(); + + if let Some(optional_field) = mime_parser.get(HeaderDef::ChatGroupMemberRemoved).cloned() { X_MrRemoveFromGrp = Some(optional_field); mime_parser.is_system_message = SystemMessage::MemberRemovedFromGroup; let left_group = Contact::lookup_id_by_addr(context, X_MrRemoveFromGrp.as_ref().unwrap()) @@ -868,11 +865,11 @@ fn create_or_lookup_group( from_id as u32, ) } else { - let field = mime_parser.lookup_field("Chat-Group-Member-Added").cloned(); + let field = mime_parser.get(HeaderDef::ChatGroupMemberAdded).cloned(); if let Some(optional_field) = field { X_MrAddToGrp = Some(optional_field); mime_parser.is_system_message = SystemMessage::MemberAddedToGroup; - if let Some(optional_field) = mime_parser.lookup_field("Chat-Group-Image").cloned() { + if let Some(optional_field) = mime_parser.get(HeaderDef::ChatGroupImage).cloned() { X_MrGrpImageChanged = optional_field; } better_msg = context.stock_system_msg( @@ -882,7 +879,7 @@ fn create_or_lookup_group( from_id as u32, ) } else { - let field = mime_parser.lookup_field("Chat-Group-Name-Changed"); + let field = mime_parser.get(HeaderDef::ChatGroupNameChanged); if let Some(field) = field { X_MrGrpNameChanged = true; better_msg = context.stock_system_msg( @@ -897,8 +894,7 @@ fn create_or_lookup_group( ); mime_parser.is_system_message = SystemMessage::GroupNameChanged; - } else if let Some(optional_field) = - mime_parser.lookup_field("Chat-Group-Image").cloned() + } else if let Some(optional_field) = mime_parser.get(HeaderDef::ChatGroupImage).cloned() { // fld_value is a pointer somewhere into mime_parser, must not be freed X_MrGrpImageChanged = optional_field; @@ -954,7 +950,7 @@ fn create_or_lookup_group( || X_MrAddToGrp.is_some() && addr_cmp(&self_addr, X_MrAddToGrp.as_ref().unwrap())) { // group does not exist but should be created - let create_verified = if mime_parser.lookup_field("Chat-Verified").is_some() { + let create_verified = if mime_parser.get(HeaderDef::ChatVerified).is_some() { if let Err(err) = check_verified_properties(context, mime_parser, from_id as u32, to_ids) { @@ -1130,8 +1126,8 @@ fn create_or_lookup_group( } /// try extract a grpid from a message-id list header value -fn get_grpid_from_list(mime_parser: &MimeParser, header_key: &str) -> Option { - if let Some(value) = mime_parser.lookup_field(header_key) { +fn extract_grpid(mime_parser: &MimeParser, headerdef: HeaderDef) -> Option { + if let Some(value) = mime_parser.get(headerdef) { for part in value.split(',').map(str::trim) { if !part.is_empty() { if let Some(extracted_grpid) = dc_extract_grpid_from_rfc724_mid(part) { @@ -1486,13 +1482,13 @@ fn is_reply_to_known_message(context: &Context, mime_parser: &MimeParser) -> boo /* check if the message is a reply to a known message; the replies are identified by the Message-ID from `In-Reply-To`/`References:` (to support non-Delta-Clients) */ - if let Some(field) = mime_parser.lookup_field("In-Reply-To") { + if let Some(field) = mime_parser.get(HeaderDef::InReplyTo) { if is_known_rfc724_mid_in_list(context, &field) { return true; } } - if let Some(field) = mime_parser.lookup_field("References") { + if let Some(field) = mime_parser.get(HeaderDef::References) { if is_known_rfc724_mid_in_list(context, &field) { return true; } @@ -1537,14 +1533,14 @@ fn is_known_rfc724_mid(context: &Context, rfc724_mid: &mailparse::MailAddr) -> b /// - checks also if any of the referenced IDs are send by a messenger /// - it is okay, if the referenced messages are moved to trash here /// - no check for the Chat-* headers (function is only called if it is no messenger message itself) -fn is_reply_to_messenger_message(context: &Context, mime_parser: &MimeParser) -> bool { - if let Some(value) = mime_parser.lookup_field("In-Reply-To") { +fn dc_is_reply_to_messenger_message(context: &Context, mime_parser: &MimeParser) -> bool { + if let Some(value) = mime_parser.get(HeaderDef::InReplyTo) { if is_msgrmsg_rfc724_mid_in_list(context, &value) { return true; } } - if let Some(value) = mime_parser.lookup_field("References") { + if let Some(value) = mime_parser.get(HeaderDef::References) { if is_msgrmsg_rfc724_mid_in_list(context, &value) { return true; } @@ -1683,9 +1679,9 @@ mod tests { \n\ hello\x00"; let mimeparser = MimeParser::from_bytes(&context.ctx, &raw[..]).unwrap(); - assert_eq!(get_grpid_from_list(&mimeparser, "In-Reply-To"), None); + assert_eq!(extract_grpid(&mimeparser, HeaderDef::InReplyTo), None); let grpid = Some("HcxyMARjyJy".to_string()); - assert_eq!(get_grpid_from_list(&mimeparser, "References"), grpid); + assert_eq!(extract_grpid(&mimeparser, HeaderDef::References), grpid); } #[test] @@ -1699,7 +1695,7 @@ mod tests { hello\x00"; let mimeparser = MimeParser::from_bytes(&context.ctx, &raw[..]).unwrap(); let grpid = Some("HcxyMARjyJy".to_string()); - assert_eq!(get_grpid_from_list(&mimeparser, "In-Reply-To"), grpid); - assert_eq!(get_grpid_from_list(&mimeparser, "References"), grpid); + assert_eq!(extract_grpid(&mimeparser, HeaderDef::InReplyTo), grpid); + assert_eq!(extract_grpid(&mimeparser, HeaderDef::References), grpid); } } diff --git a/src/headerdef.rs b/src/headerdef.rs new file mode 100644 index 000000000..ab19c33c7 --- /dev/null +++ b/src/headerdef.rs @@ -0,0 +1,104 @@ +use crate::strum::EnumProperty; + +#[derive(Debug, Clone, PartialEq, Eq, EnumProperty)] +pub enum HeaderDef { + #[strum(props(header = "message-id"))] + MessageId, + + #[strum(props(header = "subject"))] + Subject, + + #[strum(props(header = "date"))] + Date, + + #[strum(props(header = "from"))] + From_, + + #[strum(props(header = "to"))] + To, + + #[strum(props(header = "cc"))] + Cc, + + #[strum(props(header = "disposition"))] + Disposition, + + #[strum(props(header = "original-message-id"))] + OriginalMessageId, + + #[strum(props(header = "list-id"))] + ListId, + + #[strum(props(header = "references"))] + References, + + #[strum(props(header = "in-reply-to"))] + InReplyTo, + + #[strum(props(header = "precedence"))] + Precedence, + + #[strum(props(header = "chat-version"))] + ChatVersion, + + #[strum(props(header = "chat-group-id"))] + ChatGroupId, + + #[strum(props(header = "chat-group-name"))] + ChatGroupName, + + #[strum(props(header = "chat-group-name-changed"))] + ChatGroupNameChanged, + + #[strum(props(header = "chat-verified"))] + ChatVerified, + + #[strum(props(header = "chat-group-image"))] + ChatGroupImage, + + #[strum(props(header = "chat-voice-message"))] + ChatVoiceMessage, + + #[strum(props(header = "chat-group-member-removed"))] + ChatGroupMemberRemoved, + + #[strum(props(header = "chat-group-member-added"))] + ChatGroupMemberAdded, + + #[strum(props(header = "chat-content"))] + ChatContent, + + #[strum(props(header = "chat-duration"))] + ChatDuration, + + #[strum(props(header = "chat-disposition-notification-to"))] + ChatDispositionNotificationTo, + + #[strum(props(header = "autocrypt-setup-message"))] + AutocryptSetupMessage, + + #[strum(props(header = "secure-join"))] + SecureJoin, + + #[strum(props(header = "secure-join-group"))] + SecureJoinGroup, + + #[strum(props(header = "secure-join-fingerprint"))] + SecureJoinFingerprint, + + #[strum(props(header = "secure-join-invitenumber"))] + SecureJoinInvitenumber, + + #[strum(props(header = "secure-join-group"))] + SecureJoinAuth, + + #[strum(props(header = "test-header"))] + _TestHeader, +} + +impl HeaderDef { + /// Returns the corresponding Event id. + pub fn get_headername(&self) -> &str { + self.get_str("header").expect("missing header definition") + } +} diff --git a/src/lib.rs b/src/lib.rs index dd9d9833d..fe0bbef0b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,6 +33,8 @@ mod log; #[macro_use] pub mod error; +pub mod headerdef; + pub(crate) mod events; pub use events::*; diff --git a/src/mimeparser.rs b/src/mimeparser.rs index ad157ccea..f70921e03 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -14,6 +14,7 @@ use crate::dc_simplify::*; use crate::dc_tools::*; use crate::e2ee; use crate::error::Result; +use crate::headerdef::HeaderDef; use crate::job::{job_add, Action}; use crate::location; use crate::message; @@ -28,7 +29,7 @@ use crate::{bail, ensure}; pub struct MimeParser<'a> { pub context: &'a Context, pub parts: Vec, - pub header: HashMap, + header: HashMap, pub decrypting_failed: bool, pub signatures: HashSet, pub gossipped_addr: HashSet, @@ -144,7 +145,7 @@ impl<'a> MimeParser<'a> { } fn parse_headers(&mut self) -> Result<()> { - if self.lookup_field("Autocrypt-Setup-Message").is_some() { + if self.get(HeaderDef::AutocryptSetupMessage).is_some() { let has_setup_file = self.parts.iter().any(|p| { p.mimetype.is_some() && p.mimetype.as_ref().unwrap().as_ref() == MIME_AC_SETUP_FILE }); @@ -175,12 +176,12 @@ impl<'a> MimeParser<'a> { } } } - } else if let Some(value) = self.lookup_field("Chat-Content") { + } else if let Some(value) = self.get(HeaderDef::ChatContent) { if value == "location-streaming-enabled" { self.is_system_message = SystemMessage::LocationStreamingEnabled; } } - if self.lookup_field("Chat-Group-Image").is_some() && !self.parts.is_empty() { + if self.get(HeaderDef::ChatGroupImage).is_some() && !self.parts.is_empty() { let textpart = &self.parts[0]; if textpart.typ == Viewtype::Text && self.parts.len() >= 2 { let imgpart = &mut self.parts[1]; @@ -255,13 +256,13 @@ impl<'a> MimeParser<'a> { } if self.parts.len() == 1 { if self.parts[0].typ == Viewtype::Audio - && self.lookup_field("Chat-Voice-Message").is_some() + && self.get(HeaderDef::ChatVoiceMessage).is_some() { let part_mut = &mut self.parts[0]; part_mut.typ = Viewtype::Voice; } if self.parts[0].typ == Viewtype::Image { - if let Some(value) = self.lookup_field("Chat-Content") { + if let Some(value) = self.get(HeaderDef::ChatContent) { if value == "sticker" { let part_mut = &mut self.parts[0]; part_mut.typ = Viewtype::Sticker; @@ -273,7 +274,7 @@ impl<'a> MimeParser<'a> { || part.typ == Viewtype::Voice || part.typ == Viewtype::Video { - if let Some(field_0) = self.lookup_field("Chat-Duration") { + if let Some(field_0) = self.get(HeaderDef::ChatDuration) { let duration_ms = field_0.parse().unwrap_or_default(); if duration_ms > 0 && duration_ms < 24 * 60 * 60 * 1000 { let part_mut = &mut self.parts[0]; @@ -283,12 +284,12 @@ impl<'a> MimeParser<'a> { } } if !self.decrypting_failed { - if let Some(dn_field) = self.lookup_field("Chat-Disposition-Notification-To") { + if let Some(dn_field) = self.get(HeaderDef::ChatDispositionNotificationTo) { if self.get_last_nonmeta().is_some() { let addrs = mailparse::addrparse(&dn_field).unwrap(); if let Some(dn_to_addr) = addrs.first() { - if let Some(from_field) = self.lookup_field("From") { + if let Some(from_field) = self.get(HeaderDef::From_) { let from_addrs = mailparse::addrparse(&from_field).unwrap(); if let Some(from_addr) = from_addrs.first() { @@ -338,7 +339,7 @@ impl<'a> MimeParser<'a> { } pub(crate) fn get_subject(&self) -> Option { - if let Some(s) = self.header.get("subject") { + if let Some(s) = self.get(HeaderDef::Subject) { if s.is_empty() { return None; } @@ -348,8 +349,8 @@ impl<'a> MimeParser<'a> { } } - pub fn lookup_field(&self, field_name: &str) -> Option<&String> { - self.header.get(&field_name.to_lowercase()) + pub fn get(&self, headerdef: HeaderDef) -> Option<&String> { + self.header.get(headerdef.get_headername()) } fn parse_mime_recursive(&mut self, mail: &mailparse::ParsedMail<'_>) -> Result { @@ -649,11 +650,11 @@ impl<'a> MimeParser<'a> { } pub fn is_mailinglist_message(&self) -> bool { - if self.lookup_field("List-Id").is_some() { + if self.get(HeaderDef::ListId).is_some() { return true; } - if let Some(precedence) = self.lookup_field("Precedence") { + if let Some(precedence) = self.get(HeaderDef::Precedence) { precedence == "list" || precedence == "bulk" } else { false @@ -662,7 +663,7 @@ impl<'a> MimeParser<'a> { pub fn sender_equals_recipient(&self) -> bool { /* get From: and check there is exactly one sender */ - if let Some(field) = self.lookup_field("From") { + if let Some(field) = self.get(HeaderDef::From_) { if let Ok(addrs) = mailparse::addrparse(field) { if addrs.len() != 1 { return false; @@ -693,11 +694,11 @@ impl<'a> MimeParser<'a> { } pub fn get_rfc724_mid(&self) -> Option { - // get Message-ID from header - if let Some(field) = self.lookup_field("Message-ID") { - return parse_message_id(field); + if let Some(msgid) = self.get(HeaderDef::MessageId) { + parse_message_id(msgid) + } else { + None } - None } fn hash_header(&mut self, fields: &[mailparse::MailHeader<'_>]) { @@ -727,9 +728,10 @@ impl<'a> MimeParser<'a> { let (report_fields, _) = mailparse::parse_headers(&report_body)?; // must be present - if let Some(_disposition) = report_fields.get_first_value("Disposition").ok().flatten() { + let disp = HeaderDef::Disposition.get_headername(); + if let Some(_disposition) = report_fields.get_first_value(disp).ok().flatten() { if let Some(original_message_id) = report_fields - .get_first_value("Original-Message-ID") + .get_first_value(HeaderDef::OriginalMessageId.get_headername()) .ok() .flatten() .and_then(|v| parse_message_id(&v)) @@ -1108,14 +1110,14 @@ mod tests { let raw = b"From: hello\n\ Content-Type: multipart/mixed; boundary=\"==break==\";\n\ Subject: outer-subject\n\ - X-Special-A: special-a\n\ - Foo: Bar\nChat-Version: 0.0\n\ + Secure-Join-Group: no\n\ + Test-Header: Bar\nChat-Version: 0.0\n\ \n\ --==break==\n\ Content-Type: text/plain; protected-headers=\"v1\";\n\ Subject: inner-subject\n\ - X-Special-B: special-b\n\ - Foo: Xy\n\ + SecureBar-Join-Group: yes\n\ + Test-Header: Xy\n\ Chat-Version: 1.0\n\ \n\ test1\n\ @@ -1124,16 +1126,19 @@ mod tests { \n\ \x00"; let mimeparser = MimeParser::from_bytes(&context.ctx, &raw[..]).unwrap(); - + + // test that we treat Subject as a protected header that can + // bubble upwards assert_eq!(mimeparser.get_subject(), Some("inner-subject".into())); - let of = mimeparser.lookup_field("X-Special-A").unwrap(); - assert_eq!(of, "special-a"); + let of = mimeparser.get(HeaderDef::SecureJoinGroup).unwrap(); + assert_eq!(of, "no"); - let of = mimeparser.lookup_field("Foo").unwrap(); + // unprotected headers do not bubble upwards + let of = mimeparser.get(HeaderDef::_TestHeader).unwrap(); assert_eq!(of, "Bar"); - let of = mimeparser.lookup_field("Chat-Version").unwrap(); + let of = mimeparser.get(HeaderDef::ChatVersion).unwrap(); assert_eq!(of, "1.0"); assert_eq!(mimeparser.parts.len(), 1); } diff --git a/src/securejoin.rs b/src/securejoin.rs index ae493d4ee..26624958b 100644 --- a/src/securejoin.rs +++ b/src/securejoin.rs @@ -11,6 +11,7 @@ use crate::context::Context; use crate::e2ee::*; use crate::error::Error; use crate::events::Event; +use crate::headerdef::HeaderDef; use crate::key::*; use crate::lot::LotState; use crate::message::Message; @@ -350,7 +351,7 @@ pub(crate) fn handle_securejoin_handshake( "handle_securejoin_handshake(): called with special contact id" ); let step = mimeparser - .lookup_field("Secure-Join") + .get(HeaderDef::SecureJoin) .ok_or_else(|| format_err!("This message is not a Secure-Join message"))?; info!( @@ -378,7 +379,7 @@ pub(crate) fn handle_securejoin_handshake( // it just ensures, we have Bobs key now. If we do _not_ have the key because eg. MitM has removed it, // send_message() will fail with the error "End-to-end-encryption unavailable unexpectedly.", so, there is no additional check needed here. // verify that the `Secure-Join-Invitenumber:`-header matches invitenumber written to the QR code - let invitenumber = match mimeparser.lookup_field("Secure-Join-Invitenumber") { + let invitenumber = match mimeparser.get(HeaderDef::SecureJoinInvitenumber) { Some(n) => n, None => { warn!(context, "Secure-join denied (invitenumber missing).",); @@ -467,7 +468,7 @@ pub(crate) fn handle_securejoin_handshake( ==== Step 6 in "Out-of-band verified groups" protocol ==== ============================================================ */ // verify that Secure-Join-Fingerprint:-header matches the fingerprint of Bob - let fingerprint = match mimeparser.lookup_field("Secure-Join-Fingerprint") { + let fingerprint = match mimeparser.get(HeaderDef::SecureJoinFingerprint) { Some(fp) => fp, None => { could_not_establish_secure_connection( @@ -496,7 +497,7 @@ pub(crate) fn handle_securejoin_handshake( } info!(context, "Fingerprint verified.",); // verify that the `Secure-Join-Auth:`-header matches the secret written to the QR code - let auth_0 = match mimeparser.lookup_field("Secure-Join-Auth") { + let auth_0 = match mimeparser.get(HeaderDef::SecureJoinAuth) { Some(auth) => auth, None => { could_not_establish_secure_connection( @@ -526,7 +527,7 @@ pub(crate) fn handle_securejoin_handshake( inviter_progress!(context, contact_id, 600); if join_vg { let field_grpid = mimeparser - .lookup_field("Secure-Join-Group") + .get(HeaderDef::SecureJoinGroup) .map(|s| s.as_str()) .unwrap_or_else(|| ""); let (group_chat_id, _, _) = chat::get_chat_id_by_grpid(context, field_grpid); @@ -600,7 +601,7 @@ pub(crate) fn handle_securejoin_handshake( Contact::scaleup_origin_by_id(context, contact_id, Origin::SecurejoinJoined); emit_event!(context, Event::ContactsChanged(None)); let cg_member_added = mimeparser - .lookup_field("Chat-Group-Member-Added") + .get(HeaderDef::ChatGroupMemberAdded) .map(|s| s.as_str()) .unwrap_or_else(|| ""); if join_vg && !addr_equals_self(context, cg_member_added) { @@ -635,7 +636,7 @@ pub(crate) fn handle_securejoin_handshake( inviter_progress!(context, contact_id, 800); inviter_progress!(context, contact_id, 1000); let field_grpid = mimeparser - .lookup_field("Secure-Join-Group") + .get(HeaderDef::SecureJoinGroup) .map(|s| s.as_str()) .unwrap_or_else(|| ""); let (group_chat_id, _, _) = chat::get_chat_id_by_grpid(context, &field_grpid);