Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-2286: Settings.php in wp-security-audit-log/trunk/classes/Views – WordPress Plugin Repository

The WP Activity Log for WordPress is vulnerable to Cross-Site Request Forgery in versions up to, and including, 4.5.0. This is due to missing or incorrect nonce validation on the ajax_run_cleanup function. This makes it possible for unauthenticated attackers to invoke this function via a forged request granted they can trick a site administrator into performing an action such as clicking on a link.

CVE
#web#js#java#wordpress#php#auth

1<?php2/**3 * Settings Page4 *5 * Settings page of the plugin.6 *7 * @since 1.0.08 * @package wsal9 * @subpackage views10 */1112use WSAL\Helpers\WP_Helper;13use WSAL\Controllers\Constants;14use WSAL\Helpers\Settings_Helper;15use WSAL\Controllers\Alert_Manager;1617// Exit if accessed directly.18if ( ! defined( ‘ABSPATH’ ) ) {19 exit;20}2122/**23 * Class: WSAL_Views_Settings24 *25 * Settings view class to handle settings page functions.26 *27 * @since 1.0.028 *29 * @package wsal30 * @subpackage views31 */32class WSAL_Views_Settings extends WSAL_AbstractView {3334 /**35 * Adapter Message.36 *37 * @var string38 */39 public $adapter_msg = '’;4041 /**42 * WSAL Setting Tabs.43 *44 * @since 3.2.345 *46 * @var array47 */48 private $wsal_setting_tabs = array();4950 /**51 * Current Setting Tab.52 *53 * @since 3.2.354 *55 * @var string56 */57 private $current_tab = '’;5859 /**60 * Method: Constructor.61 *62 * @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.63 */64 public function __construct( WpSecurityAuditLog $plugin ) {65 parent::__construct( $plugin );66 add_action( 'admin_init’, array( $this, ‘setup_settings_tabs’ ) );67 add_action( 'wp_ajax_AjaxCheckSecurityToken’, array( $this, ‘ajax_check_security_token’ ) );68 add_action( 'wp_ajax_AjaxRunCleanup’, array( $this, ‘ajax_run_cleanup’ ) );69 add_action( 'wp_ajax_AjaxGetAllUsers’, array( $this, ‘ajax_get_all_users’ ) );70 add_action( 'wp_ajax_AjaxGetAllRoles’, array( $this, ‘ajax_get_all_roles’ ) );71 add_action( 'wp_ajax_AjaxGetAllCPT’, array( $this, ‘ajax_get_all_cpts’ ) );72 add_action( 'wp_ajax_wsal_reset_settings’, array( $this, ‘reset_settings’ ) );73 add_action( 'wp_ajax_wsal_purge_activity’, array( $this, ‘purge_activity’ ) );74 add_action( 'wp_ajax_wsal_ajax_get_all_severities’, array( $this, ‘ajax_get_all_severities’ ) );75 add_action( 'wp_ajax_wsal_ajax_get_all_event_types’, array( $this, ‘ajax_get_all_event_types’ ) );76 add_action( 'wp_ajax_wsal_ajax_get_all_object_types’, array( $this, ‘ajax_get_all_object_types’ ) );77 add_action( 'wp_ajax_wsal_ajax_get_all_event_ids’, array( $this, ‘ajax_get_all_event_ids’ ) );78 }7980 /**81 * Setup WSAL Settings Page Tabs.82 *83 * @since 3.484 */85 public function setup_settings_tabs() {8687 // Verify that the current page is WSAL settings page.88 $page = isset( $_GET[‘page’] ) ? sanitize_text_field( wp_unslash( $_GET[‘page’] ) ) : false; // phpcs:ignore89 if ( empty( $page ) || $this->get_safe_view_name() !== $page ) {90 return;91 }9293 // Tab links.94 $wsal_setting_tabs = array(95 ‘general’ => array(96 ‘name’ => esc_html__( 'General’, ‘wp-security-audit-log’ ),97 ‘link’ => add_query_arg( 'tab’, 'general’, $this->get_url() ),98 ‘render’ => array( $this, ‘tab_general’ ),99 ‘save’ => array( $this, ‘tab_general_save’ ),100 ‘priority’ => 10,101 ),102 ‘audit-log’ => array(103 ‘name’ => esc_html__( 'Activity log viewer’, ‘wp-security-audit-log’ ),104 ‘link’ => add_query_arg( 'tab’, 'audit-log’, $this->get_url() ),105 ‘render’ => array( $this, ‘tab_audit_log’ ),106 ‘save’ => array( $this, ‘tab_audit_log_save’ ),107 ‘priority’ => 20,108 ),109 ‘file-changes’ => array(110 ‘name’ => esc_html__( 'File changes’, ‘wp-security-audit-log’ ),111 ‘link’ => add_query_arg( 'tab’, 'file-changes’, $this->get_url() ),112 ‘render’ => array( $this, ‘tab_file_changes’ ),113 ‘priority’ => 30,114 ),115 ‘exclude-objects’ => array(116 ‘name’ => esc_html__( 'Exclude objects’, ‘wp-security-audit-log’ ),117 ‘link’ => add_query_arg( 'tab’, 'exclude-objects’, $this->get_url() ),118 ‘render’ => array( $this, ‘tab_exclude_objects’ ),119 ‘save’ => array( $this, ‘tab_exclude_objects_save’ ),120 ‘priority’ => 40,121 ),122 ‘advanced-settings’ => array(123 ‘name’ => esc_html__( 'Advanced settings’, ‘wp-security-audit-log’ ),124 ‘link’ => add_query_arg( 'tab’, 'advanced-settings’, $this->get_url() ),125 ‘render’ => array( $this, ‘tab_advanced_settings’ ),126 ‘save’ => array( $this, ‘tab_advanced_settings_save’ ),127 ‘priority’ => 100,128 ),129 );130131 /**132 * Filter: `wsal_setting_tabs`133 *134 * This filter is used to filter the tabs of WSAL settings page.135 *136 * Setting tabs structure:137 * $wsal_setting_tabs[‘unique-tab-id’] = array(138 * ‘name’ => Name of the tab,139 * ‘link’ => Link of the tab,140 * ‘render’ => This function is used to render HTML elements in the tab,141 * ‘name’ => This function is used to save the related setting of the tab,142 * ‘priority’ => Priority of the tab,143 * );144 *145 * @param array $wsal_setting_tabs – Array of WSAL Setting Tabs.146 *147 * @since 3.2.3148 */149 $wsal_setting_tabs = apply_filters( 'wsal_setting_tabs’, $wsal_setting_tabs );150151 // Sort by priority.152 array_multisort( array_column( $wsal_setting_tabs, ‘priority’ ), SORT_ASC, $wsal_setting_tabs );153154 $this->wsal_setting_tabs = $wsal_setting_tabs;155156 // Get the current tab.157 $current_tab = ( isset( $_GET[‘tab’] ) ) ? \sanitize_text_field( \wp_unslash( $_GET[‘tab’] ) ) : '’;158 $this->current_tab = empty( $current_tab ) ? ‘general’ : $current_tab;159 }160161 /**162 * {@inheritDoc}163 */164 public function has_plugin_shortcut_link() {165 return true;166 }167168 /**169 * {@inheritDoc}170 */171 public function get_title() {172 return esc_html__( 'Settings’, ‘wp-security-audit-log’ );173 }174175 /**176 * {@inheritDoc}177 */178 public function get_icon() {179 return 'dashicons-admin-generic’;180 }181182 /**183 * {@inheritDoc}184 */185 public function get_name() {186 return esc_html__( 'Settings’, ‘wp-security-audit-log’ );187 }188189 /**190 * {@inheritDoc}191 */192 public function get_weight() {193 return 8;194 }195196 /**197 * Method: Get Token Type.198 *199 * @param string $token - Token type.200 * @param string $type - Type of the input to check.201 */202 protected function get_token_type( $token, $type = false ) {203 return $this->plugin->settings()->get_token_type( $token, $type );204 }205206 /**207 * Method: Save settings.208 *209 * @throws Exception - Unrecognized settings tab error.210 */211 protected function save() {212 // Bail early if user does not have sufficient permissions to save.213 if ( ! $this->plugin->settings()->current_user_can( ‘edit’ ) ) {214 throw new Exception( esc_html__( 'Current user is not allowed to save settings.’, ‘wp-security-audit-log’ ) );215 }216 // Call respective tab save functions if they are set. Nonce is already verified at this point.217 if ( ! empty( $this->current_tab ) && ! empty( $this->wsal_setting_tabs[ $this->current_tab ][‘save’] ) ) {218 call_user_func( $this->wsal_setting_tabs[ $this->current_tab ][‘save’] );219 } else {220 throw new Exception( esc_html__( 'Unknown settings tab.’, ‘wp-security-audit-log’ ) );221 }222 }223224 /**225 * Method: Check security token.226 */227 public function ajax_check_security_token() {228 if ( ! $this->plugin->settings()->current_user_can( ‘edit’ ) ) {229 echo wp_json_encode(230 array(231 ‘success’ => false,232 ‘message’ => esc_html__( 'Access Denied.’, ‘wp-security-audit-log’ ),233 )234 );235 die();236 }237238 //@codingStandardsIgnoreStart239 $nonce = isset( $_POST[‘nonce’] ) ? sanitize_text_field( $_POST[‘nonce’] ) : false;240 $token = isset( $_POST[‘token’] ) ? sanitize_text_field( $_POST[‘token’] ) : false;241 //@codingStandardsIgnoreEnd242243 if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, ‘wsal-exclude-nonce’ ) ) {244 echo wp_json_encode(245 array(246 ‘success’ => false,247 ‘message’ => esc_html__( 'Nonce verification failed.’, ‘wp-security-audit-log’ ),248 )249 );250 die();251 }252253 if ( empty( $token ) ) {254 echo wp_json_encode(255 array(256 ‘success’ => false,257 ‘message’ => esc_html__( 'Invalid input.’, ‘wp-security-audit-log’ ),258 )259 );260 die();261 }262263 $input_type = isset( $_POST[‘type’] ) ? sanitize_text_field( $_POST[‘type’] ) : false;264265 echo wp_json_encode(266 array(267 ‘success’ => true,268 ‘token’ => $token,269 ‘tokenType’ => esc_html( $this->get_token_type( $token, $input_type ) ),270 )271 );272 die();273 }274275 /**276 * Method: Run cleanup.277 */278 public function ajax_run_cleanup() {279 // Verify nonce.280 if ( ! isset( $_REQUEST[‘nonce’] ) || false === wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_REQUEST[‘nonce’] ) ), ‘wsal-run-cleanup’ ) ) {281 wp_send_json_error( esc_html__( 'Insecure request.’, ‘wp-security-audit-log’ ) );282 }283284 if ( ! $this->plugin->settings()->current_user_can( ‘edit’ ) ) {285 die( ‘Access Denied.’ );286 }287288 $now = current_time( ‘timestamp’ ); // phpcs:ignore289 $max_sdate = $this->plugin->settings()->get_pruning_date(); // Pruning date.290 $archiving = Settings_Helper::is_archiving_set_and_enabled();291292 // phpcs:disable293 // phpcs:enable294295 // Calculate limit timestamp.296 $max_stamp = $now - ( strtotime( $max_sdate ) - $now );297298 // $query = new WSAL_Models_OccurrenceQuery();299 // $query->add_order_by( 'created_on’, false ); // Descending order.300 // $query->add_condition( 'created_on <= %s’, intval( $max_stamp ) ); // Add limits of timestamp.301 // $results = $query->get_adapter()->execute_query( $query );302 $items = \WSAL\Entities\Occurrences_Entity::count( 'created_on <= %s’, intval( $max_stamp ) );303 if ( $items ) {304 $this->plugin->clean_up();305 }306307 if ( $archiving ) {308 $archiving_args = array(309 ‘page’ => 'wsal-ext-settings’,310 ‘tab’ => 'archiving’,311 );312 $archiving_url = add_query_arg( $archiving_args, admin_url( ‘admin.php’ ) );313 wp_safe_redirect( $archiving_url );314 } else {315 if ( $items ) {316 $redirect_args = array(317 ‘tab’ => 'audit-log’,318 ‘pruning’ => 1,319 );320 } else {321 $redirect_args = array(322 ‘tab’ => 'audit-log’,323 ‘pruning’ => 0,324 );325 }326 wp_safe_redirect( add_query_arg( $redirect_args, $this->get_url() ) );327 }328 exit;329 }330331 /**332 * {@inheritDoc}333 */334 public function render() {335 // Verify nonce if a form is submitted.336 if ( isset( $_POST[‘_wpnonce’] ) ) {337 check_admin_referer( ‘wsal-settings’ );338 }339340 if ( ! $this->plugin->settings()->current_user_can( ‘edit’ ) ) {341 wp_die( esc_html__( 'You do not have sufficient permissions to access this page.’, ‘wp-security-audit-log’ ) );342 }343344 // Check to see if section parameter is set in the URL.345 $section = isset( $_GET[‘section’] ) ? sanitize_text_field( wp_unslash( $_GET[‘section’] ) ) : false;346347 if ( isset( $_POST[‘submit’] ) ) {348 try {349 $this->save(); // Save settings.350 if ( ‘sms-provider’ === $this->current_tab && $section && ‘test’ === $section ) :351 ?>352 <div class="updated">353 <p><?php esc_html_e( 'Message sent successfully.’, ‘wp-security-audit-log’ ); ?></p>354 </div>355 <?php else : ?>356 <div class="updated">357 <p><?php esc_html_e( 'Settings have been saved.’, ‘wp-security-audit-log’ ); ?></p>358 </div>359 <?php360 endif;361 } catch ( Exception $ex ) {362 ?>363 <div class="error">364 <p><?php esc_html_e( 'Error: ', ‘wp-security-audit-log’ ); ?><?php echo esc_html( $ex->getMessage() ); ?></p>365 </div>366 <?php367 }368 }369370 if ( isset( $_POST[‘import’] ) ) {371 call_user_func( $this->wsal_setting_tabs[ $this->current_tab ][‘save’] );372 }373374 if ( isset( $_GET[‘pruning’] ) && ‘1’ === $_GET[‘pruning’] ) {375 ?>376 <div class="updated">377 <p><?php esc_html_e( 'Old data successfully purged.’, ‘wp-security-audit-log’ ); ?></p>378 </div>379 <?php380 } elseif ( isset( $_GET[‘pruning’] ) && ‘0’ === $_GET[‘pruning’] ) {381 ?>382 <div class="error">383 <p><?php esc_html_e( 'No data is old enough to be purged.’, ‘wp-security-audit-log’ ); ?></p>384 </div>385 <?php386 }387 ?>388 <nav id="wsal-tabs" class="nav-tab-wrapper">389 <?php foreach ( $this->wsal_setting_tabs as $tab_id => $tab ) : ?>390 <a href="<?php echo esc_url( $tab[‘link’] ); ?>" class="nav-tab <?php echo ( $tab_id === $this->current_tab ) ? ‘nav-tab-active’ : false; ?>">391 <?php echo esc_html( $tab[‘name’] ); ?>392 </a>393 <?php endforeach; ?>394 </nav>395396 <form id="audit-log-settings" method="post">397 <input type="hidden" name="page" value="<?php echo isset( $_GET[‘page’] ) ? esc_attr( sanitize_text_field( wp_unslash( $_GET[‘page’] ) ) ) : false; ?>" />398 <input type="hidden" id="ajaxurl" value="<?php echo esc_attr( admin_url( ‘admin-ajax.php’ ) ); ?>" />399 <?php wp_nonce_field( ‘wsal-settings’ ); ?>400401 <div id="audit-log-adverts"></div>402 <div class="nav-tabs">403 <?php404 if ( ! empty( $this->current_tab ) && ! empty( $this->wsal_setting_tabs[ $this->current_tab ][‘render’] ) ) {405 call_user_func( $this->wsal_setting_tabs[ $this->current_tab ][‘render’] );406 } else {407 call_user_func( $this->wsal_setting_tabs[‘general’][‘render’] );408 }409 ?>410 </div>411 <?php412 if ( ‘sms-provider’ === $this->current_tab && $section && ‘test’ === $section ) {413 submit_button( esc_html__( 'Send Message’, ‘wp-security-audit-log’ ) );414 } else {415 submit_button();416 }417 ?>418 </form>419 <?php // @codingStandardsIgnoreStart ?>420 <script type="text/javascript">421 <!–422 function delete_confirm(elementRef) {423 if (elementRef.checked) {424 if ( window.confirm('<?php esc_html_e( ‘Do you want to remove all data when the plugin is deleted?’, ‘wp-security-audit-log’ ); ?>’) == false ) {425 elementRef.checked = false;426 // Ensure the “no” option is reselected.427 jQuery(‘#delete_data_no’).click();428 }429 }430 }431432 jQuery( document ).ready( function() {433 // Enable/disable setting.434 function wsal_update_setting( checkbox, setting ) {435 if ( checkbox.prop( ‘checked’ ) ) {436 setting.removeProp( ‘disabled’ );437 } else {438 setting.prop( 'disabled’, ‘disabled’ );439 }440 }441442 // Login page notification settings.443 var login_page_notif = jQuery( 'input[name=login_page_notification]' );444 var login_page_notif_text = jQuery( ‘#login_page_notification_text’ );445446 // Check the change event on checkbox.447 login_page_notif.on( 'change’, function() {448 wsal_update_setting( login_page_notif, login_page_notif_text );449 } );450451 // Proxy settings.452 var proxy_ip_setting = jQuery( 'input[name=EnableProxyIpCapture]' );453 var ip_filtering = jQuery( ‘#EnableIpFiltering’ );454 wsal_update_setting( proxy_ip_setting, ip_filtering );455 proxy_ip_setting.on( 'change’, function() {456 wsal_update_setting( proxy_ip_setting, ip_filtering );457 } );458 } );459 // --></script>460 <?php461 // @codingStandardsIgnoreEnd462 }463464 /**465 * Tab: `General`466 */467 private function tab_general() {468 $settings = $this->plugin->settings();469 $enforced_settings = $settings->get_mainwp_enforced_settings();470 $login_page_notification_settings_enforced_by_mainwp = array_key_exists( 'login_notification_enabled’, $enforced_settings );471 $incognito_setting_enforced_by_mainwp = array_key_exists( 'incognito_mode_enabled’, $enforced_settings );472 ?>473 <h3><?php esc_html_e( 'Use infinite scroll or pagination for the event viewer?’, ‘wp-security-audit-log’ ); ?></h3>474 <p class="description">475 <?php476 echo sprintf(477 /* translators: Learn more link. */478 esc_html__( 'When using infinite scroll the event viewer and search results %s load up much faster and require less resources.’, ‘wp-security-audit-log’ ),479 ‘<a href="https://wpactivitylog.com/features/search-filters-wordpress-activity-log/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">’ . esc_html__( '(Premium feature)', ‘wp-security-audit-log’ ) . '</a>’480 );481 ?>482 </p>483 <table class="form-table wsal-tab">484 <tbody>485 <tr>486 <th><label for="infinite-scroll"><?php esc_html_e( 'Select event viewer view type:’, ‘wp-security-audit-log’ ); ?></label></th>487 <td>488 <fieldset>489 <label for="infinite-scroll">490 <input type="radio" name="events-type-nav" value="infinite-scroll" id="infinite-scroll" <?php checked( $this->plugin->settings()->get_events_type_nav(), ‘infinite-scroll’ ); ?> />491 <?php esc_html_e( 'Infinite Scroll (Recommended)', ‘wp-security-audit-log’ ); ?>492 </label>493 <br/>494 <label for="pagination">495 <input type="radio" name="events-type-nav" value="pagination" id="pagination" <?php checked( $this->plugin->settings()->get_events_type_nav(), ‘pagination’ ); ?> />496 <?php esc_html_e( 'Pagination’, ‘wp-security-audit-log’ ); ?>497 </label>498 <br />499 </fieldset>500 </td>501 </tr>502 <!-- / Reverse Proxy / Firewall Options -->503 </tbody>504 </table>505 <!-- Events Navigation Type -->506507 <h3><?php esc_html_e( 'Do you want the activity log viewer to auto refresh?’, ‘wp-security-audit-log’ ); ?></h3>508 <p class="description"><?php esc_html_e( 'The activity log viewer auto refreshes every 30 seconds when opened so you can see the latest events as they happen almost in real time.’, ‘wp-security-audit-log’ ); ?></p>509 <table class="form-table wsal-tab">510 <tbody>511 <tr>512 <th><label for="aroption_on"><?php esc_html_e( 'Refresh activity log viewer’, ‘wp-security-audit-log’ ); ?></label></th>513 <td>514 <fieldset>515 <?php $are = $this->plugin->settings()->is_refresh_alerts_enabled(); ?>516 <label for="aroption_on">517 <input type="radio" name="EnableAuditViewRefresh" id="aroption_on" style="margin-top: -2px;" <?php checked( $are ); ?> value="1">518 <span><?php esc_html_e( 'Auto refresh’, ‘wp-security-audit-log’ ); ?></span>519 </label>520 <br/>521 <label for="aroption_off">522 <input type="radio" name="EnableAuditViewRefresh" id="aroption_off" style="margin-top: -2px;" <?php checked( $are, false ); ?> value="0">523 <span><?php esc_html_e( 'Do not auto refresh’, ‘wp-security-audit-log’ ); ?></span>524 </label>525 </fieldset>526 </td>527 </tr>528 <!-- Refresh activity log viewer -->529 </tbody>530 </table>531 <!-- Refresh activity log -->532533 <h3><?php esc_html_e( 'Display latest events widget in Dashboard & Admin bar’, ‘wp-security-audit-log’ ); ?></h3>534 <p class="description">535 <?php536 echo sprintf(537 /* translators: Max number of dashboard widget alerts. */538 esc_html__( 'The events widget displays the latest %d security events in the dashboard and the admin bar notification displays the latest event.’, ‘wp-security-audit-log’ ),539 esc_html( $this->plugin->settings()->get_dashboard_widget_max_alerts() )540 );541 ?>542 </p>543 <table class="form-table wsal-tab">544 <tbody>545 <tr>546 <th><label for="dwoption_on"><?php esc_html_e( 'Dashboard Widget’, ‘wp-security-audit-log’ ); ?></label></th>547 <td>548 <fieldset>549 <?php $dwe = $this->plugin->settings()->is_widgets_enabled(); ?>550 <label for="dwoption_on">551 <input type="radio" name="EnableDashboardWidgets" id="dwoption_on" style="margin-top: -2px;" <?php checked( $dwe ); ?> value="1">552 <span><?php esc_html_e( 'Yes’, ‘wp-security-audit-log’ ); ?></span>553 </label>554 <br/>555 <label for="dwoption_off">556 <input type="radio" name="EnableDashboardWidgets" id="dwoption_off" style="margin-top: -2px;" <?php checked( $dwe, false ); ?> value="0">557 <span><?php esc_html_e( 'No’, ‘wp-security-audit-log’ ); ?></span>558 </label>559 </fieldset>560 </td>561 </tr>562 <!-- / Events Dashboard Widget -->563564 <tr>565 <?php566 $disabled = '’;567 $label = esc_html__( 'Admin Bar Notification’, ‘wp-security-audit-log’ );568 if ( wsal_freemius()->is_free_plan() ) {569 $disabled = 'disabled’;570 $label = esc_html__( 'Admin Bar Notification’, ‘wp-security-audit-log’ );571 }572 ?>573 <th><label for="admin_bar_notif_on"><?php echo esc_html( $label ); ?></label></th>574 <td>575 <fieldset <?php echo esc_attr( $disabled ); ?>>576 <?php $abn = $this->plugin->settings()->is_admin_bar_notif(); ?>577 <label for="admin_bar_notif_on">578 <input type="radio" name="admin_bar_notif" id="admin_bar_notif_on" style="margin-top: -2px;" <?php checked( $abn ); ?> value="1">579 <span><?php esc_html_e( 'Yes’, ‘wp-security-audit-log’ ); ?></span>580 </label>581 <br/>582 <label for="admin_bar_notif_off">583 <input type="radio" name="admin_bar_notif" id="admin_bar_notif_off" style="margin-top: -2px;" <?php checked( $abn, false ); ?> value="0">584 <span><?php esc_html_e( 'No’, ‘wp-security-audit-log’ ); ?></span>585 </label>586 </fieldset>587 </td>588 </tr>589 <!-- / Admin Bar Notification -->590591 <tr>592 <?php593 $disabled = '’;594 $label = esc_html__( 'Admin Bar Notification Updates’, ‘wp-security-audit-log’ );595 if ( wsal_freemius()->is_free_plan() ) {596 $disabled = 'disabled’;597 $label = esc_html__( 'Admin Bar Notification Updates’, ‘wp-security-audit-log’ );598 }599 ?>600 <th><label for="admin_bar_notif_refresh"><?php echo esc_html( $label ); ?></label></th>601 <td>602 <fieldset <?php echo esc_attr( $disabled ); ?>>603 <?php $abn_updates = $this->plugin->settings()->get_admin_bar_notif_updates(); ?>604 <label for="admin_bar_notif_realtime">605 <input type="radio" name="admin_bar_notif_updates" id="admin_bar_notif_realtime" style="margin-top: -2px;" <?php checked( $abn_updates, ‘real-time’ ); ?> value="real-time">606 <span><?php esc_html_e( 'Update in near real time’, ‘wp-security-audit-log’ ); ?></span>607 </label>608 <br/>609 <label for="admin_bar_notif_refresh">610 <input type="radio" name="admin_bar_notif_updates" id="admin_bar_notif_refresh" style="margin-top: -2px;" <?php checked( $abn_updates, ‘page-refresh’ ); ?> value="page-refresh">611 <span><?php esc_html_e( 'Update only on page refreshes’, ‘wp-security-audit-log’ ); ?></span>612 </label>613 </fieldset>614 </td>615 </tr>616 <!-- / Admin Bar Notification Updates -->617 </tbody>618 </table>619 <!-- Dashboard Widget -->620621 <h3><?php esc_html_e( 'Add user notification on the WordPress login page’, ‘wp-security-audit-log’ ); ?></h3>622 <p class="description"><?php esc_html_e( 'Many compliance regulations (such as the GDPR) require website administrators to tell the users of their website that all the changes they do when logged in are being logged.’, ‘wp-security-audit-log’ ); ?></p>623 <table class="form-table wsal-tab">624 <tbody>625 <tr>626 <th><label for="login_page_notification"><?php esc_html_e( 'Login Page Notification’, ‘wp-security-audit-log’ ); ?></label></th>627 <td>628 <fieldset <?php echo disabled( $login_page_notification_settings_enforced_by_mainwp ); ?>>629 <?php630 // Get login page notification checkbox.631 $wsal_lpn = $this->plugin->settings()->is_login_page_notification();632 if ( $wsal_lpn && ‘true’ === $wsal_lpn ) {633 // If option exists, value is true then set to true.634 $wsal_lpn = true;635 } elseif ( $wsal_lpn && ‘false’ === $wsal_lpn ) {636 // If option exists, value is false then set to false.637 $wsal_lpn = false;638 } elseif ( ! $wsal_lpn ) {639 // Default option value.640 $wsal_lpn = false;641 }642 ?>643 <label for="wsal_lpn_yes">644 <input type="radio" name="login_page_notification" id="wsal_lpn_yes" <?php checked( $wsal_lpn ); ?> value="true" />645 <?php esc_html_e( 'Yes’, ‘wp-security-audit-log’ ); ?>646 </label>647 <br />648 <?php649 // Get login page notification text.650 $wsal_lpn_text = $this->plugin->settings()->get_login_page_notification_text();651 if ( ! $wsal_lpn_text ) {652 $wsal_lpn_text = __( 'For security and auditing purposes, a record of all of your logged-in actions and changes within the WordPress dashboard will be recorded in an activity log with the <a href="https://wpactivitylog.com/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">WP Activity Log plugin</a>. The audit log also includes the IP address where you accessed this site from.’, ‘wp-security-audit-log’ );653 }654 // Allowed HTML tags for this setting.655 $allowed_tags = array(656 ‘a’ => array(657 ‘href’ => array(),658 ‘title’ => array(),659 ‘target’ => array(),660 ),661 );662663 ?>664 <textarea name="login_page_notification_text"665 id="login_page_notification_text"666 cols="60" rows="6"667 <?php echo ( $wsal_lpn ) ? false : 'disabled’; ?>668 ><?php echo wp_kses( $wsal_lpn_text, $allowed_tags ); ?></textarea>669 <br/>670 <p class="description">671 <?php echo wp_kses( __( '<strong>Note: </strong>’, ‘wp-security-audit-log’ ), $this->plugin->allowed_html_tags ) . esc_html__( 'The only HTML code allowed in the login page notification is for links ( < a href >< /a > ).’, ‘wp-security-audit-log’ ); // phpcs:ignore ?>672 </p>673 <br />674675 <label for="wsal_lpn_no">676 <input type="radio" name="login_page_notification" id="wsal_lpn_no" <?php checked( $wsal_lpn, false ); ?> value="false" />677 <?php esc_html_e( 'No’, ‘wp-security-audit-log’ ); ?>678 </label>679 </fieldset>680 </td>681 </tr>682 <!-- / Login Page Notification -->683 </tbody>684 </table>685 <!-- Login Page Notification -->686687 <h3><?php esc_html_e( 'Is your website running behind a firewall or reverse proxy?’, ‘wp-security-audit-log’ ); ?></h3>688 <p class="description">689 <?php690 echo sprintf(691 /* translators: Learn more link. */692 esc_html__( 'If your website is running behind a firewall set this option to yes so the plugin retrieves the end user’s IP address from the proxy header - %s.’, ‘wp-security-audit-log’ ),693 ‘<a href="https://wpactivitylog.com/support/kb/support-reverse-proxies-web-application-firewalls/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">’ . esc_html__( 'learn more’, ‘wp-security-audit-log’ ) . '</a>’694 );695 ?>696 </p>697 <table class="form-table wsal-tab">698 <tbody>699 <tr>700 <th><label for="pioption_on"><?php esc_html_e( 'Reverse Proxy / Firewall Options’, ‘wp-security-audit-log’ ); ?></label></th>701 <td>702 <fieldset>703 <label for="enable_proxy_ip_capture_yes">704 <input type="radio" name="EnableProxyIpCapture" value="1" id="enable_proxy_ip_capture_yes" <?php checked( $this->plugin->settings()->is_main_ip_from_proxy() ); ?> />705 <?php esc_html_e( 'Yes’, ‘wp-security-audit-log’ ); ?>706 </label>707 <br/>708 <label for="EnableIpFiltering">709 <input type="checkbox" name="EnableIpFiltering" value="1" id="EnableIpFiltering" <?php checked( $this->plugin->settings()->is_internal_ips_filtered() ); ?> />710 <?php esc_html_e( 'Filter internal IP addresses from the proxy headers. Enable this option only if you are are still seeing the internal IP addresses of the firewall or proxy.’, ‘wp-security-audit-log’ ); ?>711 </label>712 <br/>713 <label for="enable_proxy_ip_capture_no">714 <input type="radio" name="EnableProxyIpCapture" value="0" id="enable_proxy_ip_capture_no" <?php checked( $this->plugin->settings()->is_main_ip_from_proxy(), false ); ?> />715 <?php esc_html_e( 'No’, ‘wp-security-audit-log’ ); ?>716 </label>717 <br />718 </fieldset>719 </td>720 </tr>721 <!-- / Reverse Proxy / Firewall Options -->722 </tbody>723 </table>724 <!-- Reverse Proxy -->725726 <h3><?php esc_html_e( 'Who can change the plugin settings?’, ‘wp-security-audit-log’ ); ?></h3>727 <p class="description">728 <?php729 $allowed_tags = array(730 ‘a’ => array(731 ‘href’ => true,732 ‘target’ => true,733 ),734 );735 echo wp_kses(736 sprintf(737 /* translators: Learn more link. */738 esc_html__( 'By default only users with administrator role (single site) and super administrator role (multisite) can change the settings of the plugin. Though you can restrict the privileges to just your user - %s.’, ‘wp-security-audit-log’ ),739 ‘<a href="https://wpactivitylog.com/support/kb/managing-wordpress-activity-log-plugin-privileges/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">’ . __( 'learn more’, ‘wp-security-audit-log’ ) . '</a>’740 ),741 $allowed_tags742 );743 $restrict_settings = $this->plugin->settings()->get_restrict_plugin_setting();744 ?>745 </p>746 <table class="form-table wsal-tab">747 <tbody>748 <tr>749 <th><label for="RestrictAdmins"><?php esc_html_e( 'Restrict plugin access’, ‘wp-security-audit-log’ ); ?></label></th>750 <td>751 <fieldset>752 <label for="only_me">753 <input type="radio" name="restrict-plugin-settings" id="only_me" value="only_me" <?php checked( $restrict_settings, ‘only_me’ ); ?> />754 <?php esc_html_e( 'Only me’, ‘wp-security-audit-log’ ); ?>755 </label>756 <br/>757 <label for="only_admins">758 <input type="radio" name="restrict-plugin-settings" id="only_admins" value="only_admins" <?php checked( $restrict_settings, ‘only_admins’ ); ?> />759 <?php760 if ( WP_Helper::is_multisite() ) {761 esc_html_e( 'All superadmins’, ‘wp-security-audit-log’ );762 } else {763 esc_html_e( 'All administrators’, ‘wp-security-audit-log’ );764 }765 ?>766 </label>767 <br/>768 </fieldset>769 </td>770 </tr>771 <!-- / Restrict Plugin Access -->772 </tbody>773 </table>774 <!-- Restrict Plugin Access -->775776 <h3><?php esc_html_e( 'Allow other users to view the activity log’, ‘wp-security-audit-log’ ); ?></h3>777 <p class="description">778 <?php779 $is_multisite = WP_Helper::is_multisite();780 if ( $is_multisite ) {781 $section_label = esc_html__( ‘By default only super administrators and the child sites\’ administrators can view the WordPress activity log. Though you can change this by using the setting below.’, ‘wp-security-audit-log’ );782 } else {783 $section_label = esc_html__( ‘You can specify the username of the user that you want to allow. If you want to add all the users with a specific role, you can also specify their role here.’, ‘wp-security-audit-log’ );784 }785786 echo wp_kses(787 $section_label . ' - <a href="https://wpactivitylog.com/support/kb/allow-users-read-access-activity-log/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">’ . __( 'learn more’, ‘wp-security-audit-log’ ) . '</a>’,788 $allowed_tags789 );790 ?>791 </p>792 <?php if ( $is_multisite ) : ?>793 <table class="form-table wsal-tab">794 <tbody>795 <tr>796 <th><?php esc_html_e( 'Can view events’, ‘wp-security-audit-log’ ); ?></th>797 <td>798 <fieldset>799 <?php800 $restrict_settings = $this->plugin->settings()->get_restrict_log_viewer();801 $viewer_restriction_options = array(802 ‘only_me’ => __( 'Only me’, ‘wp-security-audit-log’ ),803 ‘only_superadmins’ => __( 'Super administators only’, ‘wp-security-audit-log’ ),804 ‘only_admins’ => __( 'Super administators and site administrators’, ‘wp-security-audit-log’ ),805 );806 ?>807 <?php foreach ( $viewer_restriction_options as $option => $label ) : ?>808 <label for="<?php esc_attr( ‘log_viewer_’ . $option ); ?>">809 <?php $disabled = ( ‘only_me’ === $option && ‘only_superadmins’ === $restrict_settings ); ?>810 <input type="radio" name="restrict-log-viewer" id="<?php esc_attr( ‘log_viewer_’ . $option ); ?>" value="<?php echo esc_attr( $option ); ?>" <?php checked( $restrict_settings, $option ); ?> <?php disabled( $disabled ); ?> />811 <?php echo esc_html( $label ); ?>812 </label>813 <br/>814 <?php endforeach; ?>815 </fieldset>816 </td>817 </tr>818 </tbody>819 </table>820 <p class="description"><?php esc_html_e( 'To allow someone who does not have an admin role to view the activity log, specify them in the below setting.’, ‘wp-security-audit-log’ ); ?></p>821 <?php endif; ?>822 <table class="form-table wsal-tab">823 <tbody>824 <tr>825 <?php $row_label = $is_multisite ? esc_html__( 'Can also view events’, ‘wp-security-audit-log’ ) : esc_html__( 'Can view events’, ‘wp-security-audit-log’ ); ?>826 <th><label for="ViewerQueryBox"><?php echo $row_label; // phpcs:ignore ?></label></th>827 <td>828 <fieldset>829 <label>830 <input type="text" id="ViewerQueryBox" style="width: 250px;">831 <input type="button" id="ViewerQueryAdd" class="button-primary" value="<?php esc_attr_e( 'Add’, ‘wp-security-audit-log’ ); ?>">832833 <p class="description">834 <?php esc_html_e( 'Specify the username or the users which do not have an admin role but can also see the WordPress activity role. You can also specify roles.’, ‘wp-security-audit-log’ ); ?>835 </p>836 </label>837838 <div id="ViewerList">839 <?php840 foreach ( $this->plugin->settings()->get_allowed_plugin_viewers() as $item ) :841 if ( wp_get_current_user()->user_login === $item ) {842 continue;843 }844 ?>845 <span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">846 <input type="hidden" name="Viewers[]" value="<?php echo esc_attr( $item ); ?>"/>847 <?php echo esc_html( $item ); ?>848 <a href="javascript:;" title="<?php esc_attr_e( 'Remove’, ‘wp-security-audit-log’ ); ?>">×</a>849 </span>850 <?php endforeach; ?>851 </div>852 </fieldset>853 </td>854 </tr>855 <!-- / Can View Alerts -->856 </tbody>857 </table>858 <!-- Can View Events -->859860 <h3><?php esc_html_e( 'Which email address should the plugin use as a from address?’, ‘wp-security-audit-log’ ); ?></h3>861 <p class="description"><?php esc_html_e( 'By default when the plugin sends an email notification it uses the email address specified in this website’s general settings. Though you can change the email address and display name from this section.’, ‘wp-security-audit-log’ ); ?></p>862 <table class="form-table wsal-tab">863 <tbody>864 <tr>865 <th><label for="FromEmail"><?php esc_html_e( 'From Email & Name’, ‘wp-security-audit-log’ ); ?></label></th>866 <td>867 <fieldset>868 <?php $use_email = \WSAL\Helpers\Settings_Helper::get_option_value( 'use-email’, ‘default_email’ ); ?>869 <label for="default_email">870 <input type="radio" name="use-email" id="default_email" value="default_email" <?php checked( $use_email, ‘default_email’ ); ?> />871 <?php esc_html_e( 'Use the email address from the WordPress general settings’, ‘wp-security-audit-log’ ); ?>872 </label>873 <br>874 <label for="custom_email">875 <input type="radio" name="use-email" id="custom_email" value="custom_email" <?php checked( $use_email, ‘custom_email’ ); ?> />876 <?php esc_html_e( 'Use another email address’, ‘wp-security-audit-log’ ); ?>877 </label>878 <br>879 <label for="FromEmail">880 <?php esc_html_e( 'Email Address’, ‘wp-security-audit-log’ ); ?>881 <input type="email" id="FromEmail" name="FromEmail" value="<?php echo esc_attr( $this->plugin->settings()->get_from_email() ); ?>" />882 </label>883 <br>884 <label for="DisplayName">885 <?php esc_html_e( 'Display Name’, ‘wp-security-audit-log’ ); ?> 886 <input type="text" id="DisplayName" name="DisplayName" value="<?php echo esc_attr( $this->plugin->settings()->get_display_name() ); ?>" />887 </label>888 </fieldset>889 </td>890 </tr>891 <!-- / From Email & Name -->892 </tbody>893 </table>894 <!-- From Email & Name -->895896 <?php897 $is_incognito = $this->plugin->settings()->is_incognito();898 ?>899 <h3><?php esc_html_e( 'Do you want to hide the plugin from the list of installed plugins?’, ‘wp-security-audit-log’ ); ?></h3>900 <p class="description"><?php esc_html_e( 'By default all installed plugins are listed in the plugins page. Set this option to Yes remove WP Activity Log from the list of installed plugins for users who are unable to access the WP Activity Log settings.’, ‘wp-security-audit-log’ ); ?></p>901 <table class="form-table wsal-tab">902 <tbody>903 <tr>904 <th><label for="incognito_yes"><?php esc_html_e( 'Hide Plugin in Plugins Page’, ‘wp-security-audit-log’ ); ?></label></th>905 <td>906 <fieldset <?php echo disabled( $incognito_setting_enforced_by_mainwp ); ?>>907 <label for="incognito_yes">908 <input type="radio" name="Incognito" value="yes" id="incognito_yes" <?php checked( $is_incognito ); ?> />909 <?php esc_html_e( 'Yes, hide the plugin and any WP Activity Log plugin extensions from the list of installed plugins’, ‘wp-security-audit-log’ ); ?>910 </label>911 <br/>912 <label for="incognito_no">913 <input type="radio" name="Incognito" value="no" id="incognito_no" <?php checked( $is_incognito, false ); ?> />914 <?php esc_html_e( 'No, do not hide the plugin’, ‘wp-security-audit-log’ ); ?>915 </label>916 </fieldset>917 </td>918 </tr>919 <!-- / Hide Plugin in Plugins Page -->920 </tbody>921 </table>922 <!-- Hide Plugin -->923 <?php924 }925926 /**927 * Save: `General`928 */929 private function tab_general_save() {930 // Get $_POST global array.931 $post_array = filter_input_array( INPUT_POST );932933 $this->plugin->settings()->set_refresh_alerts_enabled( $post_array[‘EnableAuditViewRefresh’] );934 $this->plugin->settings()->set_events_type_nav( sanitize_text_field( $post_array[‘events-type-nav’] ) );935 $this->plugin->settings()->set_use_email( sanitize_text_field( $post_array[‘use-email’] ) );936 $this->plugin->settings()->set_from_email( sanitize_email( $post_array[‘FromEmail’] ) );937 $this->plugin->settings()->set_display_name( sanitize_text_field( $post_array[‘DisplayName’] ) );938 $this->plugin->settings()->set_widgets_enabled( sanitize_text_field( $post_array[‘EnableDashboardWidgets’] ) );939940 if ( ! wsal_freemius()->is_free_plan() ) {941 $this->plugin->settings()->set_admin_bar_notif( sanitize_text_field( $post_array[‘admin_bar_notif’] ) );942 $this->plugin->settings()->set_admin_bar_notif_updates( sanitize_text_field( $post_array[‘admin_bar_notif_updates’] ) );943 }944945 // Handle log viewer settings in multisite context.946 if ( WP_Helper::is_multisite() ) {947 $log_viewer_restrictions = isset( $post_array[‘restrict-log-viewer’] ) ? sanitize_text_field( $post_array[‘restrict-log-viewer’] ) : '’;948 $this->plugin->settings()->set_restrict_log_viewer( $log_viewer_restrictions );949 if ( ‘only_me’ === $log_viewer_restrictions ) {950 $this->plugin->settings()->set_only_me_user_id( get_current_user_id() );951 }952 }953954 // Get plugin viewers.955 $viewers = isset( $post_array[‘Viewers’] ) ? array_map( 'sanitize_text_field’, $post_array[‘Viewers’] ) : array();956 $this->plugin->settings()->set_allowed_plugin_viewers( $viewers );957958 // Handle plugin settings permissions.959 $restrict_settings = isset( $post_array[‘restrict-plugin-settings’] ) ? sanitize_text_field( $post_array[‘restrict-plugin-settings’] ) : false;960 $this->plugin->settings()->set_restrict_plugin_setting( $restrict_settings );961 if ( ‘only_me’ === $restrict_settings ) {962 $this->plugin->settings()->set_only_me_user_id( get_current_user_id() );963 }964965 $this->plugin->settings()->set_login_page_notification( isset( $post_array[‘login_page_notification’] ) ? sanitize_text_field( $post_array[‘login_page_notification’] ) : false );966 $this->plugin->settings()->set_login_page_notification_text( isset( $post_array[‘login_page_notification_text’] ) ? $post_array[‘login_page_notification_text’] : false );967 $this->plugin->settings()->set_main_ip_from_proxy( isset( $post_array[‘EnableProxyIpCapture’] ) ? sanitize_text_field( $post_array[‘EnableProxyIpCapture’] ) : false );968 $this->plugin->settings()->set_internal_ips_filtering( isset( $post_array[‘EnableIpFiltering’] ) ? sanitize_text_field( $post_array[‘EnableIpFiltering’] ) : false );969970 $is_incognito = isset( $post_array[‘Incognito’] ) ? Settings_Helper::string_to_bool( sanitize_text_field( $post_array[‘Incognito’] ) ) : false;971 $this->plugin->settings()->set_incognito( $is_incognito );972 }973974 /**975 * Tab: `Audit Log`976 */977 private function tab_audit_log() {978 ?>979 <h3><?php esc_html_e( 'For how long do you want to keep the activity log events (Retention settings)?’, ‘wp-security-audit-log’ ); ?></h3>980 <p class="description">981 <?php982 esc_html_e( 'The plugin uses an efficient way to store the activity log data in the WordPress database, though the more data you keep the more disk space will be required. ', ‘wp-security-audit-log’ );983 $retention_help_text = __( '<a href="https://wpactivitylog.com/pricing/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">Upgrade to Premium</a> to store the activity log data in an external database.’, ‘wp-security-audit-log’ );984985 // phpcs:disable986 // phpcs:enable987 echo wp_kses( $retention_help_text, $this->plugin->allowed_html_tags );988 ?>989 </p>990991 <?php992 // phpcs:disable993 /* @free:start */994 // phpcs:enable995 // Ensure it doesn’t load a 2nd time for premium users.996 if ( ! wsal_freemius()->can_use_premium_code() ) {997 $this->render_retention_settings_table();998 }999 // phpcs:disable1000 /* @free:end */1001 // phpcs:enable1002 ?>10031004 <h3><?php esc_html_e( 'What timestamp you would like to see in the WordPress activity log?’, ‘wp-security-audit-log’ ); ?></h3>1005 <p class="description"><?php esc_html_e( ‘Note that the WordPress\’ timezone might be different from that configured on the server so when you switch from UTC to WordPress timezone or vice versa you might notice a big difference.’, ‘wp-security-audit-log’ ); ?></p>1006 <table class="form-table wsal-tab">1007 <tbody>1008 <tr>1009 <th><label for="timezone-default"><?php esc_html_e( 'Events Timestamp’, ‘wp-security-audit-log’ ); ?></label></th>1010 <td>1011 <fieldset>1012 <?php1013 $timezone = Settings_Helper::get_timezone();10141015 /**1016 * Transform timezone values.1017 *1018 * @since 3.2.31019 */1020 if ( ‘0’ === $timezone ) {1021 $timezone = 'utc’;1022 } elseif ( ‘1’ === $timezone ) {1023 $timezone = 'wp’;1024 }1025 ?>1026 <label for="timezone-default">1027 <input type="radio" name="Timezone" id="timezone-default" style="margin-top: -2px;"1028 <?php checked( $timezone, ‘utc’ ); ?> value="utc">1029 <?php esc_html_e( 'UTC’, ‘wp-security-audit-log’ ); ?>1030 </label>1031 <br/>1032 <label for="timezone">1033 <input type="radio" name="Timezone" id="timezone" style="margin-top: -2px;"1034 <?php checked( $timezone, ‘wp’ ); ?> value="wp">1035 <?php esc_html_e( 'Timezone configured on this WordPress website’, ‘wp-security-audit-log’ ); ?>1036 </label>1037 </fieldset>1038 </td>1039 </tr>1040 <!-- Alerts Timestamp -->1041 <tr>1042 <th><?php esc_html_e( 'Show Milliseconds’, ‘wp-security-audit-log’ ); ?></th>1043 <td>1044 <fieldset>1045 <?php $show_milliseconds = Settings_Helper::get_show_milliseconds(); ?>1046 <label for="show_milliseconds">1047 <input type="checkbox" name="show_milliseconds" id="show_milliseconds" style="margin-top: -2px;"1048 <?php checked( $show_milliseconds ); ?> value="yes">1049 <?php esc_html_e( 'Show Milliseconds in list view’, ‘wp-security-audit-log’ ); ?>1050 </label>1051 </fieldset>1052 </td>1053 </tr>1054 <!-- Alerts Timestamp -->1055 </tbody>1056 </table>1057 <!-- Timestamp -->10581059 <h3><?php esc_html_e( 'What user information should be displayed in the WordPress activity log?’, ‘wp-security-audit-log’ ); ?></h3>1060 <p class="description"><?php esc_html_e( 'Usernames might not be the same as a user\’s first and last name so it can be difficult to recognize whose user was that did a change. When there is no first & last name or public display name configured the plugin will revert back to the WordPress username.’, ‘wp-security-audit-log’ ); ?></p>1061 <table class="form-table wsal-tab">1062 <tbody>1063 <tr>1064 <th><label for="timezone-default"><?php esc_html_e( 'User information in Activity log’, ‘wp-security-audit-log’ ); ?></label></th>1065 <td>1066 <fieldset>1067 <?php $type_username = $this->plugin->settings()->get_type_username(); ?>1068 <label for="column_username">1069 <input type="radio" name="type_username" id="column_username" style="margin-top: -2px;" <?php checked( $type_username, ‘username’ ); ?> value="username">1070 <span><?php esc_html_e( 'WordPress username’, ‘wp-security-audit-log’ ); ?></span>1071 </label>1072 <br/>1073 <label for="columns_first_last_name">1074 <input type="radio" name="type_username" id="columns_first_last_name" style="margin-top: -2px;" <?php checked( $type_username, ‘first_last_name’ ); ?> value="first_last_name">1075 <span><?php esc_html_e( 'First name & last name’, ‘wp-security-audit-log’ ); ?></span>1076 </label>1077 <br/>1078 <label for="columns_display_name">1079 <input type="radio" name="type_username" id="columns_display_name" style="margin-top: -2px;" <?php checked( $type_username, ‘display_name’ ); ?> value="display_name">1080 <span><?php esc_html_e( 'Configured public display name’, ‘wp-security-audit-log’ ); ?></span>1081 </label>1082 </fieldset>1083 </td>1084 </tr>1085 <!-- Select type of name -->1086 </tbody>1087 </table>1088 <!-- User Information -->10891090 <h3><?php esc_html_e( 'Select the columns to be displayed in the WordPress activity log’, ‘wp-security-audit-log’ ); ?></h3>1091 <p class="description"><?php esc_html_e( 'When you deselect a column it won’t be shown in the activity log viewer in both views. The data will still be recorded by the plugin.’, ‘wp-security-audit-log’ ); ?></p>1092 <table class="form-table wsal-tab">1093 <tbody>1094 <tr>1095 <th><label for="columns"><?php esc_html_e( 'Activity log columns selection’, ‘wp-security-audit-log’ ); ?></label></th>1096 <td>1097 <fieldset>1098 <?php $columns = $this->plugin->settings()->get_columns(); ?>1099 <?php foreach ( $columns as $key => $value ) { ?>1100 <label for="columns">1101 <input type="checkbox" name="Columns[<?php echo esc_attr( $key ); ?>]" id="<?php echo esc_attr( $key ); ?>" class="sel-columns" style="margin-top: -2px;"1102 <?php checked( $value, ‘1’ ); ?> value="1">1103 <?php if ( ‘alert_code’ === $key ) : ?>1104 <span><?php esc_html_e( 'Event ID’, ‘wp-security-audit-log’ ); ?></span>1105 <?php elseif ( ‘type’ === $key ) : ?>1106 <span><?php esc_html_e( 'Severity’, ‘wp-security-audit-log’ ); ?></span>1107 <?php elseif ( ‘date’ === $key ) : ?>1108 <span><?php esc_html_e( 'Date & Time’, ‘wp-security-audit-log’ ); ?></span>1109 <?php elseif ( ‘username’ === $key ) : ?>1110 <span><?php esc_html_e( 'User’, ‘wp-security-audit-log’ ); ?></span>1111 <?php elseif ( ‘source_ip’ === $key ) : ?>1112 <span><?php esc_html_e( 'Source IP Address’, ‘wp-security-audit-log’ ); ?></span>1113 <?php elseif ( ‘info’ === $key ) : ?>1114 <span><?php esc_html_e( 'Info (used in Grid view mode only)', ‘wp-security-audit-log’ ); ?></span>1115 <?php else : ?>1116 <span><?php echo esc_html( ucwords( str_replace( '_’, ' ', $key ) ) ); ?></span>1117 <?php endif; ?>1118 </label>1119 <br/>1120 <?php } ?>1121 </fieldset>1122 </td>1123 </tr>1124 <!-- Activity log columns selection -->1125 </tbody>1126 </table>1127 <!-- Activity log columns -->11281129 <?php $is_wp_backend = $this->plugin->settings()->is_wp_backend(); ?>1130 <h3><?php esc_html_e( 'Do you want to keep a log of WordPress background activity?’, ‘wp-security-audit-log’ ); ?></h3>1131 <p class="description">1132 <?php esc_html_e( 'WordPress does a lot of things in the background that you do not necessarily need to know about, such as; deletion of post revisions, deletion of auto saved drafts etc. By default the plugin does not report them since there might be a lot and are irrelevant to the user.’, ‘wp-security-audit-log’ ); ?>1133 </p>1134 <table class="form-table wsal-tab">1135 <tbody>1136 <tr>1137 <th><label for="wp_backend_no"><?php esc_html_e( 'Enable Events for WordPress Background Activity’, ‘wp-security-audit-log’ ); ?></label></th>1138 <td>1139 <fieldset>1140 <label for="wp_backend_yes">1141 <input type="radio" name="WPBackend" value="1" id="wp_backend_yes" <?php checked( $is_wp_backend ); ?> />1142 <?php esc_html_e( 'Yes’, ‘wp-security-audit-log’ ); ?>1143 </label>1144 <br/>1145 <label for="wp_backend_no">1146 <input type="radio" name="WPBackend" value="0" id="wp_backend_no" <?php checked( ! $is_wp_backend ); ?> />1147 <?php esc_html_e( 'No’, ‘wp-security-audit-log’ ); ?>1148 </label>1149 </fieldset>1150 </td>1151 </tr>1152 <!-- Disable Alerts for WordPress Background activity -->1153 </tbody>1154 </table>1155 <!-- Background Events -->1156 <?php1157 }11581159 /**1160 * Save: `Audit Log`1161 */1162 private function tab_audit_log_save() {1163 // Get $_POST global array.1164 $post_array = filter_input_array( INPUT_POST );11651166 // Get pruning date.1167 $pruning_date = isset( $post_array[‘PruningDate’] ) ? (int) sanitize_text_field( $post_array[‘PruningDate’] ) : false;1168 $pruning_unit = isset( $post_array[‘pruning-unit’] ) ? sanitize_text_field( $post_array[‘pruning-unit’] ) : false;1169 $pruning_date = ( ! empty( $pruning_date ) && ! empty( $pruning_unit ) ) ? $pruning_date . ' ' . $pruning_unit : false;11701171 $pruning_enabled = isset( $post_array[‘PruneBy’] ) ? ‘date’ === $post_array[‘PruneBy’] : '’;1172 $this->plugin->settings()->set_pruning_date_settings( $pruning_enabled, $pruning_date, $pruning_unit );1173 $this->plugin->settings()->set_timezone( $post_array[‘Timezone’] );1174 $this->plugin->settings()->set_type_username( $post_array[‘type_username’] );1175 $this->plugin->settings()->set_wp_backend( isset( $post_array[‘WPBackend’] ) ? sanitize_text_field( $post_array[‘WPBackend’] ) : false );1176 if ( ! empty( $post_array[‘Columns’] ) ) {1177 $this->plugin->settings()->set_columns( $post_array[‘Columns’] );1178 }1179 $show_milliseconds = isset( $post_array[‘show_milliseconds’] ) && ‘yes’ === $post_array[‘show_milliseconds’];1180 $this->plugin->settings()->set_show_milliseconds( $show_milliseconds );1181 }11821183 /**1184 * Tab: `File Changes`1185 */1186 private function tab_file_changes() {1187 ?>11881189 <table class="form-table wsal-tab">1190 <tbody>1191 <tr>1192 <?php if ( ! defined( ‘WFCM_PLUGIN_FILE’ ) ) : ?>1193 <div class="addon-wrapper" style="max-width: 380px; text-align: center; border: 1px solid #ccc; padding: 25px;">1194 <img src="<?php echo esc_html( trailingslashit( WSAL_BASE_URL ) . ‘img/help/website-file-changes-monitor.jpg’ ); ?>">1195 <h4><?php echo esc_html__( 'Website File Changes Monitor’, ‘wp-security-audit-log’ ); ?></h4>1196 <p><?php echo esc_html__( 'To keep a log of file changes please install Website File Changes Monitor, a plugin which is also developed by us.’, ‘wp-security-audit-log’ ); ?></p><br>1197 <p><button class="install-addon button button-primary" data-nonce="<?php echo esc_attr( wp_create_nonce( ‘wsal-install-addon’ ) ); ?>" data-plugin-slug="website-file-changes-monitor/website-file-changes-monitor.php" data-plugin-download-url="https://downloads.wordpress.org/plugin/website-file-changes-monitor.latest-stable.zip"><?php esc_html_e( 'Install plugin now’, ‘wp-security-audit-log’ ); ?></button><span class="spinner" style="display: none; visibility: visible; float: none; margin: 0 0 0 8px;"></span> <a href="https://wpactivitylog.com/support/kb/wordpress-files-changes-warning-activity-logs/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" rel="noopener noreferrer" target="_blank" style="margin-left: 15px;"><?php esc_html_e( 'Learn More’, ‘wp-security-audit-log’ ); ?></a></p>1198 </div>1199 <?php else : ?>1200 <?php1201 $redirect_args = array(1202 ‘page’ => 'wfcm-file-changes’,1203 );1204 if ( ! WP_Helper::is_multisite() ) {1205 $wcfm_settings_page = add_query_arg( $redirect_args, admin_url( ‘admin.php’ ) );1206 } else {1207 $wcfm_settings_page = add_query_arg( $redirect_args, network_admin_url( ‘admin.php’ ) );1208 }1209 ?>1210 <p><?php echo esc_html__( 'Configure how often file changes scan run and other settings from the’, ‘wp-security-audit-log’ ); ?> <a class="button button-primary" href="<?php echo esc_url( $wcfm_settings_page ); ?>"><?php echo esc_html__( 'Website File Changes plugin settings’, ‘wp-security-audit-log’ ); ?></a></p>1211 <?php endif; ?>1212 </tr>1213 </tbody>1214 </table>1215 <!-- / File Changes Logging Tab -->1216 <?php1217 }12181219 /**1220 * Tab: `Exclude Objects`1221 */1222 private function tab_exclude_objects() {1223 ?>1224 <p class="description"><?php esc_html_e( 'By default the plugin keeps a log of all user changes done on your WordPress website. Use the setting below to exclude any objects from the activity log. When an object is excluded from the activity log, any event in which that object is referred will not be logged in the activity log.’, ‘wp-security-audit-log’ ); ?></p>1225 <table class="form-table wsal-tab">1226 <tbody>1227 <tr>1228 <th><label for="ExUserQueryBox"><?php esc_html_e( 'Exclude Users:’, ‘wp-security-audit-log’ ); ?></label></th>1229 <td>1230 <fieldset>1231 <input type="text" id="ExUserQueryBox" style="width: 250px;">1232 <input type="button" id="ExUserQueryAdd" class="button-primary" value="<?php esc_attr_e( 'Add’, ‘wp-security-audit-log’ ); ?>">1233 <br style="clear: both;"/>1234 <div id="ExUserList">1235 <?php foreach ( \WSAL\Helpers\Settings_Helper::get_excluded_monitoring_users() as $item ) : ?>1236 <span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">1237 <input type="hidden" name="ExUsers[]" value="<?php echo esc_attr( $item ); ?>"/>1238 <?php echo esc_html( $item ); ?>1239 <a href="javascript:;" title="<?php esc_attr_e( 'Remove’, ‘wp-security-audit-log’ ); ?>">×</a>1240 </span>1241 <?php endforeach; ?>1242 </div>1243 </fieldset>1244 </td>1245 </tr>1246 <!-- Exclude Users -->12471248 <tr>1249 <th><label for="ExRoleQueryBox"><?php esc_html_e( 'Exclude Roles:’, ‘wp-security-audit-log’ ); ?></label></th>1250 <td>1251 <fieldset>1252 <input type="text" id="ExRoleQueryBox" style="width: 250px;">1253 <input type="button" id="ExRoleQueryAdd" class="button-primary" value="<?php esc_attr_e( 'Add’, ‘wp-security-audit-log’ ); ?>">1254 <br style="clear: both;"/>1255 <div id="ExRoleList">1256 <?php foreach ( \WSAL\Helpers\Settings_Helper::get_excluded_monitoring_roles() as $item ) : ?>1257 <span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">1258 <input type="hidden" name="ExRoles[]" value="<?php echo esc_attr( $item ); ?>"/>1259 <?php echo esc_html( $item ); ?>1260 <a href="javascript:;" title="<?php esc_attr_e( 'Remove’, ‘wp-security-audit-log’ ); ?>">×</a>1261 </span>1262 <?php endforeach; ?>1263 </div>1264 </fieldset>1265 </td>1266 </tr>1267 <!-- Exclude Roles -->12681269 <tr>1270 <th><label for="IpAddrQueryBox"><?php esc_html_e( 'Exclude IP Address(es):’, ‘wp-security-audit-log’ ); ?></label></th>1271 <td>1272 <fieldset>1273 <input type="text" id="IpAddrQueryBox" style="width: 250px;">1274 <input type="button" id="IpAddrQueryAdd" class="button-primary" value="<?php esc_attr_e( 'Add’, ‘wp-security-audit-log’ ); ?>">1275 <br style="clear: both;"/>1276 <div id="IpAddrList">1277 <?php foreach ( \WSAL\Helpers\Settings_Helper::get_excluded_monitoring_ip() as $item ) : ?>1278 <span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">1279 <input type="hidden" name="IpAddrs[]" value="<?php echo esc_attr( $item ); ?>"/>1280 <?php echo esc_html( $item ); ?>1281 <a href="javascript:;" title="<?php esc_attr_e( 'Remove’, ‘wp-security-audit-log’ ); ?>">×</a>1282 </span>1283 <?php endforeach; ?>1284 </div>1285 </fieldset>1286 <p class="description"><?php esc_html_e( 'You can exclude an individual IP address or a range of IP addresses. To exclude a range use the following format: [first IP]-[last octet of the last IP]. Example: 172.16.180.6-127.’, ‘wp-security-audit-log’ ); ?></p>1287 </td>1288 </tr>1289 <!-- Exclude IP Addresses -->12901291 <tr>1292 <th><label for="ExCPTsQueryBox"><?php esc_html_e( 'Exclude Post Type:’, ‘wp-security-audit-log’ ); ?></label></th>1293 <td>1294 <fieldset>1295 <input type="text" id="ExCPTsQueryBox" style="width: 250px;">1296 <input type="button" id="ExCPTsQueryAdd" class="button-primary" value="<?php esc_attr_e( 'Add’, ‘wp-security-audit-log’ ); ?>">1297 <br style="clear: both;"/>1298 <div id="ExCPTsList">1299 <?php foreach ( \WSAL\Helpers\Settings_Helper::get_excluded_post_types() as $item ) : ?>1300 <span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">1301 <input type="hidden" name="ExCPTss[]" value="<?php echo esc_attr( $item ); ?>"/>1302 <?php echo esc_html( $item ); ?>1303 <a href="javascript:;" title="<?php esc_attr_e( 'Remove’, ‘wp-security-audit-log’ ); ?>">×</a>1304 </span>1305 <?php endforeach; ?>1306 </div>1307 </fieldset>1308 <p class="description"><?php esc_html_e( 'WordPress has the post and page post types by default though your website might use more post types (custom post types). You can exclude all post types, including the default WordPress ones.’, ‘wp-security-audit-log’ ); ?></p>1309 </td>1310 </tr>1311 <!-- Exclude Custom Post Types -->13121313 <?php1314 $this->renderMetaExclusionSection(1315 esc_html__( 'Exclude custom post fields:’, ‘wp-security-audit-log’ ),1316 \WSAL\Helpers\Settings_Helper::get_excluded_post_meta_fields(),1317 'PostMeta’1318 );1319 ?>1320 <!-- Exclude Custom Post Fields -->13211322 <?php1323 $this->renderMetaExclusionSection(1324 esc_html__( 'Exclude custom user fields:’, ‘wp-security-audit-log’ ),1325 \WSAL\Helpers\Settings_Helper::get_excluded_user_meta_fields(),1326 'UserMeta’1327 );1328 ?>1329 <!-- Exclude Custom User Fields -->13301331 </tbody>1332 </table>1333 <!-- / Exclude Objects Tab -->1334 <?php1335 }13361337 /**1338 * Renders form section for excluding metadata of certain object type.1339 *1340 * @param string $title Section title.1341 * @param array $values Values.1342 * @param string $type Object type.1343 */1344 private function renderMetaExclusionSection( $title, $values, $type ) {1345 // @codingStandardsIgnoreStart1346 ?>1347 <tr>1348 <th><label for="Custom<?php echo $type; ?>QueryBox"><?php echo $title; ?></label></th>1349 <td>1350 <fieldset data-type="<?php echo $type; ?>">1351 <input type="text" id="<?php echo $type; ?>QueryBox" class="js-query-box" style="width: 250px;">1352 <input type="button" id="<?php echo $type; ?>QueryAdd" class="js-query-add button-primary"1353 value="<?php esc_attr_e( 'Add’, ‘wp-security-audit-log’ ); ?>">1354 <br style="clear: both;"/>1355 <div id="<?php echo $type; ?>List" class="js-list">1356 <?php foreach ( $values as $item ) : ?>1357 <span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">1358 <input type="hidden" name="<?php echo $type; ?>s[]“1359 value="<?php echo esc_attr( $item ); ?>"/>1360 <?php echo esc_html( $item ); ?>1361 <a href="javascript:;” title="<?php esc_attr_e( 'Remove’, ‘wp-security-audit-log’ ); ?>">×</a>1362 </span>1363 <?php endforeach; ?>1364 </div>1365 </fieldset>1366 <p class="description"><?php esc_html_e( 'You can use the * wildcard to exclude multiple matching custom fields. For example to exclude all custom fields starting with wp123 enter wp123*’, ‘wp-security-audit-log’ ); ?></p>1367 </td>1368 </tr>1369 <?php1370 // @codingStandardsIgnoreEnd1371 }13721373 /**1374 * Save: `Exclude Objects`1375 */1376 private function tab_exclude_objects_save() {1377 // Get $_POST global array.1378 $post_array = filter_input_array( INPUT_POST );13791380 \WSAL\Helpers\Settings_Helper::set_excluded_monitoring_users( isset( $post_array[‘ExUsers’] ) ? $post_array[‘ExUsers’] : array() );1381 \WSAL\Helpers\Settings_Helper::set_excluded_monitoring_roles( isset( $post_array[‘ExRoles’] ) ? $post_array[‘ExRoles’] : array() );1382 \WSAL\Helpers\Settings_Helper::set_excluded_post_meta_fields( isset( $post_array[‘PostMetas’] ) ? $post_array[‘PostMetas’] : array() );1383 \WSAL\Helpers\Settings_Helper::set_excluded_user_meta_fields( isset( $post_array[‘UserMetas’] ) ? $post_array[‘UserMetas’] : array() );1384 $this->plugin->settings()->set_excluded_monitoring_ip( isset( $post_array[‘IpAddrs’] ) ? $post_array[‘IpAddrs’] : array() );1385 $this->plugin->settings()->set_excluded_post_types( isset( $post_array[‘ExCPTss’] ) ? $post_array[‘ExCPTss’] : array() );1386 }13871388 /**1389 * Tab: `Advanced Settings`1390 */1391 private function tab_advanced_settings() {1392 ?>1393 <p class="description">1394 <?php esc_html_e( 'These settings are for advanced users.’, ‘wp-security-audit-log’ ); ?>1395 <?php echo sprintf( __( 'If you have any questions <a href="https://wpactivitylog.com/contact/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">contact us</a>.’, ‘wp-security-audit-log’ ), $this->plugin->allowed_html_tags ); // phpcs:ignore ?>1396 </p>13971398 <h3><?php esc_html_e( 'Reset plugin settings to default’, ‘wp-security-audit-log’ ); ?></h3>1399 <p class="description"><?php _e( 'Use this button to <em>factory reset</em> the plugin. This means that all the configured settings will be reset to default and all email notifications, scheduled reports, external database / third party services connections, archiving and mirroring rule will be deleted. NOTE: the activity log data will not be purged. Use the setting below to purge the activity log.’, ‘wp-security-audit-log’ ); // phpcs:ignore ?></p>1400 <table class="form-table wsal-tab">1401 <tbody>1402 <tr>1403 <th><?php esc_html_e( 'Reset Settings’, ‘wp-security-audit-log’ ); ?></th>1404 <td>1405 <a href="#wsal_reset_settings" class="button-primary js-settings-reset"><?php esc_html_e( 'RESET’, ‘wp-security-audit-log’ ); ?></a>1406 </td>1407 </tr>1408 </tbody>1409 </table>14101411 <h3><?php esc_html_e( 'Purge the WordPress activity log’, ‘wp-security-audit-log’ ); ?></h3>1412 <p class="description"><?php esc_html_e( 'Click the Purge button below to delete all the data from the WordPress activity log and start afresh.’, ‘wp-security-audit-log’ ); ?></p>1413 <table class="form-table wsal-tab">1414 <tbody>1415 <tr>1416 <th><?php esc_html_e( 'Purge Activity Log’, ‘wp-security-audit-log’ ); ?></th>1417 <td>1418 <a href="#wsal_purge_activity" class="button-primary js-purge-reset"><?php esc_html_e( 'PURGE’, ‘wp-security-audit-log’ ); ?></a>1419 <!-- <span class="notice purge-notice notice-success" style="display: none; margin-left: 10px; padding: 6px 10px;"><?php esc_html_e( 'Activity log successfully purged’, ‘wp-security-audit-log’ ); ?></span> -->1420 </td>1421 </tr>1422 </tbody>1423 </table>14241425 <?php $stealth_mode = $this->plugin->settings()->is_stealth_mode(); ?>1426 <h3><?php esc_html_e( 'MainWP Child Site Stealth Mode’, ‘wp-security-audit-log’ ); ?></h3>1427 <p class="description"><?php esc_html_e( 'This option is enabled automatically when the plugin detects the MainWP Child plugin on the site. When this setting is enabled plugin access is restricted to the administrator who installs the plugin, the plugin is not shown in the list of installed plugins and no admin notifications are shown. Disable this option to change the plugin to the default setup.’, ‘wp-security-audit-log’ ); ?></p>1428 <table class="form-table wsal-tab">1429 <tbody>1430 <tr>1431 <th><label for="mwp_stealth_mode"><?php esc_html_e( 'Enable MainWP Child Site Stealth Mode’, ‘wp-security-audit-log’ ); ?></label></th>1432 <td>1433 <fieldset <?php echo ! WpSecurityAuditLog::is_mainwp_active() ? ‘disabled’ : false; ?>>1434 <label for="mwp_stealth_yes">1435 <input type="radio" name="mwp_stealth_mode" value="yes" id="mwp_stealth_yes" <?php checked( $stealth_mode ); ?> />1436 <?php esc_html_e( 'Yes’, ‘wp-security-audit-log’ ); ?>1437 </label>1438 <br>1439 <label for="mwp_stealth_no">1440 <input type="radio" name="mwp_stealth_mode" value="no" id="mwp_stealth_no"1441 <?php checked( $stealth_mode, false ); ?>1442 />1443 <?php esc_html_e( 'No’, ‘wp-security-audit-log’ ); ?>1444 </label>1445 </fieldset>1446 </td>1447 </tr>1448 <!-- / MainWP Child Site Stealth Mode -->1449 <?php $admin_blocking_plugins_support = $this->plugin->settings()->get_admin_blocking_plugin_support(); ?>1450 <tr>1451 <th>1452 <label for="mwp_admin_blocking_support"><?php esc_html_e( 'Admin blocking plugins support’, ‘wp-security-audit-log’ ); ?></label>1453 </th>1454 <td>1455 <fieldset>1456 <label for="mwp_admin_blocking_support">1457 <input type="checkbox" name="mwp_admin_blocking_support" value="yes"1458 id="mwp_admin_blocking_support" <?php checked( $admin_blocking_plugins_support ); ?> <?php disabled( ! WpSecurityAuditLog::is_mainwp_active() || ! $stealth_mode ); ?>/>1459 <?php esc_html_e( 'Enable early plugin loading on sites that use admin blocking plugins’, ‘wp-security-audit-log’ ); ?>1460 </label>1461 </fieldset>1462 </td>1463 </tr>1464 <!-- / Admin blocking plugins support -->1465 </tbody>1466 </table>14671468 <?php1469 $data_deletion_enabled = $this->plugin->settings()->is_delete_data();1470 ?>1471 <h3><?php esc_html_e( 'Do you want to delete the plugin data from the database upon uninstall?’, ‘wp-security-audit-log’ ); ?></h3>1472 <p class="description"><?php esc_html_e( 'The plugin saves the activity log data and settings in the WordPress database. By default upon uninstalling the plugin the data is kept in the database so if it is installed again, you can still access the data. If the data is deleted it is not possible to recover it so you won\’t be able to access it again even when you reinstall the plugin.’, ‘wp-security-audit-log’ ); ?></p>1473 <table class="form-table wsal-tab">1474 <tbody>1475 <tr>1476 <th><label for="DeleteData"><?php esc_html_e( 'Remove Data on Uninstall’, ‘wp-security-audit-log’ ); ?></label></th>1477 <td>1478 <fieldset>1479 <label for="delete_data_yes">1480 <input type="radio" name="DeleteData" value="1" id="delete_data_yes" onclick="return delete_confirm(this);"1481 <?php checked( $data_deletion_enabled ); ?>1482 />1483 <?php esc_html_e( 'Yes’, ‘wp-security-audit-log’ ); ?>1484 </label>1485 <br>1486 <label for="delete_data_no">1487 <input type="radio" name="DeleteData" value="0" id="delete_data_no"1488 <?php checked( $data_deletion_enabled, false ); ?>1489 />1490 <?php esc_html_e( 'No’, ‘wp-security-audit-log’ ); ?>1491 </label>1492 </fieldset>1493 </td>1494 </tr>1495 <!-- / Remove Data on Uninstall -->1496 </tbody>1497 </table>14981499 <div class="remodal" data-remodal-id="wsal_reset_settings">1500 <button data-remodal-action="close" class="remodal-close"></button>1501 <h3><?php esc_html_e( 'Are you sure you want to reset all the plugin settings to default? This action cannot be undone.’, ‘wp-security-audit-log’ ); ?></h3>1502 <br>1503 <input type="hidden" id="wsal-reset-settings-nonce" value="<?php echo esc_attr( wp_create_nonce( ‘wsal-reset-settings’ ) ); ?>">1504 <button data-remodal-action="confirm" class="remodal-confirm"><?php esc_html_e( ‘Yes’ ); ?></button>1505 <button data-remodal-action="cancel" class="remodal-cancel"><?php esc_html_e( ‘No’ ); ?></button>1506 </div>1507 <!-- Reset Settings Modal -->15081509 <div class="remodal" data-remodal-id="wsal_purge_activity">1510 <button data-remodal-action="close" class="remodal-close"></button>1511 <h3><?php esc_html_e( 'Are you sure you want to purge all the activity log data?’, ‘wp-security-audit-log’ ); ?></h3>1512 <br>1513 <input type="hidden" id="wsal-purge-activity-nonce" value="<?php echo esc_attr( wp_create_nonce( ‘wsal-purge-activity’ ) ); ?>">1514 <button data-remodal-action="confirm" class="remodal-confirm"><?php esc_html_e( 'Yes’, ‘wp-security-audit-log’ ); ?></button>1515 <button data-remodal-action="cancel" class="remodal-cancel"><?php esc_html_e( 'No’, ‘wp-security-audit-log’ ); ?></button>1516 </div>1517 <!-- Purge Activity Log Modal -->1518 <?php1519 }15201521 /**1522 * Save: `Advanced Settings`1523 *1524 * @throws Exception - MainWP Child plugin not active exception.1525 */1526 private function tab_advanced_settings_save() {1527 // Get $_POST global array.1528 $post_array = filter_input_array( INPUT_POST );15291530 $this->plugin->settings()->set_delete_data( isset( $post_array[‘DeleteData’] ) ? sanitize_text_field( $post_array[‘DeleteData’] ) : false );15311532 $stealth_mode = isset( $post_array[‘mwp_stealth_mode’] ) ? $post_array[‘mwp_stealth_mode’] : false;1533 if ( ‘yes’ === $stealth_mode ) {1534 if ( ! WpSecurityAuditLog::is_mainwp_active() ) {1535 throw new Exception( __( 'MainWP Child plugin is not active on this website.’, ‘wp-security-audit-log’ ) );1536 }1537 $this->plugin->settings()->set_mainwp_child_stealth_mode();15381539 $admin_blocking_plugins_support = isset( $post_array[‘mwp_admin_blocking_support’] ) ? $post_array[‘mwp_admin_blocking_support’] : false;1540 if ( ‘yes’ === $admin_blocking_plugins_support ) {1541 $this->plugin->settings()->set_admin_blocking_plugin_support( true );1542 }1543 } else {1544 $this->plugin->settings()->deactivate_mainwp_child_stealth_mode();1545 }1546 }15471548 /**1549 * {@inheritDoc}1550 */1551 public function header() {1552 wp_enqueue_style(1553 'settings’,1554 WSAL_BASE_URL . '/css/settings.css’,1555 array(),1556 WSAL_VERSION1557 );15581559 // Check current tab.1560 if ( ! empty( $this->current_tab ) && ‘advanced-settings’ === $this->current_tab ) {1561 // Remodal styles.1562 wp_enqueue_style( 'wsal-remodal’, WSAL_BASE_URL . 'css/remodal.css’, array(), WSAL_VERSION );1563 wp_enqueue_style( 'wsal-remodal-theme’, WSAL_BASE_URL . 'css/remodal-default-theme.css’, array(), WSAL_VERSION );1564 }1565 ?>1566 <style type="text/css">1567 .wsal-tab {1568 /* display: none; */1569 }1570 .wsal-tab tr.alert-incomplete td {1571 color: #9BE;1572 }1573 .wsal-tab tr.alert-unavailable td {1574 color: #CCC;1575 }1576 </style>1577 <?php1578 }15791580 /**1581 * {@inheritDoc}1582 */1583 public function footer() {1584 // Enqueue jQuery UI from core.1585 wp_enqueue_script(1586 'wsal-jquery-ui’,1587 '//code.jquery.com/ui/1.10.3/jquery-ui.js’,1588 array(),1589 '1.10.3’,1590 false1591 );15921593 // Check current tab.1594 if ( ! empty( $this->current_tab ) && ‘advanced-settings’ === $this->current_tab ) {1595 // Remodal script.1596 wp_enqueue_script(1597 'wsal-remodal-js’,1598 WSAL_BASE_URL . 'js/remodal.min.js’,1599 array(),1600 WSAL_VERSION,1601 true1602 );1603 }16041605 // Register settings script.1606 wp_register_script(1607 'settings’,1608 WSAL_BASE_URL . '/js/settings.js’,1609 array(),1610 WSAL_VERSION,1611 true1612 );1613 // Passing nonce for security to JS file.1614 $wsal_data = array(1615 ‘wp_nonce’ => wp_create_nonce( ‘wsal-exclude-nonce’ ),1616 ‘invalidURL’ => esc_html__( 'The specified value is not a valid URL!’, ‘wp-security-audit-log’ ),1617 ‘invalidCPT’ => esc_html__( 'The specified value is not a valid post type!’, ‘wp-security-audit-log’ ),1618 ‘invalidIP’ => esc_html__( 'The specified value is not a valid IP address!’, ‘wp-security-audit-log’ ),1619 ‘invalidUser’ => esc_html__( 'The specified value is not a user nor a role!’, ‘wp-security-audit-log’ ),1620 ‘invalidFile’ => esc_html__( 'Filename cannot be added because it contains invalid characters.’, ‘wp-security-audit-log’ ),1621 ‘invalidFileExt’ => esc_html__( 'File extension cannot be added because it contains invalid characters.’, ‘wp-security-audit-log’ ),1622 ‘invalidDir’ => esc_html__( 'Directory cannot be added because it contains invalid characters.’, ‘wp-security-audit-log’ ),1623 ‘remove’ => esc_html__( 'Remove’, ‘wp-security-audit-log’ ),1624 ‘saveSettingsChanges’ => esc_html__( 'Please save any changes before switching tabs.’, ‘wp-security-audit-log’ ),1625 );1626 wp_localize_script( 'settings’, 'wsal_data’, $wsal_data );1627 wp_enqueue_script( ‘settings’ );1628 ?>1629 <script type="text/javascript">1630 jQuery( document ).ready( function() {1631 jQuery( ‘.sel-columns’ ).change( function() {1632 var notChecked = 1;1633 jQuery( ‘.sel-columns’ ).each( function() {1634 if ( this.checked ) notChecked = 0;1635 })1636 if ( notChecked == 1 ) {1637 alert( “<?php esc_html_e( 'You have to select at least one column!’, ‘wp-security-audit-log’ ); ?>” );1638 }1639 });1640 // jQuery( ‘body’ ).on( 'click’, '.remodal-confirm’, function ( e ) {1641 // jQuery( ‘.purge-notice’ ).fadeIn(500);1642 // setTimeout(function() { 1643 // jQuery( ‘.purge-notice’ ).fadeOut(500);1644 // }, 4000);1645 // });1646 });</script>1647 <?php1648 }16491650 /**1651 * Method: Ajax Request handler for AjaxGetAllUsers.1652 */1653 public function ajax_get_all_users() {1654 // Filter $_GET array for security.1655 $get_array = filter_input_array( INPUT_GET );1656 $this->check_ajax_request_is_valid( $get_array );16571658 // Fetch users.1659 $users = array();1660 foreach ( get_users() as $user ) {1661 if ( strpos( $user->user_login, $get_array[‘term’] ) !== false ) {1662 array_push( $users, $user->user_login );1663 }1664 }1665 echo wp_json_encode( $users );1666 exit;1667 }16681669 /**1670 * Method: Ajax Request handler for AjaxGetAllRoles.1671 */1672 public function ajax_get_all_roles() {1673 // Filter $_GET array for security.1674 $get_array = filter_input_array( INPUT_GET );1675 $this->check_ajax_request_is_valid( $get_array );16761677 // Get roles.1678 $roles = array();1679 foreach ( get_editable_roles() as $role_name => $role_info ) {1680 if ( strpos( $role_name, $get_array[‘term’] ) !== false ) {1681 array_push( $roles, $role_name );1682 }1683 }1684 echo wp_json_encode( $roles );1685 exit;1686 }16871688 /**1689 * Create json array of all possible severities.1690 *1691 * @return void1692 * @since 4.3.31693 */1694 public function ajax_get_all_severities() {1695 // Filter $_GET array for security.1696 $get_array = filter_input_array( INPUT_GET );1697 $this->check_ajax_request_is_valid( $get_array );16981699 $result = array_map(1700 function ( $item ) {1701 return ucfirst( strtolower( str_replace( 'WSAL_’, '’, $item ) ) );1702 },1703 array_keys( Constants::get_severities() )1704 );17051706 echo $this->filter_values_for_searched_term( // phpcs:ignore1707 $result,1708 $get_array[‘term’] // phpcs:ignore1709 );1710 exit;1711 }17121713 /**1714 * Filters values to return ones matching the desired term.1715 *1716 * @param array $items_to_filter List of items to filter.1717 * @param string $term Search term.1718 *1719 * @return string JSON encoded filtered list.1720 */1721 public function filter_values_for_searched_term( $items_to_filter, $term ) {17221723 $result = array_filter(1724 $items_to_filter,1725 function( $value ) use ( $term ) {1726 return strpos( strtolower( $value ), strtolower( $term ) ) !== false;1727 }1728 );17291730 return wp_json_encode( $result );1731 }17321733 /**1734 * Create json array of all possible event types.1735 *1736 * @return void1737 * @since 4.3.31738 */1739 public function ajax_get_all_event_types() {1740 // Filter $_GET array for security.1741 $get_array = filter_input_array( INPUT_GET );1742 $this->check_ajax_request_is_valid( $get_array );17431744 $event_types = Alert_Manager::get_event_type_data();17451746 echo $this->filter_values_for_searched_term( array_values( $event_types ), $get_array[‘term’] ); // phpcs:ignore1747 exit;1748 }17491750 /**1751 * Create json array of all possible object types.1752 *1753 * @return void1754 * @since 4.3.31755 */1756 public function ajax_get_all_object_types() {1757 // Filter $_GET array for security.1758 $get_array = filter_input_array( INPUT_GET );1759 $this->check_ajax_request_is_valid( $get_array );17601761 $event_objects = Alert_Manager::get_event_objects_data();17621763 echo $this->filter_values_for_searched_term( array_values( $event_objects ), $get_array[‘term’] ); // phpcs:ignore1764 exit;1765 }17661767 /**1768 * Create json array of all possible event IDs.1769 *1770 * @return void1771 * @since 4.3.31772 */1773 public function ajax_get_all_event_ids() {17741775 $get_array = filter_input_array( INPUT_GET );1776 $this->check_ajax_request_is_valid( $get_array );17771778 $registered_alerts = Alert_Manager::get_alerts();17791780 // $alerts = array();1781 // foreach ( $registered_alerts as $alert => $details ) {1782 // $alerts[] = (string) $details->code;1783 // }17841785 echo $this->filter_values_for_searched_term( array_keys( $registered_alerts ), $get_array[‘term’] ); // phpcs:ignore1786 exit;1787 }17881789 /**1790 * Method: Get CPTs ajax handle.1791 *1792 * @since 2.6.71793 */1794 public function ajax_get_all_cpts() {1795 // Filter $_GET array for security.1796 $get_array = filter_input_array( INPUT_GET );1797 $this->check_ajax_request_is_valid( $get_array );17981799 // Get custom post types.1800 $custom_post_types = array();1801 $post_types = get_post_types(1802 array(1803 ‘public’ => false,1804 ),1805 'names’1806 );1807 // if we are running multisite and have networkwide cpt tracker get the1808 // list from and merge to the post_types array.1809 if ( WP_Helper::is_multisite() && class_exists( ‘\WSAL\Multisite\NetworkWide\CPTsTracker’ ) ) {1810 $network_cpts = \WSAL\Multisite\NetworkWide\CPTsTracker::get_network_data_list();1811 foreach ( $network_cpts as $cpt ) {1812 $post_types[ $cpt ] = $cpt;1813 }1814 }18151816 $post_types = array_diff( $post_types, array( 'attachment’, 'revision’, 'nav_menu_item’, 'customize_changeset’, ‘custom_css’ ) );1817 foreach ( $post_types as $post_type ) {1818 if ( strpos( $post_type, $get_array[‘term’] ) !== false ) {1819 array_push( $custom_post_types, $post_type );1820 }1821 }1822 echo wp_json_encode( $custom_post_types );1823 exit;1824 }18251826 /**1827 * Checks if provided GET array is valid and bails if not.1828 *1829 * @param array $get_array Get data.1830 */1831 public function check_ajax_request_is_valid( $get_array ) {1832 // Die if user does not have permission to edit.1833 if ( ! $this->plugin->settings()->current_user_can( ‘edit’ ) ) {1834 die( ‘Access Denied.’ );1835 }18361837 // Die if nonce verification failed.1838 if ( ! wp_verify_nonce( $get_array[‘wsal_nonce’], ‘wsal-exclude-nonce’ ) ) {1839 die( esc_html__( 'Nonce verification failed.’, ‘wp-security-audit-log’ ) );1840 }1841 }18421843 /**1844 * Method: Reset plugin settings table.1845 */1846 public function reset_settings() {1847 // Die if user does not have permission to change settings.1848 if ( ! $this->plugin->settings()->current_user_can( ‘edit’ ) ) {1849 wp_send_json_error( esc_html__( 'Access Denied.’, ‘wp-security-audit-log’ ) );1850 }18511852 // Verify nonce.1853 if ( empty( $_POST[‘nonce’] ) || ! wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_POST[‘nonce’] ) ), ‘wsal-reset-settings’ ) ) {1854 wp_send_json_error( esc_html__( 'Nonce Verification Failed.’, ‘wp-security-audit-log’ ) );1855 }18561857 // Delete all settings.1858 WSAL_Uninstall::delete_options_from_wp_options();18591860 // Log settings reset event.1861 Alert_Manager::trigger_event( 6006 );1862 wp_send_json_success( esc_html__( 'Plugin settings have been reset.’, ‘wp-security-audit-log’ ) );1863 }18641865 /**1866 * Method: Purge plugin occurrence & meta tables.1867 */1868 public function purge_activity() {1869 // Die if user does not have permission to change settings.1870 if ( ! $this->plugin->settings()->current_user_can( ‘edit’ ) ) {1871 wp_send_json_error( esc_html__( 'Access Denied.’, ‘wp-security-audit-log’ ) );1872 }18731874 // Verify nonce.1875 if ( empty( $_POST[‘nonce’] ) || ! wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_POST[‘nonce’] ) ), ‘wsal-purge-activity’ ) ) {1876 wp_send_json_error( esc_html__( 'Nonce Verification Failed.’, ‘wp-security-audit-log’ ) );1877 }18781879 $connector = WpSecurityAuditLog::get_connector();1880 $result = $connector->purge_activity();18811882 if ( $result ) {1883 // Log purge activity event.1884 Alert_Manager::trigger_event( 6034 );1885 wp_send_json_success( esc_html__( 'Tables has been reset.’, ‘wp-security-audit-log’ ) );1886 } else {1887 wp_send_json_error( esc_html__( 'Reset query failed.’, ‘wp-security-audit-log’ ) );1888 }1889 }18901891 /**1892 * Renders table with retention related settings.1893 */1894 public function render_retention_settings_table() {1895 // Check if the retention settings are enforced from the MainWP master site.1896 $settings = $this->plugin->settings();1897 $enforced_settings = $settings->get_mainwp_enforced_settings();1898 $retention_settings_enforced_by_mainwp = array_key_exists( 'pruning_enabled’, $enforced_settings );1899 ?>1900 <table class="form-table wsal-tab">1901 <tbody>1902 <tr>1903 <th><label for="delete1"><?php esc_html_e( 'Activity log retention’, ‘wp-security-audit-log’ ); ?></label></th>1904 <td>1905 <fieldset>1906 <?php $nbld = ! $this->plugin->settings()->is_pruning_date_enabled(); ?>1907 <label for="delete0">1908 <input type="radio" id="delete0" name="PruneBy" value="" <?php checked( $nbld ); ?>1909 <?php disabled( $retention_settings_enforced_by_mainwp ); ?> />1910 <?php esc_html_e( 'Keep all data’, ‘wp-security-audit-log’ ); ?>1911 </label>1912 </fieldset>19131914 <fieldset>1915 <?php1916 // Check pruning date option.1917 $nbld = $this->plugin->settings()->is_pruning_date_enabled();19181919 // Find and replace ` months` in the string.1920 $pruning_date = $this->plugin->settings()->get_pruning_date();1921 $pruning_date = preg_replace( '/[^0-9]/’, '’, $pruning_date );19221923 $pruning_unit = $this->plugin->settings()->get_pruning_unit();19241925 $pruning_unit_options = array(1926 ‘days’ => esc_html__( 'Days’, ‘wp-security-audit-log’ ),1927 ‘months’ => esc_html__( 'Months’, ‘wp-security-audit-log’ ),1928 ‘years’ => esc_html__( 'Years’, ‘wp-security-audit-log’ ),1929 );19301931 // Check if pruning limit was enabled for backwards compatibility.1932 if ( $this->plugin->settings()->is_pruning_limit_enabled() ) {1933 $nbld = true;1934 $pruning_date = '6’;1935 $pruning_unit = 'months’;1936 $this->plugin->settings()->set_pruning_date_settings( true, $pruning_date . ' ' . $pruning_unit, $pruning_unit );1937 $this->plugin->settings()->set_pruning_limit_enabled( false );1938 }1939 ?>1940 <label for="delete1">1941 <input type="radio" id="delete1" name="PruneBy" value="date" <?php checked( $nbld ); ?>1942 <?php disabled( $retention_settings_enforced_by_mainwp ); ?> />1943 <?php esc_html_e( 'Delete events older than’, ‘wp-security-audit-log’ ); ?>1944 </label>1945 <input type="number" id="PruningDate" name="PruningDate"1946 value="<?php echo esc_attr( $pruning_date ); ?>"1947 onfocus="jQuery(‘#delete1’).attr('checked’, true);"1948 <?php disabled( $retention_settings_enforced_by_mainwp ); ?>1949 min="1"1950 />1951 <select name="pruning-unit" id="pruning-unit" <?php disabled( $retention_settings_enforced_by_mainwp ); ?>>1952 <?php1953 foreach ( $pruning_unit_options as $option => $label ) {1954 echo ‘<option value="’ . esc_attr( $option ) . '" ' . selected( $pruning_unit, $option, true ) . ‘>’ . ucwords( $label ) . '</option>’; // phpcs:ignore1955 }1956 ?>1957 </select>1958 </fieldset>19591960 <?php if ( $this->plugin->settings()->is_pruning_date_enabled() ) : ?>1961 <p class="description">1962 <?php1963 $next = wp_next_scheduled( ‘wsal_cleanup’ );1964 echo esc_html__( 'The next scheduled purging of activity log data that is older than ', ‘wp-security-audit-log’ );1965 echo esc_html( $pruning_date . ' ' . $pruning_unit );1966 echo sprintf(1967 ' is in %s.’,1968 esc_html( human_time_diff( current_time( ‘timestamp’ ), $next ) )1969 );1970 echo '<!-- ' . esc_html( gmdate( 'dMy H:i:s’, $next ) ) . ' --> ';1971 echo esc_html__( 'You can run the purging process now by clicking the button below.’, ‘wp-security-audit-log’ );1972 ?>1973 </p>1974 <p>1975 <a class="button-primary" href="<?php echo esc_url( add_query_arg( ['action’=> 'AjaxRunCleanup’, 'nonce’=> wp_create_nonce( ‘wsal-run-cleanup’ )], admin_url( ‘admin-ajax.php’ ) ) ); ?>" data-nonce="<?php echo esc_attr( wp_create_nonce( ‘wsal-run-cleanup’ ) ); ?>" ><?php esc_html_e( 'Purge Old Data’, ‘wp-security-audit-log’ ); ?></a>1976 </p>1977 <?php endif; ?>1978 </td>1979 </tr>1980 <!-- Activity log retention -->1981 </tbody>1982 </table>1983 <?php1984 }1985}

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907