From c1a246e1ac5181c34e83d9f838da154ca3160b5c Mon Sep 17 00:00:00 2001 From: Schmiddiii Date: Fri, 19 May 2023 12:33:23 +0200 Subject: [PATCH] Set the expire timer This sets the expire timer of a message such that the current expiration timer of a conversation stays the same (except in cases where it was explicitly set to another value). It may be a little counterproductive when sending a message to (e.g.) a contact to query the timer for the thread which unwraps it back to querying the contact, but this method may potentially also be used to display the expiration timer. Note that due to #171, I would guess that the expiration timer always stays the same for contacts directly after linking, e.g. changing it on an official client and then sending a message from presage, presage will set the expiration timer back to before the change. This fixes #93. --- presage/Cargo.toml | 4 ++-- presage/src/manager.rs | 49 +++++++++++++++++++++++++++++++++++++++--- presage/src/store.rs | 12 +++++++++++ 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/presage/Cargo.toml b/presage/Cargo.toml index bc8c5ee28..c9dcb23d7 100644 --- a/presage/Cargo.toml +++ b/presage/Cargo.toml @@ -6,8 +6,8 @@ authors = ["Gabriel FĂ©ron "] edition = "2021" [dependencies] -libsignal-service = { git = "https://github.com/whisperfish/libsignal-service-rs", rev = "c2f70ef" } -libsignal-service-hyper = { git = "https://github.com/whisperfish/libsignal-service-rs", rev = "c2f70ef" } +libsignal-service = { git = "https://github.com/whisperfish/libsignal-service-rs", rev = "a2e871a" } +libsignal-service-hyper = { git = "https://github.com/whisperfish/libsignal-service-rs", rev = "a2e871a" } base64 = "0.12" futures = "0.3" diff --git a/presage/src/manager.rs b/presage/src/manager.rs index 2d26a383c..b45b35b9e 100644 --- a/presage/src/manager.rs +++ b/presage/src/manager.rs @@ -941,6 +941,9 @@ impl Manager { /// Sends a messages to the provided [ServiceAddress]. /// The timestamp should be set to now and is used by Signal mobile apps /// to order messages later, and apply reactions. + /// + /// This method will automatically update the [DataMessage::expiration_timer] if it is set to + /// [None] such that the chat will keep the current expire timer. pub async fn send_message( &mut self, recipient_addr: impl Into, @@ -951,7 +954,24 @@ impl Manager { let online_only = false; let recipient = recipient_addr.into(); - let content_body: ContentBody = message.into(); + let mut content_body: ContentBody = message.into(); + + // Only update the expiration timer if it is not set. + match content_body { + ContentBody::DataMessage(DataMessage { + expire_timer: ref mut timer, + .. + }) if timer.is_none() => { + // Set the expire timer to None for errors. + let store_expire_timer = self + .config_store + .expire_timer(&Thread::Contact(recipient.uuid)) + .unwrap_or_default(); + + *timer = store_expire_timer; + } + _ => {} + } let sender_certificate = self.sender_certificate().await?; let unidentified_access = @@ -1006,13 +1026,36 @@ impl Manager { Ok(upload.await) } - /// Sends one message in a group (v2). + /// Sends one message in a group (v2). The `master_key_bytes` is required to have 32 elements. + /// + /// This method will automatically update the [DataMessage::expiration_timer] if it is set to + /// [None] such that the chat will keep the current expire timer. pub async fn send_message_to_group( &mut self, master_key_bytes: &[u8], - message: DataMessage, + mut message: DataMessage, timestamp: u64, ) -> Result<(), Error> { + // Only update the expiration timer if it is not set. + match message { + DataMessage { + expire_timer: ref mut timer, + .. + } if timer.is_none() => { + // Set the expire timer to None for errors. + let store_expire_timer = self + .config_store + .expire_timer(&Thread::Group( + master_key_bytes + .try_into() + .expect("Master key bytes to be of size 32."), + )) + .unwrap_or_default(); + + *timer = store_expire_timer; + } + _ => {} + } let mut sender = self.new_message_sender().await?; let mut groups_manager = self.groups_manager()?; diff --git a/presage/src/store.rs b/presage/src/store.rs index e48dddd4a..d4bca8b1f 100644 --- a/presage/src/store.rs +++ b/presage/src/store.rs @@ -72,6 +72,18 @@ pub trait Store: ProtocolStore + SenderKeyStore + SessionStoreExt + Sync + Clone range: impl RangeBounds, ) -> Result; + /// Get the expire timer from a [Thread], which corresponds to either [Contact::expire_timer] + /// or [Group::disappearing_messages_timer]. + fn expire_timer(&self, thread: &Thread) -> Result, Self::Error> { + match thread { + Thread::Contact(uuid) => Ok(self.contact_by_id(*uuid)?.map(|c| c.expire_timer)), + Thread::Group(key) => Ok(self + .group(*key)? + .and_then(|g| g.disappearing_messages_timer) + .map(|t| t.duration)), + } + } + /// Contacts /// Clear all saved synchronized contact data