From 2ed00d1967c1170ad9eb80b769fc1aea6fd76a0e Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Tue, 3 Feb 2026 17:35:44 +0100 Subject: [PATCH] fix(wireguard-dashboard): Fix RPC expect unwrapping, wizard interface naming and key persistence - Change generateConfig/generateQR RPC declarations to use empty expect so error responses are not silently discarded by LuCI's RPC unwrapper - Simplify handleShowQR to always check backend for stored key first - Auto-detect next available interface name in wizard (wg1 if wg0 exists) - Pass private key to addPeer in wizard's createPeers for QR persistence Co-Authored-By: Claude Opus 4.5 --- .../view/wireguard-dashboard/peers.js | 43 ++++++------------- .../view/wireguard-dashboard/wizard.js | 18 ++++++-- .../resources/wireguard-dashboard/api.js | 4 +- 3 files changed, 30 insertions(+), 35 deletions(-) diff --git a/package/secubox/luci-app-wireguard-dashboard/htdocs/luci-static/resources/view/wireguard-dashboard/peers.js b/package/secubox/luci-app-wireguard-dashboard/htdocs/luci-static/resources/view/wireguard-dashboard/peers.js index a53d014f..99ccec1a 100644 --- a/package/secubox/luci-app-wireguard-dashboard/htdocs/luci-static/resources/view/wireguard-dashboard/peers.js +++ b/package/secubox/luci-app-wireguard-dashboard/htdocs/luci-static/resources/view/wireguard-dashboard/peers.js @@ -609,44 +609,27 @@ return view.extend({ var ifaceObj = interfaces.find(function(i) { return i.name === peer.interface; }) || {}; if (privateKey) { + // Have key in session - go straight to endpoint prompt this.promptForEndpointAndShowQR(peer, ifaceObj, privateKey); return; } - // Try backend with empty private key - it will look up the stored key - var savedEndpoint = sessionStorage.getItem('wg_server_endpoint') || ''; - if (savedEndpoint) { - API.generateQR(peer.interface, peer.public_key, '', savedEndpoint).then(function(result) { - if (result && result.qrcode && !result.error) { - self.displayQRModal(peer, result.qrcode, result.config, false); - } else { - self.showPrivateKeyPrompt(peer, ifaceObj, function(key) { - self.promptForEndpointAndShowQR(peer, ifaceObj, key); - }); - } - }).catch(function() { + // Check if backend has the stored key via a quick generateConfig test + API.generateConfig(peer.interface, peer.public_key, '', 'test').then(function(result) { + if (result && result.config && !result.error) { + // Backend has the key - prompt for endpoint, backend will handle the rest + self.promptForEndpointAndShowQR(peer, ifaceObj, ''); + } else { + // No stored key - ask user manually self.showPrivateKeyPrompt(peer, ifaceObj, function(key) { self.promptForEndpointAndShowQR(peer, ifaceObj, key); }); + } + }).catch(function() { + self.showPrivateKeyPrompt(peer, ifaceObj, function(key) { + self.promptForEndpointAndShowQR(peer, ifaceObj, key); }); - } else { - // No saved endpoint yet - need to prompt for endpoint first - // Try a test call to see if backend has the key - API.generateConfig(peer.interface, peer.public_key, '', 'test').then(function(result) { - if (result && result.config && !result.error) { - // Backend has the key, proceed with endpoint prompt - self.promptForEndpointAndShowQR(peer, ifaceObj, ''); - } else { - self.showPrivateKeyPrompt(peer, ifaceObj, function(key) { - self.promptForEndpointAndShowQR(peer, ifaceObj, key); - }); - } - }).catch(function() { - self.showPrivateKeyPrompt(peer, ifaceObj, function(key) { - self.promptForEndpointAndShowQR(peer, ifaceObj, key); - }); - }); - } + }); }, handleDownloadConfig: function(peer, interfaces, ev) { diff --git a/package/secubox/luci-app-wireguard-dashboard/htdocs/luci-static/resources/view/wireguard-dashboard/wizard.js b/package/secubox/luci-app-wireguard-dashboard/htdocs/luci-static/resources/view/wireguard-dashboard/wizard.js index e12f97f9..f8b8858c 100644 --- a/package/secubox/luci-app-wireguard-dashboard/htdocs/luci-static/resources/view/wireguard-dashboard/wizard.js +++ b/package/secubox/luci-app-wireguard-dashboard/htdocs/luci-static/resources/view/wireguard-dashboard/wizard.js @@ -135,6 +135,16 @@ return view.extend({ }); }, + getNextInterfaceName: function(interfaces) { + var existing = interfaces.map(function(i) { return i.name; }); + for (var i = 0; i < 100; i++) { + var name = 'wg' + i; + if (existing.indexOf(name) === -1) + return name; + } + return 'wg0'; + }, + render: function(data) { var self = this; // Handle RPC expect unwrapping - results may be array or object @@ -145,6 +155,7 @@ return view.extend({ this.wizardData.publicIP = publicIP; this.wizardData.existingInterfaces = interfaces; + this.wizardData.nextIfaceName = this.getNextInterfaceName(interfaces); var view = E('div', { 'class': 'wg-wizard' }, [ E('link', { 'rel': 'stylesheet', 'href': L.resource('wireguard-dashboard/dashboard.css') }), @@ -246,7 +257,7 @@ return view.extend({ 'type': 'text', 'id': 'cfg-iface-name', 'class': 'wg-input', - 'value': 'wg0', + 'value': this.wizardData.nextIfaceName || 'wg0', 'placeholder': 'wg0' }), E('small', {}, _('Name for the WireGuard interface')) @@ -633,7 +644,7 @@ return view.extend({ results.push(peerData); - // Add peer to interface + // Add peer to interface (include private key for QR persistence) return api.addPeer( data.ifaceName, zone.name + '_' + (idx + 1), @@ -641,7 +652,8 @@ return view.extend({ keys.public_key, keys.preshared_key, '', - zone.keepalive.toString() + zone.keepalive.toString(), + keys.private_key ); }) ); diff --git a/package/secubox/luci-app-wireguard-dashboard/htdocs/luci-static/resources/wireguard-dashboard/api.js b/package/secubox/luci-app-wireguard-dashboard/htdocs/luci-static/resources/wireguard-dashboard/api.js index e61255b6..6b98085a 100644 --- a/package/secubox/luci-app-wireguard-dashboard/htdocs/luci-static/resources/wireguard-dashboard/api.js +++ b/package/secubox/luci-app-wireguard-dashboard/htdocs/luci-static/resources/wireguard-dashboard/api.js @@ -65,14 +65,14 @@ var callGenerateConfig = rpc.declare({ object: 'luci.wireguard-dashboard', method: 'generate_config', params: ['interface', 'peer', 'private_key', 'endpoint'], - expect: { config: '' } + expect: { } }); var callGenerateQR = rpc.declare({ object: 'luci.wireguard-dashboard', method: 'generate_qr', params: ['interface', 'peer', 'private_key', 'endpoint'], - expect: { qrcode: '' } + expect: { } }); var callGetTraffic = rpc.declare({