diff --git a/app/Livewire/Admin/Index.php b/app/Livewire/Admin/Index.php
index b5f6d2929..c68bba3e8 100644
--- a/app/Livewire/Admin/Index.php
+++ b/app/Livewire/Admin/Index.php
@@ -45,6 +45,9 @@ public function back()
public function submitSearch()
{
+ if (Auth::id() !== 0 && ! session('impersonating')) {
+ return redirect()->route('dashboard');
+ }
if ($this->search !== '') {
$this->foundUsers = User::where(function ($query) {
$query->where('name', 'like', "%{$this->search}%")
@@ -55,6 +58,9 @@ public function submitSearch()
public function getSubscribers()
{
+ if (Auth::id() !== 0 && ! session('impersonating')) {
+ return redirect()->route('dashboard');
+ }
$this->inactiveSubscribers = Team::whereRelation('subscription', 'stripe_invoice_paid', false)->count();
$this->activeSubscribers = Team::whereRelation('subscription', 'stripe_invoice_paid', true)->count();
}
diff --git a/app/Livewire/Project/Application/DeploymentNavbar.php b/app/Livewire/Project/Application/DeploymentNavbar.php
index f71b7f753..fcd0d4cf4 100644
--- a/app/Livewire/Project/Application/DeploymentNavbar.php
+++ b/app/Livewire/Project/Application/DeploymentNavbar.php
@@ -52,6 +52,7 @@ public function show_debug()
public function force_start()
{
try {
+ $this->authorize('deploy', $this->application);
force_start_deployment($this->application_deployment_queue);
} catch (\Throwable $e) {
return handleError($e, $this);
@@ -82,6 +83,11 @@ public function copyLogsToClipboard(): string
public function cancel()
{
+ try {
+ $this->authorize('deploy', $this->application);
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ }
$deployment_uuid = $this->application_deployment_queue->deployment_uuid;
$kill_command = "docker rm -f {$deployment_uuid}";
$build_server_id = $this->application_deployment_queue->build_server_id ?? $this->application->destination->server_id;
diff --git a/app/Livewire/Project/Application/Swarm.php b/app/Livewire/Project/Application/Swarm.php
index 197dc41ed..94d627e67 100644
--- a/app/Livewire/Project/Application/Swarm.php
+++ b/app/Livewire/Project/Application/Swarm.php
@@ -3,11 +3,14 @@
namespace App\Livewire\Project\Application;
use App\Models\Application;
+use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Attributes\Validate;
use Livewire\Component;
class Swarm extends Component
{
+ use AuthorizesRequests;
+
public Application $application;
#[Validate('required')]
@@ -51,6 +54,7 @@ public function syncData(bool $toModel = false)
public function instantSave()
{
try {
+ $this->authorize('update', $this->application);
$this->syncData(true);
$this->dispatch('success', 'Swarm settings updated.');
} catch (\Throwable $e) {
@@ -61,6 +65,7 @@ public function instantSave()
public function submit()
{
try {
+ $this->authorize('update', $this->application);
$this->syncData(true);
$this->dispatch('success', 'Swarm settings updated.');
} catch (\Throwable $e) {
diff --git a/app/Livewire/Project/Database/BackupEdit.php b/app/Livewire/Project/Database/BackupEdit.php
index 35262d7b0..8b67105cc 100644
--- a/app/Livewire/Project/Database/BackupEdit.php
+++ b/app/Livewire/Project/Database/BackupEdit.php
@@ -201,6 +201,18 @@ public function delete($password)
}
}
+ public function backupNow()
+ {
+ try {
+ $this->authorize('manageBackups', $this->backup->database);
+
+ \App\Jobs\DatabaseBackupJob::dispatch($this->backup);
+ $this->dispatch('success', 'Backup queued. It will be available in a few minutes.');
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ }
+ }
+
public function instantSave()
{
try {
diff --git a/app/Livewire/Project/Database/BackupExecutions.php b/app/Livewire/Project/Database/BackupExecutions.php
index 44f903fcc..5ffe6f509 100644
--- a/app/Livewire/Project/Database/BackupExecutions.php
+++ b/app/Livewire/Project/Database/BackupExecutions.php
@@ -3,12 +3,15 @@
namespace App\Livewire\Project\Database;
use App\Models\ScheduledDatabaseBackup;
+use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Livewire\Component;
class BackupExecutions extends Component
{
+ use AuthorizesRequests;
+
public ?ScheduledDatabaseBackup $backup = null;
public $database;
@@ -44,29 +47,45 @@ public function getListeners()
public function cleanupFailed()
{
- if ($this->backup) {
- $this->backup->executions()->where('status', 'failed')->delete();
- $this->refreshBackupExecutions();
- $this->dispatch('success', 'Failed backups cleaned up.');
+ try {
+ $this->authorize('manageBackups', $this->database);
+ if ($this->backup) {
+ $this->backup->executions()->where('status', 'failed')->delete();
+ $this->refreshBackupExecutions();
+ $this->dispatch('success', 'Failed backups cleaned up.');
+ }
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
}
}
public function cleanupDeleted()
{
- if ($this->backup) {
- $deletedCount = $this->backup->executions()->where('local_storage_deleted', true)->count();
- if ($deletedCount > 0) {
- $this->backup->executions()->where('local_storage_deleted', true)->delete();
- $this->refreshBackupExecutions();
- $this->dispatch('success', "Cleaned up {$deletedCount} backup entries deleted from local storage.");
- } else {
- $this->dispatch('info', 'No backup entries found that are deleted from local storage.');
+ try {
+ $this->authorize('manageBackups', $this->database);
+ if ($this->backup) {
+ $deletedCount = $this->backup->executions()->where('local_storage_deleted', true)->count();
+ if ($deletedCount > 0) {
+ $this->backup->executions()->where('local_storage_deleted', true)->delete();
+ $this->refreshBackupExecutions();
+ $this->dispatch('success', "Cleaned up {$deletedCount} backup entries deleted from local storage.");
+ } else {
+ $this->dispatch('info', 'No backup entries found that are deleted from local storage.');
+ }
}
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
}
}
public function deleteBackup($executionId, $password)
{
+ try {
+ $this->authorize('manageBackups', $this->database);
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ }
+
if (! verifyPasswordConfirmation($password, $this)) {
return;
}
diff --git a/app/Livewire/Project/Service/EditCompose.php b/app/Livewire/Project/Service/EditCompose.php
index 32cf72067..0f5c739b1 100644
--- a/app/Livewire/Project/Service/EditCompose.php
+++ b/app/Livewire/Project/Service/EditCompose.php
@@ -3,10 +3,13 @@
namespace App\Livewire\Project\Service;
use App\Models\Service;
+use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Component;
class EditCompose extends Component
{
+ use AuthorizesRequests;
+
public Service $service;
public $serviceId;
@@ -72,19 +75,29 @@ public function validateCompose()
public function saveEditedCompose()
{
- $this->dispatch('info', 'Saving new docker compose...');
- $this->dispatch('saveCompose', $this->dockerComposeRaw);
- $this->dispatch('refreshStorages');
+ try {
+ $this->authorize('update', $this->service);
+ $this->dispatch('info', 'Saving new docker compose...');
+ $this->dispatch('saveCompose', $this->dockerComposeRaw);
+ $this->dispatch('refreshStorages');
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ }
}
public function instantSave()
{
- $this->validate([
- 'isContainerLabelEscapeEnabled' => 'required',
- ]);
- $this->syncData(true);
- $this->service->save(['is_container_label_escape_enabled' => $this->isContainerLabelEscapeEnabled]);
- $this->dispatch('success', 'Service updated successfully');
+ try {
+ $this->authorize('update', $this->service);
+ $this->validate([
+ 'isContainerLabelEscapeEnabled' => 'required',
+ ]);
+ $this->syncData(true);
+ $this->service->save(['is_container_label_escape_enabled' => $this->isContainerLabelEscapeEnabled]);
+ $this->dispatch('success', 'Service updated successfully');
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ }
}
public function render()
diff --git a/app/Livewire/Project/Service/StackForm.php b/app/Livewire/Project/Service/StackForm.php
index 64a7d8d8b..678db17e8 100644
--- a/app/Livewire/Project/Service/StackForm.php
+++ b/app/Livewire/Project/Service/StackForm.php
@@ -4,12 +4,15 @@
use App\Models\Service;
use App\Support\ValidationPatterns;
+use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Livewire\Component;
class StackForm extends Component
{
+ use AuthorizesRequests;
+
public Service $service;
public Collection $fields;
@@ -128,14 +131,20 @@ public function saveCompose($raw)
public function instantSave()
{
- $this->syncData(true);
- $this->service->save();
- $this->dispatch('success', 'Service settings saved.');
+ try {
+ $this->authorize('update', $this->service);
+ $this->syncData(true);
+ $this->service->save();
+ $this->dispatch('success', 'Service settings saved.');
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ }
}
public function submit($notify = true)
{
try {
+ $this->authorize('update', $this->service);
$this->validate();
$this->syncData(true);
diff --git a/app/Livewire/Project/Shared/UploadConfig.php b/app/Livewire/Project/Shared/UploadConfig.php
index 1b10f588b..0f0894687 100644
--- a/app/Livewire/Project/Shared/UploadConfig.php
+++ b/app/Livewire/Project/Shared/UploadConfig.php
@@ -3,10 +3,13 @@
namespace App\Livewire\Project\Shared;
use App\Models\Application;
+use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Component;
class UploadConfig extends Component
{
+ use AuthorizesRequests;
+
public $config;
public $applicationId;
@@ -29,13 +32,12 @@ public function mount()
public function uploadConfig()
{
try {
- $application = Application::findOrFail($this->applicationId);
+ $application = Application::ownedByCurrentTeam()->findOrFail($this->applicationId);
+ $this->authorize('update', $application);
$application->setConfig($this->config);
$this->dispatch('success', 'Application settings updated');
- } catch (\Exception $e) {
- $this->dispatch('error', $e->getMessage());
-
- return;
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
}
}
diff --git a/app/Livewire/Upgrade.php b/app/Livewire/Upgrade.php
index 7948ad6a9..be4ea1cf0 100644
--- a/app/Livewire/Upgrade.php
+++ b/app/Livewire/Upgrade.php
@@ -44,6 +44,9 @@ public function checkUpdate()
public function upgrade()
{
try {
+ if (! isInstanceAdmin()) {
+ abort(403);
+ }
if ($this->updateInProgress) {
return;
}
diff --git a/resources/views/livewire/project/database/backup-edit.blade.php b/resources/views/livewire/project/database/backup-edit.blade.php
index bb5dcfc4d..b818e8f75 100644
--- a/resources/views/livewire/project/database/backup-edit.blade.php
+++ b/resources/views/livewire/project/database/backup-edit.blade.php
@@ -5,7 +5,7 @@
Save
@if (str($status)->startsWith('running'))
-
+ Backup Now
@endif
@if ($backup->database_id !== 0)