fix: Allow to send to chats after failed securejoin again (#6817)

Revert the biggest part of https://github.com/chatmail/core/pull/6722/
in order to fix #6816. Reopens
https://github.com/chatmail/core/issues/6706.

Rationale for reverting instead of fixing is that it's not trivial to
implement "if the chat is encrypted, can_send() returns true": When
sending a message, in order to check whether to encrypt, we load all
peerstates and check whether all of them can be encrypted to
(`should_encrypt()`). We could do this in `can_send()`, but this would
make it quite slow for groups. With multi-transport, the ways of
checking whether to encrypt will be different, so in order not to do
unnecessary work now, this PR just revert parts of
[https://github.com/chatmail/core/pull/6722/](https://github.com/chatmail/core/pull/6817#),
so that we can make things work nicely when multi-transport is merged.

As a quick mitigation, we could increase the timeout from 15s to
something like 1 minute or 1 day: Long enough that usually securejoin
will finish before, but short enough that it's possible to send to old
chats that had a failed securejoin long in the past.
This commit is contained in:
Hocuri
2025-04-23 22:55:50 +02:00
committed by GitHub
parent 9d3450f50c
commit ef798cd86d
2 changed files with 19 additions and 22 deletions

View File

@@ -1695,13 +1695,13 @@ impl Chat {
return Ok(Some(reason)); return Ok(Some(reason));
} }
let reason = SecurejoinWait; let reason = SecurejoinWait;
if !skip_fn(&reason) { if !skip_fn(&reason)
let (can_write, _) = self && self
.check_securejoin_wait(context, constants::SECUREJOIN_WAIT_TIMEOUT) .check_securejoin_wait(context, constants::SECUREJOIN_WAIT_TIMEOUT)
.await?; .await?
if !can_write { > 0
return Ok(Some(reason)); {
} return Ok(Some(reason));
} }
Ok(None) Ok(None)
} }
@@ -1713,18 +1713,17 @@ impl Chat {
Ok(self.why_cant_send(context).await?.is_none()) Ok(self.why_cant_send(context).await?.is_none())
} }
/// Returns if the chat can be sent to /// Returns the remaining timeout for the 1:1 chat in-progress SecureJoin.
/// and the remaining timeout for the 1:1 chat in-progress SecureJoin.
/// ///
/// If the timeout has expired, adds an info message with additional information; /// If the timeout has expired, adds an info message with additional information.
/// the chat still cannot be sent to in this case. See also [`CantSendReason::SecurejoinWait`]. /// See also [`CantSendReason::SecurejoinWait`].
pub(crate) async fn check_securejoin_wait( pub(crate) async fn check_securejoin_wait(
&self, &self,
context: &Context, context: &Context,
timeout: u64, timeout: u64,
) -> Result<(bool, u64)> { ) -> Result<u64> {
if self.typ != Chattype::Single || self.protected != ProtectionStatus::Unprotected { if self.typ != Chattype::Single || self.protected != ProtectionStatus::Unprotected {
return Ok((true, 0)); return Ok(0);
} }
// chat is single and unprotected: // chat is single and unprotected:
@@ -1748,11 +1747,10 @@ impl Chat {
) )
.await? .await?
else { else {
return Ok((true, 0)); return Ok(0);
}; };
if param == param_timeout { if param == param_timeout {
return Ok((false, 0)); return Ok(0);
} }
let now = time(); let now = time();
@@ -1762,10 +1760,9 @@ impl Chat {
.saturating_add(timeout.try_into()?) .saturating_add(timeout.try_into()?)
.saturating_sub(now); .saturating_sub(now);
if timeout > 0 { if timeout > 0 {
return Ok((false, timeout as u64)); return Ok(timeout as u64);
} }
} }
add_info_msg_with_cmd( add_info_msg_with_cmd(
context, context,
self.id, self.id,
@@ -1780,8 +1777,8 @@ impl Chat {
None, None,
) )
.await?; .await?;
context.emit_event(EventType::ChatModified(self.id));
Ok((false, 0)) Ok(0)
} }
/// Checks if the user is part of a chat /// Checks if the user is part of a chat
@@ -2584,7 +2581,7 @@ pub(crate) async fn resume_securejoin_wait(context: &Context) -> Result<()> {
for chat_id in chat_ids { for chat_id in chat_ids {
let chat = Chat::load_from_db(context, chat_id).await?; let chat = Chat::load_from_db(context, chat_id).await?;
let (_, timeout) = chat let timeout = chat
.check_securejoin_wait(context, constants::SECUREJOIN_WAIT_TIMEOUT) .check_securejoin_wait(context, constants::SECUREJOIN_WAIT_TIMEOUT)
.await?; .await?;
if timeout > 0 { if timeout > 0 {

View File

@@ -149,7 +149,7 @@ async fn test_setup_contact_ex(case: SetupContactCase) {
); );
if case == SetupContactCase::SecurejoinWaitTimeout { if case == SetupContactCase::SecurejoinWaitTimeout {
SystemTime::shift(Duration::from_secs(constants::SECUREJOIN_WAIT_TIMEOUT)); SystemTime::shift(Duration::from_secs(constants::SECUREJOIN_WAIT_TIMEOUT));
assert_eq!(bob_chat.can_send(&bob).await.unwrap(), false); assert_eq!(bob_chat.can_send(&bob).await.unwrap(), true);
} }
// Step 4: Bob receives vc-auth-required, sends vc-request-with-auth // Step 4: Bob receives vc-auth-required, sends vc-request-with-auth
@@ -318,7 +318,7 @@ async fn test_setup_contact_ex(case: SetupContactCase) {
.check_securejoin_wait(&bob, constants::SECUREJOIN_WAIT_TIMEOUT) .check_securejoin_wait(&bob, constants::SECUREJOIN_WAIT_TIMEOUT)
.await .await
.unwrap(), .unwrap(),
(true, 0) 0
); );
} }