1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter-feeds.git synced 2025-02-14 19:41:51 +00:00

Update luci-mod-network

This commit is contained in:
Ycarus (Yannick Chabanois) 2020-04-09 14:39:09 +02:00
parent 70d1670539
commit 33830e25d5
9 changed files with 747 additions and 291 deletions

View file

@ -1,9 +1,10 @@
#
# Copyright (C) 2008-2014 The LuCI Team <luci@lists.subsignal.org>
# Copyright (C) 2020 Ycarus (Yannick Chabanois) <ycarus@zugaina.org> for OpenMPTCProuter
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
# From https://github.com/openwrt/luci/commit/6efaea2ffb46f9909038b85cf12e7acf4467ae2e
# From https://github.com/openwrt/luci/commit/1e07e3a52d4d06cc82ab07f2b7fbba0a9a6fb801
include $(TOPDIR)/rules.mk

View file

@ -1,4 +1,7 @@
'use strict';
'require view';
'require dom';
'require poll';
'require rpc';
'require uci';
'require form';
@ -123,7 +126,7 @@ function validateServerSpec(sid, s) {
return true;
}
return L.view.extend({
return view.extend({
load: function() {
return Promise.all([
callHostHints(),
@ -440,7 +443,7 @@ return L.view.extend({
var node = ipopt.map.findElement('id', ipopt.cbid(section_id));
if (node)
L.dom.callClassMethod(node, 'setValue', hosts[mac].ipv4);
dom.callClassMethod(node, 'setValue', hosts[mac].ipv4);
}, this, ipopt, section_id));
return node;
@ -491,7 +494,7 @@ return L.view.extend({
o = s.taboption('leases', CBILease6Status, '__status6__');
return m.render().then(function(mapEl) {
L.Poll.add(function() {
poll.add(function() {
return callDHCPLeases().then(function(leaseinfo) {
var leases = Array.isArray(leaseinfo.dhcp_leases) ? leaseinfo.dhcp_leases : [],
leases6 = Array.isArray(leaseinfo.dhcp6_leases) ? leaseinfo.dhcp6_leases : [];

View file

@ -0,0 +1,556 @@
'use strict';
'require view';
'require dom';
'require poll';
'require rpc';
'require uci';
'require form';
'require validation';
var callHostHints, callDUIDHints, callDHCPLeases, CBILeaseStatus, CBILease6Status;
callHostHints = rpc.declare({
object: 'luci-rpc',
method: 'getHostHints',
expect: { '': {} }
});
callDUIDHints = rpc.declare({
object: 'luci-rpc',
method: 'getDUIDHints',
expect: { '': {} }
});
callDHCPLeases = rpc.declare({
object: 'luci-rpc',
method: 'getDHCPLeases',
expect: { '': {} }
});
CBILeaseStatus = form.DummyValue.extend({
renderWidget: function(section_id, option_id, cfgvalue) {
return E([
E('h4', _('Active DHCP Leases')),
E('div', { 'id': 'lease_status_table', 'class': 'table' }, [
E('div', { 'class': 'tr table-titles' }, [
E('div', { 'class': 'th' }, _('Hostname')),
E('div', { 'class': 'th' }, _('IPv4-Address')),
E('div', { 'class': 'th' }, _('MAC-Address')),
E('div', { 'class': 'th' }, _('Lease time remaining'))
]),
E('div', { 'class': 'tr placeholder' }, [
E('div', { 'class': 'td' }, E('em', _('Collecting data...')))
])
])
]);
}
});
CBILease6Status = form.DummyValue.extend({
renderWidget: function(section_id, option_id, cfgvalue) {
return E([
E('h4', _('Active DHCPv6 Leases')),
E('div', { 'id': 'lease6_status_table', 'class': 'table' }, [
E('div', { 'class': 'tr table-titles' }, [
E('div', { 'class': 'th' }, _('Host')),
E('div', { 'class': 'th' }, _('IPv6-Address')),
E('div', { 'class': 'th' }, _('DUID')),
E('div', { 'class': 'th' }, _('Lease time remaining'))
]),
E('div', { 'class': 'tr placeholder' }, [
E('div', { 'class': 'td' }, E('em', _('Collecting data...')))
])
])
]);
}
});
function validateHostname(sid, s) {
if (s.length > 256)
return _('Expecting: %s').format(_('valid hostname'));
var labels = s.replace(/^\.+|\.$/g, '').split(/\./);
for (var i = 0; i < labels.length; i++)
if (!labels[i].match(/^[a-z0-9_](?:[a-z0-9-]{0,61}[a-z0-9])?$/i))
return _('Expecting: %s').format(_('valid hostname'));
return true;
}
function validateAddressList(sid, s) {
if (s == null || s == '')
return true;
var m = s.match(/^\/(.+)\/$/),
names = m ? m[1].split(/\//) : [ s ];
for (var i = 0; i < names.length; i++) {
var res = validateHostname(sid, names[i]);
if (res !== true)
return res;
}
return true;
}
function validateServerSpec(sid, s) {
if (s == null || s == '')
return true;
var m = s.match(/^\/(.+)\/(.*)$/);
if (!m)
return _('Expecting: %s').format(_('valid hostname'));
var res = validateAddressList(sid, m[1]);
if (res !== true)
return res;
if (m[2] == '' || m[2] == '#')
return true;
// ipaddr%scopeid#srvport@source@interface#srcport
m = m[2].match(/^([0-9a-f:.]+)(?:%[^#@]+)?(?:#(\d+))?(?:@([0-9a-f:.]+)(?:@[^#]+)?(?:#(\d+))?)?$/);
if (!m)
return _('Expecting: %s').format(_('valid IP address'));
else if (validation.parseIPv4(m[1]) && m[3] != null && !validation.parseIPv4(m[3]))
return _('Expecting: %s').format(_('valid IPv4 address'));
else if (validation.parseIPv6(m[1]) && m[3] != null && !validation.parseIPv6(m[3]))
return _('Expecting: %s').format(_('valid IPv6 address'));
else if ((m[2] != null && +m[2] > 65535) || (m[4] != null && +m[4] > 65535))
return _('Expecting: %s').format(_('valid port value'));
return true;
}
return view.extend({
load: function() {
return Promise.all([
callHostHints(),
callDUIDHints()
]);
},
render: function(hosts_duids) {
var has_dhcpv6 = L.hasSystemFeature('dnsmasq', 'dhcpv6') || L.hasSystemFeature('odhcpd'),
hosts = hosts_duids[0],
duids = hosts_duids[1],
m, s, o, ss, so;
m = new form.Map('dhcp', _('DHCP and DNS'), _('Dnsmasq is a combined <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr>-Server and <abbr title="Domain Name System">DNS</abbr>-Forwarder for <abbr title="Network Address Translation">NAT</abbr> firewalls'));
s = m.section(form.TypedSection, 'dnsmasq', _('Server Settings'));
s.anonymous = true;
s.addremove = false;
s.tab('general', _('General Settings'));
s.tab('files', _('Resolv and Hosts Files'));
s.tab('tftp', _('TFTP Settings'));
s.tab('advanced', _('Advanced Settings'));
s.tab('leases', _('Static Leases'));
s.taboption('general', form.Flag, 'domainneeded',
_('Domain required'),
_('Don\'t forward <abbr title="Domain Name System">DNS</abbr>-Requests without <abbr title="Domain Name System">DNS</abbr>-Name'));
s.taboption('general', form.Flag, 'authoritative',
_('Authoritative'),
_('This is the only <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr> in the local network'));
s.taboption('files', form.Flag, 'readethers',
_('Use <code>/etc/ethers</code>'),
_('Read <code>/etc/ethers</code> to configure the <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr>-Server'));
s.taboption('files', form.Value, 'leasefile',
_('Leasefile'),
_('file where given <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr>-leases will be stored'));
s.taboption('files', form.Flag, 'noresolv',
_('Ignore resolve file')).optional = true;
o = s.taboption('files', form.Value, 'resolvfile',
_('Resolve file'),
_('local <abbr title="Domain Name System">DNS</abbr> file'));
o.depends('noresolv', '0');
o.placeholder = '/tmp/resolv.conf.d/resolv.conf.auto';
o.optional = true;
s.taboption('files', form.Flag, 'nohosts',
_('Ignore <code>/etc/hosts</code>')).optional = true;
s.taboption('files', form.DynamicList, 'addnhosts',
_('Additional Hosts files')).optional = true;
o = s.taboption('advanced', form.Flag, 'quietdhcp',
_('Suppress logging'),
_('Suppress logging of the routine operation of these protocols'));
o.optional = true;
o = s.taboption('advanced', form.Flag, 'sequential_ip',
_('Allocate IP sequentially'),
_('Allocate IP addresses sequentially, starting from the lowest available address'));
o.optional = true;
o = s.taboption('advanced', form.Flag, 'boguspriv',
_('Filter private'),
_('Do not forward reverse lookups for local networks'));
o.default = o.enabled;
s.taboption('advanced', form.Flag, 'filterwin2k',
_('Filter useless'),
_('Do not forward requests that cannot be answered by public name servers'));
s.taboption('advanced', form.Flag, 'localise_queries',
_('Localise queries'),
_('Localise hostname depending on the requesting subnet if multiple IPs are available'));
if (L.hasSystemFeature('dnsmasq', 'dnssec')) {
o = s.taboption('advanced', form.Flag, 'dnssec',
_('DNSSEC'));
o.optional = true;
o = s.taboption('advanced', form.Flag, 'dnsseccheckunsigned',
_('DNSSEC check unsigned'),
_('Requires upstream supports DNSSEC; verify unsigned domain responses really come from unsigned domains'));
o.default = o.enabled;
o.optional = true;
}
s.taboption('general', form.Value, 'local',
_('Local server'),
_('Local domain specification. Names matching this domain are never forwarded and are resolved from DHCP or hosts files only'));
s.taboption('general', form.Value, 'domain',
_('Local domain'),
_('Local domain suffix appended to DHCP names and hosts file entries'));
s.taboption('advanced', form.Flag, 'expandhosts',
_('Expand hosts'),
_('Add local domain suffix to names served from hosts files'));
s.taboption('advanced', form.Flag, 'nonegcache',
_('No negative cache'),
_('Do not cache negative replies, e.g. for not existing domains'));
s.taboption('advanced', form.Value, 'serversfile',
_('Additional servers file'),
_('This file may contain lines like \'server=/domain/1.2.3.4\' or \'server=1.2.3.4\' for domain-specific or full upstream <abbr title="Domain Name System">DNS</abbr> servers.'));
s.taboption('advanced', form.Flag, 'strictorder',
_('Strict order'),
_('<abbr title="Domain Name System">DNS</abbr> servers will be queried in the order of the resolvfile')).optional = true;
s.taboption('advanced', form.Flag, 'allservers',
_('All Servers'),
_('Query all available upstream <abbr title="Domain Name System">DNS</abbr> servers')).optional = true;
o = s.taboption('advanced', form.DynamicList, 'bogusnxdomain', _('Bogus NX Domain Override'),
_('List of hosts that supply bogus NX domain results'));
o.optional = true;
o.placeholder = '67.215.65.132';
s.taboption('general', form.Flag, 'logqueries',
_('Log queries'),
_('Write received DNS requests to syslog')).optional = true;
o = s.taboption('general', form.DynamicList, 'server', _('DNS forwardings'),
_('List of <abbr title="Domain Name System">DNS</abbr> servers to forward requests to'));
o.optional = true;
o.placeholder = '/example.org/10.1.2.3';
o.validate = validateServerSpec;
o = s.taboption('general', form.Flag, 'rebind_protection',
_('Rebind protection'),
_('Discard upstream RFC1918 responses'));
o.rmempty = false;
o = s.taboption('general', form.Flag, 'rebind_localhost',
_('Allow localhost'),
_('Allow upstream responses in the 127.0.0.0/8 range, e.g. for RBL services'));
o.depends('rebind_protection', '1');
o = s.taboption('general', form.DynamicList, 'rebind_domain',
_('Domain whitelist'),
_('List of domains to allow RFC1918 responses for'));
o.optional = true;
o.depends('rebind_protection', '1');
o.placeholder = 'ihost.netflix.com';
o.validate = validateAddressList;
o = s.taboption('advanced', form.Value, 'port',
_('<abbr title="Domain Name System">DNS</abbr> server port'),
_('Listening port for inbound DNS queries'));
o.optional = true;
o.datatype = 'port';
o.placeholder = 53;
o = s.taboption('advanced', form.Value, 'queryport',
_('<abbr title="Domain Name System">DNS</abbr> query port'),
_('Fixed source port for outbound DNS queries'));
o.optional = true;
o.datatype = 'port';
o.placeholder = _('any');
o = s.taboption('advanced', form.Value, 'dhcpleasemax',
_('<abbr title="maximal">Max.</abbr> <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr> leases'),
_('Maximum allowed number of active DHCP leases'));
o.optional = true;
o.datatype = 'uinteger';
o.placeholder = _('unlimited');
o = s.taboption('advanced', form.Value, 'ednspacket_max',
_('<abbr title="maximal">Max.</abbr> <abbr title="Extension Mechanisms for Domain Name System">EDNS0</abbr> packet size'),
_('Maximum allowed size of EDNS.0 UDP packets'));
o.optional = true;
o.datatype = 'uinteger';
o.placeholder = 1280;
o = s.taboption('advanced', form.Value, 'dnsforwardmax',
_('<abbr title="maximal">Max.</abbr> concurrent queries'),
_('Maximum allowed number of concurrent DNS queries'));
o.optional = true;
o.datatype = 'uinteger';
o.placeholder = 150;
o = s.taboption('advanced', form.Value, 'cachesize',
_('Size of DNS query cache'),
_('Number of cached DNS entries (max is 10000, 0 is no caching)'));
o.optional = true;
o.datatype = 'range(0,10000)';
o.placeholder = 150;
s.taboption('tftp', form.Flag, 'enable_tftp',
_('Enable TFTP server')).optional = true;
o = s.taboption('tftp', form.Value, 'tftp_root',
_('TFTP server root'),
_('Root directory for files served via TFTP'));
o.optional = true;
o.depends('enable_tftp', '1');
o.placeholder = '/';
o = s.taboption('tftp', form.Value, 'dhcp_boot',
_('Network boot image'),
_('Filename of the boot image advertised to clients'));
o.optional = true;
o.depends('enable_tftp', '1');
o.placeholder = 'pxelinux.0';
o = s.taboption('general', form.Flag, 'localservice',
_('Local Service Only'),
_('Limit DNS service to subnets interfaces on which we are serving DNS.'));
o.optional = false;
o.rmempty = false;
o = s.taboption('general', form.Flag, 'nonwildcard',
_('Non-wildcard'),
_('Bind dynamically to interfaces rather than wildcard address (recommended as linux default)'));
o.default = o.enabled;
o.optional = false;
o.rmempty = true;
o = s.taboption('general', form.DynamicList, 'interface',
_('Listen Interfaces'),
_('Limit listening to these interfaces, and loopback.'));
o.optional = true;
o = s.taboption('general', form.DynamicList, 'notinterface',
_('Exclude interfaces'),
_('Prevent listening on these interfaces.'));
o.optional = true;
o = s.taboption('leases', form.SectionValue, '__leases__', form.GridSection, 'host', null,
_('Static leases are used to assign fixed IP addresses and symbolic hostnames to DHCP clients. They are also required for non-dynamic interface configurations where only hosts with a corresponding lease are served.') + '<br />' +
_('Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</em> identifies the host, the <em>IPv4-Address</em> specifies the fixed address to use, and the <em>Hostname</em> is assigned as a symbolic name to the requesting host. The optional <em>Lease time</em> can be used to set non-standard host-specific lease time, e.g. 12h, 3d or infinite.'));
ss = o.subsection;
ss.addremove = true;
ss.anonymous = true;
so = ss.option(form.Value, 'name', _('Hostname'));
so.validate = validateHostname;
so.rmempty = true;
so.write = function(section, value) {
uci.set('dhcp', section, 'name', value);
uci.set('dhcp', section, 'dns', '1');
};
so.remove = function(section) {
uci.unset('dhcp', section, 'name');
uci.unset('dhcp', section, 'dns');
};
so = ss.option(form.Value, 'mac', _('<abbr title="Media Access Control">MAC</abbr>-Address'));
so.datatype = 'list(unique(macaddr))';
so.rmempty = true;
so.cfgvalue = function(section) {
var macs = uci.get('dhcp', section, 'mac'),
result = [];
if (!Array.isArray(macs))
macs = (macs != null && macs != '') ? macs.split(/\ss+/) : [];
for (var i = 0, mac; (mac = macs[i]) != null; i++)
if (/^([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2})$/.test(mac))
result.push('%02X:%02X:%02X:%02X:%02X:%02X'.format(
parseInt(RegExp.$1, 16), parseInt(RegExp.$2, 16),
parseInt(RegExp.$3, 16), parseInt(RegExp.$4, 16),
parseInt(RegExp.$5, 16), parseInt(RegExp.$6, 16)));
return result.length ? result.join(' ') : null;
};
so.renderWidget = function(section_id, option_index, cfgvalue) {
var node = form.Value.prototype.renderWidget.apply(this, [section_id, option_index, cfgvalue]),
ipopt = this.section.children.filter(function(o) { return o.option == 'ip' })[0];
node.addEventListener('cbi-dropdown-change', L.bind(function(ipopt, section_id, ev) {
var mac = ev.detail.value.value;
if (mac == null || mac == '' || !hosts[mac] || !hosts[mac].ipv4)
return;
var ip = ipopt.formvalue(section_id);
if (ip != null && ip != '')
return;
var node = ipopt.map.findElement('id', ipopt.cbid(section_id));
if (node)
dom.callClassMethod(node, 'setValue', hosts[mac].ipv4);
}, this, ipopt, section_id));
return node;
};
Object.keys(hosts).forEach(function(mac) {
var hint = hosts[mac].name || hosts[mac].ipv4;
so.value(mac, hint ? '%s (%s)'.format(mac, hint) : mac);
});
so = ss.option(form.Value, 'ip', _('<abbr title="Internet Protocol Version 4">IPv4</abbr>-Address'));
so.datatype = 'or(ip4addr,"ignore")';
so.validate = function(section, value) {
var mac = this.map.lookupOption('mac', section),
name = this.map.lookupOption('name', section),
m = mac ? mac[0].formvalue(section) : null,
n = name ? name[0].formvalue(section) : null;
if ((m == null || m == '') && (n == null || n == ''))
return _('One of hostname or mac address must be specified!');
return true;
};
Object.keys(hosts).forEach(function(mac) {
if (hosts[mac].ipv4) {
var hint = hosts[mac].name;
so.value(hosts[mac].ipv4, hint ? '%s (%s)'.format(hosts[mac].ipv4, hint) : hosts[mac].ipv4);
}
});
so = ss.option(form.Value, 'leasetime', _('Lease time'));
so.rmempty = true;
so = ss.option(form.Value, 'duid', _('<abbr title="The DHCP Unique Identifier">DUID</abbr>'));
so.datatype = 'and(rangelength(20,36),hexstring)';
Object.keys(duids).forEach(function(duid) {
so.value(duid, '%s (%s)'.format(duid, duids[duid].hostname || duids[duid].macaddr || duids[duid].ip6addr || '?'));
});
so = ss.option(form.Value, 'hostid', _('<abbr title="Internet Protocol Version 6">IPv6</abbr>-Suffix (hex)'));
o = s.taboption('leases', CBILeaseStatus, '__status__');
if (has_dhcpv6)
o = s.taboption('leases', CBILease6Status, '__status6__');
return m.render().then(function(mapEl) {
poll.add(function() {
return callDHCPLeases().then(function(leaseinfo) {
var leases = Array.isArray(leaseinfo.dhcp_leases) ? leaseinfo.dhcp_leases : [],
leases6 = Array.isArray(leaseinfo.dhcp6_leases) ? leaseinfo.dhcp6_leases : [];
cbi_update_table(mapEl.querySelector('#lease_status_table'),
leases.map(function(lease) {
var exp;
if (lease.expires === false)
exp = E('em', _('unlimited'));
else if (lease.expires <= 0)
exp = E('em', _('expired'));
else
exp = '%t'.format(lease.expires);
return [
lease.hostname || '?',
lease.ipaddr,
lease.macaddr,
exp
];
}),
E('em', _('There are no active leases')));
if (has_dhcpv6) {
cbi_update_table(mapEl.querySelector('#lease6_status_table'),
leases6.map(function(lease) {
var exp;
if (lease.expires === false)
exp = E('em', _('unlimited'));
else if (lease.expires <= 0)
exp = E('em', _('expired'));
else
exp = '%t'.format(lease.expires);
var hint = lease.macaddr ? hosts[lease.macaddr] : null,
name = hint ? (hint.name || hint.ipv4 || hint.ipv6) : null,
host = null;
if (name && lease.hostname && lease.hostname != name && lease.ip6addr != name)
host = '%s (%s)'.format(lease.hostname, name);
else if (lease.hostname)
host = lease.hostname;
else if (name)
host = name;
return [
host || '-',
lease.ip6addrs ? lease.ip6addrs.join(' ') : lease.ip6addr,
lease.duid,
exp
];
}),
E('em', _('There are no active leases')));
}
});
});
return mapEl;
});
}
});

View file

@ -1,9 +1,11 @@
'use strict';
'require view';
'require dom';
'require fs';
'require ui';
'require uci';
return L.view.extend({
return view.extend({
handleCommand: function(exec, args) {
var buttons = document.querySelectorAll('.diag-action > .cbi-button');
@ -14,7 +16,7 @@ return L.view.extend({
var out = document.querySelector('.command-output');
out.style.display = '';
L.dom.content(out, [ res.stdout || '', res.stderr || '' ]);
dom.content(out, [ res.stdout || '', res.stderr || '' ]);
}).catch(function(err) {
ui.addNotification(null, E('p', [ err ]))
}).finally(function() {

View file

@ -1,8 +1,9 @@
'use strict';
'require view';
'require rpc';
'require form';
return L.view.extend({
return view.extend({
callHostHints: rpc.declare({
object: 'luci-rpc',
method: 'getHostHints',

View file

@ -1,4 +1,7 @@
'use strict';
'require view';
'require dom';
'require poll';
'require fs';
'require ui';
'require uci';
@ -109,7 +112,7 @@ function render_status(node, ifc, with_device) {
function render_modal_status(node, ifc) {
var dev = ifc ? (ifc.getDevice() || ifc.getL3Device() || ifc.getL3Device()) : null;
L.dom.content(node, [
dom.content(node, [
E('img', {
'src': L.resource('icons/%s%s.png').format(dev ? dev.getType() : 'ethernet', (dev && dev.isUp()) ? '' : '_disabled'),
'title': dev ? dev.getTypeI18n() : _('Not present')
@ -140,7 +143,7 @@ function render_ifacebox_status(node, ifc) {
c.push(E('small', {}, ifc.isAlias() ? _('Alias of "%s"').format(ifc.isAlias())
: (dev ? dev.getName() : E('em', _('Not present')))));
L.dom.content(node, c);
dom.content(node, c);
return firewall.getZoneByNetwork(ifc.getName()).then(L.bind(function(zone) {
this.style.backgroundColor = zone ? zone.getColor() : '#EEEEEE';
@ -185,7 +188,7 @@ function iface_updown(up, id, ev, force) {
'class': 'cbi-button cbi-button-negative important',
'click': function(ev) {
dsc.setAttribute('disconnect', '');
L.dom.content(dsc, E('em', _('Interface is shutting down...')));
dom.content(dsc, E('em', _('Interface is shutting down...')));
ui.hideModal();
}
@ -195,13 +198,13 @@ function iface_updown(up, id, ev, force) {
}
else {
dsc.setAttribute('disconnect', '');
L.dom.content(dsc, E('em', _('Interface is shutting down...')));
dom.content(dsc, E('em', _('Interface is shutting down...')));
}
});
}
else {
dsc.setAttribute(up ? 'reconnect' : 'disconnect', force ? 'force' : '');
L.dom.content(dsc, E('em', up ? _('Interface is reconnecting...') : _('Interface is shutting down...')));
dom.content(dsc, E('em', up ? _('Interface is reconnecting...') : _('Interface is shutting down...')));
}
}
@ -224,7 +227,7 @@ function get_netmask(s, use_cfgvalue) {
return mask;
}
return L.view.extend({
return view.extend({
poll_status: function(map, networks) {
var resolveZone = null;
@ -245,10 +248,10 @@ return L.view.extend({
dynamic = ifc ? ifc.isDynamic() : false;
if (dsc.hasAttribute('reconnect')) {
L.dom.content(dsc, E('em', _('Interface is starting...')));
dom.content(dsc, E('em', _('Interface is starting...')));
}
else if (dsc.hasAttribute('disconnect')) {
L.dom.content(dsc, E('em', _('Interface is stopping...')));
dom.content(dsc, E('em', _('Interface is stopping...')));
}
else if (ifc.getProtocol() || uci.get('network', ifc.getName()) == null) {
render_status(dsc, ifc, false);
@ -258,18 +261,18 @@ return L.view.extend({
if (e) e.disabled = true;
var link = L.url('admin/system/opkg') + '?query=luci-proto';
L.dom.content(dsc, [
dom.content(dsc, [
E('em', _('Unsupported protocol type.')), E('br'),
E('a', { href: link }, _('Install protocol extensions...'))
]);
}
else {
L.dom.content(dsc, E('em', _('Interface not present or not connected yet.')));
dom.content(dsc, E('em', _('Interface not present or not connected yet.')));
}
if (stat) {
var dev = ifc.getDevice();
L.dom.content(stat, [
dom.content(stat, [
E('img', {
'src': L.resource('icons/%s%s.png').format(dev ? dev.getType() : 'ethernet', (dev && dev.isUp()) ? '' : '_disabled'),
'title': dev ? dev.getTypeI18n() : _('Not present')
@ -336,7 +339,7 @@ return L.view.extend({
disabled = net ? !net.isUp() : true,
dynamic = net ? net.isDynamic() : false;
L.dom.content(tdEl.lastChild, [
dom.content(tdEl.lastChild, [
E('button', {
'class': 'cbi-button cbi-button-neutral reconnect',
'click': iface_updown.bind(this, true, section_id),
@ -483,7 +486,7 @@ return L.view.extend({
};
if (L.hasSystemFeature('firewall')) {
o = s.taboption('firewall', widgets.ZoneSelect, '_zone', _('Create / Assign firewall-zone'), _('Choose the firewall zone you want to assign to this interface. Select <em>unspecified</em> to remove the interface from the associated zone or fill out the <em>create</em> field to define a new zone and attach the interface to it.'));
o = s.taboption('firewall', widgets.ZoneSelect, '_zone', _('Create / Assign firewall-zone'), _('Choose the firewall zone you want to assign to this interface. Select <em>unspecified</em> to remove the interface from the associated zone or fill out the <em>custom</em> field to define a new zone and attach the interface to it.'));
o.network = ifc.getName();
o.optional = true;
@ -979,7 +982,7 @@ return L.view.extend({
return m.render().then(L.bind(function(m, nodes) {
L.Poll.add(L.bind(function() {
poll.add(L.bind(function() {
var section_ids = m.children[0].cfgsections(),
tasks = [];

View file

@ -1,9 +1,10 @@
'use strict';
'require view';
'require form';
'require network';
'require tools.widgets as widgets';
return L.view.extend({
return view.extend({
load: function() {
return network.getDevices();
},

View file

@ -1,4 +1,7 @@
'use strict';
'require view';
'require dom';
'require poll';
'require ui';
'require rpc';
'require uci';
@ -67,13 +70,13 @@ function render_port_status(node, portstate) {
return null;
if (!portstate || !portstate.link)
L.dom.content(node, [
dom.content(node, [
E('img', { src: L.resource('icons/port_down.png') }),
E('br'),
_('no link')
]);
else
L.dom.content(node, [
dom.content(node, [
E('img', { src: L.resource('icons/port_up.png') }),
E('br'),
'%d'.format(portstate.speed) + _('baseT'),
@ -112,7 +115,7 @@ var callSwconfigPortState = rpc.declare({
expect: { result: [] }
});
return L.view.extend({
return view.extend({
load: function() {
return network.getSwitchTopologies().then(function(topologies) {
var tasks = [];
@ -365,7 +368,7 @@ return L.view.extend({
});
}
L.Poll.add(L.bind(update_port_status, m, topologies));
poll.add(L.bind(update_port_status, m, topologies));
return m.render();
}

View file

@ -1,4 +1,7 @@
'use strict';
'require view';
'require dom';
'require poll';
'require fs';
'require ui';
'require rpc';
@ -29,7 +32,7 @@ function render_radio_badge(radioDev) {
]);
}
function render_signal_badge(signalPercent, signalValue, noiseValue, wrap) {
function render_signal_badge(signalPercent, signalValue, noiseValue, wrap, mode) {
var icon, title, value;
if (signalPercent < 0)
@ -45,20 +48,42 @@ function render_signal_badge(signalPercent, signalValue, noiseValue, wrap) {
else
icon = L.resource('icons/signal-75-100.png');
if (signalValue != null && signalValue != 0 && noiseValue != null && noiseValue != 0) {
value = '%d/%d\xa0%s'.format(signalValue, noiseValue, _('dBm'));
title = '%s: %d %s / %s: %d %s / %s %d'.format(
_('Signal'), signalValue, _('dBm'),
_('Noise'), noiseValue, _('dBm'),
_('SNR'), signalValue - noiseValue);
}
else if (signalValue != null && signalValue != 0) {
value = '%d %s'.format(signalValue, _('dBm'));
title = '%s: %d %s'.format(_('Signal'), signalValue, _('dBm'));
if (signalValue != null && signalValue != 0) {
if (noiseValue != null && noiseValue != 0) {
value = '%d/%d\xa0%s'.format(signalValue, noiseValue, _('dBm'));
title = '%s: %d %s / %s: %d %s / %s %d'.format(
_('Signal'), signalValue, _('dBm'),
_('Noise'), noiseValue, _('dBm'),
_('SNR'), signalValue - noiseValue);
}
else {
value = '%d\xa0%s'.format(signalValue, _('dBm'));
title = '%s: %d %s'.format(_('Signal'), signalValue, _('dBm'));
}
}
else if (signalPercent > -1) {
value = '\xa0---\xa0';
title = _('No signal');
switch (mode) {
case 'ap':
title = _('No client associated');
break;
case 'sta':
case 'adhoc':
case 'mesh':
title = _('Not associated');
break;
default:
title = _('No RX signal');
}
if (noiseValue != null && noiseValue != 0) {
value = '---/%d\x0a%s'.format(noiseValue, _('dBm'));
title = '%s / %s: %d %s'.format(title, _('Noise'), noiseValue, _('dBm'));
}
else {
value = '---\xa0%s'.format(_('dBm'));
}
}
else {
value = E('em', {}, E('small', {}, [ _('disabled') ]));
@ -80,7 +105,9 @@ function render_signal_badge(signalPercent, signalValue, noiseValue, wrap) {
}
function render_network_badge(radioNet) {
return render_signal_badge(radioNet.isUp() ? radioNet.getSignalPercent() : -1, radioNet.getSignal(), radioNet.getNoise());
return render_signal_badge(
radioNet.isUp() ? radioNet.getSignalPercent() : -1,
radioNet.getSignal(), radioNet.getNoise(), false, radioNet.getMode());
}
function render_radio_status(radioDev, wifiNets) {
@ -143,7 +170,9 @@ function render_modal_status(node, radioNet) {
if (node == null)
node = E('span', { 'class': 'ifacebadge large', 'data-network': radioNet.getName() }, [ E('small'), E('span') ]);
L.dom.content(node.firstElementChild, render_signal_badge(disabled ? -1 : radioNet.getSignalPercent(), radioNet.getSignal(), noise, true));
dom.content(node.firstElementChild, render_signal_badge(
disabled ? -1 : radioNet.getSignalPercent(),
radioNet.getSignal(), noise, true, radioNet.getMode()));
L.itemlist(node.lastElementChild, [
_('Mode'), mode,
@ -159,7 +188,7 @@ function render_modal_status(node, radioNet) {
], [ ' | ', E('br'), E('br'), E('br'), E('br'), E('br'), ' | ', E('br'), ' | ' ]);
if (!is_assoc)
L.dom.append(node.lastElementChild, E('em', disabled ? _('Wireless is disabled') : _('Wireless is not associated')));
dom.append(node.lastElementChild, E('em', disabled ? _('Wireless is disabled') : _('Wireless is not associated')));
return node;
}
@ -190,7 +219,7 @@ function radio_restart(id, ev) {
btn.disabled = true;
dsc.setAttribute('restart', '');
L.dom.content(dsc, E('em', _('Device is restarting…')));
dom.content(dsc, E('em', _('Device is restarting…')));
}
function network_updown(id, map, ev) {
@ -233,6 +262,31 @@ function next_free_sid(offset) {
return sid;
}
function add_dependency_permutations(o, deps) {
var res = null;
for (var key in deps) {
if (!deps.hasOwnProperty(key) || !Array.isArray(deps[key]))
continue;
var list = deps[key],
tmp = [];
for (var j = 0; j < list.length; j++) {
for (var k = 0; k < (res ? res.length : 1); k++) {
var item = (res ? Object.assign({}, res[k]) : {});
item[key] = list[j];
tmp.push(item);
}
}
res = tmp;
}
for (var i = 0; i < (res ? res.length : 0); i++)
o.depends(res[i]);
}
var CBIWifiFrequencyValue = form.Value.extend({
callFrequencyList: rpc.declare({
object: 'iwinfo',
@ -381,7 +435,7 @@ var CBIWifiFrequencyValue = form.Value.extend({
renderWidget: function(section_id, option_index, cfgvalue) {
var elem = E('div');
L.dom.content(elem, [
dom.content(elem, [
E('label', { 'style': 'float:left; margin-right:3px' }, [
_('Mode'), E('br'),
E('select', {
@ -469,7 +523,7 @@ var CBIWifiTxPowerValue = form.ListValue.extend({
var widget = form.ListValue.prototype.renderWidget.apply(this, [section_id, option_index, cfgvalue]);
widget.firstElementChild.style.width = 'auto';
L.dom.append(widget, E('span', [
dom.append(widget, E('span', [
' - ', _('Current power'), ': ',
E('span', [ this.powerval != null ? '%d dBm'.format(this.powerval) : E('em', _('unknown')) ]),
this.poweroff ? ' + %d dB offset = %s dBm'.format(this.poweroff, this.powerval != null ? this.powerval + this.poweroff : '?') : ''
@ -513,7 +567,7 @@ var CBIWifiCountryValue = form.Value.extend({
}
});
return L.view.extend({
return view.extend({
poll_status: function(map, data) {
var rows = map.querySelectorAll('.cbi-section-table-row[data-sid]');
@ -527,16 +581,16 @@ return L.view.extend({
busy = btns[0].classList.contains('spinning') || btns[1].classList.contains('spinning') || btns[2].classList.contains('spinning');
if (radioDev) {
L.dom.content(badge, render_radio_badge(radioDev));
L.dom.content(stat, render_radio_status(radioDev, data[2].filter(function(n) { return n.getWifiDeviceName() == radioDev.getName() })));
dom.content(badge, render_radio_badge(radioDev));
dom.content(stat, render_radio_status(radioDev, data[2].filter(function(n) { return n.getWifiDeviceName() == radioDev.getName() })));
}
else {
L.dom.content(badge, render_network_badge(radioNet));
L.dom.content(stat, render_network_status(radioNet));
dom.content(badge, render_network_badge(radioNet));
dom.content(stat, render_network_status(radioNet));
}
if (stat.hasAttribute('restart'))
L.dom.content(stat, E('em', _('Device is restarting…')));
dom.content(stat, E('em', _('Device is restarting…')));
btns[0].disabled = busy;
btns[1].disabled = busy;
@ -594,7 +648,7 @@ return L.view.extend({
row.push(E('button', {
'class': 'cbi-button cbi-button-remove',
'click': L.bind(function(net, mac, ev) {
L.dom.parent(ev.currentTarget, '.tr').style.opacity = 0.5;
dom.parent(ev.currentTarget, '.tr').style.opacity = 0.5;
ev.currentTarget.classList.add('spinning');
ev.currentTarget.disabled = true;
ev.currentTarget.blur();
@ -895,7 +949,7 @@ return L.view.extend({
o = ss.taboption('general', form.Value, 'bssid', _('<abbr title="Basic Service Set Identifier">BSSID</abbr>'));
o.datatype = 'macaddr';
o = ss.taboption('general', widgets.NetworkSelect, 'network', _('Network'), _('Choose the network(s) you want to attach to this wireless interface or fill out the <em>create</em> field to define a new network.'));
o = ss.taboption('general', widgets.NetworkSelect, 'network', _('Network'), _('Choose the network(s) you want to attach to this wireless interface or fill out the <em>custom</em> field to define a new network.'));
o.rmempty = true;
o.multiple = true;
o.novirtual = true;
@ -1075,7 +1129,7 @@ return L.view.extend({
var e = this.section.children.filter(function(o) { return o.option == 'encryption' })[0].formvalue(section_id),
co = this.section.children.filter(function(o) { return o.option == 'cipher' })[0], c = co.formvalue(section_id);
if (value == 'wpa' || value == 'wpa2')
if (value == 'wpa' || value == 'wpa2' || value == 'wpa3' || value == 'wpa3-mixed')
uci.unset('wireless', section_id, 'key');
if (co.isActive(section_id) && e && (c == 'tkip' || c == 'ccmp' || c == 'tkip+ccmp'))
@ -1087,6 +1141,8 @@ return L.view.extend({
o = ss.taboption('encryption', form.ListValue, 'cipher', _('Cipher'));
o.depends('encryption', 'wpa');
o.depends('encryption', 'wpa2');
o.depends('encryption', 'wpa3');
o.depends('encryption', 'wpa3-mixed');
o.depends('encryption', 'psk');
o.depends('encryption', 'psk2');
o.depends('encryption', 'wpa-mixed');
@ -1128,9 +1184,13 @@ return L.view.extend({
var has_ap_owe = L.hasSystemFeature('hostapd', 'owe'),
has_sta_owe = L.hasSystemFeature('wpasupplicant', 'owe');
// Probe Suite-B support
var has_ap_eap192 = L.hasSystemFeature('hostapd', 'suiteb192'),
has_sta_eap192 = L.hasSystemFeature('wpasupplicant', 'suiteb192');
if (has_hostapd || has_supplicant) {
crypto_modes.push(['psk2', 'WPA2-PSK', 33]);
crypto_modes.push(['psk2', 'WPA2-PSK', 35]);
crypto_modes.push(['psk-mixed', 'WPA-PSK/WPA2-PSK Mixed Mode', 22]);
crypto_modes.push(['psk', 'WPA-PSK', 21]);
}
@ -1144,7 +1204,12 @@ return L.view.extend({
}
if (has_ap_eap || has_sta_eap) {
crypto_modes.push(['wpa2', 'WPA2-EAP', 32]);
if (has_ap_eap192 || has_sta_eap192) {
crypto_modes.push(['wpa3', 'WPA3-EAP', 33]);
crypto_modes.push(['wpa3-mixed', 'WPA2-EAP/WPA3-EAP Mixed Mode', 32]);
}
crypto_modes.push(['wpa2', 'WPA2-EAP', 34]);
crypto_modes.push(['wpa', 'WPA-EAP', 20]);
}
@ -1163,6 +1228,8 @@ return L.view.extend({
'sae-mixed': has_ap_sae || _('Requires hostapd with SAE support'),
'wpa': has_ap_eap || _('Requires hostapd with EAP support'),
'wpa2': has_ap_eap || _('Requires hostapd with EAP support'),
'wpa3': has_ap_eap192 || _('Requires hostapd with EAP Suite-B support'),
'wpa3-mixed': has_ap_eap192 || _('Requires hostapd with EAP Suite-B support'),
'owe': has_ap_owe || _('Requires hostapd with OWE support')
},
'sta': {
@ -1175,6 +1242,8 @@ return L.view.extend({
'sae-mixed': has_sta_sae || _('Requires wpa-supplicant with SAE support'),
'wpa': has_sta_eap || _('Requires wpa-supplicant with EAP support'),
'wpa2': has_sta_eap || _('Requires wpa-supplicant with EAP support'),
'wpa3': has_sta_eap192 || _('Requires wpa-supplicant with EAP Suite-B support'),
'wpa3-mixed': has_sta_eap192 || _('Requires wpa-supplicant with EAP Suite-B support'),
'owe': has_sta_owe || _('Requires wpa-supplicant with OWE support')
},
'adhoc': {
@ -1237,74 +1306,47 @@ return L.view.extend({
o = ss.taboption('encryption', form.Value, 'auth_server', _('Radius-Authentication-Server'));
o.depends({ mode: 'ap', encryption: 'wpa' });
o.depends({ mode: 'ap', encryption: 'wpa2' });
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o.rmempty = true;
o.datatype = 'host(0)';
o = ss.taboption('encryption', form.Value, 'auth_port', _('Radius-Authentication-Port'), _('Default %d').format(1812));
o.depends({ mode: 'ap', encryption: 'wpa' });
o.depends({ mode: 'ap', encryption: 'wpa2' });
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o.rmempty = true;
o.datatype = 'port';
o = ss.taboption('encryption', form.Value, 'auth_secret', _('Radius-Authentication-Secret'));
o.depends({ mode: 'ap', encryption: 'wpa' });
o.depends({ mode: 'ap', encryption: 'wpa2' });
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o.rmempty = true;
o.password = true;
o = ss.taboption('encryption', form.Value, 'acct_server', _('Radius-Accounting-Server'));
o.depends({ mode: 'ap', encryption: 'wpa' });
o.depends({ mode: 'ap', encryption: 'wpa2' });
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o.rmempty = true;
o.datatype = 'host(0)';
o = ss.taboption('encryption', form.Value, 'acct_port', _('Radius-Accounting-Port'), _('Default %d').format(1813));
o.depends({ mode: 'ap', encryption: 'wpa' });
o.depends({ mode: 'ap', encryption: 'wpa2' });
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o.rmempty = true;
o.datatype = 'port';
o = ss.taboption('encryption', form.Value, 'acct_secret', _('Radius-Accounting-Secret'));
o.depends({ mode: 'ap', encryption: 'wpa' });
o.depends({ mode: 'ap', encryption: 'wpa2' });
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o.rmempty = true;
o.password = true;
o = ss.taboption('encryption', form.Value, 'dae_client', _('DAE-Client'));
o.depends({ mode: 'ap', encryption: 'wpa' });
o.depends({ mode: 'ap', encryption: 'wpa2' });
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o.rmempty = true;
o.datatype = 'host(0)';
o = ss.taboption('encryption', form.Value, 'dae_port', _('DAE-Port'), _('Default %d').format(3799));
o.depends({ mode: 'ap', encryption: 'wpa' });
o.depends({ mode: 'ap', encryption: 'wpa2' });
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o.rmempty = true;
o.datatype = 'port';
o = ss.taboption('encryption', form.Value, 'dae_secret', _('DAE-Secret'));
o.depends({ mode: 'ap', encryption: 'wpa' });
o.depends({ mode: 'ap', encryption: 'wpa2' });
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o.rmempty = true;
o.password = true;
@ -1372,29 +1414,13 @@ return L.view.extend({
var has_80211r = L.hasSystemFeature('hostapd', '11r') || L.hasSystemFeature('hostapd', 'eap');
o = ss.taboption('encryption', form.Flag, 'ieee80211r', _('802.11r Fast Transition'), _('Enables fast roaming among access points that belong to the same Mobility Domain'));
o.depends({ mode: 'ap', encryption: 'wpa' });
o.depends({ mode: 'ap', encryption: 'wpa2' });
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
if (has_80211r) {
o.depends({ mode: 'ap', encryption: 'psk' });
o.depends({ mode: 'ap', encryption: 'psk2' });
o.depends({ mode: 'ap', encryption: 'psk-mixed' });
o.depends({ mode: 'ap', encryption: 'sae' });
o.depends({ mode: 'ap', encryption: 'sae-mixed' });
o.depends({ mode: 'ap-wds', encryption: 'psk' });
o.depends({ mode: 'ap-wds', encryption: 'psk2' });
o.depends({ mode: 'ap-wds', encryption: 'psk-mixed' });
o.depends({ mode: 'ap-wds', encryption: 'sae' });
o.depends({ mode: 'ap-wds', encryption: 'sae-mixed' });
}
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
if (has_80211r)
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['psk', 'psk2', 'psk-mixed', 'sae', 'sae-mixed'] });
o.rmempty = true;
o = ss.taboption('encryption', form.Value, 'nasid', _('NAS ID'), _('Used for two different purposes: RADIUS NAS ID and 802.11r R0KH-ID. Not needed with normal WPA(2)-PSK.'));
o.depends({ mode: 'ap', encryption: 'wpa' });
o.depends({ mode: 'ap', encryption: 'wpa2' });
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o.depends({ ieee80211r: '1' });
o.rmempty = true;
@ -1452,19 +1478,13 @@ return L.view.extend({
o.value('ttls', 'TTLS');
o.value('peap', 'PEAP');
o.value('fast', 'FAST');
o.depends({ mode: 'sta', encryption: 'wpa' });
o.depends({ mode: 'sta', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o = ss.taboption('encryption', form.Flag, 'ca_cert_usesystem', _('Use system certificates'), _("Validate server certificate using built-in system CA bundle,<br />requires the \"ca-bundle\" package"));
o.enabled = '1';
o.disabled = '0';
o.default = o.disabled;
o.depends({ mode: 'sta', encryption: 'wpa' });
o.depends({ mode: 'sta', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o.validate = function(section_id, value) {
if (value == '1' && !L.hasSystemFeature('cabundle')) {
return _("This option cannot be used because the ca-bundle package is not installed.");
@ -1473,52 +1493,28 @@ return L.view.extend({
};
o = ss.taboption('encryption', form.FileUpload, 'ca_cert', _('Path to CA-Certificate'));
o.depends({ mode: 'sta', encryption: 'wpa', ca_cert_usesystem: '0' });
o.depends({ mode: 'sta', encryption: 'wpa2', ca_cert_usesystem: '0' });
o.depends({ mode: 'sta-wds', encryption: 'wpa', ca_cert_usesystem: '0' });
o.depends({ mode: 'sta-wds', encryption: 'wpa2', ca_cert_usesystem: '0' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], ca_cert_usesystem: ['0'] });
o = ss.taboption('encryption', form.Value, 'subject_match', _('Certificate constraint (Subject)'), _("Certificate constraint substring - e.g. /CN=wifi.mycompany.com<br />See `logread -f` during handshake for actual values"));
o.depends({ mode: 'sta', encryption: 'wpa' });
o.depends({ mode: 'sta', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o = ss.taboption('encryption', form.DynamicList, 'altsubject_match', _('Certificate constraint (SAN)'), _("Certificate constraint(s) via Subject Alternate Name values<br />(supported attributes: EMAIL, DNS, URI) - e.g. DNS:wifi.mycompany.com"));
o.depends({ mode: 'sta', encryption: 'wpa' });
o.depends({ mode: 'sta', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o = ss.taboption('encryption', form.DynamicList, 'domain_match', _('Certificate constraint (Domain)'), _("Certificate constraint(s) against DNS SAN values (if available)<br />or Subject CN (exact match)"));
o.depends({ mode: 'sta', encryption: 'wpa' });
o.depends({ mode: 'sta', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o = ss.taboption('encryption', form.DynamicList, 'domain_suffix_match', _('Certificate constraint (Wildcard)'), _("Certificate constraint(s) against DNS SAN values (if available)<br />or Subject CN (suffix match)"));
o.depends({ mode: 'sta', encryption: 'wpa' });
o.depends({ mode: 'sta', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o = ss.taboption('encryption', form.FileUpload, 'client_cert', _('Path to Client-Certificate'));
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa' });
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['tls'] });
o = ss.taboption('encryption', form.FileUpload, 'priv_key', _('Path to Private Key'));
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['tls'] });
o = ss.taboption('encryption', form.Value, 'priv_key_pwd', _('Password of Private Key'));
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['tls'] });
o.password = true;
o = ss.taboption('encryption', form.ListValue, 'auth', _('Authentication'));
@ -1526,22 +1522,11 @@ return L.view.extend({
o.value('CHAP', 'CHAP');
o.value('MSCHAP', 'MSCHAP');
o.value('MSCHAPV2', 'MSCHAPv2');
o.value('EAP-GTC');
o.value('EAP-MD5');
o.value('EAP-MSCHAPV2');
o.value('EAP-TLS');
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa' });
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa' });
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa' });
o.value('EAP-GTC', 'EAP-GTC');
o.value('EAP-MD5', 'EAP-MD5');
o.value('EAP-MSCHAPV2', 'EAP-MSCHAPv2');
o.value('EAP-TLS', 'EAP-TLS');
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['fast', 'peap', 'ttls'] });
o.validate = function(section_id, value) {
var eo = this.section.children.filter(function(o) { return o.option == 'eap_type' })[0],
@ -1557,10 +1542,7 @@ return L.view.extend({
o.enabled = '1';
o.disabled = '0';
o.default = o.disabled;
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
o.validate = function(section_id, value) {
if (value == '1' && !L.hasSystemFeature('cabundle')) {
return _("This option cannot be used because the ca-bundle package is not installed.");
@ -1569,103 +1551,38 @@ return L.view.extend({
};
o = ss.taboption('encryption', form.FileUpload, 'ca_cert2', _('Path to inner CA-Certificate'));
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa', ca_cert2_usesystem: '0' });
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2', ca_cert2_usesystem: '0' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa', ca_cert2_usesystem: '0' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2', ca_cert2_usesystem: '0' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'], ca_cert2_usesystem: ['0'] });
o = ss.taboption('encryption', form.Value, 'subject_match2', _('Inner certificate constraint (Subject)'), _("Certificate constraint substring - e.g. /CN=wifi.mycompany.com<br />See `logread -f` during handshake for actual values"));
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
o = ss.taboption('encryption', form.DynamicList, 'altsubject_match2', _('Inner certificate constraint (SAN)'), _("Certificate constraint(s) via Subject Alternate Name values<br />(supported attributes: EMAIL, DNS, URI) - e.g. DNS:wifi.mycompany.com"));
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
o = ss.taboption('encryption', form.DynamicList, 'domain_match2', _('Inner certificate constraint (Domain)'), _("Certificate constraint(s) against DNS SAN values (if available)<br />or Subject CN (exact match)"));
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
o = ss.taboption('encryption', form.DynamicList, 'domain_suffix_match2', _('Inner certificate constraint (Wildcard)'), _("Certificate constraint(s) against DNS SAN values (if available)<br />or Subject CN (suffix match)"));
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
o = ss.taboption('encryption', form.FileUpload, 'client_cert2', _('Path to inner Client-Certificate'));
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
o = ss.taboption('encryption', form.FileUpload, 'priv_key2', _('Path to inner Private Key'));
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
o = ss.taboption('encryption', form.Value, 'priv_key2_pwd', _('Password of inner Private Key'));
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
o.password = true;
o = ss.taboption('encryption', form.Value, 'identity', _('Identity'));
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa' });
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa' });
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa' });
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['fast', 'peap', 'tls', 'ttls'] });
o = ss.taboption('encryption', form.Value, 'anonymous_identity', _('Anonymous Identity'));
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa' });
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa' });
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa' });
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['fast', 'peap', 'tls', 'ttls'] });
o = ss.taboption('encryption', form.Value, 'password', _('Password'));
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa' });
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa' });
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa2' });
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa' });
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa' });
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['fast', 'peap', 'ttls'] });
o.password = true;
@ -1676,32 +1593,10 @@ return L.view.extend({
o.value('', _('Disabled'));
o.value('1', _('Optional'));
o.value('2', _('Required'));
o.depends({ mode: 'ap', encryption: 'wpa2' });
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
o.depends({ mode: 'ap', encryption: 'psk2' });
o.depends({ mode: 'ap', encryption: 'psk-mixed' });
o.depends({ mode: 'ap', encryption: 'sae' });
o.depends({ mode: 'ap', encryption: 'sae-mixed' });
o.depends({ mode: 'ap', encryption: 'owe' });
o.depends({ mode: 'ap-wds', encryption: 'psk2' });
o.depends({ mode: 'ap-wds', encryption: 'psk-mixed' });
o.depends({ mode: 'ap-wds', encryption: 'sae' });
o.depends({ mode: 'ap-wds', encryption: 'sae-mixed' });
o.depends({ mode: 'ap-wds', encryption: 'owe' });
o.depends({ mode: 'sta', encryption: 'wpa2' });
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
o.depends({ mode: 'sta', encryption: 'psk2' });
o.depends({ mode: 'sta', encryption: 'psk-mixed' });
o.depends({ mode: 'sta', encryption: 'sae' });
o.depends({ mode: 'sta', encryption: 'sae-mixed' });
o.depends({ mode: 'sta', encryption: 'owe' });
o.depends({ mode: 'sta-wds', encryption: 'psk2' });
o.depends({ mode: 'sta-wds', encryption: 'psk-mixed' });
o.depends({ mode: 'sta-wds', encryption: 'sae' });
o.depends({ mode: 'sta-wds', encryption: 'sae-mixed' });
o.depends({ mode: 'sta-wds', encryption: 'owe' });
add_dependency_permutations(o, { mode: ['ap', 'ap-wds', 'sta', 'sta-wds'], encryption: ['owe', 'psk2', 'psk-mixed', 'sae', 'sae-mixed', 'wpa2', 'wpa3', 'wpa3-mixed'] });
o.defaults = {
'2': [{ encryption: 'sae' }, { encryption: 'owe' }],
'2': [{ encryption: 'sae' }, { encryption: 'owe' }, { encryption: 'wpa3' }, { encryption: 'wpa3-mixed' }],
'1': [{ encryption: 'sae-mixed'}],
'': []
};
@ -1722,16 +1617,7 @@ return L.view.extend({
};
o = ss.taboption('encryption', form.Flag, 'wpa_disable_eapol_key_retries', _('Enable key reinstallation (KRACK) countermeasures'), _('Complicates key reinstallation attacks on the client side by disabling retransmission of EAPOL-Key frames that are used to install keys. This workaround might cause interoperability issues and reduced robustness of key negotiation especially in environments with heavy traffic load.'));
o.depends({ mode: 'ap', encryption: 'wpa2' });
o.depends({ mode: 'ap', encryption: 'psk2' });
o.depends({ mode: 'ap', encryption: 'psk-mixed' });
o.depends({ mode: 'ap', encryption: 'sae' });
o.depends({ mode: 'ap', encryption: 'sae-mixed' });
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
o.depends({ mode: 'ap-wds', encryption: 'psk2' });
o.depends({ mode: 'ap-wds', encryption: 'psk-mixed' });
o.depends({ mode: 'ap-wds', encryption: 'sae' });
o.depends({ mode: 'ap-wds', encryption: 'sae-mixed' });
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['psk2', 'psk-mixed', 'sae', 'sae-mixed', 'wpa2', 'wpa3', 'wpa3-mixed'] });
if (L.hasSystemFeature('hostapd', 'cli') && L.hasSystemFeature('wpasupplicant')) {
o = ss.taboption('encryption', form.Flag, 'wps_pushbutton', _('Enable WPS pushbutton, requires WPA(2)-PSK/WPA3-SAE'))
@ -1793,8 +1679,8 @@ return L.view.extend({
this.pollFn = L.bind(this.handleScanRefresh, this, radioDev, {}, table, stop);
L.Poll.add(this.pollFn);
L.Poll.start();
poll.add(this.pollFn);
poll.start();
};
s.handleScanRefresh = function(radioDev, scanCache, table, stop) {
@ -1860,12 +1746,12 @@ return L.view.extend({
var btn = ev.currentTarget;
if (btn.getAttribute('data-state') == 'stop') {
L.Poll.remove(this.pollFn);
poll.remove(this.pollFn);
btn.firstChild.data = _('Start refresh');
btn.setAttribute('data-state', 'start');
}
else {
L.Poll.add(this.pollFn);
poll.add(this.pollFn);
btn.firstChild.data = _('Stop refresh');
btn.setAttribute('data-state', 'stop');
btn.classList.add('spinning');
@ -1874,14 +1760,14 @@ return L.view.extend({
};
s.handleScanAbort = function(ev) {
var md = L.dom.parent(ev.target, 'div[aria-modal="true"]');
var md = dom.parent(ev.target, 'div[aria-modal="true"]');
if (md) {
md.style.maxWidth = '';
md.style.maxHeight = '';
}
ui.hideModal();
L.Poll.remove(this.pollFn);
poll.remove(this.pollFn);
this.pollFn = null;
};
@ -2038,7 +1924,7 @@ return L.view.extend({
bssid.default = '0';
}
zone = s2.option(widgets.ZoneSelect, 'zone', _('Create / Assign firewall-zone'), _('Choose the firewall zone you want to assign to this interface. Select <em>unspecified</em> to remove the interface from the associated zone or fill out the <em>create</em> field to define a new zone and attach the interface to it.'));
zone = s2.option(widgets.ZoneSelect, 'zone', _('Create / Assign firewall-zone'), _('Choose the firewall zone you want to assign to this interface. Select <em>unspecified</em> to remove the interface from the associated zone or fill out the <em>custom</em> field to define a new zone and attach the interface to it.'));
zone.default = 'wan';
return m2.render().then(L.bind(function(nodes) {
@ -2101,7 +1987,7 @@ return L.view.extend({
};
return m.render().then(L.bind(function(m, nodes) {
L.Poll.add(L.bind(function() {
poll.add(L.bind(function() {
var section_ids = m.children[0].cfgsections(),
tasks = [ network.getHostHints(), network.getWifiDevices() ];