core_crypto_ffi/core_crypto/e2ei/
identities.rs

1use std::collections::HashMap;
2
3use core_crypto::{RecursiveError, mls::conversation::Conversation as _, prelude::VerifiableGroupInfo};
4use tls_codec::Deserialize as _;
5#[cfg(target_family = "wasm")]
6use wasm_bindgen::prelude::*;
7
8use crate::{
9    ClientId, ConversationId, CoreCrypto, CoreCryptoResult, CredentialType, E2eiConversationState, WireIdentity,
10    conversation_id_vec,
11};
12
13#[cfg(not(target_family = "wasm"))]
14type DeviceIdentities = Vec<WireIdentity>;
15
16#[cfg(target_family = "wasm")]
17type DeviceIdentities = JsValue;
18
19#[cfg(not(target_family = "wasm"))]
20pub(crate) type UserIdentities = HashMap<String, Vec<WireIdentity>>;
21
22#[cfg(target_family = "wasm")]
23pub(crate) type UserIdentities = JsValue;
24
25#[cfg_attr(not(target_family = "wasm"), uniffi::export)]
26#[cfg_attr(target_family = "wasm", wasm_bindgen)]
27impl CoreCrypto {
28    /// See [core_crypto::mls::conversation::ConversationGuard::get_device_identities]
29    #[cfg_attr(target_family = "wasm", wasm_bindgen(unchecked_return_type = "WireIdentity[]"))]
30    pub async fn get_device_identities(
31        &self,
32        conversation_id: &ConversationId,
33        device_ids: Vec<ClientId>,
34    ) -> CoreCryptoResult<DeviceIdentities> {
35        let conversation_id = conversation_id_vec!(conversation_id);
36        let conversation = self
37            .inner
38            .get_raw_conversation(&conversation_id)
39            .await
40            .map_err(RecursiveError::mls_client("getting raw conversation"))?;
41        let device_ids = device_ids.into_iter().map(|ClientId(id)| id).collect::<Vec<_>>();
42        let device_identities = conversation.get_device_identities(&device_ids).await?;
43        let device_identities = device_identities
44            .into_iter()
45            .map(WireIdentity::from)
46            .collect::<Vec<_>>();
47        #[cfg(target_family = "wasm")]
48        let device_identities =
49            serde_wasm_bindgen::to_value(&device_identities).expect("device identities can always be serialized");
50        Ok(device_identities)
51    }
52
53    /// See [core_crypto::mls::conversation::ConversationGuard::get_user_identities]
54    #[cfg_attr(
55        target_family = "wasm",
56        wasm_bindgen(unchecked_return_type = "Map<string, WireIdentity[]>")
57    )]
58    pub async fn get_user_identities(
59        &self,
60        conversation_id: &ConversationId,
61        user_ids: Vec<String>,
62    ) -> CoreCryptoResult<UserIdentities> {
63        let conversation_id = conversation_id_vec!(conversation_id);
64        let conversation = self
65            .inner
66            .get_raw_conversation(&conversation_id)
67            .await
68            .map_err(RecursiveError::mls_client("getting raw conversation"))?;
69        let identities = conversation.get_user_identities(user_ids.as_slice()).await?;
70        let identities = identities
71            .into_iter()
72            .map(|(k, v)| (k, v.into_iter().map(WireIdentity::from).collect()))
73            .collect::<HashMap<_, Vec<_>>>();
74        #[cfg(target_family = "wasm")]
75        let identities = serde_wasm_bindgen::to_value(&identities).expect("user identities can always be serialized");
76        Ok(identities)
77    }
78
79    /// See [core_crypto::mls::MlsCentral::get_credential_in_use]
80    pub async fn get_credential_in_use(
81        &self,
82        group_info: Vec<u8>,
83        credential_type: CredentialType,
84    ) -> CoreCryptoResult<E2eiConversationState> {
85        let group_info = VerifiableGroupInfo::tls_deserialize(&mut group_info.as_slice())
86            .map_err(core_crypto::mls::conversation::Error::tls_deserialize(
87                "verifiable group info",
88            ))
89            .map_err(RecursiveError::mls_conversation("deserializing veriable group info"))?;
90        self.inner
91            .get_credential_in_use(group_info, credential_type.into())
92            .await
93            .map(Into::into)
94            .map_err(RecursiveError::mls_client("getting credential in use"))
95            .map_err(Into::into)
96    }
97}