aiowps_feature_mgr)) return true; $this->aiowps_feature_mgr = new AIOWPSecurity_Feature_Item_Manager(); $initialized = true; return true; } /** * Retrieves the feature manager object. * * This method initializes the feature manager if necessary and returns the * AIOWPSecurity_Feature_Item_Manager instance. If the initialization fails or * the feature manager object is empty, it returns a WP_Error. * * @return AIOWPSecurity_Feature_Item_Manager|WP_Error */ private function get_feature_mgr_object() { $do_init = $this->feature_mgr_init(); if (true === $do_init && !empty($this->aiowps_feature_mgr)) return $this->aiowps_feature_mgr; return new WP_Error('not_initialized', __('The feature item manager could not be initialized.', 'all-in-one-wp-security-and-firewall')); } /** * Get IP address of given method. * * @param array $data - the request data * * @return array|WP_Error - an array response or a WP_Error if there was an error */ public function get_ip_address_of_given_method($data) { $ip_method_id = $data['ip_retrieve_method']; $ip_retrieve_methods = AIOS_Abstracted_Ids::get_ip_retrieve_methods(); if (isset($ip_retrieve_methods[$ip_method_id])) { return array( 'ip_address' => isset($_SERVER[$ip_retrieve_methods[$ip_method_id]]) ? sanitize_text_field(wp_unslash($_SERVER[$ip_retrieve_methods[$ip_method_id]])) : '', ); } else { return new WP_Error('aios-invalid-ip-retrieve-method', __('Invalid IP retrieve method.', 'all-in-one-wp-security-and-firewall')); } die; } /** * Dismiss a notice * * @param array $data - the request data contains the notice to dismiss * * @return array */ public function dismiss_notice($data) { global $aio_wp_security; $time_now = $aio_wp_security->notices->get_time_now(); if (in_array($data['notice'], array('dismissdashnotice', 'dismiss_season'))) { $aio_wp_security->configs->set_value($data['notice'], $time_now + (366 * 86400)); } elseif (in_array($data['notice'], array('dismiss_page_notice_until', 'dismiss_notice'))) { $aio_wp_security->configs->set_value($data['notice'], $time_now + (84 * 86400)); } elseif ('dismiss_review_notice' == $data['notice']) { if (empty($data['dismiss_forever'])) { $aio_wp_security->configs->set_value($data['notice'], $time_now + (84 * 86400)); } else { $aio_wp_security->configs->set_value($data['notice'], $time_now + (100 * 365.25 * 86400)); } } elseif ('dismiss_automated_database_backup_notice' == $data['notice']) { $aio_wp_security->delete_automated_backup_configs(); } elseif ('dismiss_ip_retrieval_settings_notice' == $data['notice']) { $aio_wp_security->configs->set_value($data['notice'], 1); } elseif ('dismiss_ip_retrieval_settings_notice' == $data['notice']) { $aio_wp_security->configs->set_value('aiowps_is_login_whitelist_disabled_on_upgrade', 1); } elseif ('dismiss_login_whitelist_disabled_on_upgrade_notice' == $data['notice']) { if (isset($data['turn_it_back_on']) && '1' == $data['turn_it_back_on']) { $aio_wp_security->configs->set_value('aiowps_enable_whitelisting', '1'); } $aio_wp_security->configs->delete_value('aiowps_is_login_whitelist_disabled_on_upgrade'); } elseif ('dismiss_ip_blacklist_notice' == $data['notice']) { if (isset($data['turn_it_back_on']) && '1' == $data['turn_it_back_on']) { $aio_wp_security->configs->set_value('aiowps_enable_blacklisting', '1'); AIOWPSecurity_Configure_Settings::set_blacklist_ip_firewall_configs(); AIOWPSecurity_Configure_Settings::set_user_agent_firewall_configs(); } $aio_wp_security->configs->delete_value('aiowps_is_ip_blacklist_settings_notice_on_upgrade'); } elseif ('dismiss_firewall_settings_disabled_on_upgrade_notice' == $data['notice']) { $is_reactivated = (isset($data['turn_it_back_on']) && '1' == $data['turn_it_back_on']); if ($is_reactivated) { $aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG); $active_settings = $aio_wp_security->configs->get_value('aiowps_firewall_active_upgrade'); if (!empty($active_settings)) { $active_settings = json_decode($active_settings); if (!empty($active_settings)) { foreach ($active_settings as $setting) { $aiowps_firewall_config->set_value($setting, true); } } } } $aio_wp_security->configs->delete_value('aiowps_firewall_active_upgrade'); } elseif ('php_56_eol_dismiss_forever' == $data['notice']) { $aio_wp_security->configs->set_value('php_56_eol_dismiss_forever', $time_now + (100 * 365.25 * 86400)); } $aio_wp_security->configs->save_config(); return array(); } /** * This is a helper function to save settings options using key/value pairs * * @param array $options - An array of options to save to the config * @param null $callback - A callback function to call when the options are saved * * @return bool */ public function save_settings($options, $callback = null) { global $aio_wp_security; $aiowps_feature_mgr = $this->get_feature_mgr_object(); if (is_wp_error($aiowps_feature_mgr)) return false; foreach ($options as $key => $value) { $aio_wp_security->configs->set_value($key, $value); } //commit the config changes $aio_wp_security->configs->save_config(); if (is_callable($callback)) { call_user_func($callback, $options); } $aiowps_feature_mgr->calculate_total_feature_points(); return true; } /** * This is a helper function to get the output feature details badge * * @param string $feature_id - the id of the feature we want to get the badge for * * @return string */ public function get_feature_details_badge($feature_id) { $aiowps_feature_mgr = $this->get_feature_mgr_object(); if (is_wp_error($aiowps_feature_mgr)) return ''; return $aiowps_feature_mgr->output_feature_details_badge($feature_id, true); } /** * Retrieves the IDs and HTML content for features. * * This method processes an array of features and returns an associative array containing * the IDs and corresponding HTML content for each feature badge. * * @param array $features - An array containing the features to retrieve IDs and HTML for. * * @return array An associative array containing the IDs and HTML content for each feature badge. */ public function get_features_id_and_html($features) { $result = array(); foreach ($features as $feature) { $result[] = array( 'id' => '#' . $feature . '-badge', 'html' => $this->get_feature_details_badge($feature) ); } return $result; } /** * Prepares and returns a structured response for AJAX commands. * * @param bool $success Indicates whether the operation was successful (true for success, false for failure). * @param string|bool $message The message to include in the response (optional). * If false, no message is passed with the response. * If empty string, it defaults to a success or error message based on the $success flag. * @param array $args Optional. An associative array of additional response data, such as badges, info, values, or content. * * @return array The constructed response array containing status, message, and any additional data from $args. */ public function handle_response($success, $message = '', $args = array()) { $response = array( 'status' => $success ? 'success' : 'error', ); if (false !== $message) { $response['message'] = $this->get_message($success, $message); } $allowed_keys = array('badges', 'info', 'values', 'content', 'extra_args'); foreach ($allowed_keys as $key) { if (!empty($args[$key])) { $response[$key] = 'badges' === $key ? $this->get_features_id_and_html($args[$key]) : $args[$key]; } } return $response; } /** * Get the appropriate message based on success flag and provided message. * * @param bool $success Indicates whether the operation was successful. * @param string $message The provided message. * * @return string The final message to be used in the response. */ private function get_message($success, $message) { if ('' === $message) { return $success ? __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall') : __('The settings update was unsuccessful.', 'all-in-one-wp-security-and-firewall'); } return $message; } /** * Get antibot keys for the spam detection * * @return array */ public function get_antibot_keys() { global $aio_wp_security; $response = array( 'status' => 'success', 'data' => array(), ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. It is the nonce. $nonce = empty($_POST['nonce']) ? '' : sanitize_key(wp_unslash($_POST['nonce'])); if (!wp_verify_nonce($nonce, 'wp-security-ajax-nonce')) { $response['status'] = false; $response['error_code'] = 'invalid_nonce'; $response['error_message'] = 'Invalid nonce (wp-security-ajax-nonce) provided for this action.'; } else { $key_map_arr = AIOWPSecurity_Comment::generate_antibot_keys(true); $response['data'] = $key_map_arr[0]; if ('1' == $aio_wp_security->configs->get_value('aiowps_spambot_detect_usecookies')) { AIOWPSecurity_Comment::insert_antibot_keys_in_cookie(); } } echo wp_json_encode($response); exit; } /** * This function will send the diagnostic report email * * @param array $data - the request data * * @return array */ public function send_report_email($data) { global $aio_wp_security; // Sanitize the email address first. $sanitized_email = !empty($data['report_email']) ? sanitize_email($data['report_email']) : ''; if ('' === $sanitized_email || !is_email($sanitized_email)) { return array( 'status' => 'error', 'message' => __('Invalid email address.', 'all-in-one-wp-security-and-firewall'), ); } $result = $aio_wp_security->debug_obj->send_report($sanitized_email, wp_kses_post(html_entity_decode($data['report_sections']))); if ($result) { return array( 'status' => 'success', 'message' => __('The diagnostic report has been sent successfully.', 'all-in-one-wp-security-and-firewall'), ); } return array( 'status' => 'error', 'message' => __('There was an error sending the diagnostic report.', 'all-in-one-wp-security-and-firewall'), ); } /** * Returns an array of translations used by the AIOS plugin. Primarily used for UpdraftCentral consumption. * * @param array $params - The parameters passed to the function. * * @return array - The AIOS translations array */ public function get_js_translation($params) { $translations = array(); if (isset($params['return_formatted_response'])) { return array( 'error' => false, 'data' => array( 'translations' => $translations, ) ); } return $translations; } /** * Get multiple widgets data. Primarily used for UpdraftCentral consumption. * * @param array $args - The arguments containing the widgets to retrieve data for. * * @return array - An array containing error status and data for each widget. */ public function get_widgets_data($args) { // Widgets. $widgets = isset($args['widgets']) ? $args['widgets'] : array(); // Return early if no widgets supplied. if (!is_array($widgets) || empty($widgets)) { return array('error' => false, 'data' => array()); } // Get the data for each widget. $data = array(); // Loop through the widgets and get their data. foreach ($widgets as $widget) { $method = 'get_' . $widget . '_data'; if (method_exists($this, $method)) { $data[$widget] = $this->$method($args); } } return array('error' => false, 'data' => $data); } /** * Get the AIOS premium upsell data for UDC widget. * * @return array */ public function get_is_premium_data() { $is_premium = AIOWPSecurity_Utility_Permissions::is_premium_installed(); $upgrade_to_premium_data = array(); if (false === $is_premium) { $upgrade_to_premium_data = array( 'heading' => __('AIOS premium', 'all-in-one-wp-security-and-firewall'), 'checklist' => array( __('Advanced malware scanning', 'all-in-one-wp-security-and-firewall'), __('Real-time response time monitoring', 'all-in-one-wp-security-and-firewall'), __('Custom two-factor authentication', 'all-in-one-wp-security-and-firewall'), __('404 error protection & bot blocking', 'all-in-one-wp-security-and-firewall'), __('Country-based traffic blocking', 'all-in-one-wp-security-and-firewall'), __('Country whitelist management', 'all-in-one-wp-security-and-firewall'), __('Guaranteed premium support', 'all-in-one-wp-security-and-firewall'), ), 'cta' => array( 'text' => __('Upgrade Now', 'all-in-one-wp-security-and-firewall'), 'url' => 'https://teamupdraft.com/all-in-one-security/pricing/', ), ); } return array( 'is_premium' => $is_premium, 'upgrade_to_premium_data' => $upgrade_to_premium_data, ); } /** * Get report data for the current month. * * @return array - An array containing this month's report data. */ public function get_report_data() { $start_time = strtotime('first day of this month 00:00:00'); $end_time = strtotime('last day of this month 23:59:59'); global $wpdb; $block_table_name = AIOWPSEC_TBL_PERM_BLOCK; $blocked_ips_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$block_table_name} WHERE created BETWEEN %d AND %d", $start_time, $end_time ) ); $audit_log_table_name = AIOWPSEC_TBL_AUDIT_LOG; $failed_login_attempts_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$audit_log_table_name} WHERE event_type='failed_login' AND created BETWEEN %d AND %d", $start_time, $end_time ) ); $stopped_malicious_requests_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$audit_log_table_name} WHERE event_type='rule_triggered' AND created BETWEEN %d AND %d", $start_time, $end_time ) ); $file_change_detection_data = AIOWPSecurity_Scan::get_fcd_data(); $critical_features = AIOWPSecurity_Feature_Item_Manager::get_critical_features(); $aiowps_feature_mgr = $this->get_feature_mgr_object(); $aiowps_feature_mgr->check_feature_status_and_recalculate_points(); $critical_issues = 0; foreach ($critical_features as $key => $feature) { $feature_item = $aiowps_feature_mgr->get_feature_item_by_id($key); if (!$feature_item) continue; if (!$feature_item->is_active()) { ++$critical_issues; } } return array( 'report_data' => array( 'login_attempts_blocked' => empty($failed_login_attempts_count) ? 0 : $failed_login_attempts_count, 'stopped_malicious_requests' => empty($stopped_malicious_requests_count) ? 0 : $stopped_malicious_requests_count, 'blocked_ips_count' => empty($blocked_ips_count) ? 0 : $blocked_ips_count, 'total_files_scanned' => empty($file_change_detection_data['file_scan_data']) ? 0 : count($file_change_detection_data['file_scan_data']), ), 'variables' => array( /* translators: %d is the number of critical issues found. */ 'security_highlights' => sprintf(__('%d critical issue(s)', 'all-in-one-wp-security-and-firewall'), $critical_issues), ), ); } }