Skip to content

feat: Remove webxdc info messages together with webxdc #7021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use std::collections::BTreeSet;
use std::collections::HashSet;
use std::collections::VecDeque;
use std::path::{Path, PathBuf};
use std::str;

Expand Down Expand Up @@ -1713,6 +1714,35 @@ pub(crate) async fn delete_msg_locally(context: &Context, msg: &Message) -> Resu
Ok(())
}

pub(crate) async fn get_webxdc_info_messages(
context: &Context,
msg: &Message,
) -> Result<Vec<MsgId>> {
let msg_ids = context
.sql
.query_map(
r#"SELECT id, param
FROM msgs
WHERE chat_id=?1 AND hidden=0 AND mime_in_reply_to = ?2
"#,
(msg.chat_id, &msg.rfc724_mid),
|row| {
let info_msg_id: MsgId = row.get(0)?;
let last_param: Params = row.get::<_, String>(1)?.parse().unwrap_or_default();
Ok((info_msg_id, last_param))
},
|row| {
Ok(row
.filter_map(Result::ok)
.filter(|(_, param)| param.get_cmd() == SystemMessage::WebxdcInfoMessage)
.map(|(msg_id, _)| msg_id)
.collect::<Vec<_>>())
},
)
.await?;
Ok(msg_ids)
}

/// Do final events and jobs after batch deletion using calls to delete_msg_locally().
/// To avoid additional database queries, collecting data is up to the caller.
pub(crate) async fn delete_msgs_locally_done(
Expand Down Expand Up @@ -1751,8 +1781,10 @@ pub async fn delete_msgs_ex(
let mut modified_chat_ids = HashSet::new();
let mut deleted_rfc724_mid = Vec::new();
let mut res = Ok(());
let mut msg_ids_queue = VecDeque::from_iter(msg_ids.iter().copied());
let mut msg_ids = Vec::from(msg_ids);

for &msg_id in msg_ids {
while let Some(msg_id) = msg_ids_queue.pop_front() {
let msg = Message::load_from_db(context, msg_id).await?;
ensure!(
!delete_for_all || msg.from_id == ContactId::SELF,
Expand All @@ -1763,6 +1795,11 @@ pub async fn delete_msgs_ex(
"Cannot request deletion of unencrypted message for others"
);

if msg.viewtype == Viewtype::Webxdc {
let info_msgs = get_webxdc_info_messages(context, &msg).await?;
msg_ids_queue.extend(&info_msgs);
msg_ids.extend(info_msgs);
}
modified_chat_ids.insert(msg.chat_id);
deleted_rfc724_mid.push(msg.rfc724_mid.clone());

Expand Down Expand Up @@ -1808,11 +1845,11 @@ pub async fn delete_msgs_ex(
.await?;
}

for &msg_id in msg_ids {
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?;
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;
Expand Down
21 changes: 21 additions & 0 deletions src/webxdc/webxdc_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::chatlist::Chatlist;
use crate::config::Config;
use crate::download::DownloadState;
use crate::ephemeral;
use crate::message::delete_msgs;
use crate::receive_imf::{receive_imf, receive_imf_from_inbox};
use crate::test_utils::{E2EE_INFO_MSGS, TestContext, TestContextManager};
use crate::tools::{self, SystemTime};
Expand Down Expand Up @@ -1616,6 +1617,26 @@ async fn test_webxdc_info_msg_no_cleanup_on_interrupted_series() -> Result<()> {
Ok(())
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_webxdc_info_msg_delete() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "c").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;

t.send_webxdc_status_update(instance.id, r#"{"info":"i1", "payload":1}"#)
.await?;
assert_eq!(chat_id.get_msg_cnt(&t).await?, 2);
send_text_msg(&t, chat_id, "msg between info".to_string()).await?;
assert_eq!(chat_id.get_msg_cnt(&t).await?, 3);
t.send_webxdc_status_update(instance.id, r#"{"info":"i2", "payload":2}"#)
.await?;
assert_eq!(chat_id.get_msg_cnt(&t).await?, 4);
delete_msgs(&t, &[instance.id]).await?;
assert_eq!(chat_id.get_msg_cnt(&t).await?, 1);

Ok(())
}

// check that `info.internet_access` is not set for normal, non-integrated webxdc -
// even if they use the deprecated option `request_internet_access` in manifest.toml
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
Expand Down
Loading