diff --git a/app/Livewire/LayoutPopups.php b/app/Livewire/LayoutPopups.php index f2ba788938..7d4c5b3414 100644 --- a/app/Livewire/LayoutPopups.php +++ b/app/Livewire/LayoutPopups.php @@ -2,17 +2,18 @@ namespace App\Livewire; +use App\Traits\ListensToTeamChannel; use Livewire\Component; class LayoutPopups extends Component { + use ListensToTeamChannel; + public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - - return [ - "echo-private:team.{$teamId},TestEvent" => 'testEvent', - ]; + return $this->teamChannelListeners([ + 'TestEvent' => 'testEvent', + ]); } public function testEvent() diff --git a/app/Livewire/Project/Application/Deployment/Index.php b/app/Livewire/Project/Application/Deployment/Index.php index e94f37544f..1c8bc27ca3 100644 --- a/app/Livewire/Project/Application/Deployment/Index.php +++ b/app/Livewire/Project/Application/Deployment/Index.php @@ -5,11 +5,14 @@ namespace App\Livewire\Project\Application\Deployment; use App\Enums\ApplicationDeploymentStatus; use App\Models\Application; use App\Models\ApplicationDeploymentQueue; +use App\Traits\ListensToTeamChannel; use Illuminate\Support\Collection; use Livewire\Component; class Index extends Component { + use ListensToTeamChannel; + public Application $application; public ?Collection $deployments; @@ -60,11 +63,9 @@ class Index extends Component public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - - return [ - "echo-private:team.{$teamId},ServiceChecked" => '$refresh', - ]; + return $this->teamChannelListeners([ + 'ServiceChecked' => '$refresh', + ]); } public function mount() diff --git a/app/Livewire/Project/Application/Domains.php b/app/Livewire/Project/Application/Domains.php index 7e9790f5d0..6803e0fd97 100644 --- a/app/Livewire/Project/Application/Domains.php +++ b/app/Livewire/Project/Application/Domains.php @@ -12,6 +12,7 @@ use App\Models\Server; use App\Support\DomainPortOverrides; use App\Support\DomainUrlParts; use App\Support\ValidationPatterns; +use App\Traits\ListensToTeamChannel; use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Collection; @@ -23,6 +24,7 @@ class Domains extends Component use AuthorizesRequests; use InteractsWithCloudflareDomainConnect; use InteractsWithDnsProviders; + use ListensToTeamChannel; protected bool $notifyRedirectUpdate = true; @@ -132,9 +134,7 @@ class Domains extends Component public function getListeners(): array { - return array_merge($this->listeners, [ - 'echo-private:team.'.currentTeam()->id.',DnsRecordConfigurationFinished' => 'dnsRecordConfigurationFinished', - ]); + return array_merge($this->listeners, $this->teamChannelListeners(['DnsRecordConfigurationFinished' => 'dnsRecordConfigurationFinished'])); } protected function rules(): array diff --git a/app/Livewire/Project/Application/Heading.php b/app/Livewire/Project/Application/Heading.php index e52d7c32ec..7c3aac02cd 100644 --- a/app/Livewire/Project/Application/Heading.php +++ b/app/Livewire/Project/Application/Heading.php @@ -6,12 +6,14 @@ use App\Actions\Application\StopApplication; use App\Actions\Docker\GetContainersStatus; use App\Models\Application; use App\Models\ApplicationDeploymentQueue; +use App\Traits\ListensToTeamChannel; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Heading extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public Application $application; @@ -29,13 +31,13 @@ class Heading extends Component public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - return [ - "echo-private:team.{$teamId},ServiceStatusChanged" => 'checkStatus', - "echo-private:team.{$teamId},ServiceChecked" => '$refresh', 'compose_loaded' => '$refresh', 'update_links' => '$refresh', + ...$this->teamChannelListeners([ + 'ServiceStatusChanged' => 'checkStatus', + 'ServiceChecked' => '$refresh', + ]), ]; } diff --git a/app/Livewire/Project/Application/ServerStatusBadge.php b/app/Livewire/Project/Application/ServerStatusBadge.php index 459271e288..a86447d568 100644 --- a/app/Livewire/Project/Application/ServerStatusBadge.php +++ b/app/Livewire/Project/Application/ServerStatusBadge.php @@ -3,30 +3,22 @@ namespace App\Livewire\Project\Application; use App\Models\Application; +use App\Traits\ListensToTeamChannel; use Illuminate\Contracts\View\View; -use Illuminate\Support\Facades\Auth; use Livewire\Component; class ServerStatusBadge extends Component { + use ListensToTeamChannel; + public Application $application; public function getListeners(): array { - $user = Auth::user(); - if (! $user) { - return []; - } - - $team = $user->currentTeam(); - if (! $team) { - return []; - } - - return [ - "echo-private:team.{$team->id},ServiceStatusChanged" => 'refreshStatus', - "echo-private:team.{$team->id},ServiceChecked" => 'refreshStatus', - ]; + return $this->teamChannelListeners([ + 'ServiceStatusChanged' => 'refreshStatus', + 'ServiceChecked' => 'refreshStatus', + ]); } public function refreshStatus(): void diff --git a/app/Livewire/Project/Application/Status.php b/app/Livewire/Project/Application/Status.php index a1393be86f..00f6e65a09 100644 --- a/app/Livewire/Project/Application/Status.php +++ b/app/Livewire/Project/Application/Status.php @@ -3,21 +3,22 @@ namespace App\Livewire\Project\Application; use App\Models\Application; +use App\Traits\ListensToTeamChannel; use Illuminate\Contracts\View\View; use Livewire\Component; class Status extends Component { + use ListensToTeamChannel; + public Application $application; public function getListeners(): array { - $teamId = auth()->user()->currentTeam()->id; - - return [ - "echo-private:team.{$teamId},ServiceStatusChanged" => 'refreshStatus', - "echo-private:team.{$teamId},ServiceChecked" => 'refreshStatus', - ]; + return $this->teamChannelListeners([ + 'ServiceStatusChanged' => 'refreshStatus', + 'ServiceChecked' => 'refreshStatus', + ]); } public function refreshStatus(): void diff --git a/app/Livewire/Project/Database/BackupEdit.php b/app/Livewire/Project/Database/BackupEdit.php index 04e86e261e..279a475f4e 100644 --- a/app/Livewire/Project/Database/BackupEdit.php +++ b/app/Livewire/Project/Database/BackupEdit.php @@ -6,6 +6,7 @@ use App\Jobs\DatabaseBackupJob; use App\Models\S3Storage; use App\Models\ScheduledDatabaseBackup; use App\Models\ServiceDatabase; +use App\Traits\ListensToTeamChannel; use Exception; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Collection; @@ -17,6 +18,7 @@ use Livewire\Component; class BackupEdit extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public ScheduledDatabaseBackup $backup; @@ -100,12 +102,10 @@ class BackupEdit extends Component $listeners["echo-private:user.{$user->id},DatabaseStatusChanged"] = 'refreshStatus'; - $team = $user->currentTeam(); - if ($team) { - $listeners["echo-private:team.{$team->id},ServiceChecked"] = 'refreshStatus'; - } - - return $listeners; + return [ + ...$listeners, + ...$this->teamChannelListeners(['ServiceChecked' => 'refreshStatus']), + ]; } public function mount() diff --git a/app/Livewire/Project/Database/BackupExecutions.php b/app/Livewire/Project/Database/BackupExecutions.php index 2786a45c3d..6f17e2fcf5 100644 --- a/app/Livewire/Project/Database/BackupExecutions.php +++ b/app/Livewire/Project/Database/BackupExecutions.php @@ -4,6 +4,7 @@ namespace App\Livewire\Project\Database; use App\Models\ScheduledDatabaseBackup; use App\Models\ServiceDatabase; +use App\Traits\ListensToTeamChannel; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Collection; use Livewire\Component; @@ -11,6 +12,7 @@ use Livewire\Component; class BackupExecutions extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public ?ScheduledDatabaseBackup $backup = null; @@ -38,11 +40,9 @@ class BackupExecutions extends Component public function getListeners(): array { - $teamId = currentTeam()->id; - - return [ - "echo-private:team.{$teamId},BackupCreated" => 'refreshBackupExecutions', - ]; + return $this->teamChannelListeners([ + 'BackupCreated' => 'refreshBackupExecutions', + ]); } public function cleanupFailed() diff --git a/app/Livewire/Project/Database/Clickhouse/General.php b/app/Livewire/Project/Database/Clickhouse/General.php index 2f87edcb2b..d61a19f2c7 100644 --- a/app/Livewire/Project/Database/Clickhouse/General.php +++ b/app/Livewire/Project/Database/Clickhouse/General.php @@ -7,14 +7,15 @@ use App\Actions\Database\StopDatabaseProxy; use App\Models\Server; use App\Models\StandaloneClickhouse; use App\Support\ValidationPatterns; +use App\Traits\ListensToTeamChannel; use Exception; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; -use Illuminate\Support\Facades\Auth; use Livewire\Component; class General extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public ?Server $server = null; @@ -46,18 +47,9 @@ class General extends Component public function getListeners(): array { - $user = Auth::user(); - if (! $user) { - return []; - } - $team = $user->currentTeam(); - if (! $team) { - return []; - } - - return [ - "echo-private:team.{$team->id},DatabaseProxyStopped" => 'databaseProxyStopped', - ]; + return $this->teamChannelListeners([ + 'DatabaseProxyStopped' => 'databaseProxyStopped', + ]); } public function mount() diff --git a/app/Livewire/Project/Database/Dragonfly/General.php b/app/Livewire/Project/Database/Dragonfly/General.php index 556925727d..1505aad781 100644 --- a/app/Livewire/Project/Database/Dragonfly/General.php +++ b/app/Livewire/Project/Database/Dragonfly/General.php @@ -7,14 +7,15 @@ use App\Actions\Database\StopDatabaseProxy; use App\Models\Server; use App\Models\StandaloneDragonfly; use App\Support\ValidationPatterns; +use App\Traits\ListensToTeamChannel; use Exception; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; -use Illuminate\Support\Facades\Auth; use Livewire\Component; class General extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public ?Server $server = null; @@ -44,18 +45,9 @@ class General extends Component public function getListeners(): array { - $user = Auth::user(); - if (! $user) { - return []; - } - $team = $user->currentTeam(); - if (! $team) { - return []; - } - - return [ - "echo-private:team.{$team->id},DatabaseProxyStopped" => 'databaseProxyStopped', - ]; + return $this->teamChannelListeners([ + 'DatabaseProxyStopped' => 'databaseProxyStopped', + ]); } public function mount() diff --git a/app/Livewire/Project/Database/Heading.php b/app/Livewire/Project/Database/Heading.php index 030da438ac..a7e8cfedd8 100644 --- a/app/Livewire/Project/Database/Heading.php +++ b/app/Livewire/Project/Database/Heading.php @@ -8,12 +8,14 @@ use App\Actions\Database\StopDatabase; use App\Actions\Docker\GetContainersStatus; use App\Events\ServiceStatusChanged; use App\Support\ResourceStartActivity; +use App\Traits\ListensToTeamChannel; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Heading extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public $database; @@ -27,14 +29,14 @@ class Heading extends Component public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - return [ - "echo-private:team.{$teamId},ServiceStatusChanged" => 'checkStatus', - "echo-private:team.{$teamId},ServiceChecked" => 'activityFinished', 'refresh' => '$refresh', 'compose_loaded' => '$refresh', 'update_links' => '$refresh', + ...$this->teamChannelListeners([ + 'ServiceStatusChanged' => 'checkStatus', + 'ServiceChecked' => 'activityFinished', + ]), ]; } diff --git a/app/Livewire/Project/Database/Import.php b/app/Livewire/Project/Database/Import.php index ea04658cfd..6d6bf94867 100644 --- a/app/Livewire/Project/Database/Import.php +++ b/app/Livewire/Project/Database/Import.php @@ -7,6 +7,7 @@ use App\Models\StandaloneClickhouse; use App\Models\StandaloneDragonfly; use App\Models\StandaloneKeydb; use App\Models\StandaloneRedis; +use App\Traits\ListensToTeamChannel; use Illuminate\Contracts\View\View; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; @@ -16,6 +17,7 @@ use Livewire\Component; class Import extends Component { use AuthorizesRequests; + use ListensToTeamChannel; #[Locked] public ?int $resourceId = null; @@ -40,12 +42,10 @@ class Import extends Component $listeners["echo-private:user.{$user->id},DatabaseStatusChanged"] = 'refreshStatus'; - $team = $user->currentTeam(); - if ($team) { - $listeners["echo-private:team.{$team->id},ServiceChecked"] = 'refreshStatus'; - } - - return $listeners; + return [ + ...$listeners, + ...$this->teamChannelListeners(['ServiceChecked' => 'refreshStatus']), + ]; } public function mount(): void diff --git a/app/Livewire/Project/Database/Keydb/General.php b/app/Livewire/Project/Database/Keydb/General.php index c32a814a1a..2ae64f3121 100644 --- a/app/Livewire/Project/Database/Keydb/General.php +++ b/app/Livewire/Project/Database/Keydb/General.php @@ -7,14 +7,15 @@ use App\Actions\Database\StopDatabaseProxy; use App\Models\Server; use App\Models\StandaloneKeydb; use App\Support\ValidationPatterns; +use App\Traits\ListensToTeamChannel; use Exception; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; -use Illuminate\Support\Facades\Auth; use Livewire\Component; class General extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public ?Server $server = null; @@ -46,18 +47,9 @@ class General extends Component public function getListeners(): array { - $user = Auth::user(); - if (! $user) { - return []; - } - $team = $user->currentTeam(); - if (! $team) { - return []; - } - - return [ - "echo-private:team.{$team->id},DatabaseProxyStopped" => 'databaseProxyStopped', - ]; + return $this->teamChannelListeners([ + 'DatabaseProxyStopped' => 'databaseProxyStopped', + ]); } public function mount() diff --git a/app/Livewire/Project/Database/Status.php b/app/Livewire/Project/Database/Status.php index eb40cf817e..8ac20ff16f 100644 --- a/app/Livewire/Project/Database/Status.php +++ b/app/Livewire/Project/Database/Status.php @@ -2,21 +2,22 @@ namespace App\Livewire\Project\Database; +use App\Traits\ListensToTeamChannel; use Illuminate\Contracts\View\View; use Livewire\Component; class Status extends Component { + use ListensToTeamChannel; + public $database; public function getListeners(): array { - $teamId = auth()->user()->currentTeam()->id; - - return [ - "echo-private:team.{$teamId},ServiceStatusChanged" => 'refreshStatus', - "echo-private:team.{$teamId},ServiceChecked" => 'refreshStatus', - ]; + return $this->teamChannelListeners([ + 'ServiceStatusChanged' => 'refreshStatus', + 'ServiceChecked' => 'refreshStatus', + ]); } public function refreshStatus(): void diff --git a/app/Livewire/Project/Service/BackupExecutions.php b/app/Livewire/Project/Service/BackupExecutions.php index 6d7fb97f68..2f21e60383 100644 --- a/app/Livewire/Project/Service/BackupExecutions.php +++ b/app/Livewire/Project/Service/BackupExecutions.php @@ -8,6 +8,7 @@ use App\Models\ScheduledVolumeBackup; use App\Models\ScheduledVolumeBackupExecution; use App\Models\Service; use App\Models\ServiceDatabase; +use App\Traits\ListensToTeamChannel; use Illuminate\Contracts\View\View; use Illuminate\Database\Query\Builder; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; @@ -18,6 +19,7 @@ use Livewire\WithPagination; class BackupExecutions extends Component { use AuthorizesRequests; + use ListensToTeamChannel; use WithPagination; public Service $service; @@ -30,11 +32,11 @@ class BackupExecutions extends Component public function getListeners(): array { - $teamId = currentTeam()->id; - return [ 'modalClosed' => 'closeExecutionModal', - "echo-private:team.{$teamId},BackupCreated" => '$refresh', + ...$this->teamChannelListeners([ + 'BackupCreated' => '$refresh', + ]), ]; } diff --git a/app/Livewire/Project/Service/Configuration.php b/app/Livewire/Project/Service/Configuration.php index f3ec3ba4df..51f3b69999 100644 --- a/app/Livewire/Project/Service/Configuration.php +++ b/app/Livewire/Project/Service/Configuration.php @@ -3,12 +3,14 @@ namespace App\Livewire\Project\Service; use App\Models\Service; +use App\Traits\ListensToTeamChannel; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Configuration extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public $currentRoute; @@ -28,13 +30,13 @@ class Configuration extends Component public function getListeners(): array { - $teamId = auth()->user()->currentTeam()->id; - return [ 'refreshServices' => 'refreshServices', 'refresh' => 'refreshServices', 'configurationChanged' => 'refreshServices', - "echo-private:team.{$teamId},ApplicationConfigurationChanged" => 'refreshServices', + ...$this->teamChannelListeners([ + 'ApplicationConfigurationChanged' => 'refreshServices', + ]), ]; } diff --git a/app/Livewire/Project/Service/Domains.php b/app/Livewire/Project/Service/Domains.php index 1a6dc91c7a..d51e5c6642 100644 --- a/app/Livewire/Project/Service/Domains.php +++ b/app/Livewire/Project/Service/Domains.php @@ -13,6 +13,7 @@ use App\Models\ServiceApplication; use App\Support\DomainPortOverrides; use App\Support\DomainUrlParts; use App\Support\ValidationPatterns; +use App\Traits\ListensToTeamChannel; use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Collection; @@ -24,6 +25,7 @@ class Domains extends Component use AuthorizesRequests; use InteractsWithCloudflareDomainConnect; use InteractsWithDnsProviders; + use ListensToTeamChannel; protected bool $notifyRedirectUpdate = true; @@ -123,9 +125,7 @@ class Domains extends Component public function getListeners(): array { - return array_merge($this->listeners, [ - 'echo-private:team.'.currentTeam()->id.',DnsRecordConfigurationFinished' => 'dnsRecordConfigurationFinished', - ]); + return array_merge($this->listeners, $this->teamChannelListeners(['DnsRecordConfigurationFinished' => 'dnsRecordConfigurationFinished'])); } protected function rules(): array diff --git a/app/Livewire/Project/Service/Heading.php b/app/Livewire/Project/Service/Heading.php index fc6720b218..e8d5375038 100644 --- a/app/Livewire/Project/Service/Heading.php +++ b/app/Livewire/Project/Service/Heading.php @@ -11,14 +11,15 @@ use App\Models\Service; use App\Models\ServiceApplication; use App\Models\ServiceDatabase; use App\Support\ResourceStartActivity; +use App\Traits\ListensToTeamChannel; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; -use Illuminate\Support\Facades\Auth; use Livewire\Component; use Spatie\Activitylog\Models\Activity; class Heading extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public Service $service; @@ -48,13 +49,13 @@ class Heading extends Component public function getListeners() { - $teamId = Auth::user()->currentTeam()->id; - return [ - "echo-private:team.{$teamId},ServiceStatusChanged" => 'checkStatus', - "echo-private:team.{$teamId},ServiceChecked" => 'serviceChecked', 'refresh' => '$refresh', 'envsUpdated' => '$refresh', + ...$this->teamChannelListeners([ + 'ServiceStatusChanged' => 'checkStatus', + 'ServiceChecked' => 'serviceChecked', + ]), ]; } diff --git a/app/Livewire/Project/Service/ResourceCard.php b/app/Livewire/Project/Service/ResourceCard.php index fd27f60c30..22ed772a80 100644 --- a/app/Livewire/Project/Service/ResourceCard.php +++ b/app/Livewire/Project/Service/ResourceCard.php @@ -5,14 +5,15 @@ namespace App\Livewire\Project\Service; use App\Models\Service; use App\Models\ServiceApplication; use App\Models\ServiceDatabase; +use App\Traits\ListensToTeamChannel; use Illuminate\Contracts\View\View; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; -use Illuminate\Support\Facades\Auth; use Livewire\Component; class ResourceCard extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public Service $service; @@ -22,19 +23,9 @@ class ResourceCard extends Component public function getListeners(): array { - $user = Auth::user(); - if (! $user) { - return []; - } - - $team = $user->currentTeam(); - if (! $team) { - return []; - } - - return [ - "echo-private:team.{$team->id},ServiceChecked" => 'refreshResource', - ]; + return $this->teamChannelListeners([ + 'ServiceChecked' => 'refreshResource', + ]); } public function refreshResource(): void diff --git a/app/Livewire/Project/Service/Status.php b/app/Livewire/Project/Service/Status.php index 27919f1ae7..e807e22171 100644 --- a/app/Livewire/Project/Service/Status.php +++ b/app/Livewire/Project/Service/Status.php @@ -3,11 +3,14 @@ namespace App\Livewire\Project\Service; use App\Models\Service; +use App\Traits\ListensToTeamChannel; use Illuminate\Contracts\View\View; use Livewire\Component; class Status extends Component { + use ListensToTeamChannel; + public Service $service; public ?string $selectedResourceUuid = null; @@ -19,12 +22,10 @@ class Status extends Component public function getListeners(): array { - $teamId = auth()->user()->currentTeam()->id; - - return [ - "echo-private:team.{$teamId},ServiceStatusChanged" => 'refreshStatus', - "echo-private:team.{$teamId},ServiceChecked" => 'refreshStatus', - ]; + return $this->teamChannelListeners([ + 'ServiceStatusChanged' => 'refreshStatus', + 'ServiceChecked' => 'refreshStatus', + ]); } public function refreshStatus(): void diff --git a/app/Livewire/Project/Service/Storage.php b/app/Livewire/Project/Service/Storage.php index 6bb1d3a588..0827a59994 100644 --- a/app/Livewire/Project/Service/Storage.php +++ b/app/Livewire/Project/Service/Storage.php @@ -9,6 +9,7 @@ use App\Models\LocalPersistentVolume; use App\Models\ServiceApplication; use App\Models\ServiceDatabase; use App\Support\ValidationPatterns; +use App\Traits\ListensToTeamChannel; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Gate; use Illuminate\Support\Str; @@ -18,6 +19,7 @@ use Livewire\Component; class Storage extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public $resource; @@ -60,12 +62,12 @@ class Storage extends Component public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - return [ - "echo-private:team.{$teamId},FileStorageChanged" => 'refreshStoragesFromEvent', 'storageCountsChanged' => 'refreshStorages', 'addNewVolume', + ...$this->teamChannelListeners([ + 'FileStorageChanged' => 'refreshStoragesFromEvent', + ]), ]; } diff --git a/app/Livewire/Project/Service/VolumeBackup/Index.php b/app/Livewire/Project/Service/VolumeBackup/Index.php index 600b8b9047..77ee2b9d1c 100644 --- a/app/Livewire/Project/Service/VolumeBackup/Index.php +++ b/app/Livewire/Project/Service/VolumeBackup/Index.php @@ -8,6 +8,7 @@ use App\Models\ScheduledDatabaseBackup; use App\Models\ScheduledVolumeBackup; use App\Models\Service; use App\Models\ServiceDatabase; +use App\Traits\ListensToTeamChannel; use Illuminate\Contracts\View\View; use Illuminate\Database\Eloquent\Collection; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; @@ -17,6 +18,7 @@ use Livewire\Component; class Index extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public Service $service; @@ -37,13 +39,13 @@ class Index extends Component public function getListeners(): array { - $teamId = currentTeam()->id; - return [ 'refreshVolumeBackups' => '$refresh', 'modalClosed' => 'closeScheduleModal', - "echo-private:team.{$teamId},ServiceChecked" => '$refresh', - "echo-private:team.{$teamId},BackupCreated" => '$refresh', + ...$this->teamChannelListeners([ + 'ServiceChecked' => '$refresh', + 'BackupCreated' => '$refresh', + ]), ]; } diff --git a/app/Livewire/Project/Shared/ConfigurationChecker.php b/app/Livewire/Project/Shared/ConfigurationChecker.php index 1a6015042c..14ce65f95f 100644 --- a/app/Livewire/Project/Shared/ConfigurationChecker.php +++ b/app/Livewire/Project/Shared/ConfigurationChecker.php @@ -13,11 +13,14 @@ use App\Models\StandaloneMysql; use App\Models\StandalonePostgresql; use App\Models\StandaloneRedis; use App\Models\StandaloneSqlite; +use App\Traits\ListensToTeamChannel; use Illuminate\Contracts\View\View; use Livewire\Component; class ConfigurationChecker extends Component { + use ListensToTeamChannel; + public bool $isConfigurationChanged = false; public array $configurationDiff = []; @@ -30,12 +33,12 @@ class ConfigurationChecker extends Component public function getListeners(): array { - $teamId = auth()->user()->currentTeam()->id; - return [ - "echo-private:team.{$teamId},ApplicationConfigurationChanged" => 'configurationChanged', 'configurationChanged' => 'configurationChanged', 'envsUpdated' => 'configurationChanged', + ...$this->teamChannelListeners([ + 'ApplicationConfigurationChanged' => 'configurationChanged', + ]), ]; } diff --git a/app/Livewire/Project/Shared/Destination.php b/app/Livewire/Project/Shared/Destination.php index 1bb46b2aa8..55d3f64e84 100644 --- a/app/Livewire/Project/Shared/Destination.php +++ b/app/Livewire/Project/Shared/Destination.php @@ -9,6 +9,7 @@ use App\Models\Application; use App\Models\Server; use App\Models\StandaloneDocker; use App\Services\ScheduleNextRunRecalculator; +use App\Traits\ListensToTeamChannel; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Collection; use Livewire\Component; @@ -16,6 +17,7 @@ use Livewire\Component; class Destination extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public $resource; @@ -23,12 +25,12 @@ class Destination extends Component public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - return [ - "echo-private:team.{$teamId},ApplicationStatusChanged" => 'loadData', - "echo-private:team.{$teamId},ServiceStatusChanged" => 'mount', 'refresh' => 'mount', + ...$this->teamChannelListeners([ + 'ApplicationStatusChanged' => 'loadData', + 'ServiceStatusChanged' => 'mount', + ]), ]; } diff --git a/app/Livewire/Project/Shared/Logs.php b/app/Livewire/Project/Shared/Logs.php index f5e4f0c33a..609d2efa3b 100644 --- a/app/Livewire/Project/Shared/Logs.php +++ b/app/Livewire/Project/Shared/Logs.php @@ -13,11 +13,14 @@ use App\Models\StandaloneMysql; use App\Models\StandalonePostgresql; use App\Models\StandaloneRedis; use App\Models\StandaloneSqlite; +use App\Traits\ListensToTeamChannel; use Illuminate\Support\Collection; use Livewire\Component; class Logs extends Component { + use ListensToTeamChannel; + public ?string $type = null; public Application|Service|StandalonePostgresql|StandaloneRedis|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse|StandaloneSqlite $resource; @@ -47,11 +50,9 @@ class Logs extends Component public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - - return [ - "echo-private:team.{$teamId},ServiceChecked" => 'loadAllContainers', - ]; + return $this->teamChannelListeners([ + 'ServiceChecked' => 'loadAllContainers', + ]); } public function loadAllContainers() diff --git a/app/Livewire/Project/Shared/ScheduledTask/Executions.php b/app/Livewire/Project/Shared/ScheduledTask/Executions.php index cf426e0ca8..76e0735ff4 100644 --- a/app/Livewire/Project/Shared/ScheduledTask/Executions.php +++ b/app/Livewire/Project/Shared/ScheduledTask/Executions.php @@ -3,6 +3,7 @@ namespace App\Livewire\Project\Shared\ScheduledTask; use App\Models\ScheduledTask; +use App\Traits\ListensToTeamChannel; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Auth; use Livewire\Attributes\Locked; @@ -10,6 +11,8 @@ use Livewire\Component; class Executions extends Component { + use ListensToTeamChannel; + #[Locked] public ScheduledTask $task; @@ -36,11 +39,9 @@ class Executions extends Component public function getListeners() { - $teamId = Auth::user()->currentTeam()->id; - - return [ - "echo-private:team.{$teamId},ScheduledTaskDone" => 'refreshExecutions', - ]; + return $this->teamChannelListeners([ + 'ScheduledTaskDone' => 'refreshExecutions', + ]); } public function mount($taskId) diff --git a/app/Livewire/Server/CloudflareTunnel.php b/app/Livewire/Server/CloudflareTunnel.php index 2ab8298543..df3ad5c197 100644 --- a/app/Livewire/Server/CloudflareTunnel.php +++ b/app/Livewire/Server/CloudflareTunnel.php @@ -4,6 +4,7 @@ namespace App\Livewire\Server; use App\Actions\Server\ConfigureCloudflared; use App\Models\Server; +use App\Traits\ListensToTeamChannel; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Validate; use Livewire\Component; @@ -11,6 +12,7 @@ use Livewire\Component; class CloudflareTunnel extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public Server $server; @@ -25,11 +27,9 @@ class CloudflareTunnel extends Component public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - - return [ - "echo-private:team.{$teamId},CloudflareTunnelConfigured" => 'refresh', - ]; + return $this->teamChannelListeners([ + 'CloudflareTunnelConfigured' => 'refresh', + ]); } public function refresh() diff --git a/app/Livewire/Server/DockerCleanupExecutions.php b/app/Livewire/Server/DockerCleanupExecutions.php index 6a739bc84c..6cb76fc9f3 100644 --- a/app/Livewire/Server/DockerCleanupExecutions.php +++ b/app/Livewire/Server/DockerCleanupExecutions.php @@ -3,11 +3,14 @@ namespace App\Livewire\Server; use App\Models\Server; +use App\Traits\ListensToTeamChannel; use Illuminate\Support\Collection; use Livewire\Component; class DockerCleanupExecutions extends Component { + use ListensToTeamChannel; + public Server $server; public Collection $executions; @@ -24,11 +27,9 @@ class DockerCleanupExecutions extends Component public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - - return [ - "echo-private:team.{$teamId},DockerCleanupDone" => 'refreshExecutions', - ]; + return $this->teamChannelListeners([ + 'DockerCleanupDone' => 'refreshExecutions', + ]); } public function mount(Server $server) diff --git a/app/Livewire/Server/Navbar.php b/app/Livewire/Server/Navbar.php index 545494db51..1a64d0a15e 100644 --- a/app/Livewire/Server/Navbar.php +++ b/app/Livewire/Server/Navbar.php @@ -9,6 +9,7 @@ use App\Enums\ProxyTypes; use App\Jobs\RestartProxyJob; use App\Models\Server; use App\Services\ProxyDashboardCacheService; +use App\Traits\ListensToTeamChannel; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Carbon; use Livewire\Component; @@ -16,6 +17,7 @@ use Livewire\Component; class Navbar extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public Server $server; @@ -39,14 +41,14 @@ class Navbar extends Component public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - return [ 'refreshServerShow' => 'refreshServer', 'sentinel-restart-requested' => 'hideSentinelWarning', - "echo-private:team.{$teamId},ProxyStatusChangedUI" => 'showNotification', - "echo-private:team.{$teamId},SentinelRestarted" => 'refreshSentinelStatus', - "echo-private:team.{$teamId},SentinelSynchronized" => 'refreshSentinelStatus', + ...$this->teamChannelListeners([ + 'ProxyStatusChangedUI' => 'showNotification', + 'SentinelRestarted' => 'refreshSentinelStatus', + 'SentinelSynchronized' => 'refreshSentinelStatus', + ]), ]; } diff --git a/app/Livewire/Server/Proxy.php b/app/Livewire/Server/Proxy.php index cc46364272..f5da7146af 100644 --- a/app/Livewire/Server/Proxy.php +++ b/app/Livewire/Server/Proxy.php @@ -9,12 +9,14 @@ use App\Actions\Proxy\SaveProxyConfiguration; use App\Enums\ProxyTypes; use App\Models\Server; use App\Rules\SafeExternalUrl; +use App\Traits\ListensToTeamChannel; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Proxy extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public Server $server; @@ -40,11 +42,11 @@ class Proxy extends Component public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - return [ 'saveConfiguration' => 'submit', - "echo-private:team.{$teamId},ProxyStatusChangedUI" => '$refresh', + ...$this->teamChannelListeners([ + 'ProxyStatusChangedUI' => '$refresh', + ]), ]; } diff --git a/app/Livewire/Server/Proxy/DynamicConfigurations.php b/app/Livewire/Server/Proxy/DynamicConfigurations.php index 6351dace86..a090872d66 100644 --- a/app/Livewire/Server/Proxy/DynamicConfigurations.php +++ b/app/Livewire/Server/Proxy/DynamicConfigurations.php @@ -3,6 +3,7 @@ namespace App\Livewire\Server\Proxy; use App\Models\Server; +use App\Traits\ListensToTeamChannel; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Collection; use Livewire\Component; @@ -10,6 +11,7 @@ use Livewire\Component; class DynamicConfigurations extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public const MAX_CONFIGURATION_FILE_SIZE_BYTES = 1024 * 1024; @@ -25,11 +27,11 @@ class DynamicConfigurations extends Component public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - return [ - "echo-private:team.{$teamId},ProxyStatusChangedUI" => 'loadDynamicConfigurations', 'loadDynamicConfigurations', + ...$this->teamChannelListeners([ + 'ProxyStatusChangedUI' => 'loadDynamicConfigurations', + ]), ]; } diff --git a/app/Livewire/Server/Resources.php b/app/Livewire/Server/Resources.php index 5d0d2538bd..dd62a9e776 100644 --- a/app/Livewire/Server/Resources.php +++ b/app/Livewire/Server/Resources.php @@ -4,6 +4,7 @@ namespace App\Livewire\Server; use App\Models\Server; use App\Support\ValidationPatterns; +use App\Traits\ListensToTeamChannel; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Pagination\LengthAwarePaginator; use Livewire\Component; @@ -12,6 +13,7 @@ use Livewire\WithPagination; class Resources extends Component { use AuthorizesRequests; + use ListensToTeamChannel; use WithPagination; public int $perPage = 10; @@ -39,11 +41,9 @@ class Resources extends Component public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - - return [ - "echo-private:team.{$teamId},ApplicationStatusChanged" => 'refreshStatus', - ]; + return $this->teamChannelListeners([ + 'ApplicationStatusChanged' => 'refreshStatus', + ]); } public function startUnmanaged($id) diff --git a/app/Livewire/Server/Security/Patches.php b/app/Livewire/Server/Security/Patches.php index 087836da3b..4dd97519aa 100644 --- a/app/Livewire/Server/Security/Patches.php +++ b/app/Livewire/Server/Security/Patches.php @@ -7,12 +7,14 @@ use App\Actions\Server\UpdatePackage; use App\Events\ServerPackageUpdated; use App\Models\Server; use App\Notifications\Server\ServerPatchCheck; +use App\Traits\ListensToTeamChannel; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Patches extends Component { use AuthorizesRequests; + use ListensToTeamChannel; public array $parameters; @@ -30,11 +32,9 @@ class Patches extends Component public function getListeners() { - $teamId = auth()->user()->currentTeam()->id; - - return [ - "echo-private:team.{$teamId},ServerPackageUpdated" => 'checkForUpdatesDispatch', - ]; + return $this->teamChannelListeners([ + 'ServerPackageUpdated' => 'checkForUpdatesDispatch', + ]); } public function mount() diff --git a/app/Traits/HasDatabaseStatusInfo.php b/app/Traits/HasDatabaseStatusInfo.php index 4b84748fd4..de9374a87f 100644 --- a/app/Traits/HasDatabaseStatusInfo.php +++ b/app/Traits/HasDatabaseStatusInfo.php @@ -20,6 +20,8 @@ use Illuminate\Support\Facades\Auth; */ trait HasDatabaseStatusInfo { + use ListensToTeamChannel; + public ?string $dbUrl = null; public ?string $dbUrlPublic = null; @@ -65,12 +67,10 @@ trait HasDatabaseStatusInfo $listeners["echo-private:user.{$user->id},DatabaseStatusChanged"] = 'refresh'; - $team = $user->currentTeam(); - if ($team) { - $listeners["echo-private:team.{$team->id},ServiceChecked"] = 'refresh'; - } - - return $listeners; + return [ + ...$listeners, + ...$this->teamChannelListeners(['ServiceChecked' => 'refresh']), + ]; } public function mount(): void diff --git a/app/Traits/ListensToTeamChannel.php b/app/Traits/ListensToTeamChannel.php new file mode 100644 index 0000000000..03242989b6 --- /dev/null +++ b/app/Traits/ListensToTeamChannel.php @@ -0,0 +1,53 @@ +teamChannelId = currentTeam()?->id; + } + + public function ignoreStaleTeamChannelEvent(): void + { + $this->skipRender(); + } + + /** + * @param array $handlers broadcast event name => handler method + * @return array + */ + protected function teamChannelListeners(array $handlers): array + { + $currentTeamId = currentTeam()?->id; + $teamId = $this->teamChannelId ?? $currentTeamId; + + if ($teamId === null) { + return []; + } + + $isStale = $teamId !== $currentTeamId; + + $listeners = []; + foreach ($handlers as $event => $handler) { + $listeners["echo-private:team.{$teamId},{$event}"] = $isStale ? 'ignoreStaleTeamChannelEvent' : $handler; + } + + return $listeners; + } +} diff --git a/tests/Feature/Livewire/TeamChannelListenersTest.php b/tests/Feature/Livewire/TeamChannelListenersTest.php new file mode 100644 index 0000000000..78127815b0 --- /dev/null +++ b/tests/Feature/Livewire/TeamChannelListenersTest.php @@ -0,0 +1,71 @@ + 0]); + $this->team = Team::factory()->create(); + $this->otherTeam = Team::factory()->create(); + $this->user = User::factory()->create(); + $this->team->members()->attach($this->user->id, ['role' => 'owner']); + $this->otherTeam->members()->attach($this->user->id, ['role' => 'owner']); + $this->actingAs($this->user); + session(['currentTeam' => $this->team]); +}); + +it('keeps team broadcast listeners of the mounted team after the session team changes', function () { + $project = Project::factory()->create(['team_id' => $this->team->id]); + $environment = Environment::factory()->create(['project_id' => $project->id]); + $application = Application::factory()->create(['environment_id' => $environment->id]); + + $component = Livewire::test(ServerStatusBadge::class, ['application' => $application]); + + // A team switch in another browser tab changes the shared session. + session(['currentTeam' => $this->otherTeam]); + + $component + ->dispatch("echo-private:team.{$this->team->id},ServiceChecked", ['teamId' => $this->team->id]) + ->assertOk(); +}); + +it('runs team broadcast handlers while the session team matches the mounted team', function () { + Livewire::test(LayoutPopups::class) + ->dispatch("echo-private:team.{$this->team->id},TestEvent") + ->assertDispatched('success'); +}); + +it('ignores team broadcasts of the mounted team after the session team changes', function () { + $component = Livewire::test(LayoutPopups::class); + + session(['currentTeam' => $this->otherTeam]); + + expect($component->instance()->getListeners()) + ->toBe(["echo-private:team.{$this->team->id},TestEvent" => 'ignoreStaleTeamChannelEvent']); + + $component + ->dispatch("echo-private:team.{$this->team->id},TestEvent") + ->assertOk() + ->assertNotDispatched('success'); +}); + +it('registers no team broadcast listeners without a current team', function () { + $project = Project::factory()->create(['team_id' => $this->team->id]); + $environment = Environment::factory()->create(['project_id' => $project->id]); + $application = Application::factory()->create(['environment_id' => $environment->id]); + session()->forget('currentTeam'); + + $component = Livewire::test(ServerStatusBadge::class, ['application' => $application]); + + expect($component->instance()->getListeners())->toBe([]); +}); diff --git a/tests/Feature/ServiceDatabaseVerticalNavigationTest.php b/tests/Feature/ServiceDatabaseVerticalNavigationTest.php index 00bf6a49ac..2c18dcf2ad 100644 --- a/tests/Feature/ServiceDatabaseVerticalNavigationTest.php +++ b/tests/Feature/ServiceDatabaseVerticalNavigationTest.php @@ -7,12 +7,13 @@ it('refreshes backup executions from backup broadcasts on the current team chann $databaseBackupJob = file_get_contents(app_path('Jobs/DatabaseBackupJob.php')); expect($serviceExecutions) - ->toContain('echo-private:team.{$teamId},BackupCreated') - ->toContain("=> '\$refresh'") + ->toContain('teamChannelListeners([') + ->toContain("'BackupCreated' => '\$refresh'") ->and($serviceBackups) - ->toContain('echo-private:team.{$teamId},BackupCreated') + ->toContain('teamChannelListeners([') + ->toContain("'BackupCreated' => '\$refresh'") ->and($databaseExecutions) - ->toContain('$teamId = currentTeam()->id') + ->toContain("'BackupCreated' => 'refreshBackupExecutions'") ->not->toContain('$userId = Auth::id()') ->and(strpos($databaseBackupJob, "'finished_at' => Carbon::now()->toImmutable()")) ->toBeLessThan(strrpos($databaseBackupJob, 'BackupCreated::dispatch($this->team->id)'));