Current File : /home/kelaby89/kelaby.company/wp-content/plugins/advanced-google-recaptcha/libs/functions.php
<?php

/**
 * WP Captcha Pro
 * https://getwpcaptcha.com/
 * (c) WebFactory Ltd, 2022 - 2023, www.webfactoryltd.com
 */

use IconCaptcha\IconCaptcha;

class WPCaptcha_Functions extends WPCaptcha
{
    static $wp_login_php;

    static function countFails($username = "")
    {
        global $wpdb;
        $options = WPCaptcha_Setup::get_options();
        $ip = WPCaptcha_Utility::getUserIP();

        $numFails = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT COUNT(login_attempt_ID) FROM " . $wpdb->wpcatcha_login_fails . " WHERE login_attempt_date + INTERVAL %d MINUTE > %s AND login_attempt_IP = %s",
                array($options['retries_within'], current_time('mysql'), $ip)
            )
        );

        return $numFails;
    }

    static function incrementFails($username = "", $reason = "")
    {
        global $wpdb;
        $options = WPCaptcha_Setup::get_options();
        $ip = WPCaptcha_Utility::getUserIP();

        $username = sanitize_user($username);
        $user = get_user_by('login', $username);

        if ($user || 1 == $options['lockout_invalid_usernames']) {
            if ($user === false) {
                $user_id = -1;
            } else {
                $user_id = $user->ID;
            }

            $agent = WPCaptcha_Utility::parse_user_agent_array();

            $wpdb->insert(
                $wpdb->wpcatcha_login_fails,
                array(
                    'user_id' => $user_id,
                    'login_attempt_date' => current_time('mysql'),
                    'login_attempt_IP' => $ip,
                    'failed_user' => $username,
                    'failed_pass' => isset($_POST['pwd']) && $options['log_passwords'] == 1 ? $_POST['pwd'] : '',
                    'country' => WPCaptcha_Utility::getUserCountry(),
                    'user_agent' => @$_SERVER['HTTP_USER_AGENT'],
                    'user_agent_browser' => $agent['browser'],
                    'user_agent_browser_version' => $agent['browser_ver'],
                    'user_agent_os' => $agent['os'],
                    'user_agent_os_ver' => $agent['os_ver'],
                    'user_agent_device' => $agent['device'],
                    'user_agent_bot' => $agent['bot'],
                    'reason' => $reason
                )
            );
        }
    }

    static function lockDown($username = "", $reason = "")
    {
        global $wpdb;
        $options = WPCaptcha_Setup::get_options();
        $ip = WPCaptcha_Utility::getUserIP();

        $username = sanitize_user($username);
        $user = get_user_by('login', $username);
        if ($user || 1 == $options['lockout_invalid_usernames']) {
            if ($user === false) {
                $user_id = -1;
            } else {
                $user_id = $user->ID;
            }

            $agent = WPCaptcha_Utility::parse_user_agent_array();

            $wpdb->insert(
                $wpdb->wpcatcha_accesslocks,
                array(
                    'user_id' => $user_id,
                    'accesslock_date' => current_time('mysql'),
                    'release_date' => date('Y-m-d H:i:s', strtotime(current_time('mysql')) + $options['lockout_length'] * 60),
                    'accesslock_IP' => $ip,
                    'country' => WPCaptcha_Utility::getUserCountry(),
                    'user_agent' => @$_SERVER['HTTP_USER_AGENT'],
                    'user_agent_browser' => $agent['browser'],
                    'user_agent_browser_version' => $agent['browser_ver'],
                    'user_agent_os' => $agent['os'],
                    'user_agent_os_ver' => $agent['os_ver'],
                    'user_agent_device' => $agent['device'],
                    'user_agent_bot' => $agent['bot'],
                    'reason' => $reason
                )
            );
        }
    }

    static function isLockedDown()
    {
        global $wpdb;
        $ip = WPCaptcha_Utility::getUserIP();

        $stillLocked = $wpdb->get_var($wpdb->prepare("SELECT user_id FROM " . $wpdb->wpcatcha_accesslocks . " WHERE release_date > %s AND accesslock_IP = %s AND unlocked = 0", array(current_time('mysql'), $ip)));

        return $stillLocked;
    }

    static function is_rest_request()
    {
        if (defined('REST_REQUEST') && REST_REQUEST || isset($_GET['rest_route']) && strpos(sanitize_text_field(wp_unslash($_GET['rest_route'])), '/', 0) === 0) {
            return true;
        }

        global $wp_rewrite;
        if (null === $wp_rewrite) {
            $wp_rewrite = new WP_Rewrite();
        }

        $rest_url    = wp_parse_url(trailingslashit(rest_url()));
        $current_url = wp_parse_url(add_query_arg(array()));
        if(!is_array($rest_url) || !array_key_exists('path', $rest_url)){
            return false;
        }
        $is_rest     = strpos($current_url['path'], $rest_url['path'], 0) === 0;

        return $is_rest;
    }

    static function check_2fa()
    {
        $options = WPCaptcha_Setup::get_options();
        if ($options['2fa_email'] !== '1') {
            return;
        }

        $user = wp_get_current_user();

        // skip all when not logged in
        if (!is_user_logged_in()) {
            return;
        }

        // skip when logging out
        if (!empty($_GET['action']) && $_GET['action'] == 'logout') {
            return;
        }

        // bypass for MainWP
        if (!empty($_GET['login_required']) && !empty($_GET['mainwpsignature']) && !empty($_GET['nonce']) && !empty($_GET['user'])) {
            $key = rand(10000, 99999);
            update_user_meta($user->ID, 'wpcaptcha_2fa_key', $key);
            update_user_meta($user->ID, 'wpcaptcha_2fa_key_check', $key);
        }

        // when email link is clicked we check and write new key
        if (!empty($_GET['wpcaptcha_2fa_confirm'])) {

            if (sanitize_text_field(@$_GET['key_hash']) != md5('elephant' . sanitize_text_field(@$_GET['key']))) {
                wp_die('Invalid 2FA hash value.', '2FA Authentication', array('link_text' => 'Log out and log in again to resend the email', 'link_url' => wp_logout_url()));
            }
            if (sanitize_text_field(@$_GET['key']) != get_user_meta($user->ID, 'wpcaptcha_2fa_key', true)) {
                wp_die('Invalid 2FA key.', '2FA Authentication', array('link_text' => 'Log out and log in again to resend the email', 'link_url' => wp_logout_url()));
            }

            // write new key
            update_user_meta($user->ID, 'wpcaptcha_2fa_key_check', $_GET['key']);

            if (!empty($_GET['redirect_to'])) {
                wp_redirect($_GET['redirect_to']);
                die();
            }
        } // setting/checking new key

        if (empty(get_user_meta($user->ID, 'wpcaptcha_2fa_key', true))) {
            wp_die('No 2FA key found.', '2FA Authentication', array('link_text' => 'Log out and log in again to resend the email', 'link_url' => wp_logout_url()));
        }

        if (empty(get_user_meta($user->ID, 'wpcaptcha_2fa_key', true)) || get_user_meta($user->ID, 'wpcaptcha_2fa_key', true) != get_user_meta($user->ID, 'wpcaptcha_2fa_key_check', true)) {
            wp_die('<b>Check your email</b> to confirm the log in.', '2FA Authentication', array('link_text' => 'Log out and log in again to resend the email', 'link_url' => wp_logout_url()));
        }
    }

    static function wp_logout($user_id)
    {
        $options = WPCaptcha_Setup::get_options();
        if ($options['2fa_email'] !== '1') {
            return true;
        }

        $user = get_user_by('ID', $user_id);

        update_user_meta($user->ID, 'wpcaptcha_2fa_key', '');
        update_user_meta($user->ID, 'wpcaptcha_2fa_key_check', '');

        return true;
    }

    static function wp_login($user_login, $user)
    {
        $options = WPCaptcha_Setup::get_options();
        if ($options['2fa_email'] !== '1') {
            return true;
        }

        $key = rand(10000, 99999);

        update_user_meta($user->ID, 'wpcaptcha_2fa_key', $key);
        update_user_meta($user->ID, 'wpcaptcha_2fa_key_check', '');

        $link_2fa = trailingslashit(get_bloginfo('url')) . '?wpcaptcha_2fa_confirm=1&key=' . $key . '&key_hash=' . md5('elephant' . $key) . '&redirect_to=' . @$_POST['redirect_to'] . '&rand=' . rand(100, 999);

        if (!empty($options['2fa_email_message'])) {
            $message = $options['2fa_email_message'];
            $message = str_replace('%%user%%', $user_login, $message);
            $message = str_replace('%%user_display_name%%', $user->display_name, $message);
            $message = str_replace('%%site_title%%', get_bloginfo('name'), $message);
            $message = str_replace('%%site_url%%', get_bloginfo('url'), $message);
            $message = str_replace('%%login_ip%%', WPCaptcha_Utility::getUserIP(), $message);
            $message = str_replace('%%login_ua%%', $user_login, $message);
            $message = str_replace('%%login_time%%', date('Y-m-d H:i:s', time()), $message);

            if (strpos($message, '%%confirm_link%%') !== false) {
                $message = str_replace('%%confirm_link%%', $link_2fa, $message);
            } else {
                $message .= PHP_EOL . PHP_EOL . trailingslashit(get_bloginfo('url')) . '?wpcaptcha_2fa_confirm=1&key=' . $key . '&key_hash=' . md5('elephant' . $key) . '&redirect_to=' . @$_POST['redirect_to'] . '&rand=' . rand(100, 999);
            }
        } else {
            $message = 'Please click the link below in order to confirm log in to ' . get_bloginfo('name') . PHP_EOL;
            $message .= 'If you did not login recently somebody might have your username and password. Change the password immediately.' . PHP_EOL;
            $message .= 'Request originated from: ' . WPCaptcha_Utility::getUserIP() . ' for user ' . $user->user_login . PHP_EOL . PHP_EOL;
            $message .= trailingslashit(get_bloginfo('url')) . '?wpcaptcha_2fa_confirm=1&key=' . $key . '&key_hash=' . md5('elephant' . $key) . '&redirect_to=' . @$_POST['redirect_to'] . '&rand=' . rand(100, 999);
        }

        if (!empty($options['2fa_email_message'])) {
            $subject = $options['2fa_email_subject'];
            $subject = str_replace('%%user%%', $user_login, $subject);
            $subject = str_replace('%%user_display_name%%', $user->display_name, $subject);
            $subject = str_replace('%%site_title%%', get_bloginfo('name'), $subject);
            $subject = str_replace('%%site_url%%', get_bloginfo('url'), $subject);
            $subject = str_replace('%%login_ip%%', WPCaptcha_Utility::getUserIP(), $subject);
            $subject = str_replace('%%login_ua%%', $_SERVER['HTTP_USER_AGENT'], $subject);
            $subject = str_replace('%%login_time%%', date('Y-m-d H:i:s', time()), $subject);
        } else {
            $subject = '2FA login confirmation for ' . get_bloginfo('name');
        }

        add_filter('wp_mail_content_type', function () {
            return "text/html";
        });

        wp_mail($user->user_email, $subject, nl2br($message));

        return true;
    }


    static function wp_authenticate_username_password($user, $username, $password)
    {
        if(empty($username)){
            return $user;
        }
        
        $options = WPCaptcha_Setup::get_options();

        $block_mode = $options['country_blocking_mode'];
        $blocked_countries = $options['country_blocking_countries'];

        $user_country = WPCaptcha_Utility::country_name_to_code(WPCaptcha_Utility::getUserCountry());

        $whitelisted = false;
        $user_ip = WPCaptcha_Utility::getUserIP();
        if (in_array($user_ip, $options['whitelist']) || self::isCloudWhitelisted()) {
            $whitelisted = true;
        }

        //Check website global cloud lock
        if (!$whitelisted && self::isCloudBlacklisted()) {
            self::accesslock_screen($options['block_message_cloud']);
        }

        if (!$whitelisted && $block_mode == 'blacklist' && ($options['block_undetermined_countries'] == 1 && $user_country == 'other' || (is_array($blocked_countries) && $user_country != 'other' && in_array($user_country, $blocked_countries)))) {
            echo self::accesslock_screen($options['block_message_country']);
            return new WP_Error('wpcaptcha_location_blocked', "<strong>ERROR</strong>: We're sorry, but access from your location is not allowed.");
        }

        if (!$whitelisted && $block_mode == 'whitelist' && ($options['block_undetermined_countries'] == 1 && $user_country == 'other' || (is_array($blocked_countries) && $user_country != 'other' && !in_array($user_country, $blocked_countries)))) {
            echo self::accesslock_screen($options['block_message_country']);
            return new WP_Error('wpcaptcha_location_blocked', "<strong>ERROR</strong>: We're sorry, but access from your location is not allowed.");
        }

        if (!$whitelisted && self::isLockedDown()) {
            echo self::accesslock_screen($options['block_message']);
            return new WP_Error('wpcaptcha_fail_count', __("<strong>ERROR</strong>: We're sorry, but this IP has been blocked due to too many recent failed login attempts.<br /><br />Please try again later.", 'advanced-google-recaptcha'));
        }

        if (!$whitelisted && (self::check_bot() || ($options['honeypot'] && !empty($_POST['ll_user_id'])))) {
            self::lockDown($username, 'Bot');
            return new WP_Error('wpcaptcha_bot', __("<strong>ERROR</strong>: We're sorry, but this IP has been blocked because it appears to be a bot.<br /><br />Please try again later.", 'advanced-google-recaptcha'));
        }

        if (self::is_rest_request()) {
            return $user;
        }

        if ($options['captcha_show_login']) {
            $captcha = self::handle_captcha();
            
            if (is_wp_error($captcha)) {
                if ($options['max_login_retries'] <= self::countFails($username) && self::countFails($username) > 0) {
                    self::lockDown($username, 'Too many captcha fails');
                }

                return $captcha;
            }
        }

        $userdata = get_user_by('login', $username);
        if (false === $userdata) {
            $userdata = get_user_by('email', $username);
        }

        if (!$whitelisted && ($options['max_login_retries'] <= self::countFails($username) || (strlen($username) > 0 && $userdata === false && $options['instant_block_nonusers'] == '1' && self::countFails($username) > 0))) {
            if ($options['max_login_retries'] <= self::countFails($username) && self::countFails($username) > 0) {
                self::lockDown($username, 'Too many fails');
            }

            if (strlen($username) > 0 && $userdata === false && $options['instant_block_nonusers'] == '1' && self::countFails($username) > 0) {
                self::lockDown($username, 'Invalid Username');
            }

            return new WP_Error('wpcaptcha_fail_count', __("<strong>ERROR</strong>: We're sorry, but this IP has been blocked due to too many recent failed login attempts.<br /><br />Please try again later.", 'advanced-google-recaptcha'));
        }

        if (empty($username) || empty($password)) {
            $error = new WP_Error();

            if (empty($username))
                $error->add('empty_username', __('<strong>ERROR</strong>: The username field is empty.', 'advanced-google-recaptcha'));

            if (empty($password))
                $error->add('empty_password', __('<strong>ERROR</strong>: The password field is empty.', 'advanced-google-recaptcha'));

            return $error;
        }

        if ($userdata === false) {
            if ($options['instant_block_nonusers'] == '1') {
                self::lockDown($username, 'Failed attempt with invalid username: ' . $username);
                return new WP_Error('incorrect_password', __("<strong>ERROR</strong>: We're sorry, but this IP has been blocked due to too many recent failed login attempts.<br /><br />Please try again later.", 'advanced-google-recaptcha'));
            }

            return new WP_Error('invalid_username', sprintf(__('<strong>ERROR</strong>: Invalid username. <a href="%s" title="Password Lost and Found">Lost your password</a>?', 'advanced-google-recaptcha'), site_url('wp-login.php?action=lostpassword', 'login')));
        }

        $userdata = apply_filters('wp_authenticate_user', $userdata, $password);
        if (is_wp_error($userdata)) {
            return $userdata;
        }

        if (!wp_check_password($password, $userdata->user_pass, $userdata->ID)) {
            return new WP_Error('incorrect_password', sprintf(__('<strong>ERROR</strong>: Incorrect password. <a href="%s" title="Password Lost and Found">Lost your password</a>?', 'advanced-google-recaptcha'), site_url('wp-login.php?action=lostpassword', 'login')));
        }

        $user =  new WP_User($userdata->ID);
        return $user;
    }

    static function check_bot()
    {
        $user_agent = WPCaptcha_Utility::parse_user_agent_array();
        if ($user_agent['device'] == 'bot') {
            return true;
        } else {
            return false;
        }
    }

    static function handle_captcha()
    {
        $options = WPCaptcha_Setup::get_options();

        if ($options['captcha'] == 'recaptchav2') {
            if (!isset($_POST['g-recaptcha-response']) || empty($_POST['g-recaptcha-response'])) {
                return new WP_Error('wpcaptcha_recaptchav2_not_submitted', __("<strong>ERROR</strong>: reCAPTHCA verification failed.<br /><br />Please try again.", 'advanced-google-recaptcha'));
            } else {
                $secret = $options['captcha_secret_key'];
                $response = wp_remote_get('https://www.google.com/recaptcha/api/siteverify?secret=' . $secret . '&response=' . sanitize_text_field(wp_unslash($_POST['g-recaptcha-response']))); // phpcs:ignore
                if (is_wp_error($response)) {
                    return new WP_Error('wpcaptcha_recaptchav3_failed', __("<strong>ERROR</strong>: reCAPTCHA verification request failed<br /><br />", 'advanced-google-recaptcha') . $response->get_error_message());
                }
                $response = json_decode($response['body']);
                if ($response->success) {
                    return true;
                } else {
                    return new WP_Error('wpcaptcha_recaptchav2_failed', __("<strong>ERROR</strong>: reCAPTCHA verification failed.<br /><br />Please try again.", 'advanced-google-recaptcha'));
                }
            }
        } else if ($options['captcha'] == 'recaptchav3') {
            if (!isset($_POST['g-recaptcha-response']) || empty($_POST['g-recaptcha-response'])) {
                return new WP_Error('wpcaptcha_recaptchav3_not_submitted', __("<strong>ERROR</strong>: reCAPTHCA verification failed.<br /><br />Please try again.", 'advanced-google-recaptcha'));
            } else {
                $secret = $options['captcha_secret_key'];
                $response = wp_remote_get('https://www.google.com/recaptcha/api/siteverify?secret=' . $secret . '&response=' . sanitize_text_field(wp_unslash($_POST['g-recaptcha-response']))); // phpcs:ignore
                if (is_wp_error($response)) {
                    return new WP_Error('wpcaptcha_recaptchav3_failed', __("<strong>ERROR</strong>: reCAPTCHA verification request failed<br /><br />", 'advanced-google-recaptcha') . $response->get_error_message());
                }
                $response = json_decode($response['body']);
                if ($response->success && $response->score >= $options['captcha_score']) {
                    return true;
                } else {
                    return new WP_Error('wpcaptcha_recaptchav3_failed', __("<strong>ERROR</strong>: reCAPTCHA verification failed.<br /><br />Please try again.", 'advanced-google-recaptcha'));
                }
            }
        } else if ($options['captcha'] == 'builtin' || $options['captcha'] == 'builtin_hc') {
            if (isset($_POST['wpcaptcha_captcha'])) {
                foreach($_POST['wpcaptcha_captcha'] as $captcha_id => $captcha_val){
                    if($captcha_val === $_COOKIE['wpcaptcha_captcha_' . $captcha_id]){
                        return true;
                    } else {
                        return new WP_Error('wpcaptcha_builtin_captcha_failed', __("<strong>ERROR</strong>: captcha verification failed.<br /><br />Please try again.", 'advanced-google-recaptcha'));
                    }
                }
            } else {
                return new WP_Error('wpcaptcha_builtin_captcha_failed', __("<strong>ERROR</strong>: captcha verification failed.<br /><br />Please try again.", 'advanced-google-recaptcha'));
            }
        } else if ($options['captcha'] == 'icons') {
            session_start();
            if (IconCaptcha::validateSubmission($_POST)) {
                return true;
            } else {
                return new WP_Error('wpcaptcha_icons_captcha_failed', __("<strong>ERROR</strong>: captcha verification failed.<br /><br />Please try again.", 'advanced-google-recaptcha'));
            }
        }

        if ($options['captcha'] == 'hcaptcha') {
            $data = array(
                'secret' => $options['captcha_secret_key'],
                'response' => $_POST['h-captcha-response']
            );
            $verify = curl_init();
            curl_setopt($verify, CURLOPT_URL, "https://hcaptcha.com/siteverify");
            curl_setopt($verify, CURLOPT_POST, true);
            curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($data));
            curl_setopt($verify, CURLOPT_RETURNTRANSFER, true);
            $response = curl_exec($verify);
            $responseData = json_decode($response);
            if ($responseData->success) {
                return true;
            } else {
                return new WP_Error('wpcaptcha_hcaptcha_failed', __("<strong>ERROR</strong>: hCaptcha verification failed.<br /><br />Please try again.", 'advanced-google-recaptcha'));
            }
        }

        if ($options['captcha'] == 'cloudflare') {
            $data = array(
                'secret' => $options['captcha_secret_key'],
                'response' => $_POST['cf-turnstile-response']
            );
            $verify = curl_init();
            curl_setopt($verify, CURLOPT_URL, "https://challenges.cloudflare.com/turnstile/v0/siteverify");
            curl_setopt($verify, CURLOPT_POST, true);
            curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($data));
            curl_setopt($verify, CURLOPT_RETURNTRANSFER, true);
            $response = curl_exec($verify);
            $responseData = json_decode($response);
            if ($responseData->success) {
                return true;
            } else {
                return new WP_Error('wpcaptcha_cloudflare_failed', __("<strong>ERROR</strong>: Cloudflare verification failed.<br /><br />Please try again.", 'advanced-google-recaptcha'));
            }
        }

        return true;
    }

    static function handle_captcha_wp_registration($errors, $user_login, $user_email)
    {
        $captcha_check = self::handle_captcha();
        if ($captcha_check !== true) {
            $errors = $captcha_check;
        }

        return $errors;
    }

    static function process_lost_password_form($errors)
    {
        $captcha_check = self::handle_captcha();
        if ($captcha_check !== true) {
            $errors->add('captcha', $captcha_check->get_error_message());
        }
    }

    static function check_woo_register_form_validation($validation_error)
    {
        if (wp_doing_ajax()) {
            return $validation_error;
        }
        
        $captcha_check = self::handle_captcha();

        if ($captcha_check !== true) {
            if (isset($validation_error) && is_wp_error($validation_error)) {
                $validation_error->add('captcha', $captcha_check->get_error_message());
                return $validation_error;
            } else {
                wc_add_notice($captcha_check->get_error_message(), 'error');
                return $validation_error;
            }
        }

        return $validation_error;
    }

    static function check_woo_checkout_form()
    {
        $captcha_check = self::handle_captcha();
        if ($captcha_check !== true) {
            wc_add_notice($captcha_check->get_error_message(), 'error');
        }
    }

    static function check_edd_register_form()
    {
        $captcha_check = self::handle_captcha();
        if ($captcha_check !== true) {
            edd_set_error('captcha', $captcha_check->get_error_message());
        }
    }

    static function process_buddypress_signup_form()
    {
        $captcha_check = self::handle_captcha();
        if ($captcha_check !== true) {
            wp_die(
                '<p><strong>' . esc_html__('ERROR:', 'advanced-google-recaptcha') . '</strong> ' . esc_html(strip_tags($captcha_check->get_error_message())) . '</p>',
                'reCAPTCHA',
                array(
                    'response'  => 403,
                    'back_link' => 1,
                )
            );
        }
    }

    static function process_comment_form($commentdata)
    {
        // No need to check for loggedin user.
        if (absint($commentdata['user_ID']) > 0) {
            return $commentdata;
        }

        $captcha_check = self::handle_captcha();
        if ($captcha_check !== true) {
            wp_die(
                '<p><strong>' . esc_html__('ERROR:', 'advanced-google-recaptcha') . '</strong> ' . esc_html(strip_tags($captcha_check->get_error_message())) . '</p>',
                'reCAPTCHA',
                array(
                    'response'  => 403,
                    'back_link' => 1,
                )
            );
        }

        return $commentdata;
    }

    static function loginFailed($username, $error)
    {
        self::incrementFails($username, $error->get_error_code());
    }


    static function handle_temporary_links()
    {
        $options = WPCaptcha_Setup::get_options();
        if (!empty($_GET['wpcaptcha_access'])) {
            $temporary_link_id = sanitize_key($_GET['wpcaptcha_access']);
            $wpcaptcha_temporary_links = WPCaptcha_AJAX::get_temp_links();
            if (array_key_exists($temporary_link_id, $wpcaptcha_temporary_links)) {
                $user_ip = WPCaptcha_Utility::getUserIP();
                if (!in_array($user_ip, $options['whitelist'])) {
                    $options['whitelist'][] = WPCaptcha_Utility::getUserIP();
                }
                update_option(WPCAPTCHA_OPTIONS_KEY, $options);

                $user_id = $wpcaptcha_temporary_links[$temporary_link_id]['user_id'];

                if (time() > $wpcaptcha_temporary_links[$temporary_link_id]['expires'] || $wpcaptcha_temporary_links[$temporary_link_id]['used'] >= $wpcaptcha_temporary_links[$temporary_link_id]['uses']) {
                    return;
                }

                $user_temporary_links = get_user_meta($user_id, 'wpcaptcha_temporary_links', true);
                $user_temporary_links[$temporary_link_id]['used']++;
                update_user_meta($user_id, 'wpcaptcha_temporary_links', $user_temporary_links);

                $user = get_user_by('ID', $user_id);
                if ($user) {
                    wp_set_current_user($user_id, $user->user_login);
                    wp_set_auth_cookie($user_id);

                    if ($options['2fa_email'] == '1') {
                        $key = rand(10000, 99999);
                        update_user_meta($user->ID, 'wpcaptcha_2fa_key', $key);
                        update_user_meta($user->ID, 'wpcaptcha_2fa_key_check', $key);
                    }

                    do_action('wp_login', $user->user_login, wp_get_current_user());
                    wp_safe_redirect(home_url('/wp-admin/'));
                    exit();
                }
            }
        }
    }

    static function login_error_message($error)
    {
        $options = WPCaptcha_Setup::get_options();

        if ($options['mask_login_errors'] == 1) {
            $error = 'Login Failed';
        }
        return $error;
    }

    static function login_form_fields()
    {
        $options = WPCaptcha_Setup::get_options();
        $showcreditlink = $options['show_credit_link'];
        if ($options['honeypot']) {
            echo '<style>input[name="ll_user_id"]{display:none;}</style>';
        }

        if ($options['honeypot']) {
            echo '<input type="text" name="ll_user_id" value="" placeholder="Enter your user ID" />';
        }

        if ($showcreditlink != "no" && $showcreditlink != 0) {
            echo "<div id='wpcaptcha-protected-by' style='display: block; clear: both; padding-top: 20px; text-align: center;''>";
            esc_html_e('Login form protected by', 'advanced-google-recaptcha');
            echo " <a href='" . esc_url('https://getwpcaptcha.com/') . "'>WP Captcha</a></div>";
            echo '<script>
            document.addEventListener("DOMContentLoaded", function() {
                document.querySelector("#loginform").append(document.querySelector("#wpcaptcha-protected-by"));
            });
            </script>';
        }
    }

    static function captcha_fields_print()
    {
        //phpcs:ignore this just prints the recaptcha HTML inline and all variables are already escaped
        echo self::captcha_fields(false); //phpcs:ignore
    }

    static function captcha_fields($output = false)
    {
        $options = WPCaptcha_Setup::get_options();
        
        if(false === $output){
            $output = '';
        } 

        if ($options['captcha'] == 'recaptchav2') {
            $output .= '<div class="g-recaptcha" style="transform: scale(0.9); -webkit-transform: scale(0.9); transform-origin: 0 0; -webkit-transform-origin: 0 0;" data-sitekey="' . $options['captcha_site_key'] . '"></div>';
        } else if ($options['captcha'] == 'recaptchav3') {
            $output .= '<input type="hidden" name="g-recaptcha-response" class="agr-recaptcha-response" value="" />';
            $output .= '<script>
                function wpcaptcha_captcha(){
                    grecaptcha.execute("' . esc_html($options['captcha_site_key']) . '", {action: "submit"}).then(function(token) {
                        var captchas = document.querySelectorAll(".agr-recaptcha-response");
                        captchas.forEach(function(captcha) {
                            captcha.value = token;
                        });
                    });
                }
                </script>';
        } else if ($options['captcha'] == 'hcaptcha') {
            $output .= '<div class="h-captcha" style="transform: scale(0.9); -webkit-transform: scale(0.9); transform-origin: 0 0; -webkit-transform-origin: 0 0;" data-sitekey="' . $options['captcha_site_key'] . '"></div>';
        } else if ($options['captcha'] == 'cloudflare') {
            $output .= '<div class="cf-turnstile" style="transform: scale(0.9); -webkit-transform: scale(0.9); transform-origin: 0 0; -webkit-transform-origin: 0 0;" data-theme="light" data-sitekey="' . $options['captcha_site_key'] . '" data-callback="javascriptCallback"></div>';
        } else if ($options['captcha'] == 'builtin') {
            $output .= '<p class="wpcaptcha_wrapper"><label for="wpcaptcha_captcha">Are you human? Please solve: ';
            $captcha_id = rand(1000,9999);
            $output .= '<img class="wpcaptcha-captcha-img" style="vertical-align: text-top;" src="' . esc_url(WPCAPTCHA_PLUGIN_URL) . '/libs/captcha.php?wpcaptcha-generate-image=true&color=' . esc_attr(urlencode('#FFFFFF')) . '&noise=1&id=' . intval($captcha_id) . '" alt="Captcha" />';
            $output .= '<input class="input" type="text" size="3" name="wpcaptcha_captcha[' . intval($captcha_id) . ']" id="wpcaptcha_captcha" />';
            $output .= '</label></p><br />';
        }  else if ($options['captcha'] == 'builtin_hc') {
            $output .= '<p class="wpcaptcha_wrapper"><label for="wpcaptcha_captcha">Are you human? Please solve: ';
            $captcha_id = rand(1000,9999);
            $output .= '<img class="wpcaptcha-captcha-img" style="vertical-align: text-top;" src="' . esc_url(WPCAPTCHA_PLUGIN_URL) . '/libs/captcha.php?wpcaptcha-generate-image=true&large=1&color=' . esc_attr(urlencode('#FFFFFF')) . '&noise=1&id=' . intval($captcha_id) . '" alt="Captcha" />';
            $output .= '<input class="input" type="text" size="3" name="wpcaptcha_captcha[' . intval($captcha_id) . ']" id="wpcaptcha_captcha" />';
            $output .= '</label></p><br />';
        } else if ($options['captcha'] == 'icons') {
            // Start a session.
            session_start();

            $output .= '<link href="' . WPCAPTCHA_PLUGIN_URL . 'css/icon-captcha.min.css" rel="stylesheet" type="text/css">';
            $output .= '<script src="' . WPCAPTCHA_PLUGIN_URL . 'js/icon-captcha.min.js" type="text/javascript"></script>';

            IconCaptcha::options([
                'iconPath' => WPCAPTCHA_PLUGIN_DIR . '/css/iconcaptcha/',
                'messages' => [
                    'wrong_icon' => 'You\'ve selected the wrong image.',
                    'no_selection' => 'No image has been selected.',
                    'empty_form' => 'You\'ve not submitted any form.',
                    'invalid_id' => 'The captcha ID was invalid.',
                    'form_token' => 'The form token was invalid.'
                ],
                'image' => [
                    'availableIcons' => 180,
                    'amount' => [
                        'min' => 5,
                        'max' => 5
                    ],
                    'rotate' => true,
                    'flip' => [
                        'horizontally' => true,
                        'vertically' => true,
                    ],
                    'border' => true
                ],
                'attempts' => [
                    'amount' => 5,
                    'timeout' => 60
                ],
                'token' => true
            ]);

            $output .= '<p>';
            $output .= '<input type="hidden" name="_iconcaptcha-token" value="' . IconCaptcha::token() . '"/>';
            $output .= '<div class="iconcaptcha-holder" style="min-width:300px; margin-left:-15px;" data-theme="light"></div>';
            $output .= '</p><br />';

            $output .= '<!-- Initialize IconCaptcha -->
                <script type="text/javascript">
                    
                    // Plain JavaScript implementation.
                    document.addEventListener("DOMContentLoaded", function() {
                        IconCaptcha.init(".iconcaptcha-holder", {
                            general: {
                                validationPath: "' . WPCAPTCHA_PLUGIN_URL . 'libs/iconcaptcha/captcha-request.php", // required, change path according to your installation.
                                fontFamily: "Poppins",
                                credits: "show",
                            },
                            security: {
                                clickDelay: 500,
                                hoverDetection: true,
                                enableInitialMessage: true,
                                initializeDelay: 500,
                                selectionResetDelay: 3000,
                                loadingAnimationDelay: 1000,
                                invalidateTime: 1000 * 60 * 2, // 2 minutes, in milliseconds
                            },
                            messages: {
                                initialization: {
                                    verify: "Verify that you are human.",
                                    loading: "Loading challenge..."
                                },
                                header: "Select the image displayed the <u>least</u> amount of times",
                                correct: "Verification complete.",
                                incorrect: {
                                    title: "Uh oh.",
                                    subtitle: "You\'ve selected the wrong image."
                                },
                                timeout: {
                                    title: "Please wait 60 sec.",
                                    subtitle: "You made too many incorrect selections."
                                }
                            }
                        });
                    });
                </script>';
        }
        return $output;
    }

    static function captcha_fields_cf7($form){
        $captcha_field = WPCaptcha_Functions::captcha_fields();
        
        $form = self::universal_forms_inject_captcha($form);

        return $form;
    }

    static function cf7_validation($result, $tag){
        $captcha_check = self::handle_captcha();
        if ($captcha_check !== true) {
            $result->invalidate($tag[(count($tag)-2)]->name, 'Invalid captcha');
        }
        
        return $result;
    }

    static function login_head()
    {
        $options = WPCaptcha_Setup::get_options();

        if ($options['design_enable']) {
            echo '<style type="text/css">';

            add_filter('login_headerurl', function ($url) {
                $options = WPCaptcha_Setup::get_options();
                if (!empty($options['design_logo_url'])) {
                    return $options['design_logo_url'];
                }
                return $url;
            });


            if (!empty($options['design_logo'])) {
                echo '#login h1 a, .login h1 a {';
                echo 'background-image: url(' . $options['design_logo'] . ');';
                echo 'background-repeat: no-repeat;';

                $background_width = 'auto';
                $background_height = 'auto';

                if (!empty($options['design_logo_width'])) {
                    $background_width = (int)$options['design_logo_width'];
                }

                if (!empty($options['design_logo_height'])) {
                    $background_height = (int)$options['design_logo_height'];
                }

                if ($background_width != 'auto') {
                    $background_width = $background_width . 'px';
                }

                if ($background_height != 'auto') {
                    $background_height = $background_height . 'px';
                }

                echo 'width: ' . $background_width . ';';
                echo 'height: ' . $background_height . ';';
                echo 'background-size:' . $background_width . ' ' . $background_height . ';';

                if (!empty($options['design_logo_margin_bottom'])) {
                    echo 'padding-bottom: ' . $options['design_logo_margin_bottom'] . 'px;';
                }

                echo '}';
            }

            if (!empty($options['design_background_color'])) {
                echo 'body.login {background-color:' . $options['design_background_color'] . '}';
            }

            if (!empty($options['design_background_image'])) {
                echo 'body.login {background-image:url(' . $options['design_background_image'] . '); background-size:cover;}';
            }

            echo 'body.login div#login form#loginform {';
            if (!empty($options['design_form_width'])) {
                echo 'width:' . $options['design_form_width'] . 'px;';
            }

            if (!empty($options['design_form_height'])) {
                echo 'height:' . $options['design_form_height'] . 'px;';
            }

            if (!empty($options['design_form_padding'])) {
                echo 'padding:' . $options['design_form_padding'] . 'px;';
            }

            if (!empty($options['design_form_border_radius'])) {
                echo 'border-radius:' . $options['design_form_border_radius'] . 'px;';
            }

            if (!is_null($options['design_form_border_width'])) {
                echo 'border-width:' . $options['design_form_border_width'] . 'px;';
            }

            if (!empty($options['design_form_border_color'])) {
                echo 'border-color:' . $options['design_form_border_color'] . ';';
            }

            if (!empty($options['design_form_background_color'])) {
                echo 'background-color:' . $options['design_form_background_color'] . ';';
            }

            if (!empty($options['design_form_background_image'])) {
                echo 'background-image:url(' . $options['design_form_background_image'] . '); background-size:cover;';
            }
            echo '}';

            echo 'body.login div#login form#loginform label {';
            if (!empty($options['design_label_font_size'])) {
                echo 'font-size:' . $options['design_label_font_size'] . 'px;';
            }

            if (!empty($options['design_label_text_color'])) {
                echo 'color:' . $options['design_label_text_color'] . ';';
            }
            echo '}';

            echo 'body.login div#login form#loginform input {';
            if (!empty($options['design_field_font_size'])) {
                echo 'font-size:' . $options['design_field_font_size'] . 'px;';
            }

            if (!empty($options['design_field_text_color'])) {
                echo 'color:' . $options['design_field_text_color'] . ';';
            }

            if (!empty($options['design_field_border_color'])) {
                echo 'border-color:' . $options['design_field_border_color'] . ';';
            }

            if (!is_null($options['design_field_border_width'])) {
                echo 'border-width:' . $options['design_field_border_width'] . 'px;';
            }

            if (!empty($options['design_field_border_radius'])) {
                echo 'border-radius:' . $options['design_field_border_radius'] . 'px;';
            }

            if (!empty($options['design_field_background_color'])) {
                echo 'background-color:' . $options['design_field_background_color'] . ';';
            }
            echo '}';

            echo 'body.login div#login form#loginform p.submit input#wp-submit {';
            if (!empty($options['design_button_font_size'])) {
                echo 'font-size:' . $options['design_button_font_size'] . 'px;';
            }

            if (!empty($options['design_button_text_color'])) {
                echo 'color:' . $options['design_button_text_color'] . ';';
            }

            if (!empty($options['design_button_border_color'])) {
                echo 'border-color:' . $options['design_button_border_color'] . ';';
            }

            if (!is_null($options['design_button_border_width'])) {
                echo 'border-width:' . $options['design_button_border_width'] . 'px;';
            }

            if (!empty($options['design_button_border_radius'])) {
                echo 'border-radius:' . $options['design_button_border_radius'] . 'px;';
            }

            if (!empty($options['design_button_background_color'])) {
                echo 'background-color:' . $options['design_button_background_color'] . ';';
            }
            echo '}';

            echo 'body.login div#login form#loginform{';
            if (!empty($options['design_text_color'])) {
                echo 'color:' . $options['design_text_color'] . ';';
            }
            echo '}';

            echo 'body.login a, body.login #nav a, body.login #backtoblog a, body.login div#login form#loginform a{';
            if (!empty($options['design_link_color'])) {
                echo 'color:' . $options['design_link_color'] . ';';
            }
            echo '}';

            echo 'body.login a:hover, body.login #nav a:hover, body.login #backtoblog a:hover, body.login div#login form#loginform a:hover{';
            if (!empty($options['design_link_hover_color'])) {
                echo 'color:' . $options['design_link_hover_color'] . ';';
            }
            echo '}';

            echo 'body.login div#login form#loginform p.submit input#wp-submit:hover {';
            if (!empty($options['design_button_hover_text_color'])) {
                echo 'color:' . $options['design_button_hover_text_color'] . ';';
            }

            if (!empty($options['design_button_hover_border_color'])) {
                echo 'border-color:' . $options['design_button_hover_border_color'] . ';';
            }

            if (!empty($options['design_button_hover_background_color'])) {
                echo 'background-color:' . $options['design_button_hover_background_color'] . ';';
            }
            echo '}';

            echo '.wp-core-ui .button .dashicons, .wp-core-ui .button-secondary .dashicons{';
            if (!empty($options['design_link_color'])) {
                echo 'color:' . $options['design_link_color'] . ';';
            }
            echo '}';

            echo '.wp-core-ui .button .dashicons:hover, .wp-core-ui .button-secondary .dashicons:hover{';
            if (!empty($options['design_link_hover_color'])) {
                echo 'color:' . $options['design_link_hover_color'] . ';';
            }
            echo '}';


            if (!empty($options['design_custom_css'])) {
                echo $options['design_custom_css'];
            }

            echo '</style>';
        }
    }

    static function login_enqueue_scripts()
    {
        $options = WPCaptcha_Setup::get_options();

        if ($options['captcha'] == 'recaptchav2') {
            wp_enqueue_script('wpcaptcha-recaptcha', 'https://www.google.com/recaptcha/api.js', array(), self::$version, true);
        } else if ($options['captcha'] == 'recaptchav3') {
            wp_enqueue_script('wpcaptcha-recaptcha', 'https://www.google.com/recaptcha/api.js?onload=wpcaptcha_captcha&render=' . $options['captcha_site_key'], array(), self::$version, true);
        } else if ($options['captcha'] == 'hcaptcha') {
            wp_enqueue_script('wpcaptcha-recaptcha', 'https://js.hcaptcha.com/1/api.js', array(), self::$version, true);
        } else if ($options['captcha'] == 'cloudflare') {
            wp_enqueue_script('wpcaptcha-recaptcha', 'https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback', array(), self::$version, true);
        }
    }

    static function get_templates()
    {
        $templates = array();

        $templates['orange'] = array(
            'design_background_color' => '#ef9b00',
            'design_background_image' => '',
            'design_logo' => 'white-wpcaptcha-icon',
            'design_logo_width' => '100',
            'design_logo_height' => '100',
            'design_logo_margin_bottom' => '30',
            'design_text_color' => '#4c3d00',
            'design_link_color' => '#7c6e13',
            'design_link_hover_color' => '#896709',
            'design_form_border_color' => '#725f00',
            'design_form_border_width' => '0',
            'design_form_width' => '',
            'design_form_height' => '',
            'design_form_padding' => '20',
            'design_form_border_radius' => '4',
            'design_form_background_color' => '#f9e7ac',
            'design_form_background_image' => '',
            'design_label_font_size' => '14',
            'design_label_text_color' => '#634000',
            'design_field_font_size' => '14',
            'design_field_text_color' => '#ffffff',
            'design_field_border_color' => '#634000',
            'design_field_border_width' => '1',
            'design_field_border_radius' => '2',
            'design_field_background_color' => '#ffffff',
            'design_button_font_size' => '14',
            'design_button_text_color' => '#ffffff',
            'design_button_border_color' => '#634000',
            'design_button_border_width' => '1',
            'design_button_border_radius' => '4',
            'design_button_background_color' => '#634000',
            'design_button_hover_text_color' => '#ffffff',
            'design_button_hover_border_color' => '#8c5f00',
            'design_button_hover_background_color' => '#8c5f00',
            'design_custom_css' => ''
        );

        $templates['red'] = array(
            'design_background_color' => '#ce0000',
            'design_background_image' => '',
            'design_logo' => 'white-wpcaptcha-icon',
            'design_logo_width' => '100',
            'design_logo_height' => '100',
            'design_logo_margin_bottom' => '30',
            'design_text_color' => '#300000',
            'design_link_color' => '#c91e1e',
            'design_link_hover_color' => '#d15959',
            'design_form_border_color' => '#c90000',
            'design_form_border_width' => '2',
            'design_form_width' => '',
            'design_form_height' => '',
            'design_form_padding' => '20',
            'design_form_border_radius' => '4',
            'design_form_background_color' => '#ffffff',
            'design_form_background_image' => '',
            'design_label_font_size' => '14',
            'design_label_text_color' => '#383838',
            'design_field_font_size' => '14',
            'design_field_text_color' => '#ffffff',
            'design_field_border_color' => '#d1d1d1',
            'design_field_border_width' => '1',
            'design_field_border_radius' => '2',
            'design_field_background_color' => '#ffffff',
            'design_button_font_size' => '14',
            'design_button_text_color' => '#ffffff',
            'design_button_border_color' => '#000000',
            'design_button_border_width' => '0',
            'design_button_border_radius' => '4',
            'design_button_background_color' => '#d30000',
            'design_button_hover_text_color' => '#ffffff',
            'design_button_hover_border_color' => '#ffffff',
            'design_button_hover_background_color' => '#9e0000',
            'design_custom_css' => ''
        );

        $templates['green'] = array(
            'design_background_color' => '#2c6600',
            'design_background_image' => '',
            'design_logo' => 'white-wpcaptcha-icon',
            'design_logo_width' => '100',
            'design_logo_height' => '100',
            'design_logo_margin_bottom' => '30',
            'design_text_color' => '#c6e500',
            'design_link_color' => '#c6e500',
            'design_link_hover_color' => '#acbf00',
            'design_form_border_color' => '#c6e500',
            'design_form_border_width' => '2',
            'design_form_width' => '',
            'design_form_height' => '',
            'design_form_padding' => '20',
            'design_form_border_radius' => '4',
            'design_form_background_color' => '#4b7c01',
            'design_form_background_image' => '',
            'design_label_font_size' => '14',
            'design_label_text_color' => '#ffffff',
            'design_field_font_size' => '14',
            'design_field_text_color' => '#ffffff',
            'design_field_border_color' => '#87d642',
            'design_field_border_width' => '1',
            'design_field_border_radius' => '2',
            'design_field_background_color' => '#3c7f02',
            'design_button_font_size' => '14',
            'design_button_text_color' => '#ffffff',
            'design_button_border_color' => '#000000',
            'design_button_border_width' => '0',
            'design_button_border_radius' => '4',
            'design_button_background_color' => '#66b500',
            'design_button_hover_text_color' => '#ffffff',
            'design_button_hover_border_color' => '#ffffff',
            'design_button_hover_background_color' => '#a6d800',
            'design_custom_css' => ''
        );

        $templates['blue'] = array(
            'design_background_color' => '#005cb2',
            'design_background_image' => '',
            'design_logo' => 'white-wpcaptcha-icon',
            'design_logo_width' => '100',
            'design_logo_height' => '100',
            'design_logo_margin_bottom' => '30',
            'design_text_color' => '#300000',
            'design_link_color' => '#2ca8ea',
            'design_link_hover_color' => '#005b93',
            'design_form_border_color' => '#008ed1',
            'design_form_border_width' => '2',
            'design_form_width' => '',
            'design_form_height' => '',
            'design_form_padding' => '20',
            'design_form_border_radius' => '4',
            'design_form_background_color' => '#ffffff',
            'design_form_background_image' => '',
            'design_label_font_size' => '14',
            'design_label_text_color' => '#383838',
            'design_field_font_size' => '14',
            'design_field_text_color' => '#ffffff',
            'design_field_border_color' => '#d1d1d1',
            'design_field_border_width' => '1',
            'design_field_border_radius' => '2',
            'design_field_background_color' => '#ffffff',
            'design_button_font_size' => '14',
            'design_button_text_color' => '#ffffff',
            'design_button_border_color' => '#000000',
            'design_button_border_width' => '0',
            'design_button_border_radius' => '4',
            'design_button_background_color' => '#0084cc',
            'design_button_hover_text_color' => '#ffffff',
            'design_button_hover_border_color' => '#ffffff',
            'design_button_hover_background_color' => '#005796',
            'design_custom_css' => ''
        );

        $templates['gray'] = array(
            'design_background_color' => '#353535',
            'design_background_image' => '',
            'design_logo' => 'white-wpcaptcha-icon',
            'design_logo_width' => '100',
            'design_logo_height' => '100',
            'design_logo_margin_bottom' => '30',
            'design_text_color' => '#300000',
            'design_link_color' => '#06a8e8',
            'design_link_hover_color' => '#005b93',
            'design_form_border_color' => '#474747',
            'design_form_border_width' => '2',
            'design_form_width' => '',
            'design_form_height' => '',
            'design_form_padding' => '20',
            'design_form_border_radius' => '4',
            'design_form_background_color' => '#ffffff',
            'design_form_background_image' => '',
            'design_label_font_size' => '14',
            'design_label_text_color' => '#383838',
            'design_field_font_size' => '14',
            'design_field_text_color' => '#ffffff',
            'design_field_border_color' => '#d1d1d1',
            'design_field_border_width' => '1',
            'design_field_border_radius' => '2',
            'design_field_background_color' => '#ffffff',
            'design_button_font_size' => '14',
            'design_button_text_color' => '#ffffff',
            'design_button_border_color' => '#000000',
            'design_button_border_width' => '0',
            'design_button_border_radius' => '4',
            'design_button_background_color' => '#595959',
            'design_button_hover_text_color' => '#ffffff',
            'design_button_hover_border_color' => '#ffffff',
            'design_button_hover_background_color' => '#878787',
            'design_custom_css' => ''
        );

        return $templates;
    }

    static function install_template()
    {
        check_admin_referer('wpcaptcha_install_template');
        $options = WPCaptcha_Setup::get_options();

        $template = $_GET['template'];
        $templates = self::get_templates();

        if (array_key_exists($template, $templates)) {
            $options = array_merge($options, $templates[$template]);
            if ($options['design_logo'] == 'white-wpcaptcha-icon') {
                $options['design_logo'] = WPCAPTCHA_PLUGIN_URL . 'images/white-icon.png';
            }
            update_option(WPCAPTCHA_OPTIONS_KEY, $options);
            WPCaptcha_Admin::add_notice('template_activated', __('Template activated.', 'advanced-google-recaptcha'), 'success', true);
        } else {
            WPCaptcha_Admin::add_notice('template_not_found', __('Unknown template ID.', 'advanced-google-recaptcha'), 'error', true);
        }

        if (!empty($_GET['redirect'])) {
            wp_safe_redirect($_GET['redirect']);
        }
    }

    static function login_scripts_print()
    {
        //phpcs:ignore this just prints the recaptcha scripts inline as they can be used in various forms where enqueing normally is not always working
        echo self::login_scripts(false); //phpcs:ignore
    }

    static function login_scripts($output = false)
    {
        $options = WPCaptcha_Setup::get_options();

        if(false === $output){
            $output = '';
        }

        if ($options['captcha'] == 'recaptchav2') {
            $output .= "<script src='https://www.google.com/recaptcha/api.js?ver=" . self::$version . "' id='wpcaptcha-recaptcha-js'></script>";
        } else if ($options['captcha'] == 'recaptchav3') {
            $output .= "<script src='https://www.google.com/recaptcha/api.js?onload=wpcaptcha_captcha&render=" . $options['captcha_site_key'] . "&ver=" . self::$version . "' id='wpcaptcha-recaptcha-js'></script>";
        } else if ($options['captcha'] == 'hcaptcha') {
            $output .= "<script src='https://www.hCaptcha.com/1/api.js?ver=" . self::$version . "' id='wpcaptcha-recaptcha-js'></script>";
        } else if ($options['captcha'] == 'cloudflare') {
            $output .= "<script src='https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback' id='wpcaptcha-recaptcha-js'></script>";
        }

        return $output;
    }

    static function accesslock_screen($block_message = false)
    {
        $main_color = '#4285f4';
        $secondary_color = '#8eb8ff';

        if (WPCaptcha_Admin::get_rebranding() !== false) {
            $brand_color = WPCaptcha_Admin::get_rebranding('color');
            if (!empty($brand_color)) {
                $main_color = $brand_color;
                $secondary_color = WPCaptcha_Admin::color_luminance($brand_color, 0.2);
            }
        }

        echo '<style>
            @import url(\'https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,400;1,500;1,700&display=swap\');

            #wpcaptcha_accesslock_screen_wrapper{
                font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
                width:100%;
                height:100%;
                position:fixed;
                top:0;
                left:0;
                z-index: 999999;
                font-size: 14px;
                color: #333;
                line-height: 1.4;
                background-image: linear-gradient(45deg, ' . $main_color . ' 25%, ' . $secondary_color . ' 25%, ' . $secondary_color . ' 50%, ' . $main_color . ' 50%, ' . $main_color . ' 75%, ' . $secondary_color . ' 75%, ' . $secondary_color . ' 100%);
                background-size: 28.28px 28.28px;
            }

            #wpcaptcha_accesslock_screen_wrapper form{
                max-width: 300px;
                top:50%;
                left:50%;
                margin-top:-200px;
                margin-left:-200px;
                border: none;
                background: #ffffffde;
                box-shadow: 0 1px 3px rgb(0 0 0 / 4%);
                position: fixed;
                text-align:center;
                background: #fffffff2;
                padding: 20px;
                -webkit-box-shadow: 5px 5px 0px 1px rgba(0,0,0,0.22);
                box-shadow: 5px 5px 0px 1px rgba(0,0,0,0.22);
            }

            #wpcaptcha_accesslock_screen_wrapper p{
                padding: 10px;
                line-height:1.5;
            }

            #wpcaptcha_accesslock_screen_wrapper p.error{
                background: #f11c1c;
                color: #FFF;
                font-weight: 500;
            }

            #wpcaptcha_accesslock_screen_wrapper form input[type="text"]{
                padding: 4px 10px;
                border-radius: 2px;
                border: 1px solid #c3c4c7;
                font-size: 16px;
                line-height: 1.33333333;
                margin: 0 6px 16px 0;
                min-height: 40px;
                max-height: none;
                width: 100%;
            }

            #wpcaptcha_accesslock_screen_wrapper form input[type="submit"]{
                padding: 10px 10px;
                border-radius: 2px;
                border: none;
                font-size: 16px;
                background: ' . $main_color . ';
                color: #FFF;
                cursor: pointer;
                width: 100%;
            }

            #wpcaptcha_accesslock_screen_wrapper form input[type="submit"]:hover{
                background: ' . $secondary_color . ';
            }
        </style>

        <script>
        document.title = "' . get_bloginfo('name') . '";
        </script>';
        echo '<div id="wpcaptcha_accesslock_screen_wrapper">';

        echo '<form method="POST">';

        if (isset($_POST['wpcaptcha_recovery_submit']) && wp_verify_nonce($_POST['wpcaptcha_recovery_nonce'], 'wpcaptcha_recovery')) {
            if (!filter_var($_POST['wpcaptcha_recovery_email'], FILTER_VALIDATE_EMAIL)) {
                $display_message = '<p class="error">Invalid email address.</p>';
            } else {
                $user = get_user_by('email', sanitize_text_field($_POST['wpcaptcha_recovery_email']));
                if (user_can($user, 'administrator')) {
                    $unblock_key = md5(time() . rand(10000, 9999));
                    $unblock_attempts = get_transient('wpcaptcha_unlock_count_' . $user->ID);
                    if (!$unblock_attempts) {
                        $unblock_attempts = 0;
                    }

                    $unblock_attempts++;
                    set_transient('wpcaptcha_unlock_count_' . $user->ID, $unblock_attempts, HOUR_IN_SECONDS);

                    if ($unblock_attempts <= 3) {
                        set_transient('wpcaptcha_unlock_' . $unblock_key, $unblock_key, HOUR_IN_SECONDS);

                        $unblock_url = add_query_arg(array('wpcaptcha_unblock' => $unblock_key), wp_login_url());

                        $subject  = 'WP Captcha unblock instructions for ' . site_url();
                        $message  = '<p>The IP ' . WPCaptcha_Utility::getUserIP() . ' has been locked down and someone submitted an unblock request using your email address <strong>' . $_POST['wpcaptcha_recovery_email'] . '</strong></p>';
                        $message .= '<p>If this was you, and you have locked yourself out please click <a target="_blank" href="' . $unblock_url . '">this link</a> which is valid for 1 hour.</p>';
                        $message .= '<p>Please note that for security reasons, this will only unblock the IP of the person opening the link, not the IP of the person who submitted the unblock request. To unblock someone else please do so on the <a href="' . admin_url('options-general.php?page=wpcaptcha#wpcaptcha_activity') . '">WP Captcha Activity Page</p>';

                        add_filter('wp_mail_content_type', function () {
                            return "text/html";
                        });

                        wp_mail($user->user_email, $subject, $message);
                    }
                } else {
                    //If no admin using the submitted email exists, ignore silently
                }

                if (isset($unblock_attempts) && $unblock_attempts > 3) {
                    $display_message = '<p class="error">You have already attempted to unblock yourself recently, please wait 1 hour before trying again.</p>';
                } else {
                    $display_message = '<p>If an administrator having the email address <strong>' . $_POST['wpcaptcha_recovery_email'] . '</strong> exists, an email has been sent with instructions to regain access.</p>';
                }
            }
        }

        if (WPCaptcha_Admin::get_rebranding('logo_url') !== false) {
            echo '<img src="' . WPCaptcha_Admin::get_rebranding('logo_url') . '" />';
        } else {
            echo '<img src="' . WPCAPTCHA_PLUGIN_URL . '/images/wp-captcha-logo.png" alt="WP Captcha PRO" height="60" title="WP Captcha PRO">';
        }
        echo '<br />';
        echo '<br />';
        if ($block_message !== false) {
            echo '<p class="error">' . $block_message . '</p>';
        } else {
            echo '<p class="error">We\'re sorry, but your IP has been blocked due to too many recent failed login attempts.</p>';
        }
        if (!empty($display_message)) {
            echo $display_message;
        }
        echo '<p>If you are a user with administrative privilege please enter your email below to receive instructions on how to unblock yourself.</p>';
        echo '<input type="text" name="wpcaptcha_recovery_email" value="" placeholder="" />';
        echo '<input type="submit" name="wpcaptcha_recovery_submit" value="Send unblock email" placeholder="" />';
        wp_nonce_field('wpcaptcha_recovery', 'wpcaptcha_recovery_nonce');


        echo '</form>';
        echo '</div>';

        exit();
    }

    static function handle_unblock()
    {
        global $wpdb;
        $options = WPCaptcha_Setup::get_options();
        if (isset($_GET['wpcaptcha_unblock']) && $options['global_unblock_key'] === $_GET['wpcaptcha_unblock']) {
            $user_ip = WPCaptcha_Utility::getUserIP();
            if (!in_array($user_ip, $options['whitelist'])) {
                $options['whitelist'][] = WPCaptcha_Utility::getUserIP();
            }
            update_option(WPCAPTCHA_OPTIONS_KEY, $options);
        }

        if (isset($_GET['wpcaptcha_unblock']) && strlen($_GET['wpcaptcha_unblock']) == 32) {
            $unblock_key = sanitize_key($_GET['wpcaptcha_unblock']);
            $unblock_transient = get_transient('wpcaptcha_unlock_' . $unblock_key);
            if ($unblock_transient == $unblock_key) {
                $user_ip = WPCaptcha_Utility::getUserIP();
                $wpdb->delete(
                    $wpdb->wpcatcha_accesslocks,
                    array(
                        'accesslock_IP' => $user_ip
                    )
                );

                if (!in_array($user_ip, $options['whitelist'])) {
                    $options['whitelist'][] = WPCaptcha_Utility::getUserIP();
                }

                update_option(WPCAPTCHA_OPTIONS_KEY, $options);
            }
        }
    }

    static function handle_global_block()
    {
        $options = WPCaptcha_Setup::get_options();

        //If user is on local or cloud whitelist, don't check anything else
        $user_ip = WPCaptcha_Utility::getUserIP();
        if (in_array($user_ip, $options['whitelist']) || self::isCloudWhitelisted()) {
            return false;
        }

        //Check website lock
        if ($options['global_block'] == '1' && self::isLockedDown()) {
            self::accesslock_screen($options['block_message']);
        }

        //Check website global cloud lock
        if ($options['cloud_global_block'] == '1' && self::isCloudBlacklisted()) {
            self::accesslock_screen($options['block_message_cloud']);
        }

        //Check country lock
        $block_mode = $options['country_blocking_mode'];
        $blocked_countries = $options['country_blocking_countries'];
        if (!is_array($blocked_countries)) {
            $blocked_countries = array();
        }

        $user_country = WPCaptcha_Utility::country_name_to_code(WPCaptcha_Utility::getUserCountry());
        if ($options['country_global_block'] == 1 && $block_mode == 'blacklist' && ($options['block_undetermined_countries'] == 1 && $user_country == 'other' || $user_country != 'other' && in_array($user_country, $blocked_countries))) {
            self::accesslock_screen($options['block_message_country']);
        }

        if ($options['country_global_block'] == 1 && $block_mode == 'whitelist' && ($options['block_undetermined_countries'] == 1 && $user_country == 'other' || $user_country != 'other' && !in_array($user_country, $blocked_countries))) {
            self::accesslock_screen($options['block_message_country']);
        }
    }

    static function bruteforce_login()
    {
        $return           = array();
        $max_users_attack = 50;
        $passwords        = file(WPCAPTCHA_PLUGIN_DIR . 'misc/brute-force-dictionary.txt', FILE_IGNORE_NEW_LINES);

        $bad_usernames = array();

        $users = get_users(array('role' => 'administrator'));
        if (count($users) < $max_users_attack) {
            $users = array_merge($users, get_users(array('role' => 'editor')));
        }
        if (count($users) < $max_users_attack) {
            $users = array_merge($users, get_users(array('role' => 'author')));
        }
        if (count($users) < $max_users_attack) {
            $users = array_merge($users, get_users(array('role' => 'contributor')));
        }
        if (count($users) < $max_users_attack) {
            $users = array_merge($users, get_users(array('role' => 'subscriber')));
        }

        $i = 0;
        foreach ($users as $user) {
            $i++;
            $passwords[] = $user->user_login;
            foreach ($passwords as $password) {

                if (self::try_login($user->user_login, $password)) {
                    $bad_usernames[] = $user->user_login;
                    break;
                }
            } // foreach $passwords

            if ($i > $max_users_attack) {
                break;
            }
        } // foreach $users

        if (empty($bad_usernames)) {
            $message = 'No vulnerable user accounts found';
        } else {
            $message = 'The following users have weak passwords: ' . implode(', ', $bad_usernames);
        }

        return array('pass' => empty($bad_usernames), 'message' => $message);
    }

    public static function try_login($username, $password)
    {
        $user = apply_filters('authenticate', null, $username, $password);

        if (isset($user->ID) && !empty($user->ID)) {
            return true;
        } else {
            return false;
        }
    }

    public static function clean_ip_string($ip)
    {
        $ip = trim($ip);
        return $ip;
    }

    public static function isCloudBlacklisted($ip = false)
    {
        global $wpcaptcha_licensing;
        $options = WPCaptcha_Setup::get_options();
        $license = $wpcaptcha_licensing->get_license();

        if (false === $ip) {
            $ip = WPCaptcha_Utility::getUserIP();
        }

        //Check cloud account blacklist
        if ($options['cloud_use_account_lists'] == 1) {
            if (is_array($license) && is_array($license['meta']) && array_key_exists('cloud_protection_blacklist', $license['meta']) && !empty($license['meta']['cloud_protection_blacklist'])) {
                $account_blacklist = explode(PHP_EOL, str_replace(',', PHP_EOL, $license['meta']['cloud_protection_blacklist']));
            } else {
                return false;
            }

            $account_blacklist = array_map('WPCaptcha_Functions::clean_ip_string', $account_blacklist);

            if (in_array($ip, $account_blacklist)) {
                return true;
            }
        }

        $path = self::get_cloud_protection_path();

        if ($options['cloud_use_blacklist'] == 1 && file_exists($path . 'ips.txt')) {
            $ips = explode(PHP_EOL, file_get_contents($path . 'ips.txt'));
            if ($ips[0] != '#WFIPS') {
                return false;
            }

            if (in_array($ip, $ips)) {
                return true;
            }
        }

        return false;
    }

    public static function login_cookie_expiration($expire)
    {
        $options = WPCaptcha_Setup::get_options();

        if ($options['cookie_lifetime'] > 0) {
            return $options['cookie_lifetime'] * DAY_IN_SECONDS;
        }

        return $expire;
    }

    public static function isCloudWhitelisted($ip = false)
    {
        global $wpcaptcha_licensing;
        $options = WPCaptcha_Setup::get_options();
        $license = $wpcaptcha_licensing->get_license();

        if ($options['cloud_use_account_lists'] != 1) {
            return false;
        }

        if (is_array($license) && is_array($license['meta']) && array_key_exists('cloud_protection_whitelist', $license['meta']) && !empty($license['meta']['cloud_protection_whitelist'])) {
            $account_whitelist = explode(PHP_EOL, str_replace(',', PHP_EOL, $license['meta']['cloud_protection_whitelist']));
        } else {
            return false;
        }

        $account_whitelist = array_map('WPCaptcha_Functions::clean_ip_string', $account_whitelist);
        
        if (false === $ip) {
            $ip = WPCaptcha_Utility::getUserIP();
        }

        if (in_array($ip, $account_whitelist)) {
            return true;
        }

        return false;
    }

    public static function get_cloud_protection_path()
    {
        $upload_dir = wp_upload_dir();

        $path = trailingslashit($upload_dir['basedir']) . '/wpcaptcha/';

        if (!file_exists($path)) {
            $folder = wp_mkdir_p($path);
            if (!$folder) {
                return new WP_Error(1, 'Unable to create ' . $path . ' folder.');
            }

            $htaccess_content = 'Options -Indexes' . PHP_EOL . 'order deny,allow' . PHP_EOL . 'deny from all';
            $htaccess_file = @fopen($path . '.htaccess', 'w');
            if ($htaccess_file) {
                fputs($htaccess_file, $htaccess_content);
                fclose($htaccess_file);
            }
        }

        return $path;
    }

    public static function sync_cloud_protection()
    {
        global $wpcaptcha_licensing;
        $license = $wpcaptcha_licensing->get_license();
        $path = self::get_cloud_protection_path();

        if (is_array($license['meta']) && isset($license['meta']['cloud_protection_url'])) {
            file_put_contents($path . 'ips.zip', fopen($license['meta']['cloud_protection_url'], 'r'));

            $import_zip = new ZipArchive();
            $zip_open = $import_zip->open($path . 'ips.zip');
            if ($zip_open === true) {
                try {
                    $import_zip->extractTo($path);
                } catch (Exception $e) {
                    unlink($path . 'ips.zip');
                    return new WP_Error(1, 'IPs ZIP file not valid');
                }
            } else {
                if (file_exists($path . 'ips.zip')) {
                    unlink($path . 'ips.zip');
                }
                return new WP_Error(1, 'IPs ZIP file not valid');
            }

            $import_zip->close();

            if (!file_exists($path . 'ips.txt')) {
                return new WP_Error(1, 'IPs file not found');
            }

            $ips = explode(PHP_EOL, file_get_contents($path . 'ips.txt'));
            if ($ips[0] != '#WFIPS') {
                return new WP_Error(1, 'IPs file invalid');
            }

            $ips_clean = array();
            foreach ($ips as $ip) {
                if (strpos($ip, '#') !== false) {
                    continue;
                }

                $ip_row = preg_split('/\s+/', $ip);
                $ips_clean[] = trim($ip_row[0]);
            }


            file_put_contents($path . 'ips.txt', implode(PHP_EOL, $ips_clean));

            if (file_exists($path . 'ips.zip')) {
                unlink($path . 'ips.zip');
            }

            return true;
        }
    }

    static function wp_loaded()
    {
        global $pagenow;

        $options = WPCaptcha_Setup::get_options();
        $request = parse_url(rawurldecode($_SERVER['REQUEST_URI']));
        if (!(isset($_GET['action']) && $_GET['action'] === 'postpass' && isset($_POST['post_password']))) {

            if (is_admin() && !is_user_logged_in() && !defined('WP_CLI') && !defined('DOING_AJAX') && !defined('DOING_CRON') && $pagenow !== 'admin-post.php' && $request['path'] !== '/wp-admin/options.php') {
                wp_safe_redirect(self::new_redirect_url());
                die();
            }

            if (!is_user_logged_in() && isset($_GET['wc-ajax']) && $pagenow === 'profile.php') {
                wp_safe_redirect(self::new_redirect_url());
                die();
            }

            if (!is_user_logged_in() && isset($request['path']) && $request['path'] === '/wp-admin/options.php') {
                header('Location: ' . self::new_redirect_url());
                die();
            }

            if ($pagenow === 'wp-login.php' && isset($request['path']) && $request['path'] !== self::trailingslashit($request['path']) && get_option('permalink_structure')) {
                wp_safe_redirect(self::trailingslashit($options['login_url']) . (!empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : ''));
                die();
            } elseif (self::$wp_login_php) {
                if (($referer = wp_get_referer()) && strpos($referer, 'wp-activate.php') !== false && ($referer = parse_url($referer)) && !empty($referer['query'])) {
                    parse_str($referer['query'], $referer);
                    @require_once WPINC . '/ms-functions.php';
                    if (!empty($referer['key']) && ($result = wpmu_activate_signup($referer['key'])) && is_wp_error($result) && ($result->get_error_code() === 'already_active' || $result->get_error_code() === 'blog_taken')) {
                        wp_safe_redirect($options['login_url'] . (!empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : ''));
                        die();
                    }
                } else {
                    header('Location: ' . self::new_redirect_url());
                    die();
                }
                self::wp_template_loader();
            } elseif ($pagenow === 'wp-login.php') {
                global $error, $interim_login, $action, $user_login;
                $requested_redirect_to = '';
                if (isset($_REQUEST['redirect_to'])) {
                    $requested_redirect_to = $_REQUEST['redirect_to'];
                }

                if (is_user_logged_in()) {
                    $user = wp_get_current_user();
                    if (!isset($_REQUEST['action'])) {
                        wp_safe_redirect($requested_redirect_to);
                        die();
                    }
                }
                @require_once ABSPATH . 'wp-login.php';
                die();
            }
        }
    }

    static function wp_template_loader()
    {
        global $pagenow;
        $pagenow = 'index.php';

        if (!defined('WP_USE_THEMES')) {
            define('WP_USE_THEMES', true);
        }

        wp();

        require_once(ABSPATH . WPINC . '/template-loader.php');
        die();
    }

    static function login_compatibility_check()
    {
        if (!function_exists('is_plugin_active') || !function_exists('get_plugin_data')) {
            require_once ABSPATH . 'wp-admin/includes/plugin.php';
        }

        if (is_plugin_active('rename-wp-login/rename-wp-login.php')) {
            return 'Rename wp-login.php';
        }

        if (is_plugin_active('lws-hide-login/lws-hide-login.php')) {
            return 'LWS Hide Login';
        }

        if (is_plugin_active('wps-hide-login/wps-hide-login.php')) {
            return 'WPS Hide Login';
        }

        if (is_plugin_active('change-wp-admin-login/change-wp-admin-login.php')) {
            return 'Change wp-admin login';
        }

        if (is_plugin_active('hide-login-page/hide-login-page.php')) {
            return 'Webcraftic Hide login page';
        }

        if (is_plugin_active('easy-hide-login/wp-hide-login.php')) {
            return 'Easy Hide Login';
        }

        if (is_plugin_active('hide-my-wp/index.php')) {
            return 'Hide My WP Ghost';
        }

        return true;
    }

    static function site_url($url, $path, $scheme, $blog_id)
    {
        $redirect_to = self::filter_wp_login_php($url, $scheme);
        return $redirect_to;

        //return self::filter_wp_login_php($url, $scheme);
    }

    static function wp_redirect($location, $status)
    {
        if (strpos($location, 'https://wordpress.com/wp-login.php') !== false) {
            return $location;
        }

        $redirect_to = self::filter_wp_login_php($location);
        return $redirect_to;
    }

    public function login_url_welcome_email($value)
    {
        $options = WPCaptcha_Setup::get_options();
        return $value = str_replace('wp-login.php', trailingslashit(get_site_option('whl_page', 'login')), $value);
    }

    static function filter_wp_login_php($url, $scheme = null)
    {
        if (strpos($url, 'wp-login.php?action=postpass') !== false) {
            return $url;
        }

        if (strpos($url, 'wp-login.php') !== false && strpos(wp_get_referer(), 'wp-login.php') === false) {
            if (is_ssl()) {
                $scheme = 'https';
            }
            $args = explode('?', $url);
            if (isset($args[1])) {
                parse_str($args[1], $args);
                if (isset($args['login'])) {
                    $args['login'] = rawurlencode($args['login']);
                }
                $url = add_query_arg($args, self::new_login_url($scheme));
            } else {
                $url = self::new_login_url($scheme);
            }
        }
        return $url;
    }

    static function new_login_url($scheme = null)
    {
        $options = WPCaptcha_Setup::get_options();

        $url = apply_filters('wps_hide_login_home_url', home_url('/', $scheme));

        if (get_option('permalink_structure')) {
            return self::trailingslashit($url . $options['login_url']);
        } else {
            return $url . '?' . $options['login_url'];
        }
    }

    static function new_redirect_url($scheme = null)
    {
        $options = WPCaptcha_Setup::get_options();

        if (get_option('permalink_structure')) {
            return self::trailingslashit(home_url('/', $scheme) . $options['login_redirect_url']);
        } else {
            return home_url('/', $scheme) . '?' . $options['login_redirect_url'];
        }
    }

    static function login_url($login_url, $redirect, $force_reauth)
    {
        if (is_404()) {
            return '#';
        }

        if ($force_reauth === false) {
            return $login_url;
        }

        if (empty($redirect)) {
            return $login_url;
        }

        $redirect = explode('?', $redirect);

        if ($redirect[0] === admin_url('options.php')) {
            $login_url = admin_url();
        }

        return $login_url;
    }

    static function override_login_urls()
    {
        global $pagenow;

        $options = WPCaptcha_Setup::get_options();

        if (self::login_compatibility_check() !== true) {
            return false;
        }

        if (empty($options['login_url'])) {
            return false;
        }

        if (!is_multisite() && (strpos(rawurldecode($_SERVER['REQUEST_URI']), 'wp-signup') !== false || strpos(rawurldecode($_SERVER['REQUEST_URI']), 'wp-activate') !== false) && apply_filters('wps_hide_login_signup_enable', false) === false) {
            wp_die(__('This feature is not enabled.', 'advanced-google-recaptcha'));
        }

        $request = parse_url(rawurldecode($_SERVER['REQUEST_URI']));

        if ((strpos(rawurldecode($_SERVER['REQUEST_URI']), 'wp-login.php') !== false || (isset($request['path']) && untrailingslashit($request['path']) === site_url('wp-login', 'relative'))) && !is_admin()) {
            self::$wp_login_php = true;
            $_SERVER['REQUEST_URI'] = self::trailingslashit('/' . str_repeat('-/', 10));
            $pagenow = 'index.php';
        } elseif ((isset($request['path']) && untrailingslashit($request['path']) === home_url($options['login_url'], 'relative')) || (!get_option('permalink_structure') && isset($_GET[$options['login_url']]) && empty($_GET[$options['login_url']]))) {
            $_SERVER['SCRIPT_NAME'] = $options['login_url'];
            $pagenow = 'wp-login.php';
        } elseif ((strpos(rawurldecode($_SERVER['REQUEST_URI']), 'wp-register.php') !== false || (isset($request['path']) && untrailingslashit($request['path']) === site_url('wp-register', 'relative'))) && !is_admin()) {
            self::$wp_login_php = true;
            $_SERVER['REQUEST_URI'] = self::trailingslashit('/' . str_repeat('-/', 10));
            $pagenow = 'index.php';
        }
    }

    public function user_request_action_email_content($email_text, $email_data)
    {
        $options = WPCaptcha_Setup::get_options();
        $email_text = str_replace('###CONFIRM_URL###', esc_url_raw(str_replace(untrailingslashit($options['login_url']) . '/', 'wp-login.php', $email_data['confirm_url'])), $email_text);
        return $email_text;
    }

    public static function site_status_tests($tests)
    {
        unset($tests['async']['loopback_requests']);
        return $tests;
    }

    static function use_trailing_slashes()
    {
        return ('/' === substr(get_option('permalink_structure'), -1, 1));
    }

    static function trailingslashit($string)
    {
        return self::use_trailing_slashes() ? trailingslashit($string) : untrailingslashit($string);
    }

    public static function pretty_fail_errors($error_code)
    {
        switch ($error_code) {
            case 'wpcaptcha_location_blocked':
                return 'Blocked Location';
                break;
            case 'wpcaptcha_fail_count':
                return 'User exceeded maximum number of fails';
                break;
            case 'wpcaptcha_bot':
                return 'Bot';
                break;
            case 'empty_username':
                return 'Empty Username';
                break;
            case 'empty_password':
                return 'Empty Password';
                break;
            case 'incorrect_password':
                return 'Incorrect Password';
                break;
            case 'invalid_username':
                return 'Invalid Username';
                break;
            case 'wpcaptcha_recaptchav2_not_submitted':
                return 'reCAPTCHA v2 not submitted';
                break;
            case 'wpcaptcha_recaptchav3_not_submitted':
                return 'reCAPTCHA v3 not submitted';
                break;
            case 'wpcaptcha_recaptchav2_failed':
                return 'reCAPTCHA v2 failed verification';
                break;
            case 'wpcaptcha_recaptchav3_not_submitted':
                return 'reCAPTCHA v3 failed verification';
                break;
            case 'wpcaptcha_builtin_captcha_failed':
                return 'Built-in captcha failed verification';
                break;
            case 'wpcaptcha_hcaptcha_failed':
                return 'hCaptcha failed verification';
                break;
            case 'wpcaptcha_icons_captcha_failed':
                return 'Icon captcha failed verification';
            default:
                return 'Unknown';
                break;
        }
    }

    static function generate_export_file()
    {
        $filename = str_replace(array('http://', 'https://'), '', home_url());
        $filename = str_replace(array('/', '\\', '.'), '-', $filename);
        $filename .= '-' . date('Y-m-d') . '-wpcaptcha.txt';

        $options = WPCaptcha_Setup::get_options();
        $options_json = json_encode($options);

        header('Content-type: text/txt');
        header('Content-Disposition: attachment; filename=' . $filename);
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . strlen($options_json));

        @ob_end_clean();
        flush();

        echo $options_json;

        exit;
    } // generate_export_file

    static function universal_forms_captcha(){
        $forms_localize = array(
            'selectors_include' => "#primary, .page",
            'selectors_exclude' => "#wpadminbar",
            'ajax_url' => admin_url('admin-ajax.php'),
            'form_ajax_nonce' => wp_create_nonce('wpcaptcha_forms_ajax_nonce'),
        );

        wp_enqueue_script('wpcaptcha-forms', WPCAPTCHA_PLUGIN_URL . 'js/wpcaptcha-forms.js', array('jquery'), self::$version, true);
        wp_localize_script('wpcaptcha-forms', 'wpcaptcha_forms_vars', $forms_localize);
    }

    static function universal_forms_scanner() {
        ob_start(array('WPCaptcha_Functions', 'wpcaptcha_output_filter'));
    }

    static function wpcaptcha_output_filter($html) {
        return preg_replace_callback(
            '/(<form\b[^>]*\bmethod\s*=\s*[\'"]post[\'"][^>]*>)(.*?)(<\/form>)/is',
            array('WPCaptcha_Functions', 'universal_forms_handle_match'),
            $html
        );
    }

    static function universal_forms_handle_match($matches) {
        $options = WPCaptcha_Setup::get_options();
    
        foreach ($options['universal_captcha_forms'] as $form_id => $required_fields) {
            if (self::universal_forms_fields_match($matches[2], $required_fields)) {
                return self:: universal_forms_inject_captcha($matches[2], $matches[1], $matches[3]);
            }
        }
    
        return $matches[1] . $matches[2] . $matches[3];
    }

    public static function universal_forms_inject_captcha($formContents, $formOpen = '', $formClose = '') {
        
        $captchaHtml = self::captcha_fields() . self::login_scripts();

        // Inject CAPTCHA before the first submit button
        $formContents = preg_replace(
            '/(<input[^>]+type=[\'"]?submit[\'"]?[^>]*>|<button[^>]+type=[\'"]?submit[\'"]?[^>]*>.*?<\/button>)/i',
            $captchaHtml . '$1',
            $formContents,
            1
        );

        return $formOpen . $formContents . $formClose;
    }

    public static function universal_forms_post_match($post, $required_fields) {
        if(!isset($post) || empty($post)){
            return false;
        }
        
        if(empty($required_fields) || !is_array($required_fields)){
            return false;
        }

        foreach ($required_fields as $field) {
            if (!isset($post[$field])) {
                return false;
            }
        }
        return true;
    }
    
    public static function universal_forms_fields_match($formHtml, $required_fields) {
        foreach ($required_fields as $field) {
            if (1 !== preg_match('/name=[\'"]' . preg_quote($field, '/') . '[\'"]/', $formHtml)) {
                return false;
            }
        }
        return true;
    }

    static function handle_captcha_universal(){
        if(!isset($_POST) || empty($_POST)){
            return true;
        }
        
        $options = WPCaptcha_Setup::get_options();
        if(empty($options['universal_captcha_forms'])){
            return true;
        }
        
        $is_captcha_protected = false;
         
        foreach ($options['universal_captcha_forms'] as $form_id => $required_fields) {
            if(self::universal_forms_post_match($_POST, $required_fields)){
                $is_captcha_protected = true;
            }
        }   

        if($is_captcha_protected){
            $captcha = self::handle_captcha();

            if (is_wp_error($captcha)) {
                echo $captcha->get_error_message();
                die();
            }
        } else {
            return true;
        }
    }
} // class
Page not found – Hello World !