core_crypto/mls/conversation/
orphan_welcome.rs

1//! This deals with DS inconsistencies. When a Welcome message is received, the client might have
2//! already deleted its associated KeyPackage (and encryption key).
3//! Feel free to remove this when this is no longer a problem !!!
4
5#[cfg(test)]
6mod tests {
7
8    use openmls::prelude::KeyPackage;
9    use openmls_traits::OpenMlsCryptoProvider;
10    use wasm_bindgen_test::*;
11
12    use super::super::error::Error;
13    use crate::test_utils::*;
14
15    wasm_bindgen_test_configure!(run_in_browser);
16
17    #[apply(all_cred_cipher)]
18    #[wasm_bindgen_test]
19    pub async fn orphan_welcome_should_generate_external_commit(case: TestContext) {
20        run_test_with_client_ids(case.clone(), ["alice", "bob"], move |[alice_central, bob_central]| {
21            Box::pin(async move {
22                let id = conversation_id();
23
24                alice_central
25                    .transaction
26                    .new_conversation(&id, case.credential_type, case.cfg.clone())
27                    .await
28                    .unwrap();
29
30                let bob = bob_central.rand_key_package(&case).await;
31                let bob_kp_ref = KeyPackage::from(bob.clone())
32                    .hash_ref(bob_central.transaction.mls_provider().await.unwrap().crypto())
33                    .unwrap();
34
35                // Alice invites Bob with a KeyPackage...
36                alice_central
37                    .transaction
38                    .conversation(&id)
39                    .await
40                    .unwrap()
41                    .add_members(vec![bob])
42                    .await
43                    .unwrap();
44
45                // ...Bob deletes locally (with the associated private key) before processing the Welcome
46                bob_central.transaction.delete_keypackages(&[bob_kp_ref]).await.unwrap();
47
48                let welcome = alice_central.mls_transport.latest_welcome_message().await;
49
50                // in that case a dedicated error is thrown for clients to identify this case
51                // and rejoin with an external commit
52                let process_welcome = bob_central
53                    .transaction
54                    .process_welcome_message(welcome.into(), case.custom_cfg())
55                    .await;
56                assert!(matches!(
57                    process_welcome.unwrap_err(),
58                    crate::transaction_context::Error::Recursive(crate::RecursiveError::MlsConversation { source, .. }) if matches!(*source, Error::OrphanWelcome)
59                ));
60            })
61        })
62        .await;
63    }
64}