mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 09:26:29 +03:00
Fix ephemeral timer rollback protection
Implement get_previous_message() that only looks for the last Message-ID in the References: header instead of using get_parent_message() which falls back to using other Message-IDs from References and In-Reply-To field.
This commit is contained in:
@@ -872,19 +872,17 @@ async fn add_parts(
|
|||||||
chat_id
|
chat_id
|
||||||
);
|
);
|
||||||
if is_dc_message == MessengerMessage::Yes
|
if is_dc_message == MessengerMessage::Yes
|
||||||
&& mime_parser
|
&& get_previous_message(context, mime_parser)
|
||||||
.parts
|
.await?
|
||||||
.get(0)
|
.map(|p| p.ephemeral_timer)
|
||||||
.and_then(|part| part.param.get(Param::Quote))
|
== Some(ephemeral_timer)
|
||||||
.is_none()
|
|
||||||
&& parent.map(|p| p.ephemeral_timer) == Some(ephemeral_timer)
|
|
||||||
{
|
{
|
||||||
// The message is a Delta Chat message without a quote, so it must be a reply to the
|
// The message is a Delta Chat message, so we know that previous message according to
|
||||||
// last message in the chat as seen by the sender. The timer is the same in both the
|
// References header is the last message in the chat as seen by the sender. The timer
|
||||||
// received message and its parent, so we know that the sender has not seen any change
|
// is the same in both the received message and the last message, so we know that the
|
||||||
// of the timer between these messages. As our timer value is different, it means the
|
// sender has not seen any change of the timer between these messages. As our timer
|
||||||
// sender has not received some timer update that we have seen or sent ourselves, so we
|
// value is different, it means the sender has not received some timer update that we
|
||||||
// ignore incoming timer to prevent a rollback.
|
// have seen or sent ourselves, so we ignore incoming timer to prevent a rollback.
|
||||||
warn!(
|
warn!(
|
||||||
context,
|
context,
|
||||||
"ignoring ephemeral timer change to {:?} for chat {} to avoid rollback",
|
"ignoring ephemeral timer change to {:?} for chat {} to avoid rollback",
|
||||||
@@ -2148,6 +2146,23 @@ fn set_better_msg(mime_parser: &mut MimeMessage, better_msg: impl AsRef<str>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the last message referenced from `References` header if it is in the database.
|
||||||
|
///
|
||||||
|
/// For Delta Chat messages it is the last message in the chat of the sender.
|
||||||
|
async fn get_previous_message(
|
||||||
|
context: &Context,
|
||||||
|
mime_parser: &MimeMessage,
|
||||||
|
) -> Result<Option<Message>> {
|
||||||
|
if let Some(field) = mime_parser.get_header(HeaderDef::References) {
|
||||||
|
if let Some(rfc724mid) = parse_message_ids(field).last() {
|
||||||
|
if let Some((_, _, msg_id)) = rfc724_mid_exists(context, rfc724mid).await? {
|
||||||
|
return Ok(Some(Message::load_from_db(context, msg_id).await?));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
/// Given a list of Message-IDs, returns the latest message found in the database.
|
/// Given a list of Message-IDs, returns the latest message found in the database.
|
||||||
async fn get_rfc724_mid_in_list(context: &Context, mid_list: &str) -> Result<Option<Message>> {
|
async fn get_rfc724_mid_in_list(context: &Context, mid_list: &str) -> Result<Option<Message>> {
|
||||||
if mid_list.is_empty() {
|
if mid_list.is_empty() {
|
||||||
|
|||||||
Reference in New Issue
Block a user