Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/broadcasting/src/BroadcastManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use Hypervel\Bus\UniqueLock;
use Hypervel\Cache\Contracts\Factory as Cache;
use Hypervel\Foundation\Http\Kernel;
use Hypervel\Foundation\Http\Middleware\VerifyCsrfToken;
use Hypervel\ObjectPool\Traits\HasPoolProxy;
use Hypervel\Queue\Contracts\Factory as Queue;
use InvalidArgumentException;
Expand Down Expand Up @@ -76,6 +77,10 @@ public function routes(array $attributes = []): void
$attributes = $attributes ?: ['middleware' => ['web']];
}

// Exclude from CSRF verification. These routes receive POST requests
// from Pusher JavaScript clients which cannot include CSRF tokens.
VerifyCsrfToken::except(['broadcasting/auth']);

$kernels = $this->app->get(ConfigInterface::class)
->get('server.kernels', []);
foreach (array_keys($kernels) as $kernel) {
Expand All @@ -97,6 +102,10 @@ public function userRoutes(?array $attributes = null): void
{
$attributes = $attributes ?: ['middleware' => ['web']];

// Exclude from CSRF verification. These routes receive POST requests
// from Pusher JavaScript clients which cannot include CSRF tokens.
VerifyCsrfToken::except(['broadcasting/user-auth']);

$this->app->get(RouterDispatcherFactory::class)->getRouter()
->addRoute(
['GET', 'POST'],
Expand Down
60 changes: 60 additions & 0 deletions tests/Broadcasting/BroadcastManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Hypervel\Tests\Broadcasting;

use Hyperf\Contract\ConfigInterface;
use Hyperf\HttpServer\Router\DispatcherFactory as RouterDispatcherFactory;
use Hypervel\Broadcasting\BroadcastEvent;
use Hypervel\Broadcasting\BroadcastManager;
use Hypervel\Broadcasting\Channel;
Expand All @@ -19,6 +20,8 @@
use Hypervel\Container\DefinitionSource;
use Hypervel\Context\ApplicationContext;
use Hypervel\Foundation\Application;
use Hypervel\Foundation\Http\Kernel;
use Hypervel\Foundation\Http\Middleware\VerifyCsrfToken;
use Hypervel\Queue\Contracts\Factory as QueueFactoryContract;
use Hypervel\Support\Facades\Broadcast;
use Hypervel\Support\Facades\Bus;
Expand Down Expand Up @@ -61,6 +64,7 @@ protected function tearDown(): void
m::close();

Facade::clearResolvedInstances();
VerifyCsrfToken::flushState();
}

public function testEventCanBeBroadcastNow()
Expand Down Expand Up @@ -117,6 +121,62 @@ public function testThrowExceptionWhenUnknownStoreIsUsed()

$broadcastManager->connection('alien_connection');
}

public function testRoutesExcludesCsrfVerification()
{
$router = m::mock('router');
$router->shouldReceive('addRoute')->once();

$routerFactory = m::mock('routerFactory');
$routerFactory->shouldReceive('getRouter')
->with('http')
->andReturn($router);

$config = m::mock(ConfigInterface::class);
$config->shouldReceive('get')
->with('server.kernels', [])
->andReturn(['http' => []]);

$app = m::mock(ContainerInterface::class);
$app->shouldReceive('has')->with(Kernel::class)->andReturn(true);
$app->shouldReceive('get')->with(ConfigInterface::class)->andReturn($config);
$app->shouldReceive('get')->with(RouterDispatcherFactory::class)->andReturn($routerFactory);

$broadcastManager = new BroadcastManager($app);
$broadcastManager->routes();

// Verify the broadcasting/auth path is excluded from CSRF verification
$middleware = new VerifyCsrfToken(
m::mock(ContainerInterface::class),
m::mock(ConfigInterface::class),
m::mock(\Hyperf\HttpServer\Request::class)
);
$this->assertContains('broadcasting/auth', $middleware->getExcludedPaths());
}

public function testUserRoutesExcludesCsrfVerification()
{
$router = m::mock('router');
$router->shouldReceive('addRoute')->once();

$routerFactory = m::mock('routerFactory');
$routerFactory->shouldReceive('getRouter')
->andReturn($router);

$app = m::mock(ContainerInterface::class);
$app->shouldReceive('get')->with(RouterDispatcherFactory::class)->andReturn($routerFactory);

$broadcastManager = new BroadcastManager($app);
$broadcastManager->userRoutes();

// Verify the broadcasting/user-auth path is excluded from CSRF verification
$middleware = new VerifyCsrfToken(
m::mock(ContainerInterface::class),
m::mock(ConfigInterface::class),
m::mock(\Hyperf\HttpServer\Request::class)
);
$this->assertContains('broadcasting/user-auth', $middleware->getExcludedPaths());
}
}

class TestEvent implements ShouldBroadcast
Expand Down