ID, wp_hash($code), 600); // 10 mins // Send email /* translators: 1: Blog name */ $subject = sprintf(__('[%1$s] Your Two-Factor Authentication Code', 'admin-login-guard-branding'), wp_specialchars_decode(get_option('blogname'), ENT_QUOTES)); $site_url = get_bloginfo('url'); $logo_url = admilogu_URL . 'assets/images/admin-login-guard-branding-logo.png'; $message = sprintf('
Admin Login Guard

Hi %1$s,

This is your one-time verification code to securely access the admin area.

%2$s

This code is only active for the next 10 minutes. Once the code expires you will have to resubmit a request for a new code.

If you did not attempt to log in, please reset your password immediately.

For any further questions, please contact the site administrator.

Secured by Admin Login Guard & Branding
', $user->display_name, $code, $site_url, $logo_url); $headers = array('Content-Type: text/html; charset=UTF-8'); wp_mail($user->user_email, $subject, $message, $headers); } /** * Intercept Login Process * * Runs after WP validates the password. Logs the user back out, sets a pending token, * and redirects to the 2FA form. */ function admilogu_intercept_login_for_2fa($user_login, $user) { if (!get_option('admilogu_enable_2fa', 0)) { return; } // Check if user has 2FA enabled $user_2fa_enabled = get_user_meta($user->ID, 'admilogu_2fa_enabled', true); // Default to ON if it has never been set if ($user_2fa_enabled === '') { $user_2fa_enabled = '1'; } // If not enabled for this user, let them pass normally if (!$user_2fa_enabled || $user_2fa_enabled === '0') { return; } // They need 2FA. Generate code and send email. admilogu_send_2fa_email($user); // Logout the user (since wp_login fires after auth cookie is set) wp_logout(); // Set a temporary cookie to identify them for the 2FA step $temp_token = wp_generate_password(32, false); set_transient('admilogu_2fa_pending_' . $temp_token, $user->ID, 600); setcookie('admilogu_2fa_token', $temp_token, time() + 600, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); // Redirect to 2FA form // phpcs:ignore WordPress.Security.NonceVerification.Recommended $redirect_to = isset($_REQUEST['redirect_to']) ? sanitize_text_field(wp_unslash($_REQUEST['redirect_to'])) : admin_url(); $login_url = wp_login_url(); $url = add_query_arg(array('action' => 'admilogu_2fa', 'redirect_to' => urlencode($redirect_to)), $login_url); wp_safe_redirect($url); exit; } // Run early (priority 5) to intercept before other plugins redirect add_action('wp_login', 'admilogu_intercept_login_for_2fa', 5, 2); /** * Render the 2FA Form on the wp-login.php page */ function admilogu_render_2fa_form() { $token = isset($_COOKIE['admilogu_2fa_token']) ? sanitize_text_field(wp_unslash($_COOKIE['admilogu_2fa_token'])) : ''; if (!$token) { wp_safe_redirect(wp_login_url()); exit; } $uid = get_transient('admilogu_2fa_pending_' . $token); if (!$uid) { wp_safe_redirect(wp_login_url()); exit; } $error = ''; $form_message = __('Please enter the 6-digit code sent to your email address.', 'admin-login-guard-branding'); // Handle form submission // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST') { if (!isset($_POST['admilogu_2fa_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['admilogu_2fa_nonce'])), 'admilogu_2fa_action')) { $error = __('Invalid security token. Please try again.', 'admin-login-guard-branding'); } elseif (isset($_POST['admilogu_resend_2fa'])) { // Handle Resend action $user = get_user_by('id', $uid); if ($user) { admilogu_send_2fa_email($user); $form_message = __('A new code has been sent to your email address.', 'admin-login-guard-branding'); } else { $error = __('User not found. Please try logging in again.', 'admin-login-guard-branding'); } } elseif (isset($_POST['admilogu_2fa_code'])) { // Handle Verification action $code = sanitize_text_field(wp_unslash($_POST['admilogu_2fa_code'])); $stored_hash = get_transient('admilogu_2fa_code_' . $uid); if ($stored_hash && hash_equals($stored_hash, wp_hash($code))) { // Success! delete_transient('admilogu_2fa_code_' . $uid); delete_transient('admilogu_2fa_pending_' . $token); setcookie('admilogu_2fa_token', '', time() - 3600, COOKIEPATH, COOKIE_DOMAIN); // Set real auth cookie wp_set_auth_cookie($uid, true); $user = get_user_by('id', $uid); if ($user) { remove_action('wp_login', 'admilogu_intercept_login_for_2fa', 5); do_action('wp_login', $user->user_login, $user); } $redirect_to = isset($_POST['redirect_to']) ? sanitize_text_field(wp_unslash($_POST['redirect_to'])) : admin_url(); wp_safe_redirect($redirect_to); exit; } else { $error = __('Invalid or expired code. Please check your email and try again.', 'admin-login-guard-branding'); } } } // Render standard WP login header $error_html = $error ? '
' . esc_html($error) . '
' : ''; $message_html = !$error && $form_message ? '

' . esc_html($form_message) . '

' : ''; login_header( __('Two-Factor Authentication', 'admin-login-guard-branding'), $error_html . $message_html ); ?>

ID, 'admilogu_2fa_enabled', true); // Default to ON if it has never been set if ($enabled === '') { $enabled = '1'; } ?>

/>