From 20d6f0f2cac58704aed3f13901669482c72a4feb Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 17 Feb 2025 12:43:20 +0000 Subject: [PATCH] fix: do not allow non-members to change ephemeral timer settings --- src/ephemeral/ephemeral_tests.rs | 42 +++++++++++++++++++++++++++++++- src/receive_imf.rs | 12 ++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/ephemeral/ephemeral_tests.rs b/src/ephemeral/ephemeral_tests.rs index 63c29ecf3a..bcf5b60161 100644 --- a/src/ephemeral/ephemeral_tests.rs +++ b/src/ephemeral/ephemeral_tests.rs @@ -1,7 +1,11 @@ use super::*; -use crate::chat::{marknoticed_chat, set_muted, ChatVisibility, MuteDuration}; +use crate::chat::{ + add_contact_to_chat, marknoticed_chat, remove_contact_from_chat, set_muted, ChatVisibility, + MuteDuration, +}; use crate::config::Config; use crate::constants::DC_CHAT_ID_ARCHIVED_LINK; +use crate::contact::Contact; use crate::download::DownloadState; use crate::location; use crate::message::markseen_msgs; @@ -779,3 +783,39 @@ async fn test_archived_ephemeral_timer() -> Result<()> { Ok(()) } + +/// Tests that non-members cannot change ephemeral timer settings. +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_ephemeral_timer_non_member() -> Result<()> { + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; + + let alice_bob_contact_id = Contact::create(alice, "Bob", "bob@example.net").await?; + let alice_chat_id = + create_group_chat(alice, ProtectionStatus::Unprotected, "Group name").await?; + add_contact_to_chat(alice, alice_chat_id, alice_bob_contact_id).await?; + send_text_msg(alice, alice_chat_id, "Hi!".to_string()).await?; + + let sent = alice.pop_sent_msg().await; + let bob_chat_id = bob.recv_msg(&sent).await.chat_id; + + // Bob wants to modify the timer. + bob_chat_id.accept(bob).await?; + bob_chat_id + .set_ephemeral_timer(bob, Timer::Enabled { duration: 60 }) + .await?; + let sent_ephemeral_timer_change = bob.pop_sent_msg().await; + + // Alice removes Bob before receiving the timer change. + remove_contact_from_chat(alice, alice_chat_id, alice_bob_contact_id).await?; + alice.recv_msg(&sent_ephemeral_timer_change).await; + + // Timer is not changed because Bob is not a member. + assert_eq!( + alice_chat_id.get_ephemeral_timer(alice).await?, + Timer::Disabled + ); + + Ok(()) +} diff --git a/src/receive_imf.rs b/src/receive_imf.rs index 6abc92dd60..ef5840a93f 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -1292,8 +1292,18 @@ async fn add_parts( && !mime_parser.parts.is_empty() && chat_id.get_ephemeral_timer(context).await? != ephemeral_timer { + let chat_contacts = + HashSet::::from_iter(chat::get_chat_contacts(context, chat_id).await?); + let is_from_in_chat = + !chat_contacts.contains(&ContactId::SELF) || chat_contacts.contains(&from_id); + info!(context, "Received new ephemeral timer value {ephemeral_timer:?} for chat {chat_id}, checking if it should be applied."); - if is_dc_message == MessengerMessage::Yes + if !is_from_in_chat { + warn!( + context, + "Ignoring ephemeral timer change to {ephemeral_timer:?} for chat {chat_id} because sender {from_id} is not a member.", + ); + } else if is_dc_message == MessengerMessage::Yes && get_previous_message(context, mime_parser) .await? .map(|p| p.ephemeral_timer)