mirror of
https://github.com/chatmail/core.git
synced 2026-05-23 16:56:30 +03:00
fix: do not fail to receive post-message with status updates for deleted webxdc
receive_imf should not fail in this case, but trash the post-message and updates. The problem with previously used message::rfc724_mid_exists check was that rfc724_mid_exists may return a trashed message.
This commit is contained in:
@@ -602,6 +602,35 @@ impl Message {
|
||||
Ok(msg)
|
||||
}
|
||||
|
||||
/// Loads the message with given Message-ID from the database.
|
||||
///
|
||||
/// Cannot return a trashed message.
|
||||
pub async fn load_by_rfc724_mid_optional(
|
||||
context: &Context,
|
||||
rfc724_mid: &str,
|
||||
) -> Result<Option<Message>> {
|
||||
if let Some(msg_id) = context
|
||||
.sql
|
||||
.query_row_optional(
|
||||
"SELECT id FROM msgs WHERE rfc724_mid=? AND chat_id != ?",
|
||||
(rfc724_mid, DC_CHAT_ID_TRASH),
|
||||
|row| {
|
||||
let msg_id: MsgId = row.get(0)?;
|
||||
Ok(msg_id)
|
||||
},
|
||||
)
|
||||
.await?
|
||||
{
|
||||
// Non-trashed message exists, load it.
|
||||
let msg = Self::load_from_db(context, msg_id)
|
||||
.await
|
||||
.context("Failed to load the message we just checked exists")?;
|
||||
Ok(Some(msg))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns additional text which is appended to the message's text field
|
||||
/// when it is loaded from the database.
|
||||
/// Currently this is used to add infomation to pre-messages of what the download will be and how large it is
|
||||
|
||||
@@ -835,21 +835,16 @@ UPDATE config SET value=? WHERE keyname='configured_addr' AND value!=?1
|
||||
{
|
||||
can_info_msg = false;
|
||||
if mime_parser.pre_message == PreMessageMode::Post
|
||||
&& let Some(msg_id) = message::rfc724_mid_exists(context, rfc724_mid_orig).await?
|
||||
&& let Some(msg) =
|
||||
Message::load_by_rfc724_mid_optional(context, rfc724_mid_orig).await?
|
||||
{
|
||||
// The messsage is a post-message and pre-message exists.
|
||||
// Assign status update to existing message because just received post-message will be trashed.
|
||||
Some(
|
||||
Message::load_from_db(context, msg_id)
|
||||
.await
|
||||
.context("Failed to load webxdc instance that we just checked exists")?,
|
||||
)
|
||||
Some(msg)
|
||||
} else {
|
||||
Some(
|
||||
Message::load_from_db(context, insert_msg_id)
|
||||
.await
|
||||
.context("Failed to load just created webxdc instance")?,
|
||||
)
|
||||
Message::load_from_db_optional(context, insert_msg_id)
|
||||
.await
|
||||
.context("Failed to load just created webxdc instance")?
|
||||
}
|
||||
} else if let Some(field) = mime_parser.get_header(HeaderDef::InReplyTo) {
|
||||
if let Some(instance) =
|
||||
|
||||
@@ -565,6 +565,45 @@ async fn test_webxdc_updates_in_post_message_after_pre_message() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_webxdc_updates_in_post_message_after_deleted_pre_message() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
|
||||
let alice_chat_id = alice.create_chat_id(bob).await;
|
||||
let big_webxdc_app = big_webxdc_app().await?;
|
||||
|
||||
let mut alice_instance = Message::new(Viewtype::Webxdc);
|
||||
alice_instance.set_file_from_bytes(alice, "test.xdc", &big_webxdc_app, None)?;
|
||||
alice_instance.set_text("Test".to_string());
|
||||
alice_chat_id
|
||||
.set_draft(alice, Some(&mut alice_instance))
|
||||
.await?;
|
||||
alice
|
||||
.send_webxdc_status_update(alice_instance.id, r#"{"payload":42, "info":"i"}"#)
|
||||
.await?;
|
||||
|
||||
send_msg(alice, alice_chat_id, &mut alice_instance).await?;
|
||||
let post_message = alice.pop_sent_msg().await;
|
||||
let pre_message = alice.pop_sent_msg().await;
|
||||
|
||||
let bob_instance = bob.recv_msg(&pre_message).await;
|
||||
assert_eq!(bob_instance.download_state, DownloadState::Available);
|
||||
delete_msgs(bob, &[bob_instance.id]).await?;
|
||||
|
||||
bob.recv_msg_trash(&post_message).await;
|
||||
|
||||
// Deleted message stays trashed because of a tombstone.
|
||||
assert!(
|
||||
Message::load_from_db_optional(bob, bob_instance.id)
|
||||
.await?
|
||||
.is_none()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Tests receiving of a large webxdc post-message with updates attached
|
||||
/// to the the .xdc post-message when pre-message arrives later.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
|
||||
Reference in New Issue
Block a user