core_crypto/mls/conversation/
wipe.rs

1use super::Result;
2use crate::{MlsError, prelude::MlsConversation};
3use mls_crypto_provider::MlsCryptoProvider;
4use openmls_traits::OpenMlsCryptoProvider;
5
6impl MlsConversation {
7    pub(crate) async fn wipe_associated_entities(&mut self, backend: &MlsCryptoProvider) -> Result<()> {
8        // the own client may or may not have generated an epoch keypair in the previous epoch
9        // Since it is a terminal operation, ignoring the error is fine here.
10        let _ = self.group.delete_previous_epoch_keypairs(backend).await;
11
12        let pending_proposals = self.group.pending_proposals().cloned().collect::<Vec<_>>();
13        for proposal in pending_proposals {
14            // Update proposals rekey the own leaf node. Hence the associated encryption keypair has to be cleared
15            self.group
16                .remove_pending_proposal(backend.key_store(), proposal.proposal_reference())
17                .await
18                .map_err(MlsError::wrap("removing pending proposal"))?;
19        }
20
21        Ok(())
22    }
23}
24
25#[cfg(test)]
26mod tests {
27    use crate::test_utils::*;
28    use wasm_bindgen_test::*;
29
30    wasm_bindgen_test_configure!(run_in_browser);
31
32    // should delete anything related to this conversation
33    #[apply(all_cred_cipher)]
34    #[wasm_bindgen_test]
35    async fn should_cascade_deletion(case: TestContext) {
36        let [cc] = case.sessions().await;
37        Box::pin(async move {
38            let id = conversation_id();
39            cc.transaction
40                .new_conversation(&id, case.credential_type, case.cfg.clone())
41                .await
42                .unwrap();
43            assert!(cc.get_conversation_unchecked(&id).await.group.is_active());
44            let initial_count = cc.transaction.count_entities().await;
45
46            cc.transaction.new_update_proposal(&id).await.unwrap();
47            let post_proposal_count = cc.transaction.count_entities().await;
48            assert_eq!(
49                post_proposal_count.encryption_keypair,
50                initial_count.encryption_keypair + 1
51            );
52
53            cc.transaction.conversation(&id).await.unwrap().wipe().await.unwrap();
54
55            let final_count = cc.transaction.count_entities().await;
56            assert!(!cc.transaction.conversation_exists(&id).await.unwrap());
57            assert_eq!(final_count.group, 0);
58            assert_eq!(final_count.encryption_keypair, final_count.key_package);
59            assert_eq!(final_count.epoch_encryption_keypair, 0);
60        })
61        .await
62    }
63}