v1.0.1
This commit is contained in:
parent
212d64abfa
commit
b8e17df2db
17 changed files with 1145 additions and 732 deletions
|
|
@ -28,21 +28,6 @@ class Two_Factor_Extended_Settings {
|
|||
*/
|
||||
const PAGE_SLUG = 'two-factor-extended';
|
||||
|
||||
/**
|
||||
* Settings sections.
|
||||
*
|
||||
* @since 0.1.0
|
||||
* @var array
|
||||
*/
|
||||
private array $sections = array();
|
||||
|
||||
/**
|
||||
* Settings fields.
|
||||
*
|
||||
* @since 0.1.0
|
||||
* @var array
|
||||
*/
|
||||
private array $fields = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
|
@ -59,8 +44,9 @@ class Two_Factor_Extended_Settings {
|
|||
* @since 0.1.0
|
||||
*/
|
||||
private function init_hooks(): void {
|
||||
add_action( 'admin_menu', array( $this, 'register_settings_page' ) );
|
||||
add_action( 'network_admin_menu', array( $this, 'register_network_settings_page' ) );
|
||||
// Priority 20 ensures our page registers after Two Factor (default priority 10).
|
||||
add_action( 'admin_menu', array( $this, 'register_settings_page' ), 20 );
|
||||
add_action( 'network_admin_menu', array( $this, 'register_network_settings_page' ), 20 );
|
||||
add_action( 'admin_init', array( $this, 'register_settings' ) );
|
||||
add_action( 'admin_init', array( $this, 'handle_import_export' ) );
|
||||
add_action( 'admin_init', array( $this, 'handle_reset_settings' ) );
|
||||
|
|
@ -186,13 +172,6 @@ class Two_Factor_Extended_Settings {
|
|||
array( $this, 'render_data_section' ),
|
||||
self::PAGE_SLUG
|
||||
);
|
||||
|
||||
$this->sections = array(
|
||||
'two_factor_extended_general',
|
||||
'two_factor_extended_role_requirements',
|
||||
'two_factor_extended_provider_visibility',
|
||||
'two_factor_extended_data',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -380,31 +359,31 @@ class Two_Factor_Extended_Settings {
|
|||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @param array $args Field arguments.
|
||||
* @param array<string, mixed> $args Field arguments.
|
||||
*/
|
||||
public function render_number_field( array $args ): void {
|
||||
$option_name = $args['option_name'] ?? '';
|
||||
$id = $args['id'] ?? '';
|
||||
$field_key = $args['field_key'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$min = $args['min'] ?? 0;
|
||||
$max = $args['max'] ?? 999;
|
||||
$default = $args['default'] ?? 0;
|
||||
$option_name = isset( $args['option_name'] ) && is_string( $args['option_name'] ) ? $args['option_name'] : '';
|
||||
$id = isset( $args['id'] ) && is_string( $args['id'] ) ? $args['id'] : '';
|
||||
$field_key = isset( $args['field_key'] ) && is_string( $args['field_key'] ) ? $args['field_key'] : '';
|
||||
$description = isset( $args['description'] ) && is_string( $args['description'] ) ? $args['description'] : '';
|
||||
$min = isset( $args['min'] ) && is_numeric( $args['min'] ) ? (int) $args['min'] : 0;
|
||||
$max = isset( $args['max'] ) && is_numeric( $args['max'] ) ? (int) $args['max'] : 999;
|
||||
$default = isset( $args['default'] ) && is_numeric( $args['default'] ) ? (int) $args['default'] : 0;
|
||||
|
||||
if ( empty( $option_name ) || empty( $id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$settings = get_option( $option_name, array() );
|
||||
$value = $settings[ $field_key ] ?? $default;
|
||||
$value = is_array( $settings ) && isset( $settings[ $field_key ] ) && is_numeric( $settings[ $field_key ] ) ? (int) $settings[ $field_key ] : $default;
|
||||
?>
|
||||
<input
|
||||
type="number"
|
||||
id="<?php echo esc_attr( $id ); ?>"
|
||||
name="<?php echo esc_attr( $option_name . '[' . $field_key . ']' ); ?>"
|
||||
value="<?php echo esc_attr( $value ); ?>"
|
||||
min="<?php echo esc_attr( $min ); ?>"
|
||||
max="<?php echo esc_attr( $max ); ?>"
|
||||
value="<?php echo esc_attr( (string) $value ); ?>"
|
||||
min="<?php echo esc_attr( (string) $min ); ?>"
|
||||
max="<?php echo esc_attr( (string) $max ); ?>"
|
||||
step="1"
|
||||
required
|
||||
aria-required="true"
|
||||
|
|
@ -423,17 +402,18 @@ class Two_Factor_Extended_Settings {
|
|||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @param array $args Field arguments.
|
||||
* @param array<string, mixed> $args Field arguments.
|
||||
*/
|
||||
public function render_role_requirements_field( array $args ): void {
|
||||
// Clear any object cache to ensure fresh data.
|
||||
wp_cache_delete( TWO_FACTOR_EXTENDED_OPTION_SETTINGS, 'options' );
|
||||
wp_cache_flush();
|
||||
|
||||
$settings = get_option( TWO_FACTOR_EXTENDED_OPTION_SETTINGS, array() );
|
||||
$roles = Two_Factor_Extended_Role_Manager::get_all_roles();
|
||||
$raw_settings = get_option( TWO_FACTOR_EXTENDED_OPTION_SETTINGS, array() );
|
||||
$settings = is_array( $raw_settings ) ? $raw_settings : array();
|
||||
$roles = Two_Factor_Extended_Role_Manager::get_all_roles();
|
||||
|
||||
// Force fresh provider detection directly from Two Factor Core
|
||||
// Force fresh provider detection directly from Two Factor Core.
|
||||
$providers = array();
|
||||
if ( class_exists( 'Two_Factor_Core' ) ) {
|
||||
$all_providers = Two_Factor_Core::get_providers();
|
||||
|
|
@ -456,7 +436,7 @@ class Two_Factor_Extended_Settings {
|
|||
return;
|
||||
}
|
||||
|
||||
$requirements = $settings['role_requirements'] ?? array();
|
||||
$requirements = isset( $settings['role_requirements'] ) && is_array( $settings['role_requirements'] ) ? $settings['role_requirements'] : array();
|
||||
?>
|
||||
<table class="widefat fixed striped">
|
||||
<thead>
|
||||
|
|
@ -473,7 +453,8 @@ class Two_Factor_Extended_Settings {
|
|||
</td>
|
||||
<td>
|
||||
<?php
|
||||
$role_requirements = $requirements[ $role_slug ] ?? array();
|
||||
$role_req_raw = $requirements[ $role_slug ] ?? array();
|
||||
$role_requirements = is_array( $role_req_raw ) ? $role_req_raw : array();
|
||||
|
||||
foreach ( $providers as $provider_class => $provider_name ) :
|
||||
$checked = in_array( $provider_class, $role_requirements, true );
|
||||
|
|
@ -504,17 +485,18 @@ class Two_Factor_Extended_Settings {
|
|||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @param array $args Field arguments.
|
||||
* @param array<string, mixed> $args Field arguments.
|
||||
*/
|
||||
public function render_provider_visibility_field( array $args ): void {
|
||||
// Clear any object cache to ensure fresh data.
|
||||
wp_cache_delete( TWO_FACTOR_EXTENDED_OPTION_SETTINGS, 'options' );
|
||||
wp_cache_flush();
|
||||
|
||||
$settings = get_option( TWO_FACTOR_EXTENDED_OPTION_SETTINGS, array() );
|
||||
$roles = Two_Factor_Extended_Role_Manager::get_all_roles();
|
||||
$raw_settings = get_option( TWO_FACTOR_EXTENDED_OPTION_SETTINGS, array() );
|
||||
$settings = is_array( $raw_settings ) ? $raw_settings : array();
|
||||
$roles = Two_Factor_Extended_Role_Manager::get_all_roles();
|
||||
|
||||
// Force fresh provider detection directly from Two Factor Core
|
||||
// Force fresh provider detection directly from Two Factor Core.
|
||||
$providers = array();
|
||||
if ( class_exists( 'Two_Factor_Core' ) ) {
|
||||
$all_providers = Two_Factor_Core::get_providers();
|
||||
|
|
@ -537,8 +519,8 @@ class Two_Factor_Extended_Settings {
|
|||
return;
|
||||
}
|
||||
|
||||
$visibility = $settings['provider_visibility'] ?? array();
|
||||
$requirements = $settings['role_requirements'] ?? array();
|
||||
$visibility = isset( $settings['provider_visibility'] ) && is_array( $settings['provider_visibility'] ) ? $settings['provider_visibility'] : array();
|
||||
$requirements = isset( $settings['role_requirements'] ) && is_array( $settings['role_requirements'] ) ? $settings['role_requirements'] : array();
|
||||
?>
|
||||
<table class="widefat fixed striped">
|
||||
<thead>
|
||||
|
|
@ -555,11 +537,13 @@ class Two_Factor_Extended_Settings {
|
|||
</td>
|
||||
<td>
|
||||
<?php
|
||||
$role_visibility = $visibility[ $role_slug ] ?? array();
|
||||
$role_required = $requirements[ $role_slug ] ?? array();
|
||||
$role_vis_raw = $visibility[ $role_slug ] ?? array();
|
||||
$role_req_raw = $requirements[ $role_slug ] ?? array();
|
||||
$role_visibility = is_array( $role_vis_raw ) ? $role_vis_raw : array();
|
||||
$role_required = is_array( $role_req_raw ) ? $role_req_raw : array();
|
||||
|
||||
foreach ( $providers as $provider_class => $provider_name ) :
|
||||
$checked = in_array( $provider_class, $role_visibility, true );
|
||||
$checked = in_array( $provider_class, $role_visibility, true );
|
||||
$is_required = in_array( $provider_class, $role_required, true );
|
||||
$disabled = $is_required ? 'disabled' : '';
|
||||
$checked = $checked || $is_required;
|
||||
|
|
@ -606,13 +590,13 @@ class Two_Factor_Extended_Settings {
|
|||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @param array $args Field arguments.
|
||||
* @param array<string, mixed> $args Field arguments.
|
||||
*/
|
||||
public function render_checkbox_field( array $args ): void {
|
||||
$option_name = $args['option_name'] ?? '';
|
||||
$id = $args['id'] ?? '';
|
||||
$label = $args['label'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$option_name = isset( $args['option_name'] ) && is_string( $args['option_name'] ) ? $args['option_name'] : '';
|
||||
$id = isset( $args['id'] ) && is_string( $args['id'] ) ? $args['id'] : '';
|
||||
$label = isset( $args['label'] ) && is_string( $args['label'] ) ? $args['label'] : '';
|
||||
$description = isset( $args['description'] ) && is_string( $args['description'] ) ? $args['description'] : '';
|
||||
|
||||
if ( empty( $option_name ) || empty( $id ) ) {
|
||||
return;
|
||||
|
|
@ -650,7 +634,8 @@ class Two_Factor_Extended_Settings {
|
|||
return;
|
||||
}
|
||||
|
||||
$network_settings = get_site_option( TWO_FACTOR_EXTENDED_NETWORK_OPTION_SETTINGS, array() );
|
||||
$network_settings_raw = get_site_option( TWO_FACTOR_EXTENDED_NETWORK_OPTION_SETTINGS, array() );
|
||||
$network_settings = is_array( $network_settings_raw ) ? $network_settings_raw : array();
|
||||
|
||||
if ( empty( $network_settings['enforce_network_wide'] ) ) {
|
||||
return;
|
||||
|
|
@ -688,7 +673,7 @@ class Two_Factor_Extended_Settings {
|
|||
}
|
||||
|
||||
// Inline CSS for tabs.
|
||||
$css = "
|
||||
$css = '
|
||||
.tab-content {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
|
@ -696,7 +681,7 @@ class Two_Factor_Extended_Settings {
|
|||
max-width: none;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
";
|
||||
';
|
||||
wp_add_inline_style( 'wp-admin', $css );
|
||||
|
||||
// Inline script for import validation.
|
||||
|
|
@ -775,6 +760,8 @@ class Two_Factor_Extended_Settings {
|
|||
* Export settings to JSON file.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @throws Exception If JSON encoding fails.
|
||||
*/
|
||||
private function export_settings(): void {
|
||||
try {
|
||||
|
|
@ -794,11 +781,14 @@ class Two_Factor_Extended_Settings {
|
|||
}
|
||||
|
||||
// Log the export.
|
||||
two_factor_extended()->get_audit_log()->log_event(
|
||||
'settings_exported',
|
||||
'Plugin settings exported',
|
||||
0
|
||||
);
|
||||
$audit_log = two_factor_extended()->get_audit_log();
|
||||
if ( null !== $audit_log ) {
|
||||
$audit_log->log_event(
|
||||
'settings_exported',
|
||||
'Plugin settings exported',
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
// Set headers for download.
|
||||
header( 'Content-Type: application/json; charset=utf-8' );
|
||||
|
|
@ -810,12 +800,15 @@ class Two_Factor_Extended_Settings {
|
|||
exit;
|
||||
} catch ( Exception $e ) {
|
||||
// Log error without exposing details to user.
|
||||
two_factor_extended()->get_audit_log()->log_event(
|
||||
'settings_export_failed',
|
||||
'Failed to export settings',
|
||||
0,
|
||||
array( 'error' => 'Export failed' )
|
||||
);
|
||||
$audit_log = two_factor_extended()->get_audit_log();
|
||||
if ( null !== $audit_log ) {
|
||||
$audit_log->log_event(
|
||||
'settings_export_failed',
|
||||
'Failed to export settings',
|
||||
0,
|
||||
array( 'error' => 'Export failed' )
|
||||
);
|
||||
}
|
||||
|
||||
wp_die(
|
||||
esc_html__( 'Unable to export settings. Please try again later.', 'two-factor-extended' ),
|
||||
|
|
@ -848,7 +841,16 @@ class Two_Factor_Extended_Settings {
|
|||
// phpcs:disable WordPress.Security.ValidatedSanitizedInput
|
||||
|
||||
// Check file upload.
|
||||
if ( ! isset( $_FILES['two_factor_extended_import_file'] ) || UPLOAD_ERR_OK !== $_FILES['two_factor_extended_import_file']['error'] ) {
|
||||
$upload_file = isset( $_FILES['two_factor_extended_import_file'] ) && is_array( $_FILES['two_factor_extended_import_file'] )
|
||||
? $_FILES['two_factor_extended_import_file']
|
||||
: array();
|
||||
|
||||
$upload_error = isset( $upload_file['error'] ) && is_int( $upload_file['error'] ) ? $upload_file['error'] : UPLOAD_ERR_NO_FILE;
|
||||
$upload_size = isset( $upload_file['size'] ) && is_int( $upload_file['size'] ) ? $upload_file['size'] : 0;
|
||||
$upload_name = isset( $upload_file['name'] ) && is_string( $upload_file['name'] ) ? $upload_file['name'] : '';
|
||||
$upload_tmp_name = isset( $upload_file['tmp_name'] ) && is_string( $upload_file['tmp_name'] ) ? $upload_file['tmp_name'] : '';
|
||||
|
||||
if ( empty( $upload_file ) || UPLOAD_ERR_OK !== $upload_error ) {
|
||||
add_settings_error(
|
||||
'two_factor_extended_import',
|
||||
'import_error',
|
||||
|
|
@ -860,7 +862,7 @@ class Two_Factor_Extended_Settings {
|
|||
|
||||
// Check file size (1MB limit).
|
||||
$max_size = 1024 * 1024; // 1MB.
|
||||
if ( $_FILES['two_factor_extended_import_file']['size'] > $max_size ) {
|
||||
if ( $upload_size > $max_size ) {
|
||||
add_settings_error(
|
||||
'two_factor_extended_import',
|
||||
'import_error',
|
||||
|
|
@ -871,7 +873,7 @@ class Two_Factor_Extended_Settings {
|
|||
}
|
||||
|
||||
// Check file extension.
|
||||
$file_name = sanitize_file_name( $_FILES['two_factor_extended_import_file']['name'] );
|
||||
$file_name = sanitize_file_name( $upload_name );
|
||||
if ( ! str_ends_with( strtolower( $file_name ), '.json' ) ) {
|
||||
add_settings_error(
|
||||
'two_factor_extended_import',
|
||||
|
|
@ -883,7 +885,7 @@ class Two_Factor_Extended_Settings {
|
|||
}
|
||||
|
||||
// Read file contents.
|
||||
$file_content = file_get_contents( $_FILES['two_factor_extended_import_file']['tmp_name'] );
|
||||
$file_content = file_get_contents( $upload_tmp_name );
|
||||
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
||||
// phpcs:enable WordPress.Security.ValidatedSanitizedInput
|
||||
|
|
@ -922,19 +924,29 @@ class Two_Factor_Extended_Settings {
|
|||
return;
|
||||
}
|
||||
|
||||
// Sanitize and update settings.
|
||||
$sanitized_settings = $this->sanitize_settings( $import_data['settings'] );
|
||||
// Sanitize and update settings. Ensure keys are strings (from JSON decode).
|
||||
$settings_to_import = array();
|
||||
foreach ( $import_data['settings'] as $key => $value ) {
|
||||
if ( is_string( $key ) ) {
|
||||
$settings_to_import[ $key ] = $value;
|
||||
}
|
||||
}
|
||||
$sanitized_settings = $this->sanitize_settings( $settings_to_import );
|
||||
update_option( TWO_FACTOR_EXTENDED_OPTION_SETTINGS, $sanitized_settings );
|
||||
|
||||
// Log the import.
|
||||
two_factor_extended()->get_audit_log()->log_event(
|
||||
'settings_imported',
|
||||
'Plugin settings imported',
|
||||
0,
|
||||
array(
|
||||
'imported_version' => $import_data['version'] ?? 'unknown',
|
||||
)
|
||||
);
|
||||
$audit_log = two_factor_extended()->get_audit_log();
|
||||
|
||||
if ( null !== $audit_log ) {
|
||||
$audit_log->log_event(
|
||||
'settings_imported',
|
||||
'Plugin settings imported',
|
||||
0,
|
||||
array(
|
||||
'imported_version' => $import_data['version'] ?? 'unknown',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
add_settings_error(
|
||||
'two_factor_extended_import',
|
||||
|
|
@ -957,7 +969,8 @@ class Two_Factor_Extended_Settings {
|
|||
|
||||
// Get current tab.
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Tab parameter for UI navigation
|
||||
$current_tab = isset( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : 'settings';
|
||||
$tab_param = isset( $_GET['tab'] ) && is_string( $_GET['tab'] ) ? $_GET['tab'] : '';
|
||||
$current_tab = $tab_param ? sanitize_key( $tab_param ) : 'settings';
|
||||
|
||||
// Define tabs.
|
||||
$tabs = array(
|
||||
|
|
@ -1012,7 +1025,8 @@ class Two_Factor_Extended_Settings {
|
|||
// Check if site settings are disabled by network.
|
||||
$settings_disabled = $this->are_site_settings_disabled();
|
||||
|
||||
if ( $settings_disabled ) : ?>
|
||||
if ( $settings_disabled ) :
|
||||
?>
|
||||
<div class="notice notice-warning">
|
||||
<p>
|
||||
<?php esc_html_e( 'Site-level settings are currently disabled by network administrator. Please contact your network administrator to make changes.', 'two-factor-extended' ); ?>
|
||||
|
|
@ -1041,6 +1055,11 @@ class Two_Factor_Extended_Settings {
|
|||
private function render_audit_log_tab(): void {
|
||||
$audit_log = two_factor_extended()->get_audit_log();
|
||||
|
||||
if ( null === $audit_log ) {
|
||||
echo '<div class="notice notice-error"><p>' . esc_html__( 'Audit log module is not available.', 'two-factor-extended' ) . '</p></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle export.
|
||||
if ( isset( $_GET['action'] ) && 'export' === $_GET['action'] ) {
|
||||
check_admin_referer( 'two_factor_extended_export_audit' );
|
||||
|
|
@ -1081,7 +1100,21 @@ class Two_Factor_Extended_Settings {
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<a href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'tab' => 'audit-log', 'action' => 'export' ) ), 'two_factor_extended_export_audit' ) ); ?>" class="button">
|
||||
<a href="
|
||||
<?php
|
||||
echo esc_url(
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'tab' => 'audit-log',
|
||||
'action' => 'export',
|
||||
)
|
||||
),
|
||||
'two_factor_extended_export_audit'
|
||||
)
|
||||
);
|
||||
?>
|
||||
" class="button">
|
||||
<?php esc_html_e( 'Export to CSV', 'two-factor-extended' ); ?>
|
||||
</a>
|
||||
</p>
|
||||
|
|
@ -1099,21 +1132,28 @@ class Two_Factor_Extended_Settings {
|
|||
<tbody>
|
||||
<?php if ( ! empty( $logs ) ) : ?>
|
||||
<?php foreach ( array_slice( $logs, 0, 50 ) as $log ) : ?>
|
||||
<?php
|
||||
$log_ts = isset( $log['timestamp'] ) && is_int( $log['timestamp'] ) ? $log['timestamp'] : null;
|
||||
$log_action = isset( $log['action'] ) && is_string( $log['action'] ) ? $log['action'] : '';
|
||||
$log_desc = isset( $log['description'] ) && is_string( $log['description'] ) ? $log['description'] : '';
|
||||
$log_actor_id = isset( $log['actor_id'] ) && is_int( $log['actor_id'] ) ? $log['actor_id'] : 0;
|
||||
$log_ip = isset( $log['ip_address'] ) && is_string( $log['ip_address'] ) ? $log['ip_address'] : '-';
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo esc_html( gmdate( 'Y-m-d H:i:s', $log['timestamp'] ) ); ?></td>
|
||||
<td><?php echo esc_html( $log['action'] ); ?></td>
|
||||
<td><?php echo esc_html( $log['description'] ); ?></td>
|
||||
<td><?php echo esc_html( gmdate( 'Y-m-d H:i:s', $log_ts ) ); ?></td>
|
||||
<td><?php echo esc_html( $log_action ); ?></td>
|
||||
<td><?php echo esc_html( $log_desc ); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
if ( $log['actor_id'] ) {
|
||||
$user = get_userdata( $log['actor_id'] );
|
||||
if ( $log_actor_id ) {
|
||||
$user = get_userdata( $log_actor_id );
|
||||
echo $user ? esc_html( $user->display_name ) : esc_html__( 'Unknown', 'two-factor-extended' );
|
||||
} else {
|
||||
esc_html_e( 'System', 'two-factor-extended' );
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo esc_html( $log['ip_address'] ?? '-' ); ?></td>
|
||||
<td><?php echo esc_html( $log_ip ); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else : ?>
|
||||
|
|
@ -1143,6 +1183,11 @@ class Two_Factor_Extended_Settings {
|
|||
private function render_compliance_tab(): void {
|
||||
$compliance = two_factor_extended()->get_compliance_report();
|
||||
|
||||
if ( null === $compliance ) {
|
||||
echo '<div class="notice notice-error"><p>' . esc_html__( 'Compliance report module is not available.', 'two-factor-extended' ) . '</p></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle export.
|
||||
if ( isset( $_GET['action'] ) && 'export' === $_GET['action'] ) {
|
||||
check_admin_referer( 'two_factor_extended_export_compliance' );
|
||||
|
|
@ -1164,23 +1209,23 @@ class Two_Factor_Extended_Settings {
|
|||
<table class="widefat fixed">
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Total Users', 'two-factor-extended' ); ?></th>
|
||||
<td><?php echo esc_html( $stats['total_users'] ); ?></td>
|
||||
<td><?php echo esc_html( (string) $stats['total_users'] ); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Compliant', 'two-factor-extended' ); ?></th>
|
||||
<td style="color: green;"><strong><?php echo esc_html( $stats['compliant_users'] ); ?></strong></td>
|
||||
<td style="color: green;"><strong><?php echo esc_html( (string) $stats['compliant_users'] ); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Non-Compliant', 'two-factor-extended' ); ?></th>
|
||||
<td style="color: red;"><strong><?php echo esc_html( $stats['non_compliant'] ); ?></strong></td>
|
||||
<td style="color: red;"><strong><?php echo esc_html( (string) $stats['non_compliant'] ); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'In Grace Period', 'two-factor-extended' ); ?></th>
|
||||
<td style="color: orange;"><strong><?php echo esc_html( $stats['grace_period'] ); ?></strong></td>
|
||||
<td style="color: orange;"><strong><?php echo esc_html( (string) $stats['grace_period'] ); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'No Requirements', 'two-factor-extended' ); ?></th>
|
||||
<td><?php echo esc_html( $stats['no_requirements'] ); ?></td>
|
||||
<td><?php echo esc_html( (string) $stats['no_requirements'] ); ?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
|
@ -1201,9 +1246,9 @@ class Two_Factor_Extended_Settings {
|
|||
<?php foreach ( $stats['by_role'] as $role => $role_stats ) : ?>
|
||||
<tr>
|
||||
<td><strong><?php echo esc_html( Two_Factor_Extended_Role_Manager::get_role_display_name( $role ) ); ?></strong></td>
|
||||
<td><?php echo esc_html( $role_stats['total'] ); ?></td>
|
||||
<td><?php echo esc_html( $role_stats['compliant'] ); ?></td>
|
||||
<td><?php echo esc_html( $role_stats['non_compliant'] ); ?></td>
|
||||
<td><?php echo esc_html( (string) $role_stats['total'] ); ?></td>
|
||||
<td><?php echo esc_html( (string) $role_stats['compliant'] ); ?></td>
|
||||
<td><?php echo esc_html( (string) $role_stats['non_compliant'] ); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
|
|
@ -1214,7 +1259,21 @@ class Two_Factor_Extended_Settings {
|
|||
<h2><?php esc_html_e( 'Non-Compliant Users', 'two-factor-extended' ); ?></h2>
|
||||
|
||||
<p>
|
||||
<a href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'tab' => 'compliance', 'action' => 'export' ) ), 'two_factor_extended_export_compliance' ) ); ?>" class="button">
|
||||
<a href="
|
||||
<?php
|
||||
echo esc_url(
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'tab' => 'compliance',
|
||||
'action' => 'export',
|
||||
)
|
||||
),
|
||||
'two_factor_extended_export_compliance'
|
||||
)
|
||||
);
|
||||
?>
|
||||
" class="button">
|
||||
<?php esc_html_e( 'Export to CSV', 'two-factor-extended' ); ?>
|
||||
</a>
|
||||
</p>
|
||||
|
|
@ -1233,21 +1292,38 @@ class Two_Factor_Extended_Settings {
|
|||
<?php if ( ! empty( $non_compliant ) ) : ?>
|
||||
<?php foreach ( $non_compliant as $user_data ) : ?>
|
||||
<?php
|
||||
$user_id_val = isset( $user_data['user_id'] ) && is_int( $user_data['user_id'] ) ? $user_data['user_id'] : 0;
|
||||
$user_login_val = isset( $user_data['user_login'] ) && is_string( $user_data['user_login'] ) ? $user_data['user_login'] : '';
|
||||
$user_email_val = isset( $user_data['user_email'] ) && is_string( $user_data['user_email'] ) ? $user_data['user_email'] : '';
|
||||
$roles_raw = isset( $user_data['roles'] ) && is_array( $user_data['roles'] ) ? $user_data['roles'] : array();
|
||||
$missing_raw = isset( $user_data['missing_providers'] ) && is_array( $user_data['missing_providers'] ) ? $user_data['missing_providers'] : array();
|
||||
$in_grace = ! empty( $user_data['in_grace_period'] );
|
||||
$grace_remaining = isset( $user_data['grace_remaining'] ) && is_numeric( $user_data['grace_remaining'] ) ? (int) $user_data['grace_remaining'] : 0;
|
||||
// Get user object for display name.
|
||||
$user = get_userdata( $user_data['user_id'] );
|
||||
$user = $user_id_val ? get_userdata( $user_id_val ) : null;
|
||||
$roles_display = array_map(
|
||||
function ( $role_slug ) {
|
||||
if ( ! is_string( $role_slug ) ) {
|
||||
return '';
|
||||
}
|
||||
return Two_Factor_Extended_Role_Manager::get_role_display_name( $role_slug );
|
||||
},
|
||||
$roles_raw
|
||||
);
|
||||
$missing_display = array_filter( $missing_raw, 'is_string' );
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo $user ? esc_html( $user->display_name ) : esc_html( $user_data['user_login'] ); ?></td>
|
||||
<td><?php echo esc_html( $user_data['user_email'] ); ?></td>
|
||||
<td><?php echo esc_html( implode( ', ', array_map( array( 'Two_Factor_Extended_Role_Manager', 'get_role_display_name' ), $user_data['roles'] ) ) ); ?></td>
|
||||
<td><?php echo $user ? esc_html( $user->display_name ) : esc_html( $user_login_val ); ?></td>
|
||||
<td><?php echo esc_html( $user_email_val ); ?></td>
|
||||
<td><?php echo esc_html( implode( ', ', $roles_display ) ); ?></td>
|
||||
<td>
|
||||
<?php if ( $user_data['in_grace_period'] ) : ?>
|
||||
<?php if ( $in_grace ) : ?>
|
||||
<span style="color: orange;">
|
||||
<?php
|
||||
printf(
|
||||
printf(
|
||||
/* translators: %d: Number of days remaining in grace period */
|
||||
esc_html__( 'Grace period (%d days left)', 'two-factor-extended' ),
|
||||
(int) $user_data["grace_remaining"]
|
||||
absint( $grace_remaining )
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
|
|
@ -1255,7 +1331,7 @@ class Two_Factor_Extended_Settings {
|
|||
<span style="color: red;"><?php esc_html_e( 'Non-compliant', 'two-factor-extended' ); ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php echo esc_html( implode( ', ', $user_data['missing_providers'] ) ); ?></td>
|
||||
<td><?php echo esc_html( implode( ', ', $missing_display ) ); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else : ?>
|
||||
|
|
@ -1282,6 +1358,10 @@ class Two_Factor_Extended_Settings {
|
|||
|
||||
$network_settings = get_site_option( TWO_FACTOR_EXTENDED_NETWORK_OPTION_SETTINGS, array() );
|
||||
|
||||
if ( ! is_array( $network_settings ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! empty( $network_settings['enforce_network_wide'] )
|
||||
&& empty( $network_settings['allow_site_override'] );
|
||||
}
|
||||
|
|
@ -1298,6 +1378,10 @@ class Two_Factor_Extended_Settings {
|
|||
|
||||
$audit_log = two_factor_extended()->get_audit_log();
|
||||
|
||||
if ( null === $audit_log ) {
|
||||
wp_die( esc_html__( 'Audit log module is not available.', 'two-factor-extended' ) );
|
||||
}
|
||||
|
||||
// Handle export.
|
||||
if ( isset( $_GET['action'] ) && 'export' === $_GET['action'] ) {
|
||||
check_admin_referer( 'two_factor_extended_export_audit' );
|
||||
|
|
@ -1364,14 +1448,19 @@ class Two_Factor_Extended_Settings {
|
|||
<?php else : ?>
|
||||
<?php foreach ( array_slice( $logs, 0, 50 ) as $log ) : ?>
|
||||
<?php
|
||||
$user = $log['user_id'] ? get_userdata( $log['user_id'] ) : null;
|
||||
$log_user_id = isset( $log['user_id'] ) && is_int( $log['user_id'] ) ? $log['user_id'] : 0;
|
||||
$log_ts = isset( $log['timestamp'] ) && is_int( $log['timestamp'] ) ? $log['timestamp'] : null;
|
||||
$log_action = isset( $log['action'] ) && is_string( $log['action'] ) ? $log['action'] : '';
|
||||
$log_desc = isset( $log['description'] ) && is_string( $log['description'] ) ? $log['description'] : '';
|
||||
$log_ip = isset( $log['ip_address'] ) && is_string( $log['ip_address'] ) ? $log['ip_address'] : '';
|
||||
$user = $log_user_id ? get_userdata( $log_user_id ) : null;
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo esc_html( gmdate( 'Y-m-d H:i:s', $log['timestamp'] ) ); ?></td>
|
||||
<td><?php echo esc_html( $log['action'] ); ?></td>
|
||||
<td><?php echo esc_html( $log['description'] ); ?></td>
|
||||
<td><?php echo esc_html( gmdate( 'Y-m-d H:i:s', $log_ts ) ); ?></td>
|
||||
<td><?php echo esc_html( $log_action ); ?></td>
|
||||
<td><?php echo esc_html( $log_desc ); ?></td>
|
||||
<td><?php echo $user ? esc_html( $user->user_login ) : '-'; ?></td>
|
||||
<td><?php echo esc_html( $log['ip_address'] ); ?></td>
|
||||
<td><?php echo esc_html( $log_ip ); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
|
@ -1399,6 +1488,10 @@ class Two_Factor_Extended_Settings {
|
|||
|
||||
$compliance = two_factor_extended()->get_compliance_report();
|
||||
|
||||
if ( null === $compliance ) {
|
||||
wp_die( esc_html__( 'Compliance report module is not available.', 'two-factor-extended' ) );
|
||||
}
|
||||
|
||||
// Handle export.
|
||||
if ( isset( $_GET['action'] ) && 'export' === $_GET['action'] ) {
|
||||
check_admin_referer( 'two_factor_extended_export_compliance' );
|
||||
|
|
@ -1415,7 +1508,7 @@ class Two_Factor_Extended_Settings {
|
|||
if ( isset( $_POST['action'] ) && 'email' === $_POST['action'] ) {
|
||||
check_admin_referer( 'two_factor_extended_email_compliance' );
|
||||
|
||||
$email = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';
|
||||
$email = isset( $_POST['email'] ) && is_string( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';
|
||||
|
||||
if ( ! empty( $email ) ) {
|
||||
$sent = $compliance->email_report( $email );
|
||||
|
|
@ -1440,23 +1533,23 @@ class Two_Factor_Extended_Settings {
|
|||
<table class="widefat fixed">
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Total Users', 'two-factor-extended' ); ?></th>
|
||||
<td><?php echo esc_html( $stats['total_users'] ); ?></td>
|
||||
<td><?php echo esc_html( (string) $stats['total_users'] ); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Compliant', 'two-factor-extended' ); ?></th>
|
||||
<td style="color: green;"><strong><?php echo esc_html( $stats['compliant_users'] ); ?></strong></td>
|
||||
<td style="color: green;"><strong><?php echo esc_html( (string) $stats['compliant_users'] ); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Non-Compliant', 'two-factor-extended' ); ?></th>
|
||||
<td style="color: red;"><strong><?php echo esc_html( $stats['non_compliant'] ); ?></strong></td>
|
||||
<td style="color: red;"><strong><?php echo esc_html( (string) $stats['non_compliant'] ); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'In Grace Period', 'two-factor-extended' ); ?></th>
|
||||
<td style="color: orange;"><strong><?php echo esc_html( $stats['grace_period'] ); ?></strong></td>
|
||||
<td style="color: orange;"><strong><?php echo esc_html( (string) $stats['grace_period'] ); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'No Requirements', 'two-factor-extended' ); ?></th>
|
||||
<td><?php echo esc_html( $stats['no_requirements'] ); ?></td>
|
||||
<td><?php echo esc_html( (string) $stats['no_requirements'] ); ?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
|
@ -1477,9 +1570,9 @@ class Two_Factor_Extended_Settings {
|
|||
<?php foreach ( $stats['by_role'] as $role => $role_stats ) : ?>
|
||||
<tr>
|
||||
<td><strong><?php echo esc_html( Two_Factor_Extended_Role_Manager::get_role_display_name( $role ) ); ?></strong></td>
|
||||
<td><?php echo esc_html( $role_stats['total'] ); ?></td>
|
||||
<td><?php echo esc_html( $role_stats['compliant'] ); ?></td>
|
||||
<td><?php echo esc_html( $role_stats['non_compliant'] ); ?></td>
|
||||
<td><?php echo esc_html( (string) $role_stats['total'] ); ?></td>
|
||||
<td><?php echo esc_html( (string) $role_stats['compliant'] ); ?></td>
|
||||
<td><?php echo esc_html( (string) $role_stats['non_compliant'] ); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
|
|
@ -1512,19 +1605,29 @@ class Two_Factor_Extended_Settings {
|
|||
</tr>
|
||||
<?php else : ?>
|
||||
<?php foreach ( $non_compliant as $user_data ) : ?>
|
||||
<?php
|
||||
$user_login_val = isset( $user_data['user_login'] ) && is_string( $user_data['user_login'] ) ? $user_data['user_login'] : '';
|
||||
$user_email_val = isset( $user_data['user_email'] ) && is_string( $user_data['user_email'] ) ? $user_data['user_email'] : '';
|
||||
$roles_raw = isset( $user_data['roles'] ) && is_array( $user_data['roles'] ) ? $user_data['roles'] : array();
|
||||
$missing_raw = isset( $user_data['missing_providers'] ) && is_array( $user_data['missing_providers'] ) ? $user_data['missing_providers'] : array();
|
||||
$in_grace = ! empty( $user_data['in_grace_period'] );
|
||||
$grace_remaining = isset( $user_data['grace_remaining'] ) && is_numeric( $user_data['grace_remaining'] ) ? (int) $user_data['grace_remaining'] : 0;
|
||||
$roles_display = array_filter( $roles_raw, 'is_string' );
|
||||
$missing_display = array_filter( $missing_raw, 'is_string' );
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo esc_html( $user_data['user_login'] ); ?></td>
|
||||
<td><?php echo esc_html( $user_data['user_email'] ); ?></td>
|
||||
<td><?php echo esc_html( implode( ', ', $user_data['roles'] ) ); ?></td>
|
||||
<td><?php echo esc_html( implode( ', ', $user_data['missing_providers'] ) ); ?></td>
|
||||
<td><?php echo esc_html( $user_login_val ); ?></td>
|
||||
<td><?php echo esc_html( $user_email_val ); ?></td>
|
||||
<td><?php echo esc_html( implode( ', ', $roles_display ) ); ?></td>
|
||||
<td><?php echo esc_html( implode( ', ', $missing_display ) ); ?></td>
|
||||
<td>
|
||||
<?php if ( $user_data['in_grace_period'] ) : ?>
|
||||
<?php if ( $in_grace ) : ?>
|
||||
<span style="color: orange;">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: Number of days */
|
||||
esc_html__( 'Grace: %d days', 'two-factor-extended' ),
|
||||
(int) $user_data["grace_remaining"]
|
||||
absint( $grace_remaining )
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
|
|
@ -1555,7 +1658,7 @@ class Two_Factor_Extended_Settings {
|
|||
// Handle form submission.
|
||||
if ( isset( $_POST['submit'] ) ) {
|
||||
// Verify nonce.
|
||||
$nonce = isset( $_POST['two_factor_extended_network_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['two_factor_extended_network_nonce'] ) ) : '';
|
||||
$nonce = isset( $_POST['two_factor_extended_network_nonce'] ) && is_string( $_POST['two_factor_extended_network_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['two_factor_extended_network_nonce'] ) ) : '';
|
||||
|
||||
if ( ! wp_verify_nonce( $nonce, 'two_factor_extended_network_settings' ) ) {
|
||||
wp_die( esc_html__( 'Security check failed.', 'two-factor-extended' ) );
|
||||
|
|
@ -1616,7 +1719,7 @@ class Two_Factor_Extended_Settings {
|
|||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @return array Default settings.
|
||||
* @return array<string, mixed> Default settings.
|
||||
*/
|
||||
private function get_default_settings(): array {
|
||||
$all_roles = Two_Factor_Extended_Role_Manager::get_all_roles();
|
||||
|
|
@ -1641,11 +1744,15 @@ class Two_Factor_Extended_Settings {
|
|||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @return array Plugin settings.
|
||||
* @return array<string, mixed> Plugin settings.
|
||||
*/
|
||||
public function get_settings(): array {
|
||||
$settings = get_option( TWO_FACTOR_EXTENDED_OPTION_SETTINGS, array() );
|
||||
|
||||
if ( ! is_array( $settings ) ) {
|
||||
$settings = array();
|
||||
}
|
||||
|
||||
return wp_parse_args( $settings, $this->get_default_settings() );
|
||||
}
|
||||
|
||||
|
|
@ -1654,7 +1761,7 @@ class Two_Factor_Extended_Settings {
|
|||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @param array $settings New settings values.
|
||||
* @param array<string, mixed> $settings New settings values.
|
||||
*
|
||||
* @return bool True if settings were updated successfully.
|
||||
*/
|
||||
|
|
@ -1669,20 +1776,20 @@ class Two_Factor_Extended_Settings {
|
|||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @param array $input Raw settings input.
|
||||
* @param array<string, mixed> $input Raw settings input.
|
||||
*
|
||||
* @return array Sanitized settings.
|
||||
* @return array<string, mixed> Sanitized settings.
|
||||
*/
|
||||
public function sanitize_settings( array $input ): array {
|
||||
$sanitized = array();
|
||||
|
||||
// Sanitize enabled setting.
|
||||
if ( isset( $input['enabled'] ) ) {
|
||||
$sanitized['enabled'] = rest_sanitize_boolean( $input['enabled'] );
|
||||
$sanitized['enabled'] = (bool) $input['enabled'];
|
||||
}
|
||||
|
||||
// Sanitize grace period days.
|
||||
if ( isset( $input['grace_period_days'] ) ) {
|
||||
if ( isset( $input['grace_period_days'] ) && is_numeric( $input['grace_period_days'] ) ) {
|
||||
$grace_days = (int) $input['grace_period_days'];
|
||||
$sanitized['grace_period_days'] = max( 0, min( 365, $grace_days ) );
|
||||
}
|
||||
|
|
@ -1701,6 +1808,9 @@ class Two_Factor_Extended_Settings {
|
|||
// Now merge any submitted role requirements data.
|
||||
if ( isset( $input['role_requirements'] ) && is_array( $input['role_requirements'] ) ) {
|
||||
foreach ( $input['role_requirements'] as $role => $providers ) {
|
||||
if ( ! is_string( $role ) ) {
|
||||
continue;
|
||||
}
|
||||
$role_slug = sanitize_key( $role );
|
||||
|
||||
if ( ! Two_Factor_Extended_Role_Manager::role_exists( $role_slug ) ) {
|
||||
|
|
@ -1708,7 +1818,12 @@ class Two_Factor_Extended_Settings {
|
|||
}
|
||||
|
||||
if ( is_array( $providers ) ) {
|
||||
$sanitized['role_requirements'][ $role_slug ] = array_map( 'sanitize_text_field', $providers );
|
||||
$sanitized['role_requirements'][ $role_slug ] = array_map(
|
||||
function ( $item ) {
|
||||
return sanitize_text_field( is_scalar( $item ) ? (string) $item : '' );
|
||||
},
|
||||
$providers
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1724,6 +1839,9 @@ class Two_Factor_Extended_Settings {
|
|||
// Now merge any submitted provider visibility data.
|
||||
if ( isset( $input['provider_visibility'] ) && is_array( $input['provider_visibility'] ) ) {
|
||||
foreach ( $input['provider_visibility'] as $role => $providers ) {
|
||||
if ( ! is_string( $role ) ) {
|
||||
continue;
|
||||
}
|
||||
$role_slug = sanitize_key( $role );
|
||||
|
||||
if ( ! Two_Factor_Extended_Role_Manager::role_exists( $role_slug ) ) {
|
||||
|
|
@ -1733,7 +1851,12 @@ class Two_Factor_Extended_Settings {
|
|||
if ( is_array( $providers ) ) {
|
||||
// Remove duplicates and sanitize.
|
||||
$sanitized['provider_visibility'][ $role_slug ] = array_unique(
|
||||
array_map( 'sanitize_text_field', $providers )
|
||||
array_map(
|
||||
function ( $item ) {
|
||||
return sanitize_text_field( is_scalar( $item ) ? (string) $item : '' );
|
||||
},
|
||||
$providers
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1750,13 +1873,14 @@ class Two_Factor_Extended_Settings {
|
|||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @param array $input Settings input to validate.
|
||||
* @param array<string, mixed> $input Settings input to validate.
|
||||
*
|
||||
* @return bool True if valid, false otherwise.
|
||||
*/
|
||||
public function validate_settings( array $input ): bool {
|
||||
// Basic validation - can be extended.
|
||||
return is_array( $input );
|
||||
// Since parameter is typed as array, it's always valid.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1771,7 +1895,7 @@ class Two_Factor_Extended_Settings {
|
|||
}
|
||||
|
||||
// Verify nonce.
|
||||
if ( ! isset( $_POST['two_factor_extended_reset_nonce'] ) ||
|
||||
if ( ! isset( $_POST['two_factor_extended_reset_nonce'] ) || ! is_string( $_POST['two_factor_extended_reset_nonce'] ) ||
|
||||
! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['two_factor_extended_reset_nonce'] ) ), 'two_factor_extended_reset' ) ) {
|
||||
wp_die( esc_html__( 'Security check failed.', 'two-factor-extended' ) );
|
||||
}
|
||||
|
|
@ -1791,15 +1915,18 @@ class Two_Factor_Extended_Settings {
|
|||
// Clear user grace period data.
|
||||
$users = get_users( array( 'fields' => 'ID' ) );
|
||||
foreach ( $users as $user_id ) {
|
||||
delete_user_meta( $user_id, 'two_factor_extended_enforcement_date' );
|
||||
delete_user_meta( (int) $user_id, 'two_factor_extended_enforcement_date' );
|
||||
}
|
||||
|
||||
// Log the reset action.
|
||||
$audit_log = two_factor_extended()->get_audit_log();
|
||||
$audit_log->log_event(
|
||||
'settings_reset',
|
||||
'Plugin settings reset to default values'
|
||||
);
|
||||
|
||||
if ( null !== $audit_log ) {
|
||||
$audit_log->log_event(
|
||||
'settings_reset',
|
||||
'Plugin settings reset to default values'
|
||||
);
|
||||
}
|
||||
|
||||
// Redirect with success message.
|
||||
add_settings_error(
|
||||
|
|
|
|||
Loading…
Reference in a new issue