diff --git a/crates/matrix-sdk/src/matrix_auth/login_builder.rs b/crates/matrix-sdk/src/matrix_auth/login_builder.rs index 5cf1b3fa8..a5d893f18 100644 --- a/crates/matrix-sdk/src/matrix_auth/login_builder.rs +++ b/crates/matrix-sdk/src/matrix_auth/login_builder.rs @@ -199,7 +199,11 @@ impl LoginBuilder { _ => None, }; - self.auth.client.encryption().bootstrap_cross_signing_if_needed(auth_data).await?; + if let Err(err) = + self.auth.client.encryption().bootstrap_cross_signing_if_needed(auth_data).await + { + tracing::warn!("cross-signing bootstrapping failed: {err}"); + } } Ok(response) diff --git a/crates/matrix-sdk/src/oidc/mod.rs b/crates/matrix-sdk/src/oidc/mod.rs index 727a50040..6e3dad276 100644 --- a/crates/matrix-sdk/src/oidc/mod.rs +++ b/crates/matrix-sdk/src/oidc/mod.rs @@ -922,7 +922,10 @@ impl Oidc { if self.client.encryption().settings().auto_enable_cross_signing { // According to MSC3967, OIDC doesn't require User-Interactive Authentication to // call this API. Let's find out! - self.client.encryption().bootstrap_cross_signing_if_needed(None).await?; + if let Err(err) = self.client.encryption().bootstrap_cross_signing_if_needed(None).await + { + warn!("cross-signing bootstrapping failed: {err}"); + } } if let Some(cross_process_manager) = self.ctx().cross_process_token_refresh_manager.get() { diff --git a/crates/matrix-sdk/tests/integration/matrix_auth.rs b/crates/matrix-sdk/tests/integration/matrix_auth.rs index bc29a1c36..d2d87f8ec 100644 --- a/crates/matrix-sdk/tests/integration/matrix_auth.rs +++ b/crates/matrix-sdk/tests/integration/matrix_auth.rs @@ -499,6 +499,77 @@ async fn test_login_with_cross_signing_bootstrapping() { assert_eq!(own_identity.user_id(), me); assert!(own_identity.is_verified()); } + + server.verify().await; +} + +#[cfg(feature = "e2e-encryption")] +#[async_test] +async fn test_login_doesnt_fail_if_cross_signing_bootstrapping_failed() { + let server = MockServer::start().await; + + Mock::given(method("POST")) + .and(path("/_matrix/client/r0/keys/query")) + .respond_with(ResponseTemplate::new(200).set_body_json(json!({ + "device_keys": { + "@alice:example.org": {} + } + }))) + .mount(&server) + .await; + + Mock::given(method("POST")) + .and(path("/_matrix/client/unstable/keys/device_signing/upload")) + .respond_with(ResponseTemplate::new(500).set_body_json(json!({}))) + .mount(&server) + .await; + + // Login with username and password. + let _guard = Mock::given(method("POST")) + .and(path("/_matrix/client/r0/login")) + .respond_with(|req: &Request| { + #[derive(serde::Deserialize)] + struct Parameters { + r#type: String, + password: String, + } + + let params: Parameters = req.body_json().unwrap(); + assert_eq!(params.r#type, "m.login.password"); + assert_eq!(params.password, "hunter2"); + + ResponseTemplate::new(200).set_body_json(json!({ + "access_token": "abc123", + "device_id": "GHTYAJCE", + "home_server": "example.org", + "user_id": "@alice:example.org" + })) + }) + .mount_as_scoped(&server) + .await; + + let client = Client::builder() + .homeserver_url(server.uri()) + .server_versions([MatrixVersion::V1_0]) + .with_encryption_settings(matrix_sdk::encryption::EncryptionSettings { + auto_enable_cross_signing: true, + }) + .request_config(RequestConfig::new().disable_retry()) + .build() + .await + .unwrap(); + + let auth = client.matrix_auth(); + auth.login_username("example", "hunter2").send().await.unwrap(); + + assert!(client.logged_in(), "Client should be logged in"); + assert!(auth.logged_in(), "Client should be logged in with the MatrixAuth API"); + + let me = client.user_id().expect("we are now logged in"); + + let own_identity = client.encryption().get_user_identity(me).await.expect("succeeds"); + let identity = own_identity.expect("created local default identity"); + assert!(identity.is_verified()); } #[cfg(feature = "e2e-encryption")]