diff --git a/src/Pusher/Http/Controllers/UsersTerminateController.php b/src/Pusher/Http/Controllers/UsersTerminateController.php index 003efe81..e16be79e 100644 --- a/src/Pusher/Http/Controllers/UsersTerminateController.php +++ b/src/Pusher/Http/Controllers/UsersTerminateController.php @@ -5,14 +5,21 @@ use Laravel\Reverb\Http\Connection; use Psr\Http\Message\RequestInterface; use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Response; class UsersTerminateController extends Controller { /** * Handle the request. */ - public function handle(RequestInterface $request, Connection $connection, ...$args) + public function handle(RequestInterface $request, Connection $connection, ...$args): Response { + if(! $connection = $this->connections->find($args['user'])) { + return new JsonResponse((object) [], 400); + } + + $connection->disconnect(); + return new JsonResponse((object) []); } } diff --git a/src/Servers/Reverb/Factory.php b/src/Servers/Reverb/Factory.php index 5894b658..c70ef2be 100644 --- a/src/Servers/Reverb/Factory.php +++ b/src/Servers/Reverb/Factory.php @@ -45,7 +45,7 @@ protected static function routes(): RouteCollection $routes->add('channels', Route::get('/apps/{appId}/channels', new ChannelsController)); $routes->add('channel', Route::get('/apps/{appId}/channels/{channel}', new ChannelController)); $routes->add('channel_users', Route::get('/apps/{appId}/channels/{channel}/users', new ChannelUsersController)); - // $routes->add('users_terminate', Route::post('/apps/{appId}/users/{user}/terminate_connections', new UsersTerminateController)); + $routes->add('users_terminate', Route::post('/apps/{appId}/users/{user}/terminate_connections', new UsersTerminateController)); return $routes; } diff --git a/tests/Feature/Ratchet/UsersTerminateControllerTest.php b/tests/Feature/Ratchet/UsersTerminateControllerTest.php new file mode 100644 index 00000000..c1a8ab59 --- /dev/null +++ b/tests/Feature/Ratchet/UsersTerminateControllerTest.php @@ -0,0 +1,37 @@ +signedPostRequest('channels/users/not-a-user/terminate_connections')); +})->throws(ResponseException::class); + +it('unsubscribes from all channels and terminates a user', function () { + $connection = $this->connect(); + $this->subscribe('test-channel-one', connection: $connection); + $this->subscribe('test-channel-two', connection: $connection); + + $this->subscribe('test-channel-one'); + $this->subscribe('test-channel-two'); + + expect($connections = connectionManager()->all())->toHaveCount(3); + expect(channelManager()->connections(ChannelBroker::create('test-channel-one')))->toHaveCount(2); + expect(channelManager()->connections(ChannelBroker::create('test-channel-two')))->toHaveCount(2); + + $connection = Arr::first($connections); + + $response = await($this->signedPostRequest("users/{$connection->id()}/terminate_connections")); + + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('{}', $response->getBody()->getContents()); + expect($connections = connectionManager()->all())->toHaveCount(2); + expect(channelManager()->connections(ChannelBroker::create('test-channel-one')))->toHaveCount(1); + expect(channelManager()->connections(ChannelBroker::create('test-channel-two')))->toHaveCount(1); +});