Defender Security – Malware Scanner, Login Security & Firewall - Version 3.1.2

Version Description

( 2022-07-20 ) =

  • Fix: WAF status not showing correctly
  • Fix: Notification scheduler error
  • Fix: Plugin support link error
Download this release

Release Info

Developer BigTonny
Plugin Icon 128x128 Defender Security – Malware Scanner, Login Security & Firewall
Version 3.1.2
Comparing to
See all releases

Code changes from version 3.1.1 to 3.1.2

languages/wpdef-default.pot CHANGED
@@ -6,9 +6,9 @@
6
  #, fuzzy
7
  msgid ""
8
  msgstr ""
9
- "Project-Id-Version: wp-defender 3.1.1\n"
10
  "Report-Msgid-Bugs-To: \n"
11
- "POT-Creation-Date: 2022-07-05 13:28+0300\n"
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -172,7 +172,7 @@ msgstr ""
172
  #. 4 Email Button CTA
173
  #: extra/free-dashboard/classes/notices/class-email.php:95
174
  #: extra/free-dashboard/classes/notices/class-email.php:213
175
- #: src/class-admin.php:249
176
  msgid "Get Fast!"
177
  msgstr ""
178
 
@@ -467,11 +467,11 @@ msgstr ""
467
  msgid "%s is disabled. Please contact your hosting provider to enable it."
468
  msgstr ""
469
 
470
- #: src/class-admin.php:124
471
  msgid "Go to Defender Settings"
472
  msgstr ""
473
 
474
- #: src/class-admin.php:124 src/component/audit/options-audit.php:227
475
  #: src/component/backup-settings.php:1176 src/controller/main-setting.php:27
476
  #: front/src/module/advanced-tools/screen/password-reset.vue:41
477
  #: front/src/module/audit/audit.vue:42 front/src/module/audit/audit.vue:49
@@ -492,15 +492,15 @@ msgstr ""
492
  msgid "Settings"
493
  msgstr ""
494
 
495
- #: src/class-admin.php:126
496
  msgid "Docs"
497
  msgstr ""
498
 
499
- #: src/class-admin.php:129
500
  msgid "Upgrade to Defender Pro"
501
  msgstr ""
502
 
503
- #: src/class-admin.php:129
504
  #: front/src/module/dashboard/component/file-scanning-free.vue:75
505
  #: front/src/module/dashboard/component/file-scanning-free.vue:90
506
  #: front/src/module/scan/screen/scan-result.vue:54
@@ -509,77 +509,77 @@ msgstr ""
509
  msgid "Upgrade"
510
  msgstr ""
511
 
512
- #: src/class-admin.php:131
513
  msgid "Renew Your Membership"
514
  msgstr ""
515
 
516
- #: src/class-admin.php:131
517
  msgid "Renew Membership"
518
  msgstr ""
519
 
520
- #: src/class-admin.php:159
521
  msgid "WPMU DEV"
522
  msgstr ""
523
 
524
- #: src/class-admin.php:161
525
  #, php-format
526
  msgid "By %s"
527
  msgstr ""
528
 
529
- #: src/class-admin.php:177
530
  #, php-format
531
  msgid "More information about %s"
532
  msgstr ""
533
 
534
- #: src/class-admin.php:179 src/class-admin.php:193
535
  msgid "View details"
536
  msgstr ""
537
 
538
- #: src/class-admin.php:185 src/class-admin.php:293
539
  msgid "Rate Defender"
540
  msgstr ""
541
 
542
- #: src/class-admin.php:186
543
  msgid "Support"
544
  msgstr ""
545
 
546
- #: src/class-admin.php:196
547
  msgid "Premium Support"
548
  msgstr ""
549
 
550
- #: src/class-admin.php:198
551
  msgid "Roadmap"
552
  msgstr ""
553
 
554
- #: src/class-admin.php:210
555
  msgid "Invalid request, you are not allowed to do that action."
556
  msgstr ""
557
 
558
- #: src/class-admin.php:219
559
  msgid "Invalid request, allowed data not provided."
560
  msgstr ""
561
 
562
- #: src/class-admin.php:289
563
  msgid ""
564
  "We've spent countless hours developing Defender and making it free for you "
565
  "to use. We would really appreciate it if you dropped us a quick rating!"
566
  msgstr ""
567
 
568
- #: src/class-admin.php:296
569
  msgid "Maybe later"
570
  msgstr ""
571
 
572
- #: src/class-admin.php:352
573
  msgid ""
574
  "There is a new version of Defender available - Deprecating PHP version 7.1. "
575
  "and lower."
576
  msgstr ""
577
 
578
- #: src/class-admin.php:355
579
  msgid "Important Upgrade Notice:"
580
  msgstr ""
581
 
582
- #: src/class-admin.php:359
583
  #, php-format
584
  msgid ""
585
  "The upcoming version %s is compatible only with PHP 7.2.0 and higher. Please "
@@ -1615,8 +1615,8 @@ msgid "Unsubscribed"
1615
  msgstr ""
1616
 
1617
  #: src/component/notification.php:383 src/component/notification.php:398
1618
- #: src/controller/firewall.php:436 src/model/notification.php:324
1619
- #: src/model/notification.php:339 src/model/notification/malware-report.php:163
1620
  #: front/src/module/ip-lockout/screen/settings.vue:28
1621
  msgid "Never"
1622
  msgstr ""
@@ -3378,22 +3378,22 @@ msgstr ""
3378
  msgid "User Agent name"
3379
  msgstr ""
3380
 
3381
- #: src/model/notification.php:306
3382
  #, php-format
3383
  msgid "%1$s at %2$s"
3384
  msgstr ""
3385
 
3386
- #: src/model/notification.php:308
3387
  #, php-format
3388
  msgid "%1$s on %2$s at %3$s"
3389
  msgstr ""
3390
 
3391
- #: src/model/notification.php:311
3392
  #, php-format
3393
  msgid "%1$s/%2$d, %3$s"
3394
  msgstr ""
3395
 
3396
- #: src/model/notification.php:354
3397
  #, php-format
3398
  msgid "Email %s is invalid format"
3399
  msgstr ""
@@ -3763,27 +3763,27 @@ msgstr ""
3763
  msgid "Invalid IP addresses detected. Please fix the following errors:"
3764
  msgstr ""
3765
 
3766
- #: src/model/setting/blacklist-lockout.php:229
3767
  msgid "IP Banning - IP Addresses Blocklist"
3768
  msgstr ""
3769
 
3770
- #: src/model/setting/blacklist-lockout.php:230
3771
  msgid "IP Banning - IP Addresses Allowlist"
3772
  msgstr ""
3773
 
3774
- #: src/model/setting/blacklist-lockout.php:231
3775
  msgid "IP Banning - Country Allowlist"
3776
  msgstr ""
3777
 
3778
- #: src/model/setting/blacklist-lockout.php:232
3779
  msgid "IP Banning - Country Blocklist"
3780
  msgstr ""
3781
 
3782
- #: src/model/setting/blacklist-lockout.php:233
3783
  msgid "IP Banning - Lockout Message"
3784
  msgstr ""
3785
 
3786
- #: src/model/setting/blacklist-lockout.php:234
3787
  msgid "MaxMind license key"
3788
  msgstr ""
3789
 
6
  #, fuzzy
7
  msgid ""
8
  msgstr ""
9
+ "Project-Id-Version: wp-defender 3.1.2\n"
10
  "Report-Msgid-Bugs-To: \n"
11
+ "POT-Creation-Date: 2022-07-20 10:42+0300\n"
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
172
  #. 4 Email Button CTA
173
  #: extra/free-dashboard/classes/notices/class-email.php:95
174
  #: extra/free-dashboard/classes/notices/class-email.php:213
175
+ #: src/class-admin.php:233
176
  msgid "Get Fast!"
177
  msgstr ""
178
 
467
  msgid "%s is disabled. Please contact your hosting provider to enable it."
468
  msgstr ""
469
 
470
+ #: src/class-admin.php:109
471
  msgid "Go to Defender Settings"
472
  msgstr ""
473
 
474
+ #: src/class-admin.php:109 src/component/audit/options-audit.php:227
475
  #: src/component/backup-settings.php:1176 src/controller/main-setting.php:27
476
  #: front/src/module/advanced-tools/screen/password-reset.vue:41
477
  #: front/src/module/audit/audit.vue:42 front/src/module/audit/audit.vue:49
492
  msgid "Settings"
493
  msgstr ""
494
 
495
+ #: src/class-admin.php:111
496
  msgid "Docs"
497
  msgstr ""
498
 
499
+ #: src/class-admin.php:114
500
  msgid "Upgrade to Defender Pro"
501
  msgstr ""
502
 
503
+ #: src/class-admin.php:114
504
  #: front/src/module/dashboard/component/file-scanning-free.vue:75
505
  #: front/src/module/dashboard/component/file-scanning-free.vue:90
506
  #: front/src/module/scan/screen/scan-result.vue:54
509
  msgid "Upgrade"
510
  msgstr ""
511
 
512
+ #: src/class-admin.php:116
513
  msgid "Renew Your Membership"
514
  msgstr ""
515
 
516
+ #: src/class-admin.php:116
517
  msgid "Renew Membership"
518
  msgstr ""
519
 
520
+ #: src/class-admin.php:144
521
  msgid "WPMU DEV"
522
  msgstr ""
523
 
524
+ #: src/class-admin.php:148
525
  #, php-format
526
  msgid "By %s"
527
  msgstr ""
528
 
529
+ #: src/class-admin.php:165
530
  #, php-format
531
  msgid "More information about %s"
532
  msgstr ""
533
 
534
+ #: src/class-admin.php:167 src/class-admin.php:181
535
  msgid "View details"
536
  msgstr ""
537
 
538
+ #: src/class-admin.php:173 src/class-admin.php:278
539
  msgid "Rate Defender"
540
  msgstr ""
541
 
542
+ #: src/class-admin.php:174
543
  msgid "Support"
544
  msgstr ""
545
 
546
+ #: src/class-admin.php:184
547
  msgid "Premium Support"
548
  msgstr ""
549
 
550
+ #: src/class-admin.php:186
551
  msgid "Roadmap"
552
  msgstr ""
553
 
554
+ #: src/class-admin.php:197
555
  msgid "Invalid request, you are not allowed to do that action."
556
  msgstr ""
557
 
558
+ #: src/class-admin.php:204
559
  msgid "Invalid request, allowed data not provided."
560
  msgstr ""
561
 
562
+ #: src/class-admin.php:274
563
  msgid ""
564
  "We've spent countless hours developing Defender and making it free for you "
565
  "to use. We would really appreciate it if you dropped us a quick rating!"
566
  msgstr ""
567
 
568
+ #: src/class-admin.php:281
569
  msgid "Maybe later"
570
  msgstr ""
571
 
572
+ #: src/class-admin.php:337
573
  msgid ""
574
  "There is a new version of Defender available - Deprecating PHP version 7.1. "
575
  "and lower."
576
  msgstr ""
577
 
578
+ #: src/class-admin.php:340
579
  msgid "Important Upgrade Notice:"
580
  msgstr ""
581
 
582
+ #: src/class-admin.php:344
583
  #, php-format
584
  msgid ""
585
  "The upcoming version %s is compatible only with PHP 7.2.0 and higher. Please "
1615
  msgstr ""
1616
 
1617
  #: src/component/notification.php:383 src/component/notification.php:398
1618
+ #: src/controller/firewall.php:436 src/model/notification.php:328
1619
+ #: src/model/notification.php:343 src/model/notification/malware-report.php:163
1620
  #: front/src/module/ip-lockout/screen/settings.vue:28
1621
  msgid "Never"
1622
  msgstr ""
3378
  msgid "User Agent name"
3379
  msgstr ""
3380
 
3381
+ #: src/model/notification.php:310
3382
  #, php-format
3383
  msgid "%1$s at %2$s"
3384
  msgstr ""
3385
 
3386
+ #: src/model/notification.php:312
3387
  #, php-format
3388
  msgid "%1$s on %2$s at %3$s"
3389
  msgstr ""
3390
 
3391
+ #: src/model/notification.php:315
3392
  #, php-format
3393
  msgid "%1$s/%2$d, %3$s"
3394
  msgstr ""
3395
 
3396
+ #: src/model/notification.php:358
3397
  #, php-format
3398
  msgid "Email %s is invalid format"
3399
  msgstr ""
3763
  msgid "Invalid IP addresses detected. Please fix the following errors:"
3764
  msgstr ""
3765
 
3766
+ #: src/model/setting/blacklist-lockout.php:227
3767
  msgid "IP Banning - IP Addresses Blocklist"
3768
  msgstr ""
3769
 
3770
+ #: src/model/setting/blacklist-lockout.php:228
3771
  msgid "IP Banning - IP Addresses Allowlist"
3772
  msgstr ""
3773
 
3774
+ #: src/model/setting/blacklist-lockout.php:229
3775
  msgid "IP Banning - Country Allowlist"
3776
  msgstr ""
3777
 
3778
+ #: src/model/setting/blacklist-lockout.php:230
3779
  msgid "IP Banning - Country Blocklist"
3780
  msgstr ""
3781
 
3782
+ #: src/model/setting/blacklist-lockout.php:231
3783
  msgid "IP Banning - Lockout Message"
3784
  msgstr ""
3785
 
3786
+ #: src/model/setting/blacklist-lockout.php:232
3787
  msgid "MaxMind license key"
3788
  msgstr ""
3789
 
readme.txt CHANGED
@@ -1,19 +1,18 @@
1
  === Defender Security - Malware Scanner, Login Security & Firewall ===
2
  Plugin Name: Defender Security - Malware Scanner, Login Security & Firewall
3
- Version: 3.1.1
4
  Author: WPMU DEV
5
  Author URI: https://wpmudev.com/
6
  Contributors: WPMUDEV
7
- Tags: security plugin, security, firewall, malware, malware scanner, antivirus, ip blocking, login security, brute force attacks, two-factor authentication, activity log, audit logs, block hackers, 2fa, hack, webauthn, authentication, fido2
8
  Requires at least: 5.2
9
- Tested up to: 6.0
10
- Stable tag: 3.1.1
11
  Requires PHP: 7.2.0
12
  License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
13
 
14
  WordPress security plugin with malware scanner, IP blocking, audit logs, antivirus scans, activity logs, firewall, 2FA, brute force login security & more.
15
 
16
-
17
  == Description ==
18
 
19
  **Defender adds the best in WordPress plugin security to your website with just a few clicks. Stop brute force login attacks, SQL injections, cross-site scripting XSS, and other WordPress vulnerabilities and hacks with Defender’s malware scanner, antivirus scans, IP blocking, firewall, activity log, security log, and two-factor authentication (2FA) login security.**
@@ -244,6 +243,12 @@ Please open a new thread in Defender’s [support forum](https://wordpress.org/s
244
 
245
  == Changelog ==
246
 
 
 
 
 
 
 
247
  = 3.1.1 ( 2022-07-05 ) =
248
 
249
  - Fix: Notifications module error
@@ -288,44 +293,6 @@ Please open a new thread in Defender’s [support forum](https://wordpress.org/s
288
 
289
  - Fix: All site visitors are blocked
290
 
291
- = 2.8.1 ( 2022-04-07 ) =
292
-
293
- - Enhance: Hide write permissions error notices for Tweaks while applying config
294
- - Enhance: Update the default Auth method on the Users page
295
- - Enhance: Singular or plural translation in email templates
296
- - Enhance: Login Protection and 404 Detection Section Update
297
- - Enhance: Show country flags for country-based lockouts
298
- - Fix: Update Firewall's 404 Detection blocklist and allowlist information notice
299
- - Fix: Firewall not working when Country is added to whitelist
300
- - Fix: Updating plugins with known vulnerabilities
301
- - Fix: No passcode when Fallback Email is not the default method
302
- - Fix: 404 Exclusions Inconsistent Logging
303
- - Fix: 2FA token issue
304
- - Fix: Undefined array key "HTTP_HOST"
305
- - Fix: Duplicate key name 'country_iso_code'
306
- - Fix: Welcome modal when white-label enabled
307
- - Fix: Jquery issue on Def's 2FA TOTP page
308
-
309
- = 2.8.0 ( 2022-03-07 ) =
310
-
311
- - New: Backup codes
312
- - Enhance: Text version of 2FA code
313
- - Enhance: Add Update Old Security Keys settings to config
314
- - Enhance: Automatically check for MaxMind database updates
315
- - Enhance: WP-CLI command to delete Defender logs
316
- - Enhance: Delete security tweak settings during uninstallation
317
- - Fix: IP Lockout issue
318
- - Fix: Malware Scanning PHP 8.1 error
319
- - Fix: Native domain mapping doesn't work with login masking
320
- - Fix: Firewall log export doesn't include all entries
321
- - Fix: Duplicate configs
322
- - Fix: Geo DB downloaded to WP-Admin directory
323
- - Fix: Branda conflict – Update User listed twice in logs
324
- - Fix: Notifications user search missing some users
325
- - Fix: When Defender login masking is active, SmartCrawl report URL are broken
326
- - Fix: User filter dropdown count not updating dynamically
327
- - Fix: SSO not working with login masking on multisite
328
-
329
 
330
  [Changelog for previous versions](https://wpmudev.com/project/wp-defender/#view-changelog).
331
 
1
  === Defender Security - Malware Scanner, Login Security & Firewall ===
2
  Plugin Name: Defender Security - Malware Scanner, Login Security & Firewall
3
+ Version: 3.1.2
4
  Author: WPMU DEV
5
  Author URI: https://wpmudev.com/
6
  Contributors: WPMUDEV
7
+ Tags: security plugin, security, firewall, malware, malware scanner, antivirus, ip blocking, login security, brute force attacks, limit login attempts, custom login url, activity log, audit logs, block hackers, two-factor authentication, 2fa, hack, captcha, webauthn, authentication, fido2, fingerprint, face verification, yubikey, USB keys
8
  Requires at least: 5.2
9
+ Tested up to: 6.0.1
10
+ Stable tag: 3.1.2
11
  Requires PHP: 7.2.0
12
  License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
13
 
14
  WordPress security plugin with malware scanner, IP blocking, audit logs, antivirus scans, activity logs, firewall, 2FA, brute force login security & more.
15
 
 
16
  == Description ==
17
 
18
  **Defender adds the best in WordPress plugin security to your website with just a few clicks. Stop brute force login attacks, SQL injections, cross-site scripting XSS, and other WordPress vulnerabilities and hacks with Defender’s malware scanner, antivirus scans, IP blocking, firewall, activity log, security log, and two-factor authentication (2FA) login security.**
243
 
244
  == Changelog ==
245
 
246
+ = 3.1.2 ( 2022-07-20 ) =
247
+
248
+ - Fix: WAF status not showing correctly
249
+ - Fix: Notification scheduler error
250
+ - Fix: Plugin support link error
251
+
252
  = 3.1.1 ( 2022-07-05 ) =
253
 
254
  - Fix: Notifications module error
293
 
294
  - Fix: All site visitors are blocked
295
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
 
297
  [Changelog for previous versions](https://wpmudev.com/project/wp-defender/#view-changelog).
298
 
src/class-admin.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
 
3
  namespace WP_Defender;
4
 
@@ -25,47 +26,32 @@ class Admin {
25
  */
26
  public function init() {
27
  $this->is_pro = ( new WPMUDEV() )->is_pro();
28
- $is_def_page = defender_current_page();
29
- $this->init_constants();
30
  // Display plugin links.
31
- add_filter( 'network_admin_plugin_action_links_' . DEFENDER_PLUGIN_BASENAME, array( $this, 'settings_link' ) );
32
- add_filter( 'plugin_action_links_' . DEFENDER_PLUGIN_BASENAME, array( $this, 'settings_link' ) );
33
- add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 3 );
34
  // WP_DEFENDER_PRO sometimes doesn't match $this->is_pro, e.g. WPMU DEV Dashboard is deactivated.
35
  if ( defined( 'WP_DEFENDER_PRO' ) && WP_DEFENDER_PRO ) {
36
  // This area is only for Pro version.
37
  add_action(
38
  'load-plugins.php',
39
  function () {
40
- add_action( 'after_plugin_row_' . DEFENDER_PLUGIN_BASENAME, array(
41
- $this,
42
- 'show_upgrade_notice'
43
- ), 10, 2 );
44
  },
45
  22
46
  );
47
  } else {
48
  // This area is only for wordpress.org members.
49
  // Add plugin upgrade notification.
50
- add_action( 'in_plugin_update_message-' . DEFENDER_PLUGIN_BASENAME, array( $this, 'show_upgrade_notice' ), 10, 2 );
51
  if ( $is_def_page && ! is_multisite() ) {
52
- add_action( 'admin_notices', array( $this, 'show_rating_notice' ) );
53
  } elseif ( $is_def_page && is_multisite() && is_main_site() ) {
54
- add_action( 'network_admin_notices', array( $this, 'show_rating_notice' ) );
55
  }
56
- add_action( 'wp_ajax_defender_dismiss_notification', array( $this, 'dismiss_notice' ) );
57
- add_action( 'admin_init', array( $this, 'register_free_modules' ), 20 );
58
- }
59
- }
60
-
61
- /**
62
- * Initialize constants in the admin panel.
63
- *
64
- * @since 3.1.0
65
- */
66
- protected function init_constants() {
67
- if ( ! defined( 'WP_DEFENDER_SUPPORT_LINK' ) ) {
68
- define( 'WP_DEFENDER_SUPPORT_LINK', 'https://wpmudev.com/hub2/support/#get-support' );
69
  }
70
  }
71
 
@@ -78,9 +64,9 @@ class Admin {
78
  *
79
  * @return string
80
  */
81
- public function get_link( $link_for, $campaign = '', $adv_path = '' ) {
82
- $domain = 'https://wpmudev.com';
83
- $wp_org = 'https://wordpress.org';
84
  $utm_tags = "?utm_source=defender&utm_medium=plugin&utm_campaign={$campaign}";
85
  switch ( $link_for ) {
86
  case 'docs':
@@ -109,7 +95,6 @@ class Admin {
109
  return $link;
110
  }
111
 
112
-
113
  /**
114
  * Adds a settings link on plugin page.
115
  *
@@ -117,18 +102,18 @@ class Admin {
117
  *
118
  * @return array
119
  */
120
- public function settings_link( $links ) {
121
  $action_links = [];
122
  $wpmu_dev = new WPMUDEV();
123
  // Settings link.
124
- $action_links['dashboard'] = '<a href="' . network_admin_url( 'admin.php?page=wdf-setting' ) . '" aria-label="' . esc_attr( __( 'Go to Defender Settings', 'wpdef' ) ) . '">' . esc_html__( 'Settings', 'wpdef' ) . '</a>';
125
  // Documentation link.
126
- $action_links['docs'] = '<a target="_blank" href="' . $this->get_link('docs', 'defender_pluginlist_docs') . '" aria-label="' . esc_attr(__('Docs', 'wpdef')) . '">' . esc_html__('Docs', 'wpdef') . '</a>';
127
  if ( ! $wpmu_dev->is_member() ) {
128
  if ( WP_DEFENDER_PRO_PATH !== DEFENDER_PLUGIN_BASENAME ) {
129
  $action_links['upgrade'] = '<a style="color: #8D00B1;" target="_blank" href="' . $this->get_link( 'plugin', 'defender_pluginlist_upgrade' ) . '" aria-label="' . esc_attr( __( 'Upgrade to Defender Pro', 'wpdef' ) ) . '">' . esc_html__( 'Upgrade', 'wpdef' ) . '</a>';
130
  } else {
131
- $action_links['renew'] = '<a style="color: #8D00B1;" target="_blank" href="' . $this->get_link( 'plugin', 'defender_pluginlist_renew' ) . '" aria-label="' . esc_attr( __( 'Renew Your Membership', 'wpdef' ) ) . '">' . esc_html__( 'Renew Membership', 'wpdef' ) . '</a>';
132
  }
133
  }
134
 
@@ -138,13 +123,13 @@ class Admin {
138
  /**
139
  * Show row meta on the plugin screen.
140
  *
141
- * @param mixed $links Plugin Row Meta.
142
- * @param mixed $file Plugin Base file.
143
- * @param array $plugin_data Plugin data.
144
  *
145
  * @return array
146
  */
147
- public function plugin_row_meta( $links, $file, $plugin_data ) {
148
  $row_meta = [];
149
  if ( ! defined( 'DEFENDER_PLUGIN_BASENAME' ) || DEFENDER_PLUGIN_BASENAME !== $file ) {
150
  return $links;
@@ -158,7 +143,10 @@ class Admin {
158
  $author_uri,
159
  __( 'WPMU DEV' )
160
  );
161
- $links[1] = sprintf( /* translators: ... */ __( 'By %s' ), $author_uri );
 
 
 
162
  }
163
 
164
  if ( ! $this->is_pro ) {
@@ -182,7 +170,7 @@ class Admin {
182
  $links[2] = str_replace( 'href=', 'target="_blank" href=', $links[2] );
183
  }
184
  }
185
- $row_meta['rate'] = '<a href="' . esc_url( $this->get_link( 'rate' ) ) . '" aria-label="' . esc_attr__( 'Rate Defender', 'wpdef' ) . '" target="_blank">' . esc_html__( 'Rate Defender', 'wpdef' ) . '</a>';
186
  $row_meta['support'] = '<a href="' . esc_url( $this->get_link( 'support' ) ) . '" aria-label="' . esc_attr__( 'Support', 'wpdef' ) . '" target="_blank">' . esc_html__( 'Support', 'wpdef' ) . '</a>';
187
  } else {
188
  // Change 'Visit plugins' link to 'View details'.
@@ -206,18 +194,14 @@ class Admin {
206
  public function dismiss_notice() {
207
  if ( ! current_user_can( 'manage_options' ) || ! check_ajax_referer( 'defender_dismiss_notification' ) ) {
208
  wp_send_json_error(
209
- array(
210
- 'message' => __( 'Invalid request, you are not allowed to do that action.', 'wpdef' ),
211
- )
212
  );
213
  }
214
 
215
  $notification_name = ! empty( $_POST['prop'] ) ? sanitize_text_field( $_POST['prop'] ) : false;
216
  if ( false === $notification_name ) {
217
  wp_send_json_error(
218
- array(
219
- 'message' => __( 'Invalid request, allowed data not provided.', 'wpdef' ),
220
- )
221
  );
222
  }
223
  update_site_option( $notification_name, true );
@@ -255,11 +239,11 @@ class Admin {
255
  'wpmudev-recommended-plugins-register-notice',
256
  DEFENDER_PLUGIN_BASENAME, // Plugin basename
257
  'Defender', // Plugin Name
258
- array(
259
  'toplevel_page_wp-defender',
260
  'toplevel_page_wp-defender-network',
261
- ),
262
- array( 'after', '.sui-wrap .sui-header' )
263
  );
264
  }
265
 
@@ -272,9 +256,10 @@ class Admin {
272
  return;
273
  }
274
 
275
- $install_date = get_site_option( 'defender_free_install_date', false );
276
  // @since 2.6.1
277
- $days_later_dismiss = get_site_option( 'defender_days_rating_later_dismiss',
 
278
  apply_filters( 'wd_dismiss_rating', false )
279
  );
280
 
@@ -345,7 +330,7 @@ class Admin {
345
  if ( isset( $plugin_data->new_version )
346
  && '3' === substr( trim( $plugin_data->new_version ), 0, 1 )
347
  && version_compare( DEFENDER_VERSION, '3', '<' )
348
- ){
349
  // Major plugin version or subsequent versions.
350
  $new_version = ( '3' === $plugin_data->new_version ) ? '3.0.0' : $plugin_data->new_version;
351
  // Collect notice.
@@ -363,7 +348,7 @@ class Admin {
363
 
364
  echo "<script type='text/javascript'>
365
  (function ($) {
366
- $(document).ready(function () {
367
  $( '.wp-list-table tr[data-plugin=\"" . esc_attr( $plugin_data->plugin ) . "\"] .notice-warning' ).html( '" . addslashes( $notice ) . "' ).css('padding-bottom', '10px');
368
  });
369
  })(jQuery);
1
  <?php
2
+ declare( strict_types=1 );
3
 
4
  namespace WP_Defender;
5
 
26
  */
27
  public function init() {
28
  $this->is_pro = ( new WPMUDEV() )->is_pro();
29
+ $is_def_page = defender_current_page();
 
30
  // Display plugin links.
31
+ add_filter( 'network_admin_plugin_action_links_' . DEFENDER_PLUGIN_BASENAME, [ $this, 'settings_link' ] );
32
+ add_filter( 'plugin_action_links_' . DEFENDER_PLUGIN_BASENAME, [ $this, 'settings_link' ] );
33
+ add_filter( 'plugin_row_meta', [ $this, 'plugin_row_meta' ], 10, 3 );
34
  // WP_DEFENDER_PRO sometimes doesn't match $this->is_pro, e.g. WPMU DEV Dashboard is deactivated.
35
  if ( defined( 'WP_DEFENDER_PRO' ) && WP_DEFENDER_PRO ) {
36
  // This area is only for Pro version.
37
  add_action(
38
  'load-plugins.php',
39
  function () {
40
+ add_action( 'after_plugin_row_' . DEFENDER_PLUGIN_BASENAME, [ $this, 'show_upgrade_notice' ], 10, 2 );
 
 
 
41
  },
42
  22
43
  );
44
  } else {
45
  // This area is only for wordpress.org members.
46
  // Add plugin upgrade notification.
47
+ add_action( 'in_plugin_update_message-' . DEFENDER_PLUGIN_BASENAME, [ $this, 'show_upgrade_notice' ], 10, 2 );
48
  if ( $is_def_page && ! is_multisite() ) {
49
+ add_action( 'admin_notices', [ $this, 'show_rating_notice' ] );
50
  } elseif ( $is_def_page && is_multisite() && is_main_site() ) {
51
+ add_action( 'network_admin_notices', [ $this, 'show_rating_notice' ] );
52
  }
53
+ add_action( 'wp_ajax_defender_dismiss_notification', [ $this, 'dismiss_notice' ] );
54
+ add_action( 'admin_init', [ $this, 'register_free_modules' ], 20 );
 
 
 
 
 
 
 
 
 
 
 
55
  }
56
  }
57
 
64
  *
65
  * @return string
66
  */
67
+ public function get_link( $link_for, $campaign = '', $adv_path = '' ): string {
68
+ $domain = 'https://wpmudev.com';
69
+ $wp_org = 'https://wordpress.org';
70
  $utm_tags = "?utm_source=defender&utm_medium=plugin&utm_campaign={$campaign}";
71
  switch ( $link_for ) {
72
  case 'docs':
95
  return $link;
96
  }
97
 
 
98
  /**
99
  * Adds a settings link on plugin page.
100
  *
102
  *
103
  * @return array
104
  */
105
+ public function settings_link( $links ): array {
106
  $action_links = [];
107
  $wpmu_dev = new WPMUDEV();
108
  // Settings link.
109
+ $action_links['dashboard'] = '<a href="' . network_admin_url( 'admin.php?page=wdf-setting' ) . '" aria-label="' . esc_attr( __( 'Go to Defender Settings', 'wpdef' ) ) . '">' . esc_html__( 'Settings', 'wpdef' ) . '</a>';
110
  // Documentation link.
111
+ $action_links['docs'] = '<a target="_blank" href="' . $this->get_link( 'docs', 'defender_pluginlist_docs' ) . '" aria-label="' . esc_attr( __( 'Docs', 'wpdef' ) ) . '">' . esc_html__( 'Docs', 'wpdef' ) . '</a>';
112
  if ( ! $wpmu_dev->is_member() ) {
113
  if ( WP_DEFENDER_PRO_PATH !== DEFENDER_PLUGIN_BASENAME ) {
114
  $action_links['upgrade'] = '<a style="color: #8D00B1;" target="_blank" href="' . $this->get_link( 'plugin', 'defender_pluginlist_upgrade' ) . '" aria-label="' . esc_attr( __( 'Upgrade to Defender Pro', 'wpdef' ) ) . '">' . esc_html__( 'Upgrade', 'wpdef' ) . '</a>';
115
  } else {
116
+ $action_links['renew'] = '<a style="color: #8D00B1;" target="_blank" href="' . $this->get_link( 'plugin', 'defender_pluginlist_renew' ) . '" aria-label="' . esc_attr( __( 'Renew Your Membership', 'wpdef' ) ) . '">' . esc_html__( 'Renew Membership', 'wpdef' ) . '</a>';
117
  }
118
  }
119
 
123
  /**
124
  * Show row meta on the plugin screen.
125
  *
126
+ * @param string[] $links Plugin Row Meta.
127
+ * @param string $file Plugin Base file.
128
+ * @param array $plugin_data Plugin data.
129
  *
130
  * @return array
131
  */
132
+ public function plugin_row_meta( $links, $file, $plugin_data ): array {
133
  $row_meta = [];
134
  if ( ! defined( 'DEFENDER_PLUGIN_BASENAME' ) || DEFENDER_PLUGIN_BASENAME !== $file ) {
135
  return $links;
143
  $author_uri,
144
  __( 'WPMU DEV' )
145
  );
146
+ $links[1] = sprintf(
147
+ /* translators: %s - author URI */
148
+ __( 'By %s' ), $author_uri
149
+ );
150
  }
151
 
152
  if ( ! $this->is_pro ) {
170
  $links[2] = str_replace( 'href=', 'target="_blank" href=', $links[2] );
171
  }
172
  }
173
+ $row_meta['rate'] = '<a href="' . esc_url( $this->get_link( 'rate' ) ) . '" aria-label="' . esc_attr__( 'Rate Defender', 'wpdef' ) . '" target="_blank">' . esc_html__( 'Rate Defender', 'wpdef' ) . '</a>';
174
  $row_meta['support'] = '<a href="' . esc_url( $this->get_link( 'support' ) ) . '" aria-label="' . esc_attr__( 'Support', 'wpdef' ) . '" target="_blank">' . esc_html__( 'Support', 'wpdef' ) . '</a>';
175
  } else {
176
  // Change 'Visit plugins' link to 'View details'.
194
  public function dismiss_notice() {
195
  if ( ! current_user_can( 'manage_options' ) || ! check_ajax_referer( 'defender_dismiss_notification' ) ) {
196
  wp_send_json_error(
197
+ [ 'message' => __( 'Invalid request, you are not allowed to do that action.', 'wpdef' ) ]
 
 
198
  );
199
  }
200
 
201
  $notification_name = ! empty( $_POST['prop'] ) ? sanitize_text_field( $_POST['prop'] ) : false;
202
  if ( false === $notification_name ) {
203
  wp_send_json_error(
204
+ [ 'message' => __( 'Invalid request, allowed data not provided.', 'wpdef' ) ]
 
 
205
  );
206
  }
207
  update_site_option( $notification_name, true );
239
  'wpmudev-recommended-plugins-register-notice',
240
  DEFENDER_PLUGIN_BASENAME, // Plugin basename
241
  'Defender', // Plugin Name
242
+ [
243
  'toplevel_page_wp-defender',
244
  'toplevel_page_wp-defender-network',
245
+ ],
246
+ [ 'after', '.sui-wrap .sui-header' ]
247
  );
248
  }
249
 
256
  return;
257
  }
258
 
259
+ $install_date = (int) get_site_option( 'defender_free_install_date', false );
260
  // @since 2.6.1
261
+ $days_later_dismiss = get_site_option(
262
+ 'defender_days_rating_later_dismiss',
263
  apply_filters( 'wd_dismiss_rating', false )
264
  );
265
 
330
  if ( isset( $plugin_data->new_version )
331
  && '3' === substr( trim( $plugin_data->new_version ), 0, 1 )
332
  && version_compare( DEFENDER_VERSION, '3', '<' )
333
+ ) {
334
  // Major plugin version or subsequent versions.
335
  $new_version = ( '3' === $plugin_data->new_version ) ? '3.0.0' : $plugin_data->new_version;
336
  // Collect notice.
348
 
349
  echo "<script type='text/javascript'>
350
  (function ($) {
351
+ $( function () {
352
  $( '.wp-list-table tr[data-plugin=\"" . esc_attr( $plugin_data->plugin ) . "\"] .notice-warning' ).html( '" . addslashes( $notice ) . "' ).css('padding-bottom', '10px');
353
  });
354
  })(jQuery);
src/model/notification.php CHANGED
@@ -168,7 +168,7 @@ abstract class Notification extends Setting {
168
  /**
169
  * Check if the current moment is right for sending.
170
  *
171
- * @return bool|void
172
  */
173
  public function maybe_send() {
174
  // @since 2.7.0 We can remove 'dry_run'-condition in the next version.
@@ -176,11 +176,15 @@ abstract class Notification extends Setting {
176
  // No send, but need to track as sent, so we can requeue it.
177
  if ( 'report' === $this->type ) {
178
  $this->last_sent = $this->est_timestamp;
179
- $this->est_timestamp = $this->get_next_run()->getTimestamp();
 
 
 
 
180
  $this->save();
181
  }
182
 
183
- return;
184
  }
185
 
186
  if ( ! $this->check_active_status() ) {
@@ -252,9 +256,9 @@ abstract class Notification extends Setting {
252
  break;
253
  case 'monthly':
254
  // We will need to check if the date is passed today, if not, use this, if yes, then queue for next month.
255
- $est->setDate( $est->format( 'Y' ), $est->format( 'm' ), 1 );
256
  if ( 31 === (int) $this->day_n ) {
257
- $this->day_n = $est->format( 't' );
258
  }
259
  $est->add( new \DateInterval( 'P' . ( $this->day_n - 1 ) . 'D' ) );
260
  $est->setTime( $hour, $min, 0 );
@@ -313,7 +317,7 @@ abstract class Notification extends Setting {
313
  }
314
 
315
  /**
316
- * @param false $for_hub
317
  *
318
  * @return false|string|void
319
  * @throws \Exception
@@ -344,7 +348,7 @@ abstract class Notification extends Setting {
344
  /**
345
  * We still need to validate the out house recipients email.
346
  */
347
- public function after_validate() {
348
  foreach ( $this->out_house_recipients as $recipient ) {
349
  $recipient['email'] = trim( $recipient['email'] );
350
  if ( empty( $recipient['email'] ) ) {
@@ -356,7 +360,7 @@ abstract class Notification extends Setting {
356
  }
357
  }
358
 
359
- public function save() {
360
  if ( empty( $this->last_sent ) ) {
361
  $this->last_sent = time();
362
  }
@@ -373,7 +377,6 @@ abstract class Notification extends Setting {
373
  * @return array
374
  */
375
  public function export(): array {
376
-
377
  $data = parent::export();
378
 
379
  global $l10n;
@@ -392,7 +395,7 @@ abstract class Notification extends Setting {
392
  /**
393
  * Overrided method to manipulate user details dynamically.
394
  */
395
- protected function after_load(): string {
396
  $in_house_recipients = [];
397
 
398
  foreach ( $this->in_house_recipients as $recipient ) {
@@ -422,7 +425,5 @@ abstract class Notification extends Setting {
422
  }
423
 
424
  $this->in_house_recipients = $in_house_recipients;
425
-
426
- return '';
427
  }
428
  }
168
  /**
169
  * Check if the current moment is right for sending.
170
  *
171
+ * @return bool
172
  */
173
  public function maybe_send() {
174
  // @since 2.7.0 We can remove 'dry_run'-condition in the next version.
176
  // No send, but need to track as sent, so we can requeue it.
177
  if ( 'report' === $this->type ) {
178
  $this->last_sent = $this->est_timestamp;
179
+
180
+ if ( $this->get_next_run() instanceof \DateTime ) {
181
+ $this->est_timestamp = $this->get_next_run()->getTimestamp();
182
+ }
183
+
184
  $this->save();
185
  }
186
 
187
+ return false;
188
  }
189
 
190
  if ( ! $this->check_active_status() ) {
256
  break;
257
  case 'monthly':
258
  // We will need to check if the date is passed today, if not, use this, if yes, then queue for next month.
259
+ $est->setDate( (int) $est->format( 'Y' ), (int) $est->format( 'm' ), 1 );
260
  if ( 31 === (int) $this->day_n ) {
261
+ $this->day_n = (int) $est->format( 't' );
262
  }
263
  $est->add( new \DateInterval( 'P' . ( $this->day_n - 1 ) . 'D' ) );
264
  $est->setTime( $hour, $min, 0 );
317
  }
318
 
319
  /**
320
+ * @param boolean $for_hub
321
  *
322
  * @return false|string|void
323
  * @throws \Exception
348
  /**
349
  * We still need to validate the out house recipients email.
350
  */
351
+ protected function after_validate(): void {
352
  foreach ( $this->out_house_recipients as $recipient ) {
353
  $recipient['email'] = trim( $recipient['email'] );
354
  if ( empty( $recipient['email'] ) ) {
360
  }
361
  }
362
 
363
+ public function save(): void {
364
  if ( empty( $this->last_sent ) ) {
365
  $this->last_sent = time();
366
  }
377
  * @return array
378
  */
379
  public function export(): array {
 
380
  $data = parent::export();
381
 
382
  global $l10n;
395
  /**
396
  * Overrided method to manipulate user details dynamically.
397
  */
398
+ protected function after_load() {
399
  $in_house_recipients = [];
400
 
401
  foreach ( $this->in_house_recipients as $recipient ) {
425
  }
426
 
427
  $this->in_house_recipients = $in_house_recipients;
 
 
428
  }
429
  }
src/model/setting/blacklist-lockout.php CHANGED
@@ -220,12 +220,10 @@ class Blacklist_Lockout extends Setting {
220
  /**
221
  * Define labels for settings key.
222
  *
223
- * @param string|null $key
224
- *
225
- * @return string|array|null
226
  */
227
- public function labels( $key = null ): array {
228
- $labels = [
229
  'ip_blacklist' => __( 'IP Banning - IP Addresses Blocklist', 'wpdef' ),
230
  'ip_whitelist' => __( 'IP Banning - IP Addresses Allowlist', 'wpdef' ),
231
  'country_blacklist' => __( 'IP Banning - Country Allowlist', 'wpdef' ),
@@ -233,12 +231,6 @@ class Blacklist_Lockout extends Setting {
233
  'ip_lockout_message' => __( 'IP Banning - Lockout Message', 'wpdef' ),
234
  'maxmind_license_key' => __( 'MaxMind license key', 'wpdef' ),
235
  ];
236
-
237
- if ( ! is_null( $key ) ) {
238
- return $labels[ $key ] ?? null;
239
- }
240
-
241
- return $labels;
242
  }
243
 
244
  protected function after_load() {
220
  /**
221
  * Define labels for settings key.
222
  *
223
+ * @return array
 
 
224
  */
225
+ public function labels(): array {
226
+ return [
227
  'ip_blacklist' => __( 'IP Banning - IP Addresses Blocklist', 'wpdef' ),
228
  'ip_whitelist' => __( 'IP Banning - IP Addresses Allowlist', 'wpdef' ),
229
  'country_blacklist' => __( 'IP Banning - Country Allowlist', 'wpdef' ),
231
  'ip_lockout_message' => __( 'IP Banning - Lockout Message', 'wpdef' ),
232
  'maxmind_license_key' => __( 'MaxMind license key', 'wpdef' ),
233
  ];
 
 
 
 
 
 
234
  }
235
 
236
  protected function after_load() {
src/traits/defender-hub-client.php CHANGED
@@ -74,11 +74,11 @@ trait Defender_Hub_Client {
74
  /**
75
  * Get WPMUDEV site id.
76
  *
77
- * @return bool
78
  */
79
- public function get_site_id(): bool {
80
  if ( $this->get_apikey() !== false ) {
81
- return \WPMUDEV_Dashboard::$api->get_site_id();
82
  }
83
 
84
  return false;
74
  /**
75
  * Get WPMUDEV site id.
76
  *
77
+ * @return int|bool
78
  */
79
+ public function get_site_id() {
80
  if ( $this->get_apikey() !== false ) {
81
+ return (int) \WPMUDEV_Dashboard::$api->get_site_id();
82
  }
83
 
84
  return false;
wp-defender.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Plugin Name: Defender
4
  * Plugin URI: https://wpmudev.com/project/wp-defender/
5
- * Version: 3.1.1
6
  * Description: Get regular security scans, vulnerability reports, safety recommendations and customized hardening for your site in just a few clicks. Defender is the analyst and enforcer who never sleeps.
7
  * Author: WPMU DEV
8
  * Author URI: https://wpmudev.com/
@@ -33,10 +33,10 @@ if ( ! defined( 'ABSPATH' ) ) {
33
  die;
34
  }
35
  if ( ! defined( 'DEFENDER_VERSION' ) ) {
36
- define( 'DEFENDER_VERSION', '3.1.1' );
37
  }
38
  if ( ! defined( 'DEFENDER_DB_VERSION' ) ) {
39
- define( 'DEFENDER_DB_VERSION', '3.1.1' );
40
  }
41
  if ( ! defined( 'DEFENDER_SUI' ) ) {
42
  define( 'DEFENDER_SUI', '2-12-8' );
2
  /**
3
  * Plugin Name: Defender
4
  * Plugin URI: https://wpmudev.com/project/wp-defender/
5
+ * Version: 3.1.2
6
  * Description: Get regular security scans, vulnerability reports, safety recommendations and customized hardening for your site in just a few clicks. Defender is the analyst and enforcer who never sleeps.
7
  * Author: WPMU DEV
8
  * Author URI: https://wpmudev.com/
33
  die;
34
  }
35
  if ( ! defined( 'DEFENDER_VERSION' ) ) {
36
+ define( 'DEFENDER_VERSION', '3.1.2' );
37
  }
38
  if ( ! defined( 'DEFENDER_DB_VERSION' ) ) {
39
+ define( 'DEFENDER_DB_VERSION', '3.1.2' );
40
  }
41
  if ( ! defined( 'DEFENDER_SUI' ) ) {
42
  define( 'DEFENDER_SUI', '2-12-8' );