mirror of
https://github.com/eduardogsilva/wireguard_webadmin.git
synced 2025-06-28 01:07:03 +00:00
auto indent lines
This commit is contained in:
parent
f7917c478a
commit
d2aa1ef044
@ -1,10 +1,10 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block page_custom_head %}
|
{% block page_custom_head %}
|
||||||
<style>
|
<style>
|
||||||
.peer-extra-info {
|
.peer-extra-info {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
@ -244,208 +244,208 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var previousMeasurements = {};
|
var previousMeasurements = {};
|
||||||
var toastShownThisCycle = false;
|
var toastShownThisCycle = false;
|
||||||
|
|
||||||
const updateThroughput = (peerId, peerInfo) => {
|
const updateThroughput = (peerId, peerInfo) => {
|
||||||
const throughputElement = document.getElementById(`peer-throughput-${peerId}`);
|
const throughputElement = document.getElementById(`peer-throughput-${peerId}`);
|
||||||
const currentTime = Date.now() / 1000; // current timestamp in seconds
|
const currentTime = Date.now() / 1000; // current timestamp in seconds
|
||||||
let formattedThroughput = '';
|
let formattedThroughput = '';
|
||||||
|
|
||||||
if (previousMeasurements[peerId]) {
|
if (previousMeasurements[peerId]) {
|
||||||
const prev = previousMeasurements[peerId];
|
const prev = previousMeasurements[peerId];
|
||||||
const timeDiff = currentTime - prev.timestamp; // time difference in seconds
|
const timeDiff = currentTime - prev.timestamp; // time difference in seconds
|
||||||
|
|
||||||
// For peer perspective: download corresponds to tx and upload to rx
|
// For peer perspective: download corresponds to tx and upload to rx
|
||||||
let downloadDiff = peerInfo.transfer.tx - prev.transfer.tx;
|
let downloadDiff = peerInfo.transfer.tx - prev.transfer.tx;
|
||||||
let uploadDiff = peerInfo.transfer.rx - prev.transfer.rx;
|
let uploadDiff = peerInfo.transfer.rx - prev.transfer.rx;
|
||||||
|
|
||||||
// If counters have been reset (current < previous), show toast (only once per cycle)
|
// If counters have been reset (current < previous), show toast (only once per cycle)
|
||||||
if (downloadDiff < 0 || uploadDiff < 0) {
|
if (downloadDiff < 0 || uploadDiff < 0) {
|
||||||
if (!toastShownThisCycle) {
|
if (!toastShownThisCycle) {
|
||||||
$(document).Toasts('create', {
|
$(document).Toasts('create', {
|
||||||
class: 'bg-info',
|
class: 'bg-info',
|
||||||
title: 'info',
|
title: 'info',
|
||||||
body: 'Throughput discarded due to counter reset',
|
body: 'Throughput discarded due to counter reset',
|
||||||
delay: 10000,
|
delay: 10000,
|
||||||
autohide: true
|
autohide: true
|
||||||
});
|
});
|
||||||
toastShownThisCycle = true;
|
toastShownThisCycle = true;
|
||||||
|
}
|
||||||
|
downloadDiff = 0;
|
||||||
|
uploadDiff = 0;
|
||||||
}
|
}
|
||||||
downloadDiff = 0;
|
|
||||||
uploadDiff = 0;
|
// Calculate throughput in bytes per second
|
||||||
|
const downloadThroughput = downloadDiff / timeDiff;
|
||||||
|
const uploadThroughput = uploadDiff / timeDiff;
|
||||||
|
|
||||||
|
// Format throughput values (using convertBytes function)
|
||||||
|
let downloadDisplay = convertBytes(downloadThroughput) + '/s';
|
||||||
|
let uploadDisplay = convertBytes(uploadThroughput) + '/s';
|
||||||
|
// Threshold: 1mb (1 megabit/s = 125000 bytes per second)
|
||||||
|
const threshold = 125000;
|
||||||
|
|
||||||
|
if (downloadThroughput > threshold) {
|
||||||
|
downloadDisplay = `<strong>${downloadDisplay}</strong>`;
|
||||||
|
}
|
||||||
|
if (uploadThroughput > threshold) {
|
||||||
|
uploadDisplay = `<strong>${uploadDisplay}</strong>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
formattedThroughput = `<i class="fas fa-arrow-down"></i> ${downloadDisplay}, <i class="fas fa-arrow-up"></i> ${uploadDisplay}`;
|
||||||
|
throughputElement.innerHTML = formattedThroughput;
|
||||||
|
} else {
|
||||||
|
// First cycle: no previous measurement available.
|
||||||
|
formattedThroughput = `<i class="fas fa-arrow-down"></i> -.- B/s, <i class="fas fa-arrow-up"></i> -.- B/s`;
|
||||||
|
throughputElement.innerHTML = formattedThroughput;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate throughput in bytes per second
|
previousMeasurements[peerId] = {
|
||||||
const downloadThroughput = downloadDiff / timeDiff;
|
timestamp: currentTime,
|
||||||
const uploadThroughput = uploadDiff / timeDiff;
|
transfer: {
|
||||||
|
tx: peerInfo.transfer.tx,
|
||||||
|
rx: peerInfo.transfer.rx
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Format throughput values (using convertBytes function)
|
return formattedThroughput;
|
||||||
let downloadDisplay = convertBytes(downloadThroughput) + '/s';
|
|
||||||
let uploadDisplay = convertBytes(uploadThroughput) + '/s';
|
|
||||||
// Threshold: 1mb (1 megabit/s = 125000 bytes per second)
|
|
||||||
const threshold = 125000;
|
|
||||||
|
|
||||||
if (downloadThroughput > threshold) {
|
|
||||||
downloadDisplay = `<strong>${downloadDisplay}</strong>`;
|
|
||||||
}
|
|
||||||
if (uploadThroughput > threshold) {
|
|
||||||
uploadDisplay = `<strong>${uploadDisplay}</strong>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
formattedThroughput = `<i class="fas fa-arrow-down"></i> ${downloadDisplay}, <i class="fas fa-arrow-up"></i> ${uploadDisplay}`;
|
|
||||||
throughputElement.innerHTML = formattedThroughput;
|
|
||||||
} else {
|
|
||||||
// First cycle: no previous measurement available.
|
|
||||||
formattedThroughput = `<i class="fas fa-arrow-down"></i> -.- B/s, <i class="fas fa-arrow-up"></i> -.- B/s`;
|
|
||||||
throughputElement.innerHTML = formattedThroughput;
|
|
||||||
}
|
|
||||||
|
|
||||||
previousMeasurements[peerId] = {
|
|
||||||
timestamp: currentTime,
|
|
||||||
transfer: {
|
|
||||||
tx: peerInfo.transfer.tx,
|
|
||||||
rx: peerInfo.transfer.rx
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return formattedThroughput;
|
// Convert bytes to human-readable format with abbreviated units
|
||||||
};
|
const convertBytes = (bytes) => {
|
||||||
|
if (bytes === 0) return '0 B';
|
||||||
|
const k = 1024;
|
||||||
|
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||||
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||||
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
||||||
|
};
|
||||||
|
|
||||||
// Convert bytes to human-readable format with abbreviated units
|
// Fetch Wireguard status and update UI
|
||||||
const convertBytes = (bytes) => {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
if (bytes === 0) return '0 B';
|
const fetchWireguardStatus = async () => {
|
||||||
const k = 1024;
|
try {
|
||||||
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
const response = await fetch('/api/wireguard_status/');
|
||||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
let data = await response.json();
|
||||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fetch Wireguard status and update UI
|
// If latest-handshakes is 0, use the stored value
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
for (const [interfaceName, peers] of Object.entries(data)) {
|
||||||
const fetchWireguardStatus = async () => {
|
for (const [peerId, peerInfo] of Object.entries(peers)) {
|
||||||
try {
|
const peerElementId = `peer-stored-latest-handshake-${peerId}`;
|
||||||
const response = await fetch('/api/wireguard_status/');
|
const storedHandshakeElement = document.getElementById(peerElementId);
|
||||||
let data = await response.json();
|
if (peerInfo['latest-handshakes'] === '0' && storedHandshakeElement) {
|
||||||
|
peerInfo['latest-handshakes'] = storedHandshakeElement.textContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If latest-handshakes is 0, use the stored value
|
updateUI(data);
|
||||||
for (const [interfaceName, peers] of Object.entries(data)) {
|
} catch (error) {
|
||||||
for (const [peerId, peerInfo] of Object.entries(peers)) {
|
console.error('Error fetching Wireguard status:', error);
|
||||||
const peerElementId = `peer-stored-latest-handshake-${peerId}`;
|
}
|
||||||
const storedHandshakeElement = document.getElementById(peerElementId);
|
};
|
||||||
if (peerInfo['latest-handshakes'] === '0' && storedHandshakeElement) {
|
|
||||||
peerInfo['latest-handshakes'] = storedHandshakeElement.textContent;
|
fetchWireguardStatus();
|
||||||
|
setInterval(fetchWireguardStatus, {{ current_instance.peer_list_refresh_interval }} * 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateUI = (data) => {
|
||||||
|
// Reset the toast flag for this update cycle
|
||||||
|
toastShownThisCycle = false;
|
||||||
|
|
||||||
|
for (const [interfaceName, peers] of Object.entries(data)) {
|
||||||
|
for (const [peerId, peerInfo] of Object.entries(peers)) {
|
||||||
|
const peerDiv = document.getElementById(`peer-${peerId}`);
|
||||||
|
if (peerDiv) {
|
||||||
|
updatePeerInfo(peerDiv, peerId, peerInfo);
|
||||||
|
updateCalloutClass(peerDiv, peerInfo['latest-handshakes']);
|
||||||
|
// Calculate throughput and update the card
|
||||||
|
const throughputHTML = updateThroughput(peerId, peerInfo);
|
||||||
|
|
||||||
|
// If the modal is active for this peer, update its fields as well
|
||||||
|
const peerUuid = peerDiv.getAttribute("data-uuid");
|
||||||
|
if ($('#peerPreviewModal').is(':visible') && $('#peerPreviewModal').data('peer-uuid') === peerUuid) {
|
||||||
|
$('#peerThroughput').html(throughputHTML);
|
||||||
|
$('#peerTransfer').text(`${convertBytes(peerInfo.transfer.tx)} TX, ${convertBytes(peerInfo.transfer.rx)} RX`);
|
||||||
|
$('#peerHandshake').text(
|
||||||
|
peerInfo['latest-handshakes'] !== '0'
|
||||||
|
? new Date(parseInt(peerInfo['latest-handshakes']) * 1000).toLocaleString()
|
||||||
|
: '0'
|
||||||
|
);
|
||||||
|
$('#peerEndpoints').text(peerInfo.endpoints);
|
||||||
|
const allowedIpsModalElement = document.getElementById('peerAllowedIPs');
|
||||||
|
checkAllowedIps(allowedIpsModalElement, peerInfo['allowed-ips']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUI(data);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching Wireguard status:', error);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchWireguardStatus();
|
const updatePeerInfo = (peerDiv, peerId, peerInfo) => {
|
||||||
setInterval(fetchWireguardStatus, {{ current_instance.peer_list_refresh_interval }} * 1000);
|
const escapedPeerId = peerId.replace(/([!"#$%&'()*+,.\/:;<=>?@[\]^`{|}~])/g, '\\$1');
|
||||||
});
|
const transfer = peerDiv.querySelector(`#peer-transfer-${escapedPeerId}`);
|
||||||
|
const latestHandshake = peerDiv.querySelector(`#peer-latest-handshake-${escapedPeerId}`);
|
||||||
|
const endpoints = peerDiv.querySelector(`#peer-endpoints-${escapedPeerId}`);
|
||||||
|
const allowedIps = peerDiv.querySelector(`#peer-allowed-ips-${escapedPeerId}`);
|
||||||
|
|
||||||
const updateUI = (data) => {
|
transfer.textContent = `${convertBytes(peerInfo.transfer.tx)} TX, ${convertBytes(peerInfo.transfer.rx)} RX`;
|
||||||
// Reset the toast flag for this update cycle
|
latestHandshake.textContent = `${peerInfo['latest-handshakes'] !== '0' ? new Date(parseInt(peerInfo['latest-handshakes']) * 1000).toLocaleString() : '0'}`;
|
||||||
toastShownThisCycle = false;
|
endpoints.textContent = `${peerInfo.endpoints}`;
|
||||||
|
checkAllowedIps(allowedIps, peerInfo['allowed-ips']);
|
||||||
|
};
|
||||||
|
|
||||||
for (const [interfaceName, peers] of Object.entries(data)) {
|
const checkAllowedIps = (allowedIpsElement, allowedIpsApiResponse) => {
|
||||||
for (const [peerId, peerInfo] of Object.entries(peers)) {
|
const apiIps = allowedIpsApiResponse[0].split(' ');
|
||||||
const peerDiv = document.getElementById(`peer-${peerId}`);
|
const htmlIpsText = allowedIpsElement.textContent.trim();
|
||||||
if (peerDiv) {
|
const htmlIpsArray = htmlIpsText.match(/\b(?:\d{1,3}\.){3}\d{1,3}\/\d{1,2}\b/g) || [];
|
||||||
updatePeerInfo(peerDiv, peerId, peerInfo);
|
|
||||||
updateCalloutClass(peerDiv, peerInfo['latest-handshakes']);
|
|
||||||
// Calculate throughput and update the card
|
|
||||||
const throughputHTML = updateThroughput(peerId, peerInfo);
|
|
||||||
|
|
||||||
// If the modal is active for this peer, update its fields as well
|
allowedIpsElement.innerHTML = '';
|
||||||
const peerUuid = peerDiv.getAttribute("data-uuid");
|
let showExtraInfo = false;
|
||||||
if ($('#peerPreviewModal').is(':visible') && $('#peerPreviewModal').data('peer-uuid') === peerUuid) {
|
|
||||||
$('#peerThroughput').html(throughputHTML);
|
htmlIpsArray.forEach((ip, index, array) => {
|
||||||
$('#peerTransfer').text(`${convertBytes(peerInfo.transfer.tx)} TX, ${convertBytes(peerInfo.transfer.rx)} RX`);
|
const ipSpan = document.createElement('span');
|
||||||
$('#peerHandshake').text(
|
ipSpan.textContent = ip;
|
||||||
peerInfo['latest-handshakes'] !== '0'
|
allowedIpsElement.appendChild(ipSpan);
|
||||||
? new Date(parseInt(peerInfo['latest-handshakes']) * 1000).toLocaleString()
|
|
||||||
: '0'
|
if (!apiIps.includes(ip)) {
|
||||||
);
|
ipSpan.style.color = 'red';
|
||||||
$('#peerEndpoints').text(peerInfo.endpoints);
|
ipSpan.style.textDecoration = 'underline';
|
||||||
const allowedIpsModalElement = document.getElementById('peerAllowedIPs');
|
ipSpan.title = 'This address does not appear in the wg show command output, likely indicating that another peer has an IP overlapping this network or that the configuration file is outdated.';
|
||||||
checkAllowedIps(allowedIpsModalElement, peerInfo['allowed-ips']);
|
showExtraInfo = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (index < array.length - 1) {
|
||||||
|
allowedIpsElement.appendChild(document.createTextNode(', '));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (showExtraInfo) {
|
||||||
|
const extraInfoContainerId = allowedIpsElement.id.replace('peer-allowed-ips-', 'peer-extra-info-allowed-ips-');
|
||||||
|
const extraInfoContainer = document.getElementById(extraInfoContainerId);
|
||||||
|
if (extraInfoContainer) {
|
||||||
|
extraInfoContainer.style.display = 'block';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
const updatePeerInfo = (peerDiv, peerId, peerInfo) => {
|
|
||||||
const escapedPeerId = peerId.replace(/([!"#$%&'()*+,.\/:;<=>?@[\]^`{|}~])/g, '\\$1');
|
|
||||||
const transfer = peerDiv.querySelector(`#peer-transfer-${escapedPeerId}`);
|
|
||||||
const latestHandshake = peerDiv.querySelector(`#peer-latest-handshake-${escapedPeerId}`);
|
|
||||||
const endpoints = peerDiv.querySelector(`#peer-endpoints-${escapedPeerId}`);
|
|
||||||
const allowedIps = peerDiv.querySelector(`#peer-allowed-ips-${escapedPeerId}`);
|
|
||||||
|
|
||||||
transfer.textContent = `${convertBytes(peerInfo.transfer.tx)} TX, ${convertBytes(peerInfo.transfer.rx)} RX`;
|
|
||||||
latestHandshake.textContent = `${peerInfo['latest-handshakes'] !== '0' ? new Date(parseInt(peerInfo['latest-handshakes']) * 1000).toLocaleString() : '0'}`;
|
|
||||||
endpoints.textContent = `${peerInfo.endpoints}`;
|
|
||||||
checkAllowedIps(allowedIps, peerInfo['allowed-ips']);
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkAllowedIps = (allowedIpsElement, allowedIpsApiResponse) => {
|
|
||||||
const apiIps = allowedIpsApiResponse[0].split(' ');
|
|
||||||
const htmlIpsText = allowedIpsElement.textContent.trim();
|
|
||||||
const htmlIpsArray = htmlIpsText.match(/\b(?:\d{1,3}\.){3}\d{1,3}\/\d{1,2}\b/g) || [];
|
|
||||||
|
|
||||||
allowedIpsElement.innerHTML = '';
|
|
||||||
let showExtraInfo = false;
|
|
||||||
|
|
||||||
htmlIpsArray.forEach((ip, index, array) => {
|
|
||||||
const ipSpan = document.createElement('span');
|
|
||||||
ipSpan.textContent = ip;
|
|
||||||
allowedIpsElement.appendChild(ipSpan);
|
|
||||||
|
|
||||||
if (!apiIps.includes(ip)) {
|
|
||||||
ipSpan.style.color = 'red';
|
|
||||||
ipSpan.style.textDecoration = 'underline';
|
|
||||||
ipSpan.title = 'This address does not appear in the wg show command output, likely indicating that another peer has an IP overlapping this network or that the configuration file is outdated.';
|
|
||||||
showExtraInfo = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index < array.length - 1) {
|
|
||||||
allowedIpsElement.appendChild(document.createTextNode(', '));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (showExtraInfo) {
|
|
||||||
const extraInfoContainerId = allowedIpsElement.id.replace('peer-allowed-ips-', 'peer-extra-info-allowed-ips-');
|
|
||||||
const extraInfoContainer = document.getElementById(extraInfoContainerId);
|
|
||||||
if (extraInfoContainer) {
|
|
||||||
extraInfoContainer.style.display = 'block';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const updateCalloutClass = (peerDiv, latestHandshake) => {
|
const updateCalloutClass = (peerDiv, latestHandshake) => {
|
||||||
const calloutDiv = peerDiv.querySelector('.callout');
|
const calloutDiv = peerDiv.querySelector('.callout');
|
||||||
calloutDiv.classList.remove('callout-success', 'callout-info', 'callout-warning', 'callout-danger');
|
calloutDiv.classList.remove('callout-success', 'callout-info', 'callout-warning', 'callout-danger');
|
||||||
const handshakeAge = Date.now() / 1000 - parseInt(latestHandshake);
|
const handshakeAge = Date.now() / 1000 - parseInt(latestHandshake);
|
||||||
|
|
||||||
if (latestHandshake === '0') {
|
if (latestHandshake === '0') {
|
||||||
calloutDiv.classList.add('callout-danger');
|
calloutDiv.classList.add('callout-danger');
|
||||||
} else if (handshakeAge < 600) {
|
} else if (handshakeAge < 600) {
|
||||||
calloutDiv.classList.add('callout-success');
|
calloutDiv.classList.add('callout-success');
|
||||||
} else if (handshakeAge < 1800) {
|
} else if (handshakeAge < 1800) {
|
||||||
calloutDiv.classList.add('callout-info');
|
calloutDiv.classList.add('callout-info');
|
||||||
} else if (handshakeAge < 21600) {
|
} else if (handshakeAge < 21600) {
|
||||||
calloutDiv.classList.add('callout-warning');
|
calloutDiv.classList.add('callout-warning');
|
||||||
}
|
}
|
||||||
calloutDiv.style.transition = 'all 5s';
|
calloutDiv.style.transition = 'all 5s';
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user