crypto: Send out done events for in-room verifications.
parent
79102b3390
commit
4ad4ad1e94
|
@ -222,7 +222,7 @@ impl VerificationMachine {
|
||||||
event: &AnySyncRoomEvent,
|
event: &AnySyncRoomEvent,
|
||||||
) -> Result<(), CryptoStoreError> {
|
) -> Result<(), CryptoStoreError> {
|
||||||
if let AnySyncRoomEvent::Message(m) = event {
|
if let AnySyncRoomEvent::Message(m) = event {
|
||||||
// Since this are room events we will get events that we send out on
|
// Since these are room events we will get events that we send out on
|
||||||
// our own as well.
|
// our own as well.
|
||||||
if m.sender() == self.account.user_id() {
|
if m.sender() == self.account.user_id() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -308,10 +308,25 @@ impl VerificationMachine {
|
||||||
&s,
|
&s,
|
||||||
&m.clone().into_full_event(room_id.clone()),
|
&m.clone().into_full_event(room_id.clone()),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AnySyncMessageEvent::KeyVerificationDone(e) => {
|
||||||
|
if let Some(s) = self.room_verifications.get(&e.content.relation.event_id) {
|
||||||
|
let content =
|
||||||
|
s.receive_room_event(&m.clone().into_full_event(room_id.clone()));
|
||||||
|
|
||||||
if s.is_done() {
|
if s.is_done() {
|
||||||
match s.mark_as_done().await? {
|
match s.mark_as_done().await? {
|
||||||
VerificationResult::Ok => (),
|
VerificationResult::Ok => {
|
||||||
|
if let Some(c) = content {
|
||||||
|
self.queue_up_content(
|
||||||
|
s.other_user_id(),
|
||||||
|
s.other_device_id(),
|
||||||
|
c,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
VerificationResult::Cancel(r) => {
|
VerificationResult::Cancel(r) => {
|
||||||
self.outgoing_to_device_messages
|
self.outgoing_to_device_messages
|
||||||
.insert(r.request_id(), r.into());
|
.insert(r.request_id(), r.into());
|
||||||
|
@ -321,6 +336,14 @@ impl VerificationMachine {
|
||||||
|
|
||||||
self.outgoing_to_device_messages
|
self.outgoing_to_device_messages
|
||||||
.insert(request.request_id, request);
|
.insert(request.request_id, request);
|
||||||
|
|
||||||
|
if let Some(c) = content {
|
||||||
|
self.queue_up_content(
|
||||||
|
s.other_user_id(),
|
||||||
|
s.other_device_id(),
|
||||||
|
c,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ use matrix_sdk_common::{
|
||||||
key::verification::{
|
key::verification::{
|
||||||
accept::{AcceptEventContent, AcceptToDeviceEventContent},
|
accept::{AcceptEventContent, AcceptToDeviceEventContent},
|
||||||
cancel::{CancelEventContent, CancelToDeviceEventContent},
|
cancel::{CancelEventContent, CancelToDeviceEventContent},
|
||||||
|
done::DoneEventContent,
|
||||||
key::{KeyEventContent, KeyToDeviceEventContent},
|
key::{KeyEventContent, KeyToDeviceEventContent},
|
||||||
mac::{MacEventContent, MacToDeviceEventContent},
|
mac::{MacEventContent, MacToDeviceEventContent},
|
||||||
start::{StartEventContent, StartMethod, StartToDeviceEventContent},
|
start::{StartEventContent, StartMethod, StartToDeviceEventContent},
|
||||||
|
@ -187,6 +188,24 @@ impl From<CancelToDeviceEventContent> for CancelContent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum DoneContent {
|
||||||
|
Room(RoomId, DoneEventContent),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DoneContent {
|
||||||
|
pub fn flow_id(&self) -> FlowId {
|
||||||
|
match self {
|
||||||
|
DoneContent::Room(r, c) => FlowId::InRoom(r.clone(), c.relation.event_id.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(RoomId, DoneEventContent)> for DoneContent {
|
||||||
|
fn from(content: (RoomId, DoneEventContent)) -> Self {
|
||||||
|
DoneContent::Room(content.0, content.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum OutgoingContent {
|
pub enum OutgoingContent {
|
||||||
Room(RoomId, AnyMessageEventContent),
|
Room(RoomId, AnyMessageEventContent),
|
||||||
|
@ -222,6 +241,14 @@ impl From<KeyContent> for OutgoingContent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<DoneContent> for OutgoingContent {
|
||||||
|
fn from(content: DoneContent) -> Self {
|
||||||
|
match content {
|
||||||
|
DoneContent::Room(r, c) => (r, AnyMessageEventContent::KeyVerificationDone(c)).into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<AnyToDeviceEventContent> for OutgoingContent {
|
impl From<AnyToDeviceEventContent> for OutgoingContent {
|
||||||
fn from(content: AnyToDeviceEventContent) -> Self {
|
fn from(content: AnyToDeviceEventContent) -> Self {
|
||||||
OutgoingContent::ToDevice(content)
|
OutgoingContent::ToDevice(content)
|
||||||
|
|
|
@ -30,6 +30,7 @@ use matrix_sdk_common::{
|
||||||
},
|
},
|
||||||
identifiers::{EventId, RoomId, UserId},
|
identifiers::{EventId, RoomId, UserId},
|
||||||
};
|
};
|
||||||
|
use tracing::trace;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
identities::{ReadOnlyDevice, UserIdentities},
|
identities::{ReadOnlyDevice, UserIdentities},
|
||||||
|
@ -40,7 +41,7 @@ use super::{
|
||||||
event_enums::{AcceptContent, CancelContent, MacContent, OutgoingContent},
|
event_enums::{AcceptContent, CancelContent, MacContent, OutgoingContent},
|
||||||
sas_state::{
|
sas_state::{
|
||||||
Accepted, Canceled, Confirmed, Created, Done, FlowId, KeyReceived, MacReceived, SasState,
|
Accepted, Canceled, Confirmed, Created, Done, FlowId, KeyReceived, MacReceived, SasState,
|
||||||
Started,
|
Started, WaitingForDone,
|
||||||
},
|
},
|
||||||
StartContent,
|
StartContent,
|
||||||
};
|
};
|
||||||
|
@ -53,6 +54,8 @@ pub enum InnerSas {
|
||||||
KeyRecieved(SasState<KeyReceived>),
|
KeyRecieved(SasState<KeyReceived>),
|
||||||
Confirmed(SasState<Confirmed>),
|
Confirmed(SasState<Confirmed>),
|
||||||
MacReceived(SasState<MacReceived>),
|
MacReceived(SasState<MacReceived>),
|
||||||
|
WaitingForDone(SasState<WaitingForDone>),
|
||||||
|
WaitingForDoneUnconfirmed(SasState<WaitingForDone>),
|
||||||
Done(SasState<Done>),
|
Done(SasState<Done>),
|
||||||
Canceled(SasState<Canceled>),
|
Canceled(SasState<Canceled>),
|
||||||
}
|
}
|
||||||
|
@ -125,6 +128,8 @@ impl InnerSas {
|
||||||
InnerSas::Confirmed(s) => s.set_creation_time(time),
|
InnerSas::Confirmed(s) => s.set_creation_time(time),
|
||||||
InnerSas::MacReceived(s) => s.set_creation_time(time),
|
InnerSas::MacReceived(s) => s.set_creation_time(time),
|
||||||
InnerSas::Done(s) => s.set_creation_time(time),
|
InnerSas::Done(s) => s.set_creation_time(time),
|
||||||
|
InnerSas::WaitingForDone(s) => s.set_creation_time(time),
|
||||||
|
InnerSas::WaitingForDoneUnconfirmed(s) => s.set_creation_time(time),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,9 +156,17 @@ impl InnerSas {
|
||||||
(InnerSas::Confirmed(sas), Some(content))
|
(InnerSas::Confirmed(sas), Some(content))
|
||||||
}
|
}
|
||||||
InnerSas::MacReceived(s) => {
|
InnerSas::MacReceived(s) => {
|
||||||
let sas = s.confirm();
|
if s.is_dm_verification() {
|
||||||
let content = sas.as_content();
|
let sas = s.confirm_and_wait_for_done();
|
||||||
(InnerSas::Done(sas), Some(content))
|
let content = sas.as_content();
|
||||||
|
|
||||||
|
(InnerSas::WaitingForDoneUnconfirmed(sas), Some(content))
|
||||||
|
} else {
|
||||||
|
let sas = s.confirm();
|
||||||
|
let content = sas.as_content();
|
||||||
|
|
||||||
|
(InnerSas::Done(sas), Some(content))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => (self, None),
|
_ => (self, None),
|
||||||
}
|
}
|
||||||
|
@ -201,6 +214,22 @@ impl InnerSas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InnerSas::Confirmed(s) => {
|
InnerSas::Confirmed(s) => {
|
||||||
|
match s.into_waiting_for_done(&e.sender, (e.room_id.clone(), e.content.clone()))
|
||||||
|
{
|
||||||
|
Ok(s) => {
|
||||||
|
let content = s.done_content();
|
||||||
|
(InnerSas::WaitingForDone(s), Some(content.into()))
|
||||||
|
}
|
||||||
|
Err(s) => {
|
||||||
|
let content = s.as_content();
|
||||||
|
(InnerSas::Canceled(s), Some(content.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (self, None),
|
||||||
|
},
|
||||||
|
AnyMessageEvent::KeyVerificationDone(e) => match self {
|
||||||
|
InnerSas::WaitingForDone(s) => {
|
||||||
match s.into_done(&e.sender, (e.room_id.clone(), e.content.clone())) {
|
match s.into_done(&e.sender, (e.room_id.clone(), e.content.clone())) {
|
||||||
Ok(s) => (InnerSas::Done(s), None),
|
Ok(s) => (InnerSas::Done(s), None),
|
||||||
Err(s) => {
|
Err(s) => {
|
||||||
|
@ -209,6 +238,19 @@ impl InnerSas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
InnerSas::WaitingForDoneUnconfirmed(s) => {
|
||||||
|
match s.into_done(&e.sender, (e.room_id.clone(), e.content.clone())) {
|
||||||
|
Ok(s) => {
|
||||||
|
let content = s.done_content();
|
||||||
|
(InnerSas::Done(s), Some(content.into()))
|
||||||
|
}
|
||||||
|
Err(s) => {
|
||||||
|
let content = s.as_content();
|
||||||
|
(InnerSas::Canceled(s), Some(content.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_ => (self, None),
|
_ => (self, None),
|
||||||
},
|
},
|
||||||
_ => (self, None),
|
_ => (self, None),
|
||||||
|
@ -300,6 +342,8 @@ impl InnerSas {
|
||||||
InnerSas::KeyRecieved(s) => s.timed_out(),
|
InnerSas::KeyRecieved(s) => s.timed_out(),
|
||||||
InnerSas::Confirmed(s) => s.timed_out(),
|
InnerSas::Confirmed(s) => s.timed_out(),
|
||||||
InnerSas::MacReceived(s) => s.timed_out(),
|
InnerSas::MacReceived(s) => s.timed_out(),
|
||||||
|
InnerSas::WaitingForDone(s) => s.timed_out(),
|
||||||
|
InnerSas::WaitingForDoneUnconfirmed(s) => s.timed_out(),
|
||||||
InnerSas::Done(s) => s.timed_out(),
|
InnerSas::Done(s) => s.timed_out(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,6 +357,8 @@ impl InnerSas {
|
||||||
InnerSas::KeyRecieved(s) => s.verification_flow_id.clone(),
|
InnerSas::KeyRecieved(s) => s.verification_flow_id.clone(),
|
||||||
InnerSas::Confirmed(s) => s.verification_flow_id.clone(),
|
InnerSas::Confirmed(s) => s.verification_flow_id.clone(),
|
||||||
InnerSas::MacReceived(s) => s.verification_flow_id.clone(),
|
InnerSas::MacReceived(s) => s.verification_flow_id.clone(),
|
||||||
|
InnerSas::WaitingForDone(s) => s.verification_flow_id.clone(),
|
||||||
|
InnerSas::WaitingForDoneUnconfirmed(s) => s.verification_flow_id.clone(),
|
||||||
InnerSas::Done(s) => s.verification_flow_id.clone(),
|
InnerSas::Done(s) => s.verification_flow_id.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ use matrix_sdk_common::{
|
||||||
MSasV1Content as AcceptV1Content, MSasV1ContentInit as AcceptV1ContentInit,
|
MSasV1Content as AcceptV1Content, MSasV1ContentInit as AcceptV1ContentInit,
|
||||||
},
|
},
|
||||||
cancel::{CancelCode, CancelEventContent, CancelToDeviceEventContent},
|
cancel::{CancelCode, CancelEventContent, CancelToDeviceEventContent},
|
||||||
|
done::DoneEventContent,
|
||||||
key::{KeyEventContent, KeyToDeviceEventContent},
|
key::{KeyEventContent, KeyToDeviceEventContent},
|
||||||
mac::MacToDeviceEventContent,
|
mac::MacToDeviceEventContent,
|
||||||
start::{
|
start::{
|
||||||
|
@ -47,7 +48,8 @@ use tracing::error;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
event_enums::{
|
event_enums::{
|
||||||
AcceptContent, CancelContent, KeyContent, MacContent, OutgoingContent, StartContent,
|
AcceptContent, CancelContent, DoneContent, KeyContent, MacContent, OutgoingContent,
|
||||||
|
StartContent,
|
||||||
},
|
},
|
||||||
helpers::{
|
helpers::{
|
||||||
calculate_commitment, get_decimal, get_emoji, get_mac_content, receive_mac_event, SasIds,
|
calculate_commitment, get_decimal, get_emoji, get_mac_content, receive_mac_event, SasIds,
|
||||||
|
@ -251,6 +253,15 @@ pub struct MacReceived {
|
||||||
verified_master_keys: Arc<[UserIdentities]>,
|
verified_master_keys: Arc<[UserIdentities]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The SAS state we're going to be in after we receive a MAC event in a DM. DMs
|
||||||
|
/// require a final message `m.key.verification.done` message to conclude the
|
||||||
|
/// verificaton. This state waits for such a message.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct WaitingForDone {
|
||||||
|
verified_devices: Arc<[ReadOnlyDevice]>,
|
||||||
|
verified_master_keys: Arc<[UserIdentities]>,
|
||||||
|
}
|
||||||
|
|
||||||
/// The SAS state indicating that the verification finished successfully.
|
/// The SAS state indicating that the verification finished successfully.
|
||||||
///
|
///
|
||||||
/// We can now mark the device in our verified devices lits as verified and sign
|
/// We can now mark the device in our verified devices lits as verified and sign
|
||||||
|
@ -300,6 +311,11 @@ impl<S: Clone> SasState<S> {
|
||||||
self.creation_time.elapsed() > MAX_AGE || self.last_event_time.elapsed() > MAX_EVENT_TIMEOUT
|
self.creation_time.elapsed() > MAX_AGE || self.last_event_time.elapsed() > MAX_EVENT_TIMEOUT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Is this verification happening inside a DM.
|
||||||
|
pub fn is_dm_verification(&self) -> bool {
|
||||||
|
matches!(&*self.verification_flow_id, FlowId::InRoom(_, _))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn set_creation_time(&mut self, time: Instant) {
|
pub fn set_creation_time(&mut self, time: Instant) {
|
||||||
|
@ -880,6 +896,48 @@ impl SasState<Confirmed> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Receive a m.key.verification.mac event, changing the state into
|
||||||
|
/// a `WaitingForDone` one. This method should be used instead of
|
||||||
|
/// `into_done()` if the verification started with a
|
||||||
|
/// `m.key.verification.request`.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `event` - The m.key.verification.mac event that was sent to us by
|
||||||
|
/// the other side.
|
||||||
|
pub fn into_waiting_for_done(
|
||||||
|
self,
|
||||||
|
sender: &UserId,
|
||||||
|
content: impl Into<MacContent>,
|
||||||
|
) -> Result<SasState<WaitingForDone>, SasState<Canceled>> {
|
||||||
|
let content = content.into();
|
||||||
|
|
||||||
|
self.check_event(&sender, &content.flow_id().as_str())
|
||||||
|
.map_err(|c| self.clone().cancel(c))?;
|
||||||
|
|
||||||
|
let (devices, master_keys) = receive_mac_event(
|
||||||
|
&self.inner.lock().unwrap(),
|
||||||
|
&self.ids,
|
||||||
|
&self.verification_flow_id.as_str(),
|
||||||
|
sender,
|
||||||
|
&content,
|
||||||
|
)
|
||||||
|
.map_err(|c| self.clone().cancel(c))?;
|
||||||
|
|
||||||
|
Ok(SasState {
|
||||||
|
inner: self.inner,
|
||||||
|
creation_time: self.creation_time,
|
||||||
|
last_event_time: self.last_event_time,
|
||||||
|
verification_flow_id: self.verification_flow_id,
|
||||||
|
ids: self.ids,
|
||||||
|
|
||||||
|
state: Arc::new(WaitingForDone {
|
||||||
|
verified_devices: devices.into(),
|
||||||
|
verified_master_keys: master_keys.into(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the content for the mac event.
|
/// Get the content for the mac event.
|
||||||
///
|
///
|
||||||
/// The content needs to be automatically sent to the other side.
|
/// The content needs to be automatically sent to the other side.
|
||||||
|
@ -911,6 +969,26 @@ impl SasState<MacReceived> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Confirm that the short auth string matches but wait for the other side
|
||||||
|
/// to confirm that it's done.
|
||||||
|
///
|
||||||
|
/// This needs to be done by the user, this will put us in the `WaitForDone`
|
||||||
|
/// state where we wait for the other side to confirm that the MAC event was
|
||||||
|
/// successfully received.
|
||||||
|
pub fn confirm_and_wait_for_done(self) -> SasState<WaitingForDone> {
|
||||||
|
SasState {
|
||||||
|
inner: self.inner,
|
||||||
|
verification_flow_id: self.verification_flow_id,
|
||||||
|
creation_time: self.creation_time,
|
||||||
|
last_event_time: self.last_event_time,
|
||||||
|
ids: self.ids,
|
||||||
|
state: Arc::new(WaitingForDone {
|
||||||
|
verified_devices: self.state.verified_devices.clone(),
|
||||||
|
verified_master_keys: self.state.verified_master_keys.clone(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the emoji version of the short authentication string.
|
/// Get the emoji version of the short authentication string.
|
||||||
///
|
///
|
||||||
/// Returns a vector of tuples where the first element is the emoji and the
|
/// Returns a vector of tuples where the first element is the emoji and the
|
||||||
|
@ -940,6 +1018,68 @@ impl SasState<MacReceived> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SasState<WaitingForDone> {
|
||||||
|
/// Get the content for the mac event.
|
||||||
|
///
|
||||||
|
/// The content needs to be automatically sent to the other side if it
|
||||||
|
/// wasn't already sent.
|
||||||
|
pub fn as_content(&self) -> MacContent {
|
||||||
|
get_mac_content(
|
||||||
|
&self.inner.lock().unwrap(),
|
||||||
|
&self.ids,
|
||||||
|
&self.verification_flow_id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn done_content(&self) -> DoneContent {
|
||||||
|
match self.verification_flow_id.as_ref() {
|
||||||
|
FlowId::ToDevice(_) => {
|
||||||
|
unreachable!("The done content isn't supported yet for to-device verifications")
|
||||||
|
}
|
||||||
|
FlowId::InRoom(r, e) => (
|
||||||
|
r.clone(),
|
||||||
|
DoneEventContent {
|
||||||
|
relation: Relation {
|
||||||
|
event_id: e.clone(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Receive a m.key.verification.mac event, changing the state into
|
||||||
|
/// a `Done` one
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `event` - The m.key.verification.mac event that was sent to us by
|
||||||
|
/// the other side.
|
||||||
|
pub fn into_done(
|
||||||
|
self,
|
||||||
|
sender: &UserId,
|
||||||
|
content: impl Into<DoneContent>,
|
||||||
|
) -> Result<SasState<Done>, SasState<Canceled>> {
|
||||||
|
let content = content.into();
|
||||||
|
|
||||||
|
self.check_event(&sender, &content.flow_id().as_str())
|
||||||
|
.map_err(|c| self.clone().cancel(c))?;
|
||||||
|
|
||||||
|
Ok(SasState {
|
||||||
|
inner: self.inner,
|
||||||
|
creation_time: self.creation_time,
|
||||||
|
last_event_time: self.last_event_time,
|
||||||
|
verification_flow_id: self.verification_flow_id,
|
||||||
|
ids: self.ids,
|
||||||
|
|
||||||
|
state: Arc::new(Done {
|
||||||
|
verified_devices: self.state.verified_devices.clone(),
|
||||||
|
verified_master_keys: self.state.verified_master_keys.clone(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SasState<Done> {
|
impl SasState<Done> {
|
||||||
/// Get the content for the mac event.
|
/// Get the content for the mac event.
|
||||||
///
|
///
|
||||||
|
@ -953,6 +1093,23 @@ impl SasState<Done> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn done_content(&self) -> DoneContent {
|
||||||
|
match self.verification_flow_id.as_ref() {
|
||||||
|
FlowId::ToDevice(_) => {
|
||||||
|
unreachable!("The done content isn't supported yet for to-device verifications")
|
||||||
|
}
|
||||||
|
FlowId::InRoom(r, e) => (
|
||||||
|
r.clone(),
|
||||||
|
DoneEventContent {
|
||||||
|
relation: Relation {
|
||||||
|
event_id: e.clone(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the list of verified devices.
|
/// Get the list of verified devices.
|
||||||
pub fn verified_devices(&self) -> Arc<[ReadOnlyDevice]> {
|
pub fn verified_devices(&self) -> Arc<[ReadOnlyDevice]> {
|
||||||
self.state.verified_devices.clone()
|
self.state.verified_devices.clone()
|
||||||
|
|
Loading…
Reference in New Issue