feat(database): implement two-step confirmation for database deletion
Added a new delete method in the Database component that includes a two-step confirmation process requiring the user to enter their password. If two-step confirmation is disabled, the deletion proceeds without password verification. Additionally, a confirmation modal has been integrated into the database view to prompt users before deletion, enhancing the safety of this critical operation.
This commit is contained in:
@@ -4,7 +4,10 @@ namespace App\Livewire\Project\Service;
|
|||||||
|
|
||||||
use App\Actions\Database\StartDatabaseProxy;
|
use App\Actions\Database\StartDatabaseProxy;
|
||||||
use App\Actions\Database\StopDatabaseProxy;
|
use App\Actions\Database\StopDatabaseProxy;
|
||||||
|
use App\Models\InstanceSettings;
|
||||||
use App\Models\ServiceDatabase;
|
use App\Models\ServiceDatabase;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Database extends Component
|
class Database extends Component
|
||||||
@@ -15,6 +18,8 @@ class Database extends Component
|
|||||||
|
|
||||||
public $fileStorages;
|
public $fileStorages;
|
||||||
|
|
||||||
|
public $parameters;
|
||||||
|
|
||||||
protected $listeners = ['refreshFileStorages'];
|
protected $listeners = ['refreshFileStorages'];
|
||||||
|
|
||||||
protected $rules = [
|
protected $rules = [
|
||||||
@@ -34,12 +39,33 @@ class Database extends Component
|
|||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
|
$this->parameters = get_route_parameters();
|
||||||
if ($this->database->is_public) {
|
if ($this->database->is_public) {
|
||||||
$this->db_url_public = $this->database->getServiceDatabaseUrl();
|
$this->db_url_public = $this->database->getServiceDatabaseUrl();
|
||||||
}
|
}
|
||||||
$this->refreshFileStorages();
|
$this->refreshFileStorages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete($password)
|
||||||
|
{
|
||||||
|
if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) {
|
||||||
|
if (! Hash::check($password, Auth::user()->password)) {
|
||||||
|
$this->addError('password', 'The provided password is incorrect.');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->database->delete();
|
||||||
|
$this->dispatch('success', 'Database deleted.');
|
||||||
|
|
||||||
|
return redirect()->route('project.service.configuration', $this->parameters);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function instantSaveExclude()
|
public function instantSaveExclude()
|
||||||
{
|
{
|
||||||
$this->submit();
|
$this->submit();
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
<h2>{{ Str::headline($database->name) }}</h2>
|
<h2>{{ Str::headline($database->name) }}</h2>
|
||||||
@endif
|
@endif
|
||||||
<x-forms.button type="submit">Save</x-forms.button>
|
<x-forms.button type="submit">Save</x-forms.button>
|
||||||
|
<x-modal-confirmation title="Confirm Service Database Deletion?" buttonTitle="Delete" isErrorButton
|
||||||
|
submitAction="delete" :actions="['The selected service database container will be stopped and permanently deleted.']" confirmationText="{{ Str::headline($database->name) }}"
|
||||||
|
confirmationLabel="Please confirm the execution of the actions by entering the Service Database Name below"
|
||||||
|
shortConfirmationLabel="Service Database Name" step3ButtonText="Permanently Delete" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
<div class="flex flex-col h-full gap-8 pt-6 sm:flex-row">
|
<div class="flex flex-col h-full gap-8 pt-6 sm:flex-row">
|
||||||
<div class="flex flex-col items-start gap-2 min-w-fit">
|
<div class="flex flex-col items-start gap-2 min-w-fit">
|
||||||
<a class="menu-item"
|
<a class="menu-item"
|
||||||
class="{{ request()->routeIs('project.service.configuration') ? 'menu-item-active' : '' }}"
|
class="{{ request()->routeIs('project.service.configuration') ? 'menu-item-active' : '' }}" wire:navigate
|
||||||
wire:navigate href="{{ route('project.service.configuration', [...$parameters, 'stack_service_uuid' => null]) }}">
|
href="{{ route('project.service.configuration', [...$parameters, 'stack_service_uuid' => null]) }}">
|
||||||
<button><- Back</button>
|
<button><- Back</button>
|
||||||
</a>
|
</a>
|
||||||
<a class="menu-item" :class="activeTab === 'general' && 'menu-item-active'"
|
<a class="menu-item" :class="activeTab === 'general' && 'menu-item-active'"
|
||||||
@@ -12,8 +12,8 @@
|
|||||||
wire:navigate href="#">General</a>
|
wire:navigate href="#">General</a>
|
||||||
@if ($serviceDatabase?->isBackupSolutionAvailable())
|
@if ($serviceDatabase?->isBackupSolutionAvailable())
|
||||||
<a :class="activeTab === 'backups' && 'menu-item-active'" class="menu-item"
|
<a :class="activeTab === 'backups' && 'menu-item-active'" class="menu-item"
|
||||||
@click.prevent="activeTab = 'backups'; window.location.hash = 'backups'"
|
@click.prevent="activeTab = 'backups'; window.location.hash = 'backups'" wire:navigate
|
||||||
wire:navigate href="#backups">Backups</a>
|
href="#backups">Backups</a>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
|
|||||||
Reference in New Issue
Block a user