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        run_test_with_client_ids(case.clone(), ["alice"], move |[cc]| {
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        })
62        .await
63    }
64}