Changeset 2124103
- Timestamp:
- 07/16/2019 05:26:35 PM (7 years ago)
- Location:
- wordfence-login-security
- Files:
-
- 44 added
- 36 deleted
- 26 edited
- 1 copied
-
tags/1.0.3 (copied) (copied from wordfence-login-security/trunk)
-
tags/1.0.3/classes/controller/ajax.php (modified) (3 diffs)
-
tags/1.0.3/classes/controller/captcha.php (modified) (1 diff)
-
tags/1.0.3/classes/controller/db.php (modified) (1 diff)
-
tags/1.0.3/classes/controller/settings.php (modified) (7 diffs)
-
tags/1.0.3/classes/controller/time.php (modified) (1 diff)
-
tags/1.0.3/classes/controller/users.php (modified) (1 diff)
-
tags/1.0.3/classes/controller/wordfencels.php (modified) (7 diffs)
-
tags/1.0.3/classes/model/settings/db.php (modified) (1 diff)
-
tags/1.0.3/css/admin-global.1559237323.css (deleted)
-
tags/1.0.3/css/admin-global.1563297209.css (added)
-
tags/1.0.3/css/admin.1559237323.css (deleted)
-
tags/1.0.3/css/admin.1563297209.css (added)
-
tags/1.0.3/css/colorbox.1559237323.css (deleted)
-
tags/1.0.3/css/colorbox.1563297209.css (added)
-
tags/1.0.3/css/font-awesome.1559237323.css (deleted)
-
tags/1.0.3/css/font-awesome.1563297209.css (added)
-
tags/1.0.3/css/ionicons.1559237323.css (deleted)
-
tags/1.0.3/css/ionicons.1563297209.css (added)
-
tags/1.0.3/css/jquery-ui-timepicker-addon.1559237323.css (deleted)
-
tags/1.0.3/css/jquery-ui-timepicker-addon.1563297209.css (added)
-
tags/1.0.3/css/jquery-ui.min.1559237323.css (deleted)
-
tags/1.0.3/css/jquery-ui.min.1563297209.css (added)
-
tags/1.0.3/css/jquery-ui.structure.min.1559237323.css (deleted)
-
tags/1.0.3/css/jquery-ui.structure.min.1563297209.css (added)
-
tags/1.0.3/css/jquery-ui.theme.min.1559237323.css (deleted)
-
tags/1.0.3/css/jquery-ui.theme.min.1563297209.css (added)
-
tags/1.0.3/css/login.1559237323.css (deleted)
-
tags/1.0.3/css/login.1563297209.css (added)
-
tags/1.0.3/css/wfselect2.min.1563297209.css (added)
-
tags/1.0.3/js/Chart.bundle.min.1563297209.js (added)
-
tags/1.0.3/js/admin-global.1559237323.js (deleted)
-
tags/1.0.3/js/admin-global.1563297209.js (added)
-
tags/1.0.3/js/admin.1559237323.js (deleted)
-
tags/1.0.3/js/admin.1563297209.js (added)
-
tags/1.0.3/js/jquery-ui-timepicker-addon.1559237323.js (deleted)
-
tags/1.0.3/js/jquery-ui-timepicker-addon.1563297209.js (added)
-
tags/1.0.3/js/jquery.colorbox.1559237323.js (deleted)
-
tags/1.0.3/js/jquery.colorbox.1563297209.js (added)
-
tags/1.0.3/js/jquery.colorbox.min.1559237323.js (deleted)
-
tags/1.0.3/js/jquery.colorbox.min.1563297209.js (added)
-
tags/1.0.3/js/jquery.qrcode.min.1559237323.js (deleted)
-
tags/1.0.3/js/jquery.qrcode.min.1563297209.js (added)
-
tags/1.0.3/js/jquery.tmpl.min.1559237323.js (deleted)
-
tags/1.0.3/js/jquery.tmpl.min.1563297209.js (added)
-
tags/1.0.3/js/login.1559237323.js (deleted)
-
tags/1.0.3/js/login.1563297209.js (added)
-
tags/1.0.3/js/wfselect2.min.1563297209.js (added)
-
tags/1.0.3/readme.txt (modified) (2 diffs)
-
tags/1.0.3/views/options/option-captcha-threshold.php (added)
-
tags/1.0.3/views/options/option-captcha.php (modified) (2 diffs)
-
tags/1.0.3/views/options/option-require-2fa.php (modified) (1 diff)
-
tags/1.0.3/views/settings/options.php (modified) (3 diffs)
-
tags/1.0.3/wordfence-login-security.php (modified) (2 diffs)
-
trunk/classes/controller/ajax.php (modified) (3 diffs)
-
trunk/classes/controller/captcha.php (modified) (1 diff)
-
trunk/classes/controller/db.php (modified) (1 diff)
-
trunk/classes/controller/settings.php (modified) (7 diffs)
-
trunk/classes/controller/time.php (modified) (1 diff)
-
trunk/classes/controller/users.php (modified) (1 diff)
-
trunk/classes/controller/wordfencels.php (modified) (7 diffs)
-
trunk/classes/model/settings/db.php (modified) (1 diff)
-
trunk/css/admin-global.1559237323.css (deleted)
-
trunk/css/admin-global.1563297209.css (added)
-
trunk/css/admin.1559237323.css (deleted)
-
trunk/css/admin.1563297209.css (added)
-
trunk/css/colorbox.1559237323.css (deleted)
-
trunk/css/colorbox.1563297209.css (added)
-
trunk/css/font-awesome.1559237323.css (deleted)
-
trunk/css/font-awesome.1563297209.css (added)
-
trunk/css/ionicons.1559237323.css (deleted)
-
trunk/css/ionicons.1563297209.css (added)
-
trunk/css/jquery-ui-timepicker-addon.1559237323.css (deleted)
-
trunk/css/jquery-ui-timepicker-addon.1563297209.css (added)
-
trunk/css/jquery-ui.min.1559237323.css (deleted)
-
trunk/css/jquery-ui.min.1563297209.css (added)
-
trunk/css/jquery-ui.structure.min.1559237323.css (deleted)
-
trunk/css/jquery-ui.structure.min.1563297209.css (added)
-
trunk/css/jquery-ui.theme.min.1559237323.css (deleted)
-
trunk/css/jquery-ui.theme.min.1563297209.css (added)
-
trunk/css/login.1559237323.css (deleted)
-
trunk/css/login.1563297209.css (added)
-
trunk/css/wfselect2.min.1563297209.css (added)
-
trunk/js/Chart.bundle.min.1563297209.js (added)
-
trunk/js/admin-global.1559237323.js (deleted)
-
trunk/js/admin-global.1563297209.js (added)
-
trunk/js/admin.1559237323.js (deleted)
-
trunk/js/admin.1563297209.js (added)
-
trunk/js/jquery-ui-timepicker-addon.1559237323.js (deleted)
-
trunk/js/jquery-ui-timepicker-addon.1563297209.js (added)
-
trunk/js/jquery.colorbox.1559237323.js (deleted)
-
trunk/js/jquery.colorbox.1563297209.js (added)
-
trunk/js/jquery.colorbox.min.1559237323.js (deleted)
-
trunk/js/jquery.colorbox.min.1563297209.js (added)
-
trunk/js/jquery.qrcode.min.1559237323.js (deleted)
-
trunk/js/jquery.qrcode.min.1563297209.js (added)
-
trunk/js/jquery.tmpl.min.1559237323.js (deleted)
-
trunk/js/jquery.tmpl.min.1563297209.js (added)
-
trunk/js/login.1559237323.js (deleted)
-
trunk/js/login.1563297209.js (added)
-
trunk/js/wfselect2.min.1563297209.js (added)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/views/options/option-captcha-threshold.php (added)
-
trunk/views/options/option-captcha.php (modified) (2 diffs)
-
trunk/views/options/option-require-2fa.php (modified) (1 diff)
-
trunk/views/settings/options.php (modified) (3 diffs)
-
trunk/wordfence-login-security.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
wordfence-login-security/tags/1.0.3/classes/controller/ajax.php
r2098090 r2124103 73 73 'required_parameters' => array('nonce', 'id'), 74 74 ), 75 'reset_recaptcha_stats' => array( 76 'handler' => array($this, '_ajax_reset_recaptcha_stats_callback'), 77 'permissions' => array(Controller_Permissions::CAP_MANAGE_SETTINGS => __('You do not have permission to reset reCAPTCHA statistics.', 'wordfence-2fa')), 78 'required_parameters' => array('nonce'), 79 ), 75 80 ); 76 81 … … 400 405 foreach ($admins as $a) { 401 406 /** @var \WP_User $a */ 402 if ( !Controller_Users::shared()->has_2fa_active($a)) {407 if (Controller_Users::shared()->has_2fa_active($a)) { 403 408 continue; 404 409 } … … 447 452 Controller_Notices::shared()->remove_notice($_POST['id'], false, wp_get_current_user()); 448 453 } 454 455 public function _ajax_reset_recaptcha_stats_callback() { 456 Controller_Settings::shared()->set_array(Controller_Settings::OPTION_CAPTCHA_STATS, array('counts' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 'avg' => 0)); 457 $response = array('success' => true); 458 return die(json_encode($response)); 459 } 449 460 } -
wordfence-login-security/tags/1.0.3/classes/controller/captcha.php
r2098090 r2124103 112 112 */ 113 113 public function is_human($score) { 114 if (Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_CAPTCHA_TEST_MODE)) { 115 return true; 116 } 117 114 118 $threshold = $this->threshold(); 115 119 return ($score >= $threshold || abs($score - $threshold) < 0.0001); -
wordfence-login-security/tags/1.0.3/classes/controller/db.php
r2098090 r2124103 59 59 } 60 60 61 public function uninstall() { 62 $tables = array(self::TABLE_2FA_SECRETS, self::TABLE_SETTINGS); 63 foreach ($tables as $table) { 64 global $wpdb; 65 $wpdb->query('DROP TABLE IF EXISTS `' . self::network_table($table) . '`'); 66 } 67 } 68 61 69 protected function _create_schema() { 62 70 $tables = array( -
wordfence-login-security/tags/1.0.3/classes/controller/settings.php
r2098090 r2124103 19 19 const OPTION_ALLOW_XML_RPC = 'allow-xml-rpc'; 20 20 const OPTION_ENABLE_AUTH_CAPTCHA = 'enable-auth-captcha'; 21 const OPTION_CAPTCHA_TEST_MODE = 'recaptcha-test-mode'; 21 22 const OPTION_RECAPTCHA_SITE_KEY = 'recaptcha-site-key'; 22 23 const OPTION_RECAPTCHA_SECRET = 'recaptcha-secret'; 23 24 const OPTION_RECAPTCHA_THRESHOLD = 'recaptcha-threshold'; 25 const OPTION_DELETE_ON_DEACTIVATION = 'delete-deactivation'; 24 26 25 27 //Internal … … 31 33 const OPTION_SHARED_SYMMETRIC_SECRET_KEY = 'shared-symmetric-secret'; 32 34 const OPTION_DISMISSED_FRESH_INSTALL_MODAL = 'dismissed-fresh-install-modal'; 35 const OPTION_CAPTCHA_STATS = 'captcha-stats'; 33 36 34 37 protected $_settingsStorage; … … 67 70 self::OPTION_ALLOW_XML_RPC => array('value' => true, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false), 68 71 self::OPTION_ENABLE_AUTH_CAPTCHA => array('value' => false, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false), 72 self::OPTION_CAPTCHA_STATS => array('value' => '{"counts":[0,0,0,0,0,0,0,0,0,0,0],"avg":0}', 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false), 69 73 self::OPTION_RECAPTCHA_THRESHOLD => array('value' => 0.5, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false), 70 74 self::OPTION_LAST_SECRET_REFRESH => array('value' => 0, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false), 75 self::OPTION_DELETE_ON_DEACTIVATION => array('value' => false, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false), 71 76 )); 72 77 } … … 130 135 case self::OPTION_ALLOW_XML_RPC: 131 136 case self::OPTION_ENABLE_AUTH_CAPTCHA: 137 case self::OPTION_CAPTCHA_TEST_MODE: 132 138 case self::OPTION_DISMISSED_FRESH_INSTALL_MODAL: 139 case self::OPTION_DELETE_ON_DEACTIVATION: 133 140 return true; 134 141 … … 139 146 //Array 140 147 case self::OPTION_GLOBAL_NOTICES: 148 case self::OPTION_CAPTCHA_STATS: 141 149 return preg_match('/^\[.*\]$/', $value) || preg_match('/^\{.*\}$/', $value); //Only a rough JSON validation 142 150 … … 166 174 case self::OPTION_RECAPTCHA_THRESHOLD: 167 175 return is_numeric($value) && $value >= 0 && $value <= 1; 176 case self::OPTION_RECAPTCHA_SITE_KEY: 177 if (empty($value)) { 178 return true; 179 } 180 181 $response = wp_remote_get('https://www.google.com/recaptcha/api.js?render=' . urlencode($value)); 182 183 if (!is_wp_error($response)) { 184 $status = wp_remote_retrieve_response_code($response); 185 if ($status == 200) { 186 return true; 187 } 188 189 $data = wp_remote_retrieve_body($response); 190 if (strpos($data, 'grecaptcha') === false) { 191 return __('Unable to validate the reCAPTCHA site key. Please check the key and try again.', 'wordfence-2fa'); 192 } 193 return true; 194 } 195 return sprintf(__('An error was encountered while validating the reCAPTCHA site key: %s', 'wordfence-2fa'), $response->get_error_message()); 168 196 } 169 197 return true; … … 202 230 case self::OPTION_ALLOW_XML_RPC: 203 231 case self::OPTION_ENABLE_AUTH_CAPTCHA: 232 case self::OPTION_CAPTCHA_TEST_MODE: 204 233 case self::OPTION_DISMISSED_FRESH_INSTALL_MODAL: 234 case self::OPTION_DELETE_ON_DEACTIVATION: 205 235 return $this->_truthy_to_bool($value); 206 236 -
wordfence-login-security/tags/1.0.3/classes/controller/time.php
r2098090 r2124103 96 96 foreach ($servers as $s) { 97 97 $socket = @fsockopen('udp://' . $s, 123, $err_no, $err_str, 1); 98 stream_set_timeout($socket, 1);99 98 if ($socket) { 99 stream_set_timeout($socket, 1); 100 100 $remote_originate = microtime(true); 101 101 $secondsNTP = ((int) $remote_originate) + self::NTP_EPOCH_CONVERT; -
wordfence-login-security/tags/1.0.3/classes/controller/users.php
r2098090 r2124103 312 312 313 313 /** 314 * Records the reCAPTCHA score for later display. 315 * 316 * This is not atomic, which means this can miscount on hits that overlap, but the overhead of being atomic is not 317 * worth it for our use. 318 * 319 * @param \WP_User $user|null 320 * @param float $score 321 */ 322 public function record_captcha_score($user, $score) { 323 if (!Controller_CAPTCHA::shared()->enabled()) { return; } 324 if ($this->has_2fa_active($user)) { return; } //2FA activated users do not retrieve a score 325 326 if ($user) { update_user_meta($user->ID, 'wfls-last-captcha-score', $score); } 327 $stats = Controller_Settings::shared()->get_array(Controller_Settings::OPTION_CAPTCHA_STATS); 328 $int_score = min(max((int) ($score * 10), 0), 10); 329 $count = array_sum($stats['counts']); 330 $stats['counts'][$int_score]++; 331 $stats['avg'] = ($stats['avg'] * $count + $int_score) / ($count + 1); 332 Controller_Settings::shared()->set_array(Controller_Settings::OPTION_CAPTCHA_STATS, $stats); 333 } 334 335 /** 314 336 * Returns the active and inactive user counts. 315 337 * -
wordfence-login-security/tags/1.0.3/classes/controller/wordfencels.php
r2098090 r2124103 125 125 } 126 126 } 127 128 if (Controller_Settings::shared()->get_bool(Controller_Settings::OPTION_CAPTCHA_TEST_MODE) && Controller_CAPTCHA::shared()->enabled() && Controller_Permissions::shared()->can_manage_settings()) { 129 if (is_multisite()) { 130 add_action('network_admin_notices', array($this, '_recaptcha_test_notice')); 131 } 132 else { 133 add_action('admin_notices', array($this, '_recaptcha_test_notice')); 134 } 135 } 127 136 } 128 137 … … 135 144 } 136 145 146 public function _recaptcha_test_notice() { 147 echo '<div class="notice notice-warning"><p>' . sprintf(__('reCAPTCHA test mode is enabled. While enabled, login and registration requests will be checked for their score but will not be blocked if the score is below the minimum score. <a href="%s">Manage Settings</a>', 'wordfence-2fa'), esc_url(network_admin_url('admin.php?page=WFLS#top#settings'))) . '</p></div>'; 148 } 149 137 150 /** 138 151 * Installation/Uninstallation … … 151 164 } 152 165 delete_option($opt); 166 } 167 168 if (Controller_Settings::shared()->get_bool(Controller_Settings::OPTION_DELETE_ON_DEACTIVATION)) { 169 Controller_DB::shared()->uninstall(); 153 170 } 154 171 } … … 243 260 } 244 261 wp_enqueue_script('wordfence-ls-admin', Model_Asset::js('admin.js'), array('jquery'), WORDFENCE_LS_VERSION); 262 if (!WORDFENCE_LS_FROM_CORE) { 263 wp_register_script('chart-js', Model_Asset::js('Chart.bundle.min.js'), array('jquery'), '2.4.0'); 264 wp_register_script('wordfence-select2-js', Model_Asset::js('wfselect2.min.js'), array('jquery'), WORDFENCE_LS_VERSION); 265 wp_register_style('wordfence-select2-css', Model_Asset::css('wfselect2.min.css'), array(), WORDFENCE_LS_VERSION); 266 } 267 wp_enqueue_script('chart-js'); 268 wp_enqueue_script('wordfence-select2-js'); 269 wp_enqueue_style('wordfence-select2-css'); 245 270 wp_enqueue_style('wordfence-ls-admin', Model_Asset::css('admin.css'), array(), WORDFENCE_LS_VERSION); 246 271 wp_enqueue_style('wordfence-ls-colorbox', Model_Asset::css('colorbox.css'), array(), WORDFENCE_LS_VERSION); 247 272 wp_enqueue_style('wordfence-ls-ionicons', Model_Asset::css('ionicons.css'), array(), WORDFENCE_LS_VERSION); 273 if (!WORDFENCE_LS_FROM_CORE) { wp_enqueue_style('wordfence-ls-font-awesome', Model_Asset::css('font-awesome.css'), array(), WORDFENCE_LS_VERSION); } 248 274 wp_localize_script('wordfence-ls-admin', 'WFLSVars', array( 249 275 'ajaxurl' => admin_url('admin-ajax.php'), … … 400 426 } 401 427 402 update_user_meta($user->ID, 'wfls-last-captcha-score', $score);428 Controller_Users::shared()->record_captcha_score($user, $score); 403 429 404 430 if (isset($_REQUEST['wfls-email-verification']) && !empty($_REQUEST['wfls-email-verification']) && is_string($_REQUEST['wfls-email-verification'])) { … … 422 448 $encrypted = Model_Symmetric::encrypt((string) $user->ID); 423 449 if ($encrypted) { 424 $jwt = new Model_JWT(array('user' => $encrypted), Controller_Time::time() + 60 * 15 /* minutes */);450 $jwt = new Model_JWT(array('user' => $encrypted), Controller_Time::time() + 60 * WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES); 425 451 $view = new Model_View('email/login-verification', array( 426 452 'siteName' => get_bloginfo('name', 'raw'), … … 618 644 619 645 if ($requireCAPTCHA) { 646 Controller_Users::shared()->record_captcha_score(null, $score); 647 620 648 if (!Controller_CAPTCHA::shared()->is_human($score)) { //Score is below the human threshold, block the user registration 621 649 $encryptedIP = Model_Symmetric::encrypt(Model_Request::current()->ip()); -
wordfence-login-security/tags/1.0.3/classes/model/settings/db.php
r2098090 r2124103 26 26 if ($wpdb->query($wpdb->prepare("INSERT INTO `{$table}` (`name`, `value`, `autoload`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`), `autoload` = VALUES(`autoload`)", $key, $value, $autoload)) !== false && $autoload != self::AUTOLOAD_NO) { 27 27 $this->_update_cached($key, $value); 28 do_action('wfls_settings_set', $key, $value); 28 29 } 29 30 } -
wordfence-login-security/tags/1.0.3/readme.txt
r2098090 r2124103 1 1 === Wordfence Login Security === 2 Contributors: wfryan 2 Contributors: wfryan, wfmattr, mmaunder, wfmatt 3 3 Tags: security, login security, 2fa, two factor authentication, captcha, xml-rpc, mfa, 2 factor 4 4 Requires at least: 4.5 5 5 Requires PHP: 5.3 6 6 Tested up to: 5.2 7 Stable tag: 1.0. 27 Stable tag: 1.0.3 8 8 9 9 Secure your website with Wordfence Login Security, providing two-factor authentication, login and registration CAPTCHA, and XML-RPC protection. … … 59 59 == Changelog == 60 60 61 = 1.0.3 - July 16, 2019 = 62 * Improvement: Added additional information about reCAPTCHA to its setting control. 63 * Improvement: Added a constant that may be overridden to customize the expiration time of login verification email links. 64 * Improvement: reCAPTCHA keys are now tested on saving to prevent accidentally inputting a v2 key. 65 * Improvement: Added a setting to control the reCAPTCHA human/bot threshold. 66 * Improvement: Added an option to trigger removal of Login Security tables and data on deactivation. 67 * Improvement: Reworked the reCAPTCHA implementation to trigger the token check on login/registration form submission to avoid the token expiring. 68 * Fix: Widened the reCAPTCHA key fields to allow the full keys to be visible. 69 * Fix: Addressed an issue when outbound UDP connections are blocked where the NTP check could log an error. 70 * Fix: Added handling for reCAPTCHA's JavaScript failing to load, which previously blocked logging in. 71 * Fix: Fixed the functionality of the button to send 2FA grace period notifications. 72 * Fix: Fixed a missing icon for some help links when running in standalone mode. 73 61 74 = 1.0.2 - May 30, 2019 = 62 75 * Initial release -
wordfence-login-security/tags/1.0.3/views/options/option-captcha.php
r2098090 r2124103 18 18 <ul class="wfls-flex-vertical wfls-flex-align-left"> 19 19 <li> 20 <strong id="wfls-enable-auth-captcha-label"><?php _e('Enable reCAPTCHA on the login and user registration pages', 'wordfence- 2fa'); ?></strong>20 <strong id="wfls-enable-auth-captcha-label"><?php _e('Enable reCAPTCHA on the login and user registration pages', 'wordfence-ls'); ?></strong> 21 21 </li> 22 <li class="wfls-option-subtitle"><?php _e('Note: This feature requires a free site key and secret for the <a href="https://www.google.com/recaptcha/intro/v3.html" target="_blank" rel="noopener noreferrer">Google reCAPTCHA v3 Service</a>.', 'wordfence-2fa'); ?></li>22 <li class="wfls-option-subtitle"><?php printf(__('reCAPTCHA v3 does not make users solve puzzles or click a checkbox like previous versions. The only visible part is the reCAPTCHA logo. If a visitor\'s browser fails the CAPTCHA, Wordfence will send an email to the user\'s address with a link they can click to verify that they are a user of your site. You can read further details <a href="%s" target="_blank" rel="noopener noreferrer">in our documentation</a>.', 'wordfence-ls'), \WordfenceLS\Controller_Support::esc_supportURL(\WordfenceLS\Controller_Support::ITEM_MODULE_LOGIN_SECURITY_CAPTCHA)); ?></li> 23 23 </ul> 24 24 </li> … … 31 31 <table> 32 32 <tr class="wfls-option wfls-option-text" data-original-value="<?php echo esc_attr($siteKeyValue); ?>" data-text-option="<?php echo esc_attr($siteKeyOptionName); ?>"> 33 <th id="wfls-enable-captcha-site-key-label" class="wfls-padding-add-bottom"><?php _e('reCAPTCHA v3 Site Key', 'wordfence '); ?></th>33 <th id="wfls-enable-captcha-site-key-label" class="wfls-padding-add-bottom"><?php _e('reCAPTCHA v3 Site Key', 'wordfence-ls'); ?></th> 34 34 <td class="wfls-option-text wfls-padding-add-bottom"><input type="text" name="recaptchaSiteKey" id="input-recaptchaSiteKey" class="wfls-form-control" value="<?php echo esc_attr($siteKeyValue); ?>"<?php if (!$currentEnableValue) { echo ' disabled'; } ?>></td> 35 35 </tr> 36 36 <tr class="wfls-option wfls-option-text" data-original-value="<?php echo esc_attr($secretValue); ?>" data-text-option="<?php echo esc_attr($secretOptionName); ?>"> 37 <th id="wfls-enable-captcha-secret-label"><?php _e('reCAPTCHA v3 Secret', 'wordfence '); ?></th>37 <th id="wfls-enable-captcha-secret-label"><?php _e('reCAPTCHA v3 Secret', 'wordfence-ls'); ?></th> 38 38 <td class="wfls-option-text"><input type="text" name="recaptchaSecret" id="input-recaptchaSecret" class="wfls-form-control" value="<?php echo esc_attr($secretValue); ?>"<?php if (!$currentEnableValue) { echo ' disabled'; } ?>></td> 39 39 </tr> 40 40 </table> 41 </li> 42 </ul> 43 <ul class="wfls-option wfls-padding-no-top"> 44 <li class="wfls-option-spacer"></li> 45 <li class="wfls-option-title"> 46 <ul class="wfls-flex-vertical wfls-flex-align-left"> 47 <li class="wfls-option-subtitle"><?php _e('Note: This feature requires a free site key and secret for the <a href="https://www.google.com/recaptcha/intro/v3.html" target="_blank" rel="noopener noreferrer">Google reCAPTCHA v3 Service</a>.', 'wordfence-ls'); ?></li> 48 </ul> 41 49 </li> 42 50 </ul> -
wordfence-login-security/tags/1.0.3/views/options/option-require-2fa.php
r2098090 r2124103 54 54 <span id="wfls-require-2fa-grace-period-label" class="wfls-padding-add-left wfls-padding-add-right"><?php _e('Grace period to require 2FA', 'wordfence'); ?> </span> 55 55 <input type="text" name="require2FAGracePeriod" id="input-require2FAGracePeriod" class="wfls-datetime wfls-form-control" placeholder="Enabled on..." data-value="<?php echo $currentGracePeriodDateValue; ?>" data-original-value="<?php echo $currentGracePeriodDateValue; ?>"<?php echo $currentGracePeriodEnabledValue ? '' : ' disabled'; ?>> 56 <div class="wfls-padding-add-left"><a href="#" id="wfls-send-grace-period-notification" class="wfls-btn wfls-btn-sm wfls-btn-default<?php echo (\WordfenceLS\Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_REQUIRE_2FA_ADMIN) && \WordfenceLS\Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_REQUIRE_2FA_GRACE_PERIOD_ENABLED) && \WordfenceLS\Controller_Time::time() < \WordfenceLS\Controller_Settings::shared()->get_int(\WordfenceLS\Controller_Settings::OPTION_REQUIRE_2FA_GRACE_PERIOD)) ? '' : ' wfls-disabled'; ?>"><?php _e('Send Notification', 'wordfence-2fa'); ?></a></div>57 56 </li> 57 </ul> 58 </li> 59 <li> 60 <ul class="wfls-option wfls-padding-no-top"> 61 <li class="wfls-option-spacer"></li> 62 <li class="wfls-option-spacer"></li> 63 <li><a href="#" id="wfls-send-grace-period-notification" class="wfls-btn wfls-btn-sm wfls-btn-default<?php echo (\WordfenceLS\Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_REQUIRE_2FA_ADMIN) && \WordfenceLS\Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_REQUIRE_2FA_GRACE_PERIOD_ENABLED) && \WordfenceLS\Controller_Time::time() < \WordfenceLS\Controller_Settings::shared()->get_int(\WordfenceLS\Controller_Settings::OPTION_REQUIRE_2FA_GRACE_PERIOD)) ? '' : ' wfls-disabled'; ?>"><?php _e('Send Notification', 'wordfence-2fa'); ?></a></li> 58 64 </ul> 59 65 </li> -
wordfence-login-security/tags/1.0.3/views/settings/options.php
r2098090 r2124103 10 10 </div> 11 11 <div class="wfls-block-header-action wfls-block-header-action-text wfls-nowrap wfls-padding-add-right-responsive"> 12 <a href="#" id="wfls-cancel-changes" class="wfls-btn wfls-btn-sm wfls-btn-default wfls-disabled"><?php _e('Cancel Changes', 'wordfence-2fa'); ?></a> <a href="#" id="wfls-save-changes" class="wfls-btn wfls-btn-sm wfls-btn-primary wfls-disabled"><?php _e('Save Changes', 'wordfence-2fa'); ?></a>12 <a href="#" id="wfls-cancel-changes" class="wfls-btn wfls-btn-sm wfls-btn-default wfls-disabled"><?php _e('Cancel<span class="wfls-visible-sm-inline"> Changes</span>', 'wordfence-2fa'); ?></a> <a href="#" id="wfls-save-changes" class="wfls-btn wfls-btn-sm wfls-btn-primary wfls-disabled"><?php _e('Save<span class="wfls-visible-sm-inline"> Changes</span>', 'wordfence-2fa'); ?></a> 13 13 </div> 14 14 </div> … … 114 114 ?> 115 115 </li> 116 <li> 117 <?php 118 echo \WordfenceLS\Model_View::create('options/option-captcha-threshold', array( 119 ))->render(); 120 ?> 121 </li> 122 <li> 123 <?php 124 echo \WordfenceLS\Model_View::create('options/option-toggled', array( 125 'optionName' => \WordfenceLS\Controller_Settings::OPTION_CAPTCHA_TEST_MODE, 126 'enabledValue' => '1', 127 'disabledValue' => '0', 128 'value' => \WordfenceLS\Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_CAPTCHA_TEST_MODE) ? '1': '0', 129 'title' => new \WordfenceLS\Text\Model_HTML('<strong>' . __('Run reCAPTCHA in test mode', 'wordfence-2fa') . '</strong>'), 130 'subtitle' => __('While in test mode, reCAPTCHA will score login and registration requests but not actually block them. The scores will be recorded and can be used to select a human/bot threshold value.', 'wordfence-2fa'), 131 ))->render(); 132 ?> 133 </li> 116 134 <?php if (!WORDFENCE_LS_FROM_CORE): ?> 117 135 <li> … … 121 139 </li> 122 140 <?php endif; ?> 141 <li> 142 <?php 143 echo \WordfenceLS\Model_View::create('options/option-toggled', array( 144 'optionName' => \WordfenceLS\Controller_Settings::OPTION_DELETE_ON_DEACTIVATION, 145 'enabledValue' => '1', 146 'disabledValue' => '0', 147 'value' => \WordfenceLS\Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_DELETE_ON_DEACTIVATION) ? '1': '0', 148 'title' => new \WordfenceLS\Text\Model_HTML('<strong>' . __('Delete Login Security tables and data on deactivation', 'wordfence-2fa') . '</strong>'), 149 'subtitle' => __('If enabled, all settings and 2FA records will be deleted on deactivation. If later reactivated, all users that previously had 2FA active will need to set it up again.', 'wordfence-2fa'), 150 ))->render(); 151 ?> 152 </li> 123 153 </ul> 124 154 </div> -
wordfence-login-security/tags/1.0.3/wordfence-login-security.php
r2098090 r2124103 5 5 Author: Wordfence 6 6 Author URI: http://www.wordfence.com/ 7 Version: 1.0. 27 Version: 1.0.3 8 8 Network: true 9 9 */ … … 34 34 define('WORDFENCE_LS_FROM_CORE', ($wfCoreActive && isset($wfCoreLoading) && $wfCoreLoading)); 35 35 36 define('WORDFENCE_LS_VERSION', '1.0.2'); 37 define('WORDFENCE_LS_BUILD_NUMBER', '1559237323'); 36 define('WORDFENCE_LS_VERSION', '1.0.3'); 37 define('WORDFENCE_LS_BUILD_NUMBER', '1563297209'); 38 39 if (!defined('WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES')) { define('WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES', 15); } 38 40 39 41 if (!WORDFENCE_LS_FROM_CORE) { -
wordfence-login-security/trunk/classes/controller/ajax.php
r2098090 r2124103 73 73 'required_parameters' => array('nonce', 'id'), 74 74 ), 75 'reset_recaptcha_stats' => array( 76 'handler' => array($this, '_ajax_reset_recaptcha_stats_callback'), 77 'permissions' => array(Controller_Permissions::CAP_MANAGE_SETTINGS => __('You do not have permission to reset reCAPTCHA statistics.', 'wordfence-2fa')), 78 'required_parameters' => array('nonce'), 79 ), 75 80 ); 76 81 … … 400 405 foreach ($admins as $a) { 401 406 /** @var \WP_User $a */ 402 if ( !Controller_Users::shared()->has_2fa_active($a)) {407 if (Controller_Users::shared()->has_2fa_active($a)) { 403 408 continue; 404 409 } … … 447 452 Controller_Notices::shared()->remove_notice($_POST['id'], false, wp_get_current_user()); 448 453 } 454 455 public function _ajax_reset_recaptcha_stats_callback() { 456 Controller_Settings::shared()->set_array(Controller_Settings::OPTION_CAPTCHA_STATS, array('counts' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 'avg' => 0)); 457 $response = array('success' => true); 458 return die(json_encode($response)); 459 } 449 460 } -
wordfence-login-security/trunk/classes/controller/captcha.php
r2098090 r2124103 112 112 */ 113 113 public function is_human($score) { 114 if (Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_CAPTCHA_TEST_MODE)) { 115 return true; 116 } 117 114 118 $threshold = $this->threshold(); 115 119 return ($score >= $threshold || abs($score - $threshold) < 0.0001); -
wordfence-login-security/trunk/classes/controller/db.php
r2098090 r2124103 59 59 } 60 60 61 public function uninstall() { 62 $tables = array(self::TABLE_2FA_SECRETS, self::TABLE_SETTINGS); 63 foreach ($tables as $table) { 64 global $wpdb; 65 $wpdb->query('DROP TABLE IF EXISTS `' . self::network_table($table) . '`'); 66 } 67 } 68 61 69 protected function _create_schema() { 62 70 $tables = array( -
wordfence-login-security/trunk/classes/controller/settings.php
r2098090 r2124103 19 19 const OPTION_ALLOW_XML_RPC = 'allow-xml-rpc'; 20 20 const OPTION_ENABLE_AUTH_CAPTCHA = 'enable-auth-captcha'; 21 const OPTION_CAPTCHA_TEST_MODE = 'recaptcha-test-mode'; 21 22 const OPTION_RECAPTCHA_SITE_KEY = 'recaptcha-site-key'; 22 23 const OPTION_RECAPTCHA_SECRET = 'recaptcha-secret'; 23 24 const OPTION_RECAPTCHA_THRESHOLD = 'recaptcha-threshold'; 25 const OPTION_DELETE_ON_DEACTIVATION = 'delete-deactivation'; 24 26 25 27 //Internal … … 31 33 const OPTION_SHARED_SYMMETRIC_SECRET_KEY = 'shared-symmetric-secret'; 32 34 const OPTION_DISMISSED_FRESH_INSTALL_MODAL = 'dismissed-fresh-install-modal'; 35 const OPTION_CAPTCHA_STATS = 'captcha-stats'; 33 36 34 37 protected $_settingsStorage; … … 67 70 self::OPTION_ALLOW_XML_RPC => array('value' => true, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false), 68 71 self::OPTION_ENABLE_AUTH_CAPTCHA => array('value' => false, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false), 72 self::OPTION_CAPTCHA_STATS => array('value' => '{"counts":[0,0,0,0,0,0,0,0,0,0,0],"avg":0}', 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false), 69 73 self::OPTION_RECAPTCHA_THRESHOLD => array('value' => 0.5, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false), 70 74 self::OPTION_LAST_SECRET_REFRESH => array('value' => 0, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false), 75 self::OPTION_DELETE_ON_DEACTIVATION => array('value' => false, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false), 71 76 )); 72 77 } … … 130 135 case self::OPTION_ALLOW_XML_RPC: 131 136 case self::OPTION_ENABLE_AUTH_CAPTCHA: 137 case self::OPTION_CAPTCHA_TEST_MODE: 132 138 case self::OPTION_DISMISSED_FRESH_INSTALL_MODAL: 139 case self::OPTION_DELETE_ON_DEACTIVATION: 133 140 return true; 134 141 … … 139 146 //Array 140 147 case self::OPTION_GLOBAL_NOTICES: 148 case self::OPTION_CAPTCHA_STATS: 141 149 return preg_match('/^\[.*\]$/', $value) || preg_match('/^\{.*\}$/', $value); //Only a rough JSON validation 142 150 … … 166 174 case self::OPTION_RECAPTCHA_THRESHOLD: 167 175 return is_numeric($value) && $value >= 0 && $value <= 1; 176 case self::OPTION_RECAPTCHA_SITE_KEY: 177 if (empty($value)) { 178 return true; 179 } 180 181 $response = wp_remote_get('https://www.google.com/recaptcha/api.js?render=' . urlencode($value)); 182 183 if (!is_wp_error($response)) { 184 $status = wp_remote_retrieve_response_code($response); 185 if ($status == 200) { 186 return true; 187 } 188 189 $data = wp_remote_retrieve_body($response); 190 if (strpos($data, 'grecaptcha') === false) { 191 return __('Unable to validate the reCAPTCHA site key. Please check the key and try again.', 'wordfence-2fa'); 192 } 193 return true; 194 } 195 return sprintf(__('An error was encountered while validating the reCAPTCHA site key: %s', 'wordfence-2fa'), $response->get_error_message()); 168 196 } 169 197 return true; … … 202 230 case self::OPTION_ALLOW_XML_RPC: 203 231 case self::OPTION_ENABLE_AUTH_CAPTCHA: 232 case self::OPTION_CAPTCHA_TEST_MODE: 204 233 case self::OPTION_DISMISSED_FRESH_INSTALL_MODAL: 234 case self::OPTION_DELETE_ON_DEACTIVATION: 205 235 return $this->_truthy_to_bool($value); 206 236 -
wordfence-login-security/trunk/classes/controller/time.php
r2098090 r2124103 96 96 foreach ($servers as $s) { 97 97 $socket = @fsockopen('udp://' . $s, 123, $err_no, $err_str, 1); 98 stream_set_timeout($socket, 1);99 98 if ($socket) { 99 stream_set_timeout($socket, 1); 100 100 $remote_originate = microtime(true); 101 101 $secondsNTP = ((int) $remote_originate) + self::NTP_EPOCH_CONVERT; -
wordfence-login-security/trunk/classes/controller/users.php
r2098090 r2124103 312 312 313 313 /** 314 * Records the reCAPTCHA score for later display. 315 * 316 * This is not atomic, which means this can miscount on hits that overlap, but the overhead of being atomic is not 317 * worth it for our use. 318 * 319 * @param \WP_User $user|null 320 * @param float $score 321 */ 322 public function record_captcha_score($user, $score) { 323 if (!Controller_CAPTCHA::shared()->enabled()) { return; } 324 if ($this->has_2fa_active($user)) { return; } //2FA activated users do not retrieve a score 325 326 if ($user) { update_user_meta($user->ID, 'wfls-last-captcha-score', $score); } 327 $stats = Controller_Settings::shared()->get_array(Controller_Settings::OPTION_CAPTCHA_STATS); 328 $int_score = min(max((int) ($score * 10), 0), 10); 329 $count = array_sum($stats['counts']); 330 $stats['counts'][$int_score]++; 331 $stats['avg'] = ($stats['avg'] * $count + $int_score) / ($count + 1); 332 Controller_Settings::shared()->set_array(Controller_Settings::OPTION_CAPTCHA_STATS, $stats); 333 } 334 335 /** 314 336 * Returns the active and inactive user counts. 315 337 * -
wordfence-login-security/trunk/classes/controller/wordfencels.php
r2098090 r2124103 125 125 } 126 126 } 127 128 if (Controller_Settings::shared()->get_bool(Controller_Settings::OPTION_CAPTCHA_TEST_MODE) && Controller_CAPTCHA::shared()->enabled() && Controller_Permissions::shared()->can_manage_settings()) { 129 if (is_multisite()) { 130 add_action('network_admin_notices', array($this, '_recaptcha_test_notice')); 131 } 132 else { 133 add_action('admin_notices', array($this, '_recaptcha_test_notice')); 134 } 135 } 127 136 } 128 137 … … 135 144 } 136 145 146 public function _recaptcha_test_notice() { 147 echo '<div class="notice notice-warning"><p>' . sprintf(__('reCAPTCHA test mode is enabled. While enabled, login and registration requests will be checked for their score but will not be blocked if the score is below the minimum score. <a href="%s">Manage Settings</a>', 'wordfence-2fa'), esc_url(network_admin_url('admin.php?page=WFLS#top#settings'))) . '</p></div>'; 148 } 149 137 150 /** 138 151 * Installation/Uninstallation … … 151 164 } 152 165 delete_option($opt); 166 } 167 168 if (Controller_Settings::shared()->get_bool(Controller_Settings::OPTION_DELETE_ON_DEACTIVATION)) { 169 Controller_DB::shared()->uninstall(); 153 170 } 154 171 } … … 243 260 } 244 261 wp_enqueue_script('wordfence-ls-admin', Model_Asset::js('admin.js'), array('jquery'), WORDFENCE_LS_VERSION); 262 if (!WORDFENCE_LS_FROM_CORE) { 263 wp_register_script('chart-js', Model_Asset::js('Chart.bundle.min.js'), array('jquery'), '2.4.0'); 264 wp_register_script('wordfence-select2-js', Model_Asset::js('wfselect2.min.js'), array('jquery'), WORDFENCE_LS_VERSION); 265 wp_register_style('wordfence-select2-css', Model_Asset::css('wfselect2.min.css'), array(), WORDFENCE_LS_VERSION); 266 } 267 wp_enqueue_script('chart-js'); 268 wp_enqueue_script('wordfence-select2-js'); 269 wp_enqueue_style('wordfence-select2-css'); 245 270 wp_enqueue_style('wordfence-ls-admin', Model_Asset::css('admin.css'), array(), WORDFENCE_LS_VERSION); 246 271 wp_enqueue_style('wordfence-ls-colorbox', Model_Asset::css('colorbox.css'), array(), WORDFENCE_LS_VERSION); 247 272 wp_enqueue_style('wordfence-ls-ionicons', Model_Asset::css('ionicons.css'), array(), WORDFENCE_LS_VERSION); 273 if (!WORDFENCE_LS_FROM_CORE) { wp_enqueue_style('wordfence-ls-font-awesome', Model_Asset::css('font-awesome.css'), array(), WORDFENCE_LS_VERSION); } 248 274 wp_localize_script('wordfence-ls-admin', 'WFLSVars', array( 249 275 'ajaxurl' => admin_url('admin-ajax.php'), … … 400 426 } 401 427 402 update_user_meta($user->ID, 'wfls-last-captcha-score', $score);428 Controller_Users::shared()->record_captcha_score($user, $score); 403 429 404 430 if (isset($_REQUEST['wfls-email-verification']) && !empty($_REQUEST['wfls-email-verification']) && is_string($_REQUEST['wfls-email-verification'])) { … … 422 448 $encrypted = Model_Symmetric::encrypt((string) $user->ID); 423 449 if ($encrypted) { 424 $jwt = new Model_JWT(array('user' => $encrypted), Controller_Time::time() + 60 * 15 /* minutes */);450 $jwt = new Model_JWT(array('user' => $encrypted), Controller_Time::time() + 60 * WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES); 425 451 $view = new Model_View('email/login-verification', array( 426 452 'siteName' => get_bloginfo('name', 'raw'), … … 618 644 619 645 if ($requireCAPTCHA) { 646 Controller_Users::shared()->record_captcha_score(null, $score); 647 620 648 if (!Controller_CAPTCHA::shared()->is_human($score)) { //Score is below the human threshold, block the user registration 621 649 $encryptedIP = Model_Symmetric::encrypt(Model_Request::current()->ip()); -
wordfence-login-security/trunk/classes/model/settings/db.php
r2098090 r2124103 26 26 if ($wpdb->query($wpdb->prepare("INSERT INTO `{$table}` (`name`, `value`, `autoload`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`), `autoload` = VALUES(`autoload`)", $key, $value, $autoload)) !== false && $autoload != self::AUTOLOAD_NO) { 27 27 $this->_update_cached($key, $value); 28 do_action('wfls_settings_set', $key, $value); 28 29 } 29 30 } -
wordfence-login-security/trunk/readme.txt
r2098090 r2124103 1 1 === Wordfence Login Security === 2 Contributors: wfryan 2 Contributors: wfryan, wfmattr, mmaunder, wfmatt 3 3 Tags: security, login security, 2fa, two factor authentication, captcha, xml-rpc, mfa, 2 factor 4 4 Requires at least: 4.5 … … 59 59 == Changelog == 60 60 61 = 1.0.3 - July 16, 2019 = 62 * Improvement: Added additional information about reCAPTCHA to its setting control. 63 * Improvement: Added a constant that may be overridden to customize the expiration time of login verification email links. 64 * Improvement: reCAPTCHA keys are now tested on saving to prevent accidentally inputting a v2 key. 65 * Improvement: Added a setting to control the reCAPTCHA human/bot threshold. 66 * Improvement: Added an option to trigger removal of Login Security tables and data on deactivation. 67 * Improvement: Reworked the reCAPTCHA implementation to trigger the token check on login/registration form submission to avoid the token expiring. 68 * Fix: Widened the reCAPTCHA key fields to allow the full keys to be visible. 69 * Fix: Addressed an issue when outbound UDP connections are blocked where the NTP check could log an error. 70 * Fix: Added handling for reCAPTCHA's JavaScript failing to load, which previously blocked logging in. 71 * Fix: Fixed the functionality of the button to send 2FA grace period notifications. 72 * Fix: Fixed a missing icon for some help links when running in standalone mode. 73 61 74 = 1.0.2 - May 30, 2019 = 62 75 * Initial release -
wordfence-login-security/trunk/views/options/option-captcha.php
r2098090 r2124103 18 18 <ul class="wfls-flex-vertical wfls-flex-align-left"> 19 19 <li> 20 <strong id="wfls-enable-auth-captcha-label"><?php _e('Enable reCAPTCHA on the login and user registration pages', 'wordfence- 2fa'); ?></strong>20 <strong id="wfls-enable-auth-captcha-label"><?php _e('Enable reCAPTCHA on the login and user registration pages', 'wordfence-ls'); ?></strong> 21 21 </li> 22 <li class="wfls-option-subtitle"><?php _e('Note: This feature requires a free site key and secret for the <a href="https://www.google.com/recaptcha/intro/v3.html" target="_blank" rel="noopener noreferrer">Google reCAPTCHA v3 Service</a>.', 'wordfence-2fa'); ?></li>22 <li class="wfls-option-subtitle"><?php printf(__('reCAPTCHA v3 does not make users solve puzzles or click a checkbox like previous versions. The only visible part is the reCAPTCHA logo. If a visitor\'s browser fails the CAPTCHA, Wordfence will send an email to the user\'s address with a link they can click to verify that they are a user of your site. You can read further details <a href="%s" target="_blank" rel="noopener noreferrer">in our documentation</a>.', 'wordfence-ls'), \WordfenceLS\Controller_Support::esc_supportURL(\WordfenceLS\Controller_Support::ITEM_MODULE_LOGIN_SECURITY_CAPTCHA)); ?></li> 23 23 </ul> 24 24 </li> … … 31 31 <table> 32 32 <tr class="wfls-option wfls-option-text" data-original-value="<?php echo esc_attr($siteKeyValue); ?>" data-text-option="<?php echo esc_attr($siteKeyOptionName); ?>"> 33 <th id="wfls-enable-captcha-site-key-label" class="wfls-padding-add-bottom"><?php _e('reCAPTCHA v3 Site Key', 'wordfence '); ?></th>33 <th id="wfls-enable-captcha-site-key-label" class="wfls-padding-add-bottom"><?php _e('reCAPTCHA v3 Site Key', 'wordfence-ls'); ?></th> 34 34 <td class="wfls-option-text wfls-padding-add-bottom"><input type="text" name="recaptchaSiteKey" id="input-recaptchaSiteKey" class="wfls-form-control" value="<?php echo esc_attr($siteKeyValue); ?>"<?php if (!$currentEnableValue) { echo ' disabled'; } ?>></td> 35 35 </tr> 36 36 <tr class="wfls-option wfls-option-text" data-original-value="<?php echo esc_attr($secretValue); ?>" data-text-option="<?php echo esc_attr($secretOptionName); ?>"> 37 <th id="wfls-enable-captcha-secret-label"><?php _e('reCAPTCHA v3 Secret', 'wordfence '); ?></th>37 <th id="wfls-enable-captcha-secret-label"><?php _e('reCAPTCHA v3 Secret', 'wordfence-ls'); ?></th> 38 38 <td class="wfls-option-text"><input type="text" name="recaptchaSecret" id="input-recaptchaSecret" class="wfls-form-control" value="<?php echo esc_attr($secretValue); ?>"<?php if (!$currentEnableValue) { echo ' disabled'; } ?>></td> 39 39 </tr> 40 40 </table> 41 </li> 42 </ul> 43 <ul class="wfls-option wfls-padding-no-top"> 44 <li class="wfls-option-spacer"></li> 45 <li class="wfls-option-title"> 46 <ul class="wfls-flex-vertical wfls-flex-align-left"> 47 <li class="wfls-option-subtitle"><?php _e('Note: This feature requires a free site key and secret for the <a href="https://www.google.com/recaptcha/intro/v3.html" target="_blank" rel="noopener noreferrer">Google reCAPTCHA v3 Service</a>.', 'wordfence-ls'); ?></li> 48 </ul> 41 49 </li> 42 50 </ul> -
wordfence-login-security/trunk/views/options/option-require-2fa.php
r2098090 r2124103 54 54 <span id="wfls-require-2fa-grace-period-label" class="wfls-padding-add-left wfls-padding-add-right"><?php _e('Grace period to require 2FA', 'wordfence'); ?> </span> 55 55 <input type="text" name="require2FAGracePeriod" id="input-require2FAGracePeriod" class="wfls-datetime wfls-form-control" placeholder="Enabled on..." data-value="<?php echo $currentGracePeriodDateValue; ?>" data-original-value="<?php echo $currentGracePeriodDateValue; ?>"<?php echo $currentGracePeriodEnabledValue ? '' : ' disabled'; ?>> 56 <div class="wfls-padding-add-left"><a href="#" id="wfls-send-grace-period-notification" class="wfls-btn wfls-btn-sm wfls-btn-default<?php echo (\WordfenceLS\Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_REQUIRE_2FA_ADMIN) && \WordfenceLS\Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_REQUIRE_2FA_GRACE_PERIOD_ENABLED) && \WordfenceLS\Controller_Time::time() < \WordfenceLS\Controller_Settings::shared()->get_int(\WordfenceLS\Controller_Settings::OPTION_REQUIRE_2FA_GRACE_PERIOD)) ? '' : ' wfls-disabled'; ?>"><?php _e('Send Notification', 'wordfence-2fa'); ?></a></div>57 56 </li> 57 </ul> 58 </li> 59 <li> 60 <ul class="wfls-option wfls-padding-no-top"> 61 <li class="wfls-option-spacer"></li> 62 <li class="wfls-option-spacer"></li> 63 <li><a href="#" id="wfls-send-grace-period-notification" class="wfls-btn wfls-btn-sm wfls-btn-default<?php echo (\WordfenceLS\Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_REQUIRE_2FA_ADMIN) && \WordfenceLS\Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_REQUIRE_2FA_GRACE_PERIOD_ENABLED) && \WordfenceLS\Controller_Time::time() < \WordfenceLS\Controller_Settings::shared()->get_int(\WordfenceLS\Controller_Settings::OPTION_REQUIRE_2FA_GRACE_PERIOD)) ? '' : ' wfls-disabled'; ?>"><?php _e('Send Notification', 'wordfence-2fa'); ?></a></li> 58 64 </ul> 59 65 </li> -
wordfence-login-security/trunk/views/settings/options.php
r2098090 r2124103 10 10 </div> 11 11 <div class="wfls-block-header-action wfls-block-header-action-text wfls-nowrap wfls-padding-add-right-responsive"> 12 <a href="#" id="wfls-cancel-changes" class="wfls-btn wfls-btn-sm wfls-btn-default wfls-disabled"><?php _e('Cancel Changes', 'wordfence-2fa'); ?></a> <a href="#" id="wfls-save-changes" class="wfls-btn wfls-btn-sm wfls-btn-primary wfls-disabled"><?php _e('Save Changes', 'wordfence-2fa'); ?></a>12 <a href="#" id="wfls-cancel-changes" class="wfls-btn wfls-btn-sm wfls-btn-default wfls-disabled"><?php _e('Cancel<span class="wfls-visible-sm-inline"> Changes</span>', 'wordfence-2fa'); ?></a> <a href="#" id="wfls-save-changes" class="wfls-btn wfls-btn-sm wfls-btn-primary wfls-disabled"><?php _e('Save<span class="wfls-visible-sm-inline"> Changes</span>', 'wordfence-2fa'); ?></a> 13 13 </div> 14 14 </div> … … 114 114 ?> 115 115 </li> 116 <li> 117 <?php 118 echo \WordfenceLS\Model_View::create('options/option-captcha-threshold', array( 119 ))->render(); 120 ?> 121 </li> 122 <li> 123 <?php 124 echo \WordfenceLS\Model_View::create('options/option-toggled', array( 125 'optionName' => \WordfenceLS\Controller_Settings::OPTION_CAPTCHA_TEST_MODE, 126 'enabledValue' => '1', 127 'disabledValue' => '0', 128 'value' => \WordfenceLS\Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_CAPTCHA_TEST_MODE) ? '1': '0', 129 'title' => new \WordfenceLS\Text\Model_HTML('<strong>' . __('Run reCAPTCHA in test mode', 'wordfence-2fa') . '</strong>'), 130 'subtitle' => __('While in test mode, reCAPTCHA will score login and registration requests but not actually block them. The scores will be recorded and can be used to select a human/bot threshold value.', 'wordfence-2fa'), 131 ))->render(); 132 ?> 133 </li> 116 134 <?php if (!WORDFENCE_LS_FROM_CORE): ?> 117 135 <li> … … 121 139 </li> 122 140 <?php endif; ?> 141 <li> 142 <?php 143 echo \WordfenceLS\Model_View::create('options/option-toggled', array( 144 'optionName' => \WordfenceLS\Controller_Settings::OPTION_DELETE_ON_DEACTIVATION, 145 'enabledValue' => '1', 146 'disabledValue' => '0', 147 'value' => \WordfenceLS\Controller_Settings::shared()->get_bool(\WordfenceLS\Controller_Settings::OPTION_DELETE_ON_DEACTIVATION) ? '1': '0', 148 'title' => new \WordfenceLS\Text\Model_HTML('<strong>' . __('Delete Login Security tables and data on deactivation', 'wordfence-2fa') . '</strong>'), 149 'subtitle' => __('If enabled, all settings and 2FA records will be deleted on deactivation. If later reactivated, all users that previously had 2FA active will need to set it up again.', 'wordfence-2fa'), 150 ))->render(); 151 ?> 152 </li> 123 153 </ul> 124 154 </div> -
wordfence-login-security/trunk/wordfence-login-security.php
r2098090 r2124103 5 5 Author: Wordfence 6 6 Author URI: http://www.wordfence.com/ 7 Version: 1.0. 27 Version: 1.0.3 8 8 Network: true 9 9 */ … … 34 34 define('WORDFENCE_LS_FROM_CORE', ($wfCoreActive && isset($wfCoreLoading) && $wfCoreLoading)); 35 35 36 define('WORDFENCE_LS_VERSION', '1.0.2'); 37 define('WORDFENCE_LS_BUILD_NUMBER', '1559237323'); 36 define('WORDFENCE_LS_VERSION', '1.0.3'); 37 define('WORDFENCE_LS_BUILD_NUMBER', '1563297209'); 38 39 if (!defined('WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES')) { define('WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES', 15); } 38 40 39 41 if (!WORDFENCE_LS_FROM_CORE) {
Note: See TracChangeset
for help on using the changeset viewer.