diff --git a/matrixgw_backend/src/controllers/matrix_link_controller.rs b/matrixgw_backend/src/controllers/matrix_link_controller.rs index 16fe6cf..d4e507e 100644 --- a/matrixgw_backend/src/controllers/matrix_link_controller.rs +++ b/matrixgw_backend/src/controllers/matrix_link_controller.rs @@ -43,3 +43,17 @@ pub async fn logout( Ok(HttpResponse::Ok().finish()) } + +#[derive(serde::Deserialize)] +struct SetRecoveryKeyRequest { + key: String, +} + +/// Set recovery key of user +pub async fn set_recovery_key(client: MatrixClientExtractor) -> HttpResult { + let key = client.auth.decode_json_body::()?.key; + + client.client.set_recovery_key(&key).await?; + + Ok(HttpResponse::Accepted().finish()) +} diff --git a/matrixgw_backend/src/extractors/auth_extractor.rs b/matrixgw_backend/src/extractors/auth_extractor.rs index 36003e6..277ffd6 100644 --- a/matrixgw_backend/src/extractors/auth_extractor.rs +++ b/matrixgw_backend/src/extractors/auth_extractor.rs @@ -40,7 +40,7 @@ impl AuthExtractor { .payload .as_ref() .context("Failed to decode request as json: missing payload!")?; - serde_json::from_slice(payload).context("Failed to decode request json!") + Ok(serde_json::from_slice(payload)?) } } diff --git a/matrixgw_backend/src/main.rs b/matrixgw_backend/src/main.rs index a239e35..f0af96a 100644 --- a/matrixgw_backend/src/main.rs +++ b/matrixgw_backend/src/main.rs @@ -106,6 +106,10 @@ async fn main() -> std::io::Result<()> { "/api/matrix_link/logout", web::post().to(matrix_link_controller::logout), ) + .route( + "/api/matrix_link/set_recovery_key", + web::post().to(matrix_link_controller::set_recovery_key), + ) }) .workers(4) .bind(&AppConfig::get().listen_address)? diff --git a/matrixgw_backend/src/matrix_connection/matrix_client.rs b/matrixgw_backend/src/matrix_connection/matrix_client.rs index 59b342c..d846e76 100644 --- a/matrixgw_backend/src/matrix_connection/matrix_client.rs +++ b/matrixgw_backend/src/matrix_connection/matrix_client.rs @@ -75,6 +75,8 @@ enum MatrixClientError { WriteSessionFile(std::io::Error), #[error("Failed to rename device! {0}")] RenameDevice(matrix_sdk::HttpError), + #[error("Failed to set recovery key! {0}")] + SetRecoveryKey(matrix_sdk::encryption::recovery::RecoveryError), } #[derive(serde::Deserialize)] @@ -338,4 +340,15 @@ impl MatrixClient { RecoveryState::Incomplete => EncryptionRecoveryState::Incomplete, } } + + /// Set new encryption key recovery key + pub async fn set_recovery_key(&self, key: &str) -> anyhow::Result<()> { + Ok(self + .client + .encryption() + .recovery() + .recover(key) + .await + .map_err(MatrixClientError::SetRecoveryKey)?) + } }