From 7207ec07c3c7c1cc18615e232567d9114abcffbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABlle=20Huisman?= Date: Wed, 21 May 2025 12:26:43 +0200 Subject: [PATCH] feat(user-management): add reset password --- src/user_management/operations.rs | 2 + .../operations/reset_password.rs | 142 ++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 src/user_management/operations/reset_password.rs diff --git a/src/user_management/operations.rs b/src/user_management/operations.rs index ca0ec64..777e818 100644 --- a/src/user_management/operations.rs +++ b/src/user_management/operations.rs @@ -15,6 +15,7 @@ mod get_magic_auth; mod get_password_reset; mod get_user_identities; mod list_users; +mod reset_password; pub use authenticate_with_code::*; pub use authenticate_with_email_verification::*; @@ -33,3 +34,4 @@ pub use get_magic_auth::*; pub use get_password_reset::*; pub use get_user_identities::*; pub use list_users::*; +pub use reset_password::*; diff --git a/src/user_management/operations/reset_password.rs b/src/user_management/operations/reset_password.rs new file mode 100644 index 0000000..a2ad408 --- /dev/null +++ b/src/user_management/operations/reset_password.rs @@ -0,0 +1,142 @@ +use async_trait::async_trait; +use serde::Serialize; +use thiserror::Error; + +use crate::user_management::{PasswordResetToken, User, UserManagement}; +use crate::{ResponseExt, WorkOsError, WorkOsResult}; + +/// The parameters for [`ResetPassword`]. +#[derive(Debug, Serialize)] +pub struct ResetPasswordParams<'a> { + /// The `token` query parameter from the password reset URL. + pub token: &'a PasswordResetToken, + + /// The new password to set for the user. + pub new_password: &'a str, +} + +/// An error returned from [`ResetPassword`]. +#[derive(Debug, Error)] +pub enum ResetPasswordError {} + +impl From for WorkOsError { + fn from(err: ResetPasswordError) -> Self { + Self::Operation(err) + } +} + +/// [WorkOS Docs: Reset the password](https://workos.com/docs/reference/user-management/password-reset/reset-password) +#[async_trait] +pub trait ResetPassword { + /// Sets a new password using the token query parameter from the link that the user received. + /// + /// [WorkOS Docs: Reset the password](https://workos.com/docs/reference/user-management/password-reset/reset-password) + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// # use workos_sdk::WorkOsResult; + /// # use workos_sdk::user_management::*; + /// use workos_sdk::{ApiKey, WorkOs}; + /// + /// # async fn run() -> WorkOsResult<(), ResetPasswordError> { + /// let workos = WorkOs::new(&ApiKey::from("sk_example_123456789")); + /// + /// let user = workos + /// .user_management() + /// .reset_password(&ResetPasswordParams { + /// token: &PasswordResetToken::from("stpIJ48IFJt0HhSIqjf8eppe0"), + /// new_password: "i8uv6g34kd490s", + /// }) + /// .await?; + /// # Ok(()) + /// # } + /// ``` + async fn reset_password( + &self, + params: &ResetPasswordParams<'_>, + ) -> WorkOsResult; +} + +#[async_trait] +impl ResetPassword for UserManagement<'_> { + async fn reset_password( + &self, + params: &ResetPasswordParams<'_>, + ) -> WorkOsResult { + let url = self + .workos + .base_url() + .join("/user_management/password_reset/confirm")?; + + let user = self + .workos + .client() + .post(url) + .bearer_auth(self.workos.key()) + .json(¶ms) + .send() + .await? + .handle_unauthorized_or_generic_error()? + .json::() + .await?; + + Ok(user) + } +} + +#[cfg(test)] +mod test { + use serde_json::json; + use tokio; + + use crate::user_management::UserId; + use crate::{ApiKey, WorkOs}; + + use super::*; + + #[tokio::test] + async fn it_calls_the_reset_password_endpoint() { + let mut server = mockito::Server::new_async().await; + + let workos = WorkOs::builder(&ApiKey::from("sk_example_123456789")) + .base_url(&server.url()) + .unwrap() + .build(); + + server + .mock("POST", "/user_management/password_reset/confirm") + .match_header("Authorization", "Bearer sk_example_123456789") + .with_status(201) + .with_body( + json!({ + "object": "user", + "id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "email": "marcelina.davis@example.com", + "first_name": "Marcelina", + "last_name": "Davis", + "email_verified": true, + "profile_picture_url": "https://workoscdn.com/images/v1/123abc", + "metadata": {}, + "created_at": "2021-06-25T19:07:33.155Z", + "updated_at": "2021-06-25T19:07:33.155Z" + }) + .to_string(), + ) + .create_async() + .await; + + let user = workos + .user_management() + .reset_password(&ResetPasswordParams { + token: &PasswordResetToken::from("stpIJ48IFJt0HhSIqjf8eppe0"), + new_password: "i8uv6g34kd490s", + }) + .await + .unwrap(); + + assert_eq!(user.id, UserId::from("user_01E4ZCR3C56J083X43JQXF3JK5")) + } +}