diff --git a/src/resources/vue/Meet/Room.vue b/src/resources/vue/Meet/Room.vue --- a/src/resources/vue/Meet/Room.vue +++ b/src/resources/vue/Meet/Room.vue @@ -467,17 +467,23 @@ return canvas.toDataURL(); }, requestId() { + const key = 'kolab-meet-uid' + + if (!this.reqId) { + this.reqId = localStorage.getItem(key) + } + if (!this.reqId) { - // FIXME: Shall we use some UUID generator? Or better something that identifies the - // user/browser so we could deny the join request for a longer time. - // I'm thinking about e.g. a bad actor knocking again and again and again, - // we don't want the room owner to be bothered every few seconds. - // Maybe a solution would be to store the identifier in the browser storage - // This would not prevent hackers from sending the new identifier on every request, - // but could make sure that it is kept after page refresh for the avg user. + // We store the identifier in the browser to make sure that it is the same after + // page refresh for the avg user. This will not prevent hackers from sending + // the new identifier on every request. + // If we're afraid of a room owner being spammed with join requests we might invent + // a way to silently ignore all join requests after the owner pressed some button + // stating "all attendees already joined, lock the room for good!". // This will create max. 24-char numeric string this.reqId = (String(Date.now()) + String(Math.random()).substring(2)).substring(0, 24) + localStorage.setItem(key, this.reqId) } return this.reqId diff --git a/src/tests/Browser/Meet/RoomControlsTest.php b/src/tests/Browser/Meet/RoomControlsTest.php --- a/src/tests/Browser/Meet/RoomControlsTest.php +++ b/src/tests/Browser/Meet/RoomControlsTest.php @@ -16,6 +16,15 @@ { parent::setUp(); $this->clearMeetEntitlements(); + $this->assignMeetEntitlement('john@kolab.org'); + + // Make sure there's no session yet, clear room settings + $room = Room::where('name', 'john')->first(); + if ($room->session_id) { + $room->session_id = null; + $room->save(); + } + $room->setSettings(['password' => null, 'locked' => null]); } public function tearDown(): void @@ -34,15 +43,6 @@ // TODO: This test does not work in headless mode $this->markTestIncomplete(); /* - // Make sure there's no session yet - $room = Room::where('name', 'john')->first(); - if ($room->session_id) { - $room->session_id = null; - $room->save(); - } - - $this->assignMeetEntitlement('john@kolab.org'); - $this->browse(function (Browser $browser) { // Join the room as an owner (authenticate) $browser->visit(new RoomPage('john')) @@ -89,15 +89,6 @@ */ public function testNicknameAndMuting(): void { - // Make sure there's no session yet - $room = Room::where('name', 'john')->first(); - if ($room->session_id) { - $room->session_id = null; - $room->save(); - } - - $this->assignMeetEntitlement('john@kolab.org'); - $this->browse(function (Browser $owner, Browser $guest) { // Join the room as an owner (authenticate) $owner->visit(new RoomPage('john')) @@ -234,15 +225,6 @@ */ public function testChat(): void { - // Make sure there's no session yet - $room = Room::where('name', 'john')->first(); - if ($room->session_id) { - $room->session_id = null; - $room->save(); - } - - $this->assignMeetEntitlement('john@kolab.org'); - $this->browse(function (Browser $owner, Browser $guest) { // Join the room as an owner $owner->visit(new RoomPage('john')) @@ -337,15 +319,6 @@ */ public function testShareScreen(): void { - // Make sure there's no session yet - $room = Room::where('name', 'john')->first(); - if ($room->session_id) { - $room->session_id = null; - $room->save(); - } - - $this->assignMeetEntitlement('john@kolab.org'); - $this->browse(function (Browser $owner, Browser $guest) { // Join the room as an owner $owner->visit(new RoomPage('john')) diff --git a/src/tests/Browser/Meet/RoomSecurityTest.php b/src/tests/Browser/Meet/RoomSecurityTest.php --- a/src/tests/Browser/Meet/RoomSecurityTest.php +++ b/src/tests/Browser/Meet/RoomSecurityTest.php @@ -23,6 +23,10 @@ $room = Room::where('name', 'john')->first(); $room->setSettings(['password' => null, 'locked' => null]); + if ($room->session_id) { + $room->session_id = null; + $room->save(); + } } public function tearDown(): void @@ -42,12 +46,7 @@ public function testRoomPassword(): void { $this->browse(function (Browser $owner, Browser $guest) { - // Make sure there's no session yet $room = Room::where('name', 'john')->first(); - if ($room->session_id) { - $room->session_id = null; - $room->save(); - } // Join the room as an owner (authenticate) $owner->visit(new RoomPage('john')) @@ -128,19 +127,15 @@ } /** - * Test locked room + * Test locked room (denying the join request) * * @group openvidu */ - public function testLockedRoom(): void + public function testLockedRoomDeny(): void { $this->browse(function (Browser $owner, Browser $guest) { // Make sure there's no session yet $room = Room::where('name', 'john')->first(); - if ($room->session_id) { - $room->session_id = null; - $room->save(); - } // Join the room as an owner (authenticate) $owner->visit(new RoomPage('john')) @@ -203,9 +198,46 @@ // wait 10 seconds to make sure the request message does not show up again ->pause(10 * 1000) ->assertMissing('.toast'); + }); + } + + /** + * Test locked room (accepting the join request, and dismissing a user) + * + * @group openvidu + */ + public function testLockedRoomAcceptAndDismiss(): void + { + $this->browse(function (Browser $owner, Browser $guest) { + // Make sure there's no session yet + $room = Room::where('name', 'john')->first(); + + // Join the room as an owner (authenticate) + $owner->visit(new RoomPage('john')) + // ->click('@setup-button') + // ->submitLogon('john@kolab.org', 'simple123') + ->waitFor('@setup-form') + ->waitUntilMissing('@setup-status-message.loading') + ->type('@setup-nickname-input', 'John') + ->clickWhenEnabled('@setup-button') + ->waitFor('@session') + // Enter Security option dialog + ->click('@menu button.link-security') + ->with(new Dialog('#security-options-dialog'), function (Browser $browser) use ($room) { + $browser->assertSeeIn('@title', 'Security options') + ->assertSeeIn('#room-lock label', 'Locked room:') + ->assertVisible('#room-lock input[type=checkbox]:not(:checked)') + ->assertVisible('#room-lock + small') + // Test setting the lock + ->click('#room-lock input') + ->assertToast(Toast::TYPE_SUCCESS, "Room configuration updated successfully.") + ->click('@button-action'); - // Test accepting the request - $guest->refresh() + $this->assertSame('true', $room->fresh()->getSetting('locked')); + }); + + // In another browser act as a guest + $guest->visit(new RoomPage('john')) ->waitFor('@setup-form') ->waitUntilMissing('@setup-status-message.loading') ->type('@setup-nickname-input', 'guest')