35 lines
1.8 KiB
PHP
35 lines
1.8 KiB
PHP
<?php
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Support\Facades\Broadcast;
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Broadcast Channels — CONVENTION: every channel is PRIVATE
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Clusev is a control plane for a whole fleet; broadcast payloads (live CPU/MEM,
|
|
| service state, future per-server streams) are infrastructure data and must NEVER
|
|
| ride a PUBLIC channel. A public channel is subscribable by anyone who can reach the
|
|
| Reverb endpoint and knows the app key — and that key is bundled into the JS
|
|
| (VITE_REVERB_APP_KEY), so it is effectively public. With on-demand TLS the `/app/*`
|
|
| Reverb socket also answers on any host Caddy still holds a cert for (e.g. an old
|
|
| domain after a domain change), so a public channel would leak metrics on a host that
|
|
| PanelScheme otherwise refuses.
|
|
|
|
|
| RULE for new channels: declare every event with a PrivateChannel (or PresenceChannel)
|
|
| and register an authorization callback here. The `/broadcasting/auth` endpoint runs in
|
|
| the `web` group, so PanelScheme + the session guard gate it — a subscriber must be an
|
|
| authenticated panel user on the active domain. Per-server channels should additionally
|
|
| scope to records the user may see, e.g.:
|
|
|
|
|
| Broadcast::channel('server.{uuid}', fn (User $u, string $uuid) =>
|
|
| Server::where('uuid', $uuid)->exists()); // tighten when RBAC lands
|
|
|
|
|
*/
|
|
|
|
// Fleet-wide metrics. Only a panel user who has completed security onboarding (rotated the
|
|
// seeded password + enrolled 2FA) may watch — mere authentication is NOT enough; this mirrors
|
|
// the EnsureSecurityOnboarded gate on panel routes (metrics are not per-user).
|
|
Broadcast::channel('metrics', fn (User $user) => $user->securityOnboarded());
|