I think you’re more interested in the last time the user reset their password than the last time they logged in. I’ve written this to check on the last password reset.
add_action( 'wp_login', 'wpse410045_check_last_login', 10, 2 );
/**
* Checks and updates the user's last login time.
*
* @param string $user_login The username.
* @param WP_User $user The user object.
*/
function wpse410045_check_last_login( $user_login, $user ) {
$now = time();
$single = true;
$last_reset = get_user_meta( $user->ID, 'my_prefix_last_password_reset', $single );
// If the user meta hasn't been set, use 0.
if ( empty( $last_reset ) ) {
$last_reset = 0;
}
if ( $now > ( absint( $last_reset + MONTH_IN_SECONDS ) ) {
// However you choose to do this.
require_user_password_reset();
}
}
add_action( 'after_password_reset', 'wpse_410045_update_password_meta', 10 );
/**
* Updates the time of the password reset for a user.
*
* @param WP_User $user The user whose password has been reset.
*/
function wpse_410045_update_password_meta( $user ) {
// Updates the "last password reset" meta to the present time.
update_user_meta( $user->ID, 'my_prefix_last_password_reset', time() );
}
Update
From the comments below: If you’re using the login_redirect
filter, you should be able to check for the last password change and redirect the user if their password has “expired”.
Replace the first part of the answer above with something like this (I’m assuming you’ve got a URL where you’ll want to redirect your users to actually change their passwords; I use /my-password-change
in the code.)
add_filter( 'login_redirect', 'wpse410045_check_password_age', 10, 3 );
/**
* Checks the user's last password change. Redirects if it's over a month old.
*
* @param string $redirect The destination URL.
* @param string $requested_redirect The requested destination URL.
* @param WP_User $user The user object.
*/
function wpse410045_check_last_login( $redirect, $requested_redirect, $user ) {
if ( is_wp_error( $user ) ) {
// Something went wrong, bail out.
return $redirect;
}
$now = time();
$single = true;
$last_reset = get_user_meta( $user->ID, 'my_prefix_last_password_reset', $single );
// If the user meta hasn't been set, use 0.
if ( empty( $last_reset ) ) {
$last_reset = 0;
}
if ( $now > ( absint( $last_reset + MONTH_IN_SECONDS ) ) {
// Redirect to the password change URL.
return '/my-password-change';
}
// Otherwise, carry on.
return $redirect;
}
The after_password_reset
action should still be fine.