0

I've created a password recovery page.

The page works correctly, the only thing I want to add is a 60 minute expiration date for the password recovery link.

Here's what happens when a user wants to recover the password:

1) Go to the page /forgot-password and write the account email.

2) An email is sent to him containing a link generated by the code below with the help of user_activation_key and user_login

3) The user selects the link and ends at the page /forgot-password/?action=rp&key =0123abcd&login=johndoe where he is asked to enter the new password twice.

Everything works properly.

The only thing I ask is:

How can I add a 60 minutes expiration date for that link since it is generated?

I heard that we should add a code like this but it doesn't work for me.

$expiration_duration = apply_filters( ‘password_reset_expiration’, 30 );

Below is the code for the forgot-password page:

<?php 
/*
Lets you display a forgot/reset password page within your theme.
Eg, create a page called 'Forgot Password'; save this file as page-forgot-password.php
Adapted from code posted here: http://wordpress.stackexchange.com/questions/14692/check-for-correct-username-on-custom-login-form/14696#14696
*/
//First pull a bunch of functions from the native WP password reset file
/**
 * Retrieves a user row based on password reset key and login
 *
 * @uses $wpdb WordPress Database object
 *
 * @param string $key Hash to validate sending user's password
 * @param string $login The user login
 * @return object|WP_Error User's database row on success, error object for invalid keys
 */

function check_password_reset_key1($key, $login) {
    global $wpdb;
    $key = preg_replace('/[^a-z0-9]/i', '', $key);
    if ( empty( $key ) || !is_string( $key ) )
        return new WP_Error('invalid_key', __('Invalid key'));
    if ( empty($login) || !is_string($login) )
        return new WP_Error('invalid_key', __('Invalid key'));
    $user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE user_activation_key = %s AND user_login = %s", $key, $login));
    if ( empty( $user ) )
        return new WP_Error('invalid_key', __('Invalid key'));
    return $user;
}
/**
 * Handles resetting the user's password.
 *
 * @param object $user The user
 * @param string $new_pass New password for the user in plaintext
 */
function reset_password1($user, $new_pass) {
    do_action('password_reset', $user, $new_pass);
    wp_set_password($new_pass, $user->ID);
    wp_password_change_notification($user);
}
/*
Forgot password page. This page allows users to enter their username/email address to reset the password.
The reset password email redirects here, allowing the user to specify a new password.
It will also process the reset password form.
*/
$error = array();
if (isset($_POST['reset_pass'])){
    global $wpdb;
    $username = trim($_POST['user_login']);
    $user_exists = false;
    if ( username_exists( $username ) ){
        $user_exists = true;
        $user = get_user_by('login', $username);
    }elseif ( email_exists($username) ){
        $user_exists = true;
        $user = get_user_by('email', $username);

    }else{
        $error[] = "Username or Email was not found";
    }
    if ($user_exists){
        $user_login = $user->user_login;
        $user_email = $user->user_email;
        // Generate something ran for a password... md5'ing current time with a rand salt
        $key = substr( md5( uniqid( microtime() ) ), 0, 8);
        // Now insert the new pass md5'd into the db
        $wpdb->query("UPDATE $wpdb->users SET user_activation_key = '$key' WHERE user_login = '$user_login'");
        //create email message
        $message = __('Someone has asked to reset the password for the following site and username.') . "\r\n\r\n";
        $message .= get_option('siteurl') . "\r\n\r\n";
        $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
        $message .= __('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.') . "\r\n\r\n";
        $message .= $_SERVER['REQUEST_URI']."?action=rp&key=$key&login=$user_login\r\n";
        //send email meassage
        if (FALSE == wp_mail($user_email, sprintf(__('[%s] Password Reset'), get_option('blogname')), $message)){
            $error[] = '<p>' . __('The e-mail could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function...') . '</p>';
        }
    }
}
if(isset($_GET['key'], $_GET['login'])){

    $user = check_password_reset_key1($_GET['key'], $_GET['login']);

    if(empty($user)){

        $error[] = "Sorry, that appears to be an invalid or expired key. Please <a href=\"/forgot-password/\">re-request the password reset email</a> and follow the link therein.";
    }
    else{

        if ( isset($_POST['pass1']) && $_POST['pass1'] != $_POST['pass2'] ) {
            $error[] = "The passwords do not match";
        } elseif ( isset($_POST['pass1']) && !empty($_POST['pass1']) ) {
            reset_password1($user, $_POST['pass1']);
            $success = 1;
        }
    }
}
/* ---------------------- PAGE OUTPUT ---------------------- */
get_header(); 
    /* The password was reset successfully */
    if($success):
        //Password reset message, eg. 'Thanks, your password has been reset. Click here to log in
    /* The form was submitted successfully */
    elseif(isset($_POST['reset_pass']) && empty($error)):

        //Email sent message, eg. 'Thanks, a message will be sent to your email address with instructions to reset your password.'

    /* User has returned from the email bearing a user key */
    elseif(isset($_GET['key'], $_GET['login'])):

        $key = $_GET['key'];
        $login = $_GET['login'];

        if(!empty($error)): //output errors if there are any ?>
        <div class="warning">
            <p>The following errors occurred:</p>
            <ul>
            <?php foreach($error as $e): ?>
                <li><?php echo $e; ?></li>
            <?php endforeach; ?>
            </ul>
        </div>
        <?php endif; ?>

        <!-- Password reset form -->

        <form class="signup" name="loginform" id="loginform" method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>?action=resetpass&#038;key=<?php echo $key; ?>&#038;login=<?php echo $login; ?>">

            <input type="hidden" id="user_login" value="<?php echo $login; ?>" autocomplete="off">
            <fieldset>
                <label for="pass1"><?php _e('New Password'); ?></label>
                <input type="password" name="pass1" id="pass1" class="input" size="20" value="" autocomplete="off">                 
            </fieldset>
            <fieldset>
                <label for="pass2"><?php _e('Confirm new Password'); ?></label>
                <input type="password" name="pass2" id="pass2" class="input" size="20" value="" autocomplete="off">                 
            </fieldset>
            <fieldset class="last">
                <input type="submit" name="user-submit" value="<?php _e('Reset my password'); ?>" class="user-submit" tabindex="1002" />
            </fieldset>
        </form>

    <?php
    /* Default state/show errors */
    else: 

        if(!empty($error)): ?>
        <div class="warning">
            <p>The following errors occurred:</p>
            <ul>
            <?php foreach($error as $e): ?>
                <li><?php echo $e; ?></li>
            <?php endforeach; ?>
            </ul>
        </div>
        <?php endif; ?>

        <!-- Password reset form -->

        <form class="signup" name="loginform" id="loginform" method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
            <fieldset>
                <label for="user_login" class="hide"><?php _e('Username or Email'); ?>: </label>
                <input type="text" name="user_login" value="" size="20" id="user_login" tabindex="1001" />                      
            </fieldset>
            <fieldset class="last">
                <?php do_action('login_form', 'resetpass'); ?>
                <input type="hidden" name="reset_pass" value="1" />
                <input type="submit" name="user-submit" value="<?php _e('Send password reset email'); ?>" class="user-submit" tabindex="1002" />
            </fieldset>
        </form>

    <?php endif;

get_footer(); ?>

Thanks to those who will help me.

Best regards.

  • Do you have it working without the 60 minute restriction? – Tom J Nowell Aug 30 at 17:04
  • I'm still at the beginning, for the moment I can only send the email but I need to know how to build the generated link to pass it to the email ... – Matteo Feduzi Aug 30 at 17:06
  • Not sure how I can move or what guides to follow? Thanks a lot. – Matteo Feduzi Aug 30 at 17:56
  • I'd recommend implementing it without the restriction as that would be the next step, otherwise the problem is too large and unwieldy to tackle. If you look for a tutorial or article that has both a time restriction AND a forgotten password, it will be much more difficult, then to find "How to implement custom password reset form" then modify it to add the restriction – Tom J Nowell Sep 1 at 22:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.