fix(proxmox): harden console sessions and firewall rollout safety
Reduce security and reliability risk across the Proxmox extension by removing password exposure from Livewire state, hardening console auth/cookie handling, and improving sanitized error paths. Improve firewall and router performance by adding safer lazy loading, bounded pagination, cross-server compatibility guards, and lower-overhead API workflows. Made-with: Cursor
This commit is contained in:
@@ -22,11 +22,17 @@ class Index extends Component
|
||||
|
||||
public $volid;
|
||||
|
||||
public function promptRestore(string $volid): void
|
||||
{
|
||||
$this->volid = $volid;
|
||||
$this->confirmRestore = false;
|
||||
$this->showRestore = true;
|
||||
}
|
||||
|
||||
public function mount(Server $server): void
|
||||
{
|
||||
parent::mount($server);
|
||||
|
||||
$proxmox = new Proxmox;
|
||||
$settings = $this->server->service->product->settings()->where('key', 'backups')->first();
|
||||
if ($settings?->value <= 0) {
|
||||
$this->redirect(route('proxmox.server.overview', $this->server->id), true);
|
||||
@@ -40,7 +46,24 @@ class Index extends Component
|
||||
return;
|
||||
}
|
||||
|
||||
$this->loadBackups();
|
||||
}
|
||||
|
||||
#[\Livewire\Attributes\On('backup-started')]
|
||||
public function handleBackupStarted(): void
|
||||
{
|
||||
$this->loadBackups();
|
||||
}
|
||||
|
||||
public function loadBackups(): void
|
||||
{
|
||||
if (empty($this->server->node->backup_location)) {
|
||||
$this->backups = [];
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$proxmox = new Proxmox;
|
||||
$response = $proxmox->request('/nodes/' . $this->server->node->name . '/storage/' . $this->server->node->backup_location . '/content', data: [
|
||||
'content' => 'backup',
|
||||
'vmid' => $this->server->vm_id,
|
||||
@@ -78,28 +101,41 @@ class Index extends Component
|
||||
|
||||
// Stop the VM before restoring — Proxmox requires it
|
||||
try {
|
||||
$proxmox->requestAndWait('/nodes/' . $this->server->node->name . '/' . $this->server->node->vmType() . '/' . $this->server->vm_id . '/status/stop', 'post', [
|
||||
$stopStatus = $proxmox->requestAndWait('/nodes/' . $this->server->node->name . '/' . $this->server->node->vmType() . '/' . $this->server->vm_id . '/status/stop', 'post', [
|
||||
'vmid' => $this->server->vm_id,
|
||||
], $this->server->node->name);
|
||||
if ($stopStatus !== 'stopped' && $stopStatus !== 'OK') {
|
||||
$this->notify('Failed to stop VM before restore. Please try again.', 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$msg = strtolower($e->getMessage());
|
||||
// If VM is already stopped, continue with restore; otherwise abort
|
||||
if (!str_contains($msg, 'not running')
|
||||
&& !str_contains($msg, 'already stopped')
|
||||
&& !str_contains($msg, 'is not running')) {
|
||||
$this->notify('Failed to stop VM before restore: ' . $e->getMessage(), 'error');
|
||||
report($e);
|
||||
$this->notify('Failed to stop VM before restore. Please try again.', 'error');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$proxmox->request('/nodes/' . $this->server->node->name . '/qemu', 'post', data: [
|
||||
$restoreStatus = $proxmox->requestAndWait('/nodes/' . $this->server->node->name . '/' . $this->server->node->vmType(), 'post', data: [
|
||||
'vmid' => $this->server->vm_id,
|
||||
'force' => true,
|
||||
'archive' => $this->volid,
|
||||
]);
|
||||
], node: $this->server->node->name);
|
||||
|
||||
if ($restoreStatus !== 'stopped' && $restoreStatus !== 'OK') {
|
||||
$this->notify('Backup restore task failed to complete successfully.', 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$this->notify('Backup restore failed: ' . $e->getMessage(), 'error');
|
||||
report($e);
|
||||
$this->notify('Backup restore failed. Please try again in a moment.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -148,7 +184,7 @@ class Index extends Component
|
||||
$response = $proxmox->request('/nodes/' . $this->server->node->name . '/storage/' . $this->server->node->backup_location . '/content/' . $volid, 'delete');
|
||||
|
||||
$this->notify('Backup deleted successfully', 'success');
|
||||
$this->backups = array_values(array_filter($this->backups, fn ($backup) => $backup['volid'] !== $volid));
|
||||
$this->loadBackups();
|
||||
$this->showDelete = false;
|
||||
$this->confirmDelete = false;
|
||||
$this->volid = null;
|
||||
|
||||
Reference in New Issue
Block a user