feat: allow scanning multiple securejoin QR codes in parallel

This commit is contained in:
link2xt
2025-02-11 19:42:53 +00:00
parent 449ba4e192
commit bbb267331c
7 changed files with 422 additions and 685 deletions

View File

@@ -26,10 +26,8 @@ use crate::token;
use crate::tools::time;
mod bob;
mod bobstate;
mod qrinvite;
pub(crate) use bobstate::BobState;
use qrinvite::QrInvite;
use crate::token::Namespace;
@@ -168,8 +166,7 @@ async fn securejoin(context: &Context, qr: &str) -> Result<ChatId> {
bob::start_protocol(context, invite).await
}
/// Send handshake message from Alice's device;
/// Bob's handshake messages are sent in `BobState::send_handshake_message()`.
/// Send handshake message from Alice's device.
async fn send_alice_handshake_msg(
context: &Context,
contact_id: ContactId,
@@ -259,7 +256,7 @@ pub(crate) enum HandshakeMessage {
/// This leaves it on the IMAP server. It means other devices on this account can
/// receive and potentially process this message as well. This is useful for example
/// when the other device is running the protocol and has the relevant QR-code
/// information while this device does not have the joiner state ([`BobState`]).
/// information while this device does not have the joiner state.
Ignore,
/// The message should be further processed by incoming message handling.
///
@@ -281,7 +278,7 @@ pub(crate) enum HandshakeMessage {
/// database; this is done by `receive_imf()` later on as needed.
pub(crate) async fn handle_securejoin_handshake(
context: &Context,
mime_message: &MimeMessage,
mime_message: &mut MimeMessage,
contact_id: ContactId,
) -> Result<HandshakeMessage> {
if contact_id.is_special() {
@@ -479,15 +476,10 @@ pub(crate) async fn handle_securejoin_handshake(
==== Step 7 in "Setup verified contact" protocol ====
=======================================================*/
"vc-contact-confirm" => {
if let Some(mut bobstate) = BobState::from_db(&context.sql).await? {
if !bobstate.is_msg_expected(context, step) {
warn!(context, "Unexpected vc-contact-confirm.");
return Ok(HandshakeMessage::Ignore);
}
bobstate.step_contact_confirm(context).await?;
bobstate.emit_progress(context, JoinerProgress::Succeeded);
}
context.emit_event(EventType::SecurejoinJoinerProgress {
contact_id,
progress: JoinerProgress::Succeeded.to_usize(),
});
Ok(HandshakeMessage::Ignore)
}
"vg-member-added" => {
@@ -506,15 +498,22 @@ pub(crate) async fn handle_securejoin_handshake(
);
return Ok(HandshakeMessage::Propagate);
}
if let Some(mut bobstate) = BobState::from_db(&context.sql).await? {
if !bobstate.is_msg_expected(context, step) {
warn!(context, "Unexpected vg-member-added.");
return Ok(HandshakeMessage::Propagate);
}
bobstate.step_contact_confirm(context).await?;
bobstate.emit_progress(context, JoinerProgress::Succeeded);
// Mark peer as backward verified.
//
// This is needed for the case when we join a non-protected group
// because in this case `Chat-Verified` header that otherwise
// sets backward verification is not sent.
if let Some(peerstate) = &mut mime_message.peerstate {
peerstate.backward_verified_key_id =
Some(context.get_config_i64(Config::KeyId).await?).filter(|&id| id > 0);
peerstate.save_to_db(&context.sql).await?;
}
context.emit_event(EventType::SecurejoinJoinerProgress {
contact_id,
progress: JoinerProgress::Succeeded.to_usize(),
});
Ok(HandshakeMessage::Propagate)
}