treewide: remove rendundant proto handler options
[project/luci.git] / protocols / luci-proto-wireguard / htdocs / luci-static / resources / protocol / wireguard.js
1 'use strict';
2 'require ui';
3 'require uci';
4 'require rpc';
5 'require form';
6 'require network';
7
8 var generateKey = rpc.declare({
9 object: 'luci.wireguard',
10 method: 'generateKeyPair',
11 expect: { keys: {} }
12 });
13
14 function validateBase64(section_id, value) {
15 if (value.length == 0)
16 return true;
17
18 if (value.length != 44 || !value.match(/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/))
19 return _('Invalid Base64 key string');
20
21 if (value[43] != "=" )
22 return _('Invalid Base64 key string');
23
24 return true;
25 }
26
27 return network.registerProtocol('wireguard', {
28 getI18n: function() {
29 return _('WireGuard VPN');
30 },
31
32 getIfname: function() {
33 return this._ubus('l3_device') || this.sid;
34 },
35
36 getOpkgPackage: function() {
37 return 'wireguard-tools';
38 },
39
40 isFloating: function() {
41 return true;
42 },
43
44 isVirtual: function() {
45 return true;
46 },
47
48 getDevices: function() {
49 return null;
50 },
51
52 containsDevice: function(ifname) {
53 return (network.getIfnameOf(ifname) == this.getIfname());
54 },
55
56 renderFormOptions: function(s) {
57 var o, ss;
58
59 // -- general ---------------------------------------------------------------------
60
61 o = s.taboption('general', form.Value, 'private_key', _('Private Key'), _('Required. Base64-encoded private key for this interface.'));
62 o.password = true;
63 o.validate = validateBase64;
64 o.rmempty = false;
65
66 o = s.taboption('general', form.Button, 'generate_key', _('Generate Key'));
67 o.inputstyle = 'apply';
68 o.onclick = ui.createHandlerFn(this, function(section_id, ev) {
69 return generateKey().then(function(keypair) {
70 var keyInput = document.getElementById('widget.cbid.network.%s.private_key'.format(section_id)),
71 changeEvent = new Event('change');
72
73 keyInput.value = keypair.priv || '';
74 keyInput.dispatchEvent(changeEvent);
75 });
76 }, s.section);
77
78 o = s.taboption('general', form.Value, 'listen_port', _('Listen Port'), _('Optional. UDP port used for outgoing and incoming packets.'));
79 o.datatype = 'port';
80 o.placeholder = _('random');
81 o.optional = true;
82
83 o = s.taboption('general', form.DynamicList, 'addresses', _('IP Addresses'), _('Recommended. IP addresses of the WireGuard interface.'));
84 o.datatype = 'ipaddr';
85 o.optional = true;
86
87 o = s.taboption('general', form.Flag, 'nohostroute', _('No Host Routes'), _('Optional. Do not create host routes to peers.'));
88 o.optional = true;
89
90 // -- advanced --------------------------------------------------------------------
91
92 o = s.taboption('advanced', form.Value, 'mtu', _('MTU'), _('Optional. Maximum Transmission Unit of tunnel interface.'));
93 o.datatype = 'range(1280,1420)';
94 o.placeholder = '1420';
95 o.optional = true;
96
97 o = s.taboption('advanced', form.Value, 'fwmark', _('Firewall Mark'), _('Optional. 32-bit mark for outgoing encrypted packets. Enter value in hex, starting with <code>0x</code>.'));
98 o.optional = true;
99 o.validate = function(section_id, value) {
100 if (value.length > 0 && !value.match(/^0x[a-fA-F0-9]{1,4}$/))
101 return _('Invalid hexadecimal value');
102
103 return true;
104 };
105
106
107 // -- peers -----------------------------------------------------------------------
108
109 try {
110 s.tab('peers', _('Peers'), _('Further information about WireGuard interfaces and peers at <a href=\'http://wireguard.com\'>wireguard.com</a>.'));
111 }
112 catch(e) {}
113
114 o = s.taboption('peers', form.SectionValue, '_peers', form.TypedSection, 'wireguard_%s'.format(s.section));
115 o.depends('proto', 'wireguard');
116
117 ss = o.subsection;
118 ss.anonymous = true;
119 ss.addremove = true;
120 ss.addbtntitle = _('Add peer');
121
122 ss.renderSectionPlaceholder = function() {
123 return E([], [
124 E('br'),
125 E('em', _('No peers defined yet'))
126 ]);
127 };
128
129 o = ss.option(form.Value, 'description', _('Description'), _('Optional. Description of peer.'));
130 o.placeholder = 'My Peer';
131 o.datatype = 'string';
132 o.optional = true;
133
134 o = ss.option(form.Value, 'public_key', _('Public Key'), _('Required. Base64-encoded public key of peer.'));
135 o.validate = validateBase64;
136 o.rmempty = false;
137
138 o = ss.option(form.Value, 'preshared_key', _('Preshared Key'), _('Optional. Base64-encoded preshared key. Adds in an additional layer of symmetric-key cryptography for post-quantum resistance.'));
139 o.password = true;
140 o.validate = validateBase64;
141 o.optional = true;
142
143 o = ss.option(form.DynamicList, 'allowed_ips', _('Allowed IPs'), _("Required. IP addresses and prefixes that this peer is allowed to use inside the tunnel. Usually the peer's tunnel IP addresses and the networks the peer routes through the tunnel."));
144 o.datatype = 'ipaddr';
145 o.validate = function(section, value) {
146 var opt = this.map.lookupOption('allowed_ips', section);
147 var ips = opt[0].formvalue(section);
148 if (ips.length == 0) {
149 return _('Value must not be empty');
150 }
151 return true;
152 };
153
154 o = ss.option(form.Flag, 'route_allowed_ips', _('Route Allowed IPs'), _('Optional. Create routes for Allowed IPs for this peer.'));
155
156 o = ss.option(form.Value, 'endpoint_host', _('Endpoint Host'), _('Optional. Host of peer. Names are resolved prior to bringing up the interface.'));
157 o.placeholder = 'vpn.example.com';
158 o.datatype = 'host';
159
160 o = ss.option(form.Value, 'endpoint_port', _('Endpoint Port'), _('Optional. Port of peer.'));
161 o.placeholder = '51820';
162 o.datatype = 'port';
163
164 o = ss.option(form.Value, 'persistent_keepalive', _('Persistent Keep Alive'), _('Optional. Seconds between keep alive messages. Default is 0 (disabled). Recommended value if this device is behind a NAT is 25.'));
165 o.datatype = 'range(0,65535)';
166 o.placeholder = '0';
167 },
168
169 deleteConfiguration: function() {
170 uci.sections('network', 'wireguard_%s'.format(this.sid), function(s) {
171 uci.remove('network', s['.name']);
172 });
173 }
174 });