' . esc_html__( 'Admin Watch Central stores the latest successful login timestamp, password-change timestamp and local password-strength classification after observing those events. When Site Activity is enabled, it retains user IDs, known event types, object references, bounded object labels, timestamps and allow-listed metadata for important user, content, plugin, theme, WordPress and Admin Watch events. Failed-login records may include a bounded attempted username or email address, grouped in 15-minute buckets; high-cardinality attempts are grouped without their identifier. Activity retention is 7, 30 or 90 days (30 by default), with daily cleanup and a manual clear-log control. It also stores aggregated missing URL paths, hit counts and timestamps. Session counts are read from current WordPress state only. Free does not store IP addresses in any form, passwords, password hashes, authentication/session tokens, cookies, browser/device history, request bodies, MFA secrets, referrers or telemetry. WordPress privacy tools export and erase retained activity linked to a current account ID or matching failed-login identifier; account names are resolved from WordPress and are not copied into history.', 'adminwatch-central' ) . '

' ); } /** @param array $exporters Registered exporters. @return array */ public function exporter( $exporters ) { $exporters['admin-watch'] = array( 'exporter_friendly_name' => __( 'Admin Watch Central account monitoring data', 'adminwatch-central' ), 'callback' => array( $this, 'export' ), ); return $exporters; } /** @param array $erasers Registered erasers. @return array */ public function eraser( $erasers ) { $erasers['admin-watch'] = array( 'eraser_friendly_name' => __( 'Admin Watch Central account monitoring data', 'adminwatch-central' ), 'callback' => array( $this, 'erase' ), ); return $erasers; } /** * Export account metadata and a bounded page of linked activity. * * @param string $email_address User email address. * @param int $page Export page number. * @return array */ public function export( $email_address, $page ) { $user = get_user_by( 'email', $email_address ); $data = array(); if ( $user && 1 === max( 1, absint( $page ) ) ) { $last_login = get_user_meta( $user->ID, WebStudio_Admin_Watch_Login_Monitor::META_KEY, true ); $password_changed = get_user_meta( $user->ID, WebStudio_Admin_Watch_Password_Monitor::CHANGED_META_KEY, true ); $password_strength = get_user_meta( $user->ID, WebStudio_Admin_Watch_Password_Monitor::STRENGTH_META_KEY, true ); $item_data = array(); if ( $last_login ) { $item_data[] = array( 'name' => __( 'Latest successful login recorded by Admin Watch Central', 'adminwatch-central' ), 'value' => wp_date( DATE_RFC3339, (int) $last_login ), ); } if ( $password_changed ) { $item_data[] = array( 'name' => __( 'Latest password change recorded by Admin Watch Central', 'adminwatch-central' ), 'value' => wp_date( DATE_RFC3339, (int) $password_changed ), ); } if ( $password_strength ) { $item_data[] = array( 'name' => __( 'Password strength classification recorded by Admin Watch Central', 'adminwatch-central' ), 'value' => sanitize_key( $password_strength ), ); } if ( $item_data ) { $data[] = array( 'group_id' => 'admin-watch', 'group_label' => __( 'Admin Watch Central', 'adminwatch-central' ), 'item_id' => 'admin-watch-login-' . $user->ID, 'data' => $item_data, ); } } $repository = new WebStudio_Admin_Watch_Activity_Repository(); $rows = $repository->items( array( 'privacy_user' => $user ? $user->ID : 0, 'privacy_email' => $email_address ), max( 1, absint( $page ) ), 100 ); foreach ( $rows as $row ) { $data[] = array( 'group_id' => 'admin-watch-activity', 'group_label' => __( 'Admin Watch Central Site Activity', 'adminwatch-central' ), 'item_id' => 'admin-watch-activity-' . $row->id, 'data' => array( array( 'name' => __( 'Activity', 'adminwatch-central' ), 'value' => WebStudio_Admin_Watch_Activity_Events::message( $row ) ), array( 'name' => __( 'Details', 'adminwatch-central' ), 'value' => WebStudio_Admin_Watch_Activity_Events::details( $row ) ), array( 'name' => __( 'Last occurred', 'adminwatch-central' ), 'value' => wp_date( DATE_RFC3339, strtotime( $row->last_occurred_at . ' UTC' ) ) ), array( 'name' => __( 'First occurred', 'adminwatch-central' ), 'value' => wp_date( DATE_RFC3339, strtotime( $row->created_at . ' UTC' ) ) ), ), ); } return array( 'data' => $data, 'done' => count( $rows ) < 100, ); } /** * Remove only this plugin's account metadata and linked activity. * * @param string $email_address User email address. * @param int $page Erasure page number. * @return array */ public function erase( $email_address, $page ) { $user = get_user_by( 'email', $email_address ); $removed = false; if ( $user ) { $removed = (bool) delete_user_meta( $user->ID, WebStudio_Admin_Watch_Login_Monitor::META_KEY ); $removed = (bool) delete_user_meta( $user->ID, WebStudio_Admin_Watch_Password_Monitor::CHANGED_META_KEY ) || $removed; $removed = (bool) delete_user_meta( $user->ID, WebStudio_Admin_Watch_Password_Monitor::STRENGTH_META_KEY ) || $removed; } $result = ( new WebStudio_Admin_Watch_Activity_Repository() )->erase( $user ? $user->ID : 0, $email_address ); $result['items_removed'] = $result['items_removed'] || $removed; return $result; } }