fix(wg): traffic header shows live peer totals; QR-name limit made explicit (v0.9.46)
- The Traffic panel header ("Empfangen/Gesendet") drew from the sampled
throughput, which is 0 until the minutely sampler accrues deltas — so a peer
with live traffic (e.g. 244 B) showed "0 B" in the header. It now sums the
live per-peer rx/tx counters, so the header always matches the peer rows. The
chart below stays windowed throughput (fills from the sampler).
- import_hint reworded to state plainly that the WireGuard phone app ALWAYS
prompts for a tunnel name on a QR scan (app behaviour, not changeable); the
.conf download is the path to an automatic name (filename = tunnel name).
Tests: header sums live peer counters. 354 pass, Pint clean, /wireguard 200 with
no console errors, lang parity 89/89.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat/v1-foundation
v0.9.46
parent
60e1edc0d5
commit
645d7dd4a4
14
CHANGELOG.md
14
CHANGELOG.md
|
|
@ -13,7 +13,19 @@ getaggte Releases (Kanal `stable`, optional `beta`) — niemals Entwicklungs-Bui
|
|||
|
||||
_Keine offenen Änderungen — der nächste Stand wird hier gesammelt und als `vX.Y.Z` getaggt._
|
||||
|
||||
## [0.9.45] - 2026-06-21
|
||||
## [0.9.46] - 2026-06-21
|
||||
|
||||
### Behoben
|
||||
- **Traffic-Kopfzeile zeigte 0 B, obwohl der Peer Traffic hatte.** „Empfangen/Gesendet" oben speiste
|
||||
sich aus dem Sample-Durchsatz (0, solange wenig Traffic floss), während die Peer-Zeile den
|
||||
Live-Zähler zeigte — inkonsistent. Die Kopfzeile zeigt jetzt die **Live-Summe der Peer-Zähler**
|
||||
(passt damit immer zur Peer-Zeile). Das Diagramm darunter bleibt der zeitfenster-bezogene Durchsatz
|
||||
(füllt sich über den minütlichen Sampler, sobald spürbarer Traffic fließt).
|
||||
|
||||
### Geändert
|
||||
- **Klarstellung QR-Import am Handy.** Der Hinweis sagt jetzt eindeutig: die WireGuard-App fragt beim
|
||||
QR-Scan **immer** nach einem Tunnel-Namen (App-Vorgabe, nicht abschaltbar). Für einen automatischen
|
||||
Namen die `.conf` **herunterladen** und importieren (Dateiname = Tunnel-Name).
|
||||
|
||||
### Hinzugefügt
|
||||
- **DNS individuell einstellbar.** Der DNS-Server in den Client-Configs war fest auf `1.1.1.1`. Jetzt
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
return [
|
||||
// First tagged release is v0.1.0 (semantic, not -dev).
|
||||
'version' => '0.9.45',
|
||||
'version' => '0.9.46',
|
||||
|
||||
// Deployed commit + branch. install.sh bakes these into .env from the host's .git (the prod
|
||||
// image ships no .git); the Versions page prefers them and falls back to a live .git read in
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ return [
|
|||
'new_peer_once' => 'Diese Konfiguration wird NUR EINMAL angezeigt und nicht gespeichert. Jetzt importieren (QR scannen oder Text kopieren).',
|
||||
'close' => 'Schließen',
|
||||
'download' => 'Herunterladen',
|
||||
'import_hint' => 'QR mit der WireGuard-App scannen (Handy; die App fragt nach einem Tunnel-Namen) oder herunterladen und importieren (PC) — der Dateiname wird zum Tunnel-Namen.',
|
||||
'import_hint' => 'Am Handy QR scannen — die WireGuard-App fragt dabei IMMER nach einem Tunnel-Namen (App-Vorgabe, nicht abschaltbar). Für einen automatischen Namen stattdessen Herunterladen und die .conf importieren (Dateiname = Tunnel-Name).',
|
||||
'settings_title' => 'Einstellungen',
|
||||
'apply' => 'Anwenden',
|
||||
'gate_toggle' => 'Gate',
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ return [
|
|||
'new_peer_once' => 'This configuration is shown ONCE and never stored. Import it now (scan the QR or copy the text).',
|
||||
'close' => 'Close',
|
||||
'download' => 'Download',
|
||||
'import_hint' => 'Scan the QR with the WireGuard app (phone; it asks for a tunnel name) or download and import it (PC) — the filename becomes the tunnel name.',
|
||||
'import_hint' => 'Scan the QR on a phone — the WireGuard app ALWAYS asks for a tunnel name (app behaviour, cannot be disabled). For an automatic name, download and import the .conf instead (filename = tunnel name).',
|
||||
'settings_title' => 'Settings',
|
||||
'apply' => 'Apply',
|
||||
'gate_toggle' => 'Gate',
|
||||
|
|
|
|||
|
|
@ -231,13 +231,17 @@
|
|||
return implode(' ', $out);
|
||||
};
|
||||
$hasTraffic = $traffic['total_down'] > 0 || $traffic['total_up'] > 0;
|
||||
// Header = LIVE cumulative totals (sum of the peer counters), so it always matches the
|
||||
// per-peer rows. The chart below is windowed THROUGHPUT history (needs the sampler).
|
||||
$liveDown = array_sum(array_map(fn ($p) => $p['rx'], $status['peers']));
|
||||
$liveUp = array_sum(array_map(fn ($p) => $p['tx'], $status['peers']));
|
||||
@endphp
|
||||
|
||||
<x-panel :title="__('wireguard.traffic_title')" :padded="false">
|
||||
<div class="flex flex-wrap items-center justify-between gap-3 border-b border-line px-4 py-3 sm:px-5">
|
||||
<div class="flex items-center gap-4 font-mono text-[11px]">
|
||||
<span class="text-accent-text">{{ __('wireguard.total_down') }}: <span class="text-ink-2">{{ $fmtBytes($traffic['total_down']) }}</span></span>
|
||||
<span class="text-cyan">{{ __('wireguard.total_up') }}: <span class="text-ink-2">{{ $fmtBytes($traffic['total_up']) }}</span></span>
|
||||
<span class="text-accent-text">{{ __('wireguard.total_down') }}: <span class="text-ink-2">{{ $fmtBytes($liveDown) }}</span></span>
|
||||
<span class="text-cyan">{{ __('wireguard.total_up') }}: <span class="text-ink-2">{{ $fmtBytes($liveUp) }}</span></span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
@foreach ($windows as $w)
|
||||
|
|
|
|||
|
|
@ -72,6 +72,23 @@ class WireguardPageTest extends TestCase
|
|||
->assertSee(__('wireguard.ssh_lock_turn_off'));
|
||||
}
|
||||
|
||||
public function test_traffic_header_shows_live_cumulative_peer_totals(): void
|
||||
{
|
||||
// The header must match the per-peer rows (sum of live counters), not the sampled throughput.
|
||||
file_put_contents($this->file, json_encode([
|
||||
'at' => time(), 'configured' => true,
|
||||
'gate' => ['marker' => false, 'chain' => false, 'ssh' => false], 'wg_quick' => 'active',
|
||||
'server' => ['subnet' => '10.99.0.0/24', 'server_ip' => '10.99.0.1', 'port' => 51820, 'endpoint' => '1.2.3.4:51820', 'dns' => '1.1.1.1', 'pubkey' => 'srvpub'],
|
||||
'peers' => [
|
||||
['name' => 'a', 'pubkey' => 'p1', 'endpoint' => '', 'latest_handshake' => time(), 'rx' => 244, 'tx' => 92],
|
||||
['name' => 'b', 'pubkey' => 'p2', 'endpoint' => '', 'latest_handshake' => 0, 'rx' => 1000, 'tx' => 0],
|
||||
],
|
||||
]));
|
||||
|
||||
Livewire::test(Index::class)
|
||||
->assertSee('1.2 KB'); // received = 244 + 1000 = 1244 B (only the summed header shows this)
|
||||
}
|
||||
|
||||
public function test_window_selector_switches_and_passes_traffic(): void
|
||||
{
|
||||
WgTrafficSample::create(['peer_pubkey' => 'p1', 'peer_name' => 'a', 'rx' => 0, 'tx' => 0, 'sampled_at' => now()->subMinutes(10)]);
|
||||
|
|
|
|||
Loading…
Reference in New Issue