From f9c746387bf639aed7de7c2c785d8dba6d53e6cd Mon Sep 17 00:00:00 2001 From: q16marvin Date: Mon, 5 May 2025 00:18:25 +0200 Subject: [PATCH 1/3] add dialin pin in room seetings --- .../Controllers/api/v1/RoomController.php | 5 + app/Models/Room.php | 8 ++ app/Services/MeetingService.php | 3 +- ...4_231945_add_dialin_pin_to_rooms_table.php | 38 ++++++ resources/js/components/RoomTabSettings.vue | 6 + .../RoomTabSettingsDialinPinInput.vue | 113 ++++++++++++++++++ .../js/composables/useRoomTypeSettings.js | 6 + resources/js/constants/roomSettings.js | 3 + resources/js/views/AdminRoomTypesView.vue | 48 ++++++++ 9 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 database/migrations/2025_05_04_231945_add_dialin_pin_to_rooms_table.php create mode 100644 resources/js/components/RoomTabSettingsDialinPinInput.vue diff --git a/app/Http/Controllers/api/v1/RoomController.php b/app/Http/Controllers/api/v1/RoomController.php index ec3c598a4..a3b7592d0 100644 --- a/app/Http/Controllers/api/v1/RoomController.php +++ b/app/Http/Controllers/api/v1/RoomController.php @@ -174,6 +174,11 @@ public function store(CreateRoom $request) $room->access_code = random_int(111111111, 999999999); } + // Create dialin pin if activated for this room type + if ($room->roomType->dialin_pin_default) { + $room->dialin_pin = random_int(11111, 99999); + } + // Apply non-expert settings of the room type foreach (Room::ROOM_SETTINGS_DEFINITION as $setting => $config) { if (! $config['expert']) { diff --git a/app/Models/Room.php b/app/Models/Room.php index 181d29ab7..3338b5cf1 100644 --- a/app/Models/Room.php +++ b/app/Models/Room.php @@ -153,6 +153,10 @@ protected function casts() 'cast' => 'boolean', 'expert' => true, ], + 'dialin_pin' => [ + 'cast' => 'integer', + 'expert' => true, + ], ]; /** @@ -189,6 +193,10 @@ public static function getRoomSettingValidationRule($settingName) } array_push($rules, $enumValidation); } + // Custom validation for dialin_pin + elseif ($settingName === 'dialin_pin') { + array_push($rules, 'integer', 'digits:5', 'min:10000', 'max:99999'); + } // Room setting validation with invalid cast else { throw new \Exception('Trying to access room setting validation rule with invalid cast '.$settingName); diff --git a/app/Services/MeetingService.php b/app/Services/MeetingService.php index 56c89cc9e..5386411d9 100644 --- a/app/Services/MeetingService.php +++ b/app/Services/MeetingService.php @@ -98,7 +98,8 @@ public function start(): ?\BigBlueButton\Responses\CreateMeetingResponse ->setLockSettingsDisableNotes($this->meeting->room->getRoomSetting('lock_settings_disable_note')) ->setLockSettingsHideUserList($this->meeting->room->getRoomSetting('lock_settings_hide_user_list')) ->setLockSettingsLockOnJoin(true) - ->setMuteOnStart($this->meeting->room->getRoomSetting('mute_on_start')); + ->setMuteOnStart($this->meeting->room->getRoomSetting('mute_on_start')) + ->setVoiceBridge($this->meeting->room->getRoomSetting('dialin_pin')); $meetingParams->addMeta('bbb-origin', 'PILOS'); $meetingParams->addMeta('pilos-sub-spool-dir', config('recording.spool-sub-directory')); diff --git a/database/migrations/2025_05_04_231945_add_dialin_pin_to_rooms_table.php b/database/migrations/2025_05_04_231945_add_dialin_pin_to_rooms_table.php new file mode 100644 index 000000000..716e5702d --- /dev/null +++ b/database/migrations/2025_05_04_231945_add_dialin_pin_to_rooms_table.php @@ -0,0 +1,38 @@ +boolean('dialin_pin_enforced')->after('has_access_code_default')->default(false); + $table->boolean('dialin_pin_default')->after('dialin_pin_enforced')->default(false); + }); + Schema::table('rooms', function (Blueprint $table) { + $table->integer('dialin_pin')->nullable()->unique()->after('meeting_id'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('room_types', function (Blueprint $table) { + $table->dropColumn('dialin_pin_enforced'); + $table->dropColumn('dialin_pin_default'); + }); + Schema::table('rooms', function (Blueprint $table) { + $table->dropColumn('dialin_pin'); + }); + } +}; diff --git a/resources/js/components/RoomTabSettings.vue b/resources/js/components/RoomTabSettings.vue index 99f48746d..72e5a1eec 100644 --- a/resources/js/components/RoomTabSettings.vue +++ b/resources/js/components/RoomTabSettings.vue @@ -129,6 +129,7 @@ import RoomTabSettingsRadioGroup from "./RoomTabSettingsRadioGroup.vue"; import RoomTabSettingsSelectButton from "./RoomTabSettingsSelectButton.vue"; import RoomTabSettingsRoomTypeSelect from "./RoomTabSettingsRoomTypeSelect.vue"; import RoomTabSettingsAccessCodeInput from "./RoomTabSettingsAccessCodeInput.vue"; +import RoomTabSettingsDialinPinInput from "./RoomTabSettingsDialinPinInput.vue"; const props = defineProps({ room: { @@ -334,6 +335,11 @@ const form = computed(() => { { value: 1, label: t("rooms.settings.advanced.visibility.public") }, ], }, + { + setting: "dialin_pin", + label: t("rooms.dialin_pin"), + component: RoomTabSettingsDialinPinInput, + } ], }, ]; diff --git a/resources/js/components/RoomTabSettingsDialinPinInput.vue b/resources/js/components/RoomTabSettingsDialinPinInput.vue new file mode 100644 index 000000000..6e410cdad --- /dev/null +++ b/resources/js/components/RoomTabSettingsDialinPinInput.vue @@ -0,0 +1,113 @@ + + + diff --git a/resources/js/composables/useRoomTypeSettings.js b/resources/js/composables/useRoomTypeSettings.js index 493341e1b..ca4b8336e 100644 --- a/resources/js/composables/useRoomTypeSettings.js +++ b/resources/js/composables/useRoomTypeSettings.js @@ -145,6 +145,12 @@ export function useRoomTypeSettings() { 1: t("rooms.settings.advanced.visibility.public"), }, }, + { + key: "dialin_pin", + current_value_key: "dialin_pin", + label: t("rooms.settings.general.dialin_pin"), + type: "switch", + }, ], }, ]; diff --git a/resources/js/constants/roomSettings.js b/resources/js/constants/roomSettings.js index 9a035eecc..10a1c9354 100644 --- a/resources/js/constants/roomSettings.js +++ b/resources/js/constants/roomSettings.js @@ -50,6 +50,9 @@ export const ROOM_SETTINGS_DEFINITION = { visibility: { expert_setting: true, }, + dialin_pin: { + expert_setting: true, + }, welcome: { expert_setting: true, has_no_room_type_default: true, diff --git a/resources/js/views/AdminRoomTypesView.vue b/resources/js/views/AdminRoomTypesView.vue index 07f51aac7..7346c79e7 100644 --- a/resources/js/views/AdminRoomTypesView.vue +++ b/resources/js/views/AdminRoomTypesView.vue @@ -1403,6 +1403,52 @@ + + +
+ +
+
+ + +
+
+ + +
+
+
@@ -1561,6 +1607,8 @@ const model = ref({ visibility_enforced: false, has_access_code_default: true, has_access_code_enforced: false, + dialin_pin_default: false, + dialin_pin_enforced: false, }); const name = ref(""); From 3f62eb61359b9e40253d6f55fbd70135ba0c1afa Mon Sep 17 00:00:00 2001 From: q16marvin Date: Mon, 5 May 2025 23:09:06 +0200 Subject: [PATCH 2/3] add locales and some fix some bugs --- .../Controllers/api/v1/RoomController.php | 1 + .../Controllers/api/v1/RoomTypeController.php | 4 +++ app/Http/Requests/RoomTypeRequest.php | 4 +++ app/Http/Requests/UpdateRoomSettings.php | 33 +++++++++++++++++++ app/Http/Resources/RoomSettings.php | 1 + app/Http/Resources/RoomType.php | 3 ++ app/Models/Room.php | 9 +---- app/Models/RoomType.php | 2 ++ ..._222245_add_dialin_pin_to_rooms_table.php} | 8 ++--- lang/de/rooms.php | 7 ++++ lang/de/validation.php | 2 ++ lang/en/rooms.php | 7 ++++ lang/en/validation.php | 2 ++ resources/js/components/RoomTabSettings.vue | 3 +- .../RoomTabSettingsDialinPinInput.vue | 14 ++++---- .../js/composables/useRoomTypeSettings.js | 2 +- resources/js/views/AdminRoomTypesView.vue | 18 +++++----- 17 files changed, 90 insertions(+), 30 deletions(-) rename database/migrations/{2025_05_04_231945_add_dialin_pin_to_rooms_table.php => 2025_05_05_222245_add_dialin_pin_to_rooms_table.php} (70%) diff --git a/app/Http/Controllers/api/v1/RoomController.php b/app/Http/Controllers/api/v1/RoomController.php index a3b7592d0..413a206c3 100644 --- a/app/Http/Controllers/api/v1/RoomController.php +++ b/app/Http/Controllers/api/v1/RoomController.php @@ -278,6 +278,7 @@ public function update(UpdateRoomSettings $request, Room $room) $room->expert_mode = $request->expert_mode; $room->short_description = $request->short_description; $room->access_code = $request->access_code; + $room->dialin_pin = $request->dialin_pin; foreach (Room::ROOM_SETTINGS_DEFINITION as $setting => $config) { // Expert mode for room is deactivated and setting is an expert setting: do not update setting diff --git a/app/Http/Controllers/api/v1/RoomTypeController.php b/app/Http/Controllers/api/v1/RoomTypeController.php index cefb74241..d08c9f5c8 100644 --- a/app/Http/Controllers/api/v1/RoomTypeController.php +++ b/app/Http/Controllers/api/v1/RoomTypeController.php @@ -108,6 +108,8 @@ public function update(RoomTypeRequest $request, RoomType $roomType) $roomType->has_access_code_default = $request->has_access_code_default; $roomType->has_access_code_enforced = $request->has_access_code_enforced; + $roomType->has_dialin_pin_default = $request->has_dialin_pin_default; + $roomType->has_dialin_pin_enforced = $request->has_dialin_pin_enforced; $roomType->save(); @@ -143,6 +145,8 @@ public function store(RoomTypeRequest $request) $roomType->has_access_code_default = $request->has_access_code_default; $roomType->has_access_code_enforced = $request->has_access_code_enforced; + $roomType->has_dialin_pin_default = $request->has_dialin_pin_default; + $roomType->has_dialin_pin_enforced = $request->has_dialin_pin_enforced; $roomType->save(); diff --git a/app/Http/Requests/RoomTypeRequest.php b/app/Http/Requests/RoomTypeRequest.php index 023a9299c..68460baf6 100644 --- a/app/Http/Requests/RoomTypeRequest.php +++ b/app/Http/Requests/RoomTypeRequest.php @@ -25,6 +25,8 @@ public function rules() // Default room settings 'has_access_code_default' => ['required', 'boolean'], 'has_access_code_enforced' => ['required', 'boolean'], + 'has_dialin_pin_default' => ['required', 'boolean'], + 'has_dialin_pin_enforced' => ['required', 'boolean'], ]; // Default room settings @@ -50,6 +52,8 @@ public function attributes(): array $locales = [ 'has_access_code_default' => __('validation.room_type_attribute_default', ['attribute' => __('validation.attributes.has_access_code')]), 'has_access_code_enforced' => __('validation.room_type_attribute_enforced', ['attribute' => __('validation.attributes.has_access_code')]), + 'has_dialin_pin_default' => __('validation.room_type_attribute_default', ['attribute' => __('validation.attributes.has_dialin_pin')]), + 'has_dialin_pin_enforced' => __('validation.room_type_attribute_enforced', ['attribute' => __('validation.attributes.has_dialin_pin')]), ]; foreach (Room::ROOM_SETTINGS_DEFINITION as $setting => $config) { diff --git a/app/Http/Requests/UpdateRoomSettings.php b/app/Http/Requests/UpdateRoomSettings.php index 1dee65f68..273ec2678 100644 --- a/app/Http/Requests/UpdateRoomSettings.php +++ b/app/Http/Requests/UpdateRoomSettings.php @@ -17,6 +17,7 @@ public function rules() 'name' => ['required', 'string', 'min:2', 'max:'.config('bigbluebutton.room_name_limit')], 'short_description' => ['nullable', 'string', 'max:300'], 'expert_mode' => ['required', 'boolean'], + 'dialin_pin' => $this->getDialinPinValidationRule(), ]; // Generate validation rules for all visible room settings @@ -66,4 +67,36 @@ private function getAccessCodeValidationRule(): array return $rules; } + + /** + * Set dialin_pin validation rule based on the settings in the room type + * + * @return string[] dialin_pin validation rules + */ + private function getDialinPinValidationRule(): array + { + $rules = ['integer', 'digits:5', 'bail', 'min:10000', 'max:99999', 'unique:rooms,dialin_pin,' . $this->room->id]; + + // Make sure that the given room type id is a number + if (is_numeric($this->input('room_type'))) { + // Check if a room type exists with the given number + $newRoomType = RoomType::find($this->input('room_type')); + if ($newRoomType) { + // Set dialin_pin to required if enforced in room type + if ($newRoomType->has_dialin_pin_enforced && $newRoomType->has_dialin_pin_default) { + array_unshift($rules, 'required'); + } + // Set dialin_pin to prohibited if enforced in room type + elseif ($newRoomType->has_adialin_pin_enforced && ! $newRoomType->has_dialin_pin_default) { + array_unshift($rules, 'prohibited', 'nullable'); + } + // Set dialin_pin to nullable (room can have an dialin_pin but dialin_pin is not enforced) + else { + array_unshift($rules, 'nullable'); + } + } + } + + return $rules; + } } diff --git a/app/Http/Resources/RoomSettings.php b/app/Http/Resources/RoomSettings.php index 4429d6df6..9c7ec7ba1 100644 --- a/app/Http/Resources/RoomSettings.php +++ b/app/Http/Resources/RoomSettings.php @@ -31,6 +31,7 @@ public function toArray($request) 'welcome' => $this->expert_mode ? $this->welcome : '', 'short_description' => $this->short_description, 'access_code' => $this->access_code, + 'dialin_pin' => $this->dialin_pin, 'room_type' => (new RoomType($this->roomType))->withDefaultRoomSettings()->withFeatures(), $this->merge($this->getRoomSettings()), ]; diff --git a/app/Http/Resources/RoomType.php b/app/Http/Resources/RoomType.php index fc5cb43fc..7e1c25cdc 100644 --- a/app/Http/Resources/RoomType.php +++ b/app/Http/Resources/RoomType.php @@ -73,6 +73,9 @@ public function getDefaultRoomSettings() $settings['has_access_code_default'] = $this->has_access_code_default; $settings['has_access_code_enforced'] = $this->has_access_code_enforced; + $settings['has_dialin_pin_default'] = $this->has_dialin_pin_default; + $settings['has_dialin_pin_enforced'] = $this->has_dialin_pin_enforced; + return $settings; } diff --git a/app/Models/Room.php b/app/Models/Room.php index 3338b5cf1..eda2d7bb9 100644 --- a/app/Models/Room.php +++ b/app/Models/Room.php @@ -66,6 +66,7 @@ protected function casts() 'expert_mode' => 'boolean', 'delete_inactive' => 'datetime', 'access_code' => 'integer', + 'dialin_pin' => 'integer', ]; // Generate casts for settings that are also present in the room type @@ -153,10 +154,6 @@ protected function casts() 'cast' => 'boolean', 'expert' => true, ], - 'dialin_pin' => [ - 'cast' => 'integer', - 'expert' => true, - ], ]; /** @@ -193,10 +190,6 @@ public static function getRoomSettingValidationRule($settingName) } array_push($rules, $enumValidation); } - // Custom validation for dialin_pin - elseif ($settingName === 'dialin_pin') { - array_push($rules, 'integer', 'digits:5', 'min:10000', 'max:99999'); - } // Room setting validation with invalid cast else { throw new \Exception('Trying to access room setting validation rule with invalid cast '.$settingName); diff --git a/app/Models/RoomType.php b/app/Models/RoomType.php index 9d11369ab..e83131b94 100644 --- a/app/Models/RoomType.php +++ b/app/Models/RoomType.php @@ -21,6 +21,8 @@ protected function casts() // Default room settings 'has_access_code_default' => 'boolean', 'has_access_code_enforced' => 'boolean', + 'has_dialin_pin_default' => 'boolean', + 'has_dialin_pin_enforced' => 'boolean', ]; // Generate casts for default room settings (that are also present in the room) diff --git a/database/migrations/2025_05_04_231945_add_dialin_pin_to_rooms_table.php b/database/migrations/2025_05_05_222245_add_dialin_pin_to_rooms_table.php similarity index 70% rename from database/migrations/2025_05_04_231945_add_dialin_pin_to_rooms_table.php rename to database/migrations/2025_05_05_222245_add_dialin_pin_to_rooms_table.php index 716e5702d..907a60fc4 100644 --- a/database/migrations/2025_05_04_231945_add_dialin_pin_to_rooms_table.php +++ b/database/migrations/2025_05_05_222245_add_dialin_pin_to_rooms_table.php @@ -14,8 +14,8 @@ public function up(): void { Schema::table('room_types', function (Blueprint $table) { - $table->boolean('dialin_pin_enforced')->after('has_access_code_default')->default(false); - $table->boolean('dialin_pin_default')->after('dialin_pin_enforced')->default(false); + $table->boolean('has_dialin_pin_enforced')->after('has_access_code_default')->default(false); + $table->boolean('has_dialin_pin_default')->after('has_dialin_pin_enforced')->default(false); }); Schema::table('rooms', function (Blueprint $table) { $table->integer('dialin_pin')->nullable()->unique()->after('meeting_id'); @@ -28,8 +28,8 @@ public function up(): void public function down(): void { Schema::table('room_types', function (Blueprint $table) { - $table->dropColumn('dialin_pin_enforced'); - $table->dropColumn('dialin_pin_default'); + $table->dropColumn('has_dialin_pin_enforced'); + $table->dropColumn('has_dialin_pin_default'); }); Schema::table('rooms', function (Blueprint $table) { $table->dropColumn('dialin_pin'); diff --git a/lang/de/rooms.php b/lang/de/rooms.php index f6fd4a9d6..78560560a 100644 --- a/lang/de/rooms.php +++ b/lang/de/rooms.php @@ -2,6 +2,7 @@ return [ 'access_code' => 'Zugangscode', + 'dialin_pin' => 'Einwahl-PIN', 'auth_throttled' => 'Zu viele Versuche. Bitte versuchen Sie es in :try_again Sekunden erneut.', 'become_member' => 'Mitglied werden', 'change_type' => [ @@ -358,6 +359,12 @@ 'public' => 'Öffentlich', 'title' => 'Sichtbarkeit', ], + 'has_dialin_pin' => 'Einwahl PIN', + 'dialin_pin_none_placeholder' => '-- Zufällig --', + 'dialin_pin_enforced' => 'Die Raumart erzwingt, dass ein Einwahl Pin existiert', + 'dialin_pin_prohibited' => 'Die Raumart erzwingt, dass kein Einwahl Pin existiert', + 'generate_dialin_pin' => 'Neuen Einwahl Pin erstellen', + 'delete_dialin_pin' => 'Einwahl Pin entfernen', ], 'expert_mode' => [ 'activate' => 'Expertenmodus aktivieren', diff --git a/lang/de/validation.php b/lang/de/validation.php index 166c611b4..576074b26 100644 --- a/lang/de/validation.php +++ b/lang/de/validation.php @@ -80,6 +80,7 @@ 'general_toast_lifetime' => 'Anzeigedauer von Pop-up-Nachrichten', 'generate_password' => 'Passwort generieren lassen', 'has_access_code' => 'Zugangscode', + 'has_dialin_pin' => 'Einwahl PIN', 'hour' => 'Stunde', 'image' => 'Bild', 'last_name' => 'Nachname', @@ -164,6 +165,7 @@ 'username' => 'Benutzerkennung', 'users' => 'Benutzer', 'visibility' => 'Sichtbarkeit', + 'dialin_pin' => 'Einwahl PIN', 'webcams_only_for_moderator' => 'Webcam nur für Moderatoren sichtbar', 'welcome' => 'Begrüßungsnachricht', 'year' => 'Jahr', diff --git a/lang/en/rooms.php b/lang/en/rooms.php index 1c0ffc042..9ecf02a73 100644 --- a/lang/en/rooms.php +++ b/lang/en/rooms.php @@ -2,6 +2,7 @@ return [ 'access_code' => 'Access code', + 'dialin_pin' => 'Dialin PIN', 'auth_throttled' => 'Too many attempts. Please try again in :try_again seconds.', 'become_member' => 'Become member', 'change_type' => [ @@ -358,6 +359,12 @@ 'public' => 'Public', 'title' => 'Visibility', ], + 'has_dialin_pin' => 'Dialin PIN', + 'dialin_pin_none_placeholder' => '-- Random --', + 'dialin_pin_enforced' => 'The room type enforces the existence of an dialin pin', + 'dialin_pin_prohibited' => 'The room type enforces the absence of an dialin pin', + 'generate_dialin_pin' => 'Generate new dialin pin', + 'delete_dialin_pin' => 'Delete dialin pin', ], 'expert_mode' => [ 'activate' => 'Activate expert mode', diff --git a/lang/en/validation.php b/lang/en/validation.php index 1f3d75efb..1588f9e8d 100644 --- a/lang/en/validation.php +++ b/lang/en/validation.php @@ -80,6 +80,7 @@ 'general_toast_lifetime' => 'Display duration of pop-up messages', 'generate_password' => 'Generate password', 'has_access_code' => 'Access code', + 'has_dialin_pin' => 'Dialin PIN', 'hour' => 'Hour', 'image' => 'Image', 'last_name' => 'Last name', @@ -164,6 +165,7 @@ 'username' => 'Username', 'users' => 'Users', 'visibility' => 'Visibility', + 'dialin_pin' => 'Dialin PIN', 'webcams_only_for_moderator' => 'Only moderators can see the webcam', 'welcome' => 'Welcome message', 'year' => 'Year', diff --git a/resources/js/components/RoomTabSettings.vue b/resources/js/components/RoomTabSettings.vue index 72e5a1eec..e04ebf492 100644 --- a/resources/js/components/RoomTabSettings.vue +++ b/resources/js/components/RoomTabSettings.vue @@ -337,7 +337,8 @@ const form = computed(() => { }, { setting: "dialin_pin", - label: t("rooms.dialin_pin"), + label: t("rooms.settings.advanced.has_dialin_pin"), + placeholder: t("rooms.settings.advanced.dialin_pin_none_placeholder"), component: RoomTabSettingsDialinPinInput, } ], diff --git a/resources/js/components/RoomTabSettingsDialinPinInput.vue b/resources/js/components/RoomTabSettingsDialinPinInput.vue index 6e410cdad..d442ab03d 100644 --- a/resources/js/components/RoomTabSettingsDialinPinInput.vue +++ b/resources/js/components/RoomTabSettingsDialinPinInput.vue @@ -20,16 +20,16 @@