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