diff --git a/matrix_sdk/examples/emoji_verification.rs b/matrix_sdk/examples/emoji_verification.rs index 4ff70983..ac212aec 100644 --- a/matrix_sdk/examples/emoji_verification.rs +++ b/matrix_sdk/examples/emoji_verification.rs @@ -11,11 +11,12 @@ use matrix_sdk::{ self, events::{room::message::MessageType, AnySyncMessageEvent, AnySyncRoomEvent, AnyToDeviceEvent}, identifiers::UserId, - Client, LoopCtrl, Sas, SyncSettings, + verification::{SasVerification, Verification}, + Client, LoopCtrl, SyncSettings, }; use url::Url; -async fn wait_for_confirmation(client: Client, sas: Sas) { +async fn wait_for_confirmation(client: Client, sas: SasVerification) { println!("Does the emoji match: {:?}", sas.emoji()); let mut input = String::new(); @@ -34,7 +35,7 @@ async fn wait_for_confirmation(client: Client, sas: Sas) { } } -fn print_result(sas: &Sas) { +fn print_result(sas: &SasVerification) { let device = sas.other_device(); println!( @@ -80,37 +81,35 @@ async fn login( for event in response.to_device.events.iter().filter_map(|e| e.deserialize().ok()) { match event { AnyToDeviceEvent::KeyVerificationStart(e) => { - let sas = client - .get_verification(&e.sender, &e.content.transaction_id) - .await - .expect("Sas object wasn't created"); - println!( - "Starting verification with {} {}", - &sas.other_device().user_id(), - &sas.other_device().device_id() - ); - print_devices(&e.sender, client).await; - sas.accept().await.unwrap(); + if let Some(Verification::SasV1(sas)) = + client.get_verification(&e.sender, &e.content.transaction_id).await + { + println!( + "Starting verification with {} {}", + &sas.other_device().user_id(), + &sas.other_device().device_id() + ); + print_devices(&e.sender, client).await; + sas.accept().await.unwrap(); + } } AnyToDeviceEvent::KeyVerificationKey(e) => { - let sas = client - .get_verification(&e.sender, &e.content.transaction_id) - .await - .expect("Sas object wasn't created"); - - tokio::spawn(wait_for_confirmation((*client).clone(), sas)); + if let Some(Verification::SasV1(sas)) = + client.get_verification(&e.sender, &e.content.transaction_id).await + { + tokio::spawn(wait_for_confirmation((*client).clone(), sas)); + } } AnyToDeviceEvent::KeyVerificationMac(e) => { - let sas = client - .get_verification(&e.sender, &e.content.transaction_id) - .await - .expect("Sas object wasn't created"); - - if sas.is_done() { - print_result(&sas); - print_devices(&e.sender, client).await; + if let Some(Verification::SasV1(sas)) = + client.get_verification(&e.sender, &e.content.transaction_id).await + { + if sas.is_done() { + print_result(&sas); + print_devices(&e.sender, client).await; + } } } @@ -140,28 +139,28 @@ async fn login( } } AnySyncMessageEvent::KeyVerificationKey(e) => { - let sas = client + if let Some(Verification::SasV1(sas)) = client .get_verification( &e.sender, e.content.relation.event_id.as_str(), ) .await - .expect("Sas object wasn't created"); - - tokio::spawn(wait_for_confirmation((*client).clone(), sas)); + { + tokio::spawn(wait_for_confirmation((*client).clone(), sas)); + } } AnySyncMessageEvent::KeyVerificationMac(e) => { - let sas = client + if let Some(Verification::SasV1(sas)) = client .get_verification( &e.sender, e.content.relation.event_id.as_str(), ) .await - .expect("Sas object wasn't created"); - - if sas.is_done() { - print_result(&sas); - print_devices(&e.sender, client).await; + { + if sas.is_done() { + print_result(&sas); + print_devices(&e.sender, client).await; + } } } _ => (), diff --git a/matrix_sdk/src/client.rs b/matrix_sdk/src/client.rs index 2f449684..62f04092 100644 --- a/matrix_sdk/src/client.rs +++ b/matrix_sdk/src/client.rs @@ -126,8 +126,7 @@ use ruma::{ #[cfg(feature = "encryption")] use crate::{ device::{Device, UserDevices}, - sas::Sas, - verification_request::VerificationRequest, + verification::{QrVerification, SasVerification, Verification, VerificationRequest}, }; use crate::{ error::HttpError, @@ -2182,14 +2181,19 @@ impl Client { Ok(response) } - /// Get a `Sas` verification object with the given flow id. + /// Get a verification object with the given flow id. #[cfg(feature = "encryption")] #[cfg_attr(feature = "docs", doc(cfg(encryption)))] - pub async fn get_verification(&self, user_id: &UserId, flow_id: &str) -> Option { - self.base_client - .get_verification(user_id, flow_id) - .await - .map(|sas| Sas { inner: sas, client: self.clone() }) + pub async fn get_verification(&self, user_id: &UserId, flow_id: &str) -> Option { + let olm = self.base_client.olm_machine().await?; + olm.get_verification(user_id, flow_id).map(|v| match v { + matrix_sdk_base::crypto::Verification::SasV1(s) => { + SasVerification { inner: s, client: self.clone() }.into() + } + matrix_sdk_base::crypto::Verification::QrV1(qr) => { + QrVerification { inner: qr, client: self.clone() }.into() + } + }) } /// Get a `VerificationRequest` object for the given user with the given @@ -2697,6 +2701,22 @@ impl Client { let request = whoami::Request::new(); self.send(request, None).await } + + pub(crate) async fn send_verification_request( + &self, + request: matrix_sdk_base::crypto::OutgoingVerificationRequest, + ) -> Result<()> { + match request { + matrix_sdk_base::crypto::OutgoingVerificationRequest::ToDevice(t) => { + self.send_to_device(&t).await?; + } + matrix_sdk_base::crypto::OutgoingVerificationRequest::InRoom(r) => { + self.room_send_helper(&r).await?; + } + } + + Ok(()) + } } #[cfg(test)] diff --git a/matrix_sdk/src/device.rs b/matrix_sdk/src/device.rs index 37bf06dc..275060a9 100644 --- a/matrix_sdk/src/device.rs +++ b/matrix_sdk/src/device.rs @@ -20,7 +20,7 @@ use matrix_sdk_base::crypto::{ }; use ruma::{DeviceId, DeviceIdBox}; -use crate::{error::Result, Client, Sas}; +use crate::{error::Result, verification::SasVerification, Client}; #[derive(Clone, Debug)] /// A device represents a E2EE capable client of an user. @@ -62,11 +62,11 @@ impl Device { /// let verification = device.start_verification().await.unwrap(); /// # }); /// ``` - pub async fn start_verification(&self) -> Result { + pub async fn start_verification(&self) -> Result { let (sas, request) = self.inner.start_verification().await?; self.client.send_to_device(&request).await?; - Ok(Sas { inner: sas, client: self.client.clone() }) + Ok(SasVerification { inner: sas, client: self.client.clone() }) } /// Is the device trusted. diff --git a/matrix_sdk/src/lib.rs b/matrix_sdk/src/lib.rs index 4473662e..eb28e8bd 100644 --- a/matrix_sdk/src/lib.rs +++ b/matrix_sdk/src/lib.rs @@ -115,9 +115,7 @@ mod room_member; #[cfg(feature = "encryption")] mod device; #[cfg(feature = "encryption")] -mod sas; -#[cfg(feature = "encryption")] -mod verification_request; +pub mod verification; pub use client::{Client, ClientConfig, LoopCtrl, RequestConfig, SyncSettings}; #[cfg(feature = "encryption")] @@ -127,12 +125,5 @@ pub use error::{Error, HttpError, Result}; pub use event_handler::{CustomEvent, EventHandler}; pub use http_client::HttpSend; pub use room_member::RoomMember; -#[cfg(feature = "encryption")] -#[cfg_attr(feature = "docs", doc(cfg(encryption)))] -pub use sas::Sas; -#[cfg(feature = "encryption")] -#[cfg_attr(feature = "docs", doc(cfg(encryption)))] -pub use verification_request::VerificationRequest; - #[cfg(not(target_arch = "wasm32"))] pub(crate) const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/matrix_sdk/src/verification/mod.rs b/matrix_sdk/src/verification/mod.rs new file mode 100644 index 00000000..a742badf --- /dev/null +++ b/matrix_sdk/src/verification/mod.rs @@ -0,0 +1,120 @@ +// Copyright 2021 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Interactive verification for E2EE capable users and devices in Matrix. +//! +//! The SDK supports interactive verification of devices and users, this module +//! contains types that model and support different verification flows. +//! +//! A verification flow usually starts its life as a [VerificationRequest], the +//! request can then be accepted, or it needs to be accepted by the other side +//! of the verification flow. +//! +//! Once both sides have agreed to pereform the verification, and the +//! [VerificationRequest::is_ready()] method returns true, the verification can +//! transition into one of the supported verification flows: +//! +//! * [SasVerification] - Interactive verification using a short authentication +//! string. +//! * [QrVerification] - Interactive verification using QR codes. + +mod qrcode; +mod requests; +mod sas; + +pub use qrcode::QrVerification; +pub use requests::VerificationRequest; +pub use sas::SasVerification; + +/// An enum over the different verification types the SDK supports. +#[derive(Debug, Clone)] +pub enum Verification { + /// The `m.sas.v1` verification variant. + SasV1(SasVerification), + /// The `m.qr_code.*.v1` verification variant. + QrV1(QrVerification), +} + +impl Verification { + /// Try to deconstruct this verification enum into a SAS verification. + pub fn sas(self) -> Option { + if let Verification::SasV1(sas) = self { + Some(sas) + } else { + None + } + } + + /// Try to deconstruct this verification enum into a QR code verification. + pub fn qr(self) -> Option { + if let Verification::QrV1(qr) = self { + Some(qr) + } else { + None + } + } + + /// Has this verification finished. + pub fn is_done(&self) -> bool { + match self { + Verification::SasV1(s) => s.is_done(), + Verification::QrV1(qr) => qr.is_done(), + } + } + + /// Has the verification been cancelled. + pub fn is_cancelled(&self) -> bool { + match self { + Verification::SasV1(s) => s.is_cancelled(), + Verification::QrV1(qr) => qr.is_cancelled(), + } + } + + /// Get our own user id. + pub fn own_user_id(&self) -> &ruma::UserId { + match self { + Verification::SasV1(v) => v.own_user_id(), + Verification::QrV1(v) => v.own_user_id(), + } + } + + /// Get the user id of the other user participating in this verification + /// flow. + pub fn other_user_id(&self) -> &ruma::UserId { + match self { + Verification::SasV1(v) => v.inner.other_user_id(), + Verification::QrV1(v) => v.inner.other_user_id(), + } + } + + /// Is this a verification that is veryfying one of our own devices. + pub fn is_self_verification(&self) -> bool { + match self { + Verification::SasV1(v) => v.is_self_verification(), + Verification::QrV1(v) => v.is_self_verification(), + } + } +} + +impl From for Verification { + fn from(sas: SasVerification) -> Self { + Self::SasV1(sas) + } +} + +impl From for Verification { + fn from(qr: QrVerification) -> Self { + Self::QrV1(qr) + } +} diff --git a/matrix_sdk/src/verification/qrcode.rs b/matrix_sdk/src/verification/qrcode.rs new file mode 100644 index 00000000..f28d11b5 --- /dev/null +++ b/matrix_sdk/src/verification/qrcode.rs @@ -0,0 +1,87 @@ +// Copyright 2021 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use matrix_sdk_base::crypto::{ + matrix_qrcode::{qrcode::QrCode, EncodingError}, + QrVerification as BaseQrVerification, +}; +use ruma::UserId; + +use crate::{Client, Result}; + +/// An object controlling QR code style key verification flows. +#[derive(Debug, Clone)] +pub struct QrVerification { + pub(crate) inner: BaseQrVerification, + pub(crate) client: Client, +} + +impl QrVerification { + /// Get our own user id. + pub fn own_user_id(&self) -> &UserId { + self.inner.user_id() + } + + /// Is this a verification that is veryfying one of our own devices. + pub fn is_self_verification(&self) -> bool { + self.inner.is_self_verification() + } + + /// Has this verification finished. + pub fn is_done(&self) -> bool { + self.inner.is_done() + } + + /// Has the verification been cancelled. + pub fn is_cancelled(&self) -> bool { + self.inner.is_cancelled() + } + + /// Generate a QR code object that is representing this verification flow. + /// + /// The `QrCode` can then be rendered as an image or as an unicode string. + /// + /// The [`to_bytes()`](#method.to_bytes) method can be used to instead + /// output the raw bytes that should be encoded as a QR code. + pub fn to_qr_code(&self) -> std::result::Result { + self.inner.to_qr_code() + } + + /// Generate a the raw bytes that should be encoded as a QR code is + /// representing this verification flow. + /// + /// The [`to_qr_code()`](#method.to_qr_code) method can be used to instead + /// output a `QrCode` object that can be rendered. + pub fn to_bytes(&self) -> std::result::Result, EncodingError> { + self.inner.to_bytes() + } + + /// Confirm that the other side has scanned our QR code. + pub async fn confirm(&self) -> Result<()> { + if let Some(request) = self.inner.confirm_scanning() { + self.client.send_verification_request(request).await?; + } + + Ok(()) + } + + /// Abort the verification flow and notify the other side that we did so. + pub async fn cancel(&self) -> Result<()> { + if let Some(request) = self.inner.cancel() { + self.client.send_verification_request(request).await?; + } + + Ok(()) + } +} diff --git a/matrix_sdk/src/verification/requests.rs b/matrix_sdk/src/verification/requests.rs new file mode 100644 index 00000000..5a94c7b9 --- /dev/null +++ b/matrix_sdk/src/verification/requests.rs @@ -0,0 +1,132 @@ +// Copyright 2021 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use matrix_sdk_base::crypto::VerificationRequest as BaseVerificationRequest; +use ruma::events::key::verification::VerificationMethod; + +use super::{QrVerification, SasVerification}; +use crate::{Client, Result}; + +/// An object controlling the interactive verification flow. +#[derive(Debug, Clone)] +pub struct VerificationRequest { + pub(crate) inner: BaseVerificationRequest, + pub(crate) client: Client, +} + +impl VerificationRequest { + /// Has this verification finished. + pub fn is_done(&self) -> bool { + self.inner.is_done() + } + + /// Has the verification been cancelled. + pub fn is_cancelled(&self) -> bool { + self.inner.is_cancelled() + } + + /// Get our own user id. + pub fn own_user_id(&self) -> &ruma::UserId { + self.inner.own_user_id() + } + + /// Has the verification request been answered by another device. + pub fn is_passive(&self) -> bool { + self.inner.is_passive() + } + + /// Is the verification request ready to start a verification flow. + pub fn is_ready(&self) -> bool { + self.inner.is_ready() + } + + /// Get the user id of the other user participating in this verification + /// flow. + pub fn other_user_id(&self) -> &ruma::UserId { + self.inner.other_user() + } + + /// Is this a verification that is veryfying one of our own devices. + pub fn is_self_verification(&self) -> bool { + self.inner.is_self_verification() + } + + /// Get the supported verification methods of the other side. + /// + /// Will be present only if the other side requested the verification or if + /// we're in the ready state. + pub fn their_supported_methods(&self) -> Option> { + self.inner.their_supported_methods() + } + + /// Accept the verification request. + /// + /// This method will accept the request and signal that it supports the + /// `m.sas.v1`, the `m.qr_code.show.v1`, and `m.reciprocate.v1` method. + /// + /// If QR code scanning should be supported or QR code showing shouldn't be + /// supported the [`accept_with_methods()`] method should be used instead. + /// + /// [`accept_with_methods()`]: #method.accept_with_methods + pub async fn accept(&self) -> Result<()> { + if let Some(request) = self.inner.accept() { + self.client.send_verification_request(request).await?; + } + + Ok(()) + } + + /// Accept the verification request signaling that our client supports the + /// given verification methods. + /// + /// # Arguments + /// + /// * `methods` - The methods that we should advertise as supported by us. + pub async fn accept_with_methods(&self, methods: Vec) -> Result<()> { + if let Some(request) = self.inner.accept_with_methods(methods) { + self.client.send_verification_request(request).await?; + } + + Ok(()) + } + + /// Generate a QR code + pub async fn generate_qr_code(&self) -> Result> { + Ok(self + .inner + .generate_qr_code() + .await? + .map(|qr| QrVerification { inner: qr, client: self.client.clone() })) + } + + /// Transition from this verification request into a SAS verification flow. + pub async fn start_sas(&self) -> Result> { + if let Some((sas, request)) = self.inner.start_sas().await? { + self.client.send_verification_request(request).await?; + + Ok(Some(SasVerification { inner: sas, client: self.client.clone() })) + } else { + Ok(None) + } + } + + /// Cancel the verification request + pub async fn cancel(&self) -> Result<()> { + if let Some(request) = self.inner.cancel() { + self.client.send_verification_request(request).await?; + } + + Ok(()) + } +} diff --git a/matrix_sdk/src/sas.rs b/matrix_sdk/src/verification/sas.rs similarity index 77% rename from matrix_sdk/src/sas.rs rename to matrix_sdk/src/verification/sas.rs index 17db6a2f..124b6504 100644 --- a/matrix_sdk/src/sas.rs +++ b/matrix_sdk/src/verification/sas.rs @@ -12,21 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -use matrix_sdk_base::crypto::{ - AcceptSettings, OutgoingVerificationRequest, ReadOnlyDevice, Sas as BaseSas, -}; +use matrix_sdk_base::crypto::{AcceptSettings, ReadOnlyDevice, Sas as BaseSas}; use ruma::UserId; use crate::{error::Result, Client}; /// An object controlling the interactive verification flow. #[derive(Debug, Clone)] -pub struct Sas { +pub struct SasVerification { pub(crate) inner: BaseSas, pub(crate) client: Client, } -impl Sas { +impl SasVerification { /// Accept the interactive verification flow. pub async fn accept(&self) -> Result<()> { self.accept_with_settings(Default::default()).await @@ -45,7 +43,7 @@ impl Sas { /// # use futures::executor::block_on; /// # use url::Url; /// # use ruma::identifiers::user_id; - /// use matrix_sdk::Sas; + /// use matrix_sdk::verification::SasVerification; /// use matrix_sdk_base::crypto::AcceptSettings; /// use matrix_sdk::events::key::verification::ShortAuthenticationString; /// # let homeserver = Url::parse("http://example.com").unwrap(); @@ -56,6 +54,8 @@ impl Sas { /// let sas = client /// .get_verification(&user_id, flow_id) /// .await + /// .unwrap() + /// .sas() /// .unwrap(); /// /// let only_decimal = AcceptSettings::with_allowed_methods( @@ -65,15 +65,8 @@ impl Sas { /// # }); /// ``` pub async fn accept_with_settings(&self, settings: AcceptSettings) -> Result<()> { - if let Some(req) = self.inner.accept_with_settings(settings) { - match req { - OutgoingVerificationRequest::ToDevice(r) => { - self.client.send_to_device(&r).await?; - } - OutgoingVerificationRequest::InRoom(r) => { - self.client.room_send_helper(&r).await?; - } - } + if let Some(request) = self.inner.accept_with_settings(settings) { + self.client.send_verification_request(request).await?; } Ok(()) } @@ -82,16 +75,8 @@ impl Sas { pub async fn confirm(&self) -> Result<()> { let (request, signature) = self.inner.confirm().await?; - match request { - Some(OutgoingVerificationRequest::InRoom(r)) => { - self.client.room_send_helper(&r).await?; - } - - Some(OutgoingVerificationRequest::ToDevice(r)) => { - self.client.send_to_device(&r).await?; - } - - None => (), + if let Some(request) = request { + self.client.send_verification_request(request).await?; } if let Some(s) = signature { @@ -104,14 +89,7 @@ impl Sas { /// Cancel the interactive verification flow. pub async fn cancel(&self) -> Result<()> { if let Some(request) = self.inner.cancel() { - match request { - OutgoingVerificationRequest::ToDevice(r) => { - self.client.send_to_device(&r).await?; - } - OutgoingVerificationRequest::InRoom(r) => { - self.client.room_send_helper(&r).await?; - } - } + self.client.send_verification_request(request).await?; } Ok(()) @@ -138,6 +116,11 @@ impl Sas { self.inner.is_done() } + /// Are we in a state where we can show the short auth string. + pub fn can_be_presented(&self) -> bool { + self.inner.can_be_presented() + } + /// Is the verification process canceled. pub fn is_cancelled(&self) -> bool { self.inner.is_cancelled() diff --git a/matrix_sdk/src/verification_request.rs b/matrix_sdk/src/verification_request.rs deleted file mode 100644 index 4d2773a2..00000000 --- a/matrix_sdk/src/verification_request.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2020 The Matrix.org Foundation C.I.C. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use matrix_sdk_base::crypto::{ - OutgoingVerificationRequest, VerificationRequest as BaseVerificationRequest, -}; - -use crate::{Client, Result}; - -/// An object controlling the interactive verification flow. -#[derive(Debug, Clone)] -pub struct VerificationRequest { - pub(crate) inner: BaseVerificationRequest, - pub(crate) client: Client, -} - -impl VerificationRequest { - /// Accept the verification request - pub async fn accept(&self) -> Result<()> { - if let Some(request) = self.inner.accept() { - match request { - OutgoingVerificationRequest::ToDevice(r) => { - self.client.send_to_device(&r).await?; - } - OutgoingVerificationRequest::InRoom(r) => { - self.client.room_send_helper(&r).await?; - } - }; - } - - Ok(()) - } - - /// Cancel the verification request - pub async fn cancel(&self) -> Result<()> { - todo!() - } -} diff --git a/matrix_sdk_base/src/client.rs b/matrix_sdk_base/src/client.rs index 0b16beff..b36d9041 100644 --- a/matrix_sdk_base/src/client.rs +++ b/matrix_sdk_base/src/client.rs @@ -36,7 +36,7 @@ use matrix_sdk_common::{locks::Mutex, uuid::Uuid}; use matrix_sdk_crypto::{ store::{CryptoStore, CryptoStoreError}, Device, EncryptionSettings, IncomingResponse, MegolmError, OlmError, OlmMachine, - OutgoingRequest, Sas, ToDeviceRequest, UserDevices, + OutgoingRequest, ToDeviceRequest, UserDevices, }; #[cfg(feature = "encryption")] use ruma::{ @@ -1202,26 +1202,6 @@ impl BaseClient { } } - /// Get a `Sas` verification object with the given flow id. - /// - /// # Arguments - /// - /// * `flow_id` - The unique id that identifies a interactive verification - /// flow. For in-room verifications this will be the event id of the - /// *m.key.verification.request* event that started the flow, for the - /// to-device verification flows this will be the transaction id of the - /// *m.key.verification.start* event. - #[cfg(feature = "encryption")] - #[cfg_attr(feature = "docs", doc(cfg(encryption)))] - pub async fn get_verification(&self, user_id: &UserId, flow_id: &str) -> Option { - self.olm - .lock() - .await - .as_ref() - .and_then(|o| o.get_verification(user_id, flow_id).map(|v| v.sas_v1())) - .flatten() - } - /// Get a specific device of a user. /// /// # Arguments diff --git a/matrix_sdk_base/src/store/sled_store/mod.rs b/matrix_sdk_base/src/store/sled_store/mod.rs index 4f3ba8f2..31a9ccbd 100644 --- a/matrix_sdk_base/src/store/sled_store/mod.rs +++ b/matrix_sdk_base/src/store/sled_store/mod.rs @@ -720,6 +720,7 @@ impl SledStore { .map(|u| { u.map_err(StoreError::Sled).and_then(|(key, value)| { self.deserialize_event(&value) + // TODO remove this unwrapping .map(|receipt| { (decode_key_value(&key, 3).unwrap().try_into().unwrap(), receipt) })