From d875ed77b02a0b6deda8d8050acfe9b7c9ca512e Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Thu, 16 Jul 2026 13:27:42 +0200 Subject: [PATCH 01/15] Add privacy setting to disable finding users by partial matches of their name --- .../Controllers/api/v1/SettingsController.php | 1 + .../Controllers/api/v1/UserController.php | 9 ++++-- app/Http/Requests/UpdateSettingsRequest.php | 1 + app/Http/Resources/ConfigResource.php | 1 + app/Http/Resources/SettingsResource.php | 1 + app/Settings/UserSettings.php | 2 ++ ...5_130614_add_user_name_search_disabled.php | 18 +++++++++++ lang/en/admin.php | 4 +++ lang/en/rooms.php | 2 ++ .../RoomTabMembersAddSingleModal.vue | 21 +++++++++++-- .../RoomTransferOwnershipButton.vue | 21 +++++++++++-- resources/js/views/AdminSettings.vue | 30 +++++++++++++++++++ 12 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 database/settings/2026_07_15_130614_add_user_name_search_disabled.php diff --git a/app/Http/Controllers/api/v1/SettingsController.php b/app/Http/Controllers/api/v1/SettingsController.php index bff8927df5..c33a375e2e 100644 --- a/app/Http/Controllers/api/v1/SettingsController.php +++ b/app/Http/Controllers/api/v1/SettingsController.php @@ -189,6 +189,7 @@ public function update(UpdateSettingsRequest $request) $roomSettings->hide_owner_from_guests = $request->boolean('room_hide_owner_from_guests'); $userSettings->password_change_allowed = $request->boolean('user_password_change_allowed'); + $userSettings->search_by_name = $request->boolean('user_search_by_name'); $bannerSettings->enabled = $request->boolean('banner_enabled'); $bannerSettings->title = $request->input('banner_title'); diff --git a/app/Http/Controllers/api/v1/UserController.php b/app/Http/Controllers/api/v1/UserController.php index c25ad099fb..20e7f48d19 100644 --- a/app/Http/Controllers/api/v1/UserController.php +++ b/app/Http/Controllers/api/v1/UserController.php @@ -19,6 +19,7 @@ use App\Services\AuthenticationService; use App\Services\EmailVerification\EmailVerificationService; use App\Settings\GeneralSettings; +use App\Settings\UserSettings; use Carbon\Carbon; use Exception; use Illuminate\Auth\Access\AuthorizationException; @@ -46,13 +47,17 @@ public function __construct() * @param UserSearchRequest $request query parameter with search query * @return AnonymousResourceCollection */ - public function search(UserSearchRequest $request) + public function search(UserSearchRequest $request, UserSettings $userSettings) { if (! $request->filled('query')) { abort(204, 'Too many results'); } - $query = User::withNameOrEmail($request->query('query')); + if ($userSettings->search_by_name) { + $query = User::withNameOrEmail($request->query('query')); + } else { + $query = User::whereLike('email', $request->query('query')); + } if ($query->count() > config('bigbluebutton.user_search_limit')) { abort(204, 'Too many results'); diff --git a/app/Http/Requests/UpdateSettingsRequest.php b/app/Http/Requests/UpdateSettingsRequest.php index 9ae7803d04..6091d97259 100644 --- a/app/Http/Requests/UpdateSettingsRequest.php +++ b/app/Http/Requests/UpdateSettingsRequest.php @@ -75,6 +75,7 @@ public function rules() 'room_hide_owner_from_guests' => ['required', 'boolean'], 'user_password_change_allowed' => ['required', 'boolean'], + 'user_search_by_name' => ['required', 'boolean'], 'recording_server_usage_enabled' => ['required', 'boolean'], 'recording_server_usage_retention_period' => ['required', 'numeric', Rule::enum(TimePeriod::class)], diff --git a/app/Http/Resources/ConfigResource.php b/app/Http/Resources/ConfigResource.php index dd529a9c1d..c9236037c9 100644 --- a/app/Http/Resources/ConfigResource.php +++ b/app/Http/Resources/ConfigResource.php @@ -69,6 +69,7 @@ public function toArray($request) ], 'user' => [ 'password_change_allowed' => $userSettings->password_change_allowed, + 'search_by_name' => $userSettings->search_by_name, ], 'bbb' => [ 'file_mimes' => config('bigbluebutton.allowed_file_mimes'), diff --git a/app/Http/Resources/SettingsResource.php b/app/Http/Resources/SettingsResource.php index 52f1b58800..5935cf606d 100644 --- a/app/Http/Resources/SettingsResource.php +++ b/app/Http/Resources/SettingsResource.php @@ -70,6 +70,7 @@ public function toArray($request) 'room_file_terms_of_use' => $roomSettings->file_terms_of_use, 'room_hide_owner_from_guests' => $roomSettings->hide_owner_from_guests, 'user_password_change_allowed' => $userSettings->password_change_allowed, + 'user_search_by_name' => $userSettings->search_by_name, 'recording_server_usage_enabled' => $recordingSettings->server_usage_enabled, 'recording_server_usage_retention_period' => $recordingSettings->server_usage_retention_period, 'recording_meeting_usage_enabled' => $recordingSettings->meeting_usage_enabled, diff --git a/app/Settings/UserSettings.php b/app/Settings/UserSettings.php index 4a5c2313e4..8ebca456e3 100644 --- a/app/Settings/UserSettings.php +++ b/app/Settings/UserSettings.php @@ -10,6 +10,8 @@ class UserSettings extends Settings { public bool $password_change_allowed; + public bool $search_by_name; + public static function group(): string { return 'user'; diff --git a/database/settings/2026_07_15_130614_add_user_name_search_disabled.php b/database/settings/2026_07_15_130614_add_user_name_search_disabled.php new file mode 100644 index 0000000000..d7be415db3 --- /dev/null +++ b/database/settings/2026_07_15_130614_add_user_name_search_disabled.php @@ -0,0 +1,18 @@ +migrator->add('user.search_by_name', true); + } + + public function down(): void + { + $this->migrator->delete('user.search_by_name'); + } +}; diff --git a/lang/en/admin.php b/lang/en/admin.php index 776656a683..adbadfb7c7 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -426,6 +426,10 @@ ], 'two_weeks' => '2 Weeks (14 Days)', 'two_years' => '2 Years (730 Days)', + 'user_search_by_name' => [ + 'description' => 'Allows users to find others by partial matches of their name or email address. When disabled, users can only be found by entering their exact email address.', + 'title' => 'Allow searching users by name', + ], 'user_settings' => 'User settings', ], 'streaming' => [ diff --git a/lang/en/rooms.php b/lang/en/rooms.php index 238a8a87f9..1aa159746a 100644 --- a/lang/en/rooms.php +++ b/lang/en/rooms.php @@ -222,8 +222,10 @@ 'add' => [ 'add' => 'Add', 'no_options' => 'Enter the name or email address of a user.', + 'no_options_email_only' => 'Enter the email address of a user.', 'no_result' => 'Oops! No user was found for this query.', 'placeholder' => 'Name or email', + 'placeholder_email_only' => 'Email', 'select_role' => 'Please select a role', 'select_user' => 'Please select the user you would like to add', 'too_many_results' => 'Too many users were found. Please enter a more precise search term.', diff --git a/resources/js/components/RoomTabMembersAddSingleModal.vue b/resources/js/components/RoomTabMembersAddSingleModal.vue index 038740d52b..dc6ef4b1e9 100644 --- a/resources/js/components/RoomTabMembersAddSingleModal.vue +++ b/resources/js/components/RoomTabMembersAddSingleModal.vue @@ -46,7 +46,11 @@ data-test="select-user-dropdown" label="lastname" track-by="id" - :placeholder="$t('rooms.members.modals.add.placeholder')" + :placeholder=" + settingsStore.getSetting('user.search_by_name') + ? $t('rooms.members.modals.add.placeholder') + : $t('rooms.members.modals.add.placeholder_email_only') + " open-direction="bottom" :options="users" :multiple="false" @@ -62,7 +66,7 @@ :show-no-results="true" :show-labels="false" :class="{ 'is-invalid': formErrors.fieldInvalid('user') }" - @search-change="asyncFind" + @search-change="onSearchChange" >