From ba36adf38b1fcdd520f983c8f1e4b63eeda590f9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 09:34:41 +0000 Subject: [PATCH 1/3] Replace RoomAuthService with Laravel Context Co-authored-by: samuelwei <4281791+samuelwei@users.noreply.github.com> # Conflicts: # app/Http/Controllers/api/v1/RoomController.php # app/Http/Middleware/RoomAuthenticate.php # app/Http/Requests/JoinMeeting.php # app/Http/Requests/StartMeeting.php # app/Http/Resources/Room.php # app/Models/Room.php # app/Services/MeetingService.php # app/Services/RoomAuthService.php # tests/Backend/Unit/MeetingTest.php # Conflicts: # app/Http/Resources/Room.php # tests/Backend/Unit/MeetingTest.php --- .../Controllers/api/v1/RoomController.php | 3 +- app/Http/Middleware/RoomAuthenticate.php | 15 +-- app/Http/Requests/JoinMeeting.php | 14 +-- app/Http/Requests/StartMeeting.php | 14 +-- app/Http/Resources/Room.php | 9 +- app/Models/Room.php | 8 +- app/Providers/AppServiceProvider.php | 5 - app/Services/MeetingService.php | 3 +- app/Services/RoomAuthService.php | 99 ------------------- tests/Backend/Unit/MeetingTest.php | 26 +++-- 10 files changed, 32 insertions(+), 164 deletions(-) delete mode 100644 app/Services/RoomAuthService.php diff --git a/app/Http/Controllers/api/v1/RoomController.php b/app/Http/Controllers/api/v1/RoomController.php index 77b62cfce..736f822a2 100644 --- a/app/Http/Controllers/api/v1/RoomController.php +++ b/app/Http/Controllers/api/v1/RoomController.php @@ -25,7 +25,6 @@ use App\Models\RoomType; use App\Models\User; use App\Prometheus\Counter; -use App\Services\RoomAuthService; use App\Services\RoomService; use App\Settings\GeneralSettings; use Illuminate\Auth\Access\AuthorizationException; @@ -201,7 +200,7 @@ public function store(CreateRoom $request) * * @return \App\Http\Resources\Room */ - public function show(Room $room, RoomAuthService $roomAuthService) + public function show(Room $room) { return (new \App\Http\Resources\Room($room))->withDetails(); } diff --git a/app/Http/Middleware/RoomAuthenticate.php b/app/Http/Middleware/RoomAuthenticate.php index 71707f9fa..f59de1ce4 100644 --- a/app/Http/Middleware/RoomAuthenticate.php +++ b/app/Http/Middleware/RoomAuthenticate.php @@ -8,22 +8,15 @@ use App\Models\Room; use App\Models\RoomAuthToken; use App\Prometheus\Counter; -use App\Services\RoomAuthService; use Closure; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Context; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; class RoomAuthenticate { - protected RoomAuthService $roomAuthService; - - public function __construct(RoomAuthService $roomAuthService) - { - $this->roomAuthService = $roomAuthService; - } - /** * Handle requests to room routes and determine room unauthenticated status * @@ -144,9 +137,9 @@ public function handle($request, Closure $next, $allowUnAuthenticated = false) return $this->handleError(CustomErrorMessages::ROOM_REQUIRE_CODE->value, 403, 'Forbidden', __('rooms.require_access_code')); } - // make authentication status and personalized link available to other parts of the application - $this->roomAuthService->setAuthenticated($room, $authenticated); - $this->roomAuthService->setRoomPersonalizedLink($room, $personalizedLink); + // make authentication status and token available to other parts of the application + Context::addHidden("room.{$room->id}.authenticated", $authenticated); + Context::addHidden("room.{$room->id}.personalized_link", $personalizedLink); return $next($request); } diff --git a/app/Http/Requests/JoinMeeting.php b/app/Http/Requests/JoinMeeting.php index fcef2cb78..9f4e07e69 100644 --- a/app/Http/Requests/JoinMeeting.php +++ b/app/Http/Requests/JoinMeeting.php @@ -3,23 +3,17 @@ namespace App\Http\Requests; use App\Rules\ValidName; -use App\Services\RoomAuthService; use Illuminate\Foundation\Http\FormRequest; +use Illuminate\Support\Facades\Context; class JoinMeeting extends FormRequest { - protected RoomAuthService $roomAuthService; - - public function __construct(RoomAuthService $roomAuthService) - { - parent::__construct(); - $this->roomAuthService = $roomAuthService; - } - public function rules(): array { + $personalizedLink = Context::getHidden("room.{$this->room->id}.personalized_link"); + $rules = [ - 'name' => auth()->check() || $this->roomAuthService->getRoomPersonalizedLink($this->room) ? [] : ['required', 'min:2', 'max:50', new ValidName], + 'name' => auth()->check() || $personalizedLink ? [] : ['required', 'min:2', 'max:50', new ValidName], 'dark_mode' => ['sometimes', 'boolean'], ]; diff --git a/app/Http/Requests/StartMeeting.php b/app/Http/Requests/StartMeeting.php index ca5c21f5f..70153caae 100644 --- a/app/Http/Requests/StartMeeting.php +++ b/app/Http/Requests/StartMeeting.php @@ -3,23 +3,17 @@ namespace App\Http\Requests; use App\Rules\ValidName; -use App\Services\RoomAuthService; use Illuminate\Foundation\Http\FormRequest; +use Illuminate\Support\Facades\Context; class StartMeeting extends FormRequest { - protected RoomAuthService $roomAuthService; - - public function __construct(RoomAuthService $roomAuthService) - { - parent::__construct(); - $this->roomAuthService = $roomAuthService; - } - public function rules(): array { + $personalizedLink = Context::getHidden("room.{$this->room->id}.personalized_link"); + $rules = [ - 'name' => auth()->check() || $this->roomAuthService->getRoomPersonalizedLink($this->room) ? [] : ['required', 'min:2', 'max:50', new ValidName], + 'name' => auth()->check() || $personalizedLink ? [] : ['required', 'min:2', 'max:50', new ValidName], 'dark_mode' => ['sometimes', 'boolean'], ]; diff --git a/app/Http/Resources/Room.php b/app/Http/Resources/Room.php index 8ec98b023..fc17fd3f6 100644 --- a/app/Http/Resources/Room.php +++ b/app/Http/Resources/Room.php @@ -4,9 +4,9 @@ use App\Http\Resources\User as UserResource; use App\Models\RoomPersonalizedLink; -use App\Services\RoomAuthService; -use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Support\Facades\Auth; +use Illuminate\Http\Resources\Json\JsonResource; +use Illuminate\Support\Facades\Context; use Illuminate\Support\Facades\Gate; class Room extends JsonResource @@ -41,9 +41,8 @@ public function __construct($resource) { parent::__construct($resource); - $roomAuthService = app()->make(RoomAuthService::class); - $this->personalizedLink = $roomAuthService->getRoomPersonalizedLink($resource); - $this->authenticated = $roomAuthService->isAuthenticated($resource); + $this->personalizedLink = Context::getHidden("room.{$resource->id}.personalized_link"); + $this->authenticated = Context::getHidden("room.{$resource->id}.authenticated") === true; } public function getDetails($latestMeeting) diff --git a/app/Models/Room.php b/app/Models/Room.php index 64523b8a7..70591c156 100644 --- a/app/Models/Room.php +++ b/app/Models/Room.php @@ -6,13 +6,13 @@ use App\Enums\RoomUserRole; use App\Enums\RoomVisibility; use App\Observers\RoomObserver; -use App\Services\RoomAuthService; use App\Settings\GeneralSettings; use App\Traits\AddsModelNameTrait; use Illuminate\Database\Eloquent\Attributes\ObservedBy; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasOne; +use Illuminate\Support\Facades\Context; use Illuminate\Validation\Rule; #[ObservedBy([RoomObserver::class])] @@ -273,8 +273,7 @@ public function personalizedLinks() */ public function isModerator(?User $user): bool { - $roomAuthService = app()->make(RoomAuthService::class); - $personalizedLink = $roomAuthService->getRoomPersonalizedLink($this); + $personalizedLink = Context::getHidden("room.{$this->id}.personalized_link"); if ($user == null && $personalizedLink != null) { return $personalizedLink->room->is($this) && $personalizedLink->role == RoomUserRole::MODERATOR; @@ -295,8 +294,7 @@ public function isCoOwner(?User $user): bool */ public function isMember(?User $user): bool { - $roomAuthService = app()->make(RoomAuthService::class); - $personalizedLink = $roomAuthService->getRoomPersonalizedLink($this); + $personalizedLink = Context::getHidden("room.{$this->id}.personalized_link"); if ($user == null && $personalizedLink != null) { return $personalizedLink->room->is($this) && ($personalizedLink->role == RoomUserRole::USER || $personalizedLink->role == RoomUserRole::MODERATOR); diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index b5e086548..f4696c02e 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -4,7 +4,6 @@ use App\Pulse\Users; use App\Services\LocaleService; -use App\Services\RoomAuthService; use App\Services\StreamingServiceFactory; use Illuminate\Filesystem\Filesystem; use Illuminate\Pagination\Paginator; @@ -31,10 +30,6 @@ public function register(): void $this->app->singleton(ResolvesUsers::class, Users::class); - $this->app->singleton(RoomAuthService::class, function () { - return new RoomAuthService; - }); - $this->app->register(\Laravel\Telescope\TelescopeServiceProvider::class); $this->app->register(TelescopeServiceProvider::class); diff --git a/app/Services/MeetingService.php b/app/Services/MeetingService.php index 01d43bc78..23df85905 100644 --- a/app/Services/MeetingService.php +++ b/app/Services/MeetingService.php @@ -633,8 +633,7 @@ private function mapAttendanceSessions($sessions): mixed */ public function getJoinUrl(JoinMeeting|StartMeeting $request): string { - $roomAuthService = app()->make(RoomAuthService::class); - $personalizedLink = $roomAuthService->getRoomPersonalizedLink($this->meeting->room); + $personalizedLink = \Illuminate\Support\Facades\Context::getHidden("room.{$this->meeting->room->id}.personalized_link"); if (Auth::guest()) { if ($personalizedLink) { diff --git a/app/Services/RoomAuthService.php b/app/Services/RoomAuthService.php deleted file mode 100644 index ee2040e29..000000000 --- a/app/Services/RoomAuthService.php +++ /dev/null @@ -1,99 +0,0 @@ -make(RoomAuthService::class) - */ -class RoomAuthService -{ - /** - * @var array Nested array of the attributes of each room - */ - protected $rooms = []; - - /** - * Get the value of a specific attribute for a room. - * - * @param Room $room The room object. - * @param string $attribute The name of the attribute to retrieve. - * @return mixed|null The value of the attribute or null if not found. - */ - protected function getRoomAttributes(Room $room, string $attribute): mixed - { - if (! isset($this->rooms[$room->id])) { - return null; - } - - if (! isset($this->rooms[$room->id][$attribute])) { - return null; - } - - return $this->rooms[$room->id][$attribute]; - } - - /** - * Set the value of a specific attribute for a room. - * - * @param Room $room The room object. - * @param string $attribute The name of the attribute to set. - * @param mixed $value The value to set for the attribute. - * @return void - */ - protected function setRoomAttributes(Room $room, string $attribute, mixed $value) - { - if (! isset($this->rooms[$room->id])) { - $this->rooms[$room->id] = []; - } - - $this->rooms[$room->id][$attribute] = $value; - } - - /** - * Set the authentication status of a user for a room. - * - * @param Room $room The room object. - * @param bool $authenticated The authentication status (true or false). - */ - public function setAuthenticated(Room $room, bool $authenticated): void - { - $this->setRoomAttributes($room, 'authenticated', $authenticated); - } - - /** - * Check if a user is authenticated for a room. - * - * @param Room $room The room object. - * @return bool Returns true if user is authenticated for the room, otherwise false. - */ - public function isAuthenticated(Room $room): bool - { - return $this->getRoomAttributes($room, 'authenticated') === true; - } - - /** - * Set the room personalized link for a room. - * - * @param Room $room The room object. - * @param RoomPersonalizedLink|null $personalizedLink The RoomPersonalizedLink object or null to unset the personalized link. - */ - public function setRoomPersonalizedLink(Room $room, ?RoomPersonalizedLink $personalizedLink): void - { - $this->setRoomAttributes($room, 'personalizedLink', $personalizedLink); - } - - /** - * Get the room personalized link of the current request for a room. - * - * @param Room $room The room object. - * @return RoomPersonalizedLink|null Returns the RoomPersonalizedLink object or null if the personalized link is not set. - */ - public function getRoomPersonalizedLink(Room $room): ?RoomPersonalizedLink - { - return $this->getRoomAttributes($room, 'personalizedLink'); - } -} diff --git a/tests/Backend/Unit/MeetingTest.php b/tests/Backend/Unit/MeetingTest.php index 855c70036..9f6102db3 100644 --- a/tests/Backend/Unit/MeetingTest.php +++ b/tests/Backend/Unit/MeetingTest.php @@ -11,11 +11,11 @@ use App\Models\Server; use App\Models\User; use App\Services\MeetingService; -use App\Services\RoomAuthService; use App\Services\ServerService; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Http\UploadedFile; +use Illuminate\Support\Facades\Context; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; @@ -337,11 +337,10 @@ public function test_join_parameters_authenticated_user() $serverService = new ServerService($server); $meetingService = new MeetingService($meeting); - $roomAuthService = app()->make(RoomAuthService::class); - $roomAuthService->setAuthenticated($meeting->room, true); + Context::addHidden("room.{$meeting->room->id}.authenticated", true); Auth::login($user); - $request = new JoinMeeting($roomAuthService); + $request = new JoinMeeting; $parameters = []; parse_str(parse_url($meetingService->setServerService($serverService)->getJoinUrl($request), PHP_URL_QUERY), $parameters); @@ -413,10 +412,9 @@ public function test_join_parameters_guest() $serverService = new ServerService($server); $meetingService = new MeetingService($meeting); - $roomAuthService = app()->make(RoomAuthService::class); - $roomAuthService->setAuthenticated($meeting->room, false); + Context::addHidden("room.{$meeting->room->id}.authenticated", false); - $request = new JoinMeeting($roomAuthService); + $request = new JoinMeeting; $request->replace([ 'name' => 'John Doe', ]); @@ -460,11 +458,10 @@ public function test_join_parameters_guest_with_personalized_link() $serverService = new ServerService($server); $meetingService = new MeetingService($meeting); - $roomAuthService = app()->make(RoomAuthService::class); - $roomAuthService->setAuthenticated($meeting->room, false); - $roomAuthService->setRoomPersonalizedLink($meeting->room, $link); + Context::addHidden("room.{$meeting->room->id}.authenticated", false); + Context::addHidden("room.{$meeting->room->id}.personalized_link", $link); - $request = new JoinMeeting($roomAuthService); + $request = new JoinMeeting; $parameters = []; parse_str(parse_url($meetingService->setServerService($serverService)->getJoinUrl($request), PHP_URL_QUERY), $parameters); @@ -506,8 +503,7 @@ public function test_join_parameters_with_custom_join_parameters() $serverService = new ServerService($server); $meetingService = new MeetingService($meeting); - $roomAuthService = app()->make(RoomAuthService::class); - $roomAuthService->setAuthenticated($meeting->room, false); + Context::addHidden("room.{$meeting->room->id}.authenticated", false); Auth::login($meeting->room->owner); @@ -515,7 +511,7 @@ public function test_join_parameters_with_custom_join_parameters() $roomType = $this->meeting->room->roomType; $roomType->join_parameters = "enforceLayout=PRESENTATION_ONLY\nwebcamBackgroundURL=https://example.com/background.png\nexcludeFromDashboard=true\nredirect=false\nuserdata-bbb_hide_presentation_on_join=true"; $roomType->save(); - $request = new JoinMeeting($roomAuthService); + $request = new JoinMeeting; $parameters = []; parse_str(parse_url($meetingService->setServerService($serverService)->getJoinUrl($request), PHP_URL_QUERY), $parameters); @@ -535,7 +531,7 @@ public function test_join_parameters_with_custom_join_parameters() $roomType->join_parameters = "enforceLayout=INVALID_LAYOUT\nexcludeFromDashboard=invalid\nuserdata-bbb_hide_presentation_on_join=true"; $roomType->save(); - $request = new JoinMeeting($roomAuthService); + $request = new JoinMeeting; $parameters = []; parse_str(parse_url($meetingService->setServerService($serverService)->getJoinUrl($request), PHP_URL_QUERY), $parameters); From 69849eba2a2af13d1e4b2e1c3c37d9d295e1425e Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Tue, 17 Feb 2026 15:07:23 +0100 Subject: [PATCH 2/3] Fix comment --- app/Http/Middleware/RoomAuthenticate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Middleware/RoomAuthenticate.php b/app/Http/Middleware/RoomAuthenticate.php index f59de1ce4..314b556cb 100644 --- a/app/Http/Middleware/RoomAuthenticate.php +++ b/app/Http/Middleware/RoomAuthenticate.php @@ -137,7 +137,7 @@ public function handle($request, Closure $next, $allowUnAuthenticated = false) return $this->handleError(CustomErrorMessages::ROOM_REQUIRE_CODE->value, 403, 'Forbidden', __('rooms.require_access_code')); } - // make authentication status and token available to other parts of the application + // make authentication status and personalized link available to other parts of the application Context::addHidden("room.{$room->id}.authenticated", $authenticated); Context::addHidden("room.{$room->id}.personalized_link", $personalizedLink); From b3090ca6cce8ce7720d8edc87a6b1969a2c440d4 Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Tue, 17 Feb 2026 15:11:06 +0100 Subject: [PATCH 3/3] Cleanup --- app/Http/Resources/Room.php | 2 +- app/Services/MeetingService.php | 4 ++-- tests/Backend/Unit/MeetingTest.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Http/Resources/Room.php b/app/Http/Resources/Room.php index fc17fd3f6..c42546609 100644 --- a/app/Http/Resources/Room.php +++ b/app/Http/Resources/Room.php @@ -4,8 +4,8 @@ use App\Http\Resources\User as UserResource; use App\Models\RoomPersonalizedLink; -use Illuminate\Support\Facades\Auth; use Illuminate\Http\Resources\Json\JsonResource; +use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Context; use Illuminate\Support\Facades\Gate; diff --git a/app/Services/MeetingService.php b/app/Services/MeetingService.php index 23df85905..5bccd3edb 100644 --- a/app/Services/MeetingService.php +++ b/app/Services/MeetingService.php @@ -9,7 +9,6 @@ use App\Http\Requests\StartMeeting; use App\Models\Meeting; use App\Models\MeetingAttendee; -use App\Models\Room; use App\Models\User; use App\Settings\BigBlueButtonSettings; use BigBlueButton\Enum\Feature; @@ -20,6 +19,7 @@ use BigBlueButton\Parameters\JoinMeetingParameters; use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Context; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\URL; @@ -633,7 +633,7 @@ private function mapAttendanceSessions($sessions): mixed */ public function getJoinUrl(JoinMeeting|StartMeeting $request): string { - $personalizedLink = \Illuminate\Support\Facades\Context::getHidden("room.{$this->meeting->room->id}.personalized_link"); + $personalizedLink = Context::getHidden("room.{$this->meeting->room->id}.personalized_link"); if (Auth::guest()) { if ($personalizedLink) { diff --git a/tests/Backend/Unit/MeetingTest.php b/tests/Backend/Unit/MeetingTest.php index 9f6102db3..29caeba73 100644 --- a/tests/Backend/Unit/MeetingTest.php +++ b/tests/Backend/Unit/MeetingTest.php @@ -15,8 +15,8 @@ use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Http\UploadedFile; -use Illuminate\Support\Facades\Context; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Context; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Storage;