diff --git a/keyserver/addons/rust-node-addon/rust-binding-types.js b/keyserver/addons/rust-node-addon/rust-binding-types.js --- a/keyserver/addons/rust-node-addon/rust-binding-types.js +++ b/keyserver/addons/rust-node-addon/rust-binding-types.js @@ -89,6 +89,13 @@ authAccessToken: string, userIds: $ReadOnlyArray, ) => Promise, + +privilegedResetUserPassword: ( + authUserId: string, + authDeviceId: string, + authAccessToken: string, + username: string, + password: string, + ) => Promise, +syncPlatformDetails: ( userId: string, deviceId: string, diff --git a/keyserver/addons/rust-node-addon/src/identity_client/mod.rs b/keyserver/addons/rust-node-addon/src/identity_client/mod.rs --- a/keyserver/addons/rust-node-addon/src/identity_client/mod.rs +++ b/keyserver/addons/rust-node-addon/src/identity_client/mod.rs @@ -7,6 +7,7 @@ pub mod nonce; pub mod prekey; mod privileged_delete_users; +mod privileged_reset_user_password; pub mod register_user; pub mod remove_reserved_usernames; mod sync_platform_details; @@ -22,7 +23,9 @@ use generated::CODE_VERSION; use grpc_clients::identity::authenticated::ChainedInterceptedAuthClient; use grpc_clients::identity::protos::authenticated::{ - InboundKeyInfo, PrivilegedDeleteUsersRequest, UploadOneTimeKeysRequest, + InboundKeyInfo, PrivilegedDeleteUsersRequest, + PrivilegedResetUserPasswordFinishRequest, + PrivilegedResetUserPasswordStartRequest, UploadOneTimeKeysRequest, }; use grpc_clients::identity::protos::unauthenticated as client_proto; use grpc_clients::identity::shared::CodeVersionLayer; diff --git a/keyserver/addons/rust-node-addon/src/identity_client/privileged_reset_user_password.rs b/keyserver/addons/rust-node-addon/src/identity_client/privileged_reset_user_password.rs new file mode 100644 --- /dev/null +++ b/keyserver/addons/rust-node-addon/src/identity_client/privileged_reset_user_password.rs @@ -0,0 +1,64 @@ +use super::*; + +#[napi] +#[instrument(skip_all)] +pub async fn privileged_reset_user_password( + auth_user_id: String, + auth_device_id: String, + auth_access_token: String, + username: String, + password: String, +) -> Result<()> { + let mut identity_client = get_authenticated_identity_client( + auth_user_id, + auth_device_id, + auth_access_token, + ) + .await?; + + let mut opaque_registration = comm_opaque2::client::Registration::new(); + let opaque_registration_request = + opaque_registration.start(&password).map_err(|_| { + Error::from_reason("Failed to create opaque registration request") + })?; + + let privileged_reset_user_password_start_request = + PrivilegedResetUserPasswordStartRequest { + opaque_registration_request, + username, + }; + + let response = identity_client + .privileged_reset_user_password_start( + privileged_reset_user_password_start_request, + ) + .await + .map_err(handle_grpc_error)?; + + let privileged_reset_user_password_start_response = response.into_inner(); + + let opaque_registration_upload = opaque_registration + .finish( + &password, + &privileged_reset_user_password_start_response + .opaque_registration_response, + ) + .map_err(|_| { + Error::from_reason("Failed to create opaque registration upload") + })?; + + let privileged_reset_user_password_finish_request = + PrivilegedResetUserPasswordFinishRequest { + session_id: privileged_reset_user_password_start_response.session_id, + opaque_registration_upload, + }; + + identity_client + .privileged_reset_user_password_finish( + privileged_reset_user_password_finish_request, + ) + .await + .map_err(handle_grpc_error)?; + + Ok(()) +}