fix(engine-b): keep admin password ciphertext in the queued mail; valid backup schedule

- CloudReady receives the ENCRYPTED password (decrypts only when rendering), so
  the queued payload never holds plaintext.
- RegisterBackup uses a valid Proxmox calendar expression (02:00).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat/portal-design
nexxo 2026-07-25 12:35:49 +02:00
parent b4cf94ee1a
commit c79874ccfe
3 changed files with 7 additions and 5 deletions

View File

@ -7,6 +7,7 @@ use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Crypt;
/**
* Delivers the initial admin credentials once provisioning completes. Queued for
@ -25,7 +26,7 @@ class CloudReady extends Notification implements ShouldQueue
public function __construct(
public Instance $instance,
public string $adminUser,
public string $adminPassword,
public string $adminPasswordEncrypted, // ciphertext — safe to serialize into the queue
) {}
/** @return array<int, string> */
@ -43,7 +44,7 @@ class CloudReady extends Notification implements ShouldQueue
->greeting(__('provisioning.mail.ready_greeting'))
->line(__('provisioning.mail.ready_line'))
->line(__('provisioning.mail.ready_user', ['user' => $this->adminUser]))
->line(__('provisioning.mail.ready_password', ['password' => $this->adminPassword]))
->line(__('provisioning.mail.ready_password', ['password' => Crypt::decryptString($this->adminPasswordEncrypted)]))
->action(__('provisioning.mail.ready_action'), $url);
}
}

View File

@ -5,7 +5,6 @@ namespace App\Provisioning\Steps\Customer;
use App\Models\ProvisioningRun;
use App\Notifications\CloudReady;
use App\Provisioning\StepResult;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Notification;
class CompleteProvisioning extends CustomerStep
@ -33,8 +32,10 @@ class CompleteProvisioning extends CustomerStep
$encrypted = $run->context('admin_password');
if ($encrypted !== null && ! $this->hasResource($run, 'credentials_sent')) {
// Pass the ENCRYPTED password — CloudReady is queued, so plaintext
// would land in the queue payload; it decrypts only when building the mail.
Notification::route('mail', $order->customer->email)->notify(
new CloudReady($instance, (string) $instance->nc_admin_ref, Crypt::decryptString($encrypted)),
new CloudReady($instance, (string) $instance->nc_admin_ref, $encrypted),
);
// Record delivery so a retry after a crash doesn't re-send.
$this->recordResource($run, $instance->host, 'credentials_sent', (string) $instance->nc_admin_ref);

View File

@ -27,7 +27,7 @@ class RegisterBackup extends CustomerStep
}
$instance = $this->instance($run);
$schedule = 'daily 02:00';
$schedule = '02:00'; // Proxmox calendar-event: daily at 02:00
// Create a real scheduled vzdump job on the host [E] before recording it.
$jobId = $this->pve->forHost($instance->host)