Skip to content

Commit b18bdd1

Browse files
authored
fix "QR process failed" error and add a test (#2725)
* better readable enum * add a failing test * let new secure-joins abort existing ones before, a stale secure-join or setup-contact made the whole qr-scanning unusable until the app is restarted, resulting in "QR process failed" errors. this commit fixes the issue by aborting existing scans - in cases, a user really wants two concurrect joins running, this is not perfect, but that did not worked before as well. * remove unused AlreadyRunning variant * make clippy happy
1 parent 6c59b0d commit b18bdd1

File tree

1 file changed

+38
-3
lines changed

1 file changed

+38
-3
lines changed

src/securejoin.rs

+38-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ impl Bob {
105105
) -> Result<StartedProtocolVariant, JoinError> {
106106
let mut guard = self.inner.lock().await;
107107
if guard.is_some() {
108-
return Err(JoinError::AlreadyRunning);
108+
warn!(context, "The new securejoin will replace the ongoing one.");
109+
*guard = None;
109110
}
110111
let variant = match invite {
111112
QrInvite::Group { ref grpid, .. } => {
@@ -248,19 +249,22 @@ async fn get_self_fingerprint(context: &Context) -> Option<Fingerprint> {
248249
pub enum JoinError {
249250
#[error("Unknown QR-code: {0}")]
250251
QrCode(#[from] QrError),
251-
#[error("A setup-contact/secure-join protocol is already running")]
252-
AlreadyRunning,
252+
253253
#[error("An \"ongoing\" process is already running")]
254254
OngoingRunning,
255+
255256
#[error("Failed to send handshake message: {0}")]
256257
SendMessage(#[from] SendMsgError),
258+
257259
// Note that this can currently only occur if there is a bug in the QR/Lot code as this
258260
// is supposed to create a contact for us.
259261
#[error("Unknown contact (this is a bug): {0}")]
260262
UnknownContact(#[source] anyhow::Error),
263+
261264
// Note that this can only occur if we failed to create the chat correctly.
262265
#[error("Ongoing sender dropped (this is a bug)")]
263266
OngoingSenderDropped,
267+
264268
#[error("Other")]
265269
Other(#[from] anyhow::Error),
266270
}
@@ -945,6 +949,7 @@ mod tests {
945949

946950
use crate::chat;
947951
use crate::chat::ProtectionStatus;
952+
use crate::constants::Chattype;
948953
use crate::events::Event;
949954
use crate::peerstate::Peerstate;
950955
use crate::test_utils::TestContext;
@@ -1285,6 +1290,36 @@ mod tests {
12851290
Ok(())
12861291
}
12871292

1293+
#[async_std::test]
1294+
async fn test_setup_contact_concurrent_calls() -> Result<()> {
1295+
let alice = TestContext::new_alice().await;
1296+
let bob = TestContext::new_bob().await;
1297+
1298+
// do a scan that is not working as claire is never responding
1299+
let qr_stale = "OPENPGP4FPR:1234567890123456789012345678901234567890#a=claire%40foo.de&n=&i=12345678901&s=23456789012";
1300+
let claire_id = dc_join_securejoin(&bob, qr_stale).await?;
1301+
let chat = Chat::load_from_db(&bob, claire_id).await?;
1302+
assert!(!claire_id.is_special());
1303+
assert_eq!(chat.typ, Chattype::Single);
1304+
assert!(bob.pop_sent_msg().await.payload().contains("[email protected]"));
1305+
1306+
// subsequent scans shall abort existing ones or run concurrently -
1307+
// but they must not fail as otherwise the whole qr scanning becomes unusable until restart.
1308+
let qr = dc_get_securejoin_qr(&alice, None).await?;
1309+
let alice_id = dc_join_securejoin(&bob, &qr).await?;
1310+
let chat = Chat::load_from_db(&bob, alice_id).await?;
1311+
assert!(!alice_id.is_special());
1312+
assert_eq!(chat.typ, Chattype::Single);
1313+
assert_ne!(claire_id, alice_id);
1314+
assert!(bob
1315+
.pop_sent_msg()
1316+
.await
1317+
.payload()
1318+
.contains("[email protected]"));
1319+
1320+
Ok(())
1321+
}
1322+
12881323
#[async_std::test]
12891324
async fn test_secure_join() -> Result<()> {
12901325
let alice = TestContext::new_alice().await;

0 commit comments

Comments
 (0)