mirror of
https://github.com/chatmail/core.git
synced 2026-05-07 08:56:30 +03:00
feat: add decryption error to the device message about outgoing message decryption failure
This commit is contained in:
@@ -2792,7 +2792,7 @@ async fn test_broadcast_members_cant_see_each_other() -> Result<()> {
|
|||||||
assert_eq!(parsed.decoded_data_contains("bob@example.net"), false);
|
assert_eq!(parsed.decoded_data_contains("bob@example.net"), false);
|
||||||
|
|
||||||
let parsed_by_bob = bob.parse_msg(&vc_pubkey).await;
|
let parsed_by_bob = bob.parse_msg(&vc_pubkey).await;
|
||||||
assert!(parsed_by_bob.decrypting_failed);
|
assert!(parsed_by_bob.decryption_error.is_some());
|
||||||
|
|
||||||
charlie.recv_msg_trash(&vc_pubkey).await;
|
charlie.recv_msg_trash(&vc_pubkey).await;
|
||||||
}
|
}
|
||||||
@@ -2821,7 +2821,7 @@ async fn test_broadcast_members_cant_see_each_other() -> Result<()> {
|
|||||||
assert_eq!(parsed.decoded_data_contains("bob@example.net"), false);
|
assert_eq!(parsed.decoded_data_contains("bob@example.net"), false);
|
||||||
|
|
||||||
let parsed_by_bob = bob.parse_msg(&member_added).await;
|
let parsed_by_bob = bob.parse_msg(&member_added).await;
|
||||||
assert!(parsed_by_bob.decrypting_failed);
|
assert!(parsed_by_bob.decryption_error.is_some());
|
||||||
|
|
||||||
let rcvd = charlie.recv_msg(&member_added).await;
|
let rcvd = charlie.recv_msg(&member_added).await;
|
||||||
assert_eq!(rcvd.param.get_cmd(), SystemMessage::MemberAddedToGroup);
|
assert_eq!(rcvd.param.get_cmd(), SystemMessage::MemberAddedToGroup);
|
||||||
@@ -2836,7 +2836,7 @@ async fn test_broadcast_members_cant_see_each_other() -> Result<()> {
|
|||||||
assert_eq!(parsed.decoded_data_contains("bob@example.net"), false);
|
assert_eq!(parsed.decoded_data_contains("bob@example.net"), false);
|
||||||
|
|
||||||
let parsed_by_bob = bob.parse_msg(&hi_msg).await;
|
let parsed_by_bob = bob.parse_msg(&hi_msg).await;
|
||||||
assert_eq!(parsed_by_bob.decrypting_failed, false);
|
assert!(parsed_by_bob.decryption_error.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
tcm.section("Alice removes Charlie. Bob must not see it.");
|
tcm.section("Alice removes Charlie. Bob must not see it.");
|
||||||
@@ -2853,7 +2853,7 @@ async fn test_broadcast_members_cant_see_each_other() -> Result<()> {
|
|||||||
assert_eq!(parsed.decoded_data_contains("bob@example.net"), false);
|
assert_eq!(parsed.decoded_data_contains("bob@example.net"), false);
|
||||||
|
|
||||||
let parsed_by_bob = bob.parse_msg(&member_removed).await;
|
let parsed_by_bob = bob.parse_msg(&member_removed).await;
|
||||||
assert!(parsed_by_bob.decrypting_failed);
|
assert!(parsed_by_bob.decryption_error.is_some());
|
||||||
|
|
||||||
let rcvd = charlie.recv_msg(&member_removed).await;
|
let rcvd = charlie.recv_msg(&member_removed).await;
|
||||||
assert_eq!(rcvd.param.get_cmd(), SystemMessage::MemberRemovedFromGroup);
|
assert_eq!(rcvd.param.get_cmd(), SystemMessage::MemberRemovedFromGroup);
|
||||||
|
|||||||
@@ -86,7 +86,9 @@ pub(crate) struct MimeMessage {
|
|||||||
/// messages to this address to post them to the list.
|
/// messages to this address to post them to the list.
|
||||||
pub list_post: Option<String>,
|
pub list_post: Option<String>,
|
||||||
pub chat_disposition_notification_to: Option<SingleInfo>,
|
pub chat_disposition_notification_to: Option<SingleInfo>,
|
||||||
pub decrypting_failed: bool,
|
|
||||||
|
/// Decryption error if decryption of the message has failed.
|
||||||
|
pub decryption_error: Option<String>,
|
||||||
|
|
||||||
/// Valid signature fingerprint if a message is an
|
/// Valid signature fingerprint if a message is an
|
||||||
/// Autocrypt encrypted and signed message and corresponding intended recipient fingerprints
|
/// Autocrypt encrypted and signed message and corresponding intended recipient fingerprints
|
||||||
@@ -664,7 +666,7 @@ impl MimeMessage {
|
|||||||
from,
|
from,
|
||||||
incoming,
|
incoming,
|
||||||
chat_disposition_notification_to,
|
chat_disposition_notification_to,
|
||||||
decrypting_failed: mail.is_err(),
|
decryption_error: mail.err().map(|err| format!("{err:#}")),
|
||||||
|
|
||||||
// only non-empty if it was a valid autocrypt message
|
// only non-empty if it was a valid autocrypt message
|
||||||
signature,
|
signature,
|
||||||
@@ -905,7 +907,7 @@ impl MimeMessage {
|
|||||||
&& let Some(ref subject) = self.get_subject()
|
&& let Some(ref subject) = self.get_subject()
|
||||||
{
|
{
|
||||||
let mut prepend_subject = true;
|
let mut prepend_subject = true;
|
||||||
if !self.decrypting_failed {
|
if self.decryption_error.is_none() {
|
||||||
let colon = subject.find(':');
|
let colon = subject.find(':');
|
||||||
if colon == Some(2)
|
if colon == Some(2)
|
||||||
|| colon == Some(3)
|
|| colon == Some(3)
|
||||||
@@ -946,7 +948,7 @@ impl MimeMessage {
|
|||||||
self.parse_attachments();
|
self.parse_attachments();
|
||||||
|
|
||||||
// See if an MDN is requested from the other side
|
// See if an MDN is requested from the other side
|
||||||
if !self.decrypting_failed
|
if self.decryption_error.is_none()
|
||||||
&& !self.parts.is_empty()
|
&& !self.parts.is_empty()
|
||||||
&& let Some(ref dn_to) = self.chat_disposition_notification_to
|
&& let Some(ref dn_to) = self.chat_disposition_notification_to
|
||||||
{
|
{
|
||||||
@@ -1078,7 +1080,7 @@ impl MimeMessage {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
/// Returns whether the decrypted data contains the given `&str`.
|
/// Returns whether the decrypted data contains the given `&str`.
|
||||||
pub(crate) fn decoded_data_contains(&self, s: &str) -> bool {
|
pub(crate) fn decoded_data_contains(&self, s: &str) -> bool {
|
||||||
assert!(!self.decrypting_failed);
|
assert!(self.decryption_error.is_none());
|
||||||
let decoded_str = str::from_utf8(&self.decoded_data).unwrap();
|
let decoded_str = str::from_utf8(&self.decoded_data).unwrap();
|
||||||
decoded_str.contains(s)
|
decoded_str.contains(s)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -727,7 +727,7 @@ pub(crate) async fn receive_imf_inner(
|
|||||||
let show_emails = ShowEmails::from_i32(context.get_config_int(Config::ShowEmails).await?)
|
let show_emails = ShowEmails::from_i32(context.get_config_int(Config::ShowEmails).await?)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let allow_creation = if mime_parser.decrypting_failed {
|
let allow_creation = if mime_parser.decryption_error.is_some() {
|
||||||
false
|
false
|
||||||
} else if is_dc_message == MessengerMessage::No
|
} else if is_dc_message == MessengerMessage::No
|
||||||
&& !context.get_config_bool(Config::IsChatmail).await?
|
&& !context.get_config_bool(Config::IsChatmail).await?
|
||||||
@@ -1211,14 +1211,18 @@ async fn decide_chat_assignment(
|
|||||||
{
|
{
|
||||||
info!(context, "Call state changed (TRASH).");
|
info!(context, "Call state changed (TRASH).");
|
||||||
true
|
true
|
||||||
} else if mime_parser.decrypting_failed && !mime_parser.incoming {
|
} else if let Some(ref decryption_error) = mime_parser.decryption_error
|
||||||
|
&& !mime_parser.incoming
|
||||||
|
{
|
||||||
// Outgoing undecryptable message.
|
// Outgoing undecryptable message.
|
||||||
let last_time = context
|
let last_time = context
|
||||||
.get_config_i64(Config::LastCantDecryptOutgoingMsgs)
|
.get_config_i64(Config::LastCantDecryptOutgoingMsgs)
|
||||||
.await?;
|
.await?;
|
||||||
let now = tools::time();
|
let now = tools::time();
|
||||||
let update_config = if last_time.saturating_add(24 * 60 * 60) <= now {
|
let update_config = if last_time.saturating_add(24 * 60 * 60) <= now {
|
||||||
let txt = "⚠️ It seems you are using Delta Chat on multiple devices that cannot decrypt each other's outgoing messages. To fix this, on the older device use \"Settings / Add Second Device\" and follow the instructions.";
|
let txt = format!(
|
||||||
|
"⚠️ It seems you are using Delta Chat on multiple devices that cannot decrypt each other's outgoing messages. To fix this, on the older device use \"Settings / Add Second Device\" and follow the instructions. (Error: {decryption_error}, {rfc724_mid})."
|
||||||
|
);
|
||||||
let mut msg = Message::new_text(txt.to_string());
|
let mut msg = Message::new_text(txt.to_string());
|
||||||
chat::add_device_msg(context, None, Some(&mut msg))
|
chat::add_device_msg(context, None, Some(&mut msg))
|
||||||
.await
|
.await
|
||||||
@@ -2290,7 +2294,7 @@ RETURNING id
|
|||||||
if trash { 0 } else { ephemeral_timestamp },
|
if trash { 0 } else { ephemeral_timestamp },
|
||||||
if trash {
|
if trash {
|
||||||
DownloadState::Done
|
DownloadState::Done
|
||||||
} else if mime_parser.decrypting_failed {
|
} else if mime_parser.decryption_error.is_some() {
|
||||||
DownloadState::Undecipherable
|
DownloadState::Undecipherable
|
||||||
} else if let PreMessageMode::Pre {..} = mime_parser.pre_message {
|
} else if let PreMessageMode::Pre {..} = mime_parser.pre_message {
|
||||||
DownloadState::Available
|
DownloadState::Available
|
||||||
@@ -2703,7 +2707,7 @@ async fn lookup_or_create_adhoc_group(
|
|||||||
allow_creation: bool,
|
allow_creation: bool,
|
||||||
create_blocked: Blocked,
|
create_blocked: Blocked,
|
||||||
) -> Result<Option<(ChatId, Blocked, bool)>> {
|
) -> Result<Option<(ChatId, Blocked, bool)>> {
|
||||||
if mime_parser.decrypting_failed {
|
if mime_parser.decryption_error.is_some() {
|
||||||
warn!(
|
warn!(
|
||||||
context,
|
context,
|
||||||
"Not creating ad-hoc group for message that cannot be decrypted."
|
"Not creating ad-hoc group for message that cannot be decrypted."
|
||||||
@@ -2925,7 +2929,7 @@ async fn create_group(
|
|||||||
|
|
||||||
if let Some(chat_id) = chat_id {
|
if let Some(chat_id) = chat_id {
|
||||||
Ok(Some((chat_id, chat_id_blocked)))
|
Ok(Some((chat_id, chat_id_blocked)))
|
||||||
} else if mime_parser.decrypting_failed {
|
} else if mime_parser.decryption_error.is_some() {
|
||||||
// It is possible that the message was sent to a valid,
|
// It is possible that the message was sent to a valid,
|
||||||
// yet unknown group, which was rejected because
|
// yet unknown group, which was rejected because
|
||||||
// Chat-Group-Name, which is in the encrypted part, was
|
// Chat-Group-Name, which is in the encrypted part, was
|
||||||
|
|||||||
@@ -3327,7 +3327,7 @@ async fn test_outgoing_undecryptable() -> Result<()> {
|
|||||||
assert!(
|
assert!(
|
||||||
dev_msg
|
dev_msg
|
||||||
.text
|
.text
|
||||||
.contains("⚠️ It seems you are using Delta Chat on multiple devices that cannot decrypt each other's outgoing messages. To fix this, on the older device use \"Settings / Add Second Device\" and follow the instructions.")
|
.starts_with("⚠️ It seems you are using Delta Chat on multiple devices that cannot decrypt each other's outgoing messages. To fix this, on the older device use \"Settings / Add Second Device\" and follow the instructions. (Error:")
|
||||||
);
|
);
|
||||||
|
|
||||||
let raw = include_bytes!("../../test-data/message/thunderbird_encrypted_signed.eml");
|
let raw = include_bytes!("../../test-data/message/thunderbird_encrypted_signed.eml");
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ async fn test_sending_pre_message() -> Result<()> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let decrypted_post_message = bob.parse_msg(post_message).await;
|
let decrypted_post_message = bob.parse_msg(post_message).await;
|
||||||
assert_eq!(decrypted_post_message.decrypting_failed, false);
|
assert!(decrypted_post_message.decryption_error.is_none());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
decrypted_post_message.header_exists(HeaderDef::ChatPostMessageId),
|
decrypted_post_message.header_exists(HeaderDef::ChatPostMessageId),
|
||||||
false
|
false
|
||||||
|
|||||||
Reference in New Issue
Block a user