%PDF- %PDF-
Direktori : /backups/router/usr/local/opnsense/mvc/app/views/OPNsense/Wireguard/ |
Current File : //backups/router/usr/local/opnsense/mvc/app/views/OPNsense/Wireguard/general.volt |
{# # Copyright (c) 2014-2023 Deciso B.V. # Copyright (c) 2018 Michael Muenz <m.muenz@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. #} <script> $( document ).ready(function() { var data_get_map = {'frm_general_settings':"/api/wireguard/general/get"}; mapDataToFormUI(data_get_map).done(function(data){ formatTokenizersUI(); $('.selectpicker').selectpicker('refresh'); }); let grid_peers = $("#grid-peers").UIBootgrid({ search: '/api/wireguard/client/searchClient', get: '/api/wireguard/client/getClient/', set: '/api/wireguard/client/setClient/', add: '/api/wireguard/client/addClient/', del: '/api/wireguard/client/delClient/', toggle: '/api/wireguard/client/toggleClient/', options:{ initialSearchPhrase: getUrlHash('search'), requestHandler: function(request){ if ( $('#server_filter').val().length > 0) { request['servers'] = $('#server_filter').val(); } return request; } } }); grid_peers.on("loaded.rs.jquery.bootgrid", function (e){ // reload servers before grid load if ($("#server_filter > option").length == 0) { ajaxGet('/api/wireguard/client/list_servers', {}, function(data, status){ if (data.rows !== undefined) { for (let i=0; i < data.rows.length ; ++i) { let row = data.rows[i]; $("#server_filter").append($("<option/>").val(row.uuid).html(row.name)); } $("#server_filter").selectpicker('refresh'); } }); } }); $("#grid-instances").UIBootgrid({ search: '/api/wireguard/server/searchServer', get: '/api/wireguard/server/getServer/', set: '/api/wireguard/server/setServer/', add: '/api/wireguard/server/addServer/', del: '/api/wireguard/server/delServer/', toggle: '/api/wireguard/server/toggleServer/' }); $("#reconfigureAct").SimpleActionButton({ onPreAction: function() { const dfObj = new $.Deferred(); saveFormToEndpoint("/api/wireguard/general/set", 'frm_general_settings', function(){ dfObj.resolve(); }); return dfObj; } }); /** * Move keypair generation button inside the instance form and hook api event */ $("#control_label_server\\.pubkey").append($("#keygen_div").detach().show()); $("#keygen").click(function(){ ajaxGet("/api/wireguard/server/key_pair", {}, function(data, status){ if (data.status && data.status === 'ok') { $("#server\\.pubkey").val(data.pubkey); $("#server\\.privkey").val(data.privkey); } }); }) $("#control_label_client\\.psk").append($("#pskgen_div").detach().show()); $("#pskgen").click(function(){ ajaxGet("/api/wireguard/client/psk", {}, function(data, status){ if (data.status && data.status === 'ok') { $("#client\\.psk").val(data.psk); } }); }) /** * Quick instance filter on top */ $("#filter_container").detach().prependTo('#grid-peers-header > .row > .actionBar > .actions'); $("#server_filter").change(function(){ $('#grid-peers').bootgrid('reload'); }); /** * Peer generator tab hooks */ $("#control_label_configbuilder\\.psk").append($("#pskgen_cb_div").detach().show()); $("#pskgen_cb").click(function(){ ajaxGet("/api/wireguard/client/psk", {}, function(data, status){ if (data.status && data.status === 'ok') { $("#configbuilder\\.psk").val(data.psk).change(); } }); }) let tmp = $("#configbuilder\\.output").closest('tr'); tmp.find('td:eq(2)').empty().append($("<div id='qrcode'/>")); $("#configbuilder\\.output").css('max-width', '100%'); $("#configbuilder\\.output").css('height', '256px'); $("#configbuilder\\.output").change(function(){ $('#qrcode').empty().qrcode($(this).val()); }); $("#configbuilder\\.servers").change(function(){ ajaxGet('/api/wireguard/client/get_server_info/' + $(this).val(), {}, function(data, status) { if (data.status === 'ok') { let endpoint = $("#configbuilder\\.endpoint"); let peer_dns = $("#configbuilder\\.peer_dns"); $("#configbuilder\\.address").val(data.address); peer_dns .val(data.peer_dns) .data('org-value', data.peer_dns); endpoint .val(data.endpoint) .data('org-value', data.endpoint) .data('mtu', data.mtu) .data('pubkey', data.pubkey) .change(); } }); }); $("#configbuilder\\.store_btn").replaceWith($("#btn_configbuilder_save")); $("#btn_configbuilder_save").click(function(){ let instance_id = $("#configbuilder\\.servers").val(); let endpoint = $("#configbuilder\\.endpoint"); let peer_dns = $("#configbuilder\\.peer_dns"); let peer = { configbuilder: { enabled: '1', name: $("#configbuilder\\.name").val(), pubkey: $("#configbuilder\\.pubkey").val(), psk: $("#configbuilder\\.psk").val(), tunneladdress: $("#configbuilder\\.address").val(), keepalive: $("#configbuilder\\.keepalive").val(), server: instance_id, endpoint: endpoint.val() } }; ajaxCall('/api/wireguard/client/addClientBuilder', peer, function(data, status) { if (data.validations) { if (data.validations['configbuilder.tunneladdress']) { /* tunnel address for the client is this peers address, since we remap these in the form, we should remap the errors as well. */ data.validations['configbuilder.address'] = data.validations['configbuilder.tunneladdress']; delete data.validations['configbuilder.tunneladdress']; } handleFormValidation("frm_config_builder", data.validations); } else { if (endpoint.val() != endpoint.data('org-value') || peer_dns.val() != peer_dns.data('org-value')) { let param = { 'server': { 'endpoint': endpoint.val(), 'peer_dns': peer_dns.val() } }; ajaxCall('/api/wireguard/server/setServer/' + instance_id, param, function(data, status){ configbuilder_new(); }); } else { configbuilder_new(); } } }); }); $('input[id ^= "configbuilder\\."]').change(configbuilder_update_config); $('select[id ^= "configbuilder\\."]').change(configbuilder_update_config); function configbuilder_new() { mapDataToFormUI({'frm_config_builder':"/api/wireguard/client/get_client_builder"}).done(function(data){ formatTokenizersUI(); $('.selectpicker').selectpicker('refresh'); ajaxGet("/api/wireguard/server/key_pair", {}, function(data, status){ if (data.status && data.status === 'ok') { $("#configbuilder\\.pubkey").val(data.pubkey); $("#configbuilder\\.privkey").val(data.privkey).change(); } }); $("#configbuilder\\.tunneladdress").val("0.0.0.0/0,::/0"); clearFormValidation("frm_config_builder"); }); } function configbuilder_update_config() { let rows = []; rows.push('[Interface]'); rows.push('PrivateKey = ' + $("#configbuilder\\.privkey").val()); if ($("#configbuilder\\.address").val()) { rows.push('Address = ' + $("#configbuilder\\.address").val()); } if ($("#configbuilder\\.peer_dns").val()) { rows.push('DNS = ' + $("#configbuilder\\.peer_dns").val()); } if ($("#configbuilder\\.endpoint").data('mtu')) { rows.push('MTU = ' + $("#configbuilder\\.endpoint").data('mtu')); } rows.push(''); rows.push('[Peer]'); rows.push('PublicKey = ' + $("#configbuilder\\.endpoint").data('pubkey')); if ($("#configbuilder\\.psk").val()) { rows.push('PresharedKey = ' + $("#configbuilder\\.psk").val()); } rows.push('Endpoint = ' + $("#configbuilder\\.endpoint").val()); rows.push('AllowedIPs = ' + $("#configbuilder\\.tunneladdress").val()); if ($("#configbuilder\\.keepalive").val()) { rows.push('PersistentKeepalive = ' + $("#configbuilder\\.keepalive").val()); } $("#configbuilder\\.output").val(rows.join("\n")).change(); } $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { if (e.target.id == 'tab_configbuilder'){ configbuilder_new(); } else if (e.target.id == 'tab_peers') { $('#grid-peers').bootgrid('reload'); } }); // update history on tab state and implement navigation if(window.location.hash != "") { $('a[href="' + window.location.hash + '"]').click() } $('.nav-tabs a').on('shown.bs.tab', function (e) { history.pushState(null, null, e.target.hash); }); $(window).on('hashchange', function(e) { $('a[href="' + window.location.hash + '"]').click() }); }); </script> <!-- Navigation bar --> <ul class="nav nav-tabs" data-tabs="tabs" id="maintabs"> <li class="active"><a data-toggle="tab" id="tab_instances" href="#instances">{{ lang._('Instances') }}</a></li> <li><a data-toggle="tab" id="tab_peers" href="#peers">{{ lang._('Peers') }}</a></li> <li><a data-toggle="tab" id="tab_configbuilder" href="#configbuilder">{{ lang._('Peer generator') }}</a></li> </ul> <div class="tab-content content-box tab-content"> <div id="peers" class="tab-pane fade in"> <span id="pskgen_div" style="display:none" class="pull-right"> <button id="pskgen" type="button" class="btn btn-secondary" title="{{ lang._('Generate new psk.') }}" data-toggle="tooltip"> <i class="fa fa-fw fa-gear"></i> </button> </span> <div class="hidden"> <!-- filter per server container --> <div id="filter_container" class="btn-group"> <select id="server_filter" data-title="{{ lang._('Instances') }}" class="selectpicker" data-live-search="true" data-size="5" multiple data-width="200px"> </select> </div> </div> <table id="grid-peers" class="table table-condensed table-hover table-striped" data-editDialog="dialogEditWireguardClient"> <thead> <tr> <th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th> <th data-column-id="enabled" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th> <th data-column-id="name" data-type="string" data-visible="true">{{ lang._('Name') }}</th> <th data-column-id="serveraddress" data-type="string" data-visible="true">{{ lang._('Endpoint address') }}</th> <th data-column-id="serverport" data-type="string" data-visible="true">{{ lang._('Endpoint port') }}</th> <th data-column-id="tunneladdress" data-type="string" data-visible="true">{{ lang._('Allowed IPs') }}</th> <th data-column-id="servers" data-type="string" data-visible="true">{{ lang._('Instances') }}</th> <th data-column-id="commands" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th> </tr> </thead> <tbody> </tbody> <tfoot> <tr> <td colspan="6"></td> <td> <button data-action="add" type="button" class="btn btn-xs btn-primary"><span class="fa fa-plus"></span></button> <button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-fw fa-trash-o"></span></button> </td> </tr> </tfoot> </table> </div> <div id="instances" class="tab-pane fade in active"> <span id="keygen_div" style="display:none" class="pull-right"> <button id="keygen" type="button" class="btn btn-secondary" title="{{ lang._('Generate new keypair.') }}" data-toggle="tooltip"> <i class="fa fa-fw fa-gear"></i> </button> </span> <table id="grid-instances" class="table table-condensed table-hover table-striped" data-editDialog="dialogEditWireguardServer"> <thead> <tr> <th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th> <th data-column-id="enabled" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th> <th data-column-id="name" data-type="string" data-visible="true">{{ lang._('Name') }}</th> <th data-column-id="interface" data-type="string" data-visible="true">{{ lang._('Device') }}</th> <th data-column-id="tunneladdress" data-type="string" data-visible="true">{{ lang._('Tunnel Address') }}</th> <th data-column-id="port" data-type="string" data-visible="true">{{ lang._('Port') }}</th> <th data-column-id="peers" data-type="string" data-visible="true">{{ lang._('Peers') }}</th> <th data-column-id="commands" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th> </tr> </thead> <tbody> </tbody> <tfoot> <tr> <td colspan="7"></td> <td> <button data-action="add" type="button" class="btn btn-xs btn-primary"><span class="fa fa-plus"></span></button> <button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-fw fa-trash-o"></span></button> </td> </tr> </tfoot> </table> </div> <div id="configbuilder" class="tab-pane fade in"> <span id="pskgen_cb_div" style="display:none" class="pull-right"> <button id="pskgen_cb" type="button" class="btn btn-secondary" title="{{ lang._('Generate new psk.') }}" data-toggle="tooltip"> <i class="fa fa-fw fa-gear"></i> </button> </span> <span id="configbuilder_div" style="display:none"> <button id="btn_configbuilder_save" type="button" class="btn btn-primary"> <i class="fa fa-fw fa-check"></i> </button> </span> {{ partial("layout_partials/base_form",['fields':formDialogConfigBuilder,'id':'frm_config_builder'])}} </div> </div> <section class="page-content-main"> <div class="content-box"> {{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_general_settings'])}} <button class="btn btn-primary __mt __mb __ml" id="reconfigureAct" data-endpoint='/api/wireguard/service/reconfigure' data-label="{{ lang._('Apply') }}" data-error-title="{{ lang._('Error reconfiguring WireGuard') }}" type="button" ></button> </div> </section> {{ partial("layout_partials/base_dialog",['fields':formDialogEditWireguardClient,'id':'dialogEditWireguardClient','label':lang._('Edit peer')])}} {{ partial("layout_partials/base_dialog",['fields':formDialogEditWireguardServer,'id':'dialogEditWireguardServer','label':lang._('Edit instance')])}}