From 3bd3e64a3dc77918cd55355f5c93c5e33c6a0a87 Mon Sep 17 00:00:00 2001 From: nexxo Date: Sat, 25 Jul 2026 22:44:31 +0200 Subject: [PATCH] fix(vpn): pause polling while a private config is on screen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every five-second poll re-rendered the page, putting the private key into another HTTP response — the handoff kept it out of the snapshot but not out of the responses. Traffic figures can wait the minute it takes to copy a key. Co-Authored-By: Claude Opus 4.8 --- resources/views/livewire/admin/vpn.blade.php | 5 ++++- tests/Feature/Admin/VpnTest.php | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/resources/views/livewire/admin/vpn.blade.php b/resources/views/livewire/admin/vpn.blade.php index a3c15d9..9ef3209 100644 --- a/resources/views/livewire/admin/vpn.blade.php +++ b/resources/views/livewire/admin/vpn.blade.php @@ -1,4 +1,7 @@ -
+{{-- Polling pauses while a config is on screen: every poll re-renders this + page, and that would put the private key into an HTTP response every five + seconds. Traffic figures can wait the minute someone needs to copy a key. --}} +

{{ __('vpn.title') }}

{{ __('vpn.subtitle') }}

diff --git a/tests/Feature/Admin/VpnTest.php b/tests/Feature/Admin/VpnTest.php index cd26c30..8c0d331 100644 --- a/tests/Feature/Admin/VpnTest.php +++ b/tests/Feature/Admin/VpnTest.php @@ -714,3 +714,20 @@ it('never leaves the previous config on screen after another access is created', ->and($component->get('newConfigName'))->toBeNull() ->and(App\Services\Wireguard\ConfigHandoff::get($firstToken))->toBeNull(); }); + +it('does not keep polling while a private config is on screen', function () { + vpnHub(); + Queue::fake(); + $owner = operator('Owner'); + + $component = Livewire::actingAs($owner)->test(Vpn::class)->assertSee('wire:poll', false); + + $component->set('name', 'Notebook')->set('ownerId', $owner->id)->call('create'); + + // Otherwise every poll would put the private key into another response. + $component->assertDontSee('wire:poll', false)->assertSee('PrivateKey'); + + $component->call('dismissConfig') + ->assertSee('wire:poll', false) + ->assertDontSee('PrivateKey'); +});