matrix_sdk_base/response_processors/e2ee/
to_device.rs1use std::collections::BTreeMap;
16
17use matrix_sdk_common::deserialized_responses::ProcessedToDeviceEvent;
18use matrix_sdk_crypto::{store::types::RoomKeyInfo, EncryptionSyncChanges, OlmMachine};
19use ruma::{
20 api::client::sync::sync_events::{v3, v5, DeviceLists},
21 events::AnyToDeviceEvent,
22 serde::Raw,
23 OneTimeKeyAlgorithm, UInt,
24};
25
26use crate::Result;
27
28pub async fn from_msc4186(
34 to_device: Option<&v5::response::ToDevice>,
35 e2ee: &v5::response::E2EE,
36 olm_machine: Option<&OlmMachine>,
37) -> Result<Output> {
38 process(
39 olm_machine,
40 to_device.as_ref().map(|to_device| to_device.events.clone()).unwrap_or_default(),
41 &e2ee.device_lists,
42 &e2ee.device_one_time_keys_count,
43 e2ee.device_unused_fallback_key_types.as_deref(),
44 to_device.as_ref().map(|to_device| to_device.next_batch.clone()),
45 )
46 .await
47}
48
49pub async fn from_sync_v2(
55 response: &v3::Response,
56 olm_machine: Option<&OlmMachine>,
57) -> Result<Output> {
58 process(
59 olm_machine,
60 response.to_device.events.clone(),
61 &response.device_lists,
62 &response.device_one_time_keys_count,
63 response.device_unused_fallback_key_types.as_deref(),
64 Some(response.next_batch.clone()),
65 )
66 .await
67}
68
69async fn process(
74 olm_machine: Option<&OlmMachine>,
75 to_device_events: Vec<Raw<AnyToDeviceEvent>>,
76 device_lists: &DeviceLists,
77 one_time_keys_counts: &BTreeMap<OneTimeKeyAlgorithm, UInt>,
78 unused_fallback_keys: Option<&[OneTimeKeyAlgorithm]>,
79 next_batch_token: Option<String>,
80) -> Result<Output> {
81 let encryption_sync_changes = EncryptionSyncChanges {
82 to_device_events,
83 changed_devices: device_lists,
84 one_time_keys_counts,
85 unused_fallback_keys,
86 next_batch_token,
87 };
88
89 Ok(if let Some(olm_machine) = olm_machine {
90 let (events, room_key_updates) =
95 olm_machine.receive_sync_changes(encryption_sync_changes).await?;
96
97 Output { processed_to_device_events: events, room_key_updates: Some(room_key_updates) }
98 } else {
99 Output {
104 processed_to_device_events: encryption_sync_changes
105 .to_device_events
106 .into_iter()
107 .map(|raw| {
108 if let Ok(Some(event_type)) = raw.get_field::<String>("type") {
109 if event_type == "m.room.encrypted" {
110 ProcessedToDeviceEvent::UnableToDecrypt(raw)
111 } else {
112 ProcessedToDeviceEvent::PlainText(raw)
113 }
114 } else {
115 ProcessedToDeviceEvent::Invalid(raw)
117 }
118 })
119 .collect(),
120 room_key_updates: None,
121 }
122 })
123}
124
125pub struct Output {
126 pub processed_to_device_events: Vec<ProcessedToDeviceEvent>,
127 pub room_key_updates: Option<Vec<RoomKeyInfo>>,
128}