Skip to content

Commit 4f1dc02

Browse files
authored
Merge branch 'main' into wasm_indexedb_and_sqlite
Signed-off-by: Daniel Salinas <zzorba@users.noreply.github.com>
2 parents cd91d9d + 08e1d38 commit 4f1dc02

File tree

5 files changed

+186
-169
lines changed

5 files changed

+186
-169
lines changed

bindings/matrix-sdk-ffi/src/client_builder.rs

Lines changed: 2 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ use std::{num::NonZeroUsize, sync::Arc, time::Duration};
22

33
use futures_util::StreamExt;
44
use matrix_sdk::{
5-
authentication::oauth::qrcode::{self, DeviceCodeErrorResponseType, LoginFailureReason},
6-
crypto::{
7-
types::qr_login::{LoginQrCodeDecodeError, QrCodeModeData},
8-
CollectStrategy, TrustRequirement,
9-
},
5+
crypto::{types::qr_login::QrCodeModeData, CollectStrategy, TrustRequirement},
106
encryption::{BackupDownloadStrategy, EncryptionSettings},
117
event_cache::EventCacheError,
128
reqwest::Certificate,
@@ -18,7 +14,6 @@ use matrix_sdk::{
1814
Client as MatrixClient, ClientBuildError as MatrixClientBuildError, HttpError, IdParseError,
1915
RumaApiError,
2016
};
21-
use matrix_sdk_common::{SendOutsideWasm, SyncOutsideWasm};
2217
use ruma::api::error::{DeserializationError, FromHttpResponseError};
2318
use tracing::{debug, error};
2419

@@ -28,6 +23,7 @@ use crate::{
2823
client::ClientSessionDelegate,
2924
error::ClientError,
3025
helpers::unwrap_or_clone_arc,
26+
qr_code::{HumanQrLoginError, QrCodeData, QrLoginProgressListener},
3127
runtime::get_runtime_handle,
3228
session_store::{SessionStoreConfig, SessionStoreResult},
3329
task_handle::TaskHandle,
@@ -43,164 +39,6 @@ enum HomeserverConfig {
4339
ServerNameOrUrl(String),
4440
}
4541

46-
/// Data for the QR code login mechanism.
47-
///
48-
/// The [`QrCodeData`] can be serialized and encoded as a QR code or it can be
49-
/// decoded from a QR code.
50-
#[derive(Debug, uniffi::Object)]
51-
pub struct QrCodeData {
52-
inner: qrcode::QrCodeData,
53-
}
54-
55-
#[matrix_sdk_ffi_macros::export]
56-
impl QrCodeData {
57-
/// Attempt to decode a slice of bytes into a [`QrCodeData`] object.
58-
///
59-
/// The slice of bytes would generally be returned by a QR code decoder.
60-
#[uniffi::constructor]
61-
pub fn from_bytes(bytes: Vec<u8>) -> Result<Arc<Self>, QrCodeDecodeError> {
62-
Ok(Self { inner: qrcode::QrCodeData::from_bytes(&bytes)? }.into())
63-
}
64-
65-
/// The server name contained within the scanned QR code data.
66-
///
67-
/// Note: This value is only present when scanning a QR code the belongs to
68-
/// a logged in client. The mode where the new client shows the QR code
69-
/// will return `None`.
70-
pub fn server_name(&self) -> Option<String> {
71-
match &self.inner.mode_data {
72-
QrCodeModeData::Reciprocate { server_name } => Some(server_name.to_owned()),
73-
QrCodeModeData::Login => None,
74-
}
75-
}
76-
}
77-
78-
/// Error type for the decoding of the [`QrCodeData`].
79-
#[derive(Debug, thiserror::Error, uniffi::Error)]
80-
#[uniffi(flat_error)]
81-
pub enum QrCodeDecodeError {
82-
#[error("Error decoding QR code: {error:?}")]
83-
Crypto {
84-
#[from]
85-
error: LoginQrCodeDecodeError,
86-
},
87-
}
88-
89-
#[derive(Debug, thiserror::Error, uniffi::Error)]
90-
pub enum HumanQrLoginError {
91-
#[error("Linking with this device is not supported.")]
92-
LinkingNotSupported,
93-
#[error("The sign in was cancelled.")]
94-
Cancelled,
95-
#[error("The sign in was not completed in the required time.")]
96-
Expired,
97-
#[error("A secure connection could not have been established between the two devices.")]
98-
ConnectionInsecure,
99-
#[error("The sign in was declined.")]
100-
Declined,
101-
#[error("An unknown error has happened.")]
102-
Unknown,
103-
#[error("The homeserver doesn't provide sliding sync in its configuration.")]
104-
SlidingSyncNotAvailable,
105-
#[error("Unable to use OIDC as the supplied client metadata is invalid.")]
106-
OidcMetadataInvalid,
107-
#[error("The other device is not signed in and as such can't sign in other devices.")]
108-
OtherDeviceNotSignedIn,
109-
}
110-
111-
impl From<qrcode::QRCodeLoginError> for HumanQrLoginError {
112-
fn from(value: qrcode::QRCodeLoginError) -> Self {
113-
use qrcode::{QRCodeLoginError, SecureChannelError};
114-
115-
match value {
116-
QRCodeLoginError::LoginFailure { reason, .. } => match reason {
117-
LoginFailureReason::UnsupportedProtocol => HumanQrLoginError::LinkingNotSupported,
118-
LoginFailureReason::AuthorizationExpired => HumanQrLoginError::Expired,
119-
LoginFailureReason::UserCancelled => HumanQrLoginError::Cancelled,
120-
_ => HumanQrLoginError::Unknown,
121-
},
122-
123-
QRCodeLoginError::OAuth(e) => {
124-
if let Some(e) = e.as_request_token_error() {
125-
match e {
126-
DeviceCodeErrorResponseType::AccessDenied => HumanQrLoginError::Declined,
127-
DeviceCodeErrorResponseType::ExpiredToken => HumanQrLoginError::Expired,
128-
_ => HumanQrLoginError::Unknown,
129-
}
130-
} else {
131-
HumanQrLoginError::Unknown
132-
}
133-
}
134-
135-
QRCodeLoginError::SecureChannel(e) => match e {
136-
SecureChannelError::Utf8(_)
137-
| SecureChannelError::MessageDecode(_)
138-
| SecureChannelError::Json(_)
139-
| SecureChannelError::RendezvousChannel(_) => HumanQrLoginError::Unknown,
140-
SecureChannelError::SecureChannelMessage { .. }
141-
| SecureChannelError::Ecies(_)
142-
| SecureChannelError::InvalidCheckCode => HumanQrLoginError::ConnectionInsecure,
143-
SecureChannelError::InvalidIntent => HumanQrLoginError::OtherDeviceNotSignedIn,
144-
},
145-
146-
QRCodeLoginError::UnexpectedMessage { .. }
147-
| QRCodeLoginError::CrossProcessRefreshLock(_)
148-
| QRCodeLoginError::DeviceKeyUpload(_)
149-
| QRCodeLoginError::SessionTokens(_)
150-
| QRCodeLoginError::UserIdDiscovery(_)
151-
| QRCodeLoginError::SecretImport(_) => HumanQrLoginError::Unknown,
152-
}
153-
}
154-
}
155-
156-
/// Enum describing the progress of the QR-code login.
157-
#[derive(Debug, Default, Clone, uniffi::Enum)]
158-
pub enum QrLoginProgress {
159-
/// The login process is starting.
160-
#[default]
161-
Starting,
162-
/// We established a secure channel with the other device.
163-
EstablishingSecureChannel {
164-
/// The check code that the device should display so the other device
165-
/// can confirm that the channel is secure as well.
166-
check_code: u8,
167-
/// The string representation of the check code, will be guaranteed to
168-
/// be 2 characters long, preserving the leading zero if the
169-
/// first digit is a zero.
170-
check_code_string: String,
171-
},
172-
/// We are waiting for the login and for the OAuth 2.0 authorization server
173-
/// to give us an access token.
174-
WaitingForToken { user_code: String },
175-
/// The login has successfully finished.
176-
Done,
177-
}
178-
179-
#[matrix_sdk_ffi_macros::export(callback_interface)]
180-
pub trait QrLoginProgressListener: SyncOutsideWasm + SendOutsideWasm {
181-
fn on_update(&self, state: QrLoginProgress);
182-
}
183-
184-
impl From<qrcode::LoginProgress> for QrLoginProgress {
185-
fn from(value: qrcode::LoginProgress) -> Self {
186-
use qrcode::LoginProgress;
187-
188-
match value {
189-
LoginProgress::Starting => Self::Starting,
190-
LoginProgress::EstablishingSecureChannel { check_code } => {
191-
let check_code = check_code.to_digit();
192-
193-
Self::EstablishingSecureChannel {
194-
check_code,
195-
check_code_string: format!("{check_code:02}"),
196-
}
197-
}
198-
LoginProgress::WaitingForToken { user_code } => Self::WaitingForToken { user_code },
199-
LoginProgress::Done => Self::Done,
200-
}
201-
}
202-
}
203-
20442
#[derive(Debug, thiserror::Error, uniffi::Error)]
20543
#[uniffi(flat_error)]
20644
pub enum ClientBuildError {

bindings/matrix-sdk-ffi/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mod live_location_share;
1818
mod notification;
1919
mod notification_settings;
2020
mod platform;
21+
mod qr_code;
2122
mod room;
2223
mod room_alias;
2324
mod room_directory_search;
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
use std::sync::Arc;
2+
3+
use matrix_sdk::{
4+
authentication::oauth::qrcode::{self, DeviceCodeErrorResponseType, LoginFailureReason},
5+
crypto::types::qr_login::{LoginQrCodeDecodeError, QrCodeModeData},
6+
};
7+
use matrix_sdk_common::{SendOutsideWasm, SyncOutsideWasm};
8+
use tracing::error;
9+
10+
/// Data for the QR code login mechanism.
11+
///
12+
/// The [`QrCodeData`] can be serialized and encoded as a QR code or it can be
13+
/// decoded from a QR code.
14+
#[derive(Debug, uniffi::Object)]
15+
pub struct QrCodeData {
16+
pub(crate) inner: qrcode::QrCodeData,
17+
}
18+
19+
#[matrix_sdk_ffi_macros::export]
20+
impl QrCodeData {
21+
/// Attempt to decode a slice of bytes into a [`QrCodeData`] object.
22+
///
23+
/// The slice of bytes would generally be returned by a QR code decoder.
24+
#[uniffi::constructor]
25+
pub fn from_bytes(bytes: Vec<u8>) -> Result<Arc<Self>, QrCodeDecodeError> {
26+
Ok(Self { inner: qrcode::QrCodeData::from_bytes(&bytes)? }.into())
27+
}
28+
29+
/// The server name contained within the scanned QR code data.
30+
///
31+
/// Note: This value is only present when scanning a QR code the belongs to
32+
/// a logged in client. The mode where the new client shows the QR code
33+
/// will return `None`.
34+
pub fn server_name(&self) -> Option<String> {
35+
match &self.inner.mode_data {
36+
QrCodeModeData::Reciprocate { server_name } => Some(server_name.to_owned()),
37+
QrCodeModeData::Login => None,
38+
}
39+
}
40+
}
41+
42+
/// Error type for the decoding of the [`QrCodeData`].
43+
#[derive(Debug, thiserror::Error, uniffi::Error)]
44+
#[uniffi(flat_error)]
45+
pub enum QrCodeDecodeError {
46+
#[error("Error decoding QR code: {error:?}")]
47+
Crypto {
48+
#[from]
49+
error: LoginQrCodeDecodeError,
50+
},
51+
}
52+
53+
#[derive(Debug, thiserror::Error, uniffi::Error)]
54+
pub enum HumanQrLoginError {
55+
#[error("Linking with this device is not supported.")]
56+
LinkingNotSupported,
57+
#[error("The sign in was cancelled.")]
58+
Cancelled,
59+
#[error("The sign in was not completed in the required time.")]
60+
Expired,
61+
#[error("A secure connection could not have been established between the two devices.")]
62+
ConnectionInsecure,
63+
#[error("The sign in was declined.")]
64+
Declined,
65+
#[error("An unknown error has happened.")]
66+
Unknown,
67+
#[error("The homeserver doesn't provide sliding sync in its configuration.")]
68+
SlidingSyncNotAvailable,
69+
#[error("Unable to use OIDC as the supplied client metadata is invalid.")]
70+
OidcMetadataInvalid,
71+
#[error("The other device is not signed in and as such can't sign in other devices.")]
72+
OtherDeviceNotSignedIn,
73+
}
74+
75+
impl From<qrcode::QRCodeLoginError> for HumanQrLoginError {
76+
fn from(value: qrcode::QRCodeLoginError) -> Self {
77+
use qrcode::{QRCodeLoginError, SecureChannelError};
78+
79+
match value {
80+
QRCodeLoginError::LoginFailure { reason, .. } => match reason {
81+
LoginFailureReason::UnsupportedProtocol => HumanQrLoginError::LinkingNotSupported,
82+
LoginFailureReason::AuthorizationExpired => HumanQrLoginError::Expired,
83+
LoginFailureReason::UserCancelled => HumanQrLoginError::Cancelled,
84+
_ => HumanQrLoginError::Unknown,
85+
},
86+
87+
QRCodeLoginError::OAuth(e) => {
88+
if let Some(e) = e.as_request_token_error() {
89+
match e {
90+
DeviceCodeErrorResponseType::AccessDenied => HumanQrLoginError::Declined,
91+
DeviceCodeErrorResponseType::ExpiredToken => HumanQrLoginError::Expired,
92+
_ => HumanQrLoginError::Unknown,
93+
}
94+
} else {
95+
HumanQrLoginError::Unknown
96+
}
97+
}
98+
99+
QRCodeLoginError::SecureChannel(e) => match e {
100+
SecureChannelError::Utf8(_)
101+
| SecureChannelError::MessageDecode(_)
102+
| SecureChannelError::Json(_)
103+
| SecureChannelError::RendezvousChannel(_) => HumanQrLoginError::Unknown,
104+
SecureChannelError::SecureChannelMessage { .. }
105+
| SecureChannelError::Ecies(_)
106+
| SecureChannelError::InvalidCheckCode => HumanQrLoginError::ConnectionInsecure,
107+
SecureChannelError::InvalidIntent => HumanQrLoginError::OtherDeviceNotSignedIn,
108+
},
109+
110+
QRCodeLoginError::UnexpectedMessage { .. }
111+
| QRCodeLoginError::CrossProcessRefreshLock(_)
112+
| QRCodeLoginError::DeviceKeyUpload(_)
113+
| QRCodeLoginError::SessionTokens(_)
114+
| QRCodeLoginError::UserIdDiscovery(_)
115+
| QRCodeLoginError::SecretImport(_) => HumanQrLoginError::Unknown,
116+
}
117+
}
118+
}
119+
120+
/// Enum describing the progress of the QR-code login.
121+
#[derive(Debug, Default, Clone, uniffi::Enum)]
122+
pub enum QrLoginProgress {
123+
/// The login process is starting.
124+
#[default]
125+
Starting,
126+
/// We established a secure channel with the other device.
127+
EstablishingSecureChannel {
128+
/// The check code that the device should display so the other device
129+
/// can confirm that the channel is secure as well.
130+
check_code: u8,
131+
/// The string representation of the check code, will be guaranteed to
132+
/// be 2 characters long, preserving the leading zero if the
133+
/// first digit is a zero.
134+
check_code_string: String,
135+
},
136+
/// We are waiting for the login and for the OAuth 2.0 authorization server
137+
/// to give us an access token.
138+
WaitingForToken { user_code: String },
139+
/// The login has successfully finished.
140+
Done,
141+
}
142+
143+
#[matrix_sdk_ffi_macros::export(callback_interface)]
144+
pub trait QrLoginProgressListener: SyncOutsideWasm + SendOutsideWasm {
145+
fn on_update(&self, state: QrLoginProgress);
146+
}
147+
148+
impl From<qrcode::LoginProgress> for QrLoginProgress {
149+
fn from(value: qrcode::LoginProgress) -> Self {
150+
use qrcode::LoginProgress;
151+
152+
match value {
153+
LoginProgress::Starting => Self::Starting,
154+
LoginProgress::EstablishingSecureChannel { check_code } => {
155+
let check_code = check_code.to_digit();
156+
157+
Self::EstablishingSecureChannel {
158+
check_code,
159+
check_code_string: format!("{check_code:02}"),
160+
}
161+
}
162+
LoginProgress::WaitingForToken { user_code } => Self::WaitingForToken { user_code },
163+
LoginProgress::Done => Self::Done,
164+
}
165+
}
166+
}

crates/matrix-sdk/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file.
66

77
## [Unreleased] - ReleaseDate
88

9+
- Add logging to `Room::join`.
10+
([#5260](https://github.com/matrix-org/matrix-rust-sdk/pull/5260))
911
- `ClientServerCapabilities` has been renamed to `ClientServerInfo`. Alongside this,
1012
`Client::reset_server_info` is now `Client::reset_server_info` and `Client::fetch_server_capabilities`
1113
is now `Client::fetch_server_versions`, returning the server versions response directly.

0 commit comments

Comments
 (0)