Wordfence Login Security - Version 1.0.10

Version Description

  • June 2, 2022 =
  • Improvement: Added option to toggle display of last login column on WP Users page
  • Improvement: Improved autocomplete support for 2FA code on Apple devices
  • Fix: Corrected issue that prevented reCAPTCHA scores from being recorded
  • Fix: Prevented invalid JSON setting values from triggering fatal errors
  • Fix: Made text domains consistent for translation support
  • Fix: Clarified that allowlisted IP addresses also bypass reCAPTCHA
Download this release

Release Info

Developer wfalexk
Plugin Icon 128x128 Wordfence Login Security
Version 1.0.10
Comparing to
See all releases

Code changes from version 1.0.9 to 1.0.10

Files changed (45) hide show
  1. classes/controller/ajax.php +14 -14
  2. classes/controller/settings.php +20 -3
  3. classes/controller/users.php +2 -2
  4. classes/controller/wordfencels.php +17 -17
  5. css/{admin-global.1634043539.css → admin-global.1654178513.css} +0 -0
  6. css/{admin.1634043539.css → admin.1654178513.css} +0 -0
  7. css/{colorbox.1634043539.css → colorbox.1654178513.css} +0 -0
  8. css/{font-awesome.1634043539.css → font-awesome.1654178513.css} +0 -0
  9. css/{ionicons.1634043539.css → ionicons.1654178513.css} +0 -0
  10. css/{jquery-ui.min.1634043539.css → jquery-ui.min.1654178513.css} +0 -0
  11. css/{jquery-ui.structure.min.1634043539.css → jquery-ui.structure.min.1654178513.css} +0 -0
  12. css/{jquery-ui.theme.min.1634043539.css → jquery-ui.theme.min.1654178513.css} +0 -0
  13. css/{login.1634043539.css → login.1654178513.css} +0 -0
  14. css/{wfselect2.min.1634043539.css → wfselect2.min.1654178513.css} +0 -0
  15. js/{Chart.bundle.min.1634043539.js → Chart.bundle.min.1654178513.js} +0 -0
  16. js/{admin-global.1634043539.js → admin-global.1654178513.js} +0 -0
  17. js/{admin.1634043539.js → admin.1654178513.js} +0 -0
  18. js/{jquery.colorbox.1634043539.js → jquery.colorbox.1654178513.js} +0 -0
  19. js/{jquery.colorbox.min.1634043539.js → jquery.colorbox.min.1654178513.js} +0 -0
  20. js/{jquery.qrcode.min.1634043539.js → jquery.qrcode.min.1654178513.js} +0 -0
  21. js/{jquery.tmpl.min.1634043539.js → jquery.tmpl.min.1654178513.js} +0 -0
  22. js/{login.1634043539.js → login.1654178513.js} +1 -1
  23. js/{wfselect2.min.1634043539.js → wfselect2.min.1654178513.js} +0 -0
  24. readme.txt +9 -1
  25. views/email/login-verification.php +6 -6
  26. views/manage/activate.php +2 -2
  27. views/manage/code.php +1 -1
  28. views/manage/deactivate.php +4 -4
  29. views/manage/regenerate.php +4 -4
  30. views/options/option-captcha-threshold.php +2 -2
  31. views/options/option-captcha.php +5 -5
  32. views/options/option-roles.php +3 -3
  33. views/options/option-select.php +1 -1
  34. views/options/option-text.php +1 -1
  35. views/options/option-toggled-boolean-switch.php +1 -1
  36. views/options/option-toggled-segmented.php +1 -1
  37. views/options/option-toggled-select.php +1 -1
  38. views/options/option-toggled-sub.php +2 -2
  39. views/options/option-toggled-textarea.php +1 -1
  40. views/options/option-token.php +1 -1
  41. views/page/role.php +3 -3
  42. views/settings/options.php +13 -1
  43. views/settings/user-stats.php +1 -1
  44. views/user/grace-period-toggle.php +1 -1
  45. wordfence-login-security.php +3 -3
classes/controller/ajax.php CHANGED
@@ -183,7 +183,7 @@ class Controller_AJAX {
183
  }
184
  }
185
  if (empty($username) || empty($password)) {
186
- self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: A username and password must be provided. <a href="%s" title="Password Lost and Found">Lost your password</a>?'), wp_lostpassword_url()), array('strong'=>array(), 'a'=>array('href'=>array(), 'title'=>array())))));
187
  }
188
 
189
  $legacy2FAActive = Controller_WordfenceLS::shared()->legacy_2fa_active();
@@ -231,7 +231,7 @@ class Controller_AJAX {
231
  $reset = false;
232
  foreach ($user->get_error_codes() as $code) {
233
  if ($code == 'invalid_username' || $code == 'invalid_email' || $code == 'incorrect_password' || $code == 'authentication_failed') {
234
- $errors[] = wp_kses(sprintf(__('<strong>ERROR</strong>: The username or password you entered is incorrect. <a href="%s" title="Password Lost and Found">Lost your password</a>?'), wp_lostpassword_url()), array('strong'=>array(), 'a'=>array('href'=>array(), 'title'=>array())));
235
  }
236
  else {
237
  if ($code == 'wfls_twofactor_invalid') {
@@ -263,7 +263,7 @@ class Controller_AJAX {
263
  }
264
  }
265
 
266
- self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: The username or password you entered is incorrect. <a href="%s" title="Password Lost and Found">Lost your password</a>?'), wp_lostpassword_url()), array('strong'=>array(), 'a'=>array('href'=>array(), 'title'=>array())))));
267
  }
268
 
269
  public function _ajax_register_support_callback() {
@@ -278,7 +278,7 @@ class Controller_AJAX {
278
  $email === null ||
279
  !isset($_POST['wfls-message']) || !is_string($_POST['wfls-message']) ||
280
  !isset($_POST['wfls-message-nonce']) || !is_string($_POST['wfls-message-nonce'])) {
281
- self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: Unable to send message. Please refresh the page and try again.')), array('strong'=>array()))));
282
  }
283
 
284
  $email = sanitize_email($email);
@@ -289,7 +289,7 @@ class Controller_AJAX {
289
  $nonce = $_POST['wfls-message-nonce'];
290
 
291
  if ((isset($_POST['user_login']) && empty($login)) || empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL) || empty($message)) {
292
- self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: Unable to send message. Please refresh the page and try again.')), array('strong'=>array()))));
293
  }
294
 
295
  $jwt = Model_JWT::decode_jwt($_POST['wfls-message-nonce']);
@@ -297,30 +297,30 @@ class Controller_AJAX {
297
  $decryptedIP = Model_Symmetric::decrypt($jwt->payload['ip']);
298
  $decryptedScore = Model_Symmetric::decrypt($jwt->payload['score']);
299
  if ($decryptedIP === false || $decryptedScore === false || Model_IP::inet_pton($decryptedIP) !== Model_IP::inet_pton(Model_Request::current()->ip())) { //JWT IP and the current request's IP don't match, refuse the message
300
- self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: Unable to send message. Please refresh the page and try again.')), array('strong'=>array()))));
301
  }
302
 
303
  $identifier = bin2hex(Model_IP::inet_pton($decryptedIP));
304
  $tokenBucket = new Model_TokenBucket('rate:' . $identifier, 2, 1 / (6 * Model_TokenBucket::HOUR)); //Maximum of two requests, refilling at a rate of one per six hours
305
  if (!$tokenBucket->consume(1)) {
306
- self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: Unable to send message. You have exceeded the maximum number of messages that may be sent at this time. Please try again later.')), array('strong'=>array()))));
307
  }
308
 
309
  $email = array(
310
  'to' => get_site_option('admin_email'),
311
- 'subject' => __('Blocked User Registration Contact Form', 'wordfence-ls'),
312
- 'body' => sprintf(__("A visitor blocked from registration sent the following message.\n\n----------------------------------------\n\nIP: %s\nUsername: %s\nEmail: %s\nreCAPTCHA Score: %f\n\n----------------------------------------\n\n%s", 'wordfence-ls'), $decryptedIP, $login, $email, $decryptedScore, $message),
313
  'headers' => '',
314
  );
315
  $success = wp_mail($email['to'], $email['subject'], $email['body'], $email['headers']);
316
  if ($success) {
317
- self::send_json(array('message' => wp_kses(sprintf(__('<strong>MESSAGE SENT</strong>: Your message was sent to the site owner.')), array('strong'=>array()))));
318
  }
319
 
320
- self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: An error occurred while sending the message. Please try again.')), array('strong'=>array()))));
321
  }
322
 
323
- self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: Unable to send message. Please refresh the page and try again.')), array('strong'=>array()))));
324
  }
325
 
326
  public function _ajax_activate_callback() {
@@ -445,7 +445,7 @@ class Controller_AJAX {
445
  }
446
 
447
  self::send_json(array(
448
- 'error' => esc_html__('No configuration changes were provided to save.', 'wordfence'),
449
  ));
450
  }
451
 
@@ -560,7 +560,7 @@ class Controller_AJAX {
560
  if ($userId !== 0 && Controller_Notices::shared()->dismiss_persistent_notice($userId, $noticeId))
561
  self::send_json(array('success' => true));
562
  self::send_json(array(
563
- 'error' => esc_html__('Unable to dismiss notice', 'wordfence')
564
  ));
565
  }
566
  }
183
  }
184
  }
185
  if (empty($username) || empty($password)) {
186
+ self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: A username and password must be provided. <a href="%s" title="Password Lost and Found">Lost your password</a>?', 'wordfence-2fa'), wp_lostpassword_url()), array('strong'=>array(), 'a'=>array('href'=>array(), 'title'=>array())))));
187
  }
188
 
189
  $legacy2FAActive = Controller_WordfenceLS::shared()->legacy_2fa_active();
231
  $reset = false;
232
  foreach ($user->get_error_codes() as $code) {
233
  if ($code == 'invalid_username' || $code == 'invalid_email' || $code == 'incorrect_password' || $code == 'authentication_failed') {
234
+ $errors[] = wp_kses(sprintf(__('<strong>ERROR</strong>: The username or password you entered is incorrect. <a href="%s" title="Password Lost and Found">Lost your password</a>?', 'wordfence-2fa'), wp_lostpassword_url()), array('strong'=>array(), 'a'=>array('href'=>array(), 'title'=>array())));
235
  }
236
  else {
237
  if ($code == 'wfls_twofactor_invalid') {
263
  }
264
  }
265
 
266
+ self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: The username or password you entered is incorrect. <a href="%s" title="Password Lost and Found">Lost your password</a>?', 'wordfence-2fa'), wp_lostpassword_url()), array('strong'=>array(), 'a'=>array('href'=>array(), 'title'=>array())))));
267
  }
268
 
269
  public function _ajax_register_support_callback() {
278
  $email === null ||
279
  !isset($_POST['wfls-message']) || !is_string($_POST['wfls-message']) ||
280
  !isset($_POST['wfls-message-nonce']) || !is_string($_POST['wfls-message-nonce'])) {
281
+ self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: Unable to send message. Please refresh the page and try again.', 'wordfence-2fa')), array('strong'=>array()))));
282
  }
283
 
284
  $email = sanitize_email($email);
289
  $nonce = $_POST['wfls-message-nonce'];
290
 
291
  if ((isset($_POST['user_login']) && empty($login)) || empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL) || empty($message)) {
292
+ self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: Unable to send message. Please refresh the page and try again.', 'wordfence-2fa')), array('strong'=>array()))));
293
  }
294
 
295
  $jwt = Model_JWT::decode_jwt($_POST['wfls-message-nonce']);
297
  $decryptedIP = Model_Symmetric::decrypt($jwt->payload['ip']);
298
  $decryptedScore = Model_Symmetric::decrypt($jwt->payload['score']);
299
  if ($decryptedIP === false || $decryptedScore === false || Model_IP::inet_pton($decryptedIP) !== Model_IP::inet_pton(Model_Request::current()->ip())) { //JWT IP and the current request's IP don't match, refuse the message
300
+ self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: Unable to send message. Please refresh the page and try again.', 'wordfence-2fa')), array('strong'=>array()))));
301
  }
302
 
303
  $identifier = bin2hex(Model_IP::inet_pton($decryptedIP));
304
  $tokenBucket = new Model_TokenBucket('rate:' . $identifier, 2, 1 / (6 * Model_TokenBucket::HOUR)); //Maximum of two requests, refilling at a rate of one per six hours
305
  if (!$tokenBucket->consume(1)) {
306
+ self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: Unable to send message. You have exceeded the maximum number of messages that may be sent at this time. Please try again later.', 'wordfence-2fa')), array('strong'=>array()))));
307
  }
308
 
309
  $email = array(
310
  'to' => get_site_option('admin_email'),
311
+ 'subject' => __('Blocked User Registration Contact Form', 'wordfence-2fa'),
312
+ 'body' => sprintf(__("A visitor blocked from registration sent the following message.\n\n----------------------------------------\n\nIP: %s\nUsername: %s\nEmail: %s\nreCAPTCHA Score: %f\n\n----------------------------------------\n\n%s", 'wordfence-2fa'), $decryptedIP, $login, $email, $decryptedScore, $message),
313
  'headers' => '',
314
  );
315
  $success = wp_mail($email['to'], $email['subject'], $email['body'], $email['headers']);
316
  if ($success) {
317
+ self::send_json(array('message' => wp_kses(sprintf(__('<strong>MESSAGE SENT</strong>: Your message was sent to the site owner.', 'wordfence-2fa')), array('strong'=>array()))));
318
  }
319
 
320
+ self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: An error occurred while sending the message. Please try again.', 'wordfence-2fa')), array('strong'=>array()))));
321
  }
322
 
323
+ self::send_json(array('error' => wp_kses(sprintf(__('<strong>ERROR</strong>: Unable to send message. Please refresh the page and try again.', 'wordfence-2fa')), array('strong'=>array()))));
324
  }
325
 
326
  public function _ajax_activate_callback() {
445
  }
446
 
447
  self::send_json(array(
448
+ 'error' => esc_html__('No configuration changes were provided to save.', 'wordfence-2fa'),
449
  ));
450
  }
451
 
560
  if ($userId !== 0 && Controller_Notices::shared()->dismiss_persistent_notice($userId, $noticeId))
561
  self::send_json(array('success' => true));
562
  self::send_json(array(
563
+ 'error' => esc_html__('Unable to dismiss notice', 'wordfence-2fa')
564
  ));
565
  }
566
  }
classes/controller/settings.php CHANGED
@@ -26,6 +26,7 @@ class Controller_Settings {
26
  const OPTION_DELETE_ON_DEACTIVATION = 'delete-deactivation';
27
  const OPTION_PREFIX_REQUIRED_2FA_ROLE = 'required-2fa-role';
28
  const OPTION_ENABLE_WOOCOMMERCE_INTEGRATION = 'enable-woocommerce-integration';
 
29
 
30
  //Internal
31
  const OPTION_GLOBAL_NOTICES = 'global-notices';
@@ -87,7 +88,8 @@ class Controller_Settings {
87
  self::OPTION_RECAPTCHA_THRESHOLD => array('value' => 0.5, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false),
88
  self::OPTION_LAST_SECRET_REFRESH => array('value' => 0, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false),
89
  self::OPTION_DELETE_ON_DEACTIVATION => array('value' => false, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false),
90
- self::OPTION_ENABLE_WOOCOMMERCE_INTEGRATION => array('value' => false, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false)
 
91
  ));
92
  }
93
 
@@ -126,7 +128,14 @@ class Controller_Settings {
126
  }
127
 
128
  public function get_array($key, $default = array()) {
129
- return (array) @json_decode($this->get($key, $default), true);
 
 
 
 
 
 
 
130
  }
131
 
132
  public function remove($key) {
@@ -152,6 +161,8 @@ class Controller_Settings {
152
  case self::OPTION_CAPTCHA_TEST_MODE:
153
  case self::OPTION_DISMISSED_FRESH_INSTALL_MODAL:
154
  case self::OPTION_DELETE_ON_DEACTIVATION:
 
 
155
  return true;
156
 
157
  //Int
@@ -249,6 +260,8 @@ class Controller_Settings {
249
  case self::OPTION_CAPTCHA_TEST_MODE:
250
  case self::OPTION_DISMISSED_FRESH_INSTALL_MODAL:
251
  case self::OPTION_DELETE_ON_DEACTIVATION:
 
 
252
  return $this->_truthy_to_bool($value);
253
 
254
  //Int
@@ -416,7 +429,11 @@ class Controller_Settings {
416
  public function disable_ntp_cron() {
417
  $this->set(self::OPTION_NTP_FAILURE_COUNT, -1);
418
  }
419
-
 
 
 
 
420
  /**
421
  * Utility
422
  */
26
  const OPTION_DELETE_ON_DEACTIVATION = 'delete-deactivation';
27
  const OPTION_PREFIX_REQUIRED_2FA_ROLE = 'required-2fa-role';
28
  const OPTION_ENABLE_WOOCOMMERCE_INTEGRATION = 'enable-woocommerce-integration';
29
+ const OPTION_ENABLE_LOGIN_HISTORY_COLUMNS = 'enable-login-history-columns';
30
 
31
  //Internal
32
  const OPTION_GLOBAL_NOTICES = 'global-notices';
88
  self::OPTION_RECAPTCHA_THRESHOLD => array('value' => 0.5, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false),
89
  self::OPTION_LAST_SECRET_REFRESH => array('value' => 0, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false),
90
  self::OPTION_DELETE_ON_DEACTIVATION => array('value' => false, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false),
91
+ self::OPTION_ENABLE_WOOCOMMERCE_INTEGRATION => array('value' => false, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false),
92
+ self::OPTION_ENABLE_LOGIN_HISTORY_COLUMNS => array('value' => true, 'autoload' => Model_Settings::AUTOLOAD_YES, 'allowOverwrite' => false)
93
  ));
94
  }
95
 
128
  }
129
 
130
  public function get_array($key, $default = array()) {
131
+ $value = $this->get($key, null);
132
+ if (is_string($value)) {
133
+ $value = @json_decode($value, true);
134
+ }
135
+ else {
136
+ $value = null;
137
+ }
138
+ return is_array($value) ? $value : $default;
139
  }
140
 
141
  public function remove($key) {
161
  case self::OPTION_CAPTCHA_TEST_MODE:
162
  case self::OPTION_DISMISSED_FRESH_INSTALL_MODAL:
163
  case self::OPTION_DELETE_ON_DEACTIVATION:
164
+ case self::OPTION_ENABLE_WOOCOMMERCE_INTEGRATION:
165
+ case self::OPTION_ENABLE_LOGIN_HISTORY_COLUMNS:
166
  return true;
167
 
168
  //Int
260
  case self::OPTION_CAPTCHA_TEST_MODE:
261
  case self::OPTION_DISMISSED_FRESH_INSTALL_MODAL:
262
  case self::OPTION_DELETE_ON_DEACTIVATION:
263
+ case self::OPTION_ENABLE_WOOCOMMERCE_INTEGRATION:
264
+ case self::OPTION_ENABLE_LOGIN_HISTORY_COLUMNS:
265
  return $this->_truthy_to_bool($value);
266
 
267
  //Int
429
  public function disable_ntp_cron() {
430
  $this->set(self::OPTION_NTP_FAILURE_COUNT, -1);
431
  }
432
+
433
+ public function are_login_history_columns_enabled() {
434
+ return Controller_Settings::shared()->get_bool(Controller_Settings::OPTION_ENABLE_LOGIN_HISTORY_COLUMNS, true);
435
+ }
436
+
437
  /**
438
  * Utility
439
  */
classes/controller/users.php CHANGED
@@ -494,7 +494,7 @@ class Controller_Users {
494
  $columns['wfls_2fa_status'] = esc_html__('2FA Status', 'wordfence-2fa');
495
  }
496
 
497
- if (Controller_Permissions::shared()->can_manage_settings(wp_get_current_user())) {
498
  $columns['wfls_last_login'] = esc_html__('Last Login', 'wordfence-2fa');
499
  if (Controller_CAPTCHA::shared()->enabled()) {
500
  $columns['wfls_last_captcha'] = esc_html__('Last CAPTCHA', 'wordfence-2fa');
@@ -518,7 +518,7 @@ class Controller_Users {
518
  $value = wp_kses(__('Inactive<small class="wfls-sub-status">(Grace Period)</small>', 'wordfence-2fa'), array('small'=>array('class'=>array())));
519
  }
520
  elseif (($requires2fa && !$has2fa)) {
521
- $value = wp_kses($inGracePeriod === null ? __('Locked Out<small class="wfls-sub-status">(Grace Period Disabled)</small>') : __('Locked Out<small class="wfls-sub-status">(Grace Period Exceeded)</small>', 'wordfence-2fa'), array('small'=>array('class'=>array())));
522
  }
523
  else {
524
  $value = esc_html__('Inactive', 'wordfence-2fa');
494
  $columns['wfls_2fa_status'] = esc_html__('2FA Status', 'wordfence-2fa');
495
  }
496
 
497
+ if (Controller_Settings::shared()->are_login_history_columns_enabled() && Controller_Permissions::shared()->can_manage_settings(wp_get_current_user())) {
498
  $columns['wfls_last_login'] = esc_html__('Last Login', 'wordfence-2fa');
499
  if (Controller_CAPTCHA::shared()->enabled()) {
500
  $columns['wfls_last_captcha'] = esc_html__('Last CAPTCHA', 'wordfence-2fa');
518
  $value = wp_kses(__('Inactive<small class="wfls-sub-status">(Grace Period)</small>', 'wordfence-2fa'), array('small'=>array('class'=>array())));
519
  }
520
  elseif (($requires2fa && !$has2fa)) {
521
+ $value = wp_kses($inGracePeriod === null ? __('Locked Out<small class="wfls-sub-status">(Grace Period Disabled)</small>', 'wordfence-2fa') : __('Locked Out<small class="wfls-sub-status">(Grace Period Exceeded)</small>', 'wordfence-2fa'), array('small'=>array('class'=>array())));
522
  }
523
  else {
524
  $value = esc_html__('Inactive', 'wordfence-2fa');
classes/controller/wordfencels.php CHANGED
@@ -82,13 +82,13 @@ class Controller_WordfenceLS {
82
  \wfModuleController::shared()->addOptionIndex('wfls-option-allow-remember', __('Login Security: Allow remembering device for 30 days', 'wordfence-2fa'));
83
  \wfModuleController::shared()->addOptionIndex('wfls-option-require-2fa-xml-rpc', __('Login Security: Require 2FA for XML-RPC call authentication', 'wordfence-2fa'));
84
  \wfModuleController::shared()->addOptionIndex('wfls-option-disable-xml-rpc', __('Login Security: Disable XML-RPC authentication', 'wordfence-2fa'));
85
- \wfModuleController::shared()->addOptionIndex('wfls-option-whitelist-2fa', __('Login Security: Allowlisted IP addresses that bypass 2FA', 'wordfence-2fa'));
86
  \wfModuleController::shared()->addOptionIndex('wfls-option-enable-captcha', __('Login Security: Enable reCAPTCHA on the login and user registration pages', 'wordfence-2fa'));
87
 
88
- $title = __('Login Security Options', 'wordfence-ls');
89
- $description = __('Login Security options are available on the Login Security options page', 'wordfence-ls');
90
  $url = esc_url(network_admin_url('admin.php?page=WFLS#top#settings'));
91
- $link = __('Login Security Options', 'wordfence');;
92
  \wfModuleController::shared()->addOptionBlock(<<<END
93
  <div class="wf-row">
94
  <div class="wf-col-xs-12">
@@ -319,9 +319,9 @@ END
319
  wp_localize_script('wordfence-ls-admin', 'WFLSVars', array(
320
  'ajaxurl' => admin_url('admin-ajax.php'),
321
  'nonce' => wp_create_nonce('wp-ajax'),
322
- 'modalTemplate' => Model_View::create('common/modal-prompt', array('title' => '${title}', 'message' => '${message}', 'primaryButton' => array('id' => 'wfls-generic-modal-close', 'label' => __('Close', 'wordfence'), 'link' => '#')))->render(),
323
- 'tokenInvalidTemplate' => Model_View::create('common/modal-prompt', array('title' => '${title}', 'message' => '${message}', 'primaryButton' => array('id' => 'wfls-token-invalid-modal-reload', 'label' => __('Reload', 'wordfence'), 'link' => '#')))->render(),
324
- 'modalHTMLTemplate' => Model_View::create('common/modal-prompt', array('title' => '${title}', 'message' => '{{html message}}', 'primaryButton' => array('id' => 'wfls-generic-modal-close', 'label' => __('Close', 'wordfence'), 'link' => '#')))->render(),
325
  ));
326
  }
327
  else {
@@ -367,7 +367,7 @@ END
367
  <h2 id="wfls-user-settings"><?php esc_html_e('Wordfence Login Security', 'wordfence-2fa'); ?></h2>
368
  <table class="form-table">
369
  <tr id="wordfence-ls">
370
- <th><label for="wordfence-ls-btn"><?php esc_html_e('2FA Status'); ?></label></th>
371
  <td>
372
  <?php if ($userAllowed2fa): ?>
373
  <p>
@@ -546,9 +546,9 @@ END
546
  'ip' => Model_Request::current()->ip(),
547
  'canEnable2FA' => Controller_Users::shared()->can_activate_2fa($user),
548
  ));
549
- wp_mail($user->user_email, __('Login Verification Required', 'wordfence-ls'), $view->render(), "Content-Type: text/html");
550
 
551
- return new \WP_Error('wfls_captcha_verify', wp_kses(__('<strong>VERIFICATION REQUIRED</strong>: Additional verification is required for login. Please check the email address associated with the account for a verification link.', 'wordfence-ls'), array('strong'=>array())));
552
  }
553
  //else -- Can't generate payload due to host failure, allow it to proceed
554
  }
@@ -871,7 +871,7 @@ END
871
  else {
872
  $sections[] = array(
873
  'tab' => new Model_Tab('manage', 'manage', __('Two-Factor Authentication', 'wordfence-2fa'), __('Two-Factor Authentication', 'wordfence-2fa')),
874
- 'title' => new Model_Title('manage', __('Two-Factor Authentication', 'wordfence-2fa'), Controller_Support::supportURL(Controller_Support::ITEM_MODULE_LOGIN_SECURITY_2FA), new Model_HTML(wp_kses(__('Learn more<span class="wfls-hidden-xs"> about Two-Factor Authentication</span>', 'wordfence'), array('span'=>array('class'=>array()))))),
875
  'content' => new Model_View('page/manage', array(
876
  'user' => $user,
877
  'canEditUsers' => $canEditUsers,
@@ -881,7 +881,7 @@ END
881
  if ($administrator) {
882
  $sections[] = array(
883
  'tab' => new Model_Tab('settings', 'settings', __('Settings', 'wordfence-2fa'), __('Settings', 'wordfence-2fa')),
884
- 'title' => new Model_Title('settings', __('Login Security Settings', 'wordfence-2fa'), Controller_Support::supportURL(Controller_Support::ITEM_MODULE_LOGIN_SECURITY), new Model_HTML(wp_kses(__('Learn more<span class="wfls-hidden-xs"> about Login Security</span>', 'wordfence'), array('span'=>array('class'=>array()))))),
885
  'content' => new Model_View('page/settings', array(
886
  'hasWoocommerce' => $this->has_woocommerce()
887
  )),
@@ -907,18 +907,18 @@ END
907
  if ($requireCaptcha) {
908
  if ($token === null && !$captchaController->test_mode()) {
909
  return array(
910
- 'message' => wp_kses(__('<strong>REGISTRATION ATTEMPT BLOCKED</strong>: This site requires a security token created when the page loads for all registration attempts. Please ensure JavaScript is enabled and try again.', 'wordfence-ls'), array('strong'=>array())),
911
  'category' => 'wfls_captcha_required'
912
  );
913
  }
914
  $score = $captchaController->score($token);
915
  if ($score === false && !$captchaController->test_mode()) {
916
  return array(
917
- 'message' => wp_kses(__('<strong>REGISTRATION ATTEMPT BLOCKED</strong>: The security token for the login attempt was invalid or expired. Please reload the page and try again.', 'wordfence-ls'), array('strong'=>array())),
918
  'category' => 'wfls_captcha_required'
919
  );
920
  }
921
- Controller_Users::shared()->record_captcha_score(null, $token);
922
  if (!$captchaController->is_human($score)) {
923
  $encryptedIP = Model_Symmetric::encrypt(Model_Request::current()->ip());
924
  $encryptedScore = Model_Symmetric::encrypt($score);
@@ -927,10 +927,10 @@ END
927
  );
928
  if ($encryptedIP && $encryptedScore && filter_var(get_site_option('admin_email'), FILTER_VALIDATE_EMAIL)) {
929
  $jwt = new Model_JWT(array('ip' => $encryptedIP, 'score' => $encryptedScore), Controller_Time::time() + 600);
930
- $result['message'] = wp_kses(sprintf(__('<strong>REGISTRATION BLOCKED</strong>: The registration request was blocked because it was flagged as spam. Please try again or <a href="#" class="wfls-registration-captcha-contact" data-token="%s">contact the site owner</a> for help.', 'wordfence-ls'), esc_attr((string)$jwt)), array('strong'=>array(), 'a'=>array('href'=>array(), 'class'=>array(), 'data-token'=>array())));
931
  }
932
  else {
933
- $result['message'] = wp_kses(__('<strong>REGISTRATION BLOCKED</strong>: The registration request was blocked because it was flagged as spam. Please try again or contact the site owner for help.', 'wordfence-ls'), array('strong'=>array()));
934
  }
935
  return $result;
936
  }
82
  \wfModuleController::shared()->addOptionIndex('wfls-option-allow-remember', __('Login Security: Allow remembering device for 30 days', 'wordfence-2fa'));
83
  \wfModuleController::shared()->addOptionIndex('wfls-option-require-2fa-xml-rpc', __('Login Security: Require 2FA for XML-RPC call authentication', 'wordfence-2fa'));
84
  \wfModuleController::shared()->addOptionIndex('wfls-option-disable-xml-rpc', __('Login Security: Disable XML-RPC authentication', 'wordfence-2fa'));
85
+ \wfModuleController::shared()->addOptionIndex('wfls-option-whitelist-2fa', __('Login Security: Allowlisted IP addresses that bypass 2FA and reCAPTCHA', 'wordfence-2fa'));
86
  \wfModuleController::shared()->addOptionIndex('wfls-option-enable-captcha', __('Login Security: Enable reCAPTCHA on the login and user registration pages', 'wordfence-2fa'));
87
 
88
+ $title = __('Login Security Options', 'wordfence-2fa');
89
+ $description = __('Login Security options are available on the Login Security options page', 'wordfence-2fa');
90
  $url = esc_url(network_admin_url('admin.php?page=WFLS#top#settings'));
91
+ $link = __('Login Security Options', 'wordfence-2fa');;
92
  \wfModuleController::shared()->addOptionBlock(<<<END
93
  <div class="wf-row">
94
  <div class="wf-col-xs-12">
319
  wp_localize_script('wordfence-ls-admin', 'WFLSVars', array(
320
  'ajaxurl' => admin_url('admin-ajax.php'),
321
  'nonce' => wp_create_nonce('wp-ajax'),
322
+ 'modalTemplate' => Model_View::create('common/modal-prompt', array('title' => '${title}', 'message' => '${message}', 'primaryButton' => array('id' => 'wfls-generic-modal-close', 'label' => __('Close', 'wordfence-2fa'), 'link' => '#')))->render(),
323
+ 'tokenInvalidTemplate' => Model_View::create('common/modal-prompt', array('title' => '${title}', 'message' => '${message}', 'primaryButton' => array('id' => 'wfls-token-invalid-modal-reload', 'label' => __('Reload', 'wordfence-2fa'), 'link' => '#')))->render(),
324
+ 'modalHTMLTemplate' => Model_View::create('common/modal-prompt', array('title' => '${title}', 'message' => '{{html message}}', 'primaryButton' => array('id' => 'wfls-generic-modal-close', 'label' => __('Close', 'wordfence-2fa'), 'link' => '#')))->render(),
325
  ));
326
  }
327
  else {
367
  <h2 id="wfls-user-settings"><?php esc_html_e('Wordfence Login Security', 'wordfence-2fa'); ?></h2>
368
  <table class="form-table">
369
  <tr id="wordfence-ls">
370
+ <th><label for="wordfence-ls-btn"><?php esc_html_e('2FA Status', 'wordfence-2fa'); ?></label></th>
371
  <td>
372
  <?php if ($userAllowed2fa): ?>
373
  <p>
546
  'ip' => Model_Request::current()->ip(),
547
  'canEnable2FA' => Controller_Users::shared()->can_activate_2fa($user),
548
  ));
549
+ wp_mail($user->user_email, __('Login Verification Required', 'wordfence-2fa'), $view->render(), "Content-Type: text/html");
550
 
551
+ return new \WP_Error('wfls_captcha_verify', wp_kses(__('<strong>VERIFICATION REQUIRED</strong>: Additional verification is required for login. Please check the email address associated with the account for a verification link.', 'wordfence-2fa'), array('strong'=>array())));
552
  }
553
  //else -- Can't generate payload due to host failure, allow it to proceed
554
  }
871
  else {
872
  $sections[] = array(
873
  'tab' => new Model_Tab('manage', 'manage', __('Two-Factor Authentication', 'wordfence-2fa'), __('Two-Factor Authentication', 'wordfence-2fa')),
874
+ 'title' => new Model_Title('manage', __('Two-Factor Authentication', 'wordfence-2fa'), Controller_Support::supportURL(Controller_Support::ITEM_MODULE_LOGIN_SECURITY_2FA), new Model_HTML(wp_kses(__('Learn more<span class="wfls-hidden-xs"> about Two-Factor Authentication</span>', 'wordfence-2fa'), array('span'=>array('class'=>array()))))),
875
  'content' => new Model_View('page/manage', array(
876
  'user' => $user,
877
  'canEditUsers' => $canEditUsers,
881
  if ($administrator) {
882
  $sections[] = array(
883
  'tab' => new Model_Tab('settings', 'settings', __('Settings', 'wordfence-2fa'), __('Settings', 'wordfence-2fa')),
884
+ 'title' => new Model_Title('settings', __('Login Security Settings', 'wordfence-2fa'), Controller_Support::supportURL(Controller_Support::ITEM_MODULE_LOGIN_SECURITY), new Model_HTML(wp_kses(__('Learn more<span class="wfls-hidden-xs"> about Login Security</span>', 'wordfence-2fa'), array('span'=>array('class'=>array()))))),
885
  'content' => new Model_View('page/settings', array(
886
  'hasWoocommerce' => $this->has_woocommerce()
887
  )),
907
  if ($requireCaptcha) {
908
  if ($token === null && !$captchaController->test_mode()) {
909
  return array(
910
+ 'message' => wp_kses(__('<strong>REGISTRATION ATTEMPT BLOCKED</strong>: This site requires a security token created when the page loads for all registration attempts. Please ensure JavaScript is enabled and try again.', 'wordfence-2fa'), array('strong'=>array())),
911
  'category' => 'wfls_captcha_required'
912
  );
913
  }
914
  $score = $captchaController->score($token);
915
  if ($score === false && !$captchaController->test_mode()) {
916
  return array(
917
+ 'message' => wp_kses(__('<strong>REGISTRATION ATTEMPT BLOCKED</strong>: The security token for the login attempt was invalid or expired. Please reload the page and try again.', 'wordfence-2fa'), array('strong'=>array())),
918
  'category' => 'wfls_captcha_required'
919
  );
920
  }
921
+ Controller_Users::shared()->record_captcha_score(null, $score);
922
  if (!$captchaController->is_human($score)) {
923
  $encryptedIP = Model_Symmetric::encrypt(Model_Request::current()->ip());
924
  $encryptedScore = Model_Symmetric::encrypt($score);
927
  );
928
  if ($encryptedIP && $encryptedScore && filter_var(get_site_option('admin_email'), FILTER_VALIDATE_EMAIL)) {
929
  $jwt = new Model_JWT(array('ip' => $encryptedIP, 'score' => $encryptedScore), Controller_Time::time() + 600);
930
+ $result['message'] = wp_kses(sprintf(__('<strong>REGISTRATION BLOCKED</strong>: The registration request was blocked because it was flagged as spam. Please try again or <a href="#" class="wfls-registration-captcha-contact" data-token="%s">contact the site owner</a> for help.', 'wordfence-2fa'), esc_attr((string)$jwt)), array('strong'=>array(), 'a'=>array('href'=>array(), 'class'=>array(), 'data-token'=>array())));
931
  }
932
  else {
933
+ $result['message'] = wp_kses(__('<strong>REGISTRATION BLOCKED</strong>: The registration request was blocked because it was flagged as spam. Please try again or contact the site owner for help.', 'wordfence-2fa'), array('strong'=>array()));
934
  }
935
  return $result;
936
  }
css/{admin-global.1634043539.css → admin-global.1654178513.css} RENAMED
File without changes
css/{admin.1634043539.css → admin.1654178513.css} RENAMED
File without changes
css/{colorbox.1634043539.css → colorbox.1654178513.css} RENAMED
File without changes
css/{font-awesome.1634043539.css → font-awesome.1654178513.css} RENAMED
File without changes
css/{ionicons.1634043539.css → ionicons.1654178513.css} RENAMED
File without changes
css/{jquery-ui.min.1634043539.css → jquery-ui.min.1654178513.css} RENAMED
File without changes
css/{jquery-ui.structure.min.1634043539.css → jquery-ui.structure.min.1654178513.css} RENAMED
File without changes
css/{jquery-ui.theme.min.1634043539.css → jquery-ui.theme.min.1654178513.css} RENAMED
File without changes
css/{login.1634043539.css → login.1654178513.css} RENAMED
File without changes
css/{wfselect2.min.1634043539.css → wfselect2.min.1654178513.css} RENAMED
File without changes
js/{Chart.bundle.min.1634043539.js → Chart.bundle.min.1654178513.js} RENAMED
File without changes
js/{admin-global.1634043539.js → admin-global.1654178513.js} RENAMED
File without changes
js/{admin.1634043539.js → admin.1654178513.js} RENAMED
File without changes
js/{jquery.colorbox.1634043539.js → jquery.colorbox.1654178513.js} RENAMED
File without changes
js/{jquery.colorbox.min.1634043539.js → jquery.colorbox.min.1654178513.js} RENAMED
File without changes
js/{jquery.qrcode.min.1634043539.js → jquery.qrcode.min.1654178513.js} RENAMED
File without changes
js/{jquery.tmpl.min.1634043539.js → jquery.tmpl.min.1654178513.js} RENAMED
File without changes
js/{login.1634043539.js → login.1654178513.js} RENAMED
@@ -340,7 +340,7 @@
340
  var overlay = $('<div id="wfls-prompt-overlay"></div>');
341
  var wrapper = $('<div id="wfls-prompt-wrapper"></div>');
342
  var label = $('<p><label for="wfls-token">2FA Code <a href="javascript:void(0)" class="wfls-2fa-code-help wfls-tooltip-trigger" title="The 2FA Code can be found within the authenticator app you used when first activating two-factor authentication. You may also use one of your recovery codes."><i class="dashicons dashicons-editor-help"></i></a></label></p>');
343
- var field = $('<p><input type="text" name="wfls-token" id="wfls-token" aria-describedby="wfls-token-error" class="input" value="" size="6" autocomplete="off"/></p>');
344
  var remember = $('<p class="wfls-remember-device-wrapper"><label for="wfls-remember-device"><input name="wfls-remember-device" type="checkbox" id="wfls-remember-device" value="1" /> Remember for 30 days</label></p>');
345
  var button = $('<p class="submit"><input type="submit" name="wfls-token-submit" id="wfls-token-submit" class="button button-primary button-large" value="Log In"/></p>');
346
  wrapper.append(label);
340
  var overlay = $('<div id="wfls-prompt-overlay"></div>');
341
  var wrapper = $('<div id="wfls-prompt-wrapper"></div>');
342
  var label = $('<p><label for="wfls-token">2FA Code <a href="javascript:void(0)" class="wfls-2fa-code-help wfls-tooltip-trigger" title="The 2FA Code can be found within the authenticator app you used when first activating two-factor authentication. You may also use one of your recovery codes."><i class="dashicons dashicons-editor-help"></i></a></label></p>');
343
+ var field = $('<p><input type="text" name="wfls-token" id="wfls-token" aria-describedby="wfls-token-error" class="input" value="" size="6" autocomplete="one-time-code"/></p>');
344
  var remember = $('<p class="wfls-remember-device-wrapper"><label for="wfls-remember-device"><input name="wfls-remember-device" type="checkbox" id="wfls-remember-device" value="1" /> Remember for 30 days</label></p>');
345
  var button = $('<p class="submit"><input type="submit" name="wfls-token-submit" id="wfls-token-submit" class="button button-primary button-large" value="Log In"/></p>');
346
  wrapper.append(label);
js/{wfselect2.min.1634043539.js → wfselect2.min.1654178513.js} RENAMED
File without changes
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: security, login security, 2fa, two factor authentication, captcha, xml-rpc
4
  Requires at least: 4.5
5
  Requires PHP: 5.3
6
  Tested up to: 6.0
7
- Stable tag: 1.0.9
8
 
9
  Secure your website with Wordfence Login Security, providing two-factor authentication, login and registration CAPTCHA, and XML-RPC protection.
10
 
@@ -58,6 +58,14 @@ Secure your website with Wordfence Login Security.
58
 
59
  == Changelog ==
60
 
 
 
 
 
 
 
 
 
61
  = 1.0.9 - October 12, 2021 =
62
  * Fix: Prevented login errors with WooCommerce integration when manual username entry is enabled on the WooCommerce registration form
63
  * Fix: Corrected theme incompatibilities with WooCommerce integration
4
  Requires at least: 4.5
5
  Requires PHP: 5.3
6
  Tested up to: 6.0
7
+ Stable tag: 1.0.10
8
 
9
  Secure your website with Wordfence Login Security, providing two-factor authentication, login and registration CAPTCHA, and XML-RPC protection.
10
 
58
 
59
  == Changelog ==
60
 
61
+ = 1.0.10 - June 2, 2022 =
62
+ * Improvement: Added option to toggle display of last login column on WP Users page
63
+ * Improvement: Improved autocomplete support for 2FA code on Apple devices
64
+ * Fix: Corrected issue that prevented reCAPTCHA scores from being recorded
65
+ * Fix: Prevented invalid JSON setting values from triggering fatal errors
66
+ * Fix: Made text domains consistent for translation support
67
+ * Fix: Clarified that allowlisted IP addresses also bypass reCAPTCHA
68
+
69
  = 1.0.9 - October 12, 2021 =
70
  * Fix: Prevented login errors with WooCommerce integration when manual username entry is enabled on the WooCommerce registration form
71
  * Fix: Corrected theme incompatibilities with WooCommerce integration
views/email/login-verification.php CHANGED
@@ -8,15 +8,15 @@ if (!defined('WORDFENCE_LS_VERSION')) { exit; }
8
  * @var bool $canEnable2FA Whether or not the user this is being sent to can enable 2FA. Optional
9
  */
10
  ?>
11
- <strong><?php echo wp_kses(sprintf(__('Please verify a login attempt for your account on <a href="%s"><strong>%s</strong></a>.', 'wordfence-ls'), esc_url($siteURL), $siteName), array('a'=>array('href'=>array()), 'strong'=>array())); ?></strong>
12
  <br><br>
13
- <?php echo '<strong>' . esc_html__('Request Time:', 'wordfence-ls') . '</strong> ' . esc_html(\WordfenceLS\Controller_Time::format_local_time('F j, Y h:i:s A')); ?><br>
14
- <?php echo '<strong>' . esc_html__('IP:', 'wordfence-ls') . '</strong> ' . esc_html($ip); ?>
15
  <br><br>
16
- <?php echo wp_kses(__('The request was flagged as suspicious, and we need verification that you attempted to log in to allow it to proceed. This verification link <b>will be valid for 15 minutes</b> from the time it was sent. If you did not attempt this login, please change your password immediately.', 'wordfence-ls'), array('b'=>array())); ?>
17
  <br><br>
18
  <?php if (isset($canEnable2FA) && $canEnable2FA): ?>
19
- <?php esc_html_e('You may bypass this verification step permanently by enabling two-factor authentication on your account.', 'wordfence-ls'); ?>
20
  <br><br>
21
  <?php endif; ?>
22
- <?php echo wp_kses(sprintf(__('<a href="%s"><b>Verify and Log In</b></a>', 'wordfence-ls'), esc_url($verificationURL)), array('a'=>array('href'=>array()), 'b'=>array())); ?>
8
  * @var bool $canEnable2FA Whether or not the user this is being sent to can enable 2FA. Optional
9
  */
10
  ?>
11
+ <strong><?php echo wp_kses(sprintf(__('Please verify a login attempt for your account on <a href="%s"><strong>%s</strong></a>.', 'wordfence-2fa'), esc_url($siteURL), $siteName), array('a'=>array('href'=>array()), 'strong'=>array())); ?></strong>
12
  <br><br>
13
+ <?php echo '<strong>' . esc_html__('Request Time:', 'wordfence-2fa') . '</strong> ' . esc_html(\WordfenceLS\Controller_Time::format_local_time('F j, Y h:i:s A')); ?><br>
14
+ <?php echo '<strong>' . esc_html__('IP:', 'wordfence-2fa') . '</strong> ' . esc_html($ip); ?>
15
  <br><br>
16
+ <?php echo wp_kses(__('The request was flagged as suspicious, and we need verification that you attempted to log in to allow it to proceed. This verification link <b>will be valid for 15 minutes</b> from the time it was sent. If you did not attempt this login, please change your password immediately.', 'wordfence-2fa'), array('b'=>array())); ?>
17
  <br><br>
18
  <?php if (isset($canEnable2FA) && $canEnable2FA): ?>
19
+ <?php esc_html_e('You may bypass this verification step permanently by enabling two-factor authentication on your account.', 'wordfence-2fa'); ?>
20
  <br><br>
21
  <?php endif; ?>
22
+ <?php echo wp_kses(sprintf(__('<a href="%s"><b>Verify and Log In</b></a>', 'wordfence-2fa'), esc_url($verificationURL)), array('a'=>array('href'=>array()), 'b'=>array())); ?>
views/manage/activate.php CHANGED
@@ -122,8 +122,8 @@ if (!defined('WORDFENCE_LS_VERSION')) { exit; }
122
  echo \WordfenceLS\Model_View::create('common/modal-prompt', array(
123
  'title' => __('Download Recovery Codes', 'wordfence-2fa'),
124
  'message' => __('Reminder: If you lose access to your authenticator device, you can use recovery codes to log in. If you have not saved a copy of your recovery codes, we recommend downloading them now.', 'wordfence-2fa'),
125
- 'primaryButton' => array('id' => 'wfls-recovery-skipped-download', 'label' => __('Download', 'wordfence'), 'link' => '#'),
126
- 'secondaryButtons' => array(array('id' => 'wfls-recovery-skipped-skip', 'label' => __('Skip', 'wordfence'), 'link' => '#')),
127
  ))->render();
128
  ?>
129
  </script>
122
  echo \WordfenceLS\Model_View::create('common/modal-prompt', array(
123
  'title' => __('Download Recovery Codes', 'wordfence-2fa'),
124
  'message' => __('Reminder: If you lose access to your authenticator device, you can use recovery codes to log in. If you have not saved a copy of your recovery codes, we recommend downloading them now.', 'wordfence-2fa'),
125
+ 'primaryButton' => array('id' => 'wfls-recovery-skipped-download', 'label' => __('Download', 'wordfence-2fa'), 'link' => '#'),
126
+ 'secondaryButtons' => array(array('id' => 'wfls-recovery-skipped-skip', 'label' => __('Skip', 'wordfence-2fa'), 'link' => '#')),
127
  ))->render();
128
  ?>
129
  </script>
views/manage/code.php CHANGED
@@ -10,7 +10,7 @@ if (!defined('WORDFENCE_LS_VERSION')) { exit; }
10
  <div class="wfls-block-header wfls-block-header-border-bottom">
11
  <div class="wfls-block-header-content">
12
  <div class="wfls-block-title">
13
- <strong><?php esc_html_e('1. Scan Code or Enter Key', 'wordfence'); ?></strong>
14
  </div>
15
  </div>
16
  </div>
10
  <div class="wfls-block-header wfls-block-header-border-bottom">
11
  <div class="wfls-block-header-content">
12
  <div class="wfls-block-title">
13
+ <strong><?php esc_html_e('1. Scan Code or Enter Key', 'wordfence-2fa'); ?></strong>
14
  </div>
15
  </div>
16
  </div>
views/manage/deactivate.php CHANGED
@@ -26,10 +26,10 @@ if ($ownUser->ID == $user->ID) {
26
  <script type="text/x-jquery-template" id="wfls-tmpl-deactivate-prompt">
27
  <?php
28
  echo \WordfenceLS\Model_View::create('common/modal-prompt', array(
29
- 'title' => __('Deactivate 2FA', 'wordfence'),
30
- 'message' => __('Are you sure you want to deactivate two-factor authentication?'),
31
- 'primaryButton' => array('id' => 'wfls-deactivate-prompt-cancel', 'label' => __('Cancel', 'wordfence'), 'link' => '#'),
32
- 'secondaryButtons' => array(array('id' => 'wfls-deactivate-prompt-confirm', 'label' => __('Deactivate', 'wordfence'), 'link' => '#')),
33
  ))->render();
34
  ?>
35
  </script>
26
  <script type="text/x-jquery-template" id="wfls-tmpl-deactivate-prompt">
27
  <?php
28
  echo \WordfenceLS\Model_View::create('common/modal-prompt', array(
29
+ 'title' => __('Deactivate 2FA', 'wordfence-2fa'),
30
+ 'message' => __('Are you sure you want to deactivate two-factor authentication?', 'wordfence-2fa'),
31
+ 'primaryButton' => array('id' => 'wfls-deactivate-prompt-cancel', 'label' => __('Cancel', 'wordfence-2fa'), 'link' => '#'),
32
+ 'secondaryButtons' => array(array('id' => 'wfls-deactivate-prompt-confirm', 'label' => __('Deactivate', 'wordfence-2fa'), 'link' => '#')),
33
  ))->render();
34
  ?>
35
  </script>
views/manage/regenerate.php CHANGED
@@ -21,10 +21,10 @@ if (!defined('WORDFENCE_LS_VERSION')) { exit; }
21
  <script type="text/x-jquery-template" id="wfls-tmpl-recovery-prompt">
22
  <?php
23
  echo \WordfenceLS\Model_View::create('common/modal-prompt', array(
24
- 'title' => __('Generate New Recovery Codes', 'wordfence'),
25
- 'message' => __('Are you sure you want to generate new recovery codes? Any remaining unused codes will be disabled.'),
26
- 'primaryButton' => array('id' => 'wfls-recovery-prompt-cancel', 'label' => __('Cancel', 'wordfence'), 'link' => '#'),
27
- 'secondaryButtons' => array(array('id' => 'wfls-recovery-prompt-confirm', 'label' => __('Generate', 'wordfence'), 'link' => '#')),
28
  ))->render();
29
  ?>
30
  </script>
21
  <script type="text/x-jquery-template" id="wfls-tmpl-recovery-prompt">
22
  <?php
23
  echo \WordfenceLS\Model_View::create('common/modal-prompt', array(
24
+ 'title' => __('Generate New Recovery Codes', 'wordfence-2fa'),
25
+ 'message' => __('Are you sure you want to generate new recovery codes? Any remaining unused codes will be disabled.', 'wordfence-2fa'),
26
+ 'primaryButton' => array('id' => 'wfls-recovery-prompt-cancel', 'label' => __('Cancel', 'wordfence-2fa'), 'link' => '#'),
27
+ 'secondaryButtons' => array(array('id' => 'wfls-recovery-prompt-confirm', 'label' => __('Generate', 'wordfence-2fa'), 'link' => '#')),
28
  ))->render();
29
  ?>
30
  </script>
views/options/option-captcha-threshold.php CHANGED
@@ -45,7 +45,7 @@ $selectOptions = array(
45
  <li class="wfls-option-spacer"></li>
46
  <li>
47
  <canvas id="wfls-recaptcha-score-history"></canvas>
48
- <div class="wfls-center"><a href="#" id="wfls-reset-recaptcha-score-stats" class="wfls-text-small"><?php esc_html_e('Reset Score Statistics', 'wordfence'); ?></a></div>
49
  </li>
50
  </ul>
51
  </li>
@@ -132,4 +132,4 @@ $selectOptions = array(
132
  }
133
  });
134
  })(jQuery);
135
- </script>
45
  <li class="wfls-option-spacer"></li>
46
  <li>
47
  <canvas id="wfls-recaptcha-score-history"></canvas>
48
+ <div class="wfls-center"><a href="#" id="wfls-reset-recaptcha-score-stats" class="wfls-text-small"><?php esc_html_e('Reset Score Statistics', 'wordfence-2fa'); ?></a></div>
49
  </li>
50
  </ul>
51
  </li>
132
  }
133
  });
134
  })(jQuery);
135
+ </script>
views/options/option-captcha.php CHANGED
@@ -17,9 +17,9 @@ $secretValue = \WordfenceLS\Controller_Settings::shared()->get($secretOptionName
17
  <li class="wfls-option-title">
18
  <ul class="wfls-flex-vertical wfls-flex-align-left">
19
  <li>
20
- <strong id="wfls-enable-auth-captcha-label"><?php esc_html_e('Enable reCAPTCHA on the login and user registration pages', 'wordfence-ls'); ?></strong>
21
  </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
  </ul>
24
  </li>
25
  </ul>
@@ -30,11 +30,11 @@ $secretValue = \WordfenceLS\Controller_Settings::shared()->get($secretOptionName
30
  <li>
31
  <table>
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 esc_html_e('reCAPTCHA v3 Site Key', 'wordfence-ls'); ?></th>
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
  </tr>
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 esc_html_e('reCAPTCHA v3 Secret', 'wordfence-ls'); ?></th>
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
  </tr>
40
  </table>
@@ -44,7 +44,7 @@ $secretValue = \WordfenceLS\Controller_Settings::shared()->get($secretOptionName
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 echo wp_kses(__('Note: This feature requires a free site key and secret for the <a href="https://www.google.com/recaptcha/about/" target="_blank" rel="noopener noreferrer">Google reCAPTCHA v3 Service</a>. To set up new reCAPTCHA keys, log into your Google account and go to the <a href="https://www.google.com/recaptcha/admin" target="_blank" rel="noopener noreferrer">reCAPTCHA admin page</a>.', 'wordfence-ls'), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()))); ?></li>
48
  </ul>
49
  </li>
50
  </ul>
17
  <li class="wfls-option-title">
18
  <ul class="wfls-flex-vertical wfls-flex-align-left">
19
  <li>
20
+ <strong id="wfls-enable-auth-captcha-label"><?php esc_html_e('Enable reCAPTCHA on the login and user registration pages', 'wordfence-2fa'); ?></strong>
21
  </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-2fa'), \WordfenceLS\Controller_Support::esc_supportURL(\WordfenceLS\Controller_Support::ITEM_MODULE_LOGIN_SECURITY_CAPTCHA)); ?></li>
23
  </ul>
24
  </li>
25
  </ul>
30
  <li>
31
  <table>
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 esc_html_e('reCAPTCHA v3 Site Key', 'wordfence-2fa'); ?></th>
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
  </tr>
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 esc_html_e('reCAPTCHA v3 Secret', 'wordfence-2fa'); ?></th>
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
  </tr>
40
  </table>
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 echo wp_kses(__('Note: This feature requires a free site key and secret for the <a href="https://www.google.com/recaptcha/about/" target="_blank" rel="noopener noreferrer">Google reCAPTCHA v3 Service</a>. To set up new reCAPTCHA keys, log into your Google account and go to the <a href="https://www.google.com/recaptcha/admin" target="_blank" rel="noopener noreferrer">reCAPTCHA admin page</a>.', 'wordfence-2fa'), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()))); ?></li>
48
  </ul>
49
  </li>
50
  </ul>
views/options/option-roles.php CHANGED
@@ -51,7 +51,7 @@ foreach ($options as $option) {
51
  <li class="wfls-2fa-grace-period-container">
52
  <label for="wfls-2fa-grace-period" class="wfls-primary-label"><?php esc_html_e('Grace Period', 'wordfence-2fa') ?></label>
53
  <input id="wfls-2fa-grace-period" type="text" pattern="[0-9]+" value="<?php echo (int)$gracePeriod; ?>" class="wfls-option-input wfls-option-input-required" name="<?php echo esc_html(Controller_Settings::OPTION_REQUIRE_2FA_USER_GRACE_PERIOD) ?>" maxlength="2">
54
- <label for="wfls-2fa-grace-period"><?php esc_html_e('days') ?></label>
55
  <div id="wfls-grace-period-zero-warning" style="display: none;">
56
  <strong><?php esc_html_e('Setting the grace period to 0 will prevent users in roles where 2FA is required, including newly created users, from logging in if they have not already enabled two-factor authentication.', 'wordfence-2fa') ?></strong>
57
  <a href="<?php echo esc_attr(\WordfenceLS\Controller_Support::esc_supportURL(\WordfenceLS\Controller_Support::ITEM_MODULE_LOGIN_SECURITY_ROLES)) ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Learn More', 'wordfence-2fa') ?></a>
@@ -65,8 +65,8 @@ foreach ($options as $option) {
65
  <option value="<?php echo esc_attr($role) ?>"><?php echo esc_html($label) ?></option>
66
  <?php endforeach ?>
67
  </select>
68
- <button class="wfls-btn wfls-btn-default wfls-btn-sm" id="wfls-send-grace-period-notification"><?php esc_html_e('Notify') ?></button>
69
- <small><?php esc_html_e('Send an email to users with the selected role to notify them of the grace period for enabling 2FA.') ?></small>
70
  </li>
71
  <?php endif ?>
72
  </ul>
51
  <li class="wfls-2fa-grace-period-container">
52
  <label for="wfls-2fa-grace-period" class="wfls-primary-label"><?php esc_html_e('Grace Period', 'wordfence-2fa') ?></label>
53
  <input id="wfls-2fa-grace-period" type="text" pattern="[0-9]+" value="<?php echo (int)$gracePeriod; ?>" class="wfls-option-input wfls-option-input-required" name="<?php echo esc_html(Controller_Settings::OPTION_REQUIRE_2FA_USER_GRACE_PERIOD) ?>" maxlength="2">
54
+ <label for="wfls-2fa-grace-period"><?php esc_html_e('days', 'wordfence-2fa') ?></label>
55
  <div id="wfls-grace-period-zero-warning" style="display: none;">
56
  <strong><?php esc_html_e('Setting the grace period to 0 will prevent users in roles where 2FA is required, including newly created users, from logging in if they have not already enabled two-factor authentication.', 'wordfence-2fa') ?></strong>
57
  <a href="<?php echo esc_attr(\WordfenceLS\Controller_Support::esc_supportURL(\WordfenceLS\Controller_Support::ITEM_MODULE_LOGIN_SECURITY_ROLES)) ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Learn More', 'wordfence-2fa') ?></a>
65
  <option value="<?php echo esc_attr($role) ?>"><?php echo esc_html($label) ?></option>
66
  <?php endforeach ?>
67
  </select>
68
+ <button class="wfls-btn wfls-btn-default wfls-btn-sm" id="wfls-send-grace-period-notification"><?php esc_html_e('Notify', 'wordfence-2fa') ?></button>
69
+ <small><?php esc_html_e('Send an email to users with the selected role to notify them of the grace period for enabling 2FA.', 'wordfence-2fa') ?></small>
70
  </li>
71
  <?php endif ?>
72
  </ul>
views/options/option-select.php CHANGED
@@ -19,7 +19,7 @@ $id = 'wfls-option-' . preg_replace('/[^a-z0-9]/i', '-', $selectOptionName);
19
  <li class="wfls-option-spacer"></li>
20
  <li class="wfls-option-content">
21
  <ul>
22
- <li class="wfls-option-title"><span id="<?php echo esc_attr($id); ?>-label"><?php echo esc_html($title); ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?></li>
23
  <li class="wfls-option-select wfls-padding-add-top-xs-small">
24
  <select<?php echo (!(!wfConfig::p() && isset($premium) && $premium) ? '' : ' disabled'); ?> aria-labelledby="<?php echo esc_attr($id); ?>-label">
25
  <?php foreach ($selectOptions as $o): ?>
19
  <li class="wfls-option-spacer"></li>
20
  <li class="wfls-option-content">
21
  <ul>
22
+ <li class="wfls-option-title"><span id="<?php echo esc_attr($id); ?>-label"><?php echo esc_html($title); ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence-2fa') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?></li>
23
  <li class="wfls-option-select wfls-padding-add-top-xs-small">
24
  <select<?php echo (!(!wfConfig::p() && isset($premium) && $premium) ? '' : ' disabled'); ?> aria-labelledby="<?php echo esc_attr($id); ?>-label">
25
  <?php foreach ($selectOptions as $o): ?>
views/options/option-text.php CHANGED
@@ -27,7 +27,7 @@ $id = 'wfls-option-' . preg_replace('/[^a-z0-9]/i', '-', $textOptionName);
27
  <ul class="wfls-flex-vertical wfls-flex-align-left">
28
  <li>
29
  <?php endif; ?>
30
- <span id="<?php echo esc_attr($id); ?>-label"><?php echo esc_html($title); ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?>
31
  <?php if (isset($subtitle)): ?>
32
  </li>
33
  <li class="wfls-option-subtitle"><?php echo esc_html($subtitle); ?></li>
27
  <ul class="wfls-flex-vertical wfls-flex-align-left">
28
  <li>
29
  <?php endif; ?>
30
+ <span id="<?php echo esc_attr($id); ?>-label"><?php echo esc_html($title); ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence-2fa') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?>
31
  <?php if (isset($subtitle)): ?>
32
  </li>
33
  <li class="wfls-option-subtitle"><?php echo esc_html($subtitle); ?></li>
views/options/option-toggled-boolean-switch.php CHANGED
@@ -29,7 +29,7 @@ $id = 'wfls-option-' . preg_replace('/[^a-z0-9]/i', '-', $optionName);
29
  <ul class="wfls-flex-vertical wfls-flex-align-left">
30
  <li>
31
  <?php endif; ?>
32
- <span id="<?php echo esc_attr($id); ?>-label"><?php echo (!empty($title)) ? esc_html($title) : ''; echo (!empty($htmlTitle)) ? wp_kses($htmlTitle, 'post') : ''; ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?>
33
  <?php if (isset($subtitleHTML)): ?>
34
  </li>
35
  <li class="wfls-option-subtitle"><?php echo $subtitleHTML; ?></li>
29
  <ul class="wfls-flex-vertical wfls-flex-align-left">
30
  <li>
31
  <?php endif; ?>
32
+ <span id="<?php echo esc_attr($id); ?>-label"><?php echo (!empty($title)) ? esc_html($title) : ''; echo (!empty($htmlTitle)) ? wp_kses($htmlTitle, 'post') : ''; ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence-2fa') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?>
33
  <?php if (isset($subtitleHTML)): ?>
34
  </li>
35
  <li class="wfls-option-subtitle"><?php echo $subtitleHTML; ?></li>
views/options/option-toggled-segmented.php CHANGED
@@ -18,7 +18,7 @@ if (!defined('WORDFENCE_LS_VERSION')) { exit; }
18
  $id = 'wfls-option-' . preg_replace('/[^a-z0-9]/i', '-', $optionName);
19
  ?>
20
  <ul id="<?php echo esc_attr($id); ?>" class="wfls-option wfls-option-toggled-segmented<?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' wfls-option-premium'; } ?>" data-option="<?php echo esc_attr($optionName); ?>" data-enabled-value="<?php echo esc_attr($enabledValue); ?>" data-disabled-value="<?php echo esc_attr($disabledValue); ?>" data-original-value="<?php echo esc_attr($value == $enabledValue ? $enabledValue : $disabledValue); ?>">
21
- <li class="wfls-option-title"><?php echo (!empty($title)) ? esc_html($title) : ''; echo (!empty($htmlTitle)) ? wp_kses($htmlTitle, 'post') : ''; ?><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?></li>
22
  <li class="wfls-option-segments">
23
  <?php
24
  $onId = sanitize_key('wfls-segment-' . $optionName . '-on');
18
  $id = 'wfls-option-' . preg_replace('/[^a-z0-9]/i', '-', $optionName);
19
  ?>
20
  <ul id="<?php echo esc_attr($id); ?>" class="wfls-option wfls-option-toggled-segmented<?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' wfls-option-premium'; } ?>" data-option="<?php echo esc_attr($optionName); ?>" data-enabled-value="<?php echo esc_attr($enabledValue); ?>" data-disabled-value="<?php echo esc_attr($disabledValue); ?>" data-original-value="<?php echo esc_attr($value == $enabledValue ? $enabledValue : $disabledValue); ?>">
21
+ <li class="wfls-option-title"><?php echo (!empty($title)) ? esc_html($title) : ''; echo (!empty($htmlTitle)) ? wp_kses($htmlTitle, 'post') : ''; ?><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence-2fa') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?></li>
22
  <li class="wfls-option-segments">
23
  <?php
24
  $onId = sanitize_key('wfls-segment-' . $optionName . '-on');
views/options/option-toggled-select.php CHANGED
@@ -24,7 +24,7 @@ $selectID = 'wfls-option-' . preg_replace('/[^a-z0-9]/i', '-', $selectOptionName
24
  <li id="<?php echo esc_attr($toggleID); ?>" class="wfls-option-checkbox<?php echo ($toggleValue == $enabledToggleValue ? ' wfls-checked' : ''); ?>" role="checkbox" aria-checked="<?php echo ($toggleValue == $enabledToggleValue ? 'true' : 'false'); ?>" tabindex="0"><i class="wfls-ion-ios-checkmark-empty" aria-hidden="true"></i></li>
25
  <li class="wfls-option-content">
26
  <ul id="<?php echo esc_attr($selectID); ?>">
27
- <li class="wfls-option-title"><span id="<?php echo esc_attr($selectID); ?>-label"><?php echo esc_html($title); ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?></li>
28
  <li class="wfls-option-select wfls-padding-add-top-xs-small">
29
  <select<?php echo ($toggleValue == $enabledToggleValue && !(!wfConfig::p() && isset($premium) && $premium) ? '' : ' disabled'); ?> aria-labelledby="<?php echo esc_attr($selectID); ?>-label">
30
  <?php foreach ($selectOptions as $o): ?>
24
  <li id="<?php echo esc_attr($toggleID); ?>" class="wfls-option-checkbox<?php echo ($toggleValue == $enabledToggleValue ? ' wfls-checked' : ''); ?>" role="checkbox" aria-checked="<?php echo ($toggleValue == $enabledToggleValue ? 'true' : 'false'); ?>" tabindex="0"><i class="wfls-ion-ios-checkmark-empty" aria-hidden="true"></i></li>
25
  <li class="wfls-option-content">
26
  <ul id="<?php echo esc_attr($selectID); ?>">
27
+ <li class="wfls-option-title"><span id="<?php echo esc_attr($selectID); ?>-label"><?php echo esc_html($title); ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence-2fa') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?></li>
28
  <li class="wfls-option-select wfls-padding-add-top-xs-small">
29
  <select<?php echo ($toggleValue == $enabledToggleValue && !(!wfConfig::p() && isset($premium) && $premium) ? '' : ' disabled'); ?> aria-labelledby="<?php echo esc_attr($selectID); ?>-label">
30
  <?php foreach ($selectOptions as $o): ?>
views/options/option-toggled-sub.php CHANGED
@@ -41,7 +41,7 @@ $subID = 'wfls-option-' . preg_replace('/[^a-z0-9]/i', '-', $subOptionName);
41
  <ul id="<?php echo esc_attr($id); ?>" class="wfls-option wfls-option-toggled<?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' wfls-option-premium'; } ?>" data-option="<?php echo esc_attr($optionName); ?>" data-enabled-value="<?php echo esc_attr($enabledValue); ?>" data-disabled-value="<?php echo esc_attr($disabledValue); ?>" data-original-value="<?php echo esc_attr($value == $enabledValue ? $enabledValue : $disabledValue); ?>">
42
  <li class="wfls-option-checkbox<?php echo ($value == $enabledValue ? ' wfls-checked' : ''); ?>" role="checkbox" aria-checked="<?php echo ($value == $enabledValue ? 'true' : 'false'); ?>" tabindex="0" aria-labelledby="<?php echo esc_attr($id); ?>-label"><i class="wfls-ion-ios-checkmark-empty" aria-hidden="true"></i></li>
43
  <li class="wfls-option-title">
44
- <span id="<?php echo esc_attr($id); ?>-label"><?php echo $htmlTitle; ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?>
45
  </li>
46
  </ul>
47
  </li>
@@ -49,7 +49,7 @@ $subID = 'wfls-option-' . preg_replace('/[^a-z0-9]/i', '-', $subOptionName);
49
  <ul id="<?php echo esc_attr($subID); ?>" class="wfls-option wfls-option-toggled<?php if (!wfConfig::p() && isset($subPremium) && $subPremium) { echo ' wfls-option-premium'; } ?>" data-option="<?php echo esc_attr($subOptionName); ?>" data-enabled-value="<?php echo esc_attr($subEnabledValue); ?>" data-disabled-value="<?php echo esc_attr($subDisabledValue); ?>" data-original-value="<?php echo esc_attr($subValue == $subEnabledValue ? $subEnabledValue : $subDisabledValue); ?>">
50
  <li class="wfls-option-checkbox<?php echo ($subValue == $subEnabledValue ? ' wfls-checked' : ''); ?>" role="checkbox" aria-checked="<?php echo ($subValue == $subEnabledValue ? 'true' : 'false'); ?>" tabindex="0" aria-labelledby="<?php echo esc_attr($subID); ?>-label"><i class="wfls-ion-ios-checkmark-empty" aria-hidden="true"></i></li>
51
  <li class="wfls-option-title">
52
- <span id="<?php echo esc_attr($subID); ?>-label"><?php echo $subHtmlTitle; ?></span><?php if (!wfConfig::p() && isset($subPremium) && $subPremium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence') . '</a>'; } ?><?php if (isset($subHelpLink)) { echo ' <a href="' . esc_attr($subHelpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?>
53
  </li>
54
  </ul>
55
  </li>
41
  <ul id="<?php echo esc_attr($id); ?>" class="wfls-option wfls-option-toggled<?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' wfls-option-premium'; } ?>" data-option="<?php echo esc_attr($optionName); ?>" data-enabled-value="<?php echo esc_attr($enabledValue); ?>" data-disabled-value="<?php echo esc_attr($disabledValue); ?>" data-original-value="<?php echo esc_attr($value == $enabledValue ? $enabledValue : $disabledValue); ?>">
42
  <li class="wfls-option-checkbox<?php echo ($value == $enabledValue ? ' wfls-checked' : ''); ?>" role="checkbox" aria-checked="<?php echo ($value == $enabledValue ? 'true' : 'false'); ?>" tabindex="0" aria-labelledby="<?php echo esc_attr($id); ?>-label"><i class="wfls-ion-ios-checkmark-empty" aria-hidden="true"></i></li>
43
  <li class="wfls-option-title">
44
+ <span id="<?php echo esc_attr($id); ?>-label"><?php echo $htmlTitle; ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence-2fa') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?>
45
  </li>
46
  </ul>
47
  </li>
49
  <ul id="<?php echo esc_attr($subID); ?>" class="wfls-option wfls-option-toggled<?php if (!wfConfig::p() && isset($subPremium) && $subPremium) { echo ' wfls-option-premium'; } ?>" data-option="<?php echo esc_attr($subOptionName); ?>" data-enabled-value="<?php echo esc_attr($subEnabledValue); ?>" data-disabled-value="<?php echo esc_attr($subDisabledValue); ?>" data-original-value="<?php echo esc_attr($subValue == $subEnabledValue ? $subEnabledValue : $subDisabledValue); ?>">
50
  <li class="wfls-option-checkbox<?php echo ($subValue == $subEnabledValue ? ' wfls-checked' : ''); ?>" role="checkbox" aria-checked="<?php echo ($subValue == $subEnabledValue ? 'true' : 'false'); ?>" tabindex="0" aria-labelledby="<?php echo esc_attr($subID); ?>-label"><i class="wfls-ion-ios-checkmark-empty" aria-hidden="true"></i></li>
51
  <li class="wfls-option-title">
52
+ <span id="<?php echo esc_attr($subID); ?>-label"><?php echo $subHtmlTitle; ?></span><?php if (!wfConfig::p() && isset($subPremium) && $subPremium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence-2fa') . '</a>'; } ?><?php if (isset($subHelpLink)) { echo ' <a href="' . esc_attr($subHelpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?>
53
  </li>
54
  </ul>
55
  </li>
views/options/option-toggled-textarea.php CHANGED
@@ -21,7 +21,7 @@ $textAreaID = 'wfls-option-' . preg_replace('/[^a-z0-9]/i', '-', $textAreaOption
21
  ?>
22
  <ul class="wfls-option wfls-option-toggled-textarea<?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' wfls-option-premium'; } ?>" data-toggle-option="<?php echo esc_attr($toggleOptionName); ?>" data-enabled-toggle-value="<?php echo esc_attr($enabledToggleValue); ?>" data-disabled-toggle-value="<?php echo esc_attr($disabledToggleValue); ?>" data-original-toggle-value="<?php echo esc_attr($toggleValue == $enabledToggleValue ? $enabledToggleValue : $disabledToggleValue); ?>" data-text-area-option="<?php echo esc_attr($textAreaOptionName); ?>" data-original-text-area-value="<?php echo esc_attr($textAreaValue); ?>">
23
  <li id="<?php echo esc_attr($toggleID); ?>" class="wfls-option-checkbox<?php echo ($toggleValue == $enabledToggleValue ? ' wfls-checked' : ''); ?>" role="checkbox" aria-checked="<?php echo ($toggleValue == $enabledToggleValue ? 'true' : 'false'); ?>" tabindex="0"><i class="wfls-ion-ios-checkmark-empty" aria-hidden="true" aria-labelledby="<?php echo esc_attr($toggleID); ?>-label"></i></li>
24
- <li class="wfls-option-title"><span id="<?php echo esc_attr($toggleID); ?>-label"><?php echo esc_html($title); ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?></li>
25
  <li id="<?php echo esc_attr($textAreaID); ?>" class="wfls-option-textarea">
26
  <select<?php echo ($toggleValue == $enabledToggleValue && !(!wfConfig::p() && isset($premium) && $premium) ? '' : ' disabled'); ?> aria-labelledby="<?php echo esc_attr($toggleID); ?>-label">
27
  <textarea<?php echo (!(!wfConfig::p() && isset($premium) && $premium) ? '' : ' disabled'); ?>><?php echo esc_html($textAreaValue); ?></textarea>
21
  ?>
22
  <ul class="wfls-option wfls-option-toggled-textarea<?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' wfls-option-premium'; } ?>" data-toggle-option="<?php echo esc_attr($toggleOptionName); ?>" data-enabled-toggle-value="<?php echo esc_attr($enabledToggleValue); ?>" data-disabled-toggle-value="<?php echo esc_attr($disabledToggleValue); ?>" data-original-toggle-value="<?php echo esc_attr($toggleValue == $enabledToggleValue ? $enabledToggleValue : $disabledToggleValue); ?>" data-text-area-option="<?php echo esc_attr($textAreaOptionName); ?>" data-original-text-area-value="<?php echo esc_attr($textAreaValue); ?>">
23
  <li id="<?php echo esc_attr($toggleID); ?>" class="wfls-option-checkbox<?php echo ($toggleValue == $enabledToggleValue ? ' wfls-checked' : ''); ?>" role="checkbox" aria-checked="<?php echo ($toggleValue == $enabledToggleValue ? 'true' : 'false'); ?>" tabindex="0"><i class="wfls-ion-ios-checkmark-empty" aria-hidden="true" aria-labelledby="<?php echo esc_attr($toggleID); ?>-label"></i></li>
24
+ <li class="wfls-option-title"><span id="<?php echo esc_attr($toggleID); ?>-label"><?php echo esc_html($title); ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence-2fa') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?></li>
25
  <li id="<?php echo esc_attr($textAreaID); ?>" class="wfls-option-textarea">
26
  <select<?php echo ($toggleValue == $enabledToggleValue && !(!wfConfig::p() && isset($premium) && $premium) ? '' : ' disabled'); ?> aria-labelledby="<?php echo esc_attr($toggleID); ?>-label">
27
  <textarea<?php echo (!(!wfConfig::p() && isset($premium) && $premium) ? '' : ' disabled'); ?>><?php echo esc_html($textAreaValue); ?></textarea>
views/options/option-token.php CHANGED
@@ -22,7 +22,7 @@ $id = 'wfls-option-' . preg_replace('/[^a-z0-9]/i', '-', $tokenOptionName);
22
  <ul class="wfls-flex-vertical wfls-flex-align-left">
23
  <li>
24
  <?php endif; ?>
25
- <span id="<?php echo esc_attr($id); ?>-label"><?php echo esc_html($title); ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?>
26
  <?php if (isset($subtitle)): ?>
27
  </li>
28
  <li class="wfls-option-subtitle"><?php echo esc_html($subtitle); ?></li>
22
  <ul class="wfls-flex-vertical wfls-flex-align-left">
23
  <li>
24
  <?php endif; ?>
25
+ <span id="<?php echo esc_attr($id); ?>-label"><?php echo esc_html($title); ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wfls-premium-link">' . esc_html__('Premium Feature', 'wordfence-2fa') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wfls-inline-help"><i class="' . (WORDFENCE_LS_FROM_CORE ? 'wf-fa wf-fa-question-circle-o' : 'wfls-fa wfls-fa-question-circle-o') . '" aria-hidden="true"></i></a>'; } ?>
26
  <?php if (isset($subtitle)): ?>
27
  </li>
28
  <li class="wfls-option-subtitle"><?php echo esc_html($subtitle); ?></li>
views/page/role.php CHANGED
@@ -2,7 +2,7 @@
2
  if (!defined('WORDFENCE_LS_VERSION')) { exit; }
3
  ?>
4
  <?php if (is_multisite()): ?>
5
- <p><em>(<?php esc_html_e('This page only shows users and roles on the main site of this network', 'wordfence') ?>)</em></p>
6
  <?php endif ?>
7
  <div class="wfls-block wfls-always-active wfls-flex-item-full-width wfls-add-bottom">
8
  <?php if ($requiredAt === false): ?>
@@ -32,7 +32,7 @@ if (!defined('WORDFENCE_LS_VERSION')) { exit; }
32
  <?php if ($user->required_at): ?>
33
  <?php echo esc_html(\WordfenceLS\Controller_Time::format_local_time('F j, Y g:i A', $user->required_at)) ?>
34
  <?php else: ?>
35
- <?php esc_html_e('N/A', 'wordfence'); ?>
36
  <?php endif ?>
37
  </td>
38
  </tr>
@@ -43,7 +43,7 @@ if (!defined('WORDFENCE_LS_VERSION')) { exit; }
43
  <?php if ($page > 1): ?>
44
  <a href="<?php echo esc_attr(add_query_arg($pageKey, $page-1) . "#$stateKey") ?>"><span class="dashicons dashicons-arrow-left-alt2"></span></a>
45
  <?php endif ?>
46
- <strong class="wfls-page-indicator"><?php esc_html_e('Page ') ?><?php echo (int) $page ?></strong>
47
  <?php if (!$lastPage): ?>
48
  <a href="<?php echo esc_attr(add_query_arg($pageKey, $page+1) . "#$stateKey") ?>"><span class="dashicons dashicons-arrow-right-alt2"></span></a>
49
  <?php endif ?>
2
  if (!defined('WORDFENCE_LS_VERSION')) { exit; }
3
  ?>
4
  <?php if (is_multisite()): ?>
5
+ <p><em>(<?php esc_html_e('This page only shows users and roles on the main site of this network', 'wordfence-2fa') ?>)</em></p>
6
  <?php endif ?>
7
  <div class="wfls-block wfls-always-active wfls-flex-item-full-width wfls-add-bottom">
8
  <?php if ($requiredAt === false): ?>
32
  <?php if ($user->required_at): ?>
33
  <?php echo esc_html(\WordfenceLS\Controller_Time::format_local_time('F j, Y g:i A', $user->required_at)) ?>
34
  <?php else: ?>
35
+ <?php esc_html_e('N/A', 'wordfence-2fa'); ?>
36
  <?php endif ?>
37
  </td>
38
  </tr>
43
  <?php if ($page > 1): ?>
44
  <a href="<?php echo esc_attr(add_query_arg($pageKey, $page-1) . "#$stateKey") ?>"><span class="dashicons dashicons-arrow-left-alt2"></span></a>
45
  <?php endif ?>
46
+ <strong class="wfls-page-indicator"><?php esc_html_e('Page ', 'wordfence-2fa') ?><?php echo (int) $page ?></strong>
47
  <?php if (!$lastPage): ?>
48
  <a href="<?php echo esc_attr(add_query_arg($pageKey, $page+1) . "#$stateKey") ?>"><span class="dashicons dashicons-arrow-right-alt2"></span></a>
49
  <?php endif ?>
views/settings/options.php CHANGED
@@ -88,7 +88,7 @@ if (!defined('WORDFENCE_LS_VERSION')) { exit; }
88
  echo \WordfenceLS\Model_View::create('options/option-textarea', array(
89
  'textOptionName' => \WordfenceLS\Controller_Settings::OPTION_2FA_WHITELISTED,
90
  'textValue' => implode("\n", \WordfenceLS\Controller_Settings::shared()->whitelisted_ips()),
91
- 'title' => new \WordfenceLS\Text\Model_HTML('<strong>' . esc_html__('Allowlisted IP addresses that bypass 2FA', 'wordfence-2fa') . '</strong>'),
92
  'alignTitle' => 'top',
93
  'subtitle' => __('Allowlisted IPs must be placed on separate lines. You can specify ranges using the following formats: 127.0.0.1/24, 127.0.0.[1-100], or 127.0.0.1-127.0.1.100.', 'wordfence-2fa'),
94
  'subtitlePosition' => 'value',
@@ -145,6 +145,18 @@ if (!defined('WORDFENCE_LS_VERSION')) { exit; }
145
  ))->render();
146
  ?>
147
  </li>
 
 
 
 
 
 
 
 
 
 
 
 
148
  <li>
149
  <?php
150
  echo \WordfenceLS\Model_View::create('options/option-toggled', array(
88
  echo \WordfenceLS\Model_View::create('options/option-textarea', array(
89
  'textOptionName' => \WordfenceLS\Controller_Settings::OPTION_2FA_WHITELISTED,
90
  'textValue' => implode("\n", \WordfenceLS\Controller_Settings::shared()->whitelisted_ips()),
91
+ 'title' => new \WordfenceLS\Text\Model_HTML('<strong>' . esc_html__('Allowlisted IP addresses that bypass 2FA and reCAPTCHA', 'wordfence-2fa') . '</strong>'),
92
  'alignTitle' => 'top',
93
  'subtitle' => __('Allowlisted IPs must be placed on separate lines. You can specify ranges using the following formats: 127.0.0.1/24, 127.0.0.[1-100], or 127.0.0.1-127.0.1.100.', 'wordfence-2fa'),
94
  'subtitlePosition' => 'value',
145
  ))->render();
146
  ?>
147
  </li>
148
+ <li>
149
+ <?php
150
+ echo \WordfenceLS\Model_View::create('options/option-toggled', array(
151
+ 'optionName' => \WordfenceLS\Controller_Settings::OPTION_ENABLE_LOGIN_HISTORY_COLUMNS,
152
+ 'enabledValue' => '1',
153
+ 'disabledValue' => '0',
154
+ 'value' => \WordfenceLS\Controller_Settings::shared()->are_login_history_columns_enabled() ? '1': '0',
155
+ 'title' => new \WordfenceLS\Text\Model_HTML('<strong>' . esc_html__('Show last login column on WP Users page', 'wordfence-2fa') . '</strong>'),
156
+ 'subtitle' => __('When enabled, the last login timestamp will be displayed for each user on the WP Users page. When used in conjunction with reCAPTCHA, the most recent score will also be displayed for each user.', 'wordfence-2fa'),
157
+ ))->render();
158
+ ?>
159
+ </li>
160
  <li>
161
  <?php
162
  echo \WordfenceLS\Model_View::create('options/option-toggled', array(
views/settings/user-stats.php CHANGED
@@ -12,7 +12,7 @@ if (!defined('WORDFENCE_LS_VERSION')) { exit; }
12
  </div>
13
  </div>
14
  <div class="wfls-block-header-action wfls-block-header-action-text wfls-nowrap wfls-padding-add-right-responsive">
15
- <a href="users.php"><?php esc_html_e('Manage Users', 'wordfence'); ?></a>
16
  </div>
17
  </div>
18
  <div class="wfls-block-content wfls-padding-no-left wfls-padding-no-right">
12
  </div>
13
  </div>
14
  <div class="wfls-block-header-action wfls-block-header-action-text wfls-nowrap wfls-padding-add-right-responsive">
15
+ <a href="users.php"><?php esc_html_e('Manage Users', 'wordfence-2fa'); ?></a>
16
  </div>
17
  </div>
18
  <div class="wfls-block-content wfls-padding-no-left wfls-padding-no-right">
views/user/grace-period-toggle.php CHANGED
@@ -7,7 +7,7 @@ if (!defined('WORDFENCE_LS_VERSION')) { exit; }
7
  <th scope="row"><label for="wfls-grace-period-toggle"><?php esc_html_e('2FA Grace Period', 'wordfence-2fa') ?></label></th>
8
  <td>
9
  <input id="wfls-grace-period-toggle" name="wfls-grace-period-toggle" type="checkbox">
10
- <label for="wfls-grace-period-toggle"><?php esc_html_e('Allow a grace period for this user prior to requiring Wordfence 2FA') ?></label>
11
  </td>
12
  </tr>
13
  </table>
7
  <th scope="row"><label for="wfls-grace-period-toggle"><?php esc_html_e('2FA Grace Period', 'wordfence-2fa') ?></label></th>
8
  <td>
9
  <input id="wfls-grace-period-toggle" name="wfls-grace-period-toggle" type="checkbox">
10
+ <label for="wfls-grace-period-toggle"><?php esc_html_e('Allow a grace period for this user prior to requiring Wordfence 2FA', 'wordfence-2fa') ?></label>
11
  </td>
12
  </tr>
13
  </table>
wordfence-login-security.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Wordfence Login Security
4
  Description: Wordfence Login Security
5
  Author: Wordfence
6
  Author URI: http://www.wordfence.com/
7
- Version: 1.0.9
8
  Network: true
9
  Requires at least: 4.5
10
  Requires PHP: 5.3
@@ -35,8 +35,8 @@ if ($wfCoreActive && !(isset($wfCoreLoading) && $wfCoreLoading)) {
35
  else {
36
  define('WORDFENCE_LS_FROM_CORE', ($wfCoreActive && isset($wfCoreLoading) && $wfCoreLoading));
37
 
38
- define('WORDFENCE_LS_VERSION', '1.0.9');
39
- define('WORDFENCE_LS_BUILD_NUMBER', '1634043539');
40
 
41
  define('WORDFENCE_LS_PLUGIN_BASENAME', plugin_basename(__FILE__));
42
 
4
  Description: Wordfence Login Security
5
  Author: Wordfence
6
  Author URI: http://www.wordfence.com/
7
+ Version: 1.0.10
8
  Network: true
9
  Requires at least: 4.5
10
  Requires PHP: 5.3
35
  else {
36
  define('WORDFENCE_LS_FROM_CORE', ($wfCoreActive && isset($wfCoreLoading) && $wfCoreLoading));
37
 
38
+ define('WORDFENCE_LS_VERSION', '1.0.10');
39
+ define('WORDFENCE_LS_BUILD_NUMBER', '1654178513');
40
 
41
  define('WORDFENCE_LS_PLUGIN_BASENAME', plugin_basename(__FILE__));
42