Ubuntu

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ /* globals jQuery: false, ajaxurl: false, wp: false, SecuPressi18nModules: false, secupressIsSpaceOrEnterKey: false, swal2: false */ // Global vars ===================================================================================== var SecuPress = { doingAjax: {}, deletedRowColor: "#FF9966", addedRowColor: "#CCEEBB", swal2Defaults: { title: SecuPressi18nModules.confirmTitle, confirmButtonText: SecuPressi18nModules.confirmText, cancelButtonText: SecuPressi18nModules.cancelText, type: "warning", allowOutsideClick: true, customClass: "wpmedia-swal2 secupress-swal2" }, swal2ConfirmDefaults: { showCancelButton: true, closeOnConfirm: false }, expandButton: '

' }; /** * Show swal2 message if no scan done yet */ if ( SecuPressi18nModules.alreadyScanned === 0 ) { var modal_title = '', modal_content; modal_content = '

'; modal_content += SecuPressi18nModules.firstScanTitle; modal_content += '

'; modal_content += '

'; modal_content += SecuPressi18nModules.firstScanText; modal_content += '

'; modal_content += '

'; modal_content += ''; modal_content += ''; modal_content += ''; modal_content += ''; modal_content += ''; modal_content += SecuPressi18nModules.firstScanButton; modal_content += ''; modal_content += ''; modal_content += '

'; swal2( jQuery.extend( {}, SecuPress.swal2Defaults, { title: modal_title, html: modal_content, type: null, width: 400, showConfirmButton: false, showCloseButton: true, showCancelButton: false, customClass: 'wpmedia-swal2 secupress-swal2 secupress-swal-dark-header secupress-text-center' } ) ); } // Tools =========================================================================================== /** * Disable a button that calls an ajax action. * - Add a "working" class, so that the spinner can be displayed. * - Add a "aria-disabled" attribute. * - If it's a link: add a "disabled" attribute. If it's a button or input: add a "disabled" attribute. * - Change the button text if a "data-loading-i18n" attribute is present. * - Use `wp.a11y.speak` if a text is provided. * - Set a `SecuPress.doingAjax` attribute to `true`. * * @since 1.0 * * @param (object) $button jQuery object of the button. * @param (string) speak Text for `wp.a11y.speak`. * @param (string) ajaxID An identifier used for `SecuPress.doingAjax`. Default: "global". */ function secupressDisableAjaxButton( $button, speak, ajaxID ) { var text = $button.attr( "data-loading-i18n" ), isButton = $button.get( 0 ).nodeName.toLowerCase(), value; ajaxID = undefined !== ajaxID ? ajaxID : "global"; SecuPress.doingAjax[ ajaxID ] = true; isButton = isButton === "button" || isButton === "input"; if ( undefined !== text && text ) { if ( isButton ) { value = $button.val(); if ( undefined !== value && value ) { $button.val( text ); } else { if ( $button.find('.text').length ) { $button.find('.text').text( text ); } else { $button.text( text ); } } } else { if ( $button.find('.text').length ) { $button.find('.text').text( text ); } else { $button.text( text ); } } if ( undefined === speak || ! speak ) { speak = text; } } if ( isButton ) { $button.addClass( "working" ).attr( { "disabled": "disabled", "aria-disabled": "true" } ); } else { $button.addClass( "disabled working" ).attr( "aria-disabled", "true" ); } if ( wp.a11y && wp.a11y.speak && undefined !== speak && speak ) { wp.a11y.speak( speak ); } } /** * Enable a button that calls an ajax action. * - Remove the "working" class, so that the spinner can be hidden again. * - Remove the "aria-disabled" attribute. * - If it's a link: remove the "disabled" attribute. If it's a button or input: remove the "disabled" attribute. * - Change the button text if a "data-original-i18n" attribute is present. * - Use `wp.a11y.speak` if a text is provided. * - Set a `SecuPress.doingAjax` attribute to `false`. * * @since 1.0 * * @param (object) $button jQuery object of the button. * @param (string) speak Text for `wp.a11y.speak`. * @param (string) ajaxID An identifier used for `SecuPress.doingAjax`. Default: "global". */ function secupressEnableAjaxButton( $button, speak, ajaxID ) { var text, isButton, value; if ( undefined !== $button && $button && $button.length ) { text = $button.attr( "data-original-i18n" ); isButton = $button.get( 0 ).nodeName.toLowerCase(); isButton = "button" === isButton || "input" === isButton; if ( undefined !== text && text ) { if ( isButton ) { value = $button.val(); if ( undefined !== value && value ) { $button.val( text ); } else { if ( $button.find('.text').length ) { $button.find('.text').text( text ); } else { $button.text( text ); } } } else { if ( $button.find('.text').length ) { $button.find('.text').text( text ); } else { $button.text( text ); } } } if ( isButton ) { $button.removeClass( "working" ).removeAttr( "disabled aria-disabled" ); } else { $button.removeClass( "disabled working" ).removeAttr( "aria-disabled" ); } } if ( wp.a11y && wp.a11y.speak && undefined !== speak && speak ) { wp.a11y.speak( speak ); } ajaxID = undefined !== ajaxID ? ajaxID : "global"; SecuPress.doingAjax[ ajaxID ] = false; } /** * Before doing an ajax call, do some tests: * - test if we have an URL. * - if the event is "keyup", test if the key is the Space bar or Enter. * - test another ajax call is not running. * Also prevent default event. * * @since 1.0 * * @param (string) href The URL. * @param (object) e The jQuery event object. * @param (string) ajaxID An identifier used for `SecuPress.doingAjax`. Default: "global". * * @return (bool|string) False on failure, the ajax URL on success. */ function secupressPreAjaxCall( href, e, ajaxID ) { e.preventDefault(); if ( undefined === href || ! href ) { return false; } if ( "keyup" === e.type && ! secupressIsSpaceOrEnterKey( e ) ) { return false; } ajaxID = undefined !== ajaxID ? ajaxID : "global"; if ( typeof SecuPress.doingAjax[ ajaxID ] === "undefined" ) { SecuPress.doingAjax[ ajaxID ] = false; } if ( SecuPress.doingAjax[ ajaxID ] ) { return false; } return href.replace( "admin-post.php", "admin-ajax.php" ); } /** * Display an error message via Sweet Alert and re-enable the button. * * @since 1.0 * * @param (object) $button jQuery object of the button. * @param (string) text Text for swal2 + `wp.a11y.speak`. * @param (string) ajaxID An identifier used for `SecuPress.doingAjax`. Default: "global". */ function secupressDisplayAjaxError( $button, text, ajaxID ) { if ( undefined === text ) { text = SecuPressi18nModules.unknownError; } swal2( jQuery.extend( {}, SecuPress.swal2Defaults, { title: SecuPressi18nModules.error, html: text, type: "error" } ) ); ajaxID = undefined !== ajaxID ? ajaxID : "global"; secupressEnableAjaxButton( $button, text, ajaxID ); } /** * Display a success message via Sweet Alert and re-enable the button. * * @since 1.0 * * @param (object) $button jQuery object of the button. * @param (string) text Text for swal2 + `wp.a11y.speak`. * @param (string) ajaxID An identifier used for `SecuPress.doingAjax`. Default: "global". */ function secupressDisplayAjaxSuccess( $button, text, ajaxID ) { if ( undefined === text ) { text = null; } swal2( jQuery.extend( {}, SecuPress.swal2Defaults, { title: SecuPressi18nModules.done, html: text, type: "success", timer: 4000 } ) ); ajaxID = undefined !== ajaxID ? ajaxID : "global"; secupressEnableAjaxButton( $button, text, ajaxID ); } // Roles: at least one role must be chosen. ======================================================== (function($, d, w, undefined) { if ( "function" === typeof document.createElement( "input" ).checkValidity ) { $( ".affected-role-row :checkbox" ).on( "click.secupress", function() { this.setCustomValidity( '' ); if ( 0 === $( '[name="' + this.name + '"]:checked' ).length ) { this.setCustomValidity( SecuPressi18nModules.selectOneRoleMinimum ); $( "#secupress-module-form-settings [type='submit']" ).first().trigger( "click.secupress" ); } } ); } else { $( ".affected-role-row p.warning" ).removeClass( "hide-if-js" ); } } )(jQuery, document, window); // Radioboxes: 1 checked at most. ================================================================== (function($, d, w, undefined) { $( ".radiobox" ).on( "click.secupress", function() { $( '[name="' + this.name + '"]:checked' ).not( this ).removeAttr( "checked" ).trigger( "change" ); } ); } )(jQuery, document, window); // Show/Hide panels, depending on some other field value. ========================================== (function($, d, w, undefined) { var $depends = $( "#wpbody-content" ).find( '[class*="depends-"]' ), // Rows that will open/close. dependsIds = {}, // IDs of the checkboxes, radios, etc that will trigger a panel open/close. dependsRadioNames = {}; // names of the radios. $( '.secupress-setting-row_move-login_slug-login' ) .on( 'secupressbeforeshow secupressinitshow', function() { $( '#move-login_slug-login' ).attr( { 'required': 'required', 'aria-required': 'true' } ); } ) .on( 'secupressafterhide secupressinithide', function() { $( '#move-login_slug-login' ).removeAttr( 'required aria-required' ); } ); $depends.each( function() { var classes = $( this ).attr( "class" ).replace( /^\s+|\s+$/g, "" ).replace( /\s+/, " " ).split( " " ); $.each( classes, function( i, id ) { var $input, // input element inputTagName, // input tag name inputTypeAttr, // input type inputNameAttr, // input name inputIsValid = false; // If the class is not a "depends-XXXXXX", bail out. if ( 0 !== id.indexOf( "depends-" ) ) { return true; } id = id.substr( 8 ); // If the ID was previously delt with, bail out. if ( "undefined" !== typeof dependsIds[ id ] ) { return true; } dependsIds[ id ] = 1; $input = $( "#" + id ); // Uh? The input doesn't exist? if ( ! $input.length ) { return true; } // We need to know which type of input we deal with, the way we deal with it is not the same. inputTagName = $input.get( 0 ).nodeName.toLowerCase(); if ( "input" === inputTagName ) { inputTypeAttr = $input.attr( "type" ).toLowerCase(); if ( "checkbox" === inputTypeAttr || "radio" === inputTypeAttr ) { inputIsValid = true; } } else if ( "button" === inputTagName ) { inputIsValid = true; } // Only checkboxes, radios groups and buttons so far. if ( ! inputIsValid ) { return true; } // Attach the events. // Buttons if ( "button" === inputTagName ) { $input.on( "click.secupress", function() { var id = $( this ).attr( "id" ); $( this ).toggleClass( 'open' ); $( ".depends-" + id ).toggle( 250 ); } ); } // Radios else if ( "radio" === inputTypeAttr ) { inputNameAttr = $input.attr( "name" ); // If the name was previously delt with, bail out. if ( "undefined" !== typeof dependsRadioNames[ inputNameAttr ] ) { return true; } dependsRadioNames[ inputNameAttr ] = 1; $( '[name="' + inputNameAttr + '"]' ).on( "change init.secupress", function( e ) { var $this = $( this ), $toShow = $( ".depends-" + $this.attr( "id" ) ), // Elements to show. toHide = [], // Elements to hide. tempo = "init" === e.type && "secupress" === e.namespace ? 0 : 250; // On page load, no animation. // The radio is checked: open the desired boxes if not visible. $toShow.not( ":visible" ).trigger( "secupressbeforeshow" ).show( tempo, function() { $( this ).trigger( "secupressaftershow" ); } ); // Find boxes to hide. $( '[name="' + $this.attr( "name" ) + '"]' ).not( $this ).each( function() { toHide.push( ".depends-" + $( this ).attr( "id" ).replace( /^\s+|\s+$/g, "" ) ); } ); $( toHide.join( "," ) ).not( $toShow ).filter( ":visible" ).trigger( "secupressbeforehide" ).hide( tempo, function() { $( this ).trigger( "secupressafterhide" ); } ); } ).filter( ":checked" ).trigger( "init.secupress" ); } // Checkboxes else if ( "checkbox" === inputTypeAttr ) { $input.on( "change init.secupress", function( e ) { var $this = $( this ), id = $this.attr( "id" ), $elems = $( ".depends-" + id ), // Elements to hide or show. tempo = "init" === e.type && "secupress" === e.namespace ? 0 : 250; // On page load, no animation. // Uh? No rows? if ( ! $elems.length ) { return true; } // The checkbox is checked: open if not visible. if ( $this.is( ":checked" ) ) { $elems.not( ":visible" ).trigger( "secupressbeforeshow" ).show( tempo, function() { $( this ).trigger( "secupressaftershow" ); } ); } // The checkbox is not checked: close if visible and no other checkboxes that want this row to be open is checked. else { $elems.filter( ":visible" ).each( function() { var $this = $( this ), classes = $this.attr( "class" ).replace( /^\s+|\s+$/g, "" ).replace( /\s+/, " " ).split( " " ), others = []; // Other checkboxes $.each( classes, function( i, v ) { if ( "depends-" + id !== v && 0 === v.indexOf( "depends-" ) ) { others.push( "#" + v.substr( 8 ) + ":checked" ); } } ); others = others.join( "," ); if ( ! $( others ).length ) { $this.trigger( "secupressbeforehide" ).hide( tempo, function() { $( this ).trigger( "secupressafterhide" ); } ); } } ); } } ).filter( ":checked" ).trigger( "init.secupress" ); if ( $input.is( ':checked' ) ) { $( '.depends-' + id ).filter( ':visible' ).trigger( 'secupressinitshow' ); } else { $( '.depends-' + id ).not( ':visible' ).trigger( 'secupressinithide' ); } } } ); } ); } )(jQuery, document, window); // Move Login ====================================================================================== (function($, d, w, undefined) { var cache = {}, timeout = {}; function secupressUpdateMoveLoginSlug( value, $input ) { $( $input ).closest( '.secupress-text-label' ).find( '.dynamic-login-url-slug' ).text( value ); } if ( SecuPressi18nModules.moveLoginNonce ) { $( '.dynamic-login-url-slug' ).closest( '.secupress-text-label' ).find( '[type="text"]' ).on( 'keyup', function( e ) { var elem, value, action, // Shift, Control, Alt, Meta, Escape. keys = [ 16, 17, 18, 224, 27 ]; if ( $.inArray( e.which, keys ) !== -1 ) { return false; } elem = this; value = elem.value.replace( /^\s+|\s+$/g, '' ); action = elem.id.replace( 'move-login_slug-', '' ); if ( typeof timeout[ elem.id ] !== undefined ) { w.clearTimeout( timeout[ elem.id ] ); } if ( 'login' !== action ) { value = '' === value ? action : value; } if ( typeof cache[ value ] === 'string' ) { secupressUpdateMoveLoginSlug( cache[ value ], elem ); return true; } timeout[ elem.id ] = w.setTimeout( function() { var $elem = $( elem ).addClass( 'ui-autocomplete-loading' ), params = { 'action': 'sanitize_move_login_slug', 'slug': value, 'default': action, '_wpnonce': SecuPressi18nModules.moveLoginNonce }; $.getJSON( ajaxurl, params ) .done( function( r ) { if ( $.isPlainObject( r ) && r.success ) { cache[ value ] = r.data; secupressUpdateMoveLoginSlug( r.data, $elem ); } else { secupressUpdateMoveLoginSlug( '--' + SecuPressi18nModules.error + '--', $elem ); } } ) .fail( function() { secupressUpdateMoveLoginSlug( '--' + SecuPressi18nModules.error + '--', $elem ); } ) .always( function() { $elem.removeClass( 'ui-autocomplete-loading' ); } ); }, 300 ); } ); } } )(jQuery, document, window); // Backups ========================================================================================= (function($, d, w, undefined) { function secupressUpdateAvailableBackupCounter( r ) { $( "#secupress-available-backups" ).text( r.data.countText ); } function secupressUpdateBackupVisibility() { if ( 0 === $( "#form-delete-backups" ).find( ".secupress-large-row" ).length ) { $( "#form-delete-backups" ).hide(); $( "#secupress-no-backups" ).show(); } else { $( "#secupress-no-backups" ).hide(); $( "#form-delete-backups" ).show(); } } // Delete all backups. function secupressDeleteAllBackups( $button, href ) { secupressDisableAjaxButton( $button, SecuPressi18nModules.deletingAllText, "backup" ); $.getJSON( href ) .done( function( r ) { var $fieldset, $legend; if ( $.isPlainObject( r ) && r.success ) { swal2.close(); $fieldset = $button.closest( "form" ).find( "fieldset" ); $legend = $fieldset.children( "legend" ); $fieldset.text( "" ).prepend( $legend ); secupressUpdateBackupVisibility(); secupressEnableAjaxButton( $button, SecuPressi18nModules.deletedAllText, "backup" ); } else { secupressDisplayAjaxError( $button, SecuPressi18nModules.deleteAllImpossible, "backup" ); } } ) .fail( function() { secupressDisplayAjaxError( $button, null, "backup" ); } ); } // Delete one backup. function secupressDeleteOneBackup( $button, href ) { secupressDisableAjaxButton( $button, SecuPressi18nModules.deletingOneText, "backup" ); $.getJSON( href ) .done( function( r ) { if ( $.isPlainObject( r ) && r.success ) { swal2.close(); $button.closest( ".secupress-large-row" ).css( "backgroundColor", SecuPress.deletedRowColor ).hide( "normal", function() { $( this ).remove(); secupressUpdateAvailableBackupCounter( r ); secupressUpdateBackupVisibility(); SecuPress.doingAjax.backup = false; } ); if ( wp.a11y && wp.a11y.speak ) { wp.a11y.speak( SecuPressi18nModules.deletedOneText ); } } else { secupressDisplayAjaxError( $button, SecuPressi18nModules.deleteOneImpossible, "backup" ); } } ) .fail( function() { secupressDisplayAjaxError( $button, null, "backup" ); } ); } // Do a DB backup. function secupressDoDbBackup( $button, href ) { secupressDisableAjaxButton( $button, SecuPressi18nModules.backupingText, 'backup' ); $.post( href, $button.closest( "form" ).serializeArray() ) .done( function( r ) { if ( $.isPlainObject( r ) ) { if ( r.success ) { $( r.data.elemRow ).addClass( "hidden" ).css( "backgroundColor", SecuPress.addedRowColor ).insertAfter( "#form-delete-backups legend" ).show( "normal", function() { $( this ).css( "backgroundColor", "" ); } ); secupressUpdateAvailableBackupCounter( r ); secupressUpdateBackupVisibility(); secupressEnableAjaxButton( $button, SecuPressi18nModules.backupedText, "backup" ); } else { r.data = r.data ? r.data : SecuPressi18nModules.backupImpossible; secupressDisplayAjaxError( $button, r.data, "backup" ); } } else { secupressDisplayAjaxError( $button, SecuPressi18nModules.backupImpossible, "backup" ); } } ) .fail( function() { secupressDisplayAjaxError( $button, null, "backup" ); } ); } // Do a files backup. function secupressDoFilesBackup( $button, href ) { secupressDisableAjaxButton( $button, SecuPressi18nModules.backupingText, 'backup' ); $.post( href, $button.closest( "form" ).serializeArray() ) .done( function( r ) { if ( $.isPlainObject( r ) ) { if ( r.success ) { $( r.data.elemRow ).addClass( "hidden" ).css( "backgroundColor", SecuPress.addedRowColor ).insertAfter( "#form-delete-backups legend" ).show( "normal", function() { $( this ).css( "backgroundColor", "" ); } ); secupressUpdateAvailableBackupCounter( r ); secupressUpdateBackupVisibility(); $( "#ignored_directories" ).val( r.data.ignoredFiles ); secupressEnableAjaxButton( $button, SecuPressi18nModules.backupedText, "backup" ); } else { r.data = r.data ? r.data : SecuPressi18nModules.backupImpossible; secupressDisplayAjaxError( $button, r.data, "backup" ); } } else { secupressDisplayAjaxError( $button, SecuPressi18nModules.backupImpossible, "backup" ); } } ) .fail( function() { secupressDisplayAjaxError( $button, null, "backup" ); } ); } // Ajax call that delete all backups. $( "#submit-delete-backups" ).on( "click.secupress", function( e ) { var $this = $( this ), href = secupressPreAjaxCall( $this.closest( "form" ).attr( "action" ), e ); if ( ! href ) { return; } if ( "function" === typeof w.swal2 ) { swal2( $.extend( {}, SecuPress.swal2Defaults, SecuPress.swal2ConfirmDefaults, { text: SecuPressi18nModules.confirmDeleteBackups, confirmButtonText: SecuPressi18nModules.yesDeleteAll, type: "question", reverseButtons: true } ) ).then( function ( isConfirm ) { if ( isConfirm ) { swal2.enableLoading(); secupressDeleteAllBackups( $this, href ); } } ); } else if ( w.confirm( SecuPressi18nModules.confirmTitle + "\n" + SecuPressi18nModules.confirmDeleteBackups ) ) { secupressDeleteAllBackups( $this, href ); } } ).removeAttr( "disabled aria-disabled" ); // Ajax call that delete one Backup. $( "body" ).on( "click.secupress keyup", ".a-delete-backup", function( e ) { var $this = $( this ), href = secupressPreAjaxCall( $this.attr( "href" ), e ); if ( ! href ) { return; } if ( "function" === typeof w.swal2 ) { swal2( $.extend( {}, SecuPress.swal2Defaults, SecuPress.swal2ConfirmDefaults, { text: SecuPressi18nModules.confirmDeleteBackup, confirmButtonText: SecuPressi18nModules.yesDeleteOne, type: "question", reverseButtons: true } ) ).then( function ( isConfirm ) { if ( isConfirm ) { swal2.enableLoading(); secupressDeleteOneBackup( $this, href ); } } ); } else if ( w.confirm( SecuPressi18nModules.confirmTitle + "\n" + SecuPressi18nModules.confirmDeleteBackup ) ) { secupressDeleteOneBackup( $this, href ); } } ); // Ajax call that does a DB Backup. $( "#submit-backup-db" ).on( "click.secupress", function( e ) { var $this = $( this ), href = secupressPreAjaxCall( $this.closest( "form" ).attr( "action" ), e ); if ( href ) { secupressDoDbBackup( $this, href ); } } ).removeAttr( 'disabled aria-disabled' ); // Ajax call that does a files Backup. $( "#submit-backup-files" ).on( "click.secupress", function( e ) { var $this = $( this ), href = secupressPreAjaxCall( $this.closest( "form" ).attr( "action" ), e ); if ( href ) { secupressDoFilesBackup( $this, href ); } } ).removeAttr( 'disabled aria-disabled' ); } )(jQuery, document, window); // Countries ======================================================================================= (function($, d, w, undefined) { function secupress_set_indeterminate_state( code ) { var all_boxes = $( "[data-code-country='" + code + "']" ).length, checked_boxes = $( "[data-code-country='" + code + "']:checked" ).length; if ( checked_boxes === all_boxes ) { $( "[value='continent-" + code + "']" ).prop( { "checked": true, "indeterminate": false } ).css( "-webkit-appearance", "none" ); } else if ( 0 === checked_boxes ) { $( "[value='continent-" + code + "']" ).prop( { "checked": false, "indeterminate": false } ).css( "-webkit-appearance", "none" ); } else { $( "[value='continent-" + code + "']" ).prop( { "checked": false, "indeterminate": true } ).css( "-webkit-appearance", "checkbox" ); } } $( ".continent input" ).on( "click.secupress", function( e ) { var $this = $( this ), val = $this.css( "-webkit-appearance", "none" ).val().replace( "continent-", "" ); $( ".depends-geoip-system_type_blacklist.depends-geoip-system_type_whitelist [data-code-country='" + val + "']" ).prop( "checked", $this.is( ":checked" ) ); } ); $( "[data-code-country]" ).on( "click.secupress", function( e ) { var code = $( this ).data( "code-country" ); secupress_set_indeterminate_state( code ); } ); $( ".continent input" ).each( function( i ) { var code = $( this ).val().replace( "continent-", "" ); secupress_set_indeterminate_state( code ); } ); $( ".expand_country" ).on( "click.secupress", function( e ) { $( this ).next( "fieldset" ).toggleClass( "hide-if-js" ); } ); } )(jQuery, document, window); // Banned IPs ====================================================================================== (function($, d, w, undefined) { var $row = $( "#banned-ips-row" ), $banForm, banUrl; if ( ! $row.length ) { return; } // Empty the list, display a message in a placeholder (a row in the list), and maybe hide the search form and the "Clear all IPs" button. function secupressBannedIPsEmptyList( message, resetSearch ) { var $form; if ( undefined === message || ! message ) { message = SecuPressi18nModules.noBannedIPs; } // Remove all rows from the list and display the placeholder. $row.find( "#secupress-banned-ips-list" ).html( '
  • ' + message + "
  • " ); if ( undefined !== resetSearch && ! resetSearch ) { return; } // Hide the "Clear all IPs" button and spinner. $row.find( "#secupress-clear-ips-button" ).next().addBack().addClass( "hidden" ); // Hide and reset the search form. $form = $row.find( "#form-search-ip" ).addClass( "hidden" ); // Reset the form. $form.find( "#reset-banned-ips-list" ).next().addBack().addClass( "hidden" ); $form.find( "#secupress-search-banned-ip" ).val( "" ); } // Fill in the list. function secupressBannedIPsFillList( data, replace ) { var $list = $row.find( "#secupress-banned-ips-list" ), template = '
  • %ip% (%time%)' + SecuPressi18nModules.delete + '
  • ', isSearch = ! $( "#reset-banned-ips-list" ).hasClass( "hidden" ), out = ""; if ( undefined === replace || replace ) { // We will replace the list content. replace = true; $list.html( "" ); } if ( undefined === data || ! data.length ) { // No data. if ( replace ) { // We must display a placeholder with a message. if ( typeof replace === "string" ) { secupressBannedIPsEmptyList( replace ); } else if ( isSearch ) { secupressBannedIPsEmptyList( SecuPressi18nModules.IPnotFound, false ); } else { secupressBannedIPsEmptyList(); } } return; } // Build the rows html. $.each( data, function( i, v ) { out += template.replace( /%ip%/g, v.ip ).replace( /%time%/g, v.time ).replace( /%unban_url%/g, v.unban_url ); } ); // Insert the rows. $list.append( out ); } // Perform an ajax call to ban an IP address. function secupressBanIP( $button, href ) { var params = { "ip": $( "#secupress-ban-ip" ).val() }; if ( ! params.ip ) { secupressBanIPswal2( $button, href ); return; } secupressDisableAjaxButton( $button, null, "ban-ip" ); $.getJSON( href, params ) .done( function( r ) { var message; if ( ! $.isPlainObject( r ) || ! r.data || ! $.isPlainObject( r.data ) ) { secupressDisplayAjaxError( $button, SecuPressi18nModules.error, "ban-ip" ); return; } if ( ! r.success ) { message = r.data.message ? r.data.message : null; secupressDisplayAjaxError( $button, message, "ban-ip" ); return; } // Remove the placeholder if it exists. $row.find( "#secupress-banned-ips-list" ).children( "#no-ips" ).remove(); // Add a new row in the list. secupressBannedIPsFillList( r.data.tmplValues, false ); // Display the search form. $row.find( "#form-search-ip" ).removeClass( "hidden" ); // Display the "Clear all IPs" button. $row.find( "#secupress-clear-ips-button" ).next().addBack().removeClass( "hidden" ); secupressDisplayAjaxSuccess( $button, r.data.message, "ban-ip" ); } ) .fail( function() { secupressDisplayAjaxError( $button, null, "ban-ip" ); } ); } // swal2 that displays the form to ban an IP address. function secupressBanIPswal2( $button, href ) { // jshint ignore:line swal2( $.extend( {}, SecuPress.swal2Defaults, SecuPress.swal2ConfirmDefaults, { title: $banForm.find( '[for="secupress-ban-ip"]' ).text(), confirmButtonText: $button.data( "original-i18n" ), html: $banForm, type: "info" } ) ).then( function ( isConfirm ) { if ( isConfirm ) { swal2.enableLoading(); secupressBanIP( $button, href ); } } ); } // Reset buttons on page load. $row.find( "button" ).removeAttr( "disabled aria-disabled" ); // The form to ban an IP address. $banForm = $row.find( "#form-ban-ip" ).remove(); banUrl = $banForm.attr( "action" ); $banForm = $banForm.children().wrapAll( "
    " ).parent(); $banForm.find( "[type='submit']" ).remove(); // Reset search. $row.on( "click.secupress keyup", "#reset-banned-ips-list", function( e ) { var $this = $( this ), href = secupressPreAjaxCall( d.location.href, e, "ban-ip" ); if ( ! href ) { return; } secupressDisableAjaxButton( $this, null, "ban-ip" ); $row.load( href + " #banned-ips-row > th, #banned-ips-row > td", function() { $row.find( "#form-ban-ip" ).remove(); $row.find( "#secupress-search-banned-ip" ).focus(); secupressEnableAjaxButton( $this, SecuPressi18nModules.searchReset, "ban-ip" ); } ); } ); // Ban an IP address. $row.on( "click.secupress keyup", "#secupress-ban-ip-button", function( e ) { var $this = $( this ), href = secupressPreAjaxCall( banUrl, e, "ban-ip" ); if ( href ) { secupressBanIPswal2( $this, href ); $("#secupress-ban-ip").focus().val(''); } } ); // Unban an IP address. $row.on( "click.secupress keyup", ".a-unban-ip", function( e ) { var $this = $( this ), href = secupressPreAjaxCall( $this.attr( "href" ), e, "ban-ip" ); if ( ! href ) { return; } secupressDisableAjaxButton( $this, null, "ban-ip" ); $.getJSON( href ) .done( function( r ) { var $list, $li, message; if ( ! $.isPlainObject( r ) || ! r.data || ! $.isPlainObject( r.data ) ) { secupressDisplayAjaxError( $this, SecuPressi18nModules.error, "ban-ip" ); return; } if ( ! r.success ) { message = r.data.message ? r.data.message : null; secupressDisplayAjaxError( $this, message, "ban-ip" ); return; } // Remove the row from the list. $li = $this.closest( ".secupress-large-row" ); $list = $li.parent(); $li.remove(); // The list is empty. if ( ! $list.children().length ) { if ( $( "#reset-banned-ips-list" ).hasClass( "hidden" ) ) { // It's not a search. secupressBannedIPsEmptyList(); } else { // It's a search. secupressBannedIPsEmptyList( SecuPressi18nModules.IPremoved, false ); } } secupressDisplayAjaxSuccess( $this, r.data.message, "ban-ip" ); } ) .fail( function() { secupressDisplayAjaxError( $this, null, "ban-ip" ); } ); } ); // Unban all IP addresses. $row.on( "click.secupress keyup", "#secupress-clear-ips-button", function( e ) { var $this = $( this ), href = secupressPreAjaxCall( $this.attr( "href" ), e, "ban-ip" ); if ( ! href ) { return; } secupressDisableAjaxButton( $this, null, "ban-ip" ); $.getJSON( href ) .done( function( r ) { var $list = $this.siblings( "#secupress-banned-ips-list" ), message; if ( ! $.isPlainObject( r ) || ! r.data || ! $.isPlainObject( r.data ) ) { secupressDisplayAjaxError( $this, SecuPressi18nModules.error, "ban-ip" ); return; } if ( ! r.success ) { message = r.data.message ? r.data.message : null; secupressDisplayAjaxError( $this, message, "ban-ip" ); return; } // Remove all rows from the list, display the placeholder, etc. secupressBannedIPsEmptyList(); secupressDisplayAjaxSuccess( $this, r.data.message, "ban-ip" ); } ) .fail( function() { secupressDisplayAjaxError( $this, null, "ban-ip" ); } ); } ); } )(jQuery, document, window); // Whitelist IPs ====================================================================================== (function($, d, w, undefined) { var $row = $( "#whitelist-ips-row" ), $whiteForm, whiteUrl; if ( ! $row.length ) { return; } // Empty the list, display a message in a placeholder (a row in the list), and maybe hide the search form and the "Clear all IPs" button. function secupressWhitelistIPsEmptyList( message, resetSearch ) { var $form; if ( undefined === message || ! message ) { message = SecuPressi18nModules.noWhitelistIPs; } // Remove all rows from the list and display the placeholder. $row.find( "#secupress-whitelist-ips-list" ).html( '
  • ' + message + "
  • " ); if ( undefined !== resetSearch && ! resetSearch ) { return; } // Hide the "Clear all IPs" button and spinner. $row.find( "#secupress-clear-whitelist-ips-button" ).next().addBack().addClass( "hidden" ); // Hide and reset the search form. $form = $row.find( "#form-search-whitelist-ip" ).addClass( "hidden" ); // Reset the form. $form.find( "#reset-whitelist-ips-list" ).next().addBack().addClass( "hidden" ); $form.find( "#secupress-search-whitelist-ip" ).val( "" ); } // Fill in the list. function secupressWhitelistIPsFillList( data, replace ) { var $list = $row.find( "#secupress-whitelist-ips-list" ), template = '
  • %ip% ' + SecuPressi18nModules.delete + '
  • ', isSearch = ! $( "#reset-whitelist-ips-list" ).hasClass( "hidden" ), out = ""; if ( undefined === replace || replace ) { // We will replace the list content. replace = true; $list.html( "" ); } if ( undefined === data || ! data.length ) { // No data. if ( replace ) { // We must display a placeholder with a message. if ( typeof replace === "string" ) { secupressWhitelistIPsEmptyList( replace ); } else if ( isSearch ) { secupressWhitelistIPsEmptyList( SecuPressi18nModules.IPnotFound, false ); } else { secupressWhitelistIPsEmptyList(); } } return; } // Build the rows html. $.each( data, function( i, v ) { out += template.replace( /%ip%/g, v.ip ).replace( /%unwhitelist_url%/g, v.unwhitelist_url ); } ); // Insert the rows. $list.append( out ); } // Perform an ajax call to ban an IP address. function secupressWhitelistIP( $button, href ) { var params = { "ip": $( "#secupress-whitelist-ip" ).val() }; if ( ! params.ip ) { secupressWhitelistIPswal2( $button, href ); return; } secupressDisableAjaxButton( $button, null, "whitelist-ip" ); $.getJSON( href, params ) .done( function( r ) { var message; if ( ! $.isPlainObject( r ) || ! r.data || ! $.isPlainObject( r.data ) ) { secupressDisplayAjaxError( $button, SecuPressi18nModules.error, "whitelist-ip" ); return; } if ( ! r.success ) { message = r.data.message ? r.data.message : null; secupressDisplayAjaxError( $button, message, "whitelist-ip" ); return; } // Remove the placeholder if it exists. $row.find( "#secupress-whitelist-ips-list" ).children( "#no-whitelist-ips" ).remove(); // Add a new row in the list. secupressWhitelistIPsFillList( r.data.tmplValues, false ); // Display the search form. $row.find( "#form-search-whitelist-ip" ).removeClass( "hidden" ); // Display the "Clear all IPs" button. $row.find( "#secupress-clear-whitelist-ips-button" ).next().addBack().removeClass( "hidden" ); secupressDisplayAjaxSuccess( $button, r.data.message, "whitelist-ip" ); } ) .fail( function() { secupressDisplayAjaxError( $button, null, "whitelist-ip" ); } ); } // swal2 that displays the form to ban an IP address. function secupressWhitelistIPswal2( $button, href ) { // jshint ignore:line swal2( $.extend( {}, SecuPress.swal2Defaults, SecuPress.swal2ConfirmDefaults, { title: $whiteForm.find( '[for="secupress-whitelist-ip"]' ).text(), confirmButtonText: $button.data( "original-i18n" ), html: $whiteForm, type: "info" } ) ).then( function ( isConfirm ) { if ( isConfirm ) { swal2.enableLoading(); secupressWhitelistIP( $button, href ); } } ); } // Reset buttons on page load. $row.find( "button" ).removeAttr( "disabled aria-disabled" ); // The form to ban an IP address. $whiteForm = $row.find( "#form-whitelist-ip" ).remove(); whiteUrl = $whiteForm.attr( "action" ); $whiteForm = $whiteForm.children().wrapAll( "
    " ).parent(); $whiteForm.find( "[type='submit']" ).remove(); // Reset search. $row.on( "click.secupress keyup", "#reset-whitelist-ips-list", function( e ) { var $this = $( this ), href = secupressPreAjaxCall( d.location.href, e, "whitelist-ip" ); if ( ! href ) { return; } secupressDisableAjaxButton( $this, null, "whitelist-ip" ); $row.load( href + " #whitelist-ips-row > th, #whitelist-ips-row > td", function() { $row.find( "#form-whitelist-ip" ).remove(); $row.find( "#secupress-search-whitelist-ip" ).focus(); secupressEnableAjaxButton( $this, SecuPressi18nModules.searchReset, "whitelist-ip" ); } ); } ); // Ban an IP address. $row.on( "click.secupress keyup", "#secupress-whitelist-ip-button", function( e ) { var $this = $( this ), href = secupressPreAjaxCall( whiteUrl, e, "whitelist-ip" ); if ( href ) { secupressWhitelistIPswal2( $this, href ); $("#secupress-whitelist-ip").focus().val(''); } } ); // Unban an IP address. $row.on( "click.secupress keyup", ".a-unwhitelist-ip", function( e ) { var $this = $( this ), href = secupressPreAjaxCall( $this.attr( "href" ), e, "whitelist-ip" ); if ( ! href ) { return; } secupressDisableAjaxButton( $this, null, "whitelist-ip" ); $.getJSON( href ) .done( function( r ) { var $list, $li, message; if ( ! $.isPlainObject( r ) || ! r.data || ! $.isPlainObject( r.data ) ) { secupressDisplayAjaxError( $this, SecuPressi18nModules.error, "whitelist-ip" ); return; } if ( ! r.success ) { message = r.data.message ? r.data.message : null; secupressDisplayAjaxError( $this, message, "whitelist-ip" ); return; } // Remove the row from the list. $li = $this.closest( ".secupress-large-row" ); $list = $li.parent(); $li.remove(); // The list is empty. if ( ! $list.children().length ) { if ( $( "#reset-whitelist-ips-list" ).hasClass( "hidden" ) ) { // It's not a search. secupressWhitelistIPsEmptyList(); } else { // It's a search. secupressWhitelistIPsEmptyList( SecuPressi18nModules.IPremoved, false ); } } secupressDisplayAjaxSuccess( $this, r.data.message, "whitelist-ip" ); } ) .fail( function() { secupressDisplayAjaxError( $this, null, "whitelist-ip" ); } ); } ); // Unban all IP addresses. $row.on( "click.secupress keyup", "#secupress-clear-whitelist-ips-button", function( e ) { var $this = $( this ), href = secupressPreAjaxCall( $this.attr( "href" ), e, "whitelist-ip" ); if ( ! href ) { return; } secupressDisableAjaxButton( $this, null, "whitelist-ip" ); $.getJSON( href ) .done( function( r ) { var $list = $this.siblings( "#secupress-whitelist-ips-list" ), message; if ( ! $.isPlainObject( r ) || ! r.data || ! $.isPlainObject( r.data ) ) { secupressDisplayAjaxError( $this, SecuPressi18nModules.error, "whitelist-ip" ); return; } if ( ! r.success ) { message = r.data.message ? r.data.message : null; secupressDisplayAjaxError( $this, message, "whitelist-ip" ); return; } // Remove all rows from the list, display the placeholder, etc. secupressWhitelistIPsEmptyList(); secupressDisplayAjaxSuccess( $this, r.data.message, "whitelist-ip" ); } ) .fail( function() { secupressDisplayAjaxError( $this, null, "whitelist-ip" ); } ); } ); } )(jQuery, document, window); // Auto Expand Textarea ============================================================================ (function($) { var SPautoSized = {}, browsers = {}, // Expandable items. $expandables = $('.secupress-textarea-container'), hCheck; browsers.msie = /msie/.test( navigator.userAgent.toLowerCase() ); browsers.opera = /opera/.test( navigator.userAgent.toLowerCase() ); hCheck = ! ( browsers.msie || browsers.opera ); // Function to resize textarea. SPautoSized.resize = function( e, init ) { var vlen, ewidth, h, $textarea, $container; // e = event or element? e = e.target || e; // Content length and box width. vlen = e.value.length; ewidth = e.offsetWidth; if ( vlen !== e.valLength || ewidth !== e.boxWidth ) { if ( hCheck && ( vlen < e.valLength || ewidth !== e.boxWidth ) ) { e.style.height = '0px'; } h = Math.max( e.expandMin, Math.min( e.scrollHeight, e.expandMax ) ); $textarea = $( e ); $container = $textarea.closest( '.secupress-textarea-container' ); e.style.overflow = 'hidden'; e.style.height = h + 'px'; e.valLength = vlen; e.boxWidth = ewidth; // Resize the container. SPautoSized.textareaParentHeight( $container, $textarea ); // Add (+) button. if ( e.scrollHeight > $container.height() && $container.next() ) { SPautoSized.handleExpandButton( $container, true ); // Create. } else if ( e.scrollHeight <= $container.height() && $container.next('.secupress-expand-trigger-container').find('.open').length === 0 ) { SPautoSized.handleExpandButton( $container, false ); // Remove. } } return true; }; // Function to resize textarea parent. SPautoSized.textareaParentHeight = function( $container, $textarea ) { $container.css( 'height', $textarea.outerHeight() + $container.outerHeight() - $container.height() ); return true; }; // Function to create (+) button. SPautoSized.handleExpandButton = function( $container, create ) { // If creation needed, check if exists, or create it. if ( ! $container.next( '.secupress-expand-trigger-container' ).length && create ) { $container.after( SecuPress.expandButton ).attr( 'spellcheck', false ); } else if ( $container.next( '.secupress-expand-trigger-container' ).length && false === create ) { $container.next( '.secupress-expand-trigger-container' ).remove(); } }; // jQuery definition. $.fn.AutoSized = function( minHeight, maxHeight ) { this.each( function() { // Is a textarea? if ( this.nodeName.toLowerCase() !== 'textarea' ) { return; } // Height restriction. this.expandMin = minHeight || 0; this.expandMax = maxHeight || 99999; // Initial resize SPautoSized.resize( this, this.Initialized ); // Resize on write. if ( ! this.Initialized ) { this.Initialized = true; $( this ).css( { 'padding-top' : '0', 'padding-bottom' : '0' } ) .on('keyup.secupress focus.secupress', SPautoSized.resize ); } } ); return this; }; // Move to end. $.fn.focusToEnd = function() { return this.each( function() { var v = $( this ).val(); $( this ).focus().val( '' ).val( v ); } ); }; // Change class on parent textarea on focus/blur. // Applied only on visible elements (see below for others). $expandables.filter( ':visible' ).find( 'textarea' ).AutoSized() .on( 'focus.secupress', function() { $( this ).parent().addClass( 'textarea-focused' ); } ) .on( 'blur.secupress', function() { $( this ).parent().removeClass( 'textarea-focused' ); } ); // Same action as previous for textarea depending on other actions to be displayed. $( '#wpbody-content' ).find( '.secupress-setting-row' ).on( 'secupressaftershow', function() { $( this ).find( '.secupress-textarea-container' ).find( 'textarea' ).AutoSized() .on('focus.secupress', function() { $( this ).parent().addClass( 'textarea-focused' ); } ) .on( 'blur.secupress', function() { $( this ).parent().removeClass( 'textarea-focused' ); } ); } ); // On click on (+) button. $expandables.closest( 'label, .secupress-setting-content-col' ).on( 'click.secupress', '.secupress-expand-trigger', function() { var $_this = $( this ), $container = $_this.closest( '.secupress-expand-trigger-container' ).prev( '.secupress-textarea-container' ), $textarea = $container.find( 'textarea' ); if ( $_this.hasClass( 'open' ) ) { $container.css( 'height', '200px' ); $_this.removeClass( 'open' ); $_this.find( '.secupress-expand-txt' ).text( SecuPressi18nModules.expandTextOpen ); $_this.find( 'i' ).removeClass( 'secupress-icon-angle-up' ).addClass( 'secupress-icon-angle-down' ); // Scroll to the top of the box on close. $( 'html, body' ).animate( { scrollTop: $container.offset().top - 80 // 80 to be slightly over the box. }, 275 ); } else { SPautoSized.textareaParentHeight( $container, $textarea ); $textarea.focusToEnd(); $_this.addClass( 'open' ); $_this.find( '.secupress-expand-txt' ).text( SecuPressi18nModules.expandTextClose ); $_this.find( 'i' ).removeClass( 'secupress-icon-angle-down' ).addClass( 'secupress-icon-angle-up' ); } return false; } ); } )(jQuery); // Auto Expand Boxed Groups ======================================================================== (function($) { $( 'fieldset.secupress-boxed-group' ).each( function() { var $box = $( this ), maxHeight = 200; $box.data( 'height', $box.outerHeight() ) .css( 'height', maxHeight ) .after( SecuPress.expandButton ); $box.next( '.secupress-expand-trigger-container' ).on( 'click.secupress', function() { var $this = $( this ); if ( $this.hasClass( 'open' ) ) { $box.css( 'height', maxHeight ); $this.removeClass( 'open' ); $this.find( '.secupress-expand-txt' ).text( SecuPressi18nModules.expandTextOpen ); $this.find( 'i' ).removeClass( 'secupress-icon-angle-up' ).addClass( 'secupress-icon-angle-down' ); // scroll to the top of the box on close. $('html, body').animate({ scrollTop: $box.offset().top - 80 // 80 to be slightly over the box. }, 275 ); } else { $box.css( 'height', $box.data( 'height' ) ); $this.addClass( 'open' ); $this.find( '.secupress-expand-txt' ).text( SecuPressi18nModules.expandTextClose ); $this.find( 'i' ).removeClass( 'secupress-icon-angle-down' ).addClass( 'secupress-icon-angle-up' ); } return false; } ); } ); } )(jQuery); // Malware Scan Status ============================================================================= (function($, d, w, undefined) { if ( undefined !== SecuPressi18nModules && 'on' === SecuPressi18nModules.malwareScanStatus ) { $( d ).on( 'heartbeat-send', function( e, data ) { data.secupress_heartbeat_malware_scan = 'malwareScanStatus'; } ) // Listen for the custom event "heartbeat-tick" on $(document). .on( 'heartbeat-tick', function( e, data ) { // Only proceed if our data is present. if ( data.malwareScanStatus ) { w.location.href = SecuPressi18nModules.MalwareScanURI; } } ); } } )(jQuery, document, window); // Malware Scan "Select all" ======================================================================= (function( w, d, $, undefined ) { var lastClicked = {}, jqPropHookChecked = $.propHooks.checked; // Force `.prop()` to trigger a `change` event. $.propHooks.checked = { set: function( elem, value, name ) { var ret; if ( undefined === jqPropHookChecked ) { ret = ( elem[ name ] = value ); } else { ret = jqPropHookChecked( elem, value, name ); } $( elem ).trigger( 'change.secupress' ); return ret; } }; // Check all checkboxes. $( '.secupress-check-group .secupress-row-check' ).on( 'click', function( e ) { var $group = $( this ).closest( '.secupress-check-group' ), allChecked = 0 === $group.find( '.secupress-row-check' ).filter( ':visible:enabled' ).not( ':checked' ).length; // Toggle "check all" checkboxes. $group.find( '.secupress-toggle-check' ).prop( 'checked', allChecked ); } ) .first().trigger( 'change.secupress' ); $( '.secupress-check-group .secupress-toggle-check' ).on( 'click.wp-toggle-checkboxes', function( e ) { var $this = $( this ), $wrap = $this.closest( '.secupress-check-group' ), controlChecked = $this.prop( 'checked' ), toggle = e.shiftKey || $this.data( 'wp-toggle' ); $wrap.find( '.secupress-toggle-check' ) .prop( 'checked', function() { var $this = $( this ); if ( $this.is( ':hidden,:disabled' ) ) { return false; } if ( toggle ) { return ! $this.prop( 'checked' ); } return controlChecked ? true : false; } ); $wrap.find( '.secupress-row-check' ) .prop( 'checked', function() { if ( toggle ) { return false; } return controlChecked ? true : false; } ); } ); } )(window, document, jQuery); // Checked checkbox class ========================================================================== (function($, d, w, undefined) { $( '.secupress-fieldset-item-checkboxes' ).each( function() { var $checkbox = $(this).find('input'), $label = $checkbox.closest( 'label' ); if ( $checkbox.filter(':checked').length ) { $label.addClass( 'is-checked' ); } $checkbox.on( 'change', function() { if ( $checkbox.filter(':checked').length ) { $label.addClass( 'is-checked' ); } else { $label.removeClass( 'is-checked' ); } } ); } ); } )(jQuery, document, window);