diff --git a/bindings/matrix-sdk-ffi/CHANGELOG.md b/bindings/matrix-sdk-ffi/CHANGELOG.md index e9e0b9acff6..c84c05b3e75 100644 --- a/bindings/matrix-sdk-ffi/CHANGELOG.md +++ b/bindings/matrix-sdk-ffi/CHANGELOG.md @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. ### Features +- Add `CheckCodeSender::validate()` to allow `CheckCode` to be validated without sending. + ([#5957](https://github.com/matrix-org/matrix-rust-sdk/pull/5957)) - Add `SpaceService::get_space_room` to get a space given its id from the space graph if available. [#5944](https://github.com/matrix-org/matrix-rust-sdk/pull/5944) - Add `QrCodeData::to_bytes()` to allow generation of a QR code. diff --git a/bindings/matrix-sdk-ffi/src/qr_code.rs b/bindings/matrix-sdk-ffi/src/qr_code.rs index a3f59cd71f1..7ee60362d7e 100644 --- a/bindings/matrix-sdk-ffi/src/qr_code.rs +++ b/bindings/matrix-sdk-ffi/src/qr_code.rs @@ -633,4 +633,16 @@ impl CheckCodeSender { pub async fn send(&self, code: u8) -> Result<(), HumanQrLoginError> { self.inner.send(code).await.map_err(HumanQrLoginError::from) } + + /// Validate the [`CheckCode`] without sending it. + /// + /// This can be used to provide immediate feedback to the user. + /// + /// # Arguments + /// * `check_code` - The check code in digits representation. + /// + /// Returns `true` if the code is valid, `false` otherwise. + pub fn validate(&self, check_code: u8) -> bool { + self.inner.validate(check_code) + } } diff --git a/crates/matrix-sdk/CHANGELOG.md b/crates/matrix-sdk/CHANGELOG.md index f9f9c17ef4e..55cda834540 100644 --- a/crates/matrix-sdk/CHANGELOG.md +++ b/crates/matrix-sdk/CHANGELOG.md @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. ### Features +- Add `CheckCodeSender::validate()` to allow `CheckCode` to be validated without sending. + ([#5957](https://github.com/matrix-org/matrix-rust-sdk/pull/5957)) - Sending `MessageLike` and `RawMessageLike` events through a `Room` now returns the used `EncryptionInfo`, if any. ([#5936](https://github.com/matrix-org/matrix-rust-sdk/pull/5936)) diff --git a/crates/matrix-sdk/src/authentication/oauth/qrcode/grant.rs b/crates/matrix-sdk/src/authentication/oauth/qrcode/grant.rs index 43a073bc785..c58ebe7da9e 100644 --- a/crates/matrix-sdk/src/authentication/oauth/qrcode/grant.rs +++ b/crates/matrix-sdk/src/authentication/oauth/qrcode/grant.rs @@ -346,7 +346,7 @@ impl<'a> IntoFuture for GrantLoginWithGeneratedQrCode<'a> { // -- MSC4108 Secure channel setup step 6 let (tx, rx) = tokio::sync::oneshot::channel(); self.state.set(GrantLoginProgress::EstablishingSecureChannel( - GeneratedQrProgress::QrScanned(CheckCodeSender::new(tx)), + GeneratedQrProgress::QrScanned(CheckCodeSender::new(tx, channel.check_code())), )); let check_code = rx.await.map_err(|_| SecureChannelError::CannotReceiveCheckCode)?; @@ -756,6 +756,8 @@ mod test { .expect("The checkcode should only be forwarded once") .await .expect("Alice should receive the checkcode"); + assert!(checkcode_sender.validate(checkcode)); + assert!(!checkcode_sender.validate((checkcode + 1) % 100)); checkcode_sender .send(checkcode) .await diff --git a/crates/matrix-sdk/src/authentication/oauth/qrcode/login.rs b/crates/matrix-sdk/src/authentication/oauth/qrcode/login.rs index 7a7cb11ddc1..698e7496f4d 100644 --- a/crates/matrix-sdk/src/authentication/oauth/qrcode/login.rs +++ b/crates/matrix-sdk/src/authentication/oauth/qrcode/login.rs @@ -470,7 +470,7 @@ impl<'a> LoginWithGeneratedQrCode<'a> { trace!("Waiting for checkcode."); let (tx, rx) = tokio::sync::oneshot::channel(); self.state.set(LoginProgress::EstablishingSecureChannel(GeneratedQrProgress::QrScanned( - CheckCodeSender::new(tx), + CheckCodeSender::new(tx, channel.check_code()), ))); // Retrieve the entered checkcode and verify it to confirm that the channel is diff --git a/crates/matrix-sdk/src/authentication/oauth/qrcode/mod.rs b/crates/matrix-sdk/src/authentication/oauth/qrcode/mod.rs index a008df1e569..44fa2ad210c 100644 --- a/crates/matrix-sdk/src/authentication/oauth/qrcode/mod.rs +++ b/crates/matrix-sdk/src/authentication/oauth/qrcode/mod.rs @@ -329,11 +329,15 @@ pub enum GeneratedQrProgress { #[derive(Clone, Debug)] pub struct CheckCodeSender { inner: Arc>>>, + expected_check_code: CheckCode, } impl CheckCodeSender { - pub(crate) fn new(tx: tokio::sync::oneshot::Sender) -> Self { - Self { inner: Arc::new(Mutex::new(Some(tx))) } + pub(crate) fn new( + tx: tokio::sync::oneshot::Sender, + expected_check_code: CheckCode, + ) -> Self { + Self { inner: Arc::new(Mutex::new(Some(tx))), expected_check_code } } /// Send the checkcode. @@ -349,6 +353,18 @@ impl CheckCodeSender { None => Err(CheckCodeSenderError::AlreadySent), } } + + /// Validate the [`CheckCode`] without sending it. + /// + /// This can be used to provide immediate feedback to the user. + /// + /// # Arguments + /// * `check_code` - The check code in digits representation. + /// + /// Returns `true` if the code is valid, `false` otherwise. + pub fn validate(&self, check_code: u8) -> bool { + self.expected_check_code.to_digit() == check_code + } } /// Possible errors when calling [`CheckCodeSender::send`]. diff --git a/crates/matrix-sdk/src/authentication/oauth/qrcode/secure_channel/mod.rs b/crates/matrix-sdk/src/authentication/oauth/qrcode/secure_channel/mod.rs index 428cbeeac31..b8095ba2672 100644 --- a/crates/matrix-sdk/src/authentication/oauth/qrcode/secure_channel/mod.rs +++ b/crates/matrix-sdk/src/authentication/oauth/qrcode/secure_channel/mod.rs @@ -124,6 +124,10 @@ impl AlmostEstablishedSecureChannel { Err(Error::InvalidCheckCode) } } + + pub fn check_code(&self) -> CheckCode { + self.secure_channel.check_code().clone() + } } pub(super) struct EstablishedSecureChannel {