From 92b672b38cf44527e8b74ea9d7d70a4d59f667d1 Mon Sep 17 00:00:00 2001 From: Paul Donald Date: Sat, 19 Jul 2025 19:15:11 +0200 Subject: [PATCH] luci-app-strongswan-swanctl: prevent section name collisions Named sections collide and overwrite each other when navigating the GUI and repeating the same name, because uci does not allow multiple named sections to share the same name. This at least forces users to pick names so their resulting config works. Closes #7159 Signed-off-by: Paul Donald (cherry picked from commit eb66bdccf815797f6d1fa0cc0aed571319a2b980) --- .../view/strongswan-swanctl/swanctl.js | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/applications/luci-app-strongswan-swanctl/htdocs/luci-static/resources/view/strongswan-swanctl/swanctl.js b/applications/luci-app-strongswan-swanctl/htdocs/luci-static/resources/view/strongswan-swanctl/swanctl.js index e618280a72..c56739e3ec 100644 --- a/applications/luci-app-strongswan-swanctl/htdocs/luci-static/resources/view/strongswan-swanctl/swanctl.js +++ b/applications/luci-app-strongswan-swanctl/htdocs/luci-static/resources/view/strongswan-swanctl/swanctl.js @@ -2,6 +2,7 @@ 'require view'; 'require form'; 'require uci'; +'require ui'; 'require tools.widgets as widgets'; 'require strongswan_algorithms'; @@ -23,6 +24,27 @@ function addAlgorithms(o, algorithms) { }); } +function sectionNameCheck(extra_class) { + var el = form.GridSection.prototype.renderSectionAdd.apply(this, arguments), + nameEl = el.querySelector('.cbi-section-create-name'); + ui.addValidator(nameEl, 'uciname', true, function(v) { + let sections = [ + ...uci.sections('ipsec', 'remote'), + ...uci.sections('ipsec', 'tunnel'), + ...uci.sections('ipsec', 'crypto_proposal'), + ]; + if (sections.find(function(s) { + return s['.name'] == v; + })) { + return _('Remotes, Encryption Proposals and Tunnels may not share the same names.') + ' ' + + _('Use combinations like tunnel1_phase1 that do not exceed 15 characters.'); + } + if (v.length > 15) return _('Name length shall not exceed 15 characters'); + return true; + }, 'blur', 'keyup'); + return el; +}; + return view.extend({ load: function () { return uci.load('network'); @@ -38,6 +60,7 @@ return view.extend({ // strongSwan General Settings s = m.section(form.TypedSection, 'ipsec', _('General Settings')); s.anonymous = true; + s.addremove = true; o = s.option(widgets.ZoneSelect, 'zone', _('Zone'), _('Firewall zone that has to match the defined firewall zone')); @@ -62,6 +85,7 @@ return view.extend({ _('Define Remote IKE Configurations.')); s.addremove = true; s.nodescriptions = true; + s.renderSectionAdd = sectionNameCheck o = s.tab('general', _('General')); o = s.tab('authentication', _('Authentication')); @@ -113,7 +137,7 @@ return view.extend({ o.rmempty = false; o = s.taboption('general', form.MultiValue, 'tunnel', _('Tunnel'), - _('Name of ESP (phase 2) section')); + _('The Tunnel containing the ESP (phase 2) section')); o.load = function (section_id) { this.keylist = []; this.vallist = []; @@ -229,6 +253,7 @@ return view.extend({ _('Define Connection Children to be used as Tunnels in Remote Configurations.')); s.addremove = true; s.nodescriptions = true; + s.renderSectionAdd = sectionNameCheck; o = s.tab('general', _('General')); o = s.tab('advanced', _('Advanced')); @@ -362,6 +387,7 @@ return view.extend({ _('Configure Cipher Suites to define IKE (Phase 1) or ESP (Phase 2) Proposals.')); s.addremove = true; s.nodescriptions = true; + s.renderSectionAdd = sectionNameCheck; o = s.option(form.Flag, 'is_esp', _('ESP Proposal'), _('Whether this is an ESP (phase 2) proposal or not')); -- 2.30.2