{% extends 'account_layout.html' %} {% load static %} {% load i18n %} {% block title %}WireGuard{% endblock %} {% block account_content %} <h2>WireGuard</h2> <p> {% blocktrans trimmed %} This page lets you manage <a href="https://www.wireguard.com/">WireGuard</a> clients. Each can only have one concurrent connection. {% endblocktrans %} <br /> {% blocktrans trimmed %} WireGuard has better performances than OpenVPN, but is not as widely supported. {% endblocktrans %} </p> <div class="page-wg-title"> <h3> {% trans "Your Devices" %} <span>{{ keys|length }}/{{ config.WIREGUARD_MAX_PEERS }}</span> </h3> <p> <a {% if not can_create_key %} href="#" disabled {% else %} href="{% url 'lambdainst:wireguard_new' %}" {% endif %} class="pure-button pure-button-primary" > {% trans "New Device" %} </a> </p> </div> {% if keys %} <table class="pure-table pure-table-bordered page-wg-table"> <thead> <tr> <td>{% trans "Public Key" %}</td> <td>{% trans "Name" %}</td> <td colspan="2"></td> </tr> </thead> {% for peer in keys %} <tr> <td> <span class="wireguard-key">{{ peer.public_key }}</span> </td> <td class="page-wg-table__name"> {{peer.name}} </td> <td class="page-wg-table__action"> <a href="#" onclick="toggleWgEdit(event, {{ peer.id }});" title="{% trans 'Edit' %}"> <i class="fa fa-pencil"></i> </a> </td> <td class="page-wg-table__action page-wg-table__action--more"> <form action="?" method="post"> {% csrf_token %} <input type="hidden" name="action" value="delete_key" /> <input type="hidden" name="peer_id" value="{{ peer.id }}" /> <a href="#" onclick="deleteWgKey(event);" title="{% trans 'Delete' %}"> <i class="fa fa-trash"></i> </a> </form> </td> </tr> {% endfor %} </table> <h3>Configuration</h3> <form method="get" class="pure-form pure-form-aligned" id="config-form" action="{% url 'django_lcore:wireguard_dl' %}"> <fieldset> <div class="pure-control-group"> <label for="p_device">{% trans 'Device' %}</label> <select name="id" id="p_device" class="pure-input-1-2"> {% for k in keys %} <option value="{{k.id}}"> {% if k.name %} {{k.name}} ({{k.public_key|truncatechars:8}}) {% else %} {{k.public_key|truncatechars:16}} {% endif %} </option> {% endfor %} </select> </div> <div class="pure-control-group"> <label for="p_gw">{% trans 'Server' %}</label> <select name="cluster" id="p_gw" class="pure-input-1-2"> <optgroup label="{% trans 'Country' %}"> {% for name, c in locations %} <option value="{{name}}"> {{c.country_name}} {% if c.message %} [ {{ c.message }} ] {% endif %} </option> {% endfor %} </optgroup> <option value="all">{% trans 'All (zip archive)' %}</option> </select> </div> <div class="pure-control-group"> <label for="p_gw">{% trans 'Server Port' %}</label> <select name="gw_port" id="gw_port" class="pure-input-1-2"> <option value="51820">51820 {% trans '(WireGuard default)' %}</option> <option value="53">53 {% trans '(standard DNS port)' %}</option> <option value="80">80 {% trans '(standard HTTP port)' %}</option> <option value="443">443 {% trans '(standard HTTPS port)' %}</option> </select> <p class="inputinfo"> {% trans 'You can try an alternative server port if 51820 is blocked.' %} </p> </div> <div class="pure-controls"> <label for="p_ipv6" class="pure-checkbox"> <input type="checkbox" name="use_ipv6" id="p_ipv6" checked /> {% trans 'Enable IPv6?' %} </label> <button type="submit" class="pure-button pure-button-primary"> <i class="fa fa-download" aria-hidden="true"></i> Download </button> <button onclick="showWgCode(this, 'config-form'); return false" class="pure-button pure-button-primary" id="qrbutton"> <i class="fa fa-qrcode" aria-hidden="true"></i> QR Code </button> </div> </fieldset> </form> {% endif %} <script src="{% static 'js/qrcode.min.js' %}"></script> <script> function showWgCode(event, formId) { const form = document.getElementById(formId); const gwSel = document.getElementById("p_gw"); const qrButton = document.getElementById("qrbutton"); var formData = new FormData(form); if (gwSel.value == "all") { alert("Select a single gateway to generate a QR Code"); return; } var urlParams = new URLSearchParams(formData).toString(); var req = new XMLHttpRequest(); var bg = document.createElement("div"); bg.classList.add("page-wg-shadow"); bg.onclick = function() { req.abort(); bg.remove(); }; document.body.appendChild(bg); var spinner = document.createElement("div"); spinner.classList.add("page-wg-shadow__loading"); bg.appendChild(spinner); var el = document.getElementById("qrcode"); req.addEventListener("load", function(e) { spinner.remove(); console.log(req.response); new QRCode(bg, { text: req.response, width: 256, height: 256, colorDark: "#000000", colorLight: "#ffffff", correctLevel: QRCode.CorrectLevel.M }); }); req.open(form.method, form.action + "?" + urlParams); req.send(); return false; } function deleteWgKey(event) { event.preventDefault(); event.target.parentNode.parentNode.submit(); } function toggleWgEdit(event, peer_id) { event.preventDefault(); const edit_class = 'page-wg-table__name--edit'; const tr = event.target.parentNode.parentNode.parentNode; const nameTd = tr.querySelector(".page-wg-table__name"); // press again to save (trigger form submit) if (tr.classList.contains(edit_class)) { const nameForm = nameTd.querySelector("form"); if (nameForm) { nameForm.submit(); } return; } function addField(form, key, value) { const f = document.createElement("input"); f.type = "hidden"; f.name = key; f.value = value; form.appendChild(f); } const currentName = nameTd.innerText; nameTd.innerHTML = ""; const nameForm = document.createElement("form"); nameForm.method = "post"; addField(nameForm, "peer_id", peer_id); addField(nameForm, "action", "set_name"); addField(nameForm, "csrfmiddlewaretoken", "{{ csrf_token }}"); const nameInput = document.createElement("input"); nameInput.type = "text"; nameInput.name = "name"; nameInput.value = currentName; nameInput.maxLength = 21; nameForm.appendChild(nameInput); const nameSubmit = document.createElement("input"); nameSubmit.type = "submit"; nameSubmit.value = "{% trans "Save" %}"; nameForm.appendChild(nameSubmit); nameTd.appendChild(nameForm); } function saveWgName(tr, name) { } </script> {% endblock %}