Enviar el enlace de restablecimiento de contraseña mediante programación

33

Tengo esta página creada manualmente:

$user_login = sanitize_text_field( $_GET['user_login'] );

if ( username_exists( $user_login ) ||  email_exists($user_login) ) { ?>
<!--Everything has been validated, proceed ....-->

<!DOCTYPE HTML>
<html lang="en-US">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        function submit()
        {
            var f = document.getElementById('lostpasswordform');
            f.onclick = function () { };
            document.lostpasswordform.submit();
        }
    </script>
</head>
<body onload="submit()">

    <form name="lostpasswordform" id="lostpasswordform" action="<?php echo esc_url( site_url( 'wp-login.php?action=lostpassword', 'login_post' ) ); ?>" method="post">

        <input type="hidden" name="user_login" id="user_login" class="input" value="<?php echo ($user_login); ?>" />

    <?php do_action('lost_password'); ?>

    </form>

</body>
</html>

<?php
    echo "SUCCESS";
    exit();
} else {
    echo "Entered Username or Email was incorrect, please try again!";
}

... todo parece correcto, pero no funciona cuando se llama desde una aplicación, pero si lo visito manualmente domain.com/forgot-password?user_login=username, envía el correo electrónico de restablecimiento bien.

Nimbuz
fuente
por appqué quieres decirplugin
amit
no, app - android
Nimbuz
no funciona lo que pasa?
pcarvalho

Respuestas:

25

Entonces, si desea enviar ese enlace de restablecimiento de contraseña y tiene acceso a la base de código, puede usar el siguiente fragmento y puede modificarlo aún más, en realidad ese código es una versión ligeramente modificada de wp-login.php

/**
 * Handles sending password retrieval email to user.
 *
 * @uses $wpdb WordPress Database object
 * @param string $user_login User Login or Email
 * @return bool true on success false on error
 */
function retrieve_password($user_login) {
    global $wpdb, $current_site;

    if ( empty( $user_login) ) {
        return false;
    } else if ( strpos( $user_login, '@' ) ) {
        $user_data = get_user_by( 'email', trim( $user_login ) );
        if ( empty( $user_data ) )
           return false;
    } else {
        $login = trim($user_login);
        $user_data = get_user_by('login', $login);
    }

    do_action('lostpassword_post');


    if ( !$user_data ) return false;

    // redefining user_login ensures we return the right case in the email
    $user_login = $user_data->user_login;
    $user_email = $user_data->user_email;

    do_action('retreive_password', $user_login);  // Misspelled and deprecated
    do_action('retrieve_password', $user_login);

    $allow = apply_filters('allow_password_reset', true, $user_data->ID);

    if ( ! $allow )
        return false;
    else if ( is_wp_error($allow) )
        return false;

    $key = $wpdb->get_var($wpdb->prepare("SELECT user_activation_key FROM $wpdb->users WHERE user_login = %s", $user_login));
    if ( empty($key) ) {
        // Generate something random for a key...
        $key = wp_generate_password(20, false);
        do_action('retrieve_password_key', $user_login, $key);
        // Now insert the new md5 key into the db
        $wpdb->update($wpdb->users, array('user_activation_key' => $key), array('user_login' => $user_login));
    }
    $message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n";
    $message .= network_home_url( '/' ) . "\r\n\r\n";
    $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
    $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n";
    $message .= __('To reset your password, visit the following address:') . "\r\n\r\n";
    $message .= '<' . network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . ">\r\n";

    if ( is_multisite() )
        $blogname = $GLOBALS['current_site']->site_name;
    else
        // The blogname option is escaped with esc_html on the way into the database in sanitize_option
        // we want to reverse this for the plain text arena of emails.
        $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);

    $title = sprintf( __('[%s] Password Reset'), $blogname );

    $title = apply_filters('retrieve_password_title', $title);
    $message = apply_filters('retrieve_password_message', $message, $key);

    if ( $message && !wp_mail($user_email, $title, $message) )
        wp_die( __('The e-mail could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function...') );

    return true;
}

$user_login = sanitize_text_field( $_GET['user_login'] );

if (retrieve_password($user_login)) {
    echo "SUCCESS";
} else {
    echo "ERROR";
}
nvartolomei
fuente
Esto no me funciona exactamente bien. Lo ingresé en un complemento personalizado y lo puse en mi sitio, pero está causando un problema en el que cuando instalo el complemento y luego hago clic en 'Cerrar sesión', no me desconectará del sitio. Alguna idea de por qué?
MxmastaMills
20

La respuesta anterior no funcionó para mí (dice que el código no es válido, en la página de inicio de sesión de wp), probablemente porque la respuesta tiene 1,5 años y algo ha cambiado en el código WP, por lo que he actualizado este código un poco (también de wp-login.php), aquí está:

function retrieve_password($user_login){
    global $wpdb, $wp_hasher;

    $user_login = sanitize_text_field($user_login);

    if ( empty( $user_login) ) {
        return false;
    } else if ( strpos( $user_login, '@' ) ) {
        $user_data = get_user_by( 'email', trim( $user_login ) );
        if ( empty( $user_data ) )
           return false;
    } else {
        $login = trim($user_login);
        $user_data = get_user_by('login', $login);
    }

    do_action('lostpassword_post');


    if ( !$user_data ) return false;

    // redefining user_login ensures we return the right case in the email
    $user_login = $user_data->user_login;
    $user_email = $user_data->user_email;

    do_action('retreive_password', $user_login);  // Misspelled and deprecated
    do_action('retrieve_password', $user_login);

    $allow = apply_filters('allow_password_reset', true, $user_data->ID);

    if ( ! $allow )
        return false;
    else if ( is_wp_error($allow) )
        return false;

    $key = wp_generate_password( 20, false );
    do_action( 'retrieve_password_key', $user_login, $key );

    if ( empty( $wp_hasher ) ) {
        require_once ABSPATH . 'wp-includes/class-phpass.php';
        $wp_hasher = new PasswordHash( 8, true );
    }
    $hashed = $wp_hasher->HashPassword( $key );
    $wpdb->update( $wpdb->users, array( 'user_activation_key' => $hashed ), array( 'user_login' => $user_login ) );

    $message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n";
    $message .= network_home_url( '/' ) . "\r\n\r\n";
    $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
    $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n";
    $message .= __('To reset your password, visit the following address:') . "\r\n\r\n";
    $message .= '<' . network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . ">\r\n";

    if ( is_multisite() )
        $blogname = $GLOBALS['current_site']->site_name;
    else
        $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);

    $title = sprintf( __('[%s] Password Reset'), $blogname );

    $title = apply_filters('retrieve_password_title', $title);
    $message = apply_filters('retrieve_password_message', $message, $key);

    if ( $message && !wp_mail($user_email, $title, $message) )
        wp_die( __('The e-mail could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function...') );

    echo '<p>Link for password reset has been emailed to you. Please check your email.</p>';;
}
DzoniT
fuente
Esto funcionó para mí. La respuesta aceptada para 3.8.1 no funcionó y terminó en clave caducada. Específicamente, en $keyprocesamiento y actualización user_activation_key.
Rolice
1
Esta respuesta también resultó en un enlace caducado para mí y no funcionó.
carburo20
7

Noté que después de actualizar WordPress a la Versión 4.3, lo anterior ya no funcionaba para mi complemento personalizado. Siempre informaría que la clave no era válida.

Cambio:

$hashed = $wp_hasher->HashPassword( $key );

a

$hashed = time() . ':' . $wp_hasher->HashPassword( $key );

Esto solucionó el problema para mí, espero que ayude a alguien más

anastymous
fuente
6

Ninguna de las respuestas anteriores funcionó para mí, así que busqué en wp-login.php su funcionalidad de restablecimiento predeterminada. Utilizaron la función get_password_reset_key ($ userData). En caso de que alguien se atasque en las respuestas anteriores, esta es mi solución:

            $userData = get_userdata($user_id);             

            $user_login = $userData->user_login;
            $user_email = $userData->user_email;
            $key = get_password_reset_key( $userData );


            $message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n";
            $message .= network_home_url( '/' ) . "\r\n\r\n";
            $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
            $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n";
            $message .= __('To reset your password, visit the following address:') . "\r\n\r\n";
            $message .= network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login');
Piyush Rawat
fuente
3

Wordpress 4.3.1

function retrieve_password($user_login){
    global $wpdb, $wp_hasher;
    $user_login = sanitize_text_field($user_login);
    if ( empty( $user_login) ) {
        return false;
    } else if ( strpos( $user_login, '@' ) ) {
        $user_data = get_user_by( 'email', trim( $user_login ) );
        if ( empty( $user_data ) )
           return false;
    } else {
        $login = trim($user_login);
        $user_data = get_user_by('login', $login);
    }

    do_action('lostpassword_post');
    if ( !$user_data ) return false;
    // redefining user_login ensures we return the right case in the email
    $user_login = $user_data->user_login;
    $user_email = $user_data->user_email;
    do_action('retreive_password', $user_login);  // Misspelled and deprecated
    do_action('retrieve_password', $user_login);
    $allow = apply_filters('allow_password_reset', true, $user_data->ID);
    if ( ! $allow )
        return false;
    else if ( is_wp_error($allow) )
        return false;
    $key = wp_generate_password( 20, false );
    do_action( 'retrieve_password_key', $user_login, $key );

    if ( empty( $wp_hasher ) ) {
        require_once ABSPATH . 'wp-includes/class-phpass.php';
        $wp_hasher = new PasswordHash( 8, true );
    }
    $hashed = $wp_hasher->HashPassword( $key );    
    $wpdb->update( $wpdb->users, array( 'user_activation_key' => time().":".$hashed ), array( 'user_login' => $user_login ) );
    $message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n";
    $message .= network_home_url( '/' ) . "\r\n\r\n";
    $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
    $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n";
    $message .= __('To reset your password, visit the following address:') . "\r\n\r\n";
    $message .= '<' . network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . ">\r\n";

    if ( is_multisite() )
        $blogname = $GLOBALS['current_site']->site_name;
    else
        $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);

    $title = sprintf( __('[%s] Password Reset'), $blogname );

    $title = apply_filters('retrieve_password_title', $title);
    $message = apply_filters('retrieve_password_message', $message, $key);

    if ( $message && !wp_mail($user_email, $title, $message) )
        wp_die( __('The e-mail could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function...') );

    echo '<p>Link for password reset has been emailed to you. Please check your email.</p>';;
}
bhavesh vala
fuente
0

Prueba esto

$wpdb->update( $wpdb->users, array( 'user_activation_key' => $key ), array( 'user_login' => $user_login ) ); 

en lugar de

$wpdb->update( $wpdb->users, array( 'user_activation_key' => $hashed ), array( 'user_login' => $user_login ) );

Me funcionó (wordpress 4.3.1)

Ashok
fuente