Remove old files
This commit is contained in:
parent
5d2e77dd42
commit
0cd7cc2730
17 changed files with 0 additions and 994 deletions
|
|
@ -1,2 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="18" fill="currentColor" viewBox="0 0 10 18">
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 110 B |
|
|
@ -1,30 +0,0 @@
|
|||
/* Sort button */
|
||||
.my-btn {
|
||||
height: 100%;
|
||||
background-color: #00000000;
|
||||
color: var(--bs-primary);
|
||||
text-align: center;
|
||||
}
|
||||
.my-btn:hover {
|
||||
background-color: #0000001a;
|
||||
}
|
||||
|
||||
/* History box */
|
||||
.my-box-on::before, .my-box-off::before {
|
||||
content: url(/fs/public/box.svg);
|
||||
border-left: thin solid black;
|
||||
}
|
||||
.my-box-on {
|
||||
background-color: var(--bs-success);
|
||||
}
|
||||
.my-box-off {
|
||||
background-color: var(--bs-gray-500);
|
||||
}
|
||||
.my-box-on:hover, .my-box-off:hover {
|
||||
background-color: #0000001a;
|
||||
}
|
||||
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
let oldFilter = '';
|
||||
let bkpArray;
|
||||
|
||||
function filterFunc(field, value) {
|
||||
|
||||
if (oldFilter == field) {
|
||||
addrsArray = bkpArray;
|
||||
}
|
||||
|
||||
switch (field) {
|
||||
case 'iface':
|
||||
addrsArray = addrsArray.filter((item) => item.Iface == value);
|
||||
break;
|
||||
case 'known':
|
||||
addrsArray = addrsArray.filter((item) => item.Known == value);
|
||||
break;
|
||||
case 'line':
|
||||
addrsArray = addrsArray.filter((item) => item.Now == value);
|
||||
break;
|
||||
default:
|
||||
console.log("Filter error");
|
||||
}
|
||||
|
||||
oldFilter = field;
|
||||
|
||||
displayArrayData(addrsArray);
|
||||
}
|
||||
|
||||
function resetFilter() {
|
||||
addrsArray = bkpArray;
|
||||
displayArrayData(addrsArray);
|
||||
}
|
||||
|
||||
function searchFunc() {
|
||||
const s = document.getElementById('search').value;
|
||||
|
||||
if (s != "") {
|
||||
|
||||
const sl = s.toLowerCase();
|
||||
|
||||
let newArray = [];
|
||||
|
||||
for (let item of addrsArray) {
|
||||
|
||||
if (searchItem(item, sl)) {
|
||||
newArray.push(item);
|
||||
}
|
||||
}
|
||||
addrsArray = newArray;
|
||||
} else {
|
||||
addrsArray = bkpArray;
|
||||
}
|
||||
|
||||
displayArrayData(addrsArray);
|
||||
}
|
||||
|
||||
function searchItem(item, sl) {
|
||||
|
||||
const name = item.Name.toLowerCase();
|
||||
const hw = item.Hw.toLowerCase();
|
||||
const mac = item.Mac.toLowerCase();
|
||||
|
||||
if ((name.includes(sl)) || (item.Iface.includes(sl)) || (item.IP.includes(sl)) || (mac.includes(sl)) || (hw.includes(sl)) || (item.Date.includes(sl))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
|
||||
function getHistHTML(hist) {
|
||||
|
||||
let html = '', col, title;
|
||||
|
||||
for (let h of hist) {
|
||||
if (h.Now != 0) {
|
||||
col = `my-box-on`;
|
||||
} else {
|
||||
col = `my-box-off`;
|
||||
}
|
||||
title = `title="Date: ${h.Date}\nIface: ${h.Iface}\nIP: ${h.IP}\nKnown: ${h.Known}"`;
|
||||
|
||||
html = html + `<i ${title} class="${col}"></i>`;
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
function sortHistByDate(hist) {
|
||||
|
||||
hist.sort((a, b) => (a.Date < b.Date ? 1 : -1));
|
||||
|
||||
return hist;
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
let show = 500;
|
||||
let addrsArray;
|
||||
|
||||
loadAddrs();
|
||||
|
||||
async function loadAddrs() {
|
||||
|
||||
const n = localStorage.getItem("histShow");
|
||||
if (n != null) {
|
||||
show = n;
|
||||
}
|
||||
|
||||
const url = '/api/all';
|
||||
addrsArray = await (await fetch(url)).json();
|
||||
|
||||
loadHistory();
|
||||
}
|
||||
|
||||
async function loadHistory() {
|
||||
|
||||
let tr, td, url, hist;
|
||||
let i = 0;
|
||||
|
||||
document.getElementById('showHist').innerHTML = '';
|
||||
|
||||
for (let a of addrsArray) {
|
||||
url = '/api/history/'+a.Mac;
|
||||
hist = await (await fetch(url)).json();
|
||||
|
||||
if (hist != null) {
|
||||
hist = sortHistByDate(hist);
|
||||
|
||||
if (show > 0) {
|
||||
hist = hist.slice(0, show);
|
||||
}
|
||||
|
||||
td = getHistHTML(hist); // hist-html.js
|
||||
}
|
||||
|
||||
i = i + 1;
|
||||
|
||||
tr = `
|
||||
<tr>
|
||||
<td style="opacity: 45%;">${i}.</td>
|
||||
<td>
|
||||
<p>${a.Name}</p>
|
||||
<p><a href="http://${a.IP}" target="_blank">${a.IP}</a></p>
|
||||
<p><a href="/host/${a.ID}">${a.Mac}</a></p>
|
||||
</td>
|
||||
<td>${td}</td>
|
||||
</tr>`;
|
||||
|
||||
document.getElementById('showHist').insertAdjacentHTML('beforeend', tr);
|
||||
}
|
||||
}
|
||||
|
||||
function showHist(n) {
|
||||
show = n;
|
||||
localStorage.setItem("histShow", show);
|
||||
loadHistory();
|
||||
}
|
||||
|
||||
function manualShow() {
|
||||
const n = document.getElementById('man-show').value;
|
||||
showHist(n);
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
let stop = false;
|
||||
|
||||
function stopScan() {
|
||||
stop = true;
|
||||
}
|
||||
|
||||
async function scanAddr() {
|
||||
const addr = document.getElementById("hostIP").value;
|
||||
let begin = document.getElementById("begin").value;
|
||||
let end = document.getElementById("end").value;
|
||||
|
||||
document.getElementById('foundPorts').innerHTML = "";
|
||||
|
||||
if (begin == "") {
|
||||
begin = 1
|
||||
}
|
||||
if (end == "") {
|
||||
end = 65535
|
||||
}
|
||||
let portOpen = false;
|
||||
stop = false;
|
||||
found = 0;
|
||||
|
||||
document.getElementById('stopBtn').style.visibility = "visible";
|
||||
|
||||
for (let i = begin ; i <= end; i++) {
|
||||
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
if (found > 9) {
|
||||
found = 0;
|
||||
document.getElementById('foundPorts').insertAdjacentHTML('beforeend', '<br>');
|
||||
}
|
||||
|
||||
let url = '/api/port/'+addr+'/'+i;
|
||||
portOpen = await (await fetch(url)).json();
|
||||
|
||||
document.getElementById("curPort").innerHTML = "Scanning port "+i;
|
||||
|
||||
if (portOpen) {
|
||||
found = found + 1;
|
||||
let html = genHTML(addr, i);
|
||||
document.getElementById('foundPorts').insertAdjacentHTML('beforeend', html);
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('stopBtn').style.visibility = "hidden";
|
||||
}
|
||||
|
||||
function genHTML(addr, port) {
|
||||
html = `<a href="http://${addr}:${port}" target="_blank">${port}</a> `;
|
||||
return html;
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
let show = 500;
|
||||
let mac;
|
||||
|
||||
async function delHost(id) {
|
||||
|
||||
const url = '/api/host/del/'+id;
|
||||
|
||||
await fetch(url);
|
||||
|
||||
window.location.href = '/';
|
||||
}
|
||||
|
||||
async function loadHistory(m) {
|
||||
|
||||
const n = localStorage.getItem("hostShow");
|
||||
if (n != null) {
|
||||
show = n;
|
||||
}
|
||||
|
||||
mac = m;
|
||||
const url = '/api/history/'+mac;
|
||||
|
||||
let hist = await (await fetch(url)).json();
|
||||
hist = sortHistByDate(hist);
|
||||
if (show > 0) {
|
||||
hist = hist.slice(0, show);
|
||||
}
|
||||
|
||||
// console.log("HIST", hist);
|
||||
displayHistory(hist);
|
||||
}
|
||||
|
||||
function displayHistory(hist) {
|
||||
|
||||
document.getElementById('showHist').innerHTML = getHistHTML(hist); // hist-html.js
|
||||
}
|
||||
|
||||
function showHist(n) {
|
||||
show = n;
|
||||
localStorage.setItem("hostShow", show);
|
||||
loadHistory(mac);
|
||||
}
|
||||
|
||||
function manualShow() {
|
||||
const n = document.getElementById('man-show').value;
|
||||
showHist(n);
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
let addrsArray = {};
|
||||
let edit = "0";
|
||||
|
||||
loadAddrs();
|
||||
|
||||
function createHTML(addr, i) {
|
||||
let now = `<i class="bi bi-circle-fill" style="color:var(--bs-gray-500);"></i>`;
|
||||
if (addr.Now == 1) {
|
||||
now = `<i class="bi bi-check-circle-fill" style="color:var(--bs-success);"></i>`;
|
||||
}
|
||||
|
||||
let known = '';
|
||||
if (addr.Known == 1) {
|
||||
known = `checked`;
|
||||
}
|
||||
|
||||
// Needs option to use value in js
|
||||
let name = `<data id="name${addr.ID}" value="${addr.Name}">${addr.Name}</data>`;
|
||||
if (edit == 1) {
|
||||
name = `<input id="name${addr.ID}" onchange="editForm(${addr.ID},'')" type="text" class="form-control" value="${addr.Name}">`;
|
||||
}
|
||||
|
||||
let html = `
|
||||
<tr>
|
||||
<td style="opacity: 45%;">${i}.</td>
|
||||
<td>${name}</td>
|
||||
<td>${addr.Iface}</td>
|
||||
<td>
|
||||
<a href="http://${addr.IP}" target="_blank">${addr.IP}</a>
|
||||
</td>
|
||||
<td><a href="/host/${addr.ID}">${addr.Mac}</a></td>
|
||||
<td>${addr.Hw}</td>
|
||||
<td>${addr.Date}</td>
|
||||
<td>
|
||||
<div class="form-check form-switch">
|
||||
<input onclick="editForm(${addr.ID}, 'toggle')" class="form-check-input" type="checkbox" ${known}>
|
||||
</div>
|
||||
</td>
|
||||
<td>${now}</td>
|
||||
</tr>
|
||||
`;
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
async function loadAddrs() {
|
||||
|
||||
const url = '/api/all';
|
||||
addrsArray = await (await fetch(url)).json();
|
||||
bkpArray = addrsArray;
|
||||
|
||||
field = localStorage.getItem("sortField");
|
||||
down = JSON.parse(localStorage.getItem("sortDown"));
|
||||
|
||||
checkNotEmpty(addrsArray);
|
||||
}
|
||||
|
||||
function sortBy(f) {
|
||||
field = f;
|
||||
if (field != oldField) {
|
||||
oldField = field;
|
||||
down = !down;
|
||||
} else {
|
||||
oldField = '';
|
||||
down = !down;
|
||||
}
|
||||
|
||||
localStorage.setItem("sortDown", down);
|
||||
localStorage.setItem("sortField", field);
|
||||
checkNotEmpty(addrsArray);
|
||||
}
|
||||
|
||||
function editClick() {
|
||||
|
||||
edit = 1 - edit;
|
||||
loadAddrs();
|
||||
}
|
||||
|
||||
function checkNotEmpty(someArray) {
|
||||
|
||||
if (someArray.length > 0) {
|
||||
if ((field != null) && (down != null)) {
|
||||
sortByAny(someArray);
|
||||
} else {
|
||||
displayArrayData(someArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function editForm(id, known) {
|
||||
|
||||
const name = document.getElementById("name"+id).value;
|
||||
const url = '/api/edit/'+id+'/'+name+'/'+known;
|
||||
|
||||
// console.log(url);
|
||||
|
||||
await fetch(url);
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
async function testNotifications() {
|
||||
|
||||
const url = '/api/notify_test';
|
||||
await fetch(url);
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
let ref = false;
|
||||
let refInterval;
|
||||
|
||||
autoRefresh();
|
||||
|
||||
function toggleRefresh() {
|
||||
ref = !ref;
|
||||
|
||||
localStorage.setItem("refAuto", ref);
|
||||
|
||||
autoRefresh();
|
||||
}
|
||||
|
||||
function autoRefresh() {
|
||||
|
||||
ref = JSON.parse(localStorage.getItem("refAuto"));
|
||||
document.getElementById("ref").checked = ref;
|
||||
|
||||
if (ref) {
|
||||
const timeout = document.getElementById("ref-timeout").value;
|
||||
console.log("Refresh timeout", timeout);
|
||||
refInterval = setInterval(loadAddrs, timeout * 1000);
|
||||
} else {
|
||||
clearInterval(refInterval);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
let oldField = '';
|
||||
let field = '';
|
||||
let down = false;
|
||||
|
||||
function displayArrayData(someArray) {
|
||||
document.getElementById('tBody').innerHTML = "";
|
||||
|
||||
let i = 0;
|
||||
for (let item of someArray){
|
||||
i = i + 1;
|
||||
html = createHTML(item, i);
|
||||
document.getElementById('tBody').insertAdjacentHTML('beforeend', html);
|
||||
}
|
||||
}
|
||||
|
||||
function sortByAny(someArray) {
|
||||
|
||||
if (field == 'IP') {
|
||||
someArray.sort((a, b) => sortIP(a, b, down));
|
||||
} else {
|
||||
someArray.sort((a, b) => byField(a, b, field, down));
|
||||
}
|
||||
|
||||
displayArrayData(someArray);
|
||||
}
|
||||
|
||||
function byField(a, b, fieldName, down){
|
||||
if (a[fieldName] > b[fieldName]) {
|
||||
return down ? 1 : -1;
|
||||
} else {
|
||||
return !down ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
function sortIP(a, b, down) {
|
||||
const num1 = numIP(a);
|
||||
const num2 = numIP(b);
|
||||
if (down) {
|
||||
return num1-num2;
|
||||
} else {
|
||||
return num2-num1;
|
||||
}
|
||||
}
|
||||
|
||||
function numIP(a) {
|
||||
return Number(a.IP.split(".").map((num) => (`000${num}`).slice(-3) ).join(""));
|
||||
}
|
||||
|
|
@ -1,233 +0,0 @@
|
|||
{{ define "config.html" }}
|
||||
|
||||
<body>
|
||||
<div class="container-lg">
|
||||
<div class="row">
|
||||
<div class="col-md mt-4">
|
||||
<div class="card border-primary">
|
||||
<div class="card-header">Basic config</div>
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-borderless">
|
||||
<form action="/config/" method="post">
|
||||
<tr>
|
||||
<td>Host</td>
|
||||
<td><input name="host" type="text" class="form-control" value="{{ .Config.Host }}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Port</td>
|
||||
<td><input name="port" type="text" class="form-control" value="{{ .Config.Port }}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Theme</td>
|
||||
<td><select name="theme" class="form-select">
|
||||
{{ range .Themes }}
|
||||
<option value="{{ . }}" {{ if eq . $.Config.Theme }}selected{{ end }}>{{ . }}</option>
|
||||
{{ end }}
|
||||
</select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Color mode</td>
|
||||
<td><select name="color" class="form-select">
|
||||
<option value="light" {{ if eq "light" .Config.Color }}selected{{ end }}>light</option>
|
||||
<option value="dark" {{ if eq "dark" .Config.Color }}selected{{ end }}>dark</option>
|
||||
</select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Local node-bootstrap URL</td>
|
||||
<td><input name="node" type="text" class="form-control" value="{{ .Config.NodePath }}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Shoutrrr URL</td>
|
||||
<td>
|
||||
<textarea name="shout" class="form-control" style="width: 100%;" rows="3" wrap="soft">{{ .Config.ShoutURL }}</textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button type="submit" class="btn btn-primary">Save</button></td>
|
||||
<td><button type="button" style="float: right;" class="btn btn-info" onclick="testNotifications()">Test notification</button></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</form>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-primary mt-4 mb-4">
|
||||
<div class="card-header">Scan settings</div>
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-borderless">
|
||||
<form action="/config_settings/" method="post">
|
||||
<tr>
|
||||
<td>Interfaces</td>
|
||||
<td><input name="ifaces" type="text" class="form-control" value="{{ .Config.Ifaces }}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Timeout (seconds)</td>
|
||||
<td><input name="timeout" type="number" class="form-control" value="{{ .Config.Timeout }}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Args for arp-scan</td>
|
||||
<td><input name="arpargs" type="text" class="form-control" value="{{ .Config.ArpArgs }}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Arp Strings</td>
|
||||
<td>{{ range .Config.ArpStrs }}
|
||||
<input name="arpstrs" type="text" class="form-control" value="{{ . }}">{{ end }}
|
||||
<input name="arpstrs" type="text" class="form-control">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Log level</td>
|
||||
<td><select name="log" class="form-select">
|
||||
<option value="debug" {{ if eq "debug" .Config.LogLevel }}selected{{ end }}>debug</option>
|
||||
<option value="info" {{ if eq "info" .Config.LogLevel }}selected{{ end }}>info</option>
|
||||
<option value="warn" {{ if eq "warn" .Config.LogLevel }}selected{{ end }}>warn</option>
|
||||
<option value="error" {{ if eq "error" .Config.LogLevel }}selected{{ end }}>error</option>
|
||||
</select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Trim History (hours)</td>
|
||||
<td><input name="trim" type="number" class="form-control" value="{{ .Config.TrimHist }}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Store History in DB</td>
|
||||
<td>
|
||||
<div class="form-check form-switch">
|
||||
{{ if .Config.HistInDB }}
|
||||
<input class="form-check-input" type="checkbox" name="histdb" checked>
|
||||
{{ else }}
|
||||
<input class="form-check-input" type="checkbox" name="histdb">
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Use DB</td>
|
||||
<td><select name="usedb" class="form-select">
|
||||
<option value="sqlite" {{ if eq "sqlite" .Config.UseDB }}selected{{ end }}>sqlite</option>
|
||||
<option value="postgres" {{ if eq "postgres" .Config.UseDB }}selected{{ end }}>postgres</option>
|
||||
</select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PG Connect URL</td>
|
||||
<td>
|
||||
<textarea name="pgconnect" class="form-control" style="width: 100%;" rows="3" wrap="soft">{{ .Config.PGConnect }}</textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button type="submit" class="btn btn-primary">Save</button></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</form>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md mt-4 mb-4">
|
||||
<div class="card border-primary">
|
||||
<div class="card-header">InfluxDB2 config</div>
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-borderless">
|
||||
<form action="/config_influx/" method="post">
|
||||
<tr>
|
||||
<td>Enable</td>
|
||||
<td>
|
||||
<div class="form-check form-switch">
|
||||
{{ if .Config.InfluxEnable }}
|
||||
<input class="form-check-input" type="checkbox" name="enable" checked>
|
||||
{{ else }}
|
||||
<input class="form-check-input" type="checkbox" name="enable">
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Address</td>
|
||||
<td><input name="addr" type="text" class="form-control" value="{{ .Config.InfluxAddr }}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Token</td>
|
||||
<td><input name="token" type="text" class="form-control" value="{{ .Config.InfluxToken }}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Org</td>
|
||||
<td><input name="org" type="text" class="form-control" value="{{ .Config.InfluxOrg }}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Bucket</td>
|
||||
<td><input name="bucket" type="text" class="form-control" value="{{ .Config.InfluxBucket }}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Skip TLS verify</td>
|
||||
<td>
|
||||
<div class="form-check form-switch">
|
||||
{{ if .Config.InfluxSkipTLS }}
|
||||
<input class="form-check-input" type="checkbox" name="skip" checked>
|
||||
{{ else }}
|
||||
<input class="form-check-input" type="checkbox" name="skip">
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button type="submit" class="btn btn-primary">Save</button></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</form>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md mt-4 mb-4">
|
||||
<div class="card border-primary">
|
||||
<div class="card-header">Prometheus config</div>
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-borderless">
|
||||
<form action="/config_prometheus/" method="post">
|
||||
<tr>
|
||||
<td>Enable</td>
|
||||
<td>
|
||||
<div class="form-check form-switch">
|
||||
{{ if .Config.PrometheusEnable }}
|
||||
<input class="form-check-input" type="checkbox" name="enable" checked>
|
||||
{{ else }}
|
||||
<input class="form-check-input" type="checkbox" name="enable">
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button type="submit" class="btn btn-primary">Save</button></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</form>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-primary mt-4 mb-4">
|
||||
<div class="card-header">
|
||||
About (<a href="https://github.com/aceberg/WatchYourLAN/releases/tag/{{ .Version }}" target="_blank">v{{ .Version }}</a>)
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>● After changing <b>Host</b> or <b>Port</b> the app must be restarted</p>
|
||||
<p>● <b>Shoutrrr URL</b> provides notifications to Discord, Email, Gotify, Telegram and other services. <a href="https://containrrr.dev/shoutrrr/v0.8/" target="_blank">Link to documentation</a></p>
|
||||
<p>● <b>Interfaces</b> - one or more, space separated</p>
|
||||
<p>● <b>Timeout (seconds)</b> - time between scans</p>
|
||||
<p>● <b>Args for arp-scan</b> - pass your own arguments to <code>arp-scan</code>. Enable <b>debug</b> log level to see resulting command. (Example: <code>-r 1</code>). See <a href="https://github.com/aceberg/WatchYourLAN/blob/main/docs/VLAN_ARP_SCAN.md" target="_blank">docs</a> for more.</p>
|
||||
<p>● <b>Arp Strings</b> - can setup scans for <code>vlans</code>, <code>docker0</code> and etcetera. See <a href="https://github.com/aceberg/WatchYourLAN/blob/main/docs/VLAN_ARP_SCAN.md" target="_blank">docs</a> for more.</p>
|
||||
<p>● <b>Trim History</b> - remove history after (hours)</p>
|
||||
<p>● <b>Store History in DB</b> - if off, the History will be stored only in memory and will be lost on app restart. Though, it will keep the app DB smaller and InfluxDB is recommended for long term History storage</p>
|
||||
<p>● <b>PG Connect URL</b> - address to connect to PostgreSQL DB. (Example: <code>postgres://username:password@192.168.0.1:5432/dbname?sslmode=disable</code>). Full list of URL parameters <a href="https://pkg.go.dev/github.com/lib/pq#hdr-Connection_String_Parameters" target="_blank">here</a></p>
|
||||
<p>● If you find this app useful, please, <a href="https://github.com/aceberg#donate" target="_blank">donate</a></p>
|
||||
<p>● Commission you own app (Golang, HTML/JS, Flutter). Contact <a href="https://github.com/aceberg" target="_blank">here</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/fs/public/js/notify.js"></script>
|
||||
|
||||
{{ template "footer.html" }}
|
||||
{{ end }}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
{{ define "footer.html"}}
|
||||
</body>
|
||||
</html>
|
||||
{{ end }}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
{{ define "header.html"}}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="{{ .Config.Color }}">
|
||||
<head>
|
||||
<title>WatchYourLAN</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!--Favicon-->
|
||||
<link rel="icon" type="image/x-icon" href="/fs/public/favicon.png">
|
||||
{{ if eq .Config.NodePath "" }}
|
||||
<!-- Font for icons -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css">
|
||||
<!-- Bootstrap and theme -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/aceberg-bootswatch-fork@v5.3.3-2/dist/{{ .Config.Theme }}/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- JavaScript Bundle with Popper -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
{{ else }} <!-- Local node_modules -->
|
||||
<link rel="stylesheet" href="{{ .Config.NodePath }}/node_modules/bootstrap-icons/font/bootstrap-icons.css">
|
||||
<link href="{{ .Config.NodePath }}/node_modules/bootswatch/dist/{{ .Config.Theme }}/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="{{ .Config.NodePath }}/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
||||
{{ end }}
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-primary">
|
||||
<div class="container-lg">
|
||||
<a class="navbar-brand" href="/">
|
||||
<img src="/fs/public/favicon.png" style="width: 2em"/>
|
||||
</a>
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<button class="btn navbar-toggler nav-link active fs-2" type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent" aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<i class="bi bi-list"></i>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="collapse navbar-collapse" id="navbarContent">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-md-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" target="_self" href="/config/">Config</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" target="_self" href="/history/">History</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active fs-3 ms-md-2" target="_blank" href="https://github.com/aceberg/WatchYourLAN"><i class="bi bi-github"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
{{ end }}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
{{ define "history.html" }}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-lg">
|
||||
<div class="row">
|
||||
<div class="col-md mt-4 mb-4">
|
||||
<div class="card border-primary">
|
||||
<div class="card-header">
|
||||
<div class="input-group">
|
||||
<button class="btn btn-outline-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Show</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" onclick="showHist(500)">500</a></li>
|
||||
<li><a class="dropdown-item" onclick="showHist(1000)">1000</a></li>
|
||||
<li><a class="dropdown-item" onclick="showHist(2000)">2000</a></li>
|
||||
<li><a class="dropdown-item" onclick="showHist(5000)">5000</a></li>
|
||||
<li><a class="dropdown-item" onclick="showHist(0)">All</a></li>
|
||||
</ul>
|
||||
<input class="form-control" id="man-show" onchange="manualShow()" placeholder="Show elements" style="max-width: 10em;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<th style="width: 3em;"></th>
|
||||
<th>Host</th>
|
||||
<th>History</th>
|
||||
</thead>
|
||||
<tbody id="showHist"></tbody>
|
||||
<!-- history.js -->
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/fs/public/js/history.js"></script>
|
||||
<script src="/fs/public/js/hist-html.js"></script>
|
||||
|
||||
{{ template "footer.html" }}
|
||||
{{ end }}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
{{ define "host.html" }}
|
||||
|
||||
<body>
|
||||
<div class="container-lg">
|
||||
<div class="row">
|
||||
<div class="col-md mt-4 mb-4">
|
||||
<div class="card border-primary">
|
||||
<div class="card-header">Host</div>
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>ID</td>
|
||||
<td>{{ .Host.ID }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{ .Host.Name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DNS name</td>
|
||||
<td>{{ .Host.DNS }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Iface</td>
|
||||
<td>{{ .Host.Iface }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IP</td>
|
||||
<td><a href="http://{{ .Host.IP }}" target="_blank">{{ .Host.IP }}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MAC</td>
|
||||
<td>{{ .Host.Mac }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Hardware</td>
|
||||
<td>{{ .Host.Hw }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Date</td>
|
||||
<td>{{ .Host.Date }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Known</td>
|
||||
<td>{{ if eq .Host.Known 1 }}Yes{{ else }}No{{ end }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Online</td>
|
||||
<td>{{ if eq .Host.Now 0 }}
|
||||
<i class="bi bi-circle-fill" style="color:var(--bs-gray-500);"></i>
|
||||
{{ else }}
|
||||
<i class="bi bi-check-circle-fill" style="color:var(--bs-success);"></i>
|
||||
{{ end }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button onclick="delHost('{{ .Host.ID }}')" class="btn btn-danger">Delete host</button>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md mt-4 mb-4">
|
||||
<div class="card border-primary">
|
||||
<div class="card-header">Port scan</div>
|
||||
<div class="card-body">
|
||||
<form class="input-group">
|
||||
<input id="begin" type="text" class="form-control" placeholder="1">
|
||||
<input id="end" type="text" class="form-control" placeholder="65535">
|
||||
<!-- To get from JS -->
|
||||
<input type="hidden" id="hostIP" value="{{ .Host.IP }}">
|
||||
<button onclick="scanAddr()" type="button" class="btn btn-primary">Scan</button>
|
||||
</form>
|
||||
<div style="display: flex; justify-content: space-between; visibility: hidden;" id="stopBtn" class="mt-2">
|
||||
<button onclick="stopScan()" type="button" class="btn btn-warning">Stop</button>
|
||||
<div id="curPort"></div>
|
||||
</div>
|
||||
<div id="foundPorts" class="mt-2">
|
||||
<!-- JS here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md mb-4">
|
||||
<div class="card border-primary">
|
||||
<div class="card-header">
|
||||
<div class="input-group">
|
||||
<button class="btn btn-outline-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Show</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" onclick="showHist(500)">500</a></li>
|
||||
<li><a class="dropdown-item" onclick="showHist(1000)">1000</a></li>
|
||||
<li><a class="dropdown-item" onclick="showHist(2000)">2000</a></li>
|
||||
<li><a class="dropdown-item" onclick="showHist(5000)">5000</a></li>
|
||||
<li><a class="dropdown-item" onclick="showHist(0)">All</a></li>
|
||||
</ul>
|
||||
<input class="form-control" id="man-show" onchange="manualShow()" placeholder="Show elements" style="max-width: 10em;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="showHist"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/fs/public/js/host-scan.js"></script>
|
||||
<script src="/fs/public/js/host.js"></script>
|
||||
<script src="/fs/public/js/hist-html.js"></script>
|
||||
<script>
|
||||
loadHistory('{{ .Host.Mac }}');
|
||||
</script>
|
||||
|
||||
{{ template "footer.html" }}
|
||||
{{ end }}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
{{ define "oldindex.html" }}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-lg">
|
||||
<div class="row">
|
||||
<div class="col-md mt-2">
|
||||
<div class="form-check form-switch">
|
||||
<input type="hidden" id="ref-timeout" value="{{ .Config.Timeout }}">
|
||||
<input class="form-check-input" type="checkbox" id="ref" onclick="toggleRefresh()" title="Auto refresh">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md mt-2 mb-4">
|
||||
<div class="card border-primary">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-md mt-1 mb-1">
|
||||
<button class="btn btn-outline-primary" disabled>Filter by</button>
|
||||
<button class="btn btn-outline-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Iface</button>
|
||||
<ul class="dropdown-menu">
|
||||
{{ range .Themes }}
|
||||
<li><a class="dropdown-item" onclick="filterFunc('iface', '{{ . }}')">{{ . }}</a></li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
<button class="btn btn-outline-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Known</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" onclick="filterFunc('known', 1)">Known</a></li>
|
||||
<li><a class="dropdown-item" onclick="filterFunc('known', 0)">Unknown</a></li>
|
||||
</ul>
|
||||
<button class="btn btn-outline-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Online</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" onclick="filterFunc('line', 1)">Online</a></li>
|
||||
<li><a class="dropdown-item" onclick="filterFunc('line', 0)">Offline</a></li>
|
||||
</ul>
|
||||
<button class="btn btn-outline-primary" onclick="resetFilter()">Reset filter</button>
|
||||
</div>
|
||||
<div class="col-md mt-1 mb-1">
|
||||
<div class="d-flex justify-content-between">
|
||||
<input class="form-control" id="search" oninput="searchFunc()" placeholder="Search" style="max-width: 10em;">
|
||||
<button class="btn btn-outline-primary" id="edit" onclick="editClick()">Edit names</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<th style="width: 3em;"></th>
|
||||
<th>Name <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Name')"></i></th>
|
||||
<th>Iface <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Iface')"></i></th>
|
||||
<th>IP <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('IP')"></i></th>
|
||||
<th>MAC <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Mac')"></i></th>
|
||||
<th>Hardware <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Hw')"></i></th>
|
||||
<th>Date <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Date')"></i></th>
|
||||
<th>Known <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Known')"></i></th>
|
||||
<th>Online <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Now')"></i></th>
|
||||
</thead>
|
||||
<tbody id="tBody"></tbody>
|
||||
<!-- index.js -->
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/fs/public/js/index.js"></script>
|
||||
<script src="/fs/public/js/sort.js"></script>
|
||||
<script src="/fs/public/js/filter-search.js"></script>
|
||||
<script src="/fs/public/js/refresh.js"></script>
|
||||
|
||||
{{ template "footer.html" }}
|
||||
{{ end }}
|
||||
Loading…
Reference in a new issue