Version Description
- Enhancement: Replaced file locking with database locking. This method of locking is compatible with all systems as it does not require the ability to write files. It also allows for locking to work on sites that have multiple front-end servers with a shared database. Since file locking is no longer used, the Global Settings > Disable File Locking setting was removed.
- Enhancement: Add "Copy to Clipboard" functionality for server and wp-config rules.
- Bug Fix: Prevent 404s when following links in email notifications on a site with Hide Backend enabled.
- Bug Fix: Ensure uninstall process is not run when another version of iThemes Security is still active.
- Bug Fix: Fixed method of working around Hide Backend.
- Bug Fix: Warnings are no longer generated when saving a user profile with a role of "No role for this site" selected.
Download this release
Release Info
Developer | chrisjean |
Plugin | iThemes Security (formerly Better WP Security) |
Version | 6.4.0 |
Comparing to | |
See all releases |
Code changes from version 6.3.0 to 6.4.0
- better-wp-security.php +1 -1
- core/admin-pages/css/style.css +42 -9
- core/admin-pages/js/script.js +215 -42
- core/admin-pages/page-settings.php +147 -118
- core/files.php +0 -80
- core/history.txt +7 -0
- core/lib.php +59 -0
- core/lib/class-itsec-mail.php +13 -1
- core/lockout.php +5 -6
- core/modules/admin-user/validator.php +4 -6
- core/modules/away-mode/js/settings-page.js +2 -0
- core/modules/backup/class-itsec-backup.php +2 -3
- core/modules/file-change/js/settings-page.js +25 -17
- core/modules/file-change/scanner.php +2 -4
- core/modules/file-change/settings-page.php +1 -1
- core/modules/file-writing/settings-page.php +4 -2
- core/modules/global/settings-page.php +0 -8
- core/modules/global/validator.php +1 -2
- core/modules/hide-backend/class-itsec-hide-backend.php +14 -0
- core/modules/malware/js/settings-page.js +2 -2
- core/modules/security-check/js/settings-page.js +2 -3
- core/modules/ssl/js/settings-page.js +1 -1
- core/modules/strong-passwords/class-itsec-strong-passwords.php +7 -2
- core/notify.php +32 -18
- core/response.php +52 -1
- core/setup.php +53 -9
- history.txt +7 -0
- readme.txt +11 -3
better-wp-security.php
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
* Description: Take the guesswork out of WordPress security. iThemes Security offers 30+ ways to lock down WordPress in an easy-to-use WordPress security plugin.
|
7 |
* Author: iThemes
|
8 |
* Author URI: https://ithemes.com
|
9 |
-
* Version: 6.
|
10 |
* Text Domain: better-wp-security
|
11 |
* Network: True
|
12 |
* License: GPLv2
|
6 |
* Description: Take the guesswork out of WordPress security. iThemes Security offers 30+ ways to lock down WordPress in an easy-to-use WordPress security plugin.
|
7 |
* Author: iThemes
|
8 |
* Author URI: https://ithemes.com
|
9 |
+
* Version: 6.4.0
|
10 |
* Text Domain: better-wp-security
|
11 |
* Network: True
|
12 |
* License: GPLv2
|
core/admin-pages/css/style.css
CHANGED
@@ -181,12 +181,12 @@ ul {
|
|
181 |
}
|
182 |
|
183 |
.itsec-pro-upsell {
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
text-decoration: none;
|
191 |
}
|
192 |
|
@@ -488,7 +488,7 @@ body.itsec-modal-open {
|
|
488 |
|
489 |
#itsec-settings-messages-container div,
|
490 |
.itsec-module-messages-container div {
|
491 |
-
|
492 |
}
|
493 |
|
494 |
#itsec-settings-messages-container.no-module {
|
@@ -498,7 +498,7 @@ body.itsec-modal-open {
|
|
498 |
right: inherit;
|
499 |
opacity: 1;
|
500 |
background: none;
|
501 |
-
border-radius:
|
502 |
box-shadow:none;
|
503 |
-webkit-transition: none;
|
504 |
transition: none;
|
@@ -507,7 +507,6 @@ body.itsec-modal-open {
|
|
507 |
}
|
508 |
|
509 |
#itsec-settings-messages-container.no-module div {
|
510 |
-
box-shadow: none;
|
511 |
background: #fff;
|
512 |
}
|
513 |
|
@@ -699,3 +698,37 @@ body.itsec-modal-open {
|
|
699 |
background-color: #c1e1b9;
|
700 |
border-color: #83c373;
|
701 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
}
|
182 |
|
183 |
.itsec-pro-upsell {
|
184 |
+
display: block;
|
185 |
+
height: 100%;
|
186 |
+
left: 0;
|
187 |
+
position: absolute;
|
188 |
+
top: 0;
|
189 |
+
width: 100%;
|
190 |
text-decoration: none;
|
191 |
}
|
192 |
|
488 |
|
489 |
#itsec-settings-messages-container div,
|
490 |
.itsec-module-messages-container div {
|
491 |
+
|
492 |
}
|
493 |
|
494 |
#itsec-settings-messages-container.no-module {
|
498 |
right: inherit;
|
499 |
opacity: 1;
|
500 |
background: none;
|
501 |
+
border-radius: 0;
|
502 |
box-shadow:none;
|
503 |
-webkit-transition: none;
|
504 |
transition: none;
|
507 |
}
|
508 |
|
509 |
#itsec-settings-messages-container.no-module div {
|
|
|
510 |
background: #fff;
|
511 |
}
|
512 |
|
698 |
background-color: #c1e1b9;
|
699 |
border-color: #83c373;
|
700 |
}
|
701 |
+
|
702 |
+
/**
|
703 |
+
* Styling for output created by ITSEC_Settings_Page::show_details_toggle()
|
704 |
+
*/
|
705 |
+
.itsec-details-toggle-container {
|
706 |
+
}
|
707 |
+
.itsec-details-toggle-container .itsec-details-toggle-details-hidde {
|
708 |
+
display: none;
|
709 |
+
}
|
710 |
+
.itsec-details-toggle-container {
|
711 |
+
font-size: 13px;
|
712 |
+
}
|
713 |
+
.itsec-details-toggle-container .itsec-details-toggle-details :last-child {
|
714 |
+
margin-bottom: 0;
|
715 |
+
}
|
716 |
+
.itsec-details-toggle-container .itsec-details-toggle-details ul li {
|
717 |
+
margin: 1em 0;
|
718 |
+
}
|
719 |
+
|
720 |
+
/**
|
721 |
+
* Styling for email contacts lists
|
722 |
+
*/
|
723 |
+
ul.itsec-settings-contacts {
|
724 |
+
list-style: none;
|
725 |
+
margin: 1em 0;
|
726 |
+
padding-left: 0;
|
727 |
+
}
|
728 |
+
ul.itsec-settings-contacts + ul.itsec-settings-contacts {
|
729 |
+
padding-top: 1em;
|
730 |
+
border-top: 1px solid #ddd;
|
731 |
+
}
|
732 |
+
ul.itsec-settings-contacts li input[type="checkbox"] {
|
733 |
+
margin-top: 0;
|
734 |
+
}
|
core/admin-pages/js/script.js
CHANGED
@@ -1,6 +1,9 @@
|
|
1 |
"use strict";
|
2 |
|
3 |
var itsecSettingsPage = {
|
|
|
|
|
|
|
4 |
init: function() {
|
5 |
jQuery( '.itsec-module-settings-container' ).hide();
|
6 |
|
@@ -9,23 +12,19 @@ var itsecSettingsPage = {
|
|
9 |
jQuery( '.itsec-settings-view-toggle .itsec-selected' ).removeClass( 'itsec-selected' ).trigger( 'click' );
|
10 |
jQuery( '.itsec-settings-toggle' ).trigger( 'change' );
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
} else {
|
16 |
-
itsecSettingsPage.closeGridSettingsModal( e );
|
17 |
-
}
|
18 |
-
|
19 |
-
if ( null !== e.originalEvent.state && 'string' == typeof e.originalEvent.state.module_type && '' !== e.originalEvent.state.module_type.replace( /[^\w-]/g, '' ) ) {
|
20 |
-
jQuery( '#itsec-module-filter-' + e.originalEvent.state.module_type.replace( /[^\w-]/g, '' ) + ' a' ).trigger( 'itsec-popstate' );
|
21 |
-
}
|
22 |
-
});
|
23 |
|
|
|
24 |
var module_type = this.getUrlParameter( 'module_type' );
|
25 |
if ( false === module_type || 0 === jQuery( '#itsec-module-filter-' + module_type.replace( /[^\w-]/g, '' ) ).length ) {
|
26 |
module_type = 'recommended';
|
27 |
}
|
28 |
jQuery( '#itsec-module-filter-' + module_type.replace( /[^\w-]/g, '' ) + ' a' ).trigger( 'click' );
|
|
|
|
|
|
|
29 |
|
30 |
var module = this.getUrlParameter( 'module' );
|
31 |
if ( 'string' === typeof module ) {
|
@@ -34,6 +33,23 @@ var itsecSettingsPage = {
|
|
34 |
},
|
35 |
|
36 |
bindEvents: function() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
var $container = jQuery( '#wpcontent' );
|
38 |
|
39 |
$container.on( 'click', '.itsec-module-filter a', this.filterView );
|
@@ -48,11 +64,27 @@ var itsecSettingsPage = {
|
|
48 |
$container.on( 'click', '.itsec-toggle-activation', this.toggleModuleActivation );
|
49 |
$container.on( 'click', '.itsec-module-settings-save', this.saveSettings );
|
50 |
$container.on( 'click', '.itsec-reload-module', this.reloadModule );
|
|
|
51 |
|
52 |
$container.on( 'change', '#itsec-filter', this.logPageChangeFilter );
|
53 |
|
54 |
// For use by module content to show/hide settings sections based upon an input.
|
55 |
$container.on( 'change', '.itsec-settings-toggle', this.toggleModuleContent );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
},
|
57 |
|
58 |
logPageChangeFilter: function( e ) {
|
@@ -87,6 +119,82 @@ var itsecSettingsPage = {
|
|
87 |
}
|
88 |
},
|
89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
saveSettings: function( e ) {
|
91 |
e.preventDefault();
|
92 |
|
@@ -124,8 +232,9 @@ var itsecSettingsPage = {
|
|
124 |
|
125 |
itsecSettingsPage.clearMessages();
|
126 |
|
127 |
-
if ( results.errors.length > 0 || ! results.closeModal ) {
|
128 |
itsecSettingsPage.showErrors( results.errors, results.module, 'open' );
|
|
|
129 |
itsecSettingsPage.showMessages( results.messages, results.module, 'open' );
|
130 |
|
131 |
if ( 'grid' === view ) {
|
@@ -149,13 +258,16 @@ var itsecSettingsPage = {
|
|
149 |
jQuery( '#itsec-settings-messages-container, .itsec-module-messages-container' ).empty();
|
150 |
},
|
151 |
|
152 |
-
showErrors: function( errors, module, containerStatus ) {
|
153 |
jQuery.each( errors, function( index, error ) {
|
154 |
-
itsecSettingsPage.showError( error, module, containerStatus );
|
155 |
} );
|
156 |
},
|
157 |
|
158 |
-
showError: function( error, module, containerStatus ) {
|
|
|
|
|
|
|
159 |
if ( jQuery( '.itsec-module-cards-container' ).hasClass( 'grid' ) ) {
|
160 |
var view = 'grid';
|
161 |
} else {
|
@@ -181,7 +293,14 @@ var itsecSettingsPage = {
|
|
181 |
var container = jQuery( '#itsec-module-card-' + module + ' .itsec-module-messages-container' );
|
182 |
}
|
183 |
|
184 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
},
|
186 |
|
187 |
showMessages: function( messages, module, containerStatus ) {
|
@@ -219,7 +338,13 @@ var itsecSettingsPage = {
|
|
219 |
var container = jQuery( '#itsec-module-card-' + module + ' .itsec-module-messages-container' );
|
220 |
}
|
221 |
|
222 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
223 |
},
|
224 |
|
225 |
filterView: function( e ) {
|
@@ -269,7 +394,7 @@ var itsecSettingsPage = {
|
|
269 |
jQuery( '.itsec-toggle-settings' ).each(function( index ) {
|
270 |
var $button = jQuery( this );
|
271 |
|
272 |
-
if ( $button.parents( '.itsec-module-card' ).hasClass( 'itsec-module-type-enabled' ) ) {
|
273 |
$button.html( itsec_page.translations.show_settings );
|
274 |
} else if ( $button.hasClass( 'information-only' ) ) {
|
275 |
$button.html( itsec_page.translations.information_only );
|
@@ -295,7 +420,8 @@ var itsecSettingsPage = {
|
|
295 |
openModuleFromLink: function( e ) {
|
296 |
|
297 |
var $link = jQuery( this ), module = $link.data( 'module-link' ),
|
298 |
-
$module = jQuery( '.itsec-module-card[data-module-id="' + module + '"]' )
|
|
|
299 |
|
300 |
if ( ! $module.length ) {
|
301 |
return; // safety check
|
@@ -308,7 +434,9 @@ var itsecSettingsPage = {
|
|
308 |
var $listClassElement = $module.parents( '.itsec-module-cards-container' ),
|
309 |
$toggleButton = $module.find( '.itsec-toggle-settings' );
|
310 |
|
311 |
-
|
|
|
|
|
312 |
|
313 |
if ( $listClassElement.hasClass( 'list' ) ) {
|
314 |
itsecSettingsPage.toggleListSettingsCard.call( $toggleButton, e );
|
@@ -605,10 +733,56 @@ var itsecSettingsPage = {
|
|
605 |
jQuery( '.itsec-settings-toggle' ).trigger( 'change' );
|
606 |
} else if ( results.errors && results.errors.length > 0 ) {
|
607 |
itsecSettingsPage.showErrors( results.errors, results.module, 'open' );
|
|
|
|
|
608 |
}
|
609 |
} );
|
610 |
},
|
611 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
612 |
reloadWidget: function( widget ) {
|
613 |
var method = 'get_refreshed_widget_settings';
|
614 |
var data = {};
|
@@ -618,6 +792,7 @@ var itsecSettingsPage = {
|
|
618 |
jQuery( '#itsec-sidebar-widget-' + module + ' .inside' ).html( results.response );
|
619 |
} else {
|
620 |
itsecSettingsPage.showErrors( results.errors, results.module, 'closed' );
|
|
|
621 |
}
|
622 |
} );
|
623 |
},
|
@@ -647,6 +822,7 @@ var itsecSettingsPage = {
|
|
647 |
'success': false,
|
648 |
'response': null,
|
649 |
'errors': [],
|
|
|
650 |
'messages': [],
|
651 |
'functionCalls': [],
|
652 |
'redirect': false,
|
@@ -660,6 +836,7 @@ var itsecSettingsPage = {
|
|
660 |
results.success = a.success;
|
661 |
results.response = a.response;
|
662 |
results.errors = a.errors;
|
|
|
663 |
results.messages = a.messages;
|
664 |
results.functionCalls = a.functionCalls;
|
665 |
results.redirect = a.redirect;
|
@@ -715,7 +892,7 @@ var itsecSettingsPage = {
|
|
715 |
if ( results.functionCalls ) {
|
716 |
for ( var i = 0; i < results.functionCalls.length; i++ ) {
|
717 |
if ( 'object' === typeof results.functionCalls[i] && 'string' === typeof results.functionCalls[i][0] && 'function' === typeof itsecSettingsPage[results.functionCalls[i][0]] ) {
|
718 |
-
itsecSettingsPage[results.functionCalls[i][0]]( results.functionCalls[i][1] );
|
719 |
} else if ( 'string' === typeof results.functionCalls[i] && 'function' === typeof window[results.functionCalls[i]] ) {
|
720 |
window[results.functionCalls[i]]();
|
721 |
} else if ( 'object' === typeof results.functionCalls[i] && 'string' === typeof results.functionCalls[i][0] && 'function' === typeof window[results.functionCalls[i][0]] ) {
|
@@ -765,33 +942,27 @@ jQuery(document).ready(function( $ ) {
|
|
765 |
}
|
766 |
|
767 |
|
768 |
-
|
769 |
jQuery( '.dialog' ).click( function ( event ) {
|
770 |
-
|
771 |
event.preventDefault();
|
772 |
|
773 |
var target = jQuery( this ).attr( 'href' );
|
774 |
var title = jQuery( this ).parents( '.inside' ).siblings( 'h3.hndle' ).children( 'span' ).text();
|
775 |
|
776 |
jQuery( '#' + target ).dialog( {
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
}
|
790 |
-
|
791 |
-
} );
|
792 |
|
793 |
jQuery( '.ui-dialog :button' ).blur();
|
794 |
-
|
795 |
} );
|
796 |
|
797 |
var regex = /[^\w]/ig;
|
@@ -801,6 +972,11 @@ jQuery(document).ready(function( $ ) {
|
|
801 |
$searchFilter = $( '#itsec-module-filter-search' ),
|
802 |
$currentFilter = $( '.itsec-feature-tabs .current' ).parent();
|
803 |
|
|
|
|
|
|
|
|
|
|
|
804 |
$search.on( 'input', _.debounce( function () {
|
805 |
var query = $search.val().trim().replace( regex, ' ' );
|
806 |
|
@@ -854,13 +1030,10 @@ jQuery(document).ready(function( $ ) {
|
|
854 |
if ( $matches.length === 1 ) {
|
855 |
$( '.itsec-toggle-settings', $matches.first() ).click();
|
856 |
}
|
857 |
-
|
858 |
}, 250 ) );
|
859 |
|
860 |
$.expr[":"].itsecContains = $.expr.createPseudo( function ( arg ) {
|
861 |
-
|
862 |
return function ( elem ) {
|
863 |
-
|
864 |
var candidate = $( elem ).text().toUpperCase().replace( regex, ' ' ), term = arg.toUpperCase();
|
865 |
var index = candidate.indexOf( term );
|
866 |
|
1 |
"use strict";
|
2 |
|
3 |
var itsecSettingsPage = {
|
4 |
+
|
5 |
+
events: jQuery( {} ),
|
6 |
+
|
7 |
init: function() {
|
8 |
jQuery( '.itsec-module-settings-container' ).hide();
|
9 |
|
12 |
jQuery( '.itsec-settings-view-toggle .itsec-selected' ).removeClass( 'itsec-selected' ).trigger( 'click' );
|
13 |
jQuery( '.itsec-settings-toggle' ).trigger( 'change' );
|
14 |
|
15 |
+
this.initFilters();
|
16 |
+
this.initCurrentModule();
|
17 |
+
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
+
initFilters: function() {
|
20 |
var module_type = this.getUrlParameter( 'module_type' );
|
21 |
if ( false === module_type || 0 === jQuery( '#itsec-module-filter-' + module_type.replace( /[^\w-]/g, '' ) ).length ) {
|
22 |
module_type = 'recommended';
|
23 |
}
|
24 |
jQuery( '#itsec-module-filter-' + module_type.replace( /[^\w-]/g, '' ) + ' a' ).trigger( 'click' );
|
25 |
+
},
|
26 |
+
|
27 |
+
initCurrentModule: function() {
|
28 |
|
29 |
var module = this.getUrlParameter( 'module' );
|
30 |
if ( 'string' === typeof module ) {
|
33 |
},
|
34 |
|
35 |
bindEvents: function() {
|
36 |
+
|
37 |
+
if ( itsecSettingsPage.bindEvents.bound ) {
|
38 |
+
return;
|
39 |
+
}
|
40 |
+
|
41 |
+
jQuery(window).on("popstate", function(e, data) {
|
42 |
+
if ( null !== e.originalEvent.state && 'string' == typeof e.originalEvent.state.module && '' !== e.originalEvent.state.module.replace( /[^\w-]/g, '' ) ) {
|
43 |
+
jQuery( '#itsec-module-card-' + e.originalEvent.state.module.replace( /[^\w-]/g, '' ) + ' button.itsec-toggle-settings' ).trigger( 'itsec-popstate' );
|
44 |
+
} else {
|
45 |
+
itsecSettingsPage.closeGridSettingsModal( e );
|
46 |
+
}
|
47 |
+
|
48 |
+
if ( null !== e.originalEvent.state && 'string' == typeof e.originalEvent.state.module_type && '' !== e.originalEvent.state.module_type.replace( /[^\w-]/g, '' ) ) {
|
49 |
+
jQuery( '#itsec-module-filter-' + e.originalEvent.state.module_type.replace( /[^\w-]/g, '' ) + ' a' ).trigger( 'itsec-popstate' );
|
50 |
+
}
|
51 |
+
});
|
52 |
+
|
53 |
var $container = jQuery( '#wpcontent' );
|
54 |
|
55 |
$container.on( 'click', '.itsec-module-filter a', this.filterView );
|
64 |
$container.on( 'click', '.itsec-toggle-activation', this.toggleModuleActivation );
|
65 |
$container.on( 'click', '.itsec-module-settings-save', this.saveSettings );
|
66 |
$container.on( 'click', '.itsec-reload-module', this.reloadModule );
|
67 |
+
$container.on( 'click', '.itsec-details-toggle-container a[href="#"]', this.toggleDetails );
|
68 |
|
69 |
$container.on( 'change', '#itsec-filter', this.logPageChangeFilter );
|
70 |
|
71 |
// For use by module content to show/hide settings sections based upon an input.
|
72 |
$container.on( 'change', '.itsec-settings-toggle', this.toggleModuleContent );
|
73 |
+
$container.on( 'click', '.itsec-copy-trigger', this.handleCopy );
|
74 |
+
|
75 |
+
itsecSettingsPage.bindEvents.bound = true;
|
76 |
+
},
|
77 |
+
|
78 |
+
toggleDetails: function( e ) {
|
79 |
+
e.preventDefault();
|
80 |
+
|
81 |
+
var $details = jQuery(this).parent().find( '.itsec-details-toggle-details' ).toggleClass( 'hide-if-js' );
|
82 |
+
|
83 |
+
if ( $details.hasClass( 'hide-if-js' ) ) {
|
84 |
+
jQuery(this).html( itsec_page.translations.show_information );
|
85 |
+
} else {
|
86 |
+
jQuery(this).html( itsec_page.translations.hide_description );
|
87 |
+
}
|
88 |
},
|
89 |
|
90 |
logPageChangeFilter: function( e ) {
|
119 |
}
|
120 |
},
|
121 |
|
122 |
+
handleCopy: function( e ) {
|
123 |
+
|
124 |
+
e.preventDefault();
|
125 |
+
|
126 |
+
var $trigger = jQuery( e.currentTarget );
|
127 |
+
var fromId = $trigger.data( 'copy-from' );
|
128 |
+
|
129 |
+
if ( ! fromId.length ) {
|
130 |
+
return;
|
131 |
+
}
|
132 |
+
|
133 |
+
var el = document.getElementById( fromId );
|
134 |
+
|
135 |
+
var removeSelect = itsecSettingsPage.selectText( el );
|
136 |
+
|
137 |
+
try {
|
138 |
+
|
139 |
+
document.execCommand( 'copy' );
|
140 |
+
removeSelect();
|
141 |
+
$trigger.text( itsec_page.translations.copied );
|
142 |
+
|
143 |
+
} catch ( e ) {
|
144 |
+
var $p = jQuery( '<p></p>' ).text( itsec_page.translations.copy_instruction ),
|
145 |
+
$notice = jQuery( '<div class="notice notice-alt notice-info"></div>' ).append( $p ),
|
146 |
+
$el = jQuery( el );
|
147 |
+
|
148 |
+
$trigger.after( $notice );
|
149 |
+
|
150 |
+
var removeNotice = function () {
|
151 |
+
$notice.fadeOut( function () {
|
152 |
+
$notice.remove();
|
153 |
+
} );
|
154 |
+
};
|
155 |
+
var copy = function () {
|
156 |
+
|
157 |
+
setTimeout( function () {
|
158 |
+
removeNotice();
|
159 |
+
removeSelect();
|
160 |
+
}, 100 );
|
161 |
+
|
162 |
+
$el.off( 'copy', copy );
|
163 |
+
|
164 |
+
return true;
|
165 |
+
};
|
166 |
+
|
167 |
+
$el.on( 'copy', copy );
|
168 |
+
|
169 |
+
setTimeout( removeNotice, 5000 );
|
170 |
+
}
|
171 |
+
},
|
172 |
+
|
173 |
+
// https://stackoverflow.com/a/987376
|
174 |
+
selectText: function( element ) {
|
175 |
+
var doc = document, text = element, range, selection;
|
176 |
+
|
177 |
+
if ( doc.body.createTextRange ) { // ie
|
178 |
+
range = document.body.createTextRange();
|
179 |
+
range.moveToElementText( text );
|
180 |
+
range.select();
|
181 |
+
} else if ( window.getSelection ) {
|
182 |
+
selection = window.getSelection();
|
183 |
+
range = document.createRange();
|
184 |
+
range.selectNodeContents( text );
|
185 |
+
selection.removeAllRanges();
|
186 |
+
selection.addRange( range );
|
187 |
+
}
|
188 |
+
|
189 |
+
return function() {
|
190 |
+
if ( selection ) {
|
191 |
+
selection.removeAllRanges();
|
192 |
+
} else {
|
193 |
+
range.collapse();
|
194 |
+
}
|
195 |
+
};
|
196 |
+
},
|
197 |
+
|
198 |
saveSettings: function( e ) {
|
199 |
e.preventDefault();
|
200 |
|
232 |
|
233 |
itsecSettingsPage.clearMessages();
|
234 |
|
235 |
+
if ( results.errors.length > 0 || results.warnings.length > 0 || ! results.closeModal ) {
|
236 |
itsecSettingsPage.showErrors( results.errors, results.module, 'open' );
|
237 |
+
itsecSettingsPage.showErrors( results.warnings, results.module, 'open', 'warning' );
|
238 |
itsecSettingsPage.showMessages( results.messages, results.module, 'open' );
|
239 |
|
240 |
if ( 'grid' === view ) {
|
258 |
jQuery( '#itsec-settings-messages-container, .itsec-module-messages-container' ).empty();
|
259 |
},
|
260 |
|
261 |
+
showErrors: function( errors, module, containerStatus, type ) {
|
262 |
jQuery.each( errors, function( index, error ) {
|
263 |
+
itsecSettingsPage.showError( error, module, containerStatus, type );
|
264 |
} );
|
265 |
},
|
266 |
|
267 |
+
showError: function( error, module, containerStatus, type ) {
|
268 |
+
|
269 |
+
type = type || 'error';
|
270 |
+
|
271 |
if ( jQuery( '.itsec-module-cards-container' ).hasClass( 'grid' ) ) {
|
272 |
var view = 'grid';
|
273 |
} else {
|
293 |
var container = jQuery( '#itsec-module-card-' + module + ' .itsec-module-messages-container' );
|
294 |
}
|
295 |
|
296 |
+
var $notice = jQuery( '<div class="notice"><p><strong>' + error + '</strong></p></div>' );
|
297 |
+
$notice.addClass( 'notice-' + type );
|
298 |
+
|
299 |
+
if ( containerStatus === 'open' || module.length ) {
|
300 |
+
$notice.addClass( 'notice-alt' );
|
301 |
+
}
|
302 |
+
|
303 |
+
container.append( $notice ).addClass( 'visible' );
|
304 |
},
|
305 |
|
306 |
showMessages: function( messages, module, containerStatus ) {
|
338 |
var container = jQuery( '#itsec-module-card-' + module + ' .itsec-module-messages-container' );
|
339 |
}
|
340 |
|
341 |
+
var $notice = jQuery( '<div class="notice notice-success fade"><p><strong>' + message + '</strong></p></div>' );
|
342 |
+
|
343 |
+
if ( containerStatus === 'open' || module.length ) {
|
344 |
+
$notice.addClass( 'notice-alt' );
|
345 |
+
}
|
346 |
+
|
347 |
+
container.append( $notice ).addClass( 'visible' );
|
348 |
},
|
349 |
|
350 |
filterView: function( e ) {
|
394 |
jQuery( '.itsec-toggle-settings' ).each(function( index ) {
|
395 |
var $button = jQuery( this );
|
396 |
|
397 |
+
if ( $button.parents( '.itsec-module-card' ).hasClass( 'itsec-module-type-enabled' ) && ! $button.hasClass( 'information-only' ) ) {
|
398 |
$button.html( itsec_page.translations.show_settings );
|
399 |
} else if ( $button.hasClass( 'information-only' ) ) {
|
400 |
$button.html( itsec_page.translations.information_only );
|
420 |
openModuleFromLink: function( e ) {
|
421 |
|
422 |
var $link = jQuery( this ), module = $link.data( 'module-link' ),
|
423 |
+
$module = jQuery( '.itsec-module-card[data-module-id="' + module + '"]' ),
|
424 |
+
highlight = $link.data( 'highlight-setting-id' );
|
425 |
|
426 |
if ( ! $module.length ) {
|
427 |
return; // safety check
|
434 |
var $listClassElement = $module.parents( '.itsec-module-cards-container' ),
|
435 |
$toggleButton = $module.find( '.itsec-toggle-settings' );
|
436 |
|
437 |
+
if ( highlight.length ) {
|
438 |
+
jQuery( 'label[for="' + highlight + '"]', $module ).parents( 'tr' ).addClass( 'itsec-highlighted-setting' );
|
439 |
+
}
|
440 |
|
441 |
if ( $listClassElement.hasClass( 'list' ) ) {
|
442 |
itsecSettingsPage.toggleListSettingsCard.call( $toggleButton, e );
|
733 |
jQuery( '.itsec-settings-toggle' ).trigger( 'change' );
|
734 |
} else if ( results.errors && results.errors.length > 0 ) {
|
735 |
itsecSettingsPage.showErrors( results.errors, results.module, 'open' );
|
736 |
+
} else if ( results.warnings && results.warnings.length > 0 ) {
|
737 |
+
itsecSettingsPage.showErrors( results.warnings, results.module, 'open', 'warning' );
|
738 |
}
|
739 |
} );
|
740 |
},
|
741 |
|
742 |
+
reloadAllModules: function( _, initialResponse) {
|
743 |
+
itsecSettingsPage.sendAJAXRequest( '#', 'get_refreshed_module_form', null, function ( response ) {
|
744 |
+
|
745 |
+
if ( ! response.success || response.errors.length ) {
|
746 |
+
return;
|
747 |
+
}
|
748 |
+
|
749 |
+
var $open;
|
750 |
+
|
751 |
+
if ( jQuery( 'body' ).hasClass( 'itsec-modal-open' ) ) {
|
752 |
+
var $newModules = jQuery( response.response ), $cardsList = jQuery( '.itsec-module-cards' );
|
753 |
+
$open = jQuery( '.itsec-module-settings-container:visible' ).parents( '.itsec-module-card' );
|
754 |
+
|
755 |
+
jQuery( '.itsec-module-card', $newModules ).each( function () {
|
756 |
+
var $new = jQuery( this ), $current = jQuery( '#' + $new.attr( 'id' ), $cardsList );
|
757 |
+
|
758 |
+
if ( $new.attr( 'id' ).length && $new.attr( 'id' ) === $open.attr( 'id' ) ) {
|
759 |
+
jQuery( '.itsec-module-settings-content-main', $current ).html( jQuery( '.itsec-module-settings-content-main', $new ).html() );
|
760 |
+
} else {
|
761 |
+
jQuery( '.itsec-module-settings-container', $new ).hide();
|
762 |
+
$current.replaceWith( $new );
|
763 |
+
}
|
764 |
+
} );
|
765 |
+
|
766 |
+
} else {
|
767 |
+
jQuery( '.itsec-module-cards-container' ).html( response.response );
|
768 |
+
}
|
769 |
+
|
770 |
+
itsecSettingsPage.initFilters();
|
771 |
+
|
772 |
+
if ( ! $open ) {
|
773 |
+
jQuery( '.itsec-module-settings-container' ).hide();
|
774 |
+
}
|
775 |
+
|
776 |
+
if ( initialResponse ) {
|
777 |
+
itsecSettingsPage.showMessages( initialResponse.messages, initialResponse.module, $open ? 'open' : 'closed' );
|
778 |
+
itsecSettingsPage.showErrors( initialResponse.errors, initialResponse.module, $open ? 'open' : 'closed' );
|
779 |
+
itsecSettingsPage.showErrors( initialResponse.warnings, initialResponse.module, $open ? 'open' : 'closed', 'warning' );
|
780 |
+
}
|
781 |
+
|
782 |
+
itsecSettingsPage.events.trigger( 'modulesReloaded', initialResponse );
|
783 |
+
} );
|
784 |
+
},
|
785 |
+
|
786 |
reloadWidget: function( widget ) {
|
787 |
var method = 'get_refreshed_widget_settings';
|
788 |
var data = {};
|
792 |
jQuery( '#itsec-sidebar-widget-' + module + ' .inside' ).html( results.response );
|
793 |
} else {
|
794 |
itsecSettingsPage.showErrors( results.errors, results.module, 'closed' );
|
795 |
+
itsecSettingsPage.showErrors( results.warnings, results.module, 'closed', 'warning' );
|
796 |
}
|
797 |
} );
|
798 |
},
|
822 |
'success': false,
|
823 |
'response': null,
|
824 |
'errors': [],
|
825 |
+
'warnings': [],
|
826 |
'messages': [],
|
827 |
'functionCalls': [],
|
828 |
'redirect': false,
|
836 |
results.success = a.success;
|
837 |
results.response = a.response;
|
838 |
results.errors = a.errors;
|
839 |
+
results.warnings = a.warnings;
|
840 |
results.messages = a.messages;
|
841 |
results.functionCalls = a.functionCalls;
|
842 |
results.redirect = a.redirect;
|
892 |
if ( results.functionCalls ) {
|
893 |
for ( var i = 0; i < results.functionCalls.length; i++ ) {
|
894 |
if ( 'object' === typeof results.functionCalls[i] && 'string' === typeof results.functionCalls[i][0] && 'function' === typeof itsecSettingsPage[results.functionCalls[i][0]] ) {
|
895 |
+
itsecSettingsPage[results.functionCalls[i][0]]( results.functionCalls[i][1], results );
|
896 |
} else if ( 'string' === typeof results.functionCalls[i] && 'function' === typeof window[results.functionCalls[i]] ) {
|
897 |
window[results.functionCalls[i]]();
|
898 |
} else if ( 'object' === typeof results.functionCalls[i] && 'string' === typeof results.functionCalls[i][0] && 'function' === typeof window[results.functionCalls[i][0]] ) {
|
942 |
}
|
943 |
|
944 |
|
|
|
945 |
jQuery( '.dialog' ).click( function ( event ) {
|
|
|
946 |
event.preventDefault();
|
947 |
|
948 |
var target = jQuery( this ).attr( 'href' );
|
949 |
var title = jQuery( this ).parents( '.inside' ).siblings( 'h3.hndle' ).children( 'span' ).text();
|
950 |
|
951 |
jQuery( '#' + target ).dialog( {
|
952 |
+
dialogClass : 'wp-dialog itsec-dialog itsec-dialog-logs',
|
953 |
+
modal : true,
|
954 |
+
closeOnEscape: true,
|
955 |
+
title : title,
|
956 |
+
height : ( jQuery( window ).height() * 0.8 ),
|
957 |
+
width : ( jQuery( window ).width() * 0.8 ),
|
958 |
+
open : function ( event, ui ) {
|
959 |
+
jQuery( '.ui-widget-overlay' ).bind( 'click', function () {
|
960 |
+
jQuery( this ).siblings( '.ui-dialog' ).find( '.ui-dialog-content' ).dialog( 'close' );
|
961 |
+
} );
|
962 |
+
}
|
963 |
+
} );
|
|
|
|
|
|
|
964 |
|
965 |
jQuery( '.ui-dialog :button' ).blur();
|
|
|
966 |
} );
|
967 |
|
968 |
var regex = /[^\w]/ig;
|
972 |
$searchFilter = $( '#itsec-module-filter-search' ),
|
973 |
$currentFilter = $( '.itsec-feature-tabs .current' ).parent();
|
974 |
|
975 |
+
itsecSettingsPage.events.on( 'modulesReloaded', function() {
|
976 |
+
$cardsContainer = $( '.itsec-module-cards' );
|
977 |
+
$cards = $( '.itsec-module-card', $cardsContainer );
|
978 |
+
} );
|
979 |
+
|
980 |
$search.on( 'input', _.debounce( function () {
|
981 |
var query = $search.val().trim().replace( regex, ' ' );
|
982 |
|
1030 |
if ( $matches.length === 1 ) {
|
1031 |
$( '.itsec-toggle-settings', $matches.first() ).click();
|
1032 |
}
|
|
|
1033 |
}, 250 ) );
|
1034 |
|
1035 |
$.expr[":"].itsecContains = $.expr.createPseudo( function ( arg ) {
|
|
|
1036 |
return function ( elem ) {
|
|
|
1037 |
var candidate = $( elem ).text().toUpperCase().replace( regex, ' ' ), term = arg.toUpperCase();
|
1038 |
var index = candidate.indexOf( term );
|
1039 |
|
core/admin-pages/page-settings.php
CHANGED
@@ -2,7 +2,9 @@
|
|
2 |
|
3 |
|
4 |
final class ITSEC_Settings_Page {
|
5 |
-
private $version = 1.
|
|
|
|
|
6 |
|
7 |
private $self_url = '';
|
8 |
private $modules = array();
|
@@ -10,7 +12,7 @@ final class ITSEC_Settings_Page {
|
|
10 |
private $translations = array();
|
11 |
|
12 |
|
13 |
-
|
14 |
add_action( 'itsec-settings-page-register-module', array( $this, 'register_module' ) );
|
15 |
add_action( 'itsec-settings-page-register-widget', array( $this, 'register_widget' ) );
|
16 |
|
@@ -43,6 +45,14 @@ final class ITSEC_Settings_Page {
|
|
43 |
}
|
44 |
}
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
public function add_settings_classes( $classes ) {
|
47 |
if ( ITSEC_Modules::get_setting( 'global', 'show_error_codes' ) ) {
|
48 |
$classes .= ' itsec-show-error-codes';
|
@@ -104,6 +114,8 @@ final class ITSEC_Settings_Page {
|
|
104 |
'activate' => __( 'Enable', 'better-wp-security' ),
|
105 |
'deactivate' => __( 'Disable', 'better-wp-security' ),
|
106 |
'error' => __( 'Error', 'better-wp-security' ),
|
|
|
|
|
107 |
|
108 |
/* translators: 1: module name */
|
109 |
'successful_save' => __( 'Settings saved successfully for %1$s.', 'better-wp-security' ),
|
@@ -167,6 +179,12 @@ final class ITSEC_Settings_Page {
|
|
167 |
ITSEC_Response::set_response( $this->get_module_settings( $module ) );
|
168 |
} else if ( 'get_refreshed_widget_settings' === $method ) {
|
169 |
ITSEC_Response::set_response( $this->get_widget_settings( $module ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
} else if ( 'handle_module_request' === $method ) {
|
171 |
if ( isset( $this->modules[$module] ) ) {
|
172 |
if ( isset( $_POST['data'] ) ) {
|
@@ -370,10 +388,7 @@ final class ITSEC_Settings_Page {
|
|
370 |
}
|
371 |
}
|
372 |
|
373 |
-
private function
|
374 |
-
$form = new ITSEC_Form();
|
375 |
-
|
376 |
-
|
377 |
$module_filters = array(
|
378 |
'all' => array(
|
379 |
_x( 'All', 'List all modules', 'better-wp-security' ),
|
@@ -389,31 +404,27 @@ final class ITSEC_Settings_Page {
|
|
389 |
),
|
390 |
);
|
391 |
|
392 |
-
|
393 |
-
$current_type = isset( $_REQUEST['module_type'] ) ? $_REQUEST['module_type'] : 'recommended';
|
394 |
-
$visible_modules = array();
|
395 |
-
|
396 |
foreach ( $this->modules as $id => $module ) {
|
397 |
$module_filters['all'][1]++;
|
398 |
|
399 |
-
if ( 'all' === $current_type ) {
|
400 |
-
$visible_modules[] = $id;
|
401 |
-
}
|
402 |
-
|
403 |
-
|
404 |
if ( isset( $module_filters[$module->type] ) ) {
|
405 |
$module_filters[$module->type][1]++;
|
406 |
-
|
407 |
-
if ( $module->type === $current_type ) {
|
408 |
-
$visible_modules[] = $id;
|
409 |
-
}
|
410 |
}
|
411 |
|
412 |
-
|
413 |
$module->enabled = ITSEC_Modules::is_active( $id );
|
414 |
$module->always_active = ITSEC_Modules::is_always_active( $id );
|
415 |
}
|
416 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
417 |
$feature_tabs = array();
|
418 |
|
419 |
foreach ( $module_filters as $type => $data ) {
|
@@ -426,10 +437,6 @@ final class ITSEC_Settings_Page {
|
|
426 |
$feature_tabs[] = "<li class='itsec-module-filter' id='itsec-module-filter-$type'><a href='" . esc_url( add_query_arg( 'module_type', $type, $this->self_url ) ) . "' class='$class'>{$data[0]} <span class='count'>({$data[1]})</span></a>";
|
427 |
}
|
428 |
|
429 |
-
|
430 |
-
$whitelisted_ips = ITSEC_Lib::get_whitelisted_ips();
|
431 |
-
$blacklisted_ips = ITSEC_Lib::get_blacklisted_ips();
|
432 |
-
|
433 |
// Get user's view preference
|
434 |
$view = get_user_meta( get_current_user_id(), 'itsec-settings-view', true );
|
435 |
|
@@ -475,99 +482,7 @@ final class ITSEC_Settings_Page {
|
|
475 |
</ul>
|
476 |
</div>
|
477 |
<div class="itsec-module-cards-container <?php echo $view; ?> hide-if-js">
|
478 |
-
<?php $
|
479 |
-
<?php $form->add_nonce( 'itsec-settings-page' ); ?>
|
480 |
-
<ul class="itsec-module-cards">
|
481 |
-
<?php foreach ( $this->modules as $id => $module ) : ?>
|
482 |
-
<?php
|
483 |
-
if ( ! in_array( $id, $visible_modules ) ) {
|
484 |
-
// continue;
|
485 |
-
}
|
486 |
-
|
487 |
-
$classes = array(
|
488 |
-
'itsec-module-type-' . $module->type,
|
489 |
-
'itsec-module-type-' . ( $module->enabled ? 'enabled' : 'disabled' ),
|
490 |
-
);
|
491 |
-
|
492 |
-
if ( $module->upsell ) {
|
493 |
-
$classes[] = 'itsec-module-pro-upsell';
|
494 |
-
}
|
495 |
-
|
496 |
-
if ( $module->pro ) {
|
497 |
-
$classes[] = 'itsec-module-type-pro';
|
498 |
-
}
|
499 |
-
?>
|
500 |
-
<li id="itsec-module-card-<?php echo $id; ?>" class="itsec-module-card <?php echo implode( ' ', $classes ); ?>" data-module-id="<?php echo $id; ?>">
|
501 |
-
<div class="itsec-module-card-content">
|
502 |
-
<?php if ( $module->upsell ) : ?>
|
503 |
-
<a href="<?php echo esc_url( $module->upsell_url ); ?>" target="_blank" rel="noopener noreferrer" class="itsec-pro-upsell"> </a>
|
504 |
-
<?php endif; ?>
|
505 |
-
<h2><?php echo esc_html( $module->title ); ?></h2>
|
506 |
-
<?php if ( $module->pro ) : ?>
|
507 |
-
<div class="itsec-pro-label"><?php _e( 'Pro', 'better-wp-security' ); ?></div>
|
508 |
-
<?php endif; ?>
|
509 |
-
<p class="module-description"><?php echo $module->description; ?></p>
|
510 |
-
<?php if ( ! $module->upsell ) : ?>
|
511 |
-
<div class="module-actions hide-if-no-js">
|
512 |
-
<?php if ( $module->information_only ) : ?>
|
513 |
-
<button class="button button-secondary itsec-toggle-settings information-only"><?php echo $this->translations['show_information']; ?></button>
|
514 |
-
<?php elseif ( $module->enabled || $module->always_active ) : ?>
|
515 |
-
<button class="button button-secondary itsec-toggle-settings"><?php echo $this->translations['show_settings']; ?></button>
|
516 |
-
<?php if ( ! $module->always_active ) : ?>
|
517 |
-
<button class="button button-secondary itsec-toggle-activation"><?php echo $this->translations['deactivate']; ?></button>
|
518 |
-
<?php endif; ?>
|
519 |
-
<?php else : ?>
|
520 |
-
<button class="button button-secondary itsec-toggle-settings"><?php echo $this->translations['show_description']; ?></button>
|
521 |
-
<button class="button button-primary itsec-toggle-activation"><?php echo $this->translations['activate']; ?></button>
|
522 |
-
<?php endif; ?>
|
523 |
-
</div>
|
524 |
-
<?php endif; ?>
|
525 |
-
</div>
|
526 |
-
<?php if ( ! $module->upsell ) : ?>
|
527 |
-
<div class="itsec-module-settings-container">
|
528 |
-
<div class="itsec-modal-navigation">
|
529 |
-
<button class="dashicons itsec-close-modal"></button>
|
530 |
-
<button class="itsec-right dashicons hidden"><span class="screen-reader-text"><?php _e( 'Configure next iThemes Security setting', 'better-wp-security' ); ?></span></button>
|
531 |
-
<button class="itsec-left dashicons hidden"><span class="screen-reader-text"><?php _e( 'Configure previous iThemes Security setting', 'better-wp-security' ); ?></span></button>
|
532 |
-
</div>
|
533 |
-
<div class="itsec-module-settings-content-container">
|
534 |
-
<div class="itsec-module-settings-content">
|
535 |
-
<h3 class="itsec-modal-header"><?php echo esc_html( $module->title ); ?></h3>
|
536 |
-
<div class="itsec-module-messages-container"></div>
|
537 |
-
<div class="itsec-module-settings-content-main">
|
538 |
-
<?php $this->get_module_settings( $id, $form, true ); ?>
|
539 |
-
</div>
|
540 |
-
</div>
|
541 |
-
</div>
|
542 |
-
<div class="itsec-list-content-footer hide-if-no-js">
|
543 |
-
<?php if ( $module->can_save ) : ?>
|
544 |
-
<button class="button button-primary align-left itsec-module-settings-save"><?php echo $this->translations['save_settings']; ?></button>
|
545 |
-
<?php endif; ?>
|
546 |
-
<button class="button button-secondary align-left itsec-module-settings-cancel"><?php _e( 'Cancel', 'better-wp-security' ); ?></button>
|
547 |
-
</div>
|
548 |
-
<div class="itsec-modal-content-footer">
|
549 |
-
<?php if ( $module->enabled || $module->always_active || $module->information_only ) : ?>
|
550 |
-
<?php if ( ! $module->always_active && ! $module->information_only ) : ?>
|
551 |
-
<button class="button button-secondary align-right itsec-toggle-activation"><?php echo $this->translations['deactivate']; ?></button>
|
552 |
-
<?php endif; ?>
|
553 |
-
<?php else : ?>
|
554 |
-
<button class="button button-primary align-right itsec-toggle-activation"><?php echo $this->translations['activate']; ?></button>
|
555 |
-
<?php endif; ?>
|
556 |
-
|
557 |
-
<?php if ( $module->can_save ) : ?>
|
558 |
-
<button class="button button-primary align-left itsec-module-settings-save"><?php echo $this->translations['save_settings']; ?></button>
|
559 |
-
<?php else : ?>
|
560 |
-
<button class="button button-primary align-left itsec-close-modal"><?php echo $this->translations['close_settings']; ?></button>
|
561 |
-
<?php endif; ?>
|
562 |
-
</div>
|
563 |
-
</div>
|
564 |
-
<?php endif; ?>
|
565 |
-
</li>
|
566 |
-
<?php endforeach; ?>
|
567 |
-
<li class="itsec-module-card-filler"></li>
|
568 |
-
</ul>
|
569 |
-
|
570 |
-
<?php $form->end_form(); ?>
|
571 |
</div>
|
572 |
</div>
|
573 |
<div class="itsec-modal-background"></div>
|
@@ -602,6 +517,120 @@ final class ITSEC_Settings_Page {
|
|
602 |
<?php
|
603 |
|
604 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
605 |
}
|
606 |
|
607 |
-
|
2 |
|
3 |
|
4 |
final class ITSEC_Settings_Page {
|
5 |
+
private $version = 1.6;
|
6 |
+
|
7 |
+
private static $instance;
|
8 |
|
9 |
private $self_url = '';
|
10 |
private $modules = array();
|
12 |
private $translations = array();
|
13 |
|
14 |
|
15 |
+
private function __construct() {
|
16 |
add_action( 'itsec-settings-page-register-module', array( $this, 'register_module' ) );
|
17 |
add_action( 'itsec-settings-page-register-widget', array( $this, 'register_widget' ) );
|
18 |
|
45 |
}
|
46 |
}
|
47 |
|
48 |
+
public static function get_instance() {
|
49 |
+
if ( ! self::$instance ) {
|
50 |
+
self::$instance = new self;
|
51 |
+
}
|
52 |
+
|
53 |
+
return self::$instance;
|
54 |
+
}
|
55 |
+
|
56 |
public function add_settings_classes( $classes ) {
|
57 |
if ( ITSEC_Modules::get_setting( 'global', 'show_error_codes' ) ) {
|
58 |
$classes .= ' itsec-show-error-codes';
|
114 |
'activate' => __( 'Enable', 'better-wp-security' ),
|
115 |
'deactivate' => __( 'Disable', 'better-wp-security' ),
|
116 |
'error' => __( 'Error', 'better-wp-security' ),
|
117 |
+
'copied' => __( 'Copied!', 'better-wp-security' ),
|
118 |
+
'copy_instruction' => __( 'Please press Ctrl/Cmd+C to copy.', 'better-wp-security' ),
|
119 |
|
120 |
/* translators: 1: module name */
|
121 |
'successful_save' => __( 'Settings saved successfully for %1$s.', 'better-wp-security' ),
|
179 |
ITSEC_Response::set_response( $this->get_module_settings( $module ) );
|
180 |
} else if ( 'get_refreshed_widget_settings' === $method ) {
|
181 |
ITSEC_Response::set_response( $this->get_widget_settings( $module ) );
|
182 |
+
} else if ( 'get_refreshed_module_form' === $method ) {
|
183 |
+
$form = new ITSEC_Form();
|
184 |
+
$this->prepare_modules_and_calculate_filters();
|
185 |
+
ob_start();
|
186 |
+
$this->print_modules_form( $form );
|
187 |
+
ITSEC_Response::set_response( ob_get_clean() );
|
188 |
} else if ( 'handle_module_request' === $method ) {
|
189 |
if ( isset( $this->modules[$module] ) ) {
|
190 |
if ( isset( $_POST['data'] ) ) {
|
388 |
}
|
389 |
}
|
390 |
|
391 |
+
private function prepare_modules_and_calculate_filters() {
|
|
|
|
|
|
|
392 |
$module_filters = array(
|
393 |
'all' => array(
|
394 |
_x( 'All', 'List all modules', 'better-wp-security' ),
|
404 |
),
|
405 |
);
|
406 |
|
|
|
|
|
|
|
|
|
407 |
foreach ( $this->modules as $id => $module ) {
|
408 |
$module_filters['all'][1]++;
|
409 |
|
|
|
|
|
|
|
|
|
|
|
410 |
if ( isset( $module_filters[$module->type] ) ) {
|
411 |
$module_filters[$module->type][1]++;
|
|
|
|
|
|
|
|
|
412 |
}
|
413 |
|
|
|
414 |
$module->enabled = ITSEC_Modules::is_active( $id );
|
415 |
$module->always_active = ITSEC_Modules::is_always_active( $id );
|
416 |
}
|
417 |
|
418 |
+
return $module_filters;
|
419 |
+
}
|
420 |
+
|
421 |
+
private function show_settings_page() {
|
422 |
+
$form = new ITSEC_Form();
|
423 |
+
|
424 |
+
$module_filters = $this->prepare_modules_and_calculate_filters();
|
425 |
+
|
426 |
+
$current_type = isset( $_REQUEST['module_type'] ) ? $_REQUEST['module_type'] : 'recommended';
|
427 |
+
|
428 |
$feature_tabs = array();
|
429 |
|
430 |
foreach ( $module_filters as $type => $data ) {
|
437 |
$feature_tabs[] = "<li class='itsec-module-filter' id='itsec-module-filter-$type'><a href='" . esc_url( add_query_arg( 'module_type', $type, $this->self_url ) ) . "' class='$class'>{$data[0]} <span class='count'>({$data[1]})</span></a>";
|
438 |
}
|
439 |
|
|
|
|
|
|
|
|
|
440 |
// Get user's view preference
|
441 |
$view = get_user_meta( get_current_user_id(), 'itsec-settings-view', true );
|
442 |
|
482 |
</ul>
|
483 |
</div>
|
484 |
<div class="itsec-module-cards-container <?php echo $view; ?> hide-if-js">
|
485 |
+
<?php $this->print_modules_form( $form ); ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
486 |
</div>
|
487 |
</div>
|
488 |
<div class="itsec-modal-background"></div>
|
517 |
<?php
|
518 |
|
519 |
}
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Print the modules form element.
|
523 |
+
*
|
524 |
+
* @param ITSEC_Form $form
|
525 |
+
*/
|
526 |
+
private function print_modules_form( $form ) {
|
527 |
+
?>
|
528 |
+
<?php $form->start_form( 'itsec-module-settings-form' ); ?>
|
529 |
+
<?php $form->add_nonce( 'itsec-settings-page' ); ?>
|
530 |
+
<ul class="itsec-module-cards">
|
531 |
+
<?php foreach ( $this->modules as $id => $module ) : ?>
|
532 |
+
<?php
|
533 |
+
|
534 |
+
$classes = array(
|
535 |
+
'itsec-module-type-' . $module->type,
|
536 |
+
'itsec-module-type-' . ( $module->enabled ? 'enabled' : 'disabled' ),
|
537 |
+
);
|
538 |
+
|
539 |
+
if ( $module->upsell ) {
|
540 |
+
$classes[] = 'itsec-module-pro-upsell';
|
541 |
+
}
|
542 |
+
|
543 |
+
if ( $module->pro ) {
|
544 |
+
$classes[] = 'itsec-module-type-pro';
|
545 |
+
}
|
546 |
+
?>
|
547 |
+
<li id="itsec-module-card-<?php echo $id; ?>" class="itsec-module-card <?php echo implode( ' ', $classes ); ?>" data-module-id="<?php echo $id; ?>">
|
548 |
+
<div class="itsec-module-card-content">
|
549 |
+
<?php if ( $module->upsell ) : ?>
|
550 |
+
<a href="<?php echo esc_url( $module->upsell_url ); ?>" target="_blank" rel="noopener noreferrer" class="itsec-pro-upsell"> </a>
|
551 |
+
<?php endif; ?>
|
552 |
+
<h2><?php echo esc_html( $module->title ); ?></h2>
|
553 |
+
<?php if ( $module->pro ) : ?>
|
554 |
+
<div class="itsec-pro-label"><?php _e( 'Pro', 'better-wp-security' ); ?></div>
|
555 |
+
<?php endif; ?>
|
556 |
+
<p class="module-description"><?php echo $module->description; ?></p>
|
557 |
+
<?php if ( ! $module->upsell ) : ?>
|
558 |
+
<div class="module-actions hide-if-no-js">
|
559 |
+
<?php if ( $module->information_only ) : ?>
|
560 |
+
<button class="button button-secondary itsec-toggle-settings information-only"><?php echo $this->translations['show_information']; ?></button>
|
561 |
+
<?php elseif ( $module->enabled || $module->always_active ) : ?>
|
562 |
+
<button class="button button-secondary itsec-toggle-settings"><?php echo $this->translations['show_settings']; ?></button>
|
563 |
+
<?php if ( ! $module->always_active ) : ?>
|
564 |
+
<button class="button button-secondary itsec-toggle-activation"><?php echo $this->translations['deactivate']; ?></button>
|
565 |
+
<?php endif; ?>
|
566 |
+
<?php else : ?>
|
567 |
+
<button class="button button-secondary itsec-toggle-settings"><?php echo $this->translations['show_description']; ?></button>
|
568 |
+
<button class="button button-primary itsec-toggle-activation"><?php echo $this->translations['activate']; ?></button>
|
569 |
+
<?php endif; ?>
|
570 |
+
</div>
|
571 |
+
<?php endif; ?>
|
572 |
+
</div>
|
573 |
+
<?php if ( ! $module->upsell ) : ?>
|
574 |
+
<div class="itsec-module-settings-container">
|
575 |
+
<div class="itsec-modal-navigation">
|
576 |
+
<button class="dashicons itsec-close-modal"></button>
|
577 |
+
<button class="itsec-right dashicons hidden"><span class="screen-reader-text"><?php _e( 'Configure next iThemes Security setting', 'better-wp-security' ); ?></span></button>
|
578 |
+
<button class="itsec-left dashicons hidden"><span class="screen-reader-text"><?php _e( 'Configure previous iThemes Security setting', 'better-wp-security' ); ?></span></button>
|
579 |
+
</div>
|
580 |
+
<div class="itsec-module-settings-content-container">
|
581 |
+
<div class="itsec-module-settings-content">
|
582 |
+
<h3 class="itsec-modal-header"><?php echo esc_html( $module->title ); ?></h3>
|
583 |
+
<div class="itsec-module-messages-container"></div>
|
584 |
+
<div class="itsec-module-settings-content-main">
|
585 |
+
<?php $this->get_module_settings( $id, $form, true ); ?>
|
586 |
+
</div>
|
587 |
+
</div>
|
588 |
+
</div>
|
589 |
+
<div class="itsec-list-content-footer hide-if-no-js">
|
590 |
+
<?php if ( $module->can_save ) : ?>
|
591 |
+
<button class="button button-primary align-left itsec-module-settings-save"><?php echo $this->translations['save_settings']; ?></button>
|
592 |
+
<?php endif; ?>
|
593 |
+
<button class="button button-secondary align-left itsec-module-settings-cancel"><?php _e( 'Cancel', 'better-wp-security' ); ?></button>
|
594 |
+
</div>
|
595 |
+
<div class="itsec-modal-content-footer">
|
596 |
+
<?php if ( $module->enabled || $module->always_active || $module->information_only ) : ?>
|
597 |
+
<?php if ( ! $module->always_active && ! $module->information_only ) : ?>
|
598 |
+
<button class="button button-secondary align-right itsec-toggle-activation"><?php echo $this->translations['deactivate']; ?></button>
|
599 |
+
<?php endif; ?>
|
600 |
+
<?php else : ?>
|
601 |
+
<button class="button button-primary align-right itsec-toggle-activation"><?php echo $this->translations['activate']; ?></button>
|
602 |
+
<?php endif; ?>
|
603 |
+
|
604 |
+
<?php if ( $module->can_save ) : ?>
|
605 |
+
<button class="button button-primary align-left itsec-module-settings-save"><?php echo $this->translations['save_settings']; ?></button>
|
606 |
+
<?php else : ?>
|
607 |
+
<button class="button button-primary align-left itsec-close-modal"><?php echo $this->translations['close_settings']; ?></button>
|
608 |
+
<?php endif; ?>
|
609 |
+
</div>
|
610 |
+
</div>
|
611 |
+
<?php endif; ?>
|
612 |
+
</li>
|
613 |
+
<?php endforeach; ?>
|
614 |
+
<li class="itsec-module-card-filler"></li>
|
615 |
+
</ul>
|
616 |
+
|
617 |
+
<?php $form->end_form(); ?>
|
618 |
+
|
619 |
+
<?php
|
620 |
+
|
621 |
+
}
|
622 |
+
|
623 |
+
public static function show_details_toggle( $description, $details ) {
|
624 |
+
$self = self::get_instance();
|
625 |
+
|
626 |
+
echo "<div class='itsec-warning-message itsec-details-toggle-container'>\n";
|
627 |
+
echo "$description<br />\n";
|
628 |
+
echo '<a href="#" class="hide-if-no-js">' . esc_html( $self->translations['show_information'] ) . '</a>';
|
629 |
+
echo "<div class='itsec-details-toggle-details hide-if-js'>\n";
|
630 |
+
echo $details;
|
631 |
+
echo "</div>\n";
|
632 |
+
echo "</div>\n";
|
633 |
+
}
|
634 |
}
|
635 |
|
636 |
+
ITSEC_Settings_Page::get_instance();
|
core/files.php
CHANGED
@@ -158,84 +158,4 @@ final class ITSEC_Files {
|
|
158 |
|
159 |
return true;
|
160 |
}
|
161 |
-
|
162 |
-
/**
|
163 |
-
* Attempt to get a lock for atomic operations.
|
164 |
-
*
|
165 |
-
* Tries to get a more robust lock on the file in question. Useful in situations where automatic
|
166 |
-
* file locking doesn't work.
|
167 |
-
*
|
168 |
-
* @since 4.0.0
|
169 |
-
*
|
170 |
-
* @param string $lock_file file name of lock
|
171 |
-
* @param int $exp seconds until lock expires
|
172 |
-
*
|
173 |
-
* @return bool true if lock was achieved, else false
|
174 |
-
*/
|
175 |
-
public function get_file_lock( $lock_file, $exp = 180 ) {
|
176 |
-
|
177 |
-
if ( ITSEC_Modules::get_setting( 'global', 'lock_file' ) ) {
|
178 |
-
return true;
|
179 |
-
}
|
180 |
-
|
181 |
-
clearstatcache();
|
182 |
-
|
183 |
-
$lock_file = ITSEC_Core::get_storage_dir() . '/' . sanitize_text_field( $lock_file ) . '.lock';
|
184 |
-
$dir_age = @filectime( $lock_file );
|
185 |
-
|
186 |
-
if ( false === @mkdir( $lock_file ) ) {
|
187 |
-
|
188 |
-
if ( false !== $dir_age ) {
|
189 |
-
|
190 |
-
if ( ( time() - $dir_age ) > intval( $exp ) ) { //see if the lock has expired
|
191 |
-
|
192 |
-
@rmdir( $lock_file );
|
193 |
-
@mkdir( $lock_file );
|
194 |
-
|
195 |
-
} else { //couldn't get the lock
|
196 |
-
|
197 |
-
return false;
|
198 |
-
|
199 |
-
}
|
200 |
-
|
201 |
-
} else {
|
202 |
-
|
203 |
-
return false;
|
204 |
-
|
205 |
-
}
|
206 |
-
|
207 |
-
}
|
208 |
-
|
209 |
-
return true; //file lock was achieved
|
210 |
-
|
211 |
-
}
|
212 |
-
|
213 |
-
/**
|
214 |
-
* Release the lock.
|
215 |
-
*
|
216 |
-
* Releases a file lock to allow others to use it.
|
217 |
-
*
|
218 |
-
* @since 4.0.0
|
219 |
-
*
|
220 |
-
* @param string $lock_file file name of lock
|
221 |
-
*
|
222 |
-
* @return bool true if released, false otherwise
|
223 |
-
*/
|
224 |
-
public function release_file_lock( $lock_file ) {
|
225 |
-
if ( ITSEC_Modules::get_setting( 'global', 'lock_file' ) ) {
|
226 |
-
return true;
|
227 |
-
}
|
228 |
-
|
229 |
-
require_once( ITSEC_Core::get_core_dir() . '/lib/class-itsec-lib-directory.php' );
|
230 |
-
|
231 |
-
$lock_file = ITSEC_Core::get_storage_dir() . '/' . sanitize_text_field( $lock_file ) . '.lock';
|
232 |
-
|
233 |
-
$result = ITSEC_Lib_Directory::remove( $lock_file );
|
234 |
-
|
235 |
-
if ( is_wp_error( $result ) ) {
|
236 |
-
return false;
|
237 |
-
}
|
238 |
-
|
239 |
-
return true;
|
240 |
-
}
|
241 |
}
|
158 |
|
159 |
return true;
|
160 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
}
|
core/history.txt
CHANGED
@@ -548,3 +548,10 @@
|
|
548 |
New Feature: Added support for the ITSEC_DISABLE_MODULES define.
|
549 |
3.4.1 - 2017-07-05 - Chris Jean & Timothy Jacobs
|
550 |
Bug Fix: Fixed password-protected posts not properly handling the password when Hide Backend is enabled.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
548 |
New Feature: Added support for the ITSEC_DISABLE_MODULES define.
|
549 |
3.4.1 - 2017-07-05 - Chris Jean & Timothy Jacobs
|
550 |
Bug Fix: Fixed password-protected posts not properly handling the password when Hide Backend is enabled.
|
551 |
+
3.5.0 - 2017-07-24 - Chris Jean & Timothy Jacobs
|
552 |
+
Enhancement: Replaced file locking with database locking. This method of locking is compatible with all systems as it does not require the ability to write files. It also allows for locking to work on sites that have multiple front-end servers with a shared database. Since file locking is no longer used, the Global Settings > Disable File Locking setting was removed.
|
553 |
+
Enhancement: Add "Copy to Clipboard" functionality for server and wp-config rules.
|
554 |
+
Bug Fix: Prevent 404s when following links in email notifications on a site with Hide Backend enabled.
|
555 |
+
Bug Fix: Ensure uninstall process is not run when another version of iThemes Security is still active.
|
556 |
+
Bug Fix: Fixed method of working around Hide Backend.
|
557 |
+
Bug Fix: Warnings are no longer generated when saving a user profile with a role of "No role for this site" selected.
|
core/lib.php
CHANGED
@@ -1002,6 +1002,7 @@ final class ITSEC_Lib {
|
|
1002 |
*/
|
1003 |
public static function get_url_path( $url, $prefix = '' ) {
|
1004 |
$path = (string) parse_url( $url, PHP_URL_PATH );
|
|
|
1005 |
$path = untrailingslashit( $path );
|
1006 |
|
1007 |
if ( ! empty( $prefix ) && 0 === strpos( $path, $prefix ) ) {
|
@@ -1025,4 +1026,62 @@ final class ITSEC_Lib {
|
|
1025 |
|
1026 |
return $GLOBALS['__itsec_lib_get_request_path'];
|
1027 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1028 |
}
|
1002 |
*/
|
1003 |
public static function get_url_path( $url, $prefix = '' ) {
|
1004 |
$path = (string) parse_url( $url, PHP_URL_PATH );
|
1005 |
+
$path = preg_replace( '|//+|', '/', $path );
|
1006 |
$path = untrailingslashit( $path );
|
1007 |
|
1008 |
if ( ! empty( $prefix ) && 0 === strpos( $path, $prefix ) ) {
|
1026 |
|
1027 |
return $GLOBALS['__itsec_lib_get_request_path'];
|
1028 |
}
|
1029 |
+
|
1030 |
+
/**
|
1031 |
+
* Acquire a lock.
|
1032 |
+
*
|
1033 |
+
* @since 6.3.0
|
1034 |
+
*
|
1035 |
+
* @param string $name Lock name.
|
1036 |
+
* @param int $expires_in Number of seconds to hold the lock for.
|
1037 |
+
*
|
1038 |
+
* @return bool
|
1039 |
+
*/
|
1040 |
+
public static function get_lock( $name, $expires_in = 30 ) {
|
1041 |
+
|
1042 |
+
/** @var \wpdb $wpdb */
|
1043 |
+
global $wpdb;
|
1044 |
+
|
1045 |
+
$lock = "itsec-lock-{$name}";
|
1046 |
+
$now = ITSEC_Core::get_current_time_gmt();
|
1047 |
+
$release_at = $now + $expires_in;
|
1048 |
+
|
1049 |
+
if ( empty( $wpdb->sitemeta ) ) {
|
1050 |
+
$result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, 'no') /* LOCK */", $lock, $release_at ) );
|
1051 |
+
} else {
|
1052 |
+
$result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->sitemeta` (`site_id`, `meta_key`, `meta_value`) VALUES (%d, %s, %s) /* LOCK */", $wpdb->siteid, $lock, $release_at ) );
|
1053 |
+
}
|
1054 |
+
|
1055 |
+
// The lock exists. See if it has expired.
|
1056 |
+
if ( ! $result ) {
|
1057 |
+
|
1058 |
+
$locked_until = get_site_option( $lock );
|
1059 |
+
|
1060 |
+
if ( ! $locked_until ) {
|
1061 |
+
// Can't write or read the lock. Bail due to an unknown and hopefully temporary error.
|
1062 |
+
return false;
|
1063 |
+
}
|
1064 |
+
|
1065 |
+
if ( $locked_until > $now ) {
|
1066 |
+
// The lock still exists and has not expired.
|
1067 |
+
return false;
|
1068 |
+
}
|
1069 |
+
}
|
1070 |
+
|
1071 |
+
// Ensure that the lock is set properly by triggering all the regular actions and filters.
|
1072 |
+
update_site_option( $lock, $release_at );
|
1073 |
+
|
1074 |
+
return true;
|
1075 |
+
}
|
1076 |
+
|
1077 |
+
/**
|
1078 |
+
* Release a lock.
|
1079 |
+
*
|
1080 |
+
* @since 6.3.0
|
1081 |
+
*
|
1082 |
+
* @param string $name The lock name.
|
1083 |
+
*/
|
1084 |
+
public static function release_lock( $name ) {
|
1085 |
+
delete_site_option( "itsec-lock-{$name}" );
|
1086 |
+
}
|
1087 |
}
|
core/lib/class-itsec-mail.php
CHANGED
@@ -69,7 +69,7 @@ final class ITSEC_Mail {
|
|
69 |
'support' => esc_html__( 'Support', 'better-wp-security' ),
|
70 |
'pro' => esc_html__( 'Pro', 'better-wp-security' ),
|
71 |
'support_content' => sprintf( wp_kses( __( 'Pro customers can contact <a href="%s">iThemes Helpdesk</a> for help. Our support team answers questions Monday – Friday, 8am – 5pm (CST).', 'better-wp-security' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( 'https://members.ithemes.com/panel/helpdesk.php' ) ),
|
72 |
-
'security_settings_link' => esc_url( ITSEC_Core::get_settings_page_url() ),
|
73 |
'unsubscribe_link_text' => esc_html__( 'This email was generated by the iThemes Security plugin.', 'better-wp-security' ) . '<br>' . esc_html__( 'To unsubscribe from these updates, visit the Settings page in the iThemes Security plugin menu.', 'better-wp-security' ),
|
74 |
'security_guide' => esc_html__( 'Free WordPress Security Guide', 'better-wp-security' ),
|
75 |
'security_guide_content' => sprintf( wp_kses( __( 'Learn simple WordPress security tips — including 3 kinds of security your site needs and 4 best security practices for keeping your WordPress site safe with our <a href="%s">free guide</a>.', 'better-wp-security' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( 'https://ithemes.com/publishing/wordpress-security/' ) ),
|
@@ -235,4 +235,16 @@ final class ITSEC_Mail {
|
|
235 |
private function get_template( $template ) {
|
236 |
return file_get_contents( $this->template_path . $template );
|
237 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
238 |
}
|
69 |
'support' => esc_html__( 'Support', 'better-wp-security' ),
|
70 |
'pro' => esc_html__( 'Pro', 'better-wp-security' ),
|
71 |
'support_content' => sprintf( wp_kses( __( 'Pro customers can contact <a href="%s">iThemes Helpdesk</a> for help. Our support team answers questions Monday – Friday, 8am – 5pm (CST).', 'better-wp-security' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( 'https://members.ithemes.com/panel/helpdesk.php' ) ),
|
72 |
+
'security_settings_link' => esc_url( self::filter_admin_page_url( ITSEC_Core::get_settings_page_url() ) ),
|
73 |
'unsubscribe_link_text' => esc_html__( 'This email was generated by the iThemes Security plugin.', 'better-wp-security' ) . '<br>' . esc_html__( 'To unsubscribe from these updates, visit the Settings page in the iThemes Security plugin menu.', 'better-wp-security' ),
|
74 |
'security_guide' => esc_html__( 'Free WordPress Security Guide', 'better-wp-security' ),
|
75 |
'security_guide_content' => sprintf( wp_kses( __( 'Learn simple WordPress security tips — including 3 kinds of security your site needs and 4 best security practices for keeping your WordPress site safe with our <a href="%s">free guide</a>.', 'better-wp-security' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( 'https://ithemes.com/publishing/wordpress-security/' ) ),
|
235 |
private function get_template( $template ) {
|
236 |
return file_get_contents( $this->template_path . $template );
|
237 |
}
|
238 |
+
|
239 |
+
public static function filter_admin_page_url( $url ) {
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Filter admin page URLs so modules can add any necessary security tokens.
|
243 |
+
*
|
244 |
+
* @since 6.4.0
|
245 |
+
*
|
246 |
+
* @param string $url
|
247 |
+
*/
|
248 |
+
return apply_filters( 'itsec_notify_admin_page_url', $url );
|
249 |
+
}
|
250 |
}
|
core/lockout.php
CHANGED
@@ -634,14 +634,13 @@ final class ITSEC_Lockout {
|
|
634 |
|
635 |
global $wpdb, $itsec_logger, $itsec_globals;
|
636 |
|
637 |
-
$itsec_files = ITSEC_Core::get_itsec_files();
|
638 |
-
|
639 |
$host_expiration = null;
|
640 |
$user_expiration = null;
|
641 |
$username = sanitize_text_field( trim( $username ) );
|
|
|
642 |
|
643 |
// Acquire a lock to prevent a lockout being created more than once by a particularly fast attacker.
|
644 |
-
if (
|
645 |
|
646 |
//Do we have a good host to lock out or not
|
647 |
if ( ! is_null( $host ) && ITSEC_Lib::is_ip_whitelisted( sanitize_text_field( $host ) ) === false && ITSEC_Lib_IP_Tools::validate( $host ) ) {
|
@@ -802,12 +801,12 @@ final class ITSEC_Lockout {
|
|
802 |
|
803 |
if ( $good_host !== false ) {
|
804 |
|
805 |
-
|
806 |
$this->execute_lock();
|
807 |
|
808 |
} else {
|
809 |
|
810 |
-
|
811 |
$this->execute_lock( true );
|
812 |
|
813 |
}
|
@@ -816,7 +815,7 @@ final class ITSEC_Lockout {
|
|
816 |
|
817 |
}
|
818 |
|
819 |
-
|
820 |
|
821 |
}
|
822 |
|
634 |
|
635 |
global $wpdb, $itsec_logger, $itsec_globals;
|
636 |
|
|
|
|
|
637 |
$host_expiration = null;
|
638 |
$user_expiration = null;
|
639 |
$username = sanitize_text_field( trim( $username ) );
|
640 |
+
$lock = 'lockout_' . $host . $user . $username;
|
641 |
|
642 |
// Acquire a lock to prevent a lockout being created more than once by a particularly fast attacker.
|
643 |
+
if ( ITSEC_Lib::get_lock( $lock, 180 ) ) {
|
644 |
|
645 |
//Do we have a good host to lock out or not
|
646 |
if ( ! is_null( $host ) && ITSEC_Lib::is_ip_whitelisted( sanitize_text_field( $host ) ) === false && ITSEC_Lib_IP_Tools::validate( $host ) ) {
|
801 |
|
802 |
if ( $good_host !== false ) {
|
803 |
|
804 |
+
ITSEC_Lib::release_lock( $lock );
|
805 |
$this->execute_lock();
|
806 |
|
807 |
} else {
|
808 |
|
809 |
+
ITSEC_Lib::release_lock( $lock );
|
810 |
$this->execute_lock( true );
|
811 |
|
812 |
}
|
815 |
|
816 |
}
|
817 |
|
818 |
+
ITSEC_Lib::release_lock( $lock );
|
819 |
|
820 |
}
|
821 |
|
core/modules/admin-user/validator.php
CHANGED
@@ -66,9 +66,7 @@ final class ITSEC_Admin_User_Validator extends ITSEC_Validator {
|
|
66 |
|
67 |
global $wpdb;
|
68 |
|
69 |
-
|
70 |
-
|
71 |
-
if ( $itsec_files->get_file_lock( 'admin_user' ) ) { //make sure it isn't already running
|
72 |
|
73 |
//sanitize the username
|
74 |
$new_user = sanitize_text_field( $username );
|
@@ -95,14 +93,14 @@ final class ITSEC_Admin_User_Validator extends ITSEC_Validator {
|
|
95 |
|
96 |
}
|
97 |
|
98 |
-
|
99 |
|
100 |
return true;
|
101 |
|
102 |
}
|
103 |
|
104 |
} elseif ( $username !== null ) { //username didn't validate
|
105 |
-
|
106 |
|
107 |
return false;
|
108 |
|
@@ -148,7 +146,7 @@ final class ITSEC_Admin_User_Validator extends ITSEC_Validator {
|
|
148 |
*/
|
149 |
do_action( 'itsec_change_admin_user_id', $new_user );
|
150 |
|
151 |
-
|
152 |
|
153 |
return true;
|
154 |
|
66 |
|
67 |
global $wpdb;
|
68 |
|
69 |
+
if ( ITSEC_Lib::get_lock( 'admin_user', 180 ) ) { //make sure it isn't already running
|
|
|
|
|
70 |
|
71 |
//sanitize the username
|
72 |
$new_user = sanitize_text_field( $username );
|
93 |
|
94 |
}
|
95 |
|
96 |
+
ITSEC_Lib::release_lock( 'admin_user' );
|
97 |
|
98 |
return true;
|
99 |
|
100 |
}
|
101 |
|
102 |
} elseif ( $username !== null ) { //username didn't validate
|
103 |
+
ITSEC_Lib::release_lock( 'admin_user' );
|
104 |
|
105 |
return false;
|
106 |
|
146 |
*/
|
147 |
do_action( 'itsec_change_admin_user_id', $new_user );
|
148 |
|
149 |
+
ITSEC_Lib::release_lock( 'admin_user' );
|
150 |
|
151 |
return true;
|
152 |
|
core/modules/away-mode/js/settings-page.js
CHANGED
@@ -19,5 +19,7 @@
|
|
19 |
$(document).ready(function() {
|
20 |
ithemesSecurityAwayModeSettingsPage.init();
|
21 |
ithemesSecurityAwayModeSettingsPage.typeChanged();
|
|
|
|
|
22 |
});
|
23 |
})( jQuery );
|
19 |
$(document).ready(function() {
|
20 |
ithemesSecurityAwayModeSettingsPage.init();
|
21 |
ithemesSecurityAwayModeSettingsPage.typeChanged();
|
22 |
+
|
23 |
+
itsecSettingsPage.events.on( 'modulesReloaded', ithemesSecurityAwayModeSettingsPage.init );
|
24 |
});
|
25 |
})( jQuery );
|
core/modules/backup/class-itsec-backup.php
CHANGED
@@ -81,16 +81,15 @@ class ITSEC_Backup {
|
|
81 |
* @return mixed false on error or nothing
|
82 |
*/
|
83 |
public function do_backup( $one_time = false ) {
|
84 |
-
$itsec_files = ITSEC_Core::get_itsec_files();
|
85 |
|
86 |
-
if (
|
87 |
return new WP_Error( 'itsec-backup-do-backup-already-running', __( 'Unable to create a backup at this time since a backup is currently being created. If you wish to create an additional backup, please wait a few minutes before trying again.', 'better-wp-security' ) );
|
88 |
}
|
89 |
|
90 |
|
91 |
ITSEC_Lib::set_minimum_memory_limit( '256M' );
|
92 |
$this->execute_backup( $one_time );
|
93 |
-
|
94 |
|
95 |
switch ( $this->settings['method'] ) {
|
96 |
|
81 |
* @return mixed false on error or nothing
|
82 |
*/
|
83 |
public function do_backup( $one_time = false ) {
|
|
|
84 |
|
85 |
+
if ( ITSEC_Lib::get_lock( 'backup', 180 ) ) {
|
86 |
return new WP_Error( 'itsec-backup-do-backup-already-running', __( 'Unable to create a backup at this time since a backup is currently being created. If you wish to create an additional backup, please wait a few minutes before trying again.', 'better-wp-security' ) );
|
87 |
}
|
88 |
|
89 |
|
90 |
ITSEC_Lib::set_minimum_memory_limit( '256M' );
|
91 |
$this->execute_backup( $one_time );
|
92 |
+
ITSEC_Lib::release_lock( 'backup' );
|
93 |
|
94 |
switch ( $this->settings['method'] ) {
|
95 |
|
core/modules/file-change/js/settings-page.js
CHANGED
@@ -1,30 +1,38 @@
|
|
1 |
jQuery( document ).ready( function ( $ ) {
|
2 |
-
/**
|
3 |
-
* Show the file tree in the settings.
|
4 |
-
*/
|
5 |
-
$( '.jquery_file_tree' ).fileTree(
|
6 |
-
{
|
7 |
-
root : itsec_file_change_settings.ABSPATH,
|
8 |
-
script : ajaxurl,
|
9 |
-
expandSpeed : -1,
|
10 |
-
collapseSpeed: -1,
|
11 |
-
multiFolder : false
|
12 |
|
13 |
-
|
14 |
|
15 |
-
|
16 |
|
17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
-
|
20 |
|
21 |
-
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
/**
|
25 |
* Performs a one-time file scan
|
26 |
*/
|
27 |
-
$( '#itsec-file-change-one_time_check'
|
28 |
e.preventDefault();
|
29 |
|
30 |
//let user know we're working
|
1 |
jQuery( document ).ready( function ( $ ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
+
itsecSettingsPage.events.on( 'modulesReloaded', initializeFileTrees );
|
4 |
|
5 |
+
function initializeFileTrees() {
|
6 |
|
7 |
+
/**
|
8 |
+
* Show the file tree in the settings.
|
9 |
+
*/
|
10 |
+
$( '.jquery_file_tree' ).fileTree(
|
11 |
+
{
|
12 |
+
root : itsec_file_change_settings.ABSPATH,
|
13 |
+
script : ajaxurl,
|
14 |
+
expandSpeed : -1,
|
15 |
+
collapseSpeed: -1,
|
16 |
+
multiFolder : false
|
17 |
|
18 |
+
}, function ( file ) {
|
19 |
|
20 |
+
$( '#itsec-file-change-file_list' ).val( file.substring( itsec_file_change_settings.ABSPATH.length ) + "\n" + $( '#itsec-file-change-file_list' ).val() );
|
21 |
+
|
22 |
+
}, function ( directory ) {
|
23 |
+
|
24 |
+
$( '#itsec-file-change-file_list' ).val( directory.substring( itsec_file_change_settings.ABSPATH.length ) + "\n" + $( '#itsec-file-change-file_list' ).val() );
|
25 |
+
|
26 |
+
}
|
27 |
+
);
|
28 |
+
}
|
29 |
+
|
30 |
+
initializeFileTrees();
|
31 |
|
32 |
/**
|
33 |
* Performs a one-time file scan
|
34 |
*/
|
35 |
+
$( document ).on( 'click', '#itsec-file-change-one_time_check', function( e ) {
|
36 |
e.preventDefault();
|
37 |
|
38 |
//let user know we're working
|
core/modules/file-change/scanner.php
CHANGED
@@ -78,9 +78,7 @@ final class ITSEC_File_Change_Scanner {
|
|
78 |
|
79 |
ITSEC_Lib::set_minimum_memory_limit( '256M' );
|
80 |
|
81 |
-
|
82 |
-
|
83 |
-
if ( $itsec_files->get_file_lock( 'file_change', 300 ) ) { //make sure it isn't already running
|
84 |
|
85 |
define( 'ITSEC_DOING_FILE_CHECK', true );
|
86 |
|
@@ -278,7 +276,7 @@ final class ITSEC_File_Change_Scanner {
|
|
278 |
ITSEC_Modules::set_setting( 'file-change', 'show_warning', true );
|
279 |
}
|
280 |
|
281 |
-
|
282 |
|
283 |
if ( $files_added_count > 0 || $files_changed_count > 0 || $files_deleted_count > 0 ) {
|
284 |
|
78 |
|
79 |
ITSEC_Lib::set_minimum_memory_limit( '256M' );
|
80 |
|
81 |
+
if ( ITSEC_Lib::get_lock( 'file_change', 300 ) ) { //make sure it isn't already running
|
|
|
|
|
82 |
|
83 |
define( 'ITSEC_DOING_FILE_CHECK', true );
|
84 |
|
276 |
ITSEC_Modules::set_setting( 'file-change', 'show_warning', true );
|
277 |
}
|
278 |
|
279 |
+
ITSEC_Lib::release_lock( 'file_change' );
|
280 |
|
281 |
if ( $files_added_count > 0 || $files_changed_count > 0 || $files_deleted_count > 0 ) {
|
282 |
|
core/modules/file-change/settings-page.php
CHANGED
@@ -155,7 +155,7 @@ final class ITSEC_File_Change_Settings_Page extends ITSEC_Module_Settings_Page {
|
|
155 |
*
|
156 |
* @since 4.0.0
|
157 |
*
|
158 |
-
* @return
|
159 |
*/
|
160 |
public function get_filetree_data( $data ) {
|
161 |
|
155 |
*
|
156 |
* @since 4.0.0
|
157 |
*
|
158 |
+
* @return string
|
159 |
*/
|
160 |
public function get_filetree_data( $data ) {
|
161 |
|
core/modules/file-writing/settings-page.php
CHANGED
@@ -21,7 +21,8 @@ final class ITSEC_Core_Server_Config_Rules_Settings_Page extends ITSEC_Module_Se
|
|
21 |
_e( 'There are no rules that need to be written.', 'better-wp-security' );
|
22 |
} else {
|
23 |
echo '<p>' . __( "The following rules need to be written to your server's config file. Please make sure to keep the comments in place." ) . '</p>';
|
24 |
-
echo '<div class="itsec_server_config_rules"><pre>' . esc_html( $config ) . '</pre></div>';
|
|
|
25 |
}
|
26 |
}
|
27 |
}
|
@@ -49,7 +50,8 @@ final class ITSEC_Core_WPConfig_File_Settings_Page extends ITSEC_Module_Settings
|
|
49 |
_e( 'There is nothing that needs to be written to your <code>wp-config.php</code> file.', 'better-wp-security' );
|
50 |
} else {
|
51 |
echo '<p>' . __( "The following rules need to be written to your <code>wp-config.php</code> file. Please make sure to keep the comments in place." ) . '</p>';
|
52 |
-
echo '<div class="itsec_rewrite_rules"><pre>' . esc_html( $config ) . '</pre></div>';
|
|
|
53 |
}
|
54 |
}
|
55 |
}
|
21 |
_e( 'There are no rules that need to be written.', 'better-wp-security' );
|
22 |
} else {
|
23 |
echo '<p>' . __( "The following rules need to be written to your server's config file. Please make sure to keep the comments in place." ) . '</p>';
|
24 |
+
echo '<div class="itsec_server_config_rules"><pre id="itsec-server-config-rules">' . esc_html( $config ) . '</pre></div>';
|
25 |
+
echo '<button class="button itsec-copy-trigger" data-copy-from="itsec-server-config-rules">' . esc_html__( 'Copy to Clipboard', 'better-wp-security' ) . '</button>';
|
26 |
}
|
27 |
}
|
28 |
}
|
50 |
_e( 'There is nothing that needs to be written to your <code>wp-config.php</code> file.', 'better-wp-security' );
|
51 |
} else {
|
52 |
echo '<p>' . __( "The following rules need to be written to your <code>wp-config.php</code> file. Please make sure to keep the comments in place." ) . '</p>';
|
53 |
+
echo '<div class="itsec_rewrite_rules"><pre id="itsec-rewrite-rules">' . esc_html( $config ) . '</pre></div>';
|
54 |
+
echo '<button class="button itsec-copy-trigger" data-copy-from="itsec-rewrite-rules">' . esc_html__( 'Copy to Clipboard', 'better-wp-security' ) . '</button>';
|
55 |
}
|
56 |
}
|
57 |
}
|
core/modules/global/settings-page.php
CHANGED
@@ -243,14 +243,6 @@ final class ITSEC_Global_Settings_Page extends ITSEC_Module_Settings_Page {
|
|
243 |
</td>
|
244 |
</tr>
|
245 |
<?php endif; ?>
|
246 |
-
<tr>
|
247 |
-
<th scope="row"><label for="itsec-global-lock_file"><?php _e( 'Disable File Locking', 'better-wp-security' ); ?></label></th>
|
248 |
-
<td>
|
249 |
-
<?php $form->add_checkbox( 'lock_file' ); ?>
|
250 |
-
<label for="itsec-global-lock_file"><?php _e( 'Disable File Locking', 'better-wp-security' ); ?></label>
|
251 |
-
<p class="description"><?php _e( 'iThemes Security uses file locking to prevent operations from being executed twice. We do not recommend disabling file locking unless your host prevents it from working correctly.', 'better-wp-security' ); ?></p>
|
252 |
-
</td>
|
253 |
-
</tr>
|
254 |
<tr>
|
255 |
<th scope="row"><label for="itsec-global-proxy_override"><?php _e( 'Override Proxy Detection', 'better-wp-security' ); ?></label></th>
|
256 |
<td>
|
243 |
</td>
|
244 |
</tr>
|
245 |
<?php endif; ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
<tr>
|
247 |
<th scope="row"><label for="itsec-global-proxy_override"><?php _e( 'Override Proxy Detection', 'better-wp-security' ); ?></label></th>
|
248 |
<td>
|
core/modules/global/validator.php
CHANGED
@@ -19,7 +19,7 @@ class ITSEC_Global_Validator extends ITSEC_Validator {
|
|
19 |
}
|
20 |
|
21 |
|
22 |
-
$this->set_previous_if_empty( array( 'did_upgrade', 'log_info', 'show_new_dashboard_notice', 'show_security_check', 'digest_last_sent', 'digest_messages', 'build', 'activation_timestamp' ) );
|
23 |
$this->set_default_if_empty( array( 'log_location', 'nginx_file' ) );
|
24 |
|
25 |
|
@@ -28,7 +28,6 @@ class ITSEC_Global_Validator extends ITSEC_Validator {
|
|
28 |
$this->sanitize_setting( 'bool', 'blacklist', __( 'Blacklist Repeat Offender', 'better-wp-security' ) );
|
29 |
$this->sanitize_setting( 'bool', 'email_notifications', __( 'Email Lockout Notifications', 'better-wp-security' ) );
|
30 |
$this->sanitize_setting( 'bool', 'allow_tracking', __( 'Allow Data Tracking', 'better-wp-security' ) );
|
31 |
-
$this->sanitize_setting( 'bool', 'lock_file', __( 'Disable File Locking', 'better-wp-security' ) );
|
32 |
$this->sanitize_setting( 'bool', 'proxy_override', __( 'Override Proxy Detection', 'better-wp-security' ) );
|
33 |
$this->sanitize_setting( 'bool', 'hide_admin_bar', __( 'Hide Security Menu in Admin Bar', 'better-wp-security' ) );
|
34 |
$this->sanitize_setting( 'bool', 'show_error_codes', __( 'Show Error Codes', 'better-wp-security' ) );
|
19 |
}
|
20 |
|
21 |
|
22 |
+
$this->set_previous_if_empty( array( 'did_upgrade', 'log_info', 'show_new_dashboard_notice', 'show_security_check', 'digest_last_sent', 'digest_messages', 'build', 'activation_timestamp', 'lock_file' ) );
|
23 |
$this->set_default_if_empty( array( 'log_location', 'nginx_file' ) );
|
24 |
|
25 |
|
28 |
$this->sanitize_setting( 'bool', 'blacklist', __( 'Blacklist Repeat Offender', 'better-wp-security' ) );
|
29 |
$this->sanitize_setting( 'bool', 'email_notifications', __( 'Email Lockout Notifications', 'better-wp-security' ) );
|
30 |
$this->sanitize_setting( 'bool', 'allow_tracking', __( 'Allow Data Tracking', 'better-wp-security' ) );
|
|
|
31 |
$this->sanitize_setting( 'bool', 'proxy_override', __( 'Override Proxy Detection', 'better-wp-security' ) );
|
32 |
$this->sanitize_setting( 'bool', 'hide_admin_bar', __( 'Hide Security Menu in Admin Bar', 'better-wp-security' ) );
|
33 |
$this->sanitize_setting( 'bool', 'show_error_codes', __( 'Show Error Codes', 'better-wp-security' ) );
|
core/modules/hide-backend/class-itsec-hide-backend.php
CHANGED
@@ -26,6 +26,7 @@ class ITSEC_Hide_Backend {
|
|
26 |
add_filter( 'network_site_url', array( $this, 'filter_generated_url' ), 100, 2 );
|
27 |
add_filter( 'wp_redirect', array( $this, 'filter_redirect' ) );
|
28 |
add_filter( 'comment_moderation_text', array( $this, 'filter_comment_moderation_text' ) );
|
|
|
29 |
|
30 |
remove_action( 'template_redirect', 'wp_redirect_admin_locations', 1000 );
|
31 |
}
|
@@ -270,6 +271,19 @@ class ITSEC_Hide_Backend {
|
|
270 |
return $this->filter_generated_url( $location, $location );
|
271 |
}
|
272 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
/**
|
274 |
* Add the access token query arg to the URL.
|
275 |
*
|
26 |
add_filter( 'network_site_url', array( $this, 'filter_generated_url' ), 100, 2 );
|
27 |
add_filter( 'wp_redirect', array( $this, 'filter_redirect' ) );
|
28 |
add_filter( 'comment_moderation_text', array( $this, 'filter_comment_moderation_text' ) );
|
29 |
+
add_filter( 'itsec_notify_admin_page_url', array( $this, 'filter_notify_admin_page_urls' ) );
|
30 |
|
31 |
remove_action( 'template_redirect', 'wp_redirect_admin_locations', 1000 );
|
32 |
}
|
271 |
return $this->filter_generated_url( $location, $location );
|
272 |
}
|
273 |
|
274 |
+
/**
|
275 |
+
* Filter URLs to admin pages in emails to include the access token query arg.
|
276 |
+
*
|
277 |
+
* This ensures that users are redirected to the correct login page if they are logged-out.
|
278 |
+
*
|
279 |
+
* @param string $location
|
280 |
+
*
|
281 |
+
* @return string
|
282 |
+
*/
|
283 |
+
public function filter_notify_admin_page_urls( $location ) {
|
284 |
+
return $this->add_token_to_url( $location, 'login' );
|
285 |
+
}
|
286 |
+
|
287 |
/**
|
288 |
* Add the access token query arg to the URL.
|
289 |
*
|
core/modules/malware/js/settings-page.js
CHANGED
@@ -7,8 +7,8 @@
|
|
7 |
},
|
8 |
|
9 |
bindEvents: function() {
|
10 |
-
$( '#itsec-malware-scan-start'
|
11 |
-
$(
|
12 |
},
|
13 |
|
14 |
toggleDetails: function( e ) {
|
7 |
},
|
8 |
|
9 |
bindEvents: function() {
|
10 |
+
$( document ).on( 'click', '#itsec-malware-scan-start', this.startScan );
|
11 |
+
$( document ).on( 'click', '.itsec-malware-scan-results-wrapper .itsec-malware-scan-toggle-details', this.toggleDetails );
|
12 |
},
|
13 |
|
14 |
toggleDetails: function( e ) {
|
core/modules/security-check/js/settings-page.js
CHANGED
@@ -1,7 +1,6 @@
|
|
1 |
jQuery( document ).ready( function ( $ ) {
|
2 |
-
var $container = $( '#itsec-module-card-security-check' );
|
3 |
|
4 |
-
$
|
5 |
e.preventDefault();
|
6 |
|
7 |
$( '#itsec-security-check-secure_site' )
|
@@ -27,7 +26,7 @@ jQuery( document ).ready( function ( $ ) {
|
|
27 |
} );
|
28 |
} );
|
29 |
|
30 |
-
$
|
31 |
e.preventDefault();
|
32 |
|
33 |
var $button = $( this );
|
1 |
jQuery( document ).ready( function ( $ ) {
|
|
|
2 |
|
3 |
+
$( document ).on( 'click', '#itsec-security-check-secure_site', function( e ) {
|
4 |
e.preventDefault();
|
5 |
|
6 |
$( '#itsec-security-check-secure_site' )
|
26 |
} );
|
27 |
} );
|
28 |
|
29 |
+
$( document ).on( 'click', '#itsec-module-card-security-check .itsec-security-check-container-is-interactive :submit', function( e ) {
|
30 |
e.preventDefault();
|
31 |
|
32 |
var $button = $( this );
|
core/modules/ssl/js/settings-page.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
(function( $ ) {
|
2 |
$(document).ready(function() {
|
3 |
-
$( '#itsec-ssl-admin'
|
4 |
if ( this.checked && ! confirm( itsec_ssl.translations.ssl_warning ) ) {
|
5 |
$(this).attr( 'checked', false );
|
6 |
}
|
1 |
(function( $ ) {
|
2 |
$(document).ready(function() {
|
3 |
+
$( document ).on( 'change', '#itsec-ssl-admin', function( e ) {
|
4 |
if ( this.checked && ! confirm( itsec_ssl.translations.ssl_warning ) ) {
|
5 |
$(this).attr( 'checked', false );
|
6 |
}
|
core/modules/strong-passwords/class-itsec-strong-passwords.php
CHANGED
@@ -65,7 +65,7 @@ final class ITSEC_Strong_Passwords {
|
|
65 |
}
|
66 |
|
67 |
require_once( ITSEC_Core::get_core_dir() . '/lib/class-itsec-lib-canonical-roles.php' );
|
68 |
-
|
69 |
if ( isset( $user->role ) ) {
|
70 |
$role = $this->get_canonical_role_from_role_and_user( $user->role, $user );
|
71 |
} else {
|
@@ -140,7 +140,12 @@ final class ITSEC_Strong_Passwords {
|
|
140 |
* @return string
|
141 |
*/
|
142 |
private function get_canonical_role_from_role_and_user( $role, $user ) {
|
143 |
-
|
|
|
|
|
|
|
|
|
|
|
144 |
$user_caps = array();
|
145 |
|
146 |
if ( isset( $user->caps ) ) {
|
65 |
}
|
66 |
|
67 |
require_once( ITSEC_Core::get_core_dir() . '/lib/class-itsec-lib-canonical-roles.php' );
|
68 |
+
|
69 |
if ( isset( $user->role ) ) {
|
70 |
$role = $this->get_canonical_role_from_role_and_user( $user->role, $user );
|
71 |
} else {
|
140 |
* @return string
|
141 |
*/
|
142 |
private function get_canonical_role_from_role_and_user( $role, $user ) {
|
143 |
+
if ( empty( $role ) ) {
|
144 |
+
$role_caps = array();
|
145 |
+
} else {
|
146 |
+
$role_caps = array_keys( array_filter( wp_roles()->get_role( $role )->capabilities ) );
|
147 |
+
}
|
148 |
+
|
149 |
$user_caps = array();
|
150 |
|
151 |
if ( isset( $user->caps ) ) {
|
core/notify.php
CHANGED
@@ -24,14 +24,7 @@ class ITSEC_Notify {
|
|
24 |
}
|
25 |
|
26 |
} else {
|
27 |
-
|
28 |
-
$yesterday = ITSEC_Core::get_current_time_gmt() - DAY_IN_SECONDS;
|
29 |
-
|
30 |
-
// Send digest if it has been 24 hours
|
31 |
-
if ( $last_sent < $yesterday && false === get_site_transient( 'itsec_notification_running' ) ) {
|
32 |
-
add_action( 'init', array( $this, 'init' ) );
|
33 |
-
}
|
34 |
-
|
35 |
}
|
36 |
|
37 |
}
|
@@ -41,21 +34,43 @@ class ITSEC_Notify {
|
|
41 |
*
|
42 |
* @since 4.5
|
43 |
*
|
44 |
-
* @return
|
45 |
*/
|
46 |
public function init() {
|
47 |
-
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
}
|
50 |
|
51 |
-
if (
|
52 |
-
|
53 |
}
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
$result = $this->send_daily_digest();
|
57 |
|
58 |
-
|
59 |
|
60 |
return $result;
|
61 |
}
|
@@ -65,7 +80,7 @@ class ITSEC_Notify {
|
|
65 |
*
|
66 |
* @since 2.6.0
|
67 |
*
|
68 |
-
* @return
|
69 |
*/
|
70 |
public function send_daily_digest() {
|
71 |
|
@@ -125,11 +140,11 @@ class ITSEC_Notify {
|
|
125 |
}
|
126 |
|
127 |
|
128 |
-
$mail->add_details_box( sprintf( wp_kses( __( 'For more details, <a href="%s"><b>visit your security logs</b></a>', 'better-wp-security' ), array( 'a' => array( 'href' => array() ), 'b' => array() ) ), ITSEC_Core::get_logs_page_url() ) );
|
129 |
$mail->add_divider();
|
130 |
$mail->add_large_text( esc_html__( 'Is your site as secure as it could be?', 'better-wp-security' ) );
|
131 |
$mail->add_text( esc_html__( 'Ensure your site is using recommended settings and features with a security check.', 'better-wp-security' ) );
|
132 |
-
$mail->add_button( esc_html__( 'Run a Security Check ✓', 'better-wp-security' ), ITSEC_Core::get_security_check_page_url() );
|
133 |
|
134 |
if ( defined( 'ITSEC_DEBUG' ) && true === ITSEC_DEBUG ) {
|
135 |
$mail->add_text( sprintf( esc_html__( 'Debug info (source page): %s', 'better-wp-security' ), esc_url( $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] ) ) );
|
@@ -294,5 +309,4 @@ class ITSEC_Notify {
|
|
294 |
return 'text/html';
|
295 |
|
296 |
}
|
297 |
-
|
298 |
}
|
24 |
}
|
25 |
|
26 |
} else {
|
27 |
+
add_action( 'init', array( $this, 'init' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
}
|
29 |
|
30 |
}
|
34 |
*
|
35 |
* @since 4.5
|
36 |
*
|
37 |
+
* @return bool
|
38 |
*/
|
39 |
public function init() {
|
40 |
+
|
41 |
+
if ( is_404() ) {
|
42 |
+
return false;
|
43 |
+
}
|
44 |
+
|
45 |
+
$use_cron = defined( 'ITSEC_NOTIFY_USE_CRON' ) && ITSEC_NOTIFY_USE_CRON;
|
46 |
+
$doing_cron = defined( 'DOING_CRON' ) && DOING_CRON;
|
47 |
+
|
48 |
+
if ( $doing_cron && ! $use_cron ) {
|
49 |
+
return false;
|
50 |
}
|
51 |
|
52 |
+
if ( ! ITSEC_Lib::get_lock( 'daily-digest' ) ) {
|
53 |
+
return false;
|
54 |
}
|
55 |
|
56 |
+
if ( ! $use_cron ) {
|
57 |
+
|
58 |
+
$global = ITSEC_Modules::get_settings_obj( 'global' );
|
59 |
+
ITSEC_Storage::reload();
|
60 |
+
$global->load();
|
61 |
+
|
62 |
+
$last_sent = $global->get('digest_last_sent' );
|
63 |
+
$yesterday = ITSEC_Core::get_current_time_gmt() - DAY_IN_SECONDS;
|
64 |
+
|
65 |
+
// Send digest if it has been 24 hours
|
66 |
+
if ( $last_sent > $yesterday ) {
|
67 |
+
return false;
|
68 |
+
}
|
69 |
+
}
|
70 |
|
71 |
$result = $this->send_daily_digest();
|
72 |
|
73 |
+
ITSEC_Lib::release_lock( 'daily-digest' );
|
74 |
|
75 |
return $result;
|
76 |
}
|
80 |
*
|
81 |
* @since 2.6.0
|
82 |
*
|
83 |
+
* @return bool
|
84 |
*/
|
85 |
public function send_daily_digest() {
|
86 |
|
140 |
}
|
141 |
|
142 |
|
143 |
+
$mail->add_details_box( sprintf( wp_kses( __( 'For more details, <a href="%s"><b>visit your security logs</b></a>', 'better-wp-security' ), array( 'a' => array( 'href' => array() ), 'b' => array() ) ), ITSEC_Mail::filter_admin_page_url( ITSEC_Core::get_logs_page_url() ) ) );
|
144 |
$mail->add_divider();
|
145 |
$mail->add_large_text( esc_html__( 'Is your site as secure as it could be?', 'better-wp-security' ) );
|
146 |
$mail->add_text( esc_html__( 'Ensure your site is using recommended settings and features with a security check.', 'better-wp-security' ) );
|
147 |
+
$mail->add_button( esc_html__( 'Run a Security Check ✓', 'better-wp-security' ), ITSEC_Mail::filter_admin_page_url( ITSEC_Core::get_security_check_page_url() ) );
|
148 |
|
149 |
if ( defined( 'ITSEC_DEBUG' ) && true === ITSEC_DEBUG ) {
|
150 |
$mail->add_text( sprintf( esc_html__( 'Debug info (source page): %s', 'better-wp-security' ), esc_url( $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] ) ) );
|
309 |
return 'text/html';
|
310 |
|
311 |
}
|
|
|
312 |
}
|
core/response.php
CHANGED
@@ -5,6 +5,7 @@ final class ITSEC_Response {
|
|
5 |
|
6 |
private $response;
|
7 |
private $errors;
|
|
|
8 |
private $messages;
|
9 |
private $success;
|
10 |
private $js_function_calls;
|
@@ -69,6 +70,24 @@ final class ITSEC_Response {
|
|
69 |
|
70 |
return $self->errors;
|
71 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
|
73 |
public static function get_error_count() {
|
74 |
$self = self::get_instance();
|
@@ -156,6 +175,10 @@ final class ITSEC_Response {
|
|
156 |
$self->add_js_function_call( 'reloadModule', $module );
|
157 |
}
|
158 |
|
|
|
|
|
|
|
|
|
159 |
public static function regenerate_wp_config() {
|
160 |
$self = self::get_instance();
|
161 |
|
@@ -244,8 +267,9 @@ final class ITSEC_Response {
|
|
244 |
'success' => $self->success,
|
245 |
'response' => $self->response,
|
246 |
'errors' => self::get_error_strings( $self->errors ),
|
|
|
247 |
'messages' => $self->messages,
|
248 |
-
'functionCalls' =>
|
249 |
'redirect' => $self->redirect,
|
250 |
'closeModal' => $self->close_modal,
|
251 |
);
|
@@ -271,6 +295,7 @@ final class ITSEC_Response {
|
|
271 |
public function reset_to_defaults() {
|
272 |
$this->response = null;
|
273 |
$this->errors = array();
|
|
|
274 |
$this->messages = array();
|
275 |
$this->success = true;
|
276 |
$this->js_function_calls = array();
|
@@ -312,6 +337,32 @@ final class ITSEC_Response {
|
|
312 |
return array( sprintf( __( 'Unknown error type received: %1$s.', 'better-wp-security' ), gettype( $error ) ) );
|
313 |
}
|
314 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
315 |
public function shutdown() {
|
316 |
self::maybe_regenerate_wp_config();
|
317 |
self::maybe_regenerate_server_config();
|
5 |
|
6 |
private $response;
|
7 |
private $errors;
|
8 |
+
private $warnings;
|
9 |
private $messages;
|
10 |
private $success;
|
11 |
private $js_function_calls;
|
70 |
|
71 |
return $self->errors;
|
72 |
}
|
73 |
+
|
74 |
+
public static function add_warnings( $warnings ) {
|
75 |
+
foreach ( $warnings as $warning ) {
|
76 |
+
self::add_warning( $warning );
|
77 |
+
}
|
78 |
+
}
|
79 |
+
|
80 |
+
public static function add_warning( $warning ) {
|
81 |
+
$self = self::get_instance();
|
82 |
+
|
83 |
+
$self->warnings[] = $warning;
|
84 |
+
}
|
85 |
+
|
86 |
+
public static function get_warnings() {
|
87 |
+
$self = self::get_instance();
|
88 |
+
|
89 |
+
return $self->warnings;
|
90 |
+
}
|
91 |
|
92 |
public static function get_error_count() {
|
93 |
$self = self::get_instance();
|
175 |
$self->add_js_function_call( 'reloadModule', $module );
|
176 |
}
|
177 |
|
178 |
+
public static function reload_all_modules() {
|
179 |
+
self::get_instance()->add_js_function_call( 'reloadAllModules' );
|
180 |
+
}
|
181 |
+
|
182 |
public static function regenerate_wp_config() {
|
183 |
$self = self::get_instance();
|
184 |
|
267 |
'success' => $self->success,
|
268 |
'response' => $self->response,
|
269 |
'errors' => self::get_error_strings( $self->errors ),
|
270 |
+
'warnings' => self::get_error_strings( $self->warnings ),
|
271 |
'messages' => $self->messages,
|
272 |
+
'functionCalls' => self::parse_js_function_calls_for_module_reloads(),
|
273 |
'redirect' => $self->redirect,
|
274 |
'closeModal' => $self->close_modal,
|
275 |
);
|
295 |
public function reset_to_defaults() {
|
296 |
$this->response = null;
|
297 |
$this->errors = array();
|
298 |
+
$this->warnings = array();
|
299 |
$this->messages = array();
|
300 |
$this->success = true;
|
301 |
$this->js_function_calls = array();
|
337 |
return array( sprintf( __( 'Unknown error type received: %1$s.', 'better-wp-security' ), gettype( $error ) ) );
|
338 |
}
|
339 |
|
340 |
+
private static function parse_js_function_calls_for_module_reloads() {
|
341 |
+
|
342 |
+
$has_reload_all = false;
|
343 |
+
|
344 |
+
$function_calls = self::get_instance()->js_function_calls;
|
345 |
+
|
346 |
+
foreach ( $function_calls as $function_call ) {
|
347 |
+
if ( $function_call[0] === 'reloadAllModules' ) {
|
348 |
+
$has_reload_all = true;
|
349 |
+
break;
|
350 |
+
}
|
351 |
+
}
|
352 |
+
|
353 |
+
if ( ! $has_reload_all ) {
|
354 |
+
return $function_calls;
|
355 |
+
}
|
356 |
+
|
357 |
+
foreach ( $function_calls as $i => $function_call ) {
|
358 |
+
if ( $function_call[0] === 'reloadModule' ) {
|
359 |
+
unset( $function_calls[ $i ] );
|
360 |
+
}
|
361 |
+
}
|
362 |
+
|
363 |
+
return array_values( $function_calls );
|
364 |
+
}
|
365 |
+
|
366 |
public function shutdown() {
|
367 |
self::maybe_regenerate_wp_config();
|
368 |
self::maybe_regenerate_server_config();
|
core/setup.php
CHANGED
@@ -12,25 +12,33 @@ final class ITSEC_Setup {
|
|
12 |
}
|
13 |
|
14 |
public static function handle_deactivation() {
|
15 |
-
if ( ! self::
|
16 |
return;
|
17 |
}
|
18 |
|
19 |
if ( defined( 'ITSEC_DEVELOPMENT' ) && ITSEC_DEVELOPMENT ) {
|
20 |
// Set this in wp-config.php to run the uninstall routine on deactivate.
|
21 |
-
self::
|
|
|
22 |
} else {
|
23 |
self::deactivate();
|
24 |
}
|
25 |
}
|
26 |
|
27 |
public static function handle_uninstall() {
|
28 |
-
|
|
|
29 |
return;
|
30 |
}
|
31 |
|
32 |
self::deactivate();
|
33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
}
|
35 |
|
36 |
public static function handle_upgrade( $build = false ) {
|
@@ -169,14 +177,38 @@ final class ITSEC_Setup {
|
|
169 |
|
170 |
}
|
171 |
|
172 |
-
private static function
|
173 |
-
$active_plugins = (array) get_option( 'active_plugins', array() );
|
174 |
|
175 |
-
if (
|
176 |
-
|
177 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
}
|
179 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
foreach ( $active_plugins as $active_plugin ) {
|
181 |
$file = basename( $active_plugin );
|
182 |
|
@@ -188,6 +220,18 @@ final class ITSEC_Setup {
|
|
188 |
return false;
|
189 |
}
|
190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
private static function upgrade_from_bwps() {
|
192 |
global $itsec_bwps_options, $wpdb;
|
193 |
|
12 |
}
|
13 |
|
14 |
public static function handle_deactivation() {
|
15 |
+
if ( ! self::is_at_least_one_itsec_version_active() ) {
|
16 |
return;
|
17 |
}
|
18 |
|
19 |
if ( defined( 'ITSEC_DEVELOPMENT' ) && ITSEC_DEVELOPMENT ) {
|
20 |
// Set this in wp-config.php to run the uninstall routine on deactivate.
|
21 |
+
self::deactivate();
|
22 |
+
self::uninstall();
|
23 |
} else {
|
24 |
self::deactivate();
|
25 |
}
|
26 |
}
|
27 |
|
28 |
public static function handle_uninstall() {
|
29 |
+
|
30 |
+
if ( self::is_at_least_one_itsec_version_active() ) {
|
31 |
return;
|
32 |
}
|
33 |
|
34 |
self::deactivate();
|
35 |
+
|
36 |
+
$uninstalled = self::get_version_being_uninstalled();
|
37 |
+
$loaded = self::get_version_loaded();
|
38 |
+
|
39 |
+
if ( $uninstalled === $loaded ) {
|
40 |
+
self::uninstall();
|
41 |
+
}
|
42 |
}
|
43 |
|
44 |
public static function handle_upgrade( $build = false ) {
|
177 |
|
178 |
}
|
179 |
|
180 |
+
private static function get_version_being_uninstalled() {
|
|
|
181 |
|
182 |
+
if ( doing_action( 'uninstall_better-wp-security/better-wp-security.php' ) ) {
|
183 |
+
return 'free';
|
184 |
+
}
|
185 |
+
|
186 |
+
if ( doing_action( 'uninstall_ithemes-security-pro/ithemes-security-pro.php' ) ) {
|
187 |
+
return 'pro';
|
188 |
+
}
|
189 |
+
|
190 |
+
return '';
|
191 |
+
}
|
192 |
+
|
193 |
+
private static function get_version_loaded() {
|
194 |
+
|
195 |
+
$plugin_dir = plugin_basename( dirname( dirname( __FILE__ ) ) );
|
196 |
+
|
197 |
+
if ( $plugin_dir === 'better-wp-security' ) {
|
198 |
+
return 'free';
|
199 |
}
|
200 |
|
201 |
+
if ( $plugin_dir === 'ithemes-security-pro' ) {
|
202 |
+
return 'pro';
|
203 |
+
}
|
204 |
+
|
205 |
+
return '';
|
206 |
+
}
|
207 |
+
|
208 |
+
private static function is_at_least_one_itsec_version_active() {
|
209 |
+
|
210 |
+
$active_plugins = self::get_active_plugins();
|
211 |
+
|
212 |
foreach ( $active_plugins as $active_plugin ) {
|
213 |
$file = basename( $active_plugin );
|
214 |
|
220 |
return false;
|
221 |
}
|
222 |
|
223 |
+
private static function get_active_plugins() {
|
224 |
+
|
225 |
+
$active_plugins = (array) get_option( 'active_plugins', array() );
|
226 |
+
|
227 |
+
if ( is_multisite() ) {
|
228 |
+
$network_plugins = (array) get_site_option( 'active_sitewide_plugins', array() );
|
229 |
+
$active_plugins = array_merge( $active_plugins, array_keys( $network_plugins ) );
|
230 |
+
}
|
231 |
+
|
232 |
+
return $active_plugins;
|
233 |
+
}
|
234 |
+
|
235 |
private static function upgrade_from_bwps() {
|
236 |
global $itsec_bwps_options, $wpdb;
|
237 |
|
history.txt
CHANGED
@@ -662,3 +662,10 @@
|
|
662 |
Enhancement: Hide Backend functions purely in PHP code now rather than relying half on PHP code and half on .htaccess and nginx.conf modifications. This allows Hide Backend to function on web servers and server configurations that it was previously not compatible with.
|
663 |
Misc: Updated or added phpDoc to many functions.
|
664 |
Misc: Updated Disable File Locking description.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
662 |
Enhancement: Hide Backend functions purely in PHP code now rather than relying half on PHP code and half on .htaccess and nginx.conf modifications. This allows Hide Backend to function on web servers and server configurations that it was previously not compatible with.
|
663 |
Misc: Updated or added phpDoc to many functions.
|
664 |
Misc: Updated Disable File Locking description.
|
665 |
+
6.4.0 - 2017-07-24 - Chris Jean & Timothy Jacobs
|
666 |
+
Enhancement: Replaced file locking with database locking. This method of locking is compatible with all systems as it does not require the ability to write files. It also allows for locking to work on sites that have multiple front-end servers with a shared database. Since file locking is no longer used, the Global Settings > Disable File Locking setting was removed.
|
667 |
+
Enhancement: Add "Copy to Clipboard" functionality for server and wp-config rules.
|
668 |
+
Bug Fix: Prevent 404s when following links in email notifications on a site with Hide Backend enabled.
|
669 |
+
Bug Fix: Ensure uninstall process is not run when another version of iThemes Security is still active.
|
670 |
+
Bug Fix: Fixed method of working around Hide Backend.
|
671 |
+
Bug Fix: Warnings are no longer generated when saving a user profile with a role of "No role for this site" selected.
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: ithemes, chrisjean, gerroald, mattdanner
|
|
3 |
Tags: security, security plugin, malware, hack, secure, block, SSL, admin, htaccess, lockdown, login, protect, protection, anti virus, attack, injection, login security, maintenance, permissions, prevention, authentication, administration, password, brute force, ban, permissions, bots, user agents, xml rpc, security log
|
4 |
Requires at least: 4.6
|
5 |
Tested up to: 4.8
|
6 |
-
Stable tag: 6.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -188,6 +188,14 @@ Free support may be available with the help of the community in the <a href="htt
|
|
188 |
|
189 |
== Changelog ==
|
190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
= 6.3.0 =
|
192 |
* Important: The way that Hide Backend functions changes in this release. Previously, if your Hide Backend Login Slug was wplogin, going to example.com/wplogin would result in the URL remaining example.com/wplogin. The new implementation of this feature results in a redirect to a URL that looks as follows: example.com/wp-login.php?itsec-hb-token=wplogin. While this may not be desireable for some users, this change was necessary to fix longstanding compatibility issues with other plugins. Once you access the login page using the Login Slug page, a cookie is set with an expiration time of one hour. As long as the cookie remains, you can access example.com/wp-login.php without having to access the Hide Backend Login Slug first. If you wish to confirm that Hide Backend is working properly on your site, opening up a private browsing window is a quick way to test without having to log out and clear cookies.
|
193 |
* New Feature: Added support for iThemes Sync to run the Security Check feature from inside the Sync service.
|
@@ -1701,5 +1709,5 @@ This release is a complete rewrite from the ground up. Special thanks to Cory Mi
|
|
1701 |
|
1702 |
== Upgrade Notice ==
|
1703 |
|
1704 |
-
= 6.
|
1705 |
-
Version 6.
|
3 |
Tags: security, security plugin, malware, hack, secure, block, SSL, admin, htaccess, lockdown, login, protect, protection, anti virus, attack, injection, login security, maintenance, permissions, prevention, authentication, administration, password, brute force, ban, permissions, bots, user agents, xml rpc, security log
|
4 |
Requires at least: 4.6
|
5 |
Tested up to: 4.8
|
6 |
+
Stable tag: 6.4.0
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
188 |
|
189 |
== Changelog ==
|
190 |
|
191 |
+
= 6.4.0 =
|
192 |
+
* Enhancement: Replaced file locking with database locking. This method of locking is compatible with all systems as it does not require the ability to write files. It also allows for locking to work on sites that have multiple front-end servers with a shared database. Since file locking is no longer used, the Global Settings > Disable File Locking setting was removed.
|
193 |
+
* Enhancement: Add "Copy to Clipboard" functionality for server and wp-config rules.
|
194 |
+
* Bug Fix: Prevent 404s when following links in email notifications on a site with Hide Backend enabled.
|
195 |
+
* Bug Fix: Ensure uninstall process is not run when another version of iThemes Security is still active.
|
196 |
+
* Bug Fix: Fixed method of working around Hide Backend.
|
197 |
+
* Bug Fix: Warnings are no longer generated when saving a user profile with a role of "No role for this site" selected.
|
198 |
+
|
199 |
= 6.3.0 =
|
200 |
* Important: The way that Hide Backend functions changes in this release. Previously, if your Hide Backend Login Slug was wplogin, going to example.com/wplogin would result in the URL remaining example.com/wplogin. The new implementation of this feature results in a redirect to a URL that looks as follows: example.com/wp-login.php?itsec-hb-token=wplogin. While this may not be desireable for some users, this change was necessary to fix longstanding compatibility issues with other plugins. Once you access the login page using the Login Slug page, a cookie is set with an expiration time of one hour. As long as the cookie remains, you can access example.com/wp-login.php without having to access the Hide Backend Login Slug first. If you wish to confirm that Hide Backend is working properly on your site, opening up a private browsing window is a quick way to test without having to log out and clear cookies.
|
201 |
* New Feature: Added support for iThemes Sync to run the Security Check feature from inside the Sync service.
|
1709 |
|
1710 |
== Upgrade Notice ==
|
1711 |
|
1712 |
+
= 6.4.0 =
|
1713 |
+
Version 6.4.0 contains important bug fixes and enhancements. It is recommended for all users.
|