I’m trying to build a custom change password page. I’ve created a REST API point for changing the password.
The function which the REST API calls is:
function change_password(WP_REST_Request $request)
{
$params = $request->get_params();
$password = $params['password'];
$new_password = $params['new_password'];
$status = 200;
$return_data = array(
"params" => $params,
);
$user = wp_get_current_user();
if ($user && wp_check_password($password, $user->data->user_pass)) {
wp_set_password($new_password, $user->ID);
// $res = wp_update_user(array('ID' => $user->ID, 'user_pass' => $new_password));
$return_data += ['message' => "Password successfully change"];
// $return_data += ['update_response' => $res];
} else {
$status = 400;
$return_data += ['error' => "You entered a wrong password"];
}
return new WP_REST_Response($return_data, $status);
}
Couple of weird observations:
- If I use wp_set_password, neither the old nor the new password work.
- If I use wp_update_user (toggling the necessary comments) approach, old password works as if nothing has changed.
- I also tried using both of them together but that again breaks both passwords.
- The forgot password link in WordPress login page works.
Side notes:
- I’m using Local for running WordPress locally (with nginx, PHP 8.3, MySQL 8.0.16)
- I’m sending a nonce field value to REST API so that the user can be identified.
- I’m asking for user to enter the new password twice, but I control it in frontend.
Here is the PHP code creating the password change form:
<form class="change-password-form" method="post">
<label for="password">Password:</label>
<input type="password" class="password" name="password"><br><br>
<label for="new-password">New Password:</label>
<input type="password" class="new-password" name="new-password"><br><br>
<label for="new-password-repeat">New Password Repeat:</label>
<input type="password" class="new-password-repeat" name="new-password-repeat"><br><br>
<input type="button" class="submit-button" value="Submit" />
<?php wp_nonce_field('change-password', 'trak-nonce'); ?>
<?php wp_nonce_field('wp_rest'); ?>
</form>
(A JS code reads the form and calls the REST API)