fix(admin): the admin password is shown once, and means it
The handoff stayed in the cache for its full ten minutes, so any replayed component request could fetch the plaintext again — "shown once" was a figure of speech. It is consumed on the first read and the token dropped; the payload reaches the view and nothing else. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>feat/portal-design
parent
d40113be8e
commit
55b1a1468f
|
|
@ -82,9 +82,21 @@ class InstanceAdminAccess extends ModalComponent
|
|||
public function render()
|
||||
{
|
||||
$payload = null;
|
||||
|
||||
if ($this->token !== null) {
|
||||
$raw = ConfigHandoff::get($this->token);
|
||||
$payload = $raw === null ? null : json_decode($raw, true);
|
||||
|
||||
if ($raw !== null) {
|
||||
// Consumed on the first read: leaving it in the cache would make
|
||||
// "shown once" a figure of speech — any replayed component
|
||||
// request could fetch the password again for ten minutes. The
|
||||
// payload lives in a local variable, so it reaches the view and
|
||||
// nothing else.
|
||||
ConfigHandoff::forget($this->token);
|
||||
$this->token = null;
|
||||
$this->waiting = false;
|
||||
$payload = json_decode($raw, true);
|
||||
}
|
||||
}
|
||||
|
||||
return view('livewire.admin.instance-admin-access', [
|
||||
|
|
|
|||
|
|
@ -114,3 +114,25 @@ it('tells the console when Proxmox is unreachable', function () {
|
|||
// Otherwise the modal polls forever with a spinner.
|
||||
expect(json_decode(ConfigHandoff::get('handoff-throw'), true))->toBe(['error' => 'failed']);
|
||||
});
|
||||
|
||||
it('shows the password once and not a second time', function () {
|
||||
$pve = new FakeProxmoxClient;
|
||||
app()->instance(ProxmoxClient::class, $pve);
|
||||
$instance = adminAccessInstance();
|
||||
$owner = operator('Owner');
|
||||
$owner->forceFill(['password' => Hash::make('geheim-1234')])->save();
|
||||
|
||||
$modal = Livewire\Livewire::actingAs($owner)
|
||||
->test(InstanceAdminAccess::class, ['uuid' => $instance->uuid])
|
||||
->set('password', 'geheim-1234')
|
||||
->call('request'); // sync queue: the job runs immediately
|
||||
|
||||
$token = $modal->get('token');
|
||||
$modal->assertSee(__('instances.admin_ready'));
|
||||
|
||||
// "Shown once" has to mean it: a replayed request must not fetch it again.
|
||||
expect(ConfigHandoff::get($token ?? 'none'))->toBeNull()
|
||||
->and($modal->get('token'))->toBeNull();
|
||||
|
||||
$modal->call('$refresh')->assertDontSee(__('instances.admin_ready'));
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue