WordPress.org

Make WordPress Core

Ticket #15384: 15384.2.patch

File 15384.2.patch, 80.2 KB (added by jfarthing84, 5 years ago)

Fixed customize login and refreshed against trunk.

  • wp-login.php

     
    1111/** Make sure that the WordPress bootstrap has run before continuing. */
    1212require( dirname(__FILE__) . '/wp-load.php' );
    1313
    14 // Redirect to https login if forced to use SSL
    15 if ( force_ssl_admin() && ! is_ssl() ) {
    16         if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
    17                 wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) );
    18                 exit();
    19         } else {
    20                 wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
    21                 exit();
    22         }
    23 }
     14// Require WP_Login class
     15require( ABSPATH . WPINC . '/class-wp-login.php' );
    2416
     17// Instantiate a new WP_Login object
     18$wp_login = new WP_Login();
     19
     20// Process the request
     21$wp_login->process();
     22
     23// Enqueue wpLogin script
     24wp_enqueue_script( 'wp-login' );
     25
    2526/**
    26  * Output the login page header.
     27 * Add the mobile viewport meta tag.
    2728 *
    28  * @param string   $title    Optional. WordPress login Page title to display in the `<title>` element.
    29  *                           Default 'Log In'.
    30  * @param string   $message  Optional. Message to display in header. Default empty.
    31  * @param WP_Error $wp_error Optional. The error to pass. Default empty.
     29 * This should be placed somewhere else, just not sure where.
     30 *
     31 * @since 3.7.0
    3232 */
    33 function login_header( $title = 'Log In', $message = '', $wp_error = '' ) {
    34         global $error, $interim_login, $action;
     33function wp_login_viewport_meta() {
     34        if ( wp_is_mobile() ) {
     35        ?>
     36        <meta name="viewport" content="width=device-width" />
     37        <?php
     38        }
     39}
    3540
    36         // Don't index any of these forms
    37         add_action( 'login_head', 'wp_no_robots' );
     41?><!DOCTYPE html>
     42<!--[if IE 8]>
     43        <html xmlns="http://www.w3.org/1999/xhtml" class="ie8" <?php language_attributes(); ?>>
     44<![endif]-->
     45<!--[if !(IE 8) ]><!-->
     46        <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
     47<!--<![endif]-->
     48<head>
     49        <meta http-equiv="Content-Type" content="<?php bloginfo( 'html_type' ); ?>; charset=<?php bloginfo( 'charset' ); ?>" />
    3850
    39         if ( wp_is_mobile() )
    40                 add_action( 'login_head', 'wp_login_viewport_meta' );
     51        <title><?php bloginfo( 'name' ); ?> &rsaquo; <?php echo $wp_login->title(); ?></title>
    4152
    42         if ( empty($wp_error) )
    43                 $wp_error = new WP_Error();
    44 
    45         // Shake it!
    46         $shake_error_codes = array( 'empty_password', 'empty_email', 'invalid_email', 'invalidcombo', 'empty_username', 'invalid_username', 'incorrect_password' );
    47         /**
    48          * Filter the error codes array for shaking the login form.
    49          *
    50          * @since 3.0.0
    51          *
    52          * @param array $shake_error_codes Error codes that shake the login form.
    53          */
    54         $shake_error_codes = apply_filters( 'shake_error_codes', $shake_error_codes );
    55 
    56         if ( $shake_error_codes && $wp_error->get_error_code() && in_array( $wp_error->get_error_code(), $shake_error_codes ) )
    57                 add_action( 'login_head', 'wp_shake_js', 12 );
    58 
    59         ?><!DOCTYPE html>
    60         <!--[if IE 8]>
    61                 <html xmlns="http://www.w3.org/1999/xhtml" class="ie8" <?php language_attributes(); ?>>
    62         <![endif]-->
    63         <!--[if !(IE 8) ]><!-->
    64                 <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
    65         <!--<![endif]-->
    66         <head>
    67         <meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
    68         <title><?php bloginfo('name'); ?> &rsaquo; <?php echo $title; ?></title>
    6953        <?php
    7054
     55        // Output admin styles
    7156        wp_admin_css( 'login', true );
    7257
    73         /*
    74          * Remove all stored post data on logging out.
    75          * This could be added by add_action('login_head'...) like wp_shake_js(),
    76          * but maybe better if it's not removable by plugins
    77          */
    78         if ( 'loggedout' == $wp_error->get_error_code() ) {
    79                 ?>
    80                 <script>if("sessionStorage" in window){try{for(var key in sessionStorage){if(key.indexOf("wp-autosave-")!=-1){sessionStorage.removeItem(key)}}}catch(e){}};</script>
    81                 <?php
    82         }
    83 
    8458        /**
    8559         * Enqueue scripts and styles for the login page.
    8660         *
     
    8761         * @since 3.1.0
    8862         */
    8963        do_action( 'login_enqueue_scripts' );
     64
    9065        /**
    9166         * Fires in the login page header after scripts are enqueued.
    9267         *
     
    9469         */
    9570        do_action( 'login_head' );
    9671
    97         if ( is_multisite() ) {
    98                 $login_header_url   = network_home_url();
    99                 $login_header_title = get_current_site()->site_name;
    100         } else {
    101                 $login_header_url   = __( 'https://wordpress.org/' );
    102                 $login_header_title = __( 'Powered by WordPress' );
    103         }
    104 
    105         /**
    106          * Filter link URL of the header logo above login form.
    107          *
    108          * @since 2.1.0
    109          *
    110          * @param string $login_header_url Login header logo URL.
    111          */
    112         $login_header_url = apply_filters( 'login_headerurl', $login_header_url );
    113         /**
    114          * Filter the title attribute of the header logo above login form.
    115          *
    116          * @since 2.1.0
    117          *
    118          * @param string $login_header_title Login header logo title attribute.
    119          */
    120         $login_header_title = apply_filters( 'login_headertitle', $login_header_title );
    121 
    122         $classes = array( 'login-action-' . $action, 'wp-core-ui' );
    123         if ( wp_is_mobile() )
    124                 $classes[] = 'mobile';
    125         if ( is_rtl() )
    126                 $classes[] = 'rtl';
    127         if ( $interim_login ) {
    128                 $classes[] = 'interim-login';
     72        // Make background transparent for interim login
     73        if ( $wp_login->is_interim_login() ) {
    12974                ?>
    13075                <style type="text/css">html{background-color: transparent;}</style>
    13176                <?php
    132 
    133                 if ( 'success' ===  $interim_login )
    134                         $classes[] = 'interim-login-success';
    13577        }
    136         $classes[] =' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_locale() ) ) );
    13778
    138         /**
    139          * Filter the login page body classes.
    140          *
    141          * @since 3.5.0
    142          *
    143          * @param array  $classes An array of body classes.
    144          * @param string $action  The action that brought the visitor to the login page.
    145          */
    146         $classes = apply_filters( 'login_body_class', $classes, $action );
    147 
    14879        ?>
    149         </head>
    150         <body class="login <?php echo esc_attr( implode( ' ', $classes ) ); ?>">
     80</head>
     81<body class="<?php $wp_login->body_class(); ?>">
    15182        <div id="login">
    152                 <h1><a href="<?php echo esc_url( $login_header_url ); ?>" title="<?php echo esc_attr( $login_header_title ); ?>" tabindex="-1"><?php bloginfo( 'name' ); ?></a></h1>
    153         <?php
    154 
    155         unset( $login_header_url, $login_header_title );
    156 
    157         /**
    158          * Filter the message to display above the login form.
    159          *
    160          * @since 2.1.0
    161          *
    162          * @param string $message Login message text.
    163          */
    164         $message = apply_filters( 'login_message', $message );
    165         if ( !empty( $message ) )
    166                 echo $message . "\n";
    167 
    168         // In case a plugin uses $error rather than the $wp_errors object
    169         if ( !empty( $error ) ) {
    170                 $wp_error->add('error', $error);
    171                 unset($error);
    172         }
    173 
    174         if ( $wp_error->get_error_code() ) {
    175                 $errors = '';
    176                 $messages = '';
    177                 foreach ( $wp_error->get_error_codes() as $code ) {
    178                         $severity = $wp_error->get_error_data( $code );
    179                         foreach ( $wp_error->get_error_messages( $code ) as $error_message ) {
    180                                 if ( 'message' == $severity )
    181                                         $messages .= '  ' . $error_message . "<br />\n";
    182                                 else
    183                                         $errors .= '    ' . $error_message . "<br />\n";
    184                         }
    185                 }
    186                 if ( ! empty( $errors ) ) {
    187                         /**
    188                          * Filter the error messages displayed above the login form.
    189                          *
    190                          * @since 2.1.0
    191                          *
    192                          * @param string $errors Login error message.
    193                          */
    194                         echo '<div id="login_error">' . apply_filters( 'login_errors', $errors ) . "</div>\n";
    195                 }
    196                 if ( ! empty( $messages ) ) {
    197                         /**
    198                          * Filter instructional messages displayed above the login form.
    199                          *
    200                          * @since 2.5.0
    201                          *
    202                          * @param string $messages Login messages.
    203                          */
    204                         echo '<p class="message">' . apply_filters( 'login_messages', $messages ) . "</p>\n";
    205                 }
    206         }
    207 } // End of login_header()
    208 
    209 /**
    210  * Outputs the footer for the login page.
    211  *
    212  * @param string $input_id Which input to auto-focus
    213  */
    214 function login_footer($input_id = '') {
    215         global $interim_login;
    216 
    217         // Don't allow interim logins to navigate away from the page.
    218         if ( ! $interim_login ): ?>
    219         <p id="backtoblog"><a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php esc_attr_e( 'Are you lost?' ); ?>"><?php printf( __( '&larr; Back to %s' ), get_bloginfo( 'title', 'display' ) ); ?></a></p>
    220         <?php endif; ?>
    221 
     83                <?php $wp_login->render(); ?>
    22284        </div>
    22385
    224         <?php if ( !empty($input_id) ) : ?>
    225         <script type="text/javascript">
    226         try{document.getElementById('<?php echo $input_id; ?>').focus();}catch(e){}
    227         if(typeof wpOnload=='function')wpOnload();
    228         </script>
    229         <?php endif; ?>
    230 
    23186        <?php
    23287        /**
    23388         * Fires in the login page footer.
     
    23590         * @since 3.1.0
    23691         */
    23792        do_action( 'login_footer' ); ?>
     93
    23894        <div class="clear"></div>
    239         </body>
    240         </html>
    241         <?php
    242 }
    243 
    244 /**
    245  * @since 3.0.0
    246  */
    247 function wp_shake_js() {
    248         if ( wp_is_mobile() )
    249                 return;
    250 ?>
    251 <script type="text/javascript">
    252 addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
    253 function s(id,pos){g(id).left=pos+'px';}
    254 function g(id){return document.getElementById(id).style;}
    255 function shake(id,a,d){c=a.shift();s(id,c);if(a.length>0){setTimeout(function(){shake(id,a,d);},d);}else{try{g(id).position='static';wp_attempt_focus();}catch(e){}}}
    256 addLoadEvent(function(){ var p=new Array(15,30,15,0,-15,-30,-15,0);p=p.concat(p.concat(p));var i=document.forms[0].id;g(i).position='relative';shake(i,p,20);});
    257 </script>
    258 <?php
    259 }
    260 
    261 /**
    262  * @since 3.7.0
    263  */
    264 function wp_login_viewport_meta() {
    265         ?>
    266         <meta name="viewport" content="width=device-width" />
    267         <?php
    268 }
    269 
    270 /**
    271  * Handles sending password retrieval email to user.
    272  *
    273  * @global wpdb         $wpdb      WordPress database abstraction object.
    274  * @global PasswordHash $wp_hasher Portable PHP password hashing framework.
    275  *
    276  * @return bool|WP_Error True: when finish. WP_Error on error
    277  */
    278 function retrieve_password() {
    279         global $wpdb, $wp_hasher;
    280 
    281         $errors = new WP_Error();
    282 
    283         if ( empty( $_POST['user_login'] ) ) {
    284                 $errors->add('empty_username', __('<strong>ERROR</strong>: Enter a username or email address.'));
    285         } elseif ( strpos( $_POST['user_login'], '@' ) ) {
    286                 $user_data = get_user_by( 'email', trim( $_POST['user_login'] ) );
    287                 if ( empty( $user_data ) )
    288                         $errors->add('invalid_email', __('<strong>ERROR</strong>: There is no user registered with that email address.'));
    289         } else {
    290                 $login = trim($_POST['user_login']);
    291                 $user_data = get_user_by('login', $login);
    292         }
    293 
    294         /**
    295          * Fires before errors are returned from a password reset request.
    296          *
    297          * @since 2.1.0
    298          * @since 4.4.0 Added the `$errors` parameter.
    299          *
    300          * @param WP_Error $errors A WP_Error object containing any errors generated
    301          *                         by using invalid credentials.
    302          */
    303         do_action( 'lostpassword_post', $errors );
    304 
    305         if ( $errors->get_error_code() )
    306                 return $errors;
    307 
    308         if ( !$user_data ) {
    309                 $errors->add('invalidcombo', __('<strong>ERROR</strong>: Invalid username or email.'));
    310                 return $errors;
    311         }
    312 
    313         // Redefining user_login ensures we return the right case in the email.
    314         $user_login = $user_data->user_login;
    315         $user_email = $user_data->user_email;
    316 
    317         /**
    318          * Fires before a new password is retrieved.
    319          *
    320          * @since 1.5.0
    321          * @deprecated 1.5.1 Misspelled. Use 'retrieve_password' hook instead.
    322          *
    323          * @param string $user_login The user login name.
    324          */
    325         do_action( 'retreive_password', $user_login );
    326 
    327         /**
    328          * Fires before a new password is retrieved.
    329          *
    330          * @since 1.5.1
    331          *
    332          * @param string $user_login The user login name.
    333          */
    334         do_action( 'retrieve_password', $user_login );
    335 
    336         /**
    337          * Filter whether to allow a password to be reset.
    338          *
    339          * @since 2.7.0
    340          *
    341          * @param bool true           Whether to allow the password to be reset. Default true.
    342          * @param int  $user_data->ID The ID of the user attempting to reset a password.
    343          */
    344         $allow = apply_filters( 'allow_password_reset', true, $user_data->ID );
    345 
    346         if ( ! $allow ) {
    347                 return new WP_Error( 'no_password_reset', __('Password reset is not allowed for this user') );
    348         } elseif ( is_wp_error( $allow ) ) {
    349                 return $allow;
    350         }
    351 
    352         // Generate something random for a password reset key.
    353         $key = wp_generate_password( 20, false );
    354 
    355         /**
    356          * Fires when a password reset key is generated.
    357          *
    358          * @since 2.5.0
    359          *
    360          * @param string $user_login The username for the user.
    361          * @param string $key        The generated password reset key.
    362          */
    363         do_action( 'retrieve_password_key', $user_login, $key );
    364 
    365         // Now insert the key, hashed, into the DB.
    366         if ( empty( $wp_hasher ) ) {
    367                 require_once ABSPATH . WPINC . '/class-phpass.php';
    368                 $wp_hasher = new PasswordHash( 8, true );
    369         }
    370         $hashed = time() . ':' . $wp_hasher->HashPassword( $key );
    371         $wpdb->update( $wpdb->users, array( 'user_activation_key' => $hashed ), array( 'user_login' => $user_login ) );
    372 
    373         $message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n";
    374         $message .= network_home_url( '/' ) . "\r\n\r\n";
    375         $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
    376         $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n";
    377         $message .= __('To reset your password, visit the following address:') . "\r\n\r\n";
    378         $message .= '<' . network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . ">\r\n";
    379 
    380         if ( is_multisite() )
    381                 $blogname = $GLOBALS['current_site']->site_name;
    382         else
    383                 /*
    384                  * The blogname option is escaped with esc_html on the way into the database
    385                  * in sanitize_option we want to reverse this for the plain text arena of emails.
    386                  */
    387                 $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
    388 
    389         $title = sprintf( __('[%s] Password Reset'), $blogname );
    390 
    391         /**
    392          * Filter the subject of the password reset email.
    393          *
    394          * @since 2.8.0
    395          *
    396          * @param string $title Default email title.
    397          */
    398         $title = apply_filters( 'retrieve_password_title', $title );
    399 
    400         /**
    401          * Filter the message body of the password reset mail.
    402          *
    403          * @since 2.8.0
    404          * @since 4.1.0 Added `$user_login` and `$user_data` parameters.
    405          *
    406          * @param string  $message    Default mail message.
    407          * @param string  $key        The activation key.
    408          * @param string  $user_login The username for the user.
    409          * @param WP_User $user_data  WP_User object.
    410          */
    411         $message = apply_filters( 'retrieve_password_message', $message, $key, $user_login, $user_data );
    412 
    413         if ( $message && !wp_mail( $user_email, wp_specialchars_decode( $title ), $message ) )
    414                 wp_die( __('The email could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function.') );
    415 
    416         return true;
    417 }
    418 
    419 //
    420 // Main
    421 //
    422 
    423 $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'login';
    424 $errors = new WP_Error();
    425 
    426 if ( isset($_GET['key']) )
    427         $action = 'resetpass';
    428 
    429 // validate action so as to default to the login screen
    430 if ( !in_array( $action, array( 'postpass', 'logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'login' ), true ) && false === has_filter( 'login_form_' . $action ) )
    431         $action = 'login';
    432 
    433 nocache_headers();
    434 
    435 header('Content-Type: '.get_bloginfo('html_type').'; charset='.get_bloginfo('charset'));
    436 
    437 if ( defined( 'RELOCATE' ) && RELOCATE ) { // Move flag is set
    438         if ( isset( $_SERVER['PATH_INFO'] ) && ($_SERVER['PATH_INFO'] != $_SERVER['PHP_SELF']) )
    439                 $_SERVER['PHP_SELF'] = str_replace( $_SERVER['PATH_INFO'], '', $_SERVER['PHP_SELF'] );
    440 
    441         $url = dirname( set_url_scheme( 'http://' .  $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] ) );
    442         if ( $url != get_option( 'siteurl' ) )
    443                 update_option( 'siteurl', $url );
    444 }
    445 
    446 //Set a cookie now to see if they are supported by the browser.
    447 $secure = ( 'https' === parse_url( site_url(), PHP_URL_SCHEME ) && 'https' === parse_url( home_url(), PHP_URL_SCHEME ) );
    448 setcookie( TEST_COOKIE, 'WP Cookie check', 0, COOKIEPATH, COOKIE_DOMAIN, $secure );
    449 if ( SITECOOKIEPATH != COOKIEPATH )
    450         setcookie( TEST_COOKIE, 'WP Cookie check', 0, SITECOOKIEPATH, COOKIE_DOMAIN, $secure );
    451 
    452 /**
    453  * Fires when the login form is initialized.
    454  *
    455  * @since 3.2.0
    456  */
    457 do_action( 'login_init' );
    458 /**
    459  * Fires before a specified login form action.
    460  *
    461  * The dynamic portion of the hook name, `$action`, refers to the action
    462  * that brought the visitor to the login form. Actions include 'postpass',
    463  * 'logout', 'lostpassword', etc.
    464  *
    465  * @since 2.8.0
    466  */
    467 do_action( 'login_form_' . $action );
    468 
    469 $http_post = ('POST' == $_SERVER['REQUEST_METHOD']);
    470 $interim_login = isset($_REQUEST['interim-login']);
    471 
    472 switch ($action) {
    473 
    474 case 'postpass' :
    475         require_once ABSPATH . WPINC . '/class-phpass.php';
    476         $hasher = new PasswordHash( 8, true );
    477 
    478         /**
    479          * Filter the life span of the post password cookie.
    480          *
    481          * By default, the cookie expires 10 days from creation. To turn this
    482          * into a session cookie, return 0.
    483          *
    484          * @since 3.7.0
    485          *
    486          * @param int $expires The expiry time, as passed to setcookie().
    487          */
    488         $expire = apply_filters( 'post_password_expires', time() + 10 * DAY_IN_SECONDS );
    489         $secure = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) );
    490         setcookie( 'wp-postpass_' . COOKIEHASH, $hasher->HashPassword( wp_unslash( $_POST['post_password'] ) ), $expire, COOKIEPATH, COOKIE_DOMAIN, $secure );
    491 
    492         wp_safe_redirect( wp_get_referer() );
    493         exit();
    494 
    495 case 'logout' :
    496         check_admin_referer('log-out');
    497 
    498         $user = wp_get_current_user();
    499 
    500         wp_logout();
    501 
    502         if ( ! empty( $_REQUEST['redirect_to'] ) ) {
    503                 $redirect_to = $requested_redirect_to = $_REQUEST['redirect_to'];
    504         } else {
    505                 $redirect_to = 'wp-login.php?loggedout=true';
    506                 $requested_redirect_to = '';
    507         }
    508 
    509         /**
    510          * Filter the log out redirect URL.
    511          *
    512          * @since 4.2.0
    513          *
    514          * @param string  $redirect_to           The redirect destination URL.
    515          * @param string  $requested_redirect_to The requested redirect destination URL passed as a parameter.
    516          * @param WP_User $user                  The WP_User object for the user that's logging out.
    517          */
    518         $redirect_to = apply_filters( 'logout_redirect', $redirect_to, $requested_redirect_to, $user );
    519         wp_safe_redirect( $redirect_to );
    520         exit();
    521 
    522 case 'lostpassword' :
    523 case 'retrievepassword' :
    524 
    525         if ( $http_post ) {
    526                 $errors = retrieve_password();
    527                 if ( !is_wp_error($errors) ) {
    528                         $redirect_to = !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : 'wp-login.php?checkemail=confirm';
    529                         wp_safe_redirect( $redirect_to );
    530                         exit();
    531                 }
    532         }
    533 
    534         if ( isset( $_GET['error'] ) ) {
    535                 if ( 'invalidkey' == $_GET['error'] ) {
    536                         $errors->add( 'invalidkey', __( 'Your password reset link appears to be invalid. Please request a new link below.' ) );
    537                 } elseif ( 'expiredkey' == $_GET['error'] ) {
    538                         $errors->add( 'expiredkey', __( 'Your password reset link has expired. Please request a new link below.' ) );
    539                 }
    540         }
    541 
    542         $lostpassword_redirect = ! empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
    543         /**
    544          * Filter the URL redirected to after submitting the lostpassword/retrievepassword form.
    545          *
    546          * @since 3.0.0
    547          *
    548          * @param string $lostpassword_redirect The redirect destination URL.
    549          */
    550         $redirect_to = apply_filters( 'lostpassword_redirect', $lostpassword_redirect );
    551 
    552         /**
    553          * Fires before the lost password form.
    554          *
    555          * @since 1.5.1
    556          */
    557         do_action( 'lost_password' );
    558 
    559         login_header(__('Lost Password'), '<p class="message">' . __('Please enter your username or email address. You will receive a link to create a new password via email.') . '</p>', $errors);
    560 
    561         $user_login = isset($_POST['user_login']) ? wp_unslash($_POST['user_login']) : '';
    562 
    563 ?>
    564 
    565 <form name="lostpasswordform" id="lostpasswordform" action="<?php echo esc_url( network_site_url( 'wp-login.php?action=lostpassword', 'login_post' ) ); ?>" method="post">
    566         <p>
    567                 <label for="user_login" ><?php _e('Username or Email:') ?><br />
    568                 <input type="text" name="user_login" id="user_login" class="input" value="<?php echo esc_attr($user_login); ?>" size="20" /></label>
    569         </p>
    570         <?php
    571         /**
    572          * Fires inside the lostpassword form tags, before the hidden fields.
    573          *
    574          * @since 2.1.0
    575          */
    576         do_action( 'lostpassword_form' ); ?>
    577         <input type="hidden" name="redirect_to" value="<?php echo esc_attr( $redirect_to ); ?>" />
    578         <p class="submit"><input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e('Get New Password'); ?>" /></p>
    579 </form>
    580 
    581 <p id="nav">
    582 <a href="<?php echo esc_url( wp_login_url() ); ?>"><?php _e('Log in') ?></a>
    583 <?php
    584 if ( get_option( 'users_can_register' ) ) :
    585         $registration_url = sprintf( '<a href="%s">%s</a>', esc_url( wp_registration_url() ), __( 'Register' ) );
    586 
    587         /** This filter is documented in wp-includes/general-template.php */
    588         echo ' | ' . apply_filters( 'register', $registration_url );
    589 endif;
    590 ?>
    591 </p>
    592 
    593 <?php
    594 login_footer('user_login');
    595 break;
    596 
    597 case 'resetpass' :
    598 case 'rp' :
    599         list( $rp_path ) = explode( '?', wp_unslash( $_SERVER['REQUEST_URI'] ) );
    600         $rp_cookie = 'wp-resetpass-' . COOKIEHASH;
    601         if ( isset( $_GET['key'] ) ) {
    602                 $value = sprintf( '%s:%s', wp_unslash( $_GET['login'] ), wp_unslash( $_GET['key'] ) );
    603                 setcookie( $rp_cookie, $value, 0, $rp_path, COOKIE_DOMAIN, is_ssl(), true );
    604                 wp_safe_redirect( remove_query_arg( array( 'key', 'login' ) ) );
    605                 exit;
    606         }
    607 
    608         if ( isset( $_COOKIE[ $rp_cookie ] ) && 0 < strpos( $_COOKIE[ $rp_cookie ], ':' ) ) {
    609                 list( $rp_login, $rp_key ) = explode( ':', wp_unslash( $_COOKIE[ $rp_cookie ] ), 2 );
    610                 $user = check_password_reset_key( $rp_key, $rp_login );
    611                 if ( isset( $_POST['pass1'] ) && ! hash_equals( $rp_key, $_POST['rp_key'] ) ) {
    612                         $user = false;
    613                 }
    614         } else {
    615                 $user = false;
    616         }
    617 
    618         if ( ! $user || is_wp_error( $user ) ) {
    619                 setcookie( $rp_cookie, ' ', time() - YEAR_IN_SECONDS, $rp_path, COOKIE_DOMAIN, is_ssl(), true );
    620                 if ( $user && $user->get_error_code() === 'expired_key' )
    621                         wp_redirect( site_url( 'wp-login.php?action=lostpassword&error=expiredkey' ) );
    622                 else
    623                         wp_redirect( site_url( 'wp-login.php?action=lostpassword&error=invalidkey' ) );
    624                 exit;
    625         }
    626 
    627         $errors = new WP_Error();
    628 
    629         if ( isset($_POST['pass1']) && $_POST['pass1'] != $_POST['pass2'] )
    630                 $errors->add( 'password_reset_mismatch', __( 'The passwords do not match.' ) );
    631 
    632         /**
    633          * Fires before the password reset procedure is validated.
    634          *
    635          * @since 3.5.0
    636          *
    637          * @param object           $errors WP Error object.
    638          * @param WP_User|WP_Error $user   WP_User object if the login and reset key match. WP_Error object otherwise.
    639          */
    640         do_action( 'validate_password_reset', $errors, $user );
    641 
    642         if ( ( ! $errors->get_error_code() ) && isset( $_POST['pass1'] ) && !empty( $_POST['pass1'] ) ) {
    643                 reset_password($user, $_POST['pass1']);
    644                 setcookie( $rp_cookie, ' ', time() - YEAR_IN_SECONDS, $rp_path, COOKIE_DOMAIN, is_ssl(), true );
    645                 login_header( __( 'Password Reset' ), '<p class="message reset-pass">' . __( 'Your password has been reset.' ) . ' <a href="' . esc_url( wp_login_url() ) . '">' . __( 'Log in' ) . '</a></p>' );
    646                 login_footer();
    647                 exit;
    648         }
    649 
    650         wp_enqueue_script('utils');
    651         wp_enqueue_script('user-profile');
    652 
    653         login_header(__('Reset Password'), '<p class="message reset-pass">' . __('Enter your new password below.') . '</p>', $errors );
    654 
    655 ?>
    656 <form name="resetpassform" id="resetpassform" action="<?php echo esc_url( network_site_url( 'wp-login.php?action=resetpass', 'login_post' ) ); ?>" method="post" autocomplete="off">
    657         <input type="hidden" id="user_login" value="<?php echo esc_attr( $rp_login ); ?>" autocomplete="off" />
    658 
    659         <div class="user-pass1-wrap">
    660                 <p>
    661                         <label for="pass1"><?php _e( 'New password' ) ?></label>
    662                 </p>
    663 
    664                 <div class="wp-pwd">
    665                         <span class="password-input-wrapper">
    666                                 <input type="password" data-reveal="1" data-pw="<?php echo esc_attr( wp_generate_password( 16 ) ); ?>" name="pass1" id="pass1" class="input" size="20" value="" autocomplete="off" aria-describedby="pass-strength-result" />
    667                         </span>
    668                         <div id="pass-strength-result" class="hide-if-no-js" aria-live="polite"><?php _e( 'Strength indicator' ); ?></div>
    669                 </div>
    670         </div>
    671 
    672         <p class="user-pass2-wrap">
    673                 <label for="pass2"><?php _e( 'Confirm new password' ) ?></label><br />
    674                 <input type="password" name="pass2" id="pass2" class="input" size="20" value="" autocomplete="off" />
    675         </p>
    676 
    677         <p class="description indicator-hint"><?php echo wp_get_password_hint(); ?></p>
    678         <br class="clear" />
    679 
    680         <?php
    681         /**
    682          * Fires following the 'Strength indicator' meter in the user password reset form.
    683          *
    684          * @since 3.9.0
    685          *
    686          * @param WP_User $user User object of the user whose password is being reset.
    687          */
    688         do_action( 'resetpass_form', $user );
    689         ?>
    690         <input type="hidden" name="rp_key" value="<?php echo esc_attr( $rp_key ); ?>" />
    691         <p class="submit"><input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e('Reset Password'); ?>" /></p>
    692 </form>
    693 
    694 <p id="nav">
    695 <a href="<?php echo esc_url( wp_login_url() ); ?>"><?php _e( 'Log in' ); ?></a>
    696 <?php
    697 if ( get_option( 'users_can_register' ) ) :
    698         $registration_url = sprintf( '<a href="%s">%s</a>', esc_url( wp_registration_url() ), __( 'Register' ) );
    699 
    700         /** This filter is documented in wp-includes/general-template.php */
    701         echo ' | ' . apply_filters( 'register', $registration_url );
    702 endif;
    703 ?>
    704 </p>
    705 
    706 <?php
    707 login_footer('user_pass');
    708 break;
    709 
    710 case 'register' :
    711         if ( is_multisite() ) {
    712                 /**
    713                  * Filter the Multisite sign up URL.
    714                  *
    715                  * @since 3.0.0
    716                  *
    717                  * @param string $sign_up_url The sign up URL.
    718                  */
    719                 wp_redirect( apply_filters( 'wp_signup_location', network_site_url( 'wp-signup.php' ) ) );
    720                 exit;
    721         }
    722 
    723         if ( !get_option('users_can_register') ) {
    724                 wp_redirect( site_url('wp-login.php?registration=disabled') );
    725                 exit();
    726         }
    727 
    728         $user_login = '';
    729         $user_email = '';
    730         if ( $http_post ) {
    731                 $user_login = $_POST['user_login'];
    732                 $user_email = $_POST['user_email'];
    733                 $errors = register_new_user($user_login, $user_email);
    734                 if ( !is_wp_error($errors) ) {
    735                         $redirect_to = !empty( $_POST['redirect_to'] ) ? $_POST['redirect_to'] : 'wp-login.php?checkemail=registered';
    736                         wp_safe_redirect( $redirect_to );
    737                         exit();
    738                 }
    739         }
    740 
    741         $registration_redirect = ! empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
    742         /**
    743          * Filter the registration redirect URL.
    744          *
    745          * @since 3.0.0
    746          *
    747          * @param string $registration_redirect The redirect destination URL.
    748          */
    749         $redirect_to = apply_filters( 'registration_redirect', $registration_redirect );
    750         login_header(__('Registration Form'), '<p class="message register">' . __('Register For This Site') . '</p>', $errors);
    751 ?>
    752 
    753 <form name="registerform" id="registerform" action="<?php echo esc_url( wp_registration_url() ); ?>" method="post" novalidate="novalidate">
    754         <p>
    755                 <label for="user_login"><?php _e('Username') ?><br />
    756                 <input type="text" name="user_login" id="user_login" class="input" value="<?php echo esc_attr(wp_unslash($user_login)); ?>" size="20" /></label>
    757         </p>
    758         <p>
    759                 <label for="user_email"><?php _e('Email') ?><br />
    760                 <input type="email" name="user_email" id="user_email" class="input" value="<?php echo esc_attr( wp_unslash( $user_email ) ); ?>" size="25" /></label>
    761         </p>
    762         <?php
    763         /**
    764          * Fires following the 'Email' field in the user registration form.
    765          *
    766          * @since 2.1.0
    767          */
    768         do_action( 'register_form' );
    769         ?>
    770         <p id="reg_passmail"><?php _e( 'Registration confirmation will be emailed to you.' ); ?></p>
    771         <br class="clear" />
    772         <input type="hidden" name="redirect_to" value="<?php echo esc_attr( $redirect_to ); ?>" />
    773         <p class="submit"><input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e('Register'); ?>" /></p>
    774 </form>
    775 
    776 <p id="nav">
    777 <a href="<?php echo esc_url( wp_login_url() ); ?>"><?php _e( 'Log in' ); ?></a> |
    778 <a href="<?php echo esc_url( wp_lostpassword_url() ); ?>" title="<?php esc_attr_e( 'Password Lost and Found' ) ?>"><?php _e( 'Lost your password?' ); ?></a>
    779 </p>
    780 
    781 <?php
    782 login_footer('user_login');
    783 break;
    784 
    785 case 'login' :
    786 default:
    787         $secure_cookie = '';
    788         $customize_login = isset( $_REQUEST['customize-login'] );
    789         if ( $customize_login )
    790                 wp_enqueue_script( 'customize-base' );
    791 
    792         // If the user wants ssl but the session is not ssl, force a secure cookie.
    793         if ( !empty($_POST['log']) && !force_ssl_admin() ) {
    794                 $user_name = sanitize_user($_POST['log']);
    795                 if ( $user = get_user_by('login', $user_name) ) {
    796                         if ( get_user_option('use_ssl', $user->ID) ) {
    797                                 $secure_cookie = true;
    798                                 force_ssl_admin(true);
    799                         }
    800                 }
    801         }
    802 
    803         if ( isset( $_REQUEST['redirect_to'] ) ) {
    804                 $redirect_to = $_REQUEST['redirect_to'];
    805                 // Redirect to https if user wants ssl
    806                 if ( $secure_cookie && false !== strpos($redirect_to, 'wp-admin') )
    807                         $redirect_to = preg_replace('|^http://|', 'https://', $redirect_to);
    808         } else {
    809                 $redirect_to = admin_url();
    810         }
    811 
    812         $reauth = empty($_REQUEST['reauth']) ? false : true;
    813 
    814         $user = wp_signon( '', $secure_cookie );
    815 
    816         if ( empty( $_COOKIE[ LOGGED_IN_COOKIE ] ) ) {
    817                 if ( headers_sent() ) {
    818                         $user = new WP_Error( 'test_cookie', sprintf( __( '<strong>ERROR</strong>: Cookies are blocked due to unexpected output. For help, please see <a href="%1$s">this documentation</a> or try the <a href="%2$s">support forums</a>.' ),
    819                                 __( 'https://codex.wordpress.org/Cookies' ), __( 'https://wordpress.org/support/' ) ) );
    820                 } elseif ( isset( $_POST['testcookie'] ) && empty( $_COOKIE[ TEST_COOKIE ] ) ) {
    821                         // If cookies are disabled we can't log in even with a valid user+pass
    822                         $user = new WP_Error( 'test_cookie', sprintf( __( '<strong>ERROR</strong>: Cookies are blocked or not supported by your browser. You must <a href="%s">enable cookies</a> to use WordPress.' ),
    823                                 __( 'https://codex.wordpress.org/Cookies' ) ) );
    824                 }
    825         }
    826 
    827         $requested_redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
    828         /**
    829          * Filter the login redirect URL.
    830          *
    831          * @since 3.0.0
    832          *
    833          * @param string           $redirect_to           The redirect destination URL.
    834          * @param string           $requested_redirect_to The requested redirect destination URL passed as a parameter.
    835          * @param WP_User|WP_Error $user                  WP_User object if login was successful, WP_Error object otherwise.
    836          */
    837         $redirect_to = apply_filters( 'login_redirect', $redirect_to, $requested_redirect_to, $user );
    838 
    839         if ( !is_wp_error($user) && !$reauth ) {
    840                 if ( $interim_login ) {
    841                         $message = '<p class="message">' . __('You have logged in successfully.') . '</p>';
    842                         $interim_login = 'success';
    843                         login_header( '', $message ); ?>
    844                         </div>
    845                         <?php
    846                         /** This action is documented in wp-login.php */
    847                         do_action( 'login_footer' ); ?>
    848                         <?php if ( $customize_login ) : ?>
    849                                 <script type="text/javascript">setTimeout( function(){ new wp.customize.Messenger({ url: '<?php echo wp_customize_url(); ?>', channel: 'login' }).send('login') }, 1000 );</script>
    850                         <?php endif; ?>
    851                         </body></html>
    852 <?php           exit;
    853                 }
    854 
    855                 if ( ( empty( $redirect_to ) || $redirect_to == 'wp-admin/' || $redirect_to == admin_url() ) ) {
    856                         // If the user doesn't belong to a blog, send them to user admin. If the user can't edit posts, send them to their profile.
    857                         if ( is_multisite() && !get_active_blog_for_user($user->ID) && !is_super_admin( $user->ID ) )
    858                                 $redirect_to = user_admin_url();
    859                         elseif ( is_multisite() && !$user->has_cap('read') )
    860                                 $redirect_to = get_dashboard_url( $user->ID );
    861                         elseif ( !$user->has_cap('edit_posts') )
    862                                 $redirect_to = $user->has_cap( 'read' ) ? admin_url( 'profile.php' ) : home_url();
    863                 }
    864                 wp_safe_redirect($redirect_to);
    865                 exit();
    866         }
    867 
    868         $errors = $user;
    869         // Clear errors if loggedout is set.
    870         if ( !empty($_GET['loggedout']) || $reauth )
    871                 $errors = new WP_Error();
    872 
    873         if ( $interim_login ) {
    874                 if ( ! $errors->get_error_code() )
    875                         $errors->add('expired', __('Session expired. Please log in again. You will not move away from this page.'), 'message');
    876         } else {
    877                 // Some parts of this script use the main login form to display a message
    878                 if              ( isset($_GET['loggedout']) && true == $_GET['loggedout'] )
    879                         $errors->add('loggedout', __('You are now logged out.'), 'message');
    880                 elseif  ( isset($_GET['registration']) && 'disabled' == $_GET['registration'] )
    881                         $errors->add('registerdisabled', __('User registration is currently not allowed.'));
    882                 elseif  ( isset($_GET['checkemail']) && 'confirm' == $_GET['checkemail'] )
    883                         $errors->add('confirm', __('Check your email for the confirmation link.'), 'message');
    884                 elseif  ( isset($_GET['checkemail']) && 'newpass' == $_GET['checkemail'] )
    885                         $errors->add('newpass', __('Check your email for your new password.'), 'message');
    886                 elseif  ( isset($_GET['checkemail']) && 'registered' == $_GET['checkemail'] )
    887                         $errors->add('registered', __('Registration complete. Please check your email.'), 'message');
    888                 elseif ( strpos( $redirect_to, 'about.php?updated' ) )
    889                         $errors->add('updated', __( '<strong>You have successfully updated WordPress!</strong> Please log back in to see what&#8217;s new.' ), 'message' );
    890         }
    891 
    892         /**
    893          * Filter the login page errors.
    894          *
    895          * @since 3.6.0
    896          *
    897          * @param object $errors      WP Error object.
    898          * @param string $redirect_to Redirect destination URL.
    899          */
    900         $errors = apply_filters( 'wp_login_errors', $errors, $redirect_to );
    901 
    902         // Clear any stale cookies.
    903         if ( $reauth )
    904                 wp_clear_auth_cookie();
    905 
    906         login_header(__('Log In'), '', $errors);
    907 
    908         if ( isset($_POST['log']) )
    909                 $user_login = ( 'incorrect_password' == $errors->get_error_code() || 'empty_password' == $errors->get_error_code() ) ? esc_attr(wp_unslash($_POST['log'])) : '';
    910         $rememberme = ! empty( $_POST['rememberme'] );
    911 
    912         if ( ! empty( $errors->errors ) ) {
    913                 $aria_describedby_error = ' aria-describedby="login_error"';
    914         } else {
    915                 $aria_describedby_error = '';
    916         }
    917 ?>
    918 
    919 <form name="loginform" id="loginform" action="<?php echo esc_url( wp_login_url() ); ?>" method="post">
    920         <p>
    921                 <label for="user_login"><?php _e('Username') ?><br />
    922                 <input type="text" name="log" id="user_login"<?php echo $aria_describedby_error; ?> class="input" value="<?php echo esc_attr( $user_login ); ?>" size="20" /></label>
    923         </p>
    924         <p>
    925                 <label for="user_pass"><?php _e('Password') ?><br />
    926                 <input type="password" name="pwd" id="user_pass"<?php echo $aria_describedby_error; ?> class="input" value="" size="20" /></label>
    927         </p>
    928         <?php
    929         /**
    930          * Fires following the 'Password' field in the login form.
    931          *
    932          * @since 2.1.0
    933          */
    934         do_action( 'login_form' );
    935         ?>
    936         <p class="forgetmenot"><label for="rememberme"><input name="rememberme" type="checkbox" id="rememberme" value="forever" <?php checked( $rememberme ); ?> /> <?php esc_attr_e('Remember Me'); ?></label></p>
    937         <p class="submit">
    938                 <input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e('Log In'); ?>" />
    939 <?php   if ( $interim_login ) { ?>
    940                 <input type="hidden" name="interim-login" value="1" />
    941 <?php   } else { ?>
    942                 <input type="hidden" name="redirect_to" value="<?php echo esc_attr($redirect_to); ?>" />
    943 <?php   } ?>
    944 <?php   if ( $customize_login ) : ?>
    945                 <input type="hidden" name="customize-login" value="1" />
    946 <?php   endif; ?>
    947                 <input type="hidden" name="testcookie" value="1" />
    948         </p>
    949 </form>
    950 
    951 <?php if ( ! $interim_login ) { ?>
    952 <p id="nav">
    953 <?php if ( ! isset( $_GET['checkemail'] ) || ! in_array( $_GET['checkemail'], array( 'confirm', 'newpass' ) ) ) :
    954         if ( get_option( 'users_can_register' ) ) :
    955                 $registration_url = sprintf( '<a href="%s">%s</a>', esc_url( wp_registration_url() ), __( 'Register' ) );
    956 
    957                 /** This filter is documented in wp-includes/general-template.php */
    958                 echo apply_filters( 'register', $registration_url ) . ' | ';
    959         endif;
    960         ?>
    961         <a href="<?php echo esc_url( wp_lostpassword_url() ); ?>" title="<?php esc_attr_e( 'Password Lost and Found' ); ?>"><?php _e( 'Lost your password?' ); ?></a>
    962 <?php endif; ?>
    963 </p>
    964 <?php } ?>
    965 
    966 <script type="text/javascript">
    967 function wp_attempt_focus(){
    968 setTimeout( function(){ try{
    969 <?php if ( $user_login ) { ?>
    970 d = document.getElementById('user_pass');
    971 d.value = '';
    972 <?php } else { ?>
    973 d = document.getElementById('user_login');
    974 <?php if ( 'invalid_username' == $errors->get_error_code() ) { ?>
    975 if( d.value != '' )
    976 d.value = '';
    977 <?php
    978 }
    979 }?>
    980 d.focus();
    981 d.select();
    982 } catch(e){}
    983 }, 200);
    984 }
    985 
    986 <?php if ( !$error ) { ?>
    987 wp_attempt_focus();
    988 <?php } ?>
    989 if(typeof wpOnload=='function')wpOnload();
    990 <?php if ( $interim_login ) { ?>
    991 (function(){
    992 try {
    993         var i, links = document.getElementsByTagName('a');
    994         for ( i in links ) {
    995                 if ( links[i].href )
    996                         links[i].target = '_blank';
    997         }
    998 } catch(e){}
    999 }());
    1000 <?php } ?>
    1001 </script>
    1002 
    1003 <?php
    1004 login_footer();
    1005 break;
    1006 } // end action switch
     95</body>
     96</html>
  • wp-includes/user-functions.php

     
    18611861}
    18621862
    18631863/**
     1864 * Handles sending password retrieval email to user.
     1865 *
     1866 * @global wpdb $wpdb WordPress database abstraction object.
     1867 *
     1868 * @param string $user_login User login
     1869 * @return bool|WP_Error True on success, WP_Error on failure.
     1870 */
     1871function retrieve_password( $user_login = '' ) {
     1872        global $wpdb;
     1873
     1874        $errors = new WP_Error();
     1875
     1876        if ( empty( $user_login ) ) {
     1877                return new WP_Error( 'empty_username', __( '<strong>ERROR</strong>: Enter a username or email address.' ) );
     1878
     1879        } elseif ( strpos( $user_login, '@' ) ) {
     1880                $user_data = get_user_by( 'email', trim( $user_login ) );
     1881                if ( empty( $user_data ) )
     1882                        return new WP_Error( 'invalid_email', __( '<strong>ERROR</strong>: There is no user registered with that email address.' ) );
     1883
     1884        } else {
     1885                $login = trim( $user_login );
     1886                $user_data = get_user_by( 'login', $login );
     1887        }
     1888
     1889        if ( ! $user_data )
     1890                return new WP_Error( 'invalidcombo', __( '<strong>ERROR</strong>: Invalid username or email.' ) );
     1891
     1892        // Redefining user_login ensures we return the right case in the email.
     1893        $user_login = $user_data->user_login;
     1894        $user_email = $user_data->user_email;
     1895
     1896        /**
     1897         * Fires before a new password is retrieved.
     1898         *
     1899         * @since 1.5.0
     1900         * @deprecated 1.5.1 Misspelled. Use 'retrieve_password' hook instead.
     1901         *
     1902         * @param string $user_login The user login name.
     1903         */
     1904        do_action( 'retreive_password', $user_login );
     1905
     1906        /**
     1907         * Fires before a new password is retrieved.
     1908         *
     1909         * @since 1.5.1
     1910         *
     1911         * @param string $user_login The user login name.
     1912         */
     1913        do_action( 'retrieve_password', $user_login );
     1914
     1915        /**
     1916         * Filter whether to allow a password to be reset.
     1917         *
     1918         * @since 2.7.0
     1919         *
     1920         * @param bool true           Whether to allow the password to be reset. Default true.
     1921         * @param int  $user_data->ID The ID of the user attempting to reset a password.
     1922         */
     1923        $allow = apply_filters( 'allow_password_reset', true, $user_data->ID );
     1924
     1925        if ( ! $allow ) {
     1926                return new WP_Error( 'no_password_reset', __( 'Password reset is not allowed for this user' ) );
     1927        } elseif ( is_wp_error( $allow ) ) {
     1928                return $allow;
     1929        }
     1930
     1931        // Generate something random for a password reset key.
     1932        $key = wp_generate_password( 20, false );
     1933
     1934        /**
     1935         * Fires when a password reset key is generated.
     1936         *
     1937         * @since 2.5.0
     1938         *
     1939         * @param string $user_login The username for the user.
     1940         * @param string $key        The generated password reset key.
     1941         */
     1942        do_action( 'retrieve_password_key', $user_login, $key );
     1943
     1944        // Now insert the key, hashed, into the DB.
     1945        if ( empty( $wp_hasher ) ) {
     1946                require_once ABSPATH . WPINC . '/class-phpass.php';
     1947                $wp_hasher = new PasswordHash( 8, true );
     1948        }
     1949        $hashed = time() . ':' . $wp_hasher->HashPassword( $key );
     1950        $wpdb->update( $wpdb->users, array( 'user_activation_key' => $hashed ), array( 'user_login' => $user_login ) );
     1951
     1952        $message = __( 'Someone requested that the password be reset for the following account:' ) . "\r\n\r\n";
     1953        $message .= network_home_url( '/' ) . "\r\n\r\n";
     1954        $message .= sprintf( __( 'Username: %s' ), $user_login ) . "\r\n\r\n";
     1955        $message .= __( 'If this was a mistake, just ignore this email and nothing will happen.' ) . "\r\n\r\n";
     1956        $message .= __( 'To reset your password, visit the following address:' ) . "\r\n\r\n";
     1957        $message .= '<' . network_site_url( "wp-login.php?action=rp&key=$key&login=" . rawurlencode( $user_login ), 'login' ) . ">\r\n";
     1958
     1959        if ( is_multisite() )
     1960                $blogname = $GLOBALS['current_site']->site_name;
     1961        else
     1962                /*
     1963                 * The blogname option is escaped with esc_html on the way into the database
     1964                 * in sanitize_option we want to reverse this for the plain text arena of emails.
     1965                 */
     1966                $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
     1967
     1968        $title = sprintf( __( '[%s] Password Reset' ), $blogname );
     1969
     1970        /**
     1971         * Filter the subject of the password reset email.
     1972         *
     1973         * @since 2.8.0
     1974         *
     1975         * @param string $title Default email title.
     1976         */
     1977        $title = apply_filters( 'retrieve_password_title', $title );
     1978
     1979        /**
     1980         * Filter the message body of the password reset mail.
     1981         *
     1982         * @since 2.8.0
     1983         * @since 4.1.0 Added `$user_login` and `$user_data` parameters.
     1984         *
     1985         * @param string  $message    Default mail message.
     1986         * @param string  $key        The activation key.
     1987         * @param string  $user_login The username for the user.
     1988         * @param WP_User $user_data  WP_User object.
     1989         */
     1990        $message = apply_filters( 'retrieve_password_message', $message, $key, $user_login, $user_data );
     1991
     1992        if ( $message && ! wp_mail( $user_email, wp_specialchars_decode( $title ), $message ) )
     1993                wp_die( __( 'The email could not be sent.' ) . "<br />\n" . __( 'Possible reason: your host may have disabled the mail() function.' ) );
     1994
     1995        return true;
     1996}
     1997
     1998/**
    18641999 * Retrieves a user row based on password reset key and login
    18652000 *
    18662001 * A key is considered 'expired' if it exactly matches the value of the
  • wp-includes/script-loader.php

     
    475475        $scripts->add( 'media-audiovideo', "/wp-includes/js/media-audiovideo$suffix.js", array( 'media-editor' ), false, 1 );
    476476        $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'jquery', 'media-views', 'media-audiovideo' ), false, 1 );
    477477
     478        $scripts->add( 'wp-login', "/wp-includes/js/wp-login$suffix.js", array( 'jquery' ), false, 1 );
     479        did_action( 'init' ) && $scripts->localize( 'wp-login', 'wpLoginSettings', array(
     480                'customizeUrl' => wp_customize_url()
     481        ) );
     482
    478483        if ( is_admin() ) {
    479484                $scripts->add( 'admin-tags', "/wp-admin/js/tags$suffix.js", array( 'jquery', 'wp-ajax-response' ), false, 1 );
    480485                did_action( 'init' ) && $scripts->localize( 'admin-tags', 'tagsl10n', array(
  • wp-includes/js/wp-login.min.js

     
     1var wpLogin;!function(a){wpLogin={init:function(){var b=a("body");if(this.form=b.find("form").first(),b.hasClass("shake")){var c=[15,30,15,0,-15,-30,-15,0],d=20;c=c.concat(c.concat(c)),this.shakeForm(c,d)}b.hasClass("interim-login")&&b.find("a").each(function(a,b){b.href&&(b.target="_blank")}),b.hasClass("customize-login")&&b.hasClass("interim-login-success")&&setTimeout(function(){new wp.customize.Messenger({url:wpLoginSettings.customizeUrl,channel:"login"}).send("login")},1e3),b.hasClass("loggedout")&&this.clearSessionStorage(),this.attemptFocus()},clearSessionStorage:function(){if("sessionStorage"in window)try{for(var a in sessionStorage)-1!=a.indexOf("wp-autosave-")&&sessionStorage.removeItem(a)}catch(b){}},shakeForm:function(a,b){var c=this,d=a.shift();this.form.css({left:d+"px",position:"relative"}),a.length>0?setTimeout(function(){c.shakeForm(a,b)},b):this.form.css("position","static")},attemptFocus:function(){var b=this,c=a("#user_login"),d=a("#user_pass");setTimeout(function(){c.length&&d.length?c.val()?d.val("").focus():c.focus():b.form.find(":input").filter(":visible:first").focus()},200)}},a(document).ready(function(){wpLogin.init()})}(jQuery);
  • wp-includes/js/wp-login.js

     
     1var wpLogin;
     2
     3( function( $ ) {
     4
     5        wpLogin = {
     6
     7                init: function() {
     8                        var body = $( 'body' );
     9
     10                        this.form = body.find('form').first();
     11
     12                        if ( body.hasClass( 'shake' ) ) {
     13                                var coords = [15, 30, 15, 0, -15, -30, -15, 0],
     14                                        duration = 20;
     15
     16                                coords = coords.concat( coords.concat( coords ) );
     17
     18                                this.shakeForm( coords, duration );
     19                        }
     20
     21                        if ( body.hasClass( 'interim-login' ) ) {
     22                                body.find( 'a' ).each( function( index, link ) {
     23                                        if ( link.href )
     24                                                link.target = '_blank';
     25                                } );
     26                        }
     27
     28                        if ( body.hasClass( 'customize-login' ) && body.hasClass( 'interim-login-success' ) ) {
     29                                setTimeout( function() {
     30                                        new wp.customize.Messenger( {
     31                                                url: wpLoginSettings.customizeUrl,
     32                                                channel: 'login'
     33                                        } ).send( 'login' );
     34                                }, 1000 );
     35                        }
     36
     37                        if ( body.hasClass( 'loggedout' ) ) {
     38                                this.clearSessionStorage();
     39                        }
     40
     41                        this.attemptFocus();
     42                },
     43
     44                clearSessionStorage: function() {
     45                        if ( 'sessionStorage' in window ) {
     46                                try {
     47                                        for ( var key in sessionStorage ) {
     48                                                if ( key.indexOf( 'wp-autosave-' ) != -1 ) {
     49                                                        sessionStorage.removeItem( key );
     50                                                }
     51                                        }
     52                                } catch (e) {
     53                                        // Do nothing
     54                                }
     55                        }
     56                },
     57
     58                shakeForm: function( coords, duration ) {
     59                        var t = this,
     60                                pos = coords.shift();
     61
     62                        this.form.css({
     63                                left: pos + 'px',
     64                                position: 'relative'
     65                        });
     66
     67                        if ( coords.length > 0 ) {
     68                                setTimeout( function(){
     69                                        t.shakeForm( coords, duration );
     70                                }, duration );
     71                        } else {
     72                                this.form.css( 'position', 'static' );
     73                        }
     74                },
     75
     76                attemptFocus: function() {
     77                        var t = this,
     78                                userLogin = $( '#user_login' ),
     79                                userPass = $( '#user_pass' );
     80
     81                        setTimeout( function() {
     82                                if ( userLogin.length && userPass.length ) {
     83                                        if ( userLogin.val() ) {
     84                                                userPass.val('').focus();
     85                                        } else {
     86                                                userLogin.focus();
     87                                        }
     88                                } else {
     89                                        t.form.find(':input').filter(':visible:first').focus();
     90                                }
     91                        }, 200 );
     92                }
     93        };
     94
     95        $( document ).ready( function() {
     96                wpLogin.init();
     97        });
     98
     99} )( jQuery );
  • wp-includes/default-filters.php

     
    234234
    235235// Login actions
    236236add_action( 'login_head',          'wp_print_head_scripts',         9     );
     237add_action( 'login_head',          'wp_no_robots',                  10    );
     238add_action( 'login_head',          'wp_login_viewport_meta',        10    );
    237239add_action( 'login_head',          'wp_site_icon',                  99    );
    238240add_action( 'login_footer',        'wp_print_footer_scripts',       20    );
    239241add_action( 'login_init',          'send_frame_options_header',     10, 0 );
  • wp-includes/class-wp-login.php

     
     1<?php
     2/**
     3 * WordPress Login API
     4 *
     5 * @package WordPress
     6 */
     7
     8/**
     9 * WordPress Login Class
     10 *
     11 * @package WordPress
     12 * @since unknown
     13 */
     14class WP_Login {
     15        /**
     16         * Stores the current action.
     17         *
     18         * @since unknown
     19         * @var string
     20         */
     21        public $action;
     22
     23        /**
     24         * Stores the available actions.
     25         *
     26         * @since unknown
     27         * @var array
     28         */
     29        public $actions = array(
     30                'postpass',
     31                'logout',
     32                'lostpassword',
     33                'retrievepassword',
     34                'resetpass',
     35                'rp',
     36                'register',
     37                'login'
     38        );
     39
     40        /**
     41         * Stores login errors and notices.
     42         *
     43         * @since unknown
     44         * @var WP_Error
     45         */
     46        public $errors;
     47
     48        /**
     49         * Stores user object once authenticated or found.
     50         *
     51         * @since unknown
     52         * @var WP_User
     53         */
     54        private $user;
     55
     56        /**
     57         * Stores the current redirect location.
     58         *
     59         * @since unknown
     60         * @var string
     61         */
     62        private $redirect_to = '';
     63
     64        /**
     65         * Construct the object.
     66         *
     67         * @since unknown
     68         */
     69        public function __construct() {
     70
     71                $this->action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'login';
     72                if ( isset( $_GET['key'] ) )
     73                        $this->action = 'resetpass';
     74
     75                // validate action so as to default to the login screen
     76                if ( ! in_array( $this->action, $this->actions, true ) && false === has_filter( 'login_form_' . $this->action ) )
     77                        $this->action = 'login';
     78
     79                $this->errors = new WP_Error();
     80        }
     81
     82        /**
     83         * Process the request.
     84         *
     85         * @since unknown
     86         */
     87        public function process() {
     88                $this->enforce_ssl();
     89                $this->headers();
     90                $this->maybe_relocate();
     91                $this->test_cookie();
     92
     93                /**
     94                 * Fires when the login form is initialized.
     95                 *
     96                 * @since 3.2.0
     97                 */
     98                do_action( 'login_init' );
     99
     100                /**
     101                 * Fires before a specified login form action.
     102                 *
     103                 * The dynamic portion of the hook name, `$action`, refers to the action
     104                 * that brought the visitor to the login form. Actions include 'postpass',
     105                 * 'logout', 'lostpassword', etc.
     106                 *
     107                 * @since 2.8.0
     108                 */
     109                do_action( 'login_form_' . $this->action );
     110
     111                switch ( $this->action ) {
     112                        case 'postpass' :
     113                                $this->post_password();
     114                                break;
     115
     116                        case 'lostpassword' :
     117                        case 'retrievepassword' :
     118                                $this->lost_password();
     119                                break;
     120
     121                        case 'resetpass' :
     122                        case 'rp' :
     123                                $this->reset_password();
     124                                break;
     125
     126                        case 'register' :
     127                                $this->register();
     128                                break;
     129
     130                        case 'login' :
     131                        default :
     132                                $this->login();
     133                                break;
     134                }
     135        }
     136
     137        /**
     138         * Render the form.
     139         *
     140         * @since unknown
     141         */
     142        public function render() {
     143                $this->header();
     144                $this->message();
     145                $this->errors();
     146                $this->form();
     147                $this->navigation();
     148        }
     149
     150        /**
     151         * Redirect to a secure URL if required.
     152         *
     153         * @since unknown
     154         */
     155        public function enforce_ssl() {
     156                // Redirect to https login if forced to use SSL
     157                if ( force_ssl_admin() && ! is_ssl() ) {
     158                        if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
     159                                wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) );
     160                                exit;
     161                        } else {
     162                                wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
     163                                exit;
     164                        }
     165                }
     166        }
     167
     168        /**
     169         * Send headers.
     170         *
     171         * @since unknown
     172         */
     173        public function headers() {
     174                nocache_headers();
     175                header( 'Content-Type: ' . get_bloginfo( 'html_type' ) . '; charset=' . get_bloginfo( 'charset' ) );
     176        }
     177
     178        /**
     179         * Handle relocation.
     180         *
     181         * @since unknown
     182         */
     183        public function maybe_relocate() {
     184                if ( defined( 'RELOCATE' ) && RELOCATE ) {
     185                        if ( isset( $_SERVER['PATH_INFO'] ) && ($_SERVER['PATH_INFO'] != $_SERVER['PHP_SELF']) )
     186                                $_SERVER['PHP_SELF'] = str_replace( $_SERVER['PATH_INFO'], '', $_SERVER['PHP_SELF'] );
     187
     188                        $url = dirname( set_url_scheme( 'http://' .  $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] ) );
     189                        if ( $url != get_option( 'siteurl' ) )
     190                                update_option( 'siteurl', $url );
     191                }
     192        }
     193
     194        /**
     195         * Set a test cookie to see if they are supported by the browser.
     196         *
     197         * @since unknown
     198         */
     199        public function test_cookie() {
     200                $secure = ( 'https' === parse_url( site_url(), PHP_URL_SCHEME ) && 'https' === parse_url( home_url(), PHP_URL_SCHEME ) );
     201                setcookie( TEST_COOKIE, 'WP Cookie check', 0, COOKIEPATH, COOKIE_DOMAIN, $secure );
     202                if ( SITECOOKIEPATH != COOKIEPATH )
     203                        setcookie( TEST_COOKIE, 'WP Cookie check', 0, SITECOOKIEPATH, COOKIE_DOMAIN, $secure );
     204        }
     205
     206        /**
     207         * Process the post password request.
     208         *
     209         * @since unknown
     210         */
     211        public function post_password() {
     212                require_once( ABSPATH . WPINC . '/class-phpass.php' );
     213                $hasher = new PasswordHash( 8, true );
     214
     215                /**
     216                 * Filter the life span of the post password cookie.
     217                 *
     218                 * By default, the cookie expires 10 days from creation. To turn this
     219                 * into a session cookie, return 0.
     220                 *
     221                 * @since 3.7.0
     222                 *
     223                 * @param int $expires The expiry time, as passed to setcookie().
     224                 */
     225                $expire = apply_filters( 'post_password_expires', time() + 10 * DAY_IN_SECONDS );
     226                $secure = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) );
     227                setcookie( 'wp-postpass_' . COOKIEHASH, $hasher->HashPassword( wp_unslash( $_POST['post_password'] ) ), $expire, COOKIEPATH, COOKIE_DOMAIN, $secure );
     228
     229                wp_safe_redirect( wp_get_referer() );
     230                exit;
     231        }
     232
     233        /**
     234         * Process the log out request.
     235         *
     236         * @since unknown
     237         */
     238        public function logout() {
     239                check_admin_referer( 'log-out' );
     240
     241                $user = wp_get_current_user();
     242
     243                wp_logout();
     244
     245                if ( ! empty( $_REQUEST['redirect_to'] ) ) {
     246                        $redirect_to = $requested_redirect_to = $_REQUEST['redirect_to'];
     247                } else {
     248                        $redirect_to = 'wp-login.php?loggedout=true';
     249                        $requested_redirect_to = '';
     250                }
     251
     252                /**
     253                 * Filter the log out redirect URL.
     254                 *
     255                 * @since 4.2.0
     256                 *
     257                 * @param string  $redirect_to           The redirect destination URL.
     258                 * @param string  $requested_redirect_to The requested redirect destination URL passed as a parameter.
     259                 * @param WP_User $user                  The WP_User object for the user that's logging out.
     260                 */
     261                $redirect_to = apply_filters( 'logout_redirect', $redirect_to, $requested_redirect_to, $user );
     262                wp_safe_redirect( $redirect_to );
     263                exit;
     264        }
     265
     266        /**
     267         * Process the lost password request.
     268         *
     269         * @since unknown
     270         */
     271        public function lost_password() {
     272                // Is this a POST request?
     273                if ( $this->is_post_request() ) {
     274
     275                        /**
     276                         * Fires before errors are returned from a password reset request.
     277                         *
     278                         * @since 2.1.0
     279                         * @since 4.4.0 Added the `$errors` parameter.
     280                         *
     281                         * @param WP_Error $errors A WP_Error object containing any errors generated
     282                         *                         by using invalid credentials.
     283                         */
     284                        do_action( 'lostpassword_post', $errors );
     285
     286                        $user_login = isset( $_POST['user_login'] ) ? wp_unslash( $_POST['user_login'] ) : '';
     287
     288                        $errors = retrieve_password( $user_login );
     289                        if ( ! is_wp_error( $errors ) ) {
     290                                $redirect_to = ! empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : 'wp-login.php?checkemail=confirm';
     291                                wp_safe_redirect( $redirect_to );
     292                                exit;
     293                        } else {
     294                                $this->errors = $errors;
     295                        }
     296                }
     297
     298                if ( isset( $_GET['error'] ) ) {
     299                        if ( 'invalidkey' == $_GET['error'] ) {
     300                                $this->errors->add( 'invalidkey', __( 'Your password reset link appears to be invalid. Please request a new link below.' ) );
     301                        } elseif ( 'expiredkey' == $_GET['error'] ) {
     302                                $this->errors->add( 'expiredkey', __( 'Your password reset link has expired. Please request a new link below.' ) );
     303                        }
     304                }
     305        }
     306
     307        /**
     308         * Output the lost password form.
     309         *
     310         * @since unknown
     311         */
     312        public function lost_password_form() {
     313                $user_login = isset( $_POST['user_login'] ) ? wp_unslash( $_POST['user_login'] ) : '';
     314
     315                $lostpassword_redirect = ! empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
     316                /**
     317                 * Filter the URL redirected to after submitting the lostpassword/retrievepassword form.
     318                 *
     319                 * @since 3.0.0
     320                 *
     321                 * @param string $lostpassword_redirect The redirect destination URL.
     322                 */
     323                $redirect_to = apply_filters( 'lostpassword_redirect', $lostpassword_redirect );
     324
     325                /**
     326                 * Fires before the lost password form.
     327                 *
     328                 * @since 1.5.1
     329                 */
     330                do_action( 'lost_password' );
     331                ?>
     332
     333                <form name="lostpasswordform" id="lostpasswordform" action="<?php echo esc_url( network_site_url( 'wp-login.php?action=lostpassword', 'login_post' ) ); ?>" method="post">
     334                        <p>
     335                                <label for="user_login" ><?php _e( 'Username or Email:' ) ?><br />
     336                                <input type="text" name="user_login" id="user_login" class="input" value="<?php echo esc_attr( $user_login ); ?>" size="20" /></label>
     337                        </p>
     338                        <?php
     339                        /**
     340                         * Fires inside the lostpassword form tags, before the hidden fields.
     341                         *
     342                         * @since 2.1.0
     343                         */
     344                        do_action( 'lostpassword_form' ); ?>
     345
     346                        <p class="submit">
     347                                <input type="hidden" name="redirect_to" value="<?php echo esc_attr( $redirect_to ); ?>" />
     348                                <input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e( 'Get New Password' ); ?>" />
     349                        </p>
     350                </form>
     351
     352                <?php
     353        }
     354
     355        /**
     356         * Process the password reset request.
     357         *
     358         * @since unknown
     359         */
     360        public function reset_password() {
     361                list( $rp_path ) = explode( '?', wp_unslash( $_SERVER['REQUEST_URI'] ) );
     362                $rp_cookie = 'wp-resetpass-' . COOKIEHASH;
     363                if ( isset( $_GET['key'] ) ) {
     364                        $value = sprintf( '%s:%s', wp_unslash( $_GET['login'] ), wp_unslash( $_GET['key'] ) );
     365                        setcookie( $rp_cookie, $value, 0, $rp_path, COOKIE_DOMAIN, is_ssl(), true );
     366                        wp_safe_redirect( remove_query_arg( array( 'key', 'login' ) ) );
     367                        exit;
     368                }
     369
     370                if ( isset( $_COOKIE[ $rp_cookie ] ) && 0 < strpos( $_COOKIE[ $rp_cookie ], ':' ) ) {
     371                        list( $rp_login, $rp_key ) = explode( ':', wp_unslash( $_COOKIE[ $rp_cookie ] ), 2 );
     372                        $user = check_password_reset_key( $rp_key, $rp_login );
     373                        if ( isset( $_POST['pass1'] ) && ! hash_equals( $rp_key, $_POST['rp_key'] ) ) {
     374                                $user = false;
     375                        }
     376                } else {
     377                        $user = false;
     378                }
     379
     380                if ( ! $user || is_wp_error( $user ) ) {
     381                        setcookie( $rp_cookie, ' ', time() - YEAR_IN_SECONDS, $rp_path, COOKIE_DOMAIN, is_ssl(), true );
     382                        if ( $user && $user->get_error_code() === 'expired_key' )
     383                                wp_redirect( site_url( 'wp-login.php?action=lostpassword&error=expiredkey' ) );
     384                        else
     385                                wp_redirect( site_url( 'wp-login.php?action=lostpassword&error=invalidkey' ) );
     386                        exit;
     387                } else {
     388                        $this->user = $user;
     389                }
     390
     391                if ( isset( $_POST['pass1'] ) && $_POST['pass1'] != $_POST['pass2'] )
     392                        $this->errors->add( 'password_reset_mismatch', __( 'The passwords do not match.' ) );
     393
     394                /**
     395                 * Fires before the password reset procedure is validated.
     396                 *
     397                 * @since 3.5.0
     398                 *
     399                 * @param object           $errors WP Error object.
     400                 * @param WP_User|WP_Error $user   WP_User object if the login and reset key match. WP_Error object otherwise.
     401                 */
     402                do_action( 'validate_password_reset', $this->errors, $this->user );
     403
     404                if ( ( ! $this->errors->get_error_code() ) && isset( $_POST['pass1'] ) && ! empty( $_POST['pass1'] ) ) {
     405                        reset_password( $this->user, $_POST['pass1'] );
     406                        setcookie( $rp_cookie, ' ', time() - YEAR_IN_SECONDS, $rp_path, COOKIE_DOMAIN, is_ssl(), true );
     407                } else {
     408                        wp_enqueue_script('utils');
     409                        wp_enqueue_script('user-profile');
     410                }
     411        }
     412
     413        /**
     414         * Output the password reset form.
     415         *
     416         * @since unknown
     417         */
     418        public function reset_password_form() {
     419                // Don't show the form if the password has been successfully reset
     420                if ( did_action( 'password_reset' ) )
     421                        return;
     422
     423                list( $rp_login, $rp_key ) = explode( ':', wp_unslash( $_COOKIE[ 'wp-resetpass-' . COOKIEHASH ] ), 2 );
     424                ?>
     425
     426                <form name="resetpassform" id="resetpassform" action="<?php echo esc_url( network_site_url( 'wp-login.php?action=resetpass', 'login_post' ) ); ?>" method="post" autocomplete="off">
     427                        <div class="user-pass1-wrap">
     428                                <p>
     429                                        <label for="pass1"><?php _e( 'New password' ) ?></label>
     430                                </p>
     431
     432                                <div class="wp-pwd">
     433                                        <span class="password-input-wrapper">
     434                                                <input type="password" data-reveal="1" data-pw="<?php echo esc_attr( wp_generate_password( 16 ) ); ?>" name="pass1" id="pass1" class="input" size="20" value="" autocomplete="off" aria-describedby="pass-strength-result" />
     435                                        </span>
     436                                        <div id="pass-strength-result" class="hide-if-no-js" aria-live="polite"><?php _e( 'Strength indicator' ); ?></div>
     437                                </div>
     438                        </div>
     439
     440                        <p class="user-pass2-wrap">
     441                                <label for="pass2"><?php _e( 'Confirm new password' ) ?></label><br />
     442                                <input type="password" name="pass2" id="pass2" class="input" size="20" value="" autocomplete="off" />
     443                        </p>
     444
     445                        <p class="description indicator-hint"><?php echo wp_get_password_hint(); ?></p>
     446                        <br class="clear" />
     447
     448                        <?php
     449                        /**
     450                         * Fires following the 'Strength indicator' meter in the user password reset form.
     451                         *
     452                         * @since 3.9.0
     453                         *
     454                         * @param WP_User $user User object of the user whose password is being reset.
     455                         */
     456                        do_action( 'resetpass_form', $this->user ); ?>
     457
     458                        <p class="submit">
     459                                <input type="hidden" id="user_login" value="<?php echo esc_attr( $rp_login ); ?>" autocomplete="off" />
     460                                <input type="hidden" name="rp_key" value="<?php echo esc_attr( $rp_key ); ?>" />
     461                                <input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e('Reset Password'); ?>" />
     462                        </p>
     463                </form>
     464
     465                <?php
     466        }
     467
     468        /**
     469         * Process the register request.
     470         *
     471         * @since unknown
     472         */
     473        public function register() {
     474
     475                // Bail and redirect to wp-signup.php if multisite
     476                if ( is_multisite() ) {
     477                        /**
     478                         * Filter the Multisite sign up URL.
     479                         *
     480                         * @since 3.0.0
     481                         *
     482                         * @param string $sign_up_url The sign up URL.
     483                         */
     484                        wp_redirect( apply_filters( 'wp_signup_location', network_site_url( 'wp-signup.php' ) ) );
     485                        exit;
     486                }
     487
     488                // Bail if registration is disabled
     489                if ( ! get_option( 'users_can_register' ) ) {
     490                        wp_redirect( site_url( 'wp-login.php?registration=disabled' ) );
     491                        exit;
     492                }
     493
     494                // Is this a post request?
     495                if ( $this->is_post_request() ) {
     496
     497                        // Attempt to register the user
     498                        $errors = register_new_user($_POST['user_login'], $_POST['user_email']);
     499
     500                        // Registration succeeded
     501                        if ( ! is_wp_error( $errors ) ) {
     502                                $redirect_to = ! empty( $_POST['redirect_to'] ) ? $_POST['redirect_to'] : 'wp-login.php?checkemail=registered';
     503                                wp_safe_redirect( $redirect_to );
     504                                exit;
     505
     506                        // Registration failed
     507                        } else {
     508                                $this->errors = $errors;
     509                        }
     510                }
     511        }
     512
     513        /**
     514         * Output the register form.
     515         *
     516         * @since unknown
     517         */
     518        public function register_form() {
     519                $user_login = isset( $_POST['user_login'] ) ? $_POST['user_login'] : '';
     520                $user_email = isset( $_POST['user_email'] ) ? $_POST['user_email'] : '';
     521
     522                $registration_redirect = ! empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
     523                /**
     524                 * Filter the registration redirect URL.
     525                 *
     526                 * @since 3.0.0
     527                 *
     528                 * @param string $registration_redirect The redirect destination URL.
     529                 */
     530                $redirect_to = apply_filters( 'registration_redirect', $registration_redirect );
     531                ?>
     532
     533                <form name="registerform" id="registerform" action="<?php echo esc_url( wp_registration_url() ); ?>" method="post" novalidate="novalidate">
     534                        <p>
     535                                <label for="user_login"><?php _e( 'Username' ) ?><br />
     536                                <input type="text" name="user_login" id="user_login" class="input" value="<?php echo esc_attr( wp_unslash( $user_login ) ); ?>" size="20" /></label>
     537                        </p>
     538                        <p>
     539                                <label for="user_email"><?php _e( 'Email' ) ?><br />
     540                                <input type="email" name="user_email" id="user_email" class="input" value="<?php echo esc_attr( wp_unslash( $user_email ) ); ?>" size="25" /></label>
     541                        </p>
     542
     543                        <?php
     544                        /**
     545                         * Fires following the 'Email' field in the user registration form.
     546                         *
     547                         * @since 2.1.0
     548                         */
     549                        do_action( 'register_form' ); ?>
     550
     551                        <p id="reg_passmail"><?php _e( 'Registration confirmation will be emailed to you.' ); ?></p>
     552
     553                        <br class="clear" />
     554
     555                        <p class="submit">
     556                                <input type="hidden" name="redirect_to" value="<?php echo esc_attr( $redirect_to ); ?>" />
     557                                <input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e( 'Register' ); ?>" />
     558                        </p>
     559                </form>
     560                <?php
     561        }
     562
     563        /**
     564         * Process the login request.
     565         *
     566         * @since unknown
     567         */
     568        public function login() {
     569                $secure_cookie = '';
     570                if ( $this->is_customize_login() )
     571                        wp_enqueue_script( 'customize-base' );
     572
     573                // If the user wants ssl but the session is not ssl, force a secure cookie.
     574                if ( ! empty( $_POST['log'] ) && ! force_ssl_admin() ) {
     575                        $user_name = sanitize_user( $_POST['log'] );
     576                        if ( $user = get_user_by( 'login', $user_name ) ) {
     577                                if ( get_user_option( 'use_ssl', $user->ID ) ) {
     578                                        $secure_cookie = true;
     579                                        force_ssl_admin( true );
     580                                }
     581                        }
     582                }
     583
     584                if ( isset( $_REQUEST['redirect_to'] ) ) {
     585                        $redirect_to = $_REQUEST['redirect_to'];
     586                        // Redirect to https if user wants ssl
     587                        if ( $secure_cookie && false !== strpos( $redirect_to, 'wp-admin' ) )
     588                                $redirect_to = preg_replace( '|^http://|', 'https://', $redirect_to );
     589                } else {
     590                        $redirect_to = admin_url();
     591                }
     592
     593                $user = wp_signon( '', $secure_cookie );
     594
     595                if ( empty( $_COOKIE[ LOGGED_IN_COOKIE ] ) ) {
     596                        if ( headers_sent() ) {
     597                                $user = new WP_Error( 'test_cookie', sprintf( __( '<strong>ERROR</strong>: Cookies are blocked due to unexpected output. For help, please see <a href="%1$s">this documentation</a> or try the <a href="%2$s">support forums</a>.' ),
     598                                        __( 'https://codex.wordpress.org/Cookies' ), __( 'https://wordpress.org/support/' ) ) );
     599                        } elseif ( isset( $_POST['testcookie'] ) && empty( $_COOKIE[ TEST_COOKIE ] ) ) {
     600                                // If cookies are disabled we can't log in even with a valid user+pass
     601                                $user = new WP_Error( 'test_cookie', sprintf( __( '<strong>ERROR</strong>: Cookies are blocked or not supported by your browser. You must <a href="%s">enable cookies</a> to use WordPress.' ),
     602                                        __( 'https://codex.wordpress.org/Cookies' ) ) );
     603                        }
     604                }
     605
     606                $requested_redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
     607                /**
     608                 * Filter the login redirect URL.
     609                 *
     610                 * @since 3.0.0
     611                 *
     612                 * @param string           $redirect_to           The redirect destination URL.
     613                 * @param string           $requested_redirect_to The requested redirect destination URL passed as a parameter.
     614                 * @param WP_User|WP_Error $user                  WP_User object if login was successful, WP_Error object otherwise.
     615                 */
     616                $redirect_to = apply_filters( 'login_redirect', $redirect_to, $requested_redirect_to, $user );
     617
     618                if ( ! is_wp_error( $user ) && ! $this->is_reauth_required() ) {
     619                        if ( $this->is_interim_login() ) {
     620                                $this->user = $user;
     621                        } else {
     622                                if ( ( empty( $redirect_to ) || $redirect_to == 'wp-admin/' || $redirect_to == admin_url() ) ) {
     623                                        // If the user doesn't belong to a blog, send them to user admin. If the user can't edit posts, send them to their profile.
     624                                        if ( is_multisite() && ! get_active_blog_for_user( $user->ID ) && ! is_super_admin( $user->ID ) )
     625                                                $redirect_to = user_admin_url();
     626                                        elseif ( is_multisite() && ! $user->has_cap( 'read' ) )
     627                                                $redirect_to = get_dashboard_url( $user->ID );
     628                                        elseif ( ! $user->has_cap( 'edit_posts' ) )
     629                                                $redirect_to = $user->has_cap( 'read' ) ? admin_url( 'profile.php' ) : home_url();
     630                                }
     631                                wp_safe_redirect( $redirect_to );
     632                                exit;
     633                        }
     634                }
     635
     636                $this->errors = $user;
     637                $this->redirect_to = $redirect_to;
     638
     639                // Clear errors if loggedout is set.
     640                if ( ! empty( $_GET['loggedout'] ) || $this->is_reauth_required() )
     641                        $this->errors = new WP_Error();
     642
     643                if ( $this->is_interim_login() ) {
     644                        if ( ! $this->errors->get_error_code() )
     645                                $this->errors->add( 'expired', __( 'Session expired. Please log in again. You will not move away from this page.' ), 'message' );
     646                } else {
     647                        // Some parts of this script use the main login form to display a message
     648                        if              ( isset($_GET['loggedout']) && true == $_GET['loggedout'] )
     649                                $this->errors->add('loggedout', __('You are now logged out.'), 'message');
     650                        elseif  ( isset($_GET['registration']) && 'disabled' == $_GET['registration'] )
     651                                $this->errors->add('registerdisabled', __('User registration is currently not allowed.'));
     652                        elseif  ( isset($_GET['checkemail']) && 'confirm' == $_GET['checkemail'] )
     653                                $this->errors->add('confirm', __('Check your email for the confirmation link.'), 'message');
     654                        elseif  ( isset($_GET['checkemail']) && 'newpass' == $_GET['checkemail'] )
     655                                $this->errors->add('newpass', __('Check your email for your new password.'), 'message');
     656                        elseif  ( isset($_GET['checkemail']) && 'registered' == $_GET['checkemail'] )
     657                                $this->errors->add('registered', __('Registration complete. Please check your email.'), 'message');
     658                        elseif ( strpos( $redirect_to, 'about.php?updated' ) )
     659                                $this->errors->add('updated', __( '<strong>You have successfully updated WordPress!</strong> Please log back in to see what&#8217;s new.' ), 'message' );
     660                }
     661
     662                /**
     663                 * Filter the login page errors.
     664                 *
     665                 * @since 3.6.0
     666                 *
     667                 * @param object $errors      WP Error object.
     668                 * @param string $redirect_to Redirect destination URL.
     669                 */
     670                $this->errors = apply_filters( 'wp_login_errors', $this->errors, $this->redirect_to );
     671
     672                // Clear any stale cookies.
     673                if ( $this->is_reauth_required() )
     674                        wp_clear_auth_cookie();
     675        }
     676
     677        /**
     678         * Output the login form.
     679         *
     680         * @since unknown
     681         */
     682        public function login_form() {
     683                // Don't show the form if this is a successful interim login
     684                if ( $this->is_interim_login() && ! empty( $this->user ) )
     685                        return;
     686
     687                $user_login = '';
     688                if ( isset( $_POST['log'] ) )
     689                        $user_login = ( 'incorrect_password' == $this->errors->get_error_code() || 'empty_password' == $this->errors->get_error_code() ) ? esc_attr( wp_unslash( $_POST['log'] ) ) : '';
     690                $rememberme = ! empty( $_POST['rememberme'] );
     691
     692                if ( ! empty( $errors->errors ) ) {
     693                        $aria_describedby_error = ' aria-describedby="login_error"';
     694                } else {
     695                        $aria_describedby_error = '';
     696                }
     697                ?>
     698
     699                <form name="loginform" id="loginform" action="<?php echo esc_url( wp_login_url() ); ?>" method="post">
     700                        <p>
     701                                <label for="user_login"><?php _e( 'Username' ) ?><br />
     702                                <input type="text" name="log" id="user_login"<?php echo $aria_describedby_error; ?> class="input" value="<?php echo esc_attr( $user_login ); ?>" size="20" /></label>
     703                        </p>
     704                        <p>
     705                                <label for="user_pass"><?php _e( 'Password' ) ?><br />
     706                                <input type="password" name="pwd" id="user_pass"<?php echo $aria_describedby_error; ?> class="input" value="" size="20" /></label>
     707                        </p>
     708
     709                        <?php
     710                        /**
     711                         * Fires following the 'Password' field in the login form.
     712                         *
     713                         * @since 2.1.0
     714                         */
     715                        do_action( 'login_form' ); ?>
     716
     717                        <p class="forgetmenot">
     718                                <label for="rememberme"><input name="rememberme" type="checkbox" id="rememberme" value="forever" <?php checked( $rememberme ); ?> /> <?php esc_attr_e( 'Remember Me' ); ?></label>
     719                        </p>
     720
     721                        <p class="submit">
     722                                <input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e( 'Log In' ); ?>" />
     723
     724                                <?php if ( $this->is_interim_login() ) : ?>
     725                                <input type="hidden" name="interim-login" value="1" />
     726                                <?php else : ?>
     727                                <input type="hidden" name="redirect_to" value="<?php echo esc_attr( $this->redirect_to ); ?>" />
     728                                <?php endif; ?>
     729
     730                                <?php if ( $this->is_customize_login() ) : ?>
     731                                <input type="hidden" name="customize-login" value="1" />
     732                                <?php endif; ?>
     733
     734                                <input type="hidden" name="testcookie" value="1" />
     735                        </p>
     736                </form>
     737                <?php
     738        }
     739
     740        /**
     741         * Output the page title.
     742         *
     743         * @since unknown
     744         */
     745        public function title() {
     746                switch ( $this->action ) {
     747                        case 'lostpassword' :
     748                        case 'retrievepassword' :
     749                                $title = __( 'Lost Password' );
     750                                break;
     751
     752                        case 'resetpass' :
     753                        case 'rp' :
     754                                $title = did_action( 'password_reset' ) ? __( 'Password Reset' ) : __( 'Reset Password' );
     755                                break;
     756
     757                        case 'register' :
     758                                $title = __( 'Registration Form' );
     759                                break;
     760
     761                        case 'login':
     762                        default:
     763                                $title = __( 'Log In' );
     764                }
     765
     766                echo $title;
     767        }
     768
     769        /**
     770         * Output the header.
     771         *
     772         * @since unknown
     773         */
     774        public function header() {
     775                if ( is_multisite() ) {
     776                        $login_header_url   = network_home_url();
     777                        $login_header_title = get_current_site()->site_name;
     778                } else {
     779                        $login_header_url   = __( 'https://wordpress.org/' );
     780                        $login_header_title = __( 'Powered by WordPress' );
     781                }
     782
     783                /**
     784                 * Filter link URL of the header logo above login form.
     785                 *
     786                 * @since 2.1.0
     787                 *
     788                 * @param string $login_header_url Login header logo URL.
     789                 */
     790                $login_header_url = apply_filters( 'login_headerurl', $login_header_url );
     791                /**
     792                 * Filter the title attribute of the header logo above login form.
     793                 *
     794                 * @since 2.1.0
     795                 *
     796                 * @param string $login_header_title Login header logo title attribute.
     797                 */
     798                $login_header_title = apply_filters( 'login_headertitle', $login_header_title );
     799                ?>
     800
     801                <h1><a href="<?php echo esc_url( $login_header_url ); ?>" title="<?php echo esc_attr( $login_header_title ); ?>" tabindex="-1"><?php bloginfo( 'name' ); ?></a></h1>
     802
     803                <?php
     804        }
     805
     806        /**
     807         * Output the message above the form.
     808         *
     809         * @since unknown
     810         */
     811        public function message() {
     812                switch ( $this->action ) {
     813                        case 'lostpassword' :
     814                        case 'retrievepassword' :
     815                                $message = __( 'Please enter your username or email address. You will receive a link to create a new password via email.' );
     816                                $class = 'message';
     817                                break;
     818
     819                        case 'resetpass' :
     820                        case 'rp' :
     821                                if ( did_action( 'password_reset' ) ) {
     822                                        $message = __( 'Your password has been reset.' ) . ' <a href="' . esc_url( wp_login_url() ) . '">' . __( 'Log in' ) . '</a>';
     823                                } else {
     824                                        $message = __( 'Enter your new password below.' );
     825                                }
     826                                $class = 'message reset-pass';
     827                                break;
     828
     829                        case 'register' :
     830                                $message =  __( 'Register For This Site' );
     831                                $class = 'message register';
     832                                break;
     833
     834                        case 'login' :
     835                        default :
     836                                $message = ( $this->is_interim_login() && ! empty( $this->user ) ) ? __( 'You have logged in successfully.' ) : '';
     837                                $class = 'message';
     838                }
     839
     840                /**
     841                 * Filter the message to display above the login form.
     842                 *
     843                 * @since 2.1.0
     844                 *
     845                 * @param string $message Login message text.
     846                 */
     847                $message = apply_filters( 'login_message', $message );
     848
     849                if ( ! empty( $message ) )
     850                        echo '<p class="' . $class . '">' . $message . "</p>\n";
     851        }
     852
     853        /**
     854         * Output the errors.
     855         *
     856         * @since unknown
     857         */
     858        public function errors() {
     859                global $error;
     860
     861                // In case a plugin uses $error rather than the $wp_errors object
     862                if ( ! empty( $error ) ) {
     863                        $this->errors->add( 'error', $error );
     864                        unset( $error );
     865                }
     866
     867                if ( $this->has_errors() ) {
     868                        $errors = '';
     869                        $messages = '';
     870                        foreach ( $this->errors->get_error_codes() as $code ) {
     871                                $severity = $this->errors->get_error_data( $code );
     872                                foreach ( $this->errors->get_error_messages( $code ) as $error_message ) {
     873                                        if ( 'message' == $severity )
     874                                                $messages .= '  ' . $error_message . "<br />\n";
     875                                        else
     876                                                $errors .= '    ' . $error_message . "<br />\n";
     877                                }
     878                        }
     879                        if ( ! empty( $errors ) ) {
     880                                /**
     881                                 * Filter the error messages displayed above the login form.
     882                                 *
     883                                 * @since 2.1.0
     884                                 *
     885                                 * @param string $errors Login error message.
     886                                 */
     887                                echo '<div id="login_error">' . apply_filters( 'login_errors', $errors ) . "</div>\n";
     888                        }
     889                        if ( ! empty( $messages ) ) {
     890                                /**
     891                                 * Filter instructional messages displayed above the login form.
     892                                 *
     893                                 * @since 2.5.0
     894                                 *
     895                                 * @param string $messages Login messages.
     896                                 */
     897                                echo '<p class="message">' . apply_filters( 'login_messages', $messages ) . "</p>\n";
     898                        }
     899                }
     900        }
     901
     902        /**
     903         * Output the form.
     904         *
     905         * @since unknown
     906         */
     907        public function form() {
     908                switch ( $this->action ) {
     909                        case 'lostpassword' :
     910                        case 'retrievepassword' :
     911                                $this->lost_password_form();
     912                                break;
     913
     914                        case 'resetpass' :
     915                        case 'rp' :
     916                                $this->reset_password_form();
     917                                break;
     918
     919                        case 'register' :
     920                                $this->register_form();
     921                                break;
     922
     923                        case 'login' :
     924                        default :
     925                                $this->login_form();
     926                                break;
     927                }
     928        }
     929
     930        /**
     931         * Output the nav links at the bottom of the form.
     932         *
     933         * @since unknown
     934         */
     935        public function navigation() {
     936                $links = array(
     937                        'login' => sprintf(
     938                                '<a href="%1$s">%2$s</a>',
     939                                esc_url( wp_login_url() ),
     940                                __( 'Log in' )
     941                        ),
     942
     943                        'register' => sprintf(
     944                                '<a href="%1$s">%2$s</a>',
     945                                esc_url( apply_filters( 'register', wp_registration_url() ) ),
     946                                __( 'Register' )
     947                        ),
     948
     949                        'lostpassword' => sprintf(
     950                                '<a href="%1$s" title="%2$s">%3$s</a>',
     951                                esc_url( wp_lostpassword_url() ),
     952                                esc_attr__( 'Password Lost and Found' ),
     953                                __( 'Lost your password?' )
     954                        )
     955                );
     956
     957                if ( ! get_option( 'users_can_register' ) )
     958                        unset( $links['register'] );
     959
     960                switch ( $this->action ) {
     961                        case 'lostpassword' :
     962                        case 'retrievepassword' :
     963                        case 'resetpass' :
     964                        case 'rp' :
     965                                unset( $links['lostpassword'] );
     966
     967                                if ( did_action( 'password_reset' ) )
     968                                        $links = array();
     969                                break;
     970
     971                        case 'register' :
     972                                unset( $links['register'] );
     973                                break;
     974
     975                        case 'login' :
     976                        default :
     977                                unset( $links['login'] );
     978
     979                                if ( isset( $_GET['checkemail'] ) && in_array( $_GET['checkemail'], array( 'confirm', 'newpass' ) ) )
     980                                        $links = array();
     981
     982                                if ( $this->is_interim_login() )
     983                                        $links = array();
     984                }
     985                ?>
     986
     987                <p id="nav">
     988                        <?php echo implode( ' | ', $links ); ?>
     989                </p>
     990
     991                <?php if ( ! $this->is_interim_login() ): ?>
     992                <p id="backtoblog">
     993                        <a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php esc_attr_e( 'Are you lost?' ); ?>"><?php printf( __( '&larr; Back to %s' ), get_bloginfo( 'title', 'display' ) ); ?></a>
     994                </p>
     995                <?php endif;
     996        }
     997
     998        /**
     999         * Output the body class.
     1000         *
     1001         * @since unknown
     1002         */
     1003        public function body_class() {
     1004                $classes = array(
     1005                        'login-action-' . $this->action,
     1006                        'wp-core-ui'
     1007                );
     1008
     1009                if ( wp_is_mobile() )
     1010                        $classes[] = 'mobile';
     1011
     1012                if ( is_rtl() )
     1013                        $classes[] = 'rtl';
     1014
     1015                if ( $this->is_interim_login() ) {
     1016                        $classes[] = 'interim-login';
     1017
     1018                        if ( $this->is_post_request() && ! empty( $this->user ) )
     1019                                $classes[] = 'interim-login-success';
     1020                }
     1021
     1022                if ( $this->is_customize_login() )
     1023                        $classes[] = 'customize-login';
     1024
     1025                $classes[] =' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_locale() ) ) );
     1026
     1027                if ( $this->has_errors() ) {
     1028
     1029                        if ( 'loggedout' == $this->errors->get_error_code() )
     1030                                $classes[] = 'loggedout';
     1031
     1032                        if ( ! wp_is_mobile() ) {
     1033                                // Shake it!
     1034                                $shake_error_codes = array(
     1035                                        'empty_password',
     1036                                        'empty_email',
     1037                                        'invalid_email',
     1038                                        'invalidcombo',
     1039                                        'empty_username',
     1040                                        'invalid_username',
     1041                                        'incorrect_password'
     1042                                );
     1043
     1044                                /**
     1045                                 * Filter the error codes array for shaking the login form.
     1046                                 *
     1047                                 * @since 3.0.0
     1048                                 *
     1049                                 * @param array $shake_error_codes Error codes that shake the login form.
     1050                                 */
     1051                                $shake_error_codes = apply_filters( 'shake_error_codes', $shake_error_codes );
     1052
     1053                                if ( $shake_error_codes && in_array( $this->errors->get_error_code(), $shake_error_codes ) )
     1054                                        $classes[] = 'shake';
     1055                        }
     1056                }
     1057
     1058                /**
     1059                 * Filter the login page body classes.
     1060                 *
     1061                 * @since 3.5.0
     1062                 *
     1063                 * @param array  $classes An array of body classes.
     1064                 * @param string $action  The action that brought the visitor to the login page.
     1065                 */
     1066                $classes = apply_filters( 'login_body_class', $classes, $this->action );
     1067
     1068                // Login cannot be removed
     1069                array_unshift( $classes, 'login' );
     1070
     1071                echo implode( ' ', $classes );
     1072        }
     1073
     1074        /**
     1075         * Output the header title.
     1076         *
     1077         * @since unknown
     1078         */
     1079        public function header_title() {
     1080                $header_title = is_multisite() ? get_current_site()->site_name : __( 'Powered by WordPress' );
     1081                /**
     1082                 * Filter the title attribute of the header logo above login form.
     1083                 *
     1084                 * @since 2.1.0
     1085                 *
     1086                 * @param string $header_title Login header logo title attribute.
     1087                 */
     1088                $header_title = apply_filters( 'login_headertitle', $header_title );
     1089
     1090                echo esc_attr( $header_title );
     1091        }
     1092
     1093        /**
     1094         * Output the header URL.
     1095         *
     1096         * @since unknown
     1097         */
     1098        public function header_url() {
     1099                $header_url = is_multisite() ? network_home_url() : __( 'https://wordpress.org/' );
     1100                /**
     1101                 * Filter link URL of the header logo above login form.
     1102                 *
     1103                 * @since 2.1.0
     1104                 *
     1105                 * @param string $header_url Login header logo URL.
     1106                 */
     1107                $header_url = apply_filters( 'login_headerurl', $header_url );
     1108
     1109                echo esc_url( $header_url );
     1110        }
     1111
     1112        /**
     1113         * Determine if there are any errors.
     1114         *
     1115         * @since unknown
     1116         *
     1117         * @return bool True if there are errors, false if not.
     1118         */
     1119        public function has_errors() {
     1120                return (bool) $this->errors->get_error_code();
     1121        }
     1122
     1123        /**
     1124         * Determine if the current request is a POST request.
     1125         *
     1126         * @since unknown
     1127         *
     1128         * @return bool True if this is a POST request, false if not.
     1129         */
     1130        public function is_post_request() {
     1131                return ( 'POST' == $_SERVER['REQUEST_METHOD'] );
     1132        }
     1133
     1134        /**
     1135         * Determine if reauthorizaiton is required.
     1136         *
     1137         * @since unknown
     1138         *
     1139         * @return bool True if reauthorization is required, false if not.
     1140         */
     1141        public function is_reauth_required() {
     1142                return isset( $_REQUEST['reauth'] );
     1143        }
     1144
     1145        /**
     1146         * Determine if the current request is an intermin login request.
     1147         *
     1148         * @since unknown
     1149         *
     1150         * @return bool True if this is an interim login, false if not.
     1151         */
     1152        public function is_interim_login() {
     1153                return isset( $_REQUEST['interim-login'] );
     1154        }
     1155
     1156        /**
     1157         * Determine if the current request is a customize login request.
     1158         *
     1159         * @since unknown
     1160         */
     1161        public function is_customize_login() {
     1162                return isset( $_REQUEST['customize-login'] );
     1163        }
     1164}