diff --git a/src/chat.rs b/src/chat.rs index 48f22e44b..b938fd5a9 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -424,7 +424,7 @@ impl ChatId { async fn get_parent_mime_headers(self, context: &Context) -> Option<(String, String, String)> { let collect = |row: &rusqlite::Row| Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?)); - let (packed, rfc724_mid, mime_in_reply_to, mime_references): ( + let (rfc724_mid, mime_in_reply_to, mime_references, error): ( String, String, String, @@ -432,15 +432,14 @@ impl ChatId { ) = self .parent_query( context, - "param, rfc724_mid, mime_in_reply_to, mime_references", + "rfc724_mid, mime_in_reply_to, mime_references, error", collect, ) .await .ok() .flatten()?; - let param = packed.parse::().ok()?; - if param.exists(Param::Error) { + if !error.is_empty() { // Do not reply to error messages. // // An error message could be a group chat message that we failed to decrypt and @@ -454,12 +453,13 @@ impl ChatId { } async fn parent_is_encrypted(self, context: &Context) -> Result { - let collect = |row: &rusqlite::Row| Ok(row.get(0)?); - let packed: Option = self.parent_query(context, "param", collect).await?; + let collect = |row: &rusqlite::Row| Ok((row.get(0)?, row.get(1)?)); + let res: Option<(String, String)> = + self.parent_query(context, "param, error", collect).await?; - if let Some(ref packed) = packed { + if let Some((ref packed, ref error)) = res { let param = packed.parse::()?; - Ok(!param.exists(Param::Error) && param.exists(Param::GuaranteeE2ee)) + Ok(error.is_empty() && param.exists(Param::GuaranteeE2ee)) } else { // No messages Ok(false) diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index eda689103..89f582293 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -665,8 +665,8 @@ async fn add_parts( "INSERT INTO msgs \ (rfc724_mid, server_folder, server_uid, chat_id, from_id, to_id, timestamp, \ timestamp_sent, timestamp_rcvd, type, state, msgrmsg, txt, txt_raw, param, \ - bytes, hidden, mime_headers, mime_in_reply_to, mime_references) \ - VALUES (?,?,?,?,?,?, ?,?,?,?,?,?, ?,?,?,?,?,?, ?,?);", + bytes, hidden, mime_headers, mime_in_reply_to, mime_references, error) \ + VALUES (?,?,?,?,?,?, ?,?,?,?,?,?, ?,?,?,?,?,?, ?,?, ?);", )?; let is_location_kml = location_kml_is @@ -710,6 +710,7 @@ async fn add_parts( mime_headers, mime_in_reply_to, mime_references, + part.error, ])?; drop(stmt); @@ -2337,20 +2338,52 @@ mod tests { } #[async_std::test] - async fn test_parse_ndn() { - let t = configured_offline_context().await; + async fn test_parse_ndn_gmail() { + test_parse_ndn( + "alice@gmail.com", + "assidhfaaspocwaeofi@gmail.com", + "CABXKi8zruXJc_6e4Dr087H5wE7sLp+u250o0N2q5DdjF_r-8wg@mail.gmail.com", + include_bytes!("../test-data/message/gmail_ndn.eml"), + "Delivery Status Notification (Failure) – ** Die Adresse wurde nicht gefunden **\n\nIhre Nachricht wurde nicht an assidhfaaspocwaeofi@gmail.com zugestellt, weil die Adresse nicht gefunden wurde oder keine E-Mails empfangen kann.\n\nHier erfahren Sie mehr: https://support.google.com/mail/?p=NoSuchUser\n\nAntwort:\n\n550 5.1.1 The email account that you tried to reach does not exist. Please try double-checking the recipient\'s email address for typos or unnecessary spaces. Learn more at https://support.google.com/mail/?p=NoSuchUser i18sor6261697wrs.38 - gsmtp", + ) + .await; + } + + async fn test_parse_ndn( + self_addr: &str, + foreign_addr: &str, + rfc724_mid_outgoing: &str, + raw_ndn: &[u8], + error_msg: &str, + ) { + let t = dummy_context().await; + t.ctx + .set_config(Config::Addr, Some(self_addr)) + .await + .unwrap(); + t.ctx + .set_config(Config::ConfiguredAddr, Some(self_addr)) + .await + .unwrap(); + t.ctx + .set_config(Config::Configured, Some("1")) + .await + .unwrap(); dc_receive_imf( &t.ctx, - b"From: alice@example.org\n\ - To: assidhfaaspocwaeofi@gmail.com\n\ + format!( + "From: {}\n\ + To: {}\n\ Subject: foo\n\ - Message-ID: \n\ + Message-ID: <{}>\n\ Chat-Version: 1.0\n\ - Chat-Disposition-Notification-To: alice@example.org\n\ Date: Sun, 22 Mar 2020 22:37:57 +0000\n\ \n\ hello\n", + self_addr, foreign_addr, rfc724_mid_outgoing + ) + .as_bytes(), "INBOX", 1, false, @@ -2361,18 +2394,13 @@ mod tests { let chats = Chatlist::try_load(&t.ctx, 0, None, None).await.unwrap(); let msg_id = chats.get_msg_id(0).unwrap(); - let raw = include_bytes!("../test-data/message/gmail_ndn.eml"); - dc_receive_imf(&t.ctx, raw, "INBOX", 1, false) + dc_receive_imf(&t.ctx, raw_ndn, "INBOX", 1, false) .await .unwrap(); - println!("Loading msg {}…", msg_id); let msg = Message::load_from_db(&t.ctx, msg_id).await.unwrap(); assert_eq!(msg.state, MessageState::OutFailed); - assert_eq!( - msg.error.as_ref().map(|s| s.as_str()), - Some("Delivery Status Notification (Failure) – ** Die Adresse wurde nicht gefunden **\n\nIhre Nachricht wurde nicht an assidhfaaspocwaeofi@gmail.com zugestellt, weil die Adresse nicht gefunden wurde oder keine E-Mails empfangen kann.\n\nHier erfahren Sie mehr: https://support.google.com/mail/?p=NoSuchUser\n\nAntwort:\n\n550 5.1.1 The email account that you tried to reach does not exist. Please try double-checking the recipient\'s email address for typos or unnecessary spaces. Learn more at https://support.google.com/mail/?p=NoSuchUser i18sor6261697wrs.38 - gsmtp") - ) + assert_eq!(msg.error, error_msg); } #[async_std::test] diff --git a/src/message.rs b/src/message.rs index 884c1a28f..ad6679b18 100644 --- a/src/message.rs +++ b/src/message.rs @@ -255,7 +255,7 @@ pub struct Message { pub(crate) starred: bool, pub(crate) chat_blocked: Blocked, pub(crate) location_id: u32, - pub(crate) error: Option, + pub(crate) error: String, pub(crate) param: Params, } @@ -941,10 +941,9 @@ pub async fn get_msg_info(context: &Context, msg_id: MsgId) -> String { } ret += "\n"; - if let Some(err) = &msg.error { - if !err.is_empty() { - ret += &format!("Error: {}", err) - } + + if !msg.error.is_empty() { + ret += &format!("Error: {}", msg.error); } if let Some(path) = msg.get_file(context) { @@ -1432,8 +1431,10 @@ pub async fn ndn_from_ext( if let Ok((msg_id, chat_id, chat_type, contact_id)) = res { set_msg_failed(context, msg_id, error).await; + info!(context, "cht {} {} {}", chat_id, chat_type, contact_id); if chat_type == Chattype::Group || chat_type == Chattype::VerifiedGroup { + info!(context, "Adding info msg to chat {}", chat_id); let contact = Contact::load_from_db(context, contact_id).await.unwrap(); chat::add_info_msg( context, @@ -1446,6 +1447,7 @@ pub async fn ndn_from_ext( .await, ) .await; + context.emit_event(Event::ChatModified(chat_id)); } } } diff --git a/src/mimeparser.rs b/src/mimeparser.rs index 1f4bae0f3..ecfdfaea9 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -529,7 +529,7 @@ impl MimeMessage { part.typ = Viewtype::Text; part.msg_raw = Some(txt.clone()); part.msg = txt; - part.param.set(Param::Error, "Decryption failed"); + part.error = "Decryption failed".to_string(); self.parts.push(part); @@ -1013,6 +1013,7 @@ pub struct Part { pub bytes: usize, pub param: Params, org_filename: Option, + pub error: String, } /// return mimetype and viewtype for a parsed mail