Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion src/Loggers/CliLogger.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function message(string $message): void
$message['data'] = json_decode($message['data'], true);
}

if (isset($message['data']['channel_data'])) {
if (isset($message['data']['channel_data']) && is_string($message['data']['channel_data'])) {
$message['data']['channel_data'] = json_decode($message['data']['channel_data'], true);
}

Expand Down
7 changes: 7 additions & 0 deletions src/Protocols/Pusher/ClientEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Laravel\Reverb\Protocols\Pusher;

use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Laravel\Reverb\Contracts\Connection;

Expand All @@ -12,6 +13,12 @@ class ClientEvent
*/
public static function handle(Connection $connection, array $event): ?ClientEvent
{
Validator::make($event, [
'event' => ['required', 'string'],
'channel' => ['required', 'string'],
'data' => ['required', 'array'],
])->validate();

if (! Str::startsWith($event['event'], 'client-')) {
return null;
}
Expand Down
15 changes: 14 additions & 1 deletion src/Protocols/Pusher/EventHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Laravel\Reverb\Protocols\Pusher;

use Exception;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Laravel\Reverb\Contracts\Connection;
use Laravel\Reverb\Protocols\Pusher\Channels\CacheChannel;
Expand All @@ -24,7 +25,9 @@ public function __construct(protected ChannelManager $channels)
*/
public function handle(Connection $connection, string $event, array $payload = []): void
{
match (Str::after($event, 'pusher:')) {
$event = Str::after($event, 'pusher:');

match ($event) {
'connection_established' => $this->acknowledge($connection),
'subscribe' => $this->subscribe(
$connection,
Expand Down Expand Up @@ -55,6 +58,16 @@ public function acknowledge(Connection $connection): void
*/
public function subscribe(Connection $connection, string $channel, ?string $auth = null, ?string $data = null): void
{
Validator::make([
'channel' => $channel,
'auth' => $auth,
'channel_data' => $data,
], [
'channel' => ['nullable', 'string'],
'auth' => ['nullable', 'string'],
'channel_data' => ['nullable', 'json'],
])->validate();

$channel = $this->channels
->for($connection->app())
->findOrCreate($channel);
Expand Down
9 changes: 6 additions & 3 deletions src/Protocols/Pusher/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Laravel\Reverb\Protocols\Pusher;

use Exception;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Laravel\Reverb\Contracts\Connection;
use Laravel\Reverb\Events\MessageReceived;
Expand All @@ -12,6 +13,7 @@
use Laravel\Reverb\Protocols\Pusher\Exceptions\PusherException;
use Ratchet\RFC6455\Messaging\Frame;
use Ratchet\RFC6455\Messaging\FrameInterface;
use Throwable;

class Server
{
Expand Down Expand Up @@ -54,20 +56,21 @@ public function message(Connection $from, string $message): void
try {
$event = json_decode($message, associative: true, flags: JSON_THROW_ON_ERROR);

Validator::make($event, ['event' => ['required', 'string']])->validate();

match (Str::startsWith($event['event'], 'pusher:')) {
true => $this->handler->handle(
$from,
$event['event'],
empty($event['data']) ? [] : $event['data'],
$event['channel'] ?? null
),
default => ClientEvent::handle($from, $event)
};

Log::info('Message Handled', $from->id());

MessageReceived::dispatch($from, $message);
} catch (Exception $e) {
} catch (Throwable $e) {
$this->error($from, $e);
}
}
Expand Down Expand Up @@ -104,7 +107,7 @@ public function close(Connection $connection): void
/**
* Handle an error.
*/
public function error(Connection $connection, Exception $exception): void
public function error(Connection $connection, Throwable $exception): void
{
if ($exception instanceof PusherException) {
$connection->send(json_encode($exception->payload()));
Expand Down
154 changes: 154 additions & 0 deletions tests/Unit/Protocols/Pusher/ServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -329,3 +329,157 @@
['localhost', '*.localhost'],
],
]);

it('sends an error if something fails for event type', function () {
$this->server->message(
$connection = new FakeConnection,
json_encode([
'event' => [],
])
);

$connection->assertReceived([
'event' => 'pusher:error',
'data' => json_encode([
'code' => 4200,
'message' => 'Invalid message format',
]),
]);
});

it('sends an error if something fails for data type', function () {
$this->server->message(
$connection = new FakeConnection,
json_encode([
'event' => 'pusher:subscribe',
'data' => 'sfsfsfs',
])
);

$connection->assertReceived([
'event' => 'pusher:error',
'data' => json_encode([
'code' => 4200,
'message' => 'Invalid message format',
]),
]);
});

it('sends an error if something fails for data channel type', function () {
$this->server->message(
$connection = new FakeConnection,
json_encode([
'event' => 'pusher:subscribe',
'data' => [
'channel' => [],
],
])
);

$connection->assertReceived([
'event' => 'pusher:error',
'data' => json_encode([
'code' => 4200,
'message' => 'Invalid message format',
]),
]);

$this->server->message(
$connection = new FakeConnection,
json_encode([
'event' => 'pusher:subscribe',
'data' => [
'channel' => null,
],
])
);

$connection->assertReceived([
'event' => 'pusher:error',
'data' => json_encode([
'code' => 4200,
'message' => 'Invalid message format',
]),
]);
});

it('sends an error if something fails for data auth type', function () {
$this->server->message(
$connection = new FakeConnection,
json_encode([
'event' => 'pusher:subscribe',
'data' => [
'channel' => 'presence-test-channel',
'auth' => [],
],
])
);

$connection->assertReceived([
'event' => 'pusher:error',
'data' => json_encode([
'code' => 4200,
'message' => 'Invalid message format',
]),
]);
});

it('sends an error if something fails for data channel_data type', function () {
$this->server->message(
$connection = new FakeConnection,
json_encode([
'event' => 'pusher:subscribe',
'data' => [
'channel' => 'presence-test-channel',
'auth' => '',
'channel_data' => [],
],
])
);

$connection->assertReceived([
'event' => 'pusher:error',
'data' => json_encode([
'code' => 4200,
'message' => 'Invalid message format',
]),
]);

$this->server->message(
$connection = new FakeConnection,
json_encode([
'event' => 'pusher:subscribe',
'data' => [
'channel' => 'presence-test-channel',
'auth' => '',
'channel_data' => 'Hello',
],
])
);

$connection->assertReceived([
'event' => 'pusher:error',
'data' => json_encode([
'code' => 4200,
'message' => 'Invalid message format',
]),
]);
});

it('sends an error if something fails for channel type', function () {
$this->server->message(
$connection = new FakeConnection,
json_encode([
'event' => 'client-start-typing',
'channel' => [],
])
);

$connection->assertReceived([
'event' => 'pusher:error',
'data' => json_encode([
'code' => 4200,
'message' => 'Invalid message format',
]),
]);
});
Loading