message deletion request API (#6576)

this PR adds an API allowing users to delete their messages on other
member's devices

this PR is build on top of
https://github.com/deltachat/deltachat-core-rust/pull/6573 which should
be merged first

a test is missing, otherwise ready for review; it is working already in
https://github.com/deltachat/deltachat-ios/pull/2611
This commit is contained in:
bjoern
2025-02-26 19:02:50 +01:00
committed by GitHub
parent a4e478a071
commit c58f6107ba
9 changed files with 167 additions and 13 deletions

View File

@@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
use tokio::{fs, io};
use crate::blob::BlobObject;
use crate::chat::{Chat, ChatId, ChatIdBlocked, ChatVisibility};
use crate::chat::{send_msg, Chat, ChatId, ChatIdBlocked, ChatVisibility};
use crate::chatlist_events;
use crate::config::Config;
use crate::constants::{
@@ -1711,20 +1711,31 @@ pub(crate) async fn delete_msgs_locally_done(
Ok(())
}
/// Deletes requested messages
/// by moving them to the trash chat
/// and scheduling for deletion on IMAP.
/// Delete messages on all devices and on IMAP.
pub async fn delete_msgs(context: &Context, msg_ids: &[MsgId]) -> Result<()> {
delete_msgs_ex(context, msg_ids, false).await
}
/// Delete messages on all devices, on IMAP and optionally for all chat members.
/// Deleted messages are moved to the trash chat and scheduling for deletion on IMAP.
/// When deleting messages for others, all messages must be self-sent and in the same chat.
pub async fn delete_msgs_ex(
context: &Context,
msg_ids: &[MsgId],
delete_for_all: bool,
) -> Result<()> {
let mut modified_chat_ids = HashSet::new();
let mut deleted_rfc724_mid = Vec::new();
let mut res = Ok(());
for &msg_id in msg_ids {
let msg = Message::load_from_db(context, msg_id).await?;
delete_msg_locally(context, &msg).await?;
ensure!(
!delete_for_all || msg.from_id == ContactId::SELF,
"Can delete only own messages for others"
);
modified_chat_ids.insert(msg.chat_id);
deleted_rfc724_mid.push(msg.rfc724_mid.clone());
let target = context.get_delete_msgs_target().await?;
@@ -1744,13 +1755,32 @@ pub async fn delete_msgs(context: &Context, msg_ids: &[MsgId]) -> Result<()> {
}
res?;
delete_msgs_locally_done(context, msg_ids, modified_chat_ids).await?;
if delete_for_all {
ensure!(
modified_chat_ids.len() == 1,
"Can delete only from same chat."
);
if let Some(chat_id) = modified_chat_ids.iter().next() {
let mut msg = Message::new_text("🚮".to_owned());
msg.param.set_int(Param::GuaranteeE2ee, 1);
msg.param
.set(Param::DeleteRequestFor, deleted_rfc724_mid.join(" "));
msg.hidden = true;
send_msg(context, *chat_id, &mut msg).await?;
}
} else {
context
.add_sync_item(SyncData::DeleteMessages {
msgs: deleted_rfc724_mid,
})
.await?;
}
context
.add_sync_item(SyncData::DeleteMessages {
msgs: deleted_rfc724_mid,
})
.await?;
for &msg_id in msg_ids {
let msg = Message::load_from_db(context, msg_id).await?;
delete_msg_locally(context, &msg).await?;
}
delete_msgs_locally_done(context, msg_ids, modified_chat_ids).await?;
// Interrupt Inbox loop to start message deletion, run housekeeping and call send_sync_msg().
context.scheduler.interrupt_inbox().await;