/** * Send an action over AJAX. A wrapper around jQuery.ajax. In future, all consumers can be reviewed to simplify some of the options, where there is historical cruft. * * @param {string} action - the action to send * @param {*} data - data to send * @param {Function} callback - will be called with the results * @param {object} options -further options. Relevant properties include: * - [json_parse=true] - whether to JSON parse the results * - [alert_on_error=true] - whether to show an alert box if there was a problem (otherwise, suppress it) * - [action='aios_ajax'] - what to send as the action parameter on the AJAX request (N.B. action parameter to this function goes as the 'subaction' parameter on the AJAX request) * - [nonce=aios_ajax_nonce] - the nonce value to send. * - [nonce_key='nonce'] - the key value for the nonce field * - [timeout=null] - set a timeout after this number of seconds (or if null, none is set) * - [async=true] - control whether the request is asynchronous (almost always wanted) or blocking (would need to have a specific reason) * - [type='POST'] - GET or POST */ function aios_send_command(action, data, callback, options) { var default_options = { json_parse: true, alert_on_error: true, action: 'aios_ajax', nonce: aios_data.ajax_nonce, nonce_key: 'nonce', timeout: null, async: true, type: 'POST' }; if ('undefined' === typeof options) options = {}; for (var opt in default_options) { if (!options.hasOwnProperty(opt)) { options[opt] = default_options[opt]; } } var ajax_data = { action: options.action, subaction: action }; ajax_data[options.nonce_key] = options.nonce; ajax_data.data = data; var ajax_opts = { type: options.type, url: ajaxurl, data: ajax_data, success: function(response, status) { if (options.json_parse) { try { var resp = aios_parse_json(response); } catch (e) { if ('function' == typeof options.error_callback) { return options.error_callback(response, e, 502, resp); } else { console.log(e); console.log(response); if (options.alert_on_error) { alert(aios_trans.unexpected_response+' '+response); } return; } } if (resp.hasOwnProperty('fatal_error')) { if ('function' == typeof options.error_callback) { // 500 is internal server error code return options.error_callback(response, status, 500, resp); } else { console.error(resp.fatal_error_message); if (options.alert_on_error) { alert(resp.fatal_error_message); } return false; } } if ('function' == typeof callback) callback(resp, status, response); } else { if ('function' == typeof callback) callback(response, status); } }, error: function(response, status, error_code) { if ('function' == typeof options.error_callback) { options.error_callback(response, status, error_code); } else { console.log("aios_send_command: error: "+status+" ("+error_code+")"); console.log(response); } }, dataType: 'text', async: options.async }; if (null != options.timeout) { ajax_opts.timeout = options.timeout; } jQuery.ajax(ajax_opts); } /** * Parse JSON string, including automatically detecting unwanted extra input and skipping it * * @param {string} json_mix_str - JSON string which need to parse and convert to object * @param {boolean} analyse - if true, then the return format will contain information on the parsing, and parsing will skip attempting to JSON.parse() the entire string (will begin with trying to locate the actual JSON) * * @throws SyntaxError|String (including passing on what JSON.parse may throw) if a parsing error occurs. * * @returns Mixed parsed JSON object. Will only return if parsing is successful (otherwise, will throw). If analyse is true, then will rather return an object with properties (mixed)parsed, (integer)json_start_pos and (integer)json_end_pos */ function aios_parse_json(json_mix_str, analyse) { analyse = ('undefined' === typeof analyse) ? false : true; // Just try it - i.e. the 'default' case where things work (which can include extra whitespace/line-feeds, and simple strings, etc.). if (!analyse) { try { var result = JSON.parse(json_mix_str); return result; } catch (e) { console.log('AIOS: Exception when trying to parse JSON (1) - will attempt to fix/re-parse based upon first/last curly brackets'); console.log(json_mix_str); } } var json_start_pos = json_mix_str.indexOf('{'); var json_last_pos = json_mix_str.lastIndexOf('}'); // Case where some php notice may be added after or before json string if (json_start_pos > -1 && json_last_pos > -1) { var json_str = json_mix_str.slice(json_start_pos, json_last_pos + 1); try { var parsed = JSON.parse(json_str); if (!analyse) { console.log('AIOS: JSON re-parse successful'); } return analyse ? { parsed: parsed, json_start_pos: json_start_pos, json_last_pos: json_last_pos + 1 } : parsed; } catch (e) { console.log('AIOS: Exception when trying to parse JSON (2) - will attempt to fix/re-parse based upon bracket counting'); var cursor = json_start_pos; var open_count = 0; var last_character = ''; var inside_string = false; // Don't mistake this for a real JSON parser. Its aim is to improve the odds in real-world cases seen, not to arrive at universal perfection. while ((open_count > 0 || cursor == json_start_pos) && cursor <= json_last_pos) { var current_character = json_mix_str.charAt(cursor); if (!inside_string && '{' == current_character) { open_count++; } else if (!inside_string && '}' == current_character) { open_count--; } else if ('"' == current_character && '\\' != last_character) { inside_string = inside_string ? false : true; } last_character = current_character; cursor++; } console.log("Started at cursor="+json_start_pos+", ended at cursor="+cursor+" with result following:"); console.log(json_mix_str.substring(json_start_pos, cursor)); try { var parsed = JSON.parse(json_mix_str.substring(json_start_pos, cursor)); console.log('AIOS: JSON re-parse successful'); return analyse ? { parsed: parsed, json_start_pos: json_start_pos, json_last_pos: cursor } : parsed; } catch (e) { // Throw it again, so that our function works just like JSON.parse() in its behaviour. throw e; } } } throw "AIOS: could not parse the JSON"; } /** * Updates the content of an HTML element identified by its ID with the provided badge text. * * @param {Array} badges - An array of objects representing badges to update. * @param {string} badges.id - The ID of the HTML element to update. * @param {string} badges.html - The HTML content to set for the element. * @returns {void} */ function aios_update_badge(badges) { badges.forEach(function(badge) { aios_update_content(badge.id, badge.html); }); } /** * Update the content of an element with the specified HTML. * * @param {string} id - The ID of the element to update. * @param {string} html - The HTML content to set for the element. * @returns {void} */ function aios_update_content(id, html) { jQuery(id).html(html); } /** * Function to block the UI and display a loading message. * Uses jQuery blockUI plugin. * * @param {string} message - A string to be shown when function is called * * @returns {void} */ function aios_block_ui(message = aios_trans.saving) { jQuery.blockUI({ css: { width: '500px', border: 'none', 'border-radius': '10px', left: 'calc(50% - 250px)', top: 'calc(50% - 150px)', padding: '20px' }, message: '
'+ aios_trans.processing + '
'); jQuery('#aiowps_activejobs_table .aiowps_spinner').addClass('visible'); }, function(response) { var loading_span = jQuery('#aiowps_activejobs_table'); loading_span.hide(); }); }) jQuery('#aios-frame-display-settings-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_save_frame_display_prevent'); }) jQuery('#aios-copy-protection-settings-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this),'perform_save_copy_protection'); }) //End of Filesystem menu ajaxify // Firewall menu ajaxify jQuery('#aios-php-firewall-settings-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_php_firewall_settings', true, aios_trans.saving, null, function(response) { if ("success" === response.status) { jQuery('.aio_orange_box').remove(); if (jQuery('#aiowps_enable_6g_firewall').prop('checked')) { jQuery('.aios-toggle-advanced-options').removeClass('advanced-options-disabled'); jQuery('.aios-advanced-options-panel .aiowps_more_info_body').hide(); toggleMoreInfo('.aios-advanced-options-panel .aiowps_more_info_anchor'); } else { jQuery('.aios-toggle-advanced-options').addClass('advanced-options-disabled'); jQuery('.button.button-link.aios-toggle-advanced-options').removeClass('opened'); } check_input(); jQuery('#post-body h2:first').after(response.extra_args.xmlprc_warning); } }); }); jQuery('#aios-htaccess-firewall-settings-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this),'perform_htaccess_firewall_settings'); }); jQuery("#aios-blacklist-settings-form").on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this),'perform_save_blacklist_settings'); }); jQuery("#aios-firewall-allowlist-form").on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this),'perform_firewall_allowlist'); }); jQuery("#aios-5g-firewall-settings-form").on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_save_5g_settings') }); jQuery('#aiowps-firewall-status-container').on('submit', "#aiowpsec-firewall-setup-form", function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_setup_firewall', true, aios_trans.setting_up_firewall, null, function (response) { if (response.extra_args && response.extra_args.info_box) { jQuery("#aios-firewall-setup-notice").remove(); jQuery('#wpbody-content .wrap h2:first').after(response.extra_args.info_box); } }); }); jQuery('#aiowps-firewall-status-container').on('submit', "#aiowps-firewall-downgrade-form", function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_downgrade_firewall', true, aios_trans.downgrading_firewall, null, function (response) { if (response.extra_args && response.extra_args.info_box) { jQuery("#aios-firewall-installed-notice").remove(); jQuery('#wpbody-content .wrap h2:first').after(response.extra_args.info_box); } }); }); jQuery('#aios-upgrade-unsafe-http-calls-settings-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_save_upgrade_unsafe_http_calls_settings'); }) // end of firewall menu ajax // Start of file scan handling jQuery('.aiowps_next_scheduled_scan_wrapper').on('click', '.aiowps_view_last_fcd_results', view_scan_results_handler); jQuery('#aiowps_fcds_change_detected').on('click', '.aiowps_view_last_fcd_results', view_scan_results_handler); // start of user security menu ajax jQuery('#aios-user-accounts-settings-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_save_user_account_settings'); }); jQuery('#aios-change-admin-username-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_change_admin_username', true, aios_trans.saving, null, function (response) { if (response.hasOwnProperty('logout_user') && true === response.logout_user) { setTimeout(function() { // Check if a logout URL is present in the response if (response.hasOwnProperty('logout_url')) { // Redirect to the logout URL window.location.href = response.logout_url; } else { // If no logout URL is provided, reload the current page location.reload(); } }, 3000); } }); }); jQuery('#aios-user-login-lockdown-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_save_login_lockout_settings'); }); jQuery('#aios-user-login-lockout-whitelist-settings-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_save_login_lockout_whitelist_settings'); }); jQuery('#aios-force-user-logout-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_force_logout', true, aios_trans.saving, null, function (response) { if (response.hasOwnProperty('logout_user') && true === response.logout_user) { setTimeout(function() { // Check if a logout URL is present in the response if (response.hasOwnProperty('logout_url')) { // Redirect to the logout URL window.location.href = response.logout_url; } else { // If no logout URL is provided, reload the current page location.reload(); } }, 3000); } }); }); jQuery('#aios-hibp-password-settings-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_save_hibp_settings'); }); jQuery('#aios-disable-application-password-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_disable_application_password'); }); jQuery('#aios-enable-salt-postfix-form').submit(function (e) { e.preventDefault(); aios_submit_form(jQuery(this),'perform_add_salt_postfix', true, aios_trans.saving, null,function() { setTimeout(function () { location.reload(); }, 3000); }); }); jQuery('#aios-logged-in-users-table').on('click', '.aios-force-logout-user', function(e) { e.preventDefault(); let user_id = jQuery(this).data('user-id'), data = { logged_in_id: user_id, action: 'force_user_logout' }; if (confirm(jQuery(this).data('message'))) { aios_submit_form(jQuery(this), 'perform_logged_in_user_action', data, aios_trans.processing, null, function (response) { if ('success' === response.status) { jQuery('#aios-logged-in-users-table').load(' #aios-logged-in-users-table > *'); } }); } }); jQuery("#aios-refresh-logged-in-user-list-form").on('submit', function(e) { e.preventDefault(); aios_block_ui(aios_trans.refreshing); var submitButton = jQuery(this).find(':submit'); submitButton.prop('disabled', true); jQuery('#aios-logged-in-users-table').load(' #aios-logged-in-users-table > *', function () { jQuery.unblockUI(); submitButton.prop('disabled', false); }); }); jQuery('#aios-manually-approve-registrations-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_manual_approval_settings'); }); jQuery("#aios-manual-approval-table").on('click', '.aios-approve-user-acct', function(e) { e.preventDefault(); let user_id = jQuery(this).data('id'), data = { user_id: user_id, action: 'approve_acct' }; if (confirm(jQuery(this).data('message'))) { aios_submit_form(jQuery(this), 'perform_manual_approval_item_action', data, aios_trans.processing, null, function () { jQuery('#aios-manual-approval-table').load(' #aios-manual-approval-table > *'); }); } }); jQuery("#aios-manual-approval-table").on('click', '.aios-delete-user-acct', function(e) { e.preventDefault(); let user_id = jQuery(this).data('id'), data = { user_id: user_id, action: 'delete_acct' }; if (confirm(jQuery(this).data('message'))) { aios_submit_form(jQuery(this), 'perform_manual_approval_item_action', data, aios_trans.processing, null, function () { jQuery('#aios-manual-approval-table').load(' #aios-manual-approval-table > *'); }); } }); jQuery("#aios-manual-approval-table").on('click', '.aios-block-ip', function(e) { e.preventDefault(); let ip_address = jQuery(this).data('ip'), data = { ip_address: ip_address, action: 'block_ip' }; if (confirm(jQuery(this).data('message'))) { aios_submit_form(jQuery(this),'perform_manual_approval_item_action', data, aios_trans.blocking, null, function() { jQuery('#aios-manual-approval-table').load(' #aios-manual-approval-table > *'); }) } }); jQuery("#aios-refresh-manual-approval-list-form").on('submit', function(e) { e.preventDefault(); aios_block_ui(aios_trans.refreshing); var submitButton = jQuery(this).find(':submit'); submitButton.prop('disabled', true); jQuery('#aios-manual-approval-table').load(' #aios-manual-approval-table > *', function () { jQuery.unblockUI(); submitButton.prop('disabled', false); }); }); jQuery("#aios-enforce-strong-password-form").on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'enforce_strong_password'); }); // end of user security menu ajax // start of tools menu ajaxify jQuery("#aiowpsec-whois-lookup-form").on('submit', function(e) { e.preventDefault(); jQuery('#aios-who-is-lookup-result-container').html(''); aios_submit_form(jQuery(this), 'perform_whois_lookup', true, aios_trans.processing, null, function () { var targetOffset = jQuery('#aios-who-is-lookup-result-container').offset().top; jQuery('html, body').animate({ scrollTop: targetOffset }, 'slow'); }); }); jQuery("#aiowpsec-site-lockout-form").on('submit', function (e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_general_visitor_lockout', true, aios_trans.saving, function () { var editor = tinyMCE.get('aiowps_site_lockout_msg_editor_content'); if (editor) { editor.save(); } }); }); jQuery('#maintenance_mode_status').on('click', '#aiowps_site_lockout', function (e) { aios_block_ui(aios_trans.saving); var enabled = jQuery(this).is(':checked'); var data = {}; if (enabled) { data.aiowps_site_lockout = '1'; } aios_send_command('perform_general_visitor_lockout_dashboard_widget', data, function(response) { aios_show_ajax_response_message(response); if ('success' === response.status) { if (enabled) { jQuery("#aiowpsec-dashboard-maintenance-mode-status-message").text(aios_trans.maintenance_mode_enabled); } else { jQuery("#aiowpsec-dashboard-maintenance-mode-status-message").text(aios_trans.maintenance_mode_disabled); } } }); }); jQuery("#aiowpsec-save-custom-rules-settings-form").on('submit', function (e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_store_custom_htaccess_settings'); }); // end of tools menu ajaxify jQuery('#aiowpsec-scheduled-fcd-scan-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_save_file_detection_change_settings'); }); /** * This function handles the view last scan result event * * @param {*} e - the event */ function view_scan_results_handler(e) { e.preventDefault(); var reset_change_detected = jQuery(this).data('reset_change_detected') ? 1 : 0; aios_submit_form(jQuery(this), 'get_last_scan_results', { reset_change_detected: reset_change_detected}, aios_trans.processing, null, function (response) { if (reset_change_detected) jQuery('#aiowps_fcds_change_detected').remove(); var targetOffset = jQuery('#aiowps_previous_scan_wrapper').offset().top; jQuery('html, body').animate({ scrollTop: targetOffset }, 'slow'); }) } jQuery('#aiowps_manual_fcd_scan').on('click', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_file_scan', true, aios_trans.scanning, function () { jQuery('#aiowps_activejobs_table').html(''+ aios_trans.processing + '
'); jQuery('#aiowps_activejobs_table .aiowps_spinner').addClass('visible'); }, function (response) { jQuery('#aiowps_activejobs_table').html(''); if ('success' === response.status) { jQuery('#aiowps_activejobs_table').append(''+response.extra_args.result+'
'); } }); }); // End of file scan handling // start of brute force ajax jQuery('#aios-rename-login-page-form').on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_rename_login_page', true, aios_trans.saving, null,function(response) { if ("error" === response.status) { jQuery('#aiowps_enable_rename_login_page').prop('checked', false); } }) }); jQuery("#aios-cookie-based-settings-form").on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_cookie_based_brute_force_prevention', true, aios_trans.saving, null, function (response) { if ("success" === response.status) { jQuery('#aios_message').remove(); jQuery('#post-body .postbox').before(response.info_box); } }) }); jQuery("#aios-perform-cookie-test").on('click', function(e) { e.preventDefault(); var cookieButton = jQuery(this); cookieButton.prop('disabled', true); aios_submit_form(jQuery(this), 'perform_cookie_test', {}, aios_trans.processing, null,function(response) { cookieButton.prop('disabled', false); if ("success" === response.status) { var submitButton = jQuery('#aios-cookie-based-settings-form').find(':submit'); submitButton.prop('disabled', false); } }) }); jQuery("#aios-login-whitelist-settings-form").on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_login_whitelist_settings'); }); jQuery("#aios-honeypot-settings-form").on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_honeypot_settings'); }); jQuery("#aios-captcha-settings-form").on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_captcha_settings'); }); jQuery("#aios-404-detection-settings-form").on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_404_settings', true, aios_trans.saving, null, function(response) { if ("success" === response.status) { jQuery('.aios-404-detection-container').toggleClass('aio_hidden', !jQuery('#aiowps_enable_404_IP_lockout').is(':checked')); } }); }); jQuery("#aios-delete-404-form").on('submit', function(e) { e.preventDefault(); aios_submit_form(jQuery(this), 'perform_delete_404_event_records', true, aios_trans.deleting, null, function(response) { if ("success" === response.status) jQuery('#aios-404-event-logs-table').load(' #aios-404-event-logs-table > *', function () { jQuery(".aiowps_more_info_body").hide(); }); }); }); jQuery("#aios-404-event-logs-table").on('click', ".aios-delete-404", function(e) { e.preventDefault(); let data = { id: jQuery(this).data('id'), action: 'delete' }; if (confirm(jQuery(this).data('message'))) { aios_submit_form(jQuery(this), 'perform_404_log_item_action', data, aios_trans.deleting, null, function (response) { if ('success' === response.status) jQuery('#aios-404-event-logs-table').load(' #aios-404-event-logs-table > *'); }); } }); jQuery("#aios-404-event-logs-table").on('click', ".aios-temp-block-404", function(e) { e.preventDefault(); let ip = jQuery(this).data('ip'), username = jQuery(this).data('username'), data = { ip: ip, action: 'temp_block', username: username }; if (confirm(jQuery(this).data('message'))) { aios_submit_form(jQuery(this), 'perform_404_log_item_action', data, aios_trans.blocking, null, function (response) { if ('success' === response.status) jQuery('#aios-404-event-logs-table').load(' #aios-404-event-logs-table > *'); }); } }); jQuery("#aios-404-event-logs-table").on('click', ".aios-blacklist-404", function(e) { e.preventDefault(); let ip = jQuery(this).data('ip'), data = { ip: ip, action: 'blacklist' }; if (confirm(jQuery(this).data('message'))) { aios_submit_form(jQuery(this), 'perform_404_log_item_action', data, aios_trans.processing, null, function (response) { if ('success' === response.status) jQuery('#aios-404-event-logs-table').load(' #aios-404-event-logs-table > *'); }); } }); jQuery("#aios-404-event-logs-table").on('click', ".aios-unblock-404", function(e) { e.preventDefault(); let ip = jQuery(this).data('ip'), data = { ip: ip, action: 'unblock' }; if (confirm(jQuery(this).data('message'))) { aios_submit_form(jQuery(this), 'perform_404_log_item_action', data, aios_trans.unlocking, null, function (response) { if ('success' === response.status) jQuery('#aios-404-event-logs-table').load(' #aios-404-event-logs-table > *'); }); } }); // end of brute force ajax // Start of login whitelist suggests both IPv4 and IPv6 if (jQuery('#aios_user_ip_maybe_also').length) { var selector = '#aios-ipify-ip-address'; var ipfield = '#aios_user_ip_maybe_also'; var getting_text = jQuery(ipfield).attr('getting_text'); var ip_maybe = jQuery(ipfield).attr('ip_maybe'); if ('v6' == ip_maybe) { var url = 'https://api64.ipify.org/?format=json'; } else { var url = 'https://api.ipify.org/?format=json'; } jQuery(selector).html(getting_text); jQuery.ajax({ type: 'GET', dataType: 'json', url: url, success: function (response, status) { if (response.hasOwnProperty('ip') && response.ip != jQuery('#aiowps_user_ip').val()) { jQuery(ipfield).val(response.ip); jQuery(ipfield).removeClass('aio_hidden'); } else { console.log(response); } jQuery(selector).html(''); }, error: function (response, status, error_code) { console.log(response); jQuery(selector).html(''); } }); } // End of login whitelist suggests both IPv4 and IPv6 // Click the 'show/hide advanced options' button jQuery('button.button-link.aios-toggle-advanced-options').on('click', function() { if (!jQuery(this).hasClass('advanced-options-disabled')) { jQuery(this).toggleClass('opened'); } }); // Start of the new UI settings var initial_values = {}; jQuery('.aiowps-actions').hide(); /** * Set active tab from URL * * @param {string} subtab * * @returns {void} */ function set_active_tab_from_url() { const url_params = new URLSearchParams(window.location.search); const subtab = url_params.get('subtab'); if (subtab) { jQuery('.aiowps-rules li').removeClass('aiowps-active'); jQuery(`.aiowps-rules li[data-template="${subtab}"]`).addClass('aiowps-active'); jQuery('.aiowps-settings .postbox').hide(); jQuery(`.aiowps-settings .postbox[data-template="${subtab}"]`).show(); } else { jQuery('.aiowps-settings .postbox:first').show(); } } var initial_values = {}; /** * Store initial values of the settings * * @returns {void} */ function store_values() { jQuery('.aiowps-settings :input').each(function() { if (jQuery(this).is(':checkbox')) { initial_values[jQuery(this).attr('name')] = jQuery(this).is(':checked'); } else { initial_values[jQuery(this).attr('name')] = jQuery(this).val(); } }); } // Store initial values on page load store_values(); // Add change event listener to all inputs function check_input() { jQuery('.aiowps-settings :input').on('change', function() { var all_inputs_back_to_original = true; jQuery('.aiowps-settings :input').each(function() { var input_name = jQuery(this).attr('name'); if (jQuery(this).is(':checkbox')) { if (jQuery(this).is(':checked') !== initial_values[input_name]) { all_inputs_back_to_original = false; return false; } } else { if (jQuery(this).val() !== initial_values[input_name]) { all_inputs_back_to_original = false; return false; } } }); if (all_inputs_back_to_original) { jQuery('.aiowps-actions').hide(); } else { jQuery('.aiowps-actions').show(); } }); } check_input(); // Add click event listener to the button jQuery('.aiowps-actions :input').on('click', function() { // Hide the actions div jQuery('.aiowps-actions').hide(); // Re-store the values store_values(); }); /** * Initiates the download of a text file with the provided data and title. * * @param {string} data - The text data to be included in the file. * @param {string} title - The name of the file to be downloaded. */ function aios_download_txt_file(data, title) { // Create a Blob containing the text data let blob = new Blob([data], {type: 'text/plain'}); aios_download_file(blob, title); } /** * Initiates the download of a CSV file with the provided data and title. * * @param {string} data - The CSV data to be included in the file. * @param {string} title - The name of the file to be downloaded. */ function aios_download_csv_file(data, title) { // Create a Blob containing the CSV data let blob = new Blob([data], {type: 'text/csv'}); aios_download_file(blob, title); } /** * Triggers the download of a file using the provided Blob and filename. * * This function creates a temporary URL for the given Blob, then creates * and triggers a download of the file with the specified title. After the * download is initiated, it cleans up by removing the temporary element * and revoking the Blob URL. * * @param {Blob} blob - The Blob object containing the file data to be downloaded. * @param {string} title - The name of the file to be downloaded (including the file extension). */ function aios_download_file(blob, title) { // Create a temporary URL to the Blob let url = window.URL.createObjectURL(blob); // Create a temporary element to trigger the download let a = document.createElement('a'); a.href = url; a.download = title; document.body.appendChild(a); a.click(); // Cleanup: remove the temporary element and revoke the Blob URL document.body.removeChild(a); window.URL.revokeObjectURL(url); } // Add click event listener to rules jQuery('.aiowps-rules li').on('click', function() { jQuery('.aiowps-rules li').removeClass('aiowps-active'); jQuery(this).addClass('aiowps-active'); var template = jQuery(this).data('template'); jQuery('.aiowps-settings .postbox').hide(); jQuery('.aiowps-settings .postbox').each(function() { if (jQuery(this).data('template') === template) { jQuery(this).show(); return false; } }); const url_params = new URLSearchParams(window.location.search); const subtab_param = 'subtab=' + template; if (url_params.has('subtab')) { // If subtab parameter already exists, replace its value url_params.set('subtab', template); } else { // If subtab parameter doesn't exist if ("" === url_params.toString()) { // If there are no existing parameters, append subtab with '?' window.history.replaceState({}, '', window.location.pathname + '?' + subtab_param); return; } else { // If there are existing parameters const query_params = Array.from(url_params.entries()); const new_params = query_params.map(param => param.join('=')).join('&'); window.history.replaceState({}, '', window.location.pathname + '?' + new_params + '&' + subtab_param); return; } } window.history.replaceState({}, '', window.location.pathname + '?' + url_params.toString()); }); // Search for rules jQuery('.aiowps-search').on('keydown', function(event) { if ('Enter' === event.key) { event.preventDefault(); } }); jQuery('.aiowps-search').on('keyup', function(event) { if ('Enter' === event.key) { event.preventDefault(); } var value = jQuery(this).val().toLowerCase(); jQuery('.aiowps-rules li').each(function() { var template_value = jQuery(this).data('template').toLowerCase(); var span_text = jQuery(this).find('span').text().toLowerCase(); var th_match = false; jQuery('.form-table th').each(function() { var th_text = jQuery(this).text().toLowerCase(); if (th_text.indexOf(value) > -1) { var template = jQuery(this).closest('.postbox').data('template'); if (template === template_value) { th_match = true; return false; } } }); if (template_value.indexOf(value) > -1 || span_text.indexOf(value) > -1 || th_match) { jQuery(this).show(); } else { jQuery(this).hide(); } }); }); jQuery('#aiowps-rule-search .clear-search').on('click', function() { jQuery('.aiowps-search').val(''); jQuery('.aiowps-search').trigger('keyup'); }); set_active_tab_from_url(); // End of the new UI settings //toggle xmlrpc warning jQuery('#aiowps_enable_pingback_firewall').change(function() { if (jQuery(this).is(':checked')) { // When the checkbox is checked, remove the 'aio_hidden' class jQuery('.xmlrpc_warning_box').removeClass('aio_hidden'); } else { // Optionally, if unchecked, you can add the class back (if needed) jQuery('.xmlrpc_warning_box').addClass('aio_hidden'); } }); // Start of WP REST API toggle whitelist setting handling jQuery('input[name=aiowps_disallow_unauthorized_rest_requests]').on('click', function() { jQuery('.aios-rest-white-list-options-panel').toggleClass('hidden'); }); // End of WP REST API toggle whitelist setting handling // Start of the copy report button handling jQuery('#copy-report').on('click', function(event) { var text = jQuery('#report-textarea').val(); if (navigator.clipboard) { navigator.clipboard.writeText(text).then(function() { alert(aios_trans.copied); }, function() { deprecated_copy(text); }); } else { deprecated_copy(text); } }); // End of the copy report button handling // Start of the send report button handling jQuery('#send-report').on('click', function(e) { e.preventDefault(); var report_email = jQuery('#report_email').val(); var report_sections = jQuery('#report_sections').val(); jQuery('#report-response').html(''+ aios_trans.processing + '
'); jQuery('#report-response .aiowps_spinner').addClass('visible'); aios_send_command('send_report_email', {'report_email': report_email, 'report_sections': report_sections}, function (resp) { if (resp.hasOwnProperty('message')) { alert(resp.message); } }); }); // End of the send report button handling });