2024-02-14 16:36:01 -03:00
{% extends "base.html" %}
2025-04-15 14:22:40 -03:00
{% load i18n %}
2024-02-14 16:36:01 -03:00
{% block content %}
< div class = "card card-primary card-outline" >
< div class = "card-header" >
2025-04-15 14:22:40 -03:00
< h3 class = "card-title" > {% trans 'Peer Configuration' %}</ h3 >
2024-02-14 16:36:01 -03:00
</ div >
< form method = "post" >
{% csrf_token %}
< div class = "card-body row" >
< div class = "col-lg-6" >
<!-- Name -->
< div class = "form-group" >
< label for = "{{ form.name.id_for_label }}" > {{ form.name.label }}</ label >
2025-04-15 14:22:40 -03:00
< input type = "text" class = "form-control" id = "{{ form.name.id_for_label }}" name = "{{ form.name.html_name }}" placeholder = "{% trans 'Enter Name' %}" value = "{{ form.name.value|default_if_none:'' }}" >
2024-02-14 16:36:01 -03:00
</ div >
<!-- Persistent Keepalive -->
< div class = "form-group" >
< label for = "{{ form.persistent_keepalive.id_for_label }}" > {{ form.persistent_keepalive.label }}</ label >
2025-04-15 14:22:40 -03:00
< input type = "number" class = "form-control" id = "{{ form.persistent_keepalive.id_for_label }}" name = "{{ form.persistent_keepalive.html_name }}" placeholder = "{% trans 'Persistent Keepalive' %}" value = "{{ form.persistent_keepalive.value|default_if_none:'' }}" required >
2024-02-14 16:36:01 -03:00
</ div >
<!-- Public Key -->
< div class = "form-group" >
< label for = "{{ form.public_key.id_for_label }}" > {{ form.public_key.label }}</ label >
2025-04-15 14:22:40 -03:00
< input type = "text" class = "form-control" id = "{{ form.public_key.id_for_label }}" name = "{{ form.public_key.html_name }}" placeholder = "{% trans 'Public Key' %}" value = "{{ form.public_key.value|default_if_none:'' }}" required >
2024-02-14 16:36:01 -03:00
</ div >
<!-- Private Key -->
< div class = "form-group" >
< label for = "{{ form.private_key.id_for_label }}" > {{ form.private_key.label }}</ label >
2024-03-08 12:32:05 -03:00
< div class = "input-group" >
2025-08-12 11:11:53 -03:00
< input type = "password" class = "form-control" id = "{{ form.private_key.id_for_label }}" name = "{{ form.private_key.html_name }}" placeholder = "{% trans 'Private Key' %}" value = "{{ form.private_key.value|default_if_none:'' }}" >
2024-03-08 12:32:05 -03:00
< div class = "input-group-append" >
< button class = "btn btn-outline-secondary toggle-password" type = "button" >< i class = "fas fa-eye" ></ i ></ button >
</ div >
</ div >
2024-02-14 16:36:01 -03:00
</ div >
<!-- Pre-Shared Key -->
< div class = "form-group" >
< label for = "{{ form.pre_shared_key.id_for_label }}" > {{ form.pre_shared_key.label }}</ label >
2025-04-15 14:22:40 -03:00
< input type = "text" class = "form-control" id = "{{ form.pre_shared_key.id_for_label }}" name = "{{ form.pre_shared_key.html_name }}" placeholder = "{% trans 'Pre-Shared Key' %}" value = "{{ form.pre_shared_key.value|default_if_none:'' }}" required >
2024-02-14 16:36:01 -03:00
</ div >
</ div >
< div class = "col-lg-6" >
2025-02-21 22:18:26 -03:00
< div class = "row mt-3" >
< div class = "col-lg-12" >
< div class = "d-flex justify-content-between align-items-center " >
2025-02-21 21:59:30 -03:00
< label >
< i class = "fas fa-chart-area" ></ i >
2025-04-15 14:22:40 -03:00
{% trans 'Peer Traffic' %}
2025-02-21 21:59:30 -03:00
</ label >
2025-02-21 22:18:26 -03:00
< div class = "btn-group" role = "group" aria-label = "Graph interval" >
< a href = "#" data-period = "1h" class = "btn btn-outline-primary btn-xs" > 1h</ a >
< a href = "#" data-period = "3h" class = "btn btn-outline-primary btn-xs" > 3h</ a >
< a href = "#" data-period = "6h" class = "btn btn-outline-primary btn-xs" > 6h</ a >
2025-02-22 09:14:59 -03:00
< a href = "#" data-period = "1d" class = "btn btn-outline-primary btn-xs" > 1d</ a >
2025-02-21 22:18:26 -03:00
< a href = "#" data-period = "7d" class = "btn btn-outline-primary btn-xs" > 7d</ a >
< a href = "#" data-period = "30d" class = "btn btn-outline-primary btn-xs" > 1m</ a >
< a href = "#" data-period = "90d" class = "btn btn-outline-primary btn-xs" > 3m</ a >
< a href = "#" data-period = "180d" class = "btn btn-outline-primary btn-xs" > 6m</ a >
< a href = "#" data-period = "365d" class = "btn btn-outline-primary btn-xs" > 1y</ a >
</ div >
2025-02-21 16:28:53 -03:00
</ div >
2025-02-21 21:59:30 -03:00
< center >
2025-04-15 14:22:40 -03:00
< img id = "graphImg" src = "/rrd/graph/?peer={{ current_peer.uuid }}{% if request.GET.period %}&period={{ request.GET.period }}{% endif %}" class = "img-fluid" alt = "{% trans 'No traffic history, please wait a few minutes' %}" onerror = "this.onerror=null; this.style.display='none'; this.insertAdjacentHTML('afterend', this.alt);" >
2025-02-21 21:59:30 -03:00
</ center >
2025-02-21 22:18:26 -03:00
< div class = "d-flex justify-content-between align-items-center border-bottom mb-3" style = "padding-top: 16px;" ></ div >
2025-02-21 21:59:30 -03:00
</ div >
</ div >
2025-02-21 22:18:26 -03:00
2024-03-09 16:02:48 -03:00
< div class = "row" >
< div class = "col-md-12" >
< div class = "d-flex justify-content-between align-items-center" >
< label >
2025-04-15 14:22:40 -03:00
< i class = "fas fa-info-circle" title = "{% trans 'AllowedIPs at Peer section of wg' %}{{ current_peer.wireguard_instance.instance_id }}.conf" ></ i >
{% trans 'Peer IP Addresses and networks' %}
2024-03-09 16:02:48 -03:00
</ label >
2025-04-15 14:22:40 -03:00
< a class = "btn btn-outline-primary btn-xs" href = "/peer/manage_ip_address/?peer={{ current_peer.uuid }}&config=server" > {% trans 'Add IP Address' %}</ a >
2024-03-09 16:02:48 -03:00
</ div >
{% for ip_address in peer_ip_list %}
< div class = "d-flex justify-content-between align-items-center border-bottom mb-3" >
< p >
< a href = "/peer/manage_ip_address/?ip={{ ip_address.uuid }}" >
< i class = "fas fa-network-wired" ></ i >
{{ ip_address}}
</ a >
</ p >
< p class = "d-flex flex-column text-right small" >
{% if ip_address.priority == 0 %}
2025-04-15 14:22:40 -03:00
{% trans 'Main ip address' %}
2024-03-09 16:02:48 -03:00
{% else %}
2025-04-15 14:22:40 -03:00
{% trans 'Priority' %}: {{ ip_address.priority }}
2024-03-09 16:02:48 -03:00
{% endif %}
</ p >
</ div >
{% endfor %}
</ div >
</ div >
< div class = "row" >
< div class = "col-md-12" >
< div class = "d-flex justify-content-between align-items-center" >
< label >
< i class = "fas fa-info-circle" title = "AllowedIPs at client configuration file" ></ i >
2025-04-15 14:22:40 -03:00
{% trans 'Client Routing Configuration' %}
2024-03-09 16:02:48 -03:00
</ label >
2025-04-15 14:22:40 -03:00
< a class = "btn btn-outline-primary btn-xs" href = "/peer/manage_ip_address/?peer={{ current_peer.uuid }}&config=client" > {% trans 'Add Client route' %}</ a >
2024-03-09 16:02:48 -03:00
</ div >
< div class = "d-flex justify-content-between align-items-center border-bottom mb-3" >
< p >
< a href = "#"
{% if peer_client_ip_list %}
2025-04-15 14:22:40 -03:00
onclick = "alert('{% trans 'The client is not configured to use the VPN as the default gateway.\n\nOnly the specific networks listed below are routed through the VPN.\n\nNote: These routes are not automatically pushed to the client. You will need to manually update the client configuration file to reflect these settings.' %}');"
2024-03-09 16:02:48 -03:00
style = "text-decoration: line-through;"
{% else %}
2025-04-15 14:22:40 -03:00
onclick = "alert('{% trans 'The client is configured to use the VPN as the default gateway. \n\nThis setting routes all client internet traffic through the VPN, enhancing privacy and security across all connections.' %}');"
2024-03-09 16:02:48 -03:00
{% endif %}
>
< i class = "fas fa-network-wired" ></ i >
0.0.0.0/0, ::/0
</ a >
</ p >
< p class = "d-flex flex-column text-right small" >
2025-04-15 14:22:40 -03:00
{% trans 'default route' %}
2024-03-09 16:02:48 -03:00
</ p >
</ div >
{% for ip_address in peer_client_ip_list %}
< div class = "d-flex justify-content-between align-items-center border-bottom mb-3" >
< p >
< a href = "/peer/manage_ip_address/?ip={{ ip_address.uuid }}" >
< i class = "fas fa-network-wired" ></ i >
{{ ip_address}}
</ a >
</ p >
< p class = "d-flex flex-column text-right small" >
{% if ip_address.priority == 0 %}
2025-04-15 14:22:40 -03:00
{% trans 'Main ip address' %}
2024-03-09 16:02:48 -03:00
{% else %}
2025-04-15 14:22:40 -03:00
{% trans 'Priority' %}: {{ ip_address.priority }}
2024-03-09 16:02:48 -03:00
{% endif %}
</ p >
</ div >
{% endfor %}
</ div >
</ div >
2024-02-14 16:36:01 -03:00
</ div >
</ div >
< div class = "card-footer" >
2025-04-15 14:22:40 -03:00
< button type = "submit" class = "btn btn-primary" > {% trans 'Save' %}</ button >
< a href = "/peer/manage_ip_address/?peer={{ current_peer.uuid }}" class = "btn btn-outline-primary" > {% trans 'Add IP Address' %}</ a >
< a class = "btn btn-outline-secondary" href = "/peer/list/?uuid={{ current_peer.wireguard_instance.uuid }}#peer-{{ current_peer.public_key }}" > {% trans 'Back' %}</ a >
< a href = 'javascript:void(0)' class = 'btn btn-outline-danger' data-command = 'delete' onclick = 'openCommandDialog(this)' > {% trans 'Delete Peer' %}</ a >
2024-02-14 16:36:01 -03:00
</ div >
</ form >
</ div >
{% endblock %}
{% block custom_page_scripts %}
< script >
document . addEventListener ( 'DOMContentLoaded' , function () {
var alertShown = false ;
var fieldsToWatch = [ 'id_public_key' , 'id_pre_shared_key' , 'id_private_key' ];
function showAlert () {
if ( ! alertShown ) {
$ ( document ). Toasts ( 'create' , {
class : 'bg-warning' ,
2025-04-15 14:22:40 -03:00
title : '{% trans ' Action Required ! ' %}' ,
body : '{% trans ' When manually updating the "Public Key" , "Pre-Shared Key" , or "Private Key" , please ensure the configuration is correct . ' %}' ,
2024-02-14 16:36:01 -03:00
});
alertShown = true ;
}
}
fieldsToWatch . forEach ( function ( fieldId ) {
var field = document . getElementById ( fieldId );
if ( field ) {
field . addEventListener ( 'change' , showAlert );
}
});
});
</ script >
< script >
function openCommandDialog ( element ) {
var command = element . getAttribute ( 'data-command' );
2025-04-15 14:22:40 -03:00
var confirmation = prompt ( "{% trans 'Please type \"delete\" to remove peer configuration.' %}" );
2024-02-14 16:36:01 -03:00
if ( confirmation ) {
var url = "?peer={{ current_peer.uuid }}&action=delete&confirmation=" + encodeURIComponent ( confirmation );
window . location . href = url ;
}
}
</ script >
2024-03-08 12:32:05 -03:00
< script >
document . addEventListener ( 'DOMContentLoaded' , function () {
document . querySelector ( '.toggle-password' ). addEventListener ( 'click' , function () {
let passwordInput = document . getElementById ( '{{ form.private_key.id_for_label }}' );
let passStatus = passwordInput . getAttribute ( 'type' ) === 'password' ;
passwordInput . setAttribute ( 'type' , passStatus ? 'text' : 'password' );
this . innerHTML = passStatus ? '<i class="fas fa-eye-slash"></i>' : '<i class="fas fa-eye"></i>' ;
});
document . getElementById ( '{{ form.private_key.id_for_label }}' ). addEventListener ( 'keypress' , function () {
this . setAttribute ( 'type' , 'text' );
});
});
</ script >
2024-02-14 16:36:01 -03:00
2025-02-21 21:59:30 -03:00
< script >
document . addEventListener ( 'DOMContentLoaded' , function (){
var buttons = document . querySelectorAll ( '.btn-group a' );
buttons . forEach ( function ( button ){
button . addEventListener ( 'click' , function ( e ){
e . preventDefault ();
var period = this . getAttribute ( 'data-period' );
var newSrc = '/rrd/graph/?peer={{ current_peer.uuid }}&period=' + period ;
var imgElement = document . getElementById ( 'graphImg' );
if ( imgElement ){
imgElement . setAttribute ( 'src' , newSrc );
}
});
});
});
</ script >
2025-08-12 11:11:53 -03:00
< script >
document . addEventListener ( 'DOMContentLoaded' , function () {
var form = document . querySelector ( 'form[method="post"]' );
if ( form ) {
form . addEventListener ( 'submit' , function ( e ) {
var privateKeyField = document . getElementById ( '{{ form.private_key.id_for_label }}' );
if ( privateKeyField && privateKeyField . value . trim () === '' ) {
var confirmed = confirm ( '{% trans "The private key is empty. The peer’ s configuration file and QR code will be generated without the private key.\n It must be inserted manually when importing.\n\n Do you want to continue?" %}' );
if ( ! confirmed ) {
e . preventDefault ();
return false ;
}
}
});
}
});
</ script >
2024-03-08 12:32:05 -03:00
2024-02-14 16:36:01 -03:00
{% endblock %}