Implement directory privacy settings and add rate limiting

Adds configurable privacy options for member directories, allowing restrictions on visibility based on roles or login status. Introduces rate limiting for unauthenticated AJAX requests to prevent brute-force attacks or abuse.
This commit is contained in:
Mykyta Synelnikov
2025-12-11 17:36:42 +02:00
parent b75a2145dd
commit fc2c5456e4
18 changed files with 285 additions and 78 deletions
+6
View File
@@ -284,6 +284,12 @@ if ( ! class_exists( 'um\admin\Admin' ) ) {
'_um_mode' => array(
'sanitize' => 'key',
),
'_um_privacy' => array(
'sanitize' => 'absint',
),
'_um_privacy_roles' => array(
'sanitize' => array( $this, 'sanitize_existed_role' ),
),
'_um_view_types' => array(
'sanitize' => array( $this, 'sanitize_md_view_types' ),
),
+7
View File
@@ -209,6 +209,13 @@ if ( ! class_exists( 'um\admin\Secure' ) ) {
$scanner_content .= '</span>';
$secure_fields = array(
array(
'id' => 'ajax_nopriv_rate_limit',
'type' => 'checkbox',
'label' => __( 'Rate Limit', 'ultimate-member' ),
'checkbox_label' => __( 'Enable Rate Limiting', 'ultimate-member' ),
'description' => __( 'This prevents brute-force enumeration attempts in guest AJAX requests.', 'ultimate-member' ),
),
array(
'id' => 'banned_capabilities',
'type' => 'multi_checkbox',
+2 -1
View File
@@ -728,7 +728,7 @@ if ( ! class_exists( 'um\admin\core\Admin_Metabox' ) ) {
* @param $object
* @param $box
*/
function load_metabox_directory( $object, $box ) {
public function load_metabox_directory( $object, $box ) {
$box['id'] = str_replace( 'um-admin-form-', '', $box['id'] );
preg_match('#\{.*?\}#s', $box['id'], $matches );
@@ -857,6 +857,7 @@ if ( ! class_exists( 'um\admin\core\Admin_Metabox' ) ) {
public function add_metabox_directory() {
add_meta_box( 'submitdiv', __( 'Publish', 'ultimate-member' ), array( &$this, 'custom_submitdiv' ), 'um_directory', 'side', 'high' );
add_meta_box( 'um-admin-form-general', __( 'General Options', 'ultimate-member' ), array( &$this, 'load_metabox_directory' ), 'um_directory', 'normal', 'default' );
add_meta_box( 'um-admin-form-privacy', __( 'Privacy Options', 'ultimate-member' ), array( &$this, 'load_metabox_directory' ), 'um_directory', 'normal', 'default' );
add_meta_box( 'um-admin-form-sorting', __( 'Sorting', 'ultimate-member' ), array( &$this, 'load_metabox_directory' ), 'um_directory', 'normal', 'default' );
add_meta_box( 'um-admin-form-profile', __( 'Profile Card', 'ultimate-member' ), array( &$this, 'load_metabox_directory' ), 'um_directory', 'normal', 'default' );
add_meta_box( 'um-admin-form-search', __( 'Search Options', 'ultimate-member' ), array( &$this, 'load_metabox_directory' ), 'um_directory', 'normal', 'default' );
@@ -1032,6 +1032,9 @@ if ( ! class_exists( 'um\admin\core\Admin_Settings' ) ) {
'display_login_form_notice' => array(
'sanitize' => 'bool',
),
'ajax_nopriv_rate_limit' => array(
'sanitize' => 'bool',
),
'banned_capabilities' => array(
'sanitize' => array( UM()->admin(), 'sanitize_wp_capabilities_assoc' ),
),
@@ -0,0 +1,48 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$fields = array(
array(
'id' => '_um_privacy',
'type' => 'select',
'label' => __( 'Who can see this member directory', 'ultimate-member' ),
'description' => __( 'Select which users can view this member directory. Minimum recommended visibility is `Members only`. Please pay attention that visible for guests (anyone) member directory can have sensitive information.', 'ultimate-member' ),
'options' => array(
0 => __( 'Anyone', 'ultimate-member' ),
1 => __( 'Guests only', 'ultimate-member' ),
2 => __( 'Members only', 'ultimate-member' ),
3 => __( 'Only specific roles', 'ultimate-member' ),
),
'value' => UM()->query()->get_meta_value( '_um_privacy', null, 2 ),
),
array(
'id' => '_um_privacy_roles',
'type' => 'select',
'multi' => true,
'label' => __( 'Allowed roles', 'ultimate-member' ),
'description' => __( 'Select the the user roles allowed to view this member directory.', 'ultimate-member' ),
'options' => UM()->roles()->get_roles(),
'placeholder' => __( 'Choose user roles...', 'ultimate-member' ),
'conditional' => array( '_um_privacy', '=', '3' ),
'value' => UM()->query()->get_meta_value( '_um_privacy_roles', null, 'na' ),
),
);
$fields = apply_filters( 'um_admin_extend_directory_options_privacy', $fields );
?>
<div class="um-admin-metabox">
<?php
UM()->admin_forms(
array(
'class' => 'um-member-directory-privacy um-half-column',
'prefix_id' => 'um_metadata',
'fields' => $fields,
)
)->render_form();
?>
<div class="clear"></div>
</div>