Starts the securejoin protocol with the QR `invite`. This will try to start the securejoin protocol for the given QR `invite`. If Bob already has Alice's key, he sends `AUTH` token and forgets about the invite. If Bob does not yet have Alice's key, he sends `vc-request` or `vg-request` message and stores a row in the `bobstate` table so he can check Alice's key against the fingerprint and send `
(context: &Context, invite: QrInvite)
| 44 | /// The [`ChatId`] of the created chat is returned, for a SetupContact QR this is the 1:1 |
| 45 | /// chat with Alice, for a SecureJoin QR this is the group chat. |
| 46 | pub(super) async fn start_protocol(context: &Context, invite: QrInvite) -> Result<ChatId> { |
| 47 | // A 1:1 chat is needed to send messages to Alice. When joining a group this chat is |
| 48 | // hidden, if a user starts sending messages in it it will be unhidden in |
| 49 | // receive_imf. |
| 50 | let private_chat_id = private_chat_id(context, &invite).await?; |
| 51 | |
| 52 | match invite { |
| 53 | QrInvite::Group { .. } | QrInvite::Contact { .. } => { |
| 54 | ContactId::scaleup_origin(context, &[invite.contact_id()], Origin::SecurejoinJoined) |
| 55 | .await?; |
| 56 | context.emit_event(EventType::ContactsChanged(None)); |
| 57 | } |
| 58 | QrInvite::Broadcast { .. } => {} |
| 59 | } |
| 60 | |
| 61 | let has_key = context |
| 62 | .sql |
| 63 | .exists( |
| 64 | "SELECT COUNT(*) FROM public_keys WHERE fingerprint=?", |
| 65 | (invite.fingerprint().hex(),), |
| 66 | ) |
| 67 | .await?; |
| 68 | |
| 69 | // Now start the protocol and initialise the state. |
| 70 | { |
| 71 | // `joining_chat_id` is `Some` if group chat |
| 72 | // already exists and we are in the chat. |
| 73 | let joining_chat_id = match invite { |
| 74 | QrInvite::Group { ref grpid, .. } | QrInvite::Broadcast { ref grpid, .. } => { |
| 75 | if let Some((joining_chat_id, _blocked)) = |
| 76 | chat::get_chat_id_by_grpid(context, grpid).await? |
| 77 | { |
| 78 | if is_contact_in_chat(context, joining_chat_id, ContactId::SELF).await? { |
| 79 | Some(joining_chat_id) |
| 80 | } else { |
| 81 | None |
| 82 | } |
| 83 | } else { |
| 84 | None |
| 85 | } |
| 86 | } |
| 87 | QrInvite::Contact { .. } => None, |
| 88 | }; |
| 89 | |
| 90 | if let Some(joining_chat_id) = joining_chat_id { |
| 91 | // If QR code is a group invite |
| 92 | // and we are already in the chat, |
| 93 | // nothing needs to be done. |
| 94 | // Even if Alice is not verified, we don't send anything. |
| 95 | context.emit_event(EventType::SecurejoinJoinerProgress { |
| 96 | contact_id: invite.contact_id(), |
| 97 | progress: JoinerProgress::Succeeded.into_u16(), |
| 98 | }); |
| 99 | return Ok(joining_chat_id); |
| 100 | } else if has_key |
| 101 | && verify_sender_by_fingerprint(context, invite.fingerprint(), invite.contact_id()) |
| 102 | .await? |
| 103 | { |
no test coverage detected