diff --git a/matrixgw_backend/src/extractors/matrix_client_extractor.rs b/matrixgw_backend/src/extractors/matrix_client_extractor.rs index 5de4f7f..545db6c 100644 --- a/matrixgw_backend/src/extractors/matrix_client_extractor.rs +++ b/matrixgw_backend/src/extractors/matrix_client_extractor.rs @@ -17,6 +17,7 @@ impl MatrixClientExtractor { user: self.auth.user.clone(), matrix_user_id: self.client.client.user_id().map(|id| id.to_string()), matrix_device_id: self.client.client.device_id().map(|id| id.to_string()), + matrix_recovery_state: self.client.recovery_state(), }) } } diff --git a/matrixgw_backend/src/matrix_connection/matrix_client.rs b/matrixgw_backend/src/matrix_connection/matrix_client.rs index cfc23b1..59b342c 100644 --- a/matrixgw_backend/src/matrix_connection/matrix_client.rs +++ b/matrixgw_backend/src/matrix_connection/matrix_client.rs @@ -9,6 +9,7 @@ use matrix_sdk::authentication::oauth::error::{ use matrix_sdk::authentication::oauth::{ ClientId, OAuthError, OAuthSession, UrlOrQuery, UserSession, }; +use matrix_sdk::encryption::recovery::RecoveryState; use matrix_sdk::ruma::serde::Raw; use matrix_sdk::{Client, ClientBuildError, RefreshTokenError}; use ractor::ActorRef; @@ -25,6 +26,14 @@ struct StoredSession { client_id: ClientId, } +#[derive(Debug, Serialize, Deserialize, Copy, Clone)] +pub enum EncryptionRecoveryState { + Unknown, + Enabled, + Disabled, + Incomplete, +} + /// Matrix Gateway session errors #[derive(thiserror::Error, Debug)] enum MatrixClientError { @@ -64,6 +73,8 @@ enum MatrixClientError { FinishLogin(matrix_sdk::Error), #[error("Failed to write session file! {0}")] WriteSessionFile(std::io::Error), + #[error("Failed to rename device! {0}")] + RenameDevice(matrix_sdk::HttpError), } #[derive(serde::Deserialize)] @@ -232,6 +243,19 @@ impl MatrixClient { // Persist session tokens self.save_stored_session().await?; + // Rename created session to give it a more explicit name + self.client + .rename_device( + self.client + .session_meta() + .context("Missing device ID!")? + .device_id + .as_ref(), + &AppConfig::get().website_origin, + ) + .await + .map_err(MatrixClientError::RenameDevice)?; + Ok(()) } @@ -304,4 +328,14 @@ impl MatrixClient { Ok(()) } + + /// Get current encryption keys recovery state + pub fn recovery_state(&self) -> EncryptionRecoveryState { + match self.client.encryption().recovery().state() { + RecoveryState::Unknown => EncryptionRecoveryState::Unknown, + RecoveryState::Enabled => EncryptionRecoveryState::Enabled, + RecoveryState::Disabled => EncryptionRecoveryState::Disabled, + RecoveryState::Incomplete => EncryptionRecoveryState::Incomplete, + } + } } diff --git a/matrixgw_backend/src/users.rs b/matrixgw_backend/src/users.rs index 7eca242..3dd37da 100644 --- a/matrixgw_backend/src/users.rs +++ b/matrixgw_backend/src/users.rs @@ -1,4 +1,5 @@ use crate::app_config::AppConfig; +use crate::matrix_connection::matrix_client::EncryptionRecoveryState; use crate::utils::time_utils::time_secs; use jwt_simple::reexports::serde_json; use std::cmp::min; @@ -173,4 +174,5 @@ pub struct ExtendedUserInfo { pub user: User, pub matrix_user_id: Option, pub matrix_device_id: Option, + pub matrix_recovery_state: EncryptionRecoveryState, } diff --git a/matrixgw_frontend/src/api/AuthApi.ts b/matrixgw_frontend/src/api/AuthApi.ts index e2e10ac..e504b25 100644 --- a/matrixgw_frontend/src/api/AuthApi.ts +++ b/matrixgw_frontend/src/api/AuthApi.ts @@ -8,6 +8,7 @@ export interface UserInfo { email: string; matrix_user_id?: string; matrix_device_id?: string; + matrix_recovery_state?: string; } const TokenStateKey = "auth-state";