| 1 |
<?php |
| 2 |
|
| 3 |
if (!defined('ABSPATH')) die('No direct access.'); |
| 4 |
|
| 5 |
/** |
| 6 |
* Purpose of this class: abstract out code handling integrations with login forms |
| 7 |
*/ |
| 8 |
|
| 9 |
class Simba_TFA_Login_Form_Integrations { |
| 10 |
|
| 11 |
// Main class |
| 12 |
private $tfa; |
| 13 |
|
| 14 |
/** |
| 15 |
* Plugin constructor |
| 16 |
* |
| 17 |
* @param Object $tfa |
| 18 |
*/ |
| 19 |
public function __construct($tfa) { |
| 20 |
|
| 21 |
$this->tfa = $tfa; |
| 22 |
|
| 23 |
$enqueue_upon_actions = array( |
| 24 |
// This is needed for the login form on the dedicated payment page (e.g. /checkout/order-pay/123456/?pay_for_order=true&key=wc_order_blahblahblah) |
| 25 |
'woocommerce_login_form_start', |
| 26 |
'woocommerce_before_customer_login_form', |
| 27 |
// The login form on the checkout doesn't call the woocommerce_before_customer_login_form action |
| 28 |
'woocommerce_before_checkout_form', |
| 29 |
'affwp_login_fields_before', |
| 30 |
); |
| 31 |
|
| 32 |
foreach ($enqueue_upon_actions as $action) { |
| 33 |
add_action($action, array($this->tfa, 'login_enqueue_scripts')); |
| 34 |
} |
| 35 |
|
| 36 |
if (!defined('TWO_FACTOR_DISABLE') || !TWO_FACTOR_DISABLE) { |
| 37 |
add_action('affwp_process_login_form', array($this, 'affwp_process_login_form')); |
| 38 |
} |
| 39 |
|
| 40 |
add_filter('tml_display', array($this, 'tml_display')); |
| 41 |
add_filter('wppb_login_form_bottom', array($this, 'pb_login_form')); |
| 42 |
|
| 43 |
// We want to run first if possible, so that we're not aborted by JavaScript exceptions in other components (our code is critical to the login process for TFA users) |
| 44 |
// Unfortunately, though, people start enqueuing from init onwards (before that is buggy - https://core.trac.wordpress.org/ticket/11526), so, we try to detect the login page and go earlier there. |
| 45 |
if (isset($GLOBALS['pagenow']) && 'wp-login.php' === $GLOBALS['pagenow']) { |
| 46 |
add_action('init', array($this->tfa, 'login_enqueue_scripts'), -99999999999); |
| 47 |
} else { |
| 48 |
add_action('login_enqueue_scripts', array($this->tfa, 'login_enqueue_scripts'), -99999999999); |
| 49 |
} |
| 50 |
|
| 51 |
add_filter('do_shortcode_tag', array($this, 'do_shortcode_tag'), 10, 2); |
| 52 |
|
| 53 |
add_filter('simba_tfa_login_enqueue_localize', array($this, 'simba_tfa_login_enqueue_localize'), 9); |
| 54 |
|
| 55 |
add_filter('edd_errors', array($this, 'edd_errors')); |
| 56 |
} |
| 57 |
|
| 58 |
/** |
| 59 |
* Catch TML login widgets (other TML login forms already trigger) |
| 60 |
* |
| 61 |
* @param Mixed $whatever |
| 62 |
* |
| 63 |
* @return Mixed |
| 64 |
*/ |
| 65 |
public function tml_display($whatever) { |
| 66 |
$this->tfa->login_enqueue_scripts(); |
| 67 |
return $whatever; |
| 68 |
} |
| 69 |
|
| 70 |
/** |
| 71 |
* Catch Profile Builder login form |
| 72 |
* |
| 73 |
* @param Mixed $whatever |
| 74 |
* |
| 75 |
* @return Mixed |
| 76 |
*/ |
| 77 |
public function pb_login_form($whatever) { |
| 78 |
$this->tfa->login_enqueue_scripts(); |
| 79 |
return $whatever; |
| 80 |
} |
| 81 |
|
| 82 |
/** |
| 83 |
* Runs upon the WP filter simba_tfa_login_enqueue_localize. |
| 84 |
* |
| 85 |
* @param Array $localize |
| 86 |
* |
| 87 |
* @return Array |
| 88 |
*/ |
| 89 |
public function simba_tfa_login_enqueue_localize($localize) { |
| 90 |
// WP login form is #loginform |
| 91 |
// Ultimate Membership Pro - April 2018 |
| 92 |
// Theme My Login 6.x - .tml-login form[name="loginform"] |
| 93 |
// Theme My Login 7.x - .tml-login form[name="login"] (July 2018) |
| 94 |
// WP Members - March 2018 |
| 95 |
// bbPress - June 2021 |
| 96 |
// WooCommerce - ported over from the separate wooextend.js code, June 2021 |
| 97 |
// Affiliates WP - ported over from the separate wooextend.js code, June 2021 |
| 98 |
// Easy Digital Downloads(EDD) - November 2025 |
| 99 |
$localize['login_form_selectors'] .= '.tml-login form[name="loginform"], .tml-login form[name="login"], #loginform, #wpmem_login form, form#ihc_login_form, .bbp-login-form, .woocommerce form.login, #affwp-login-form, #wppb-loginform, form#edd_login_form'; |
| 100 |
$localize['login_form_off_selectors'] .= '#ihc_login_form'; |
| 101 |
return $localize; |
| 102 |
} |
| 103 |
|
| 104 |
/** |
| 105 |
* Runs upon the WP action affwp_process_login_form |
| 106 |
*/ |
| 107 |
public function affwp_process_login_form() { |
| 108 |
|
| 109 |
if (!function_exists('affiliate_wp')) return; |
| 110 |
|
| 111 |
$affiliate_wp = affiliate_wp(); |
| 112 |
$login = $affiliate_wp->login; |
| 113 |
|
| 114 |
$params = array( |
| 115 |
// phpcs:ignore WordPress.Security.NonceVerification -- No nonce. |
| 116 |
'log' => isset($_POST['affwp_user_login']) ? sanitize_user(wp_unslash($_POST['affwp_user_login'])): '', |
| 117 |
|
| 118 |
$request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '', |
| 119 |
'caller'=> isset($_SERVER['PHP_SELF']) ? sanitize_text_field(wp_unslash($_SERVER['PHP_SELF'])) : $request_uri, |
| 120 |
// phpcs:ignore WordPress.Security.NonceVerification -- No nonce. |
| 121 |
'two_factor_code' => isset($_POST['two_factor_code']) ? sanitize_text_field(wp_unslash((string) $_POST['two_factor_code'])) : '', |
| 122 |
); |
| 123 |
$code_ok = $this->tfa->authorise_user_from_login($params, true); |
| 124 |
|
| 125 |
$code_ok = apply_filters('simbatfa_affwp_process_login_form_auth_result', $code_ok, $params); |
| 126 |
|
| 127 |
if (is_wp_error($code_ok)) { |
| 128 |
$login->add_error($code_ok->get_error_code(), $code_ok->get_error_message()); |
| 129 |
} elseif (!$code_ok) { |
| 130 |
$login->add_error('authentication_failed', __('Error:', 'two-factor-authentication').' '.apply_filters('simba_tfa_message_code_incorrect', __('The one-time password (TFA code) you entered was incorrect.', 'two-factor-authentication'))); |
| 131 |
} |
| 132 |
|
| 133 |
} |
| 134 |
|
| 135 |
/** |
| 136 |
* Ultimate Membership Pro support |
| 137 |
* |
| 138 |
* @param String $output |
| 139 |
* @param String $tag |
| 140 |
* |
| 141 |
* @return String |
| 142 |
*/ |
| 143 |
public function do_shortcode_tag($output, $tag) { |
| 144 |
// Enqueue TFA scripts for supported login shortcodes. |
| 145 |
$supported_shortcodes = array('ihc-login-form', 'edd_login'); |
| 146 |
|
| 147 |
if (in_array($tag, $supported_shortcodes)) { |
| 148 |
$this->tfa->login_enqueue_scripts(); |
| 149 |
} |
| 150 |
return $output; |
| 151 |
} |
| 152 |
|
| 153 |
/** |
| 154 |
* Filters Easy Digital Downloads (EDD) error messages. |
| 155 |
* |
| 156 |
* Removes the default EDD invalid login error when a Two-Factor Authentication (TFA) |
| 157 |
* authentication error is already present. This prevents conflicting error messages |
| 158 |
* from being displayed on the EDD login form. |
| 159 |
* |
| 160 |
* @param array $errors Array of EDD error messages. |
| 161 |
* |
| 162 |
* @return array |
| 163 |
*/ |
| 164 |
public function edd_errors($errors) { |
| 165 |
// Remove default EDD login error if a TFA authentication error exists. |
| 166 |
if (!empty($errors) && isset($errors['authentication_failed'])) { |
| 167 |
unset($errors['edd_invalid_login']); |
| 168 |
} |
| 169 |
return $errors; |
| 170 |
} |
| 171 |
} |
| 172 |
|