mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
docs + freebox parsing issue #927
This commit is contained in:
@@ -83,9 +83,7 @@ Get notified about a new release, what new functionality you can use and about b
|
||||
|
||||
[](https://github.com/sponsors/jokob-sk)
|
||||
|
||||
Thank you to all the wonderful people who are sponsoring this project.
|
||||
|
||||
> preventing my burnout😅 are:
|
||||
Thank you to all the wonderful people who are sponsoring this project (private sponsors are hidden).
|
||||
|
||||
<!-- SPONSORS-LIST DO NOT MODIFY BELOW -->
|
||||
| All Sponsors |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
version: "3"
|
||||
services:
|
||||
netalertx:
|
||||
privileged: true
|
||||
@@ -43,8 +42,7 @@ services:
|
||||
- ${DEV_LOCATION}/install/start.debian.sh:/app/install/start.debian.sh
|
||||
- ${DEV_LOCATION}/install/user-mapping.debian.sh:/app/install/user-mapping.debian.sh
|
||||
- ${DEV_LOCATION}/install/install.debian.sh:/app/install/install.debian.sh
|
||||
- ${DEV_LOCATION}/install/install_dependencies.debian.sh:/app/install/install_dependencies.debian.sh
|
||||
|
||||
- ${DEV_LOCATION}/install/install_dependencies.debian.sh:/app/install/install_dependencies.debian.sh
|
||||
- ${DEV_LOCATION}/front/php:/app/front/php
|
||||
- ${DEV_LOCATION}/front/deviceDetails.php:/app/front/deviceDetails.php
|
||||
- ${DEV_LOCATION}/front/deviceDetailsEdit.php:/app/front/deviceDetailsEdit.php
|
||||
@@ -73,8 +71,8 @@ services:
|
||||
- ${DEV_LOCATION}/front/plugins:/app/front/plugins
|
||||
# DELETE END anyone trying to use this file: comment out / delete ABOVE lines, they are only for development purposes
|
||||
# ---------------------------------------------------------------------------
|
||||
environment:
|
||||
# - APP_CONF_OVERRIDE={"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_theme":"Dark"}
|
||||
environment:
|
||||
# - APP_CONF_OVERRIDE={"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","GRAPHQL_PORT":"20223","UI_theme":"Light"}
|
||||
- TZ=${TZ}
|
||||
- PORT=${PORT}
|
||||
# ❗ DANGER ZONE BELOW - Setting ALWAYS_FRESH_INSTALL=true will delete the content of the /db & /config folders
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Custom Properties for Network Devices
|
||||
# Custom Properties for Devices
|
||||
|
||||

|
||||
|
||||
## Overview
|
||||
|
||||
This functionality allows you to define **custom properties** for network devices, which can store and display additional information on the device listing page. By marking properties as visible, you can enhance the user interface with quick actions, notes, or external links.
|
||||
This functionality allows you to define **custom properties** for devices, which can store and display additional information on the device listing page. By marking properties as visible, you can enhance the user interface with quick actions, notes, or external links.
|
||||
|
||||
### Key Features:
|
||||
- **Customizable Properties**: Define specific properties for each device.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
You need to specify the network interface and the network mask. You can also configure multiple subnets and specify VLANs (see VLAN exceptions below).
|
||||
|
||||
`ARPSCAN` can scan multiple networks if the network allows it. To scan networks directly, the subnets must be accessible from the network where NetAlertX is running. This means NetAlertX needs to have access to the interface attached to that subnet. You can verify this by running the following command in the container:
|
||||
`ARPSCAN` can scan multiple networks if the network allows it. To scan networks directly, the subnets must be accessible from the network where NetAlertX is running. This means NetAlertX needs to have access to the interface attached to that subnet. You can verify this by running the following command in the container (replace the interface and ip mask):
|
||||
|
||||
`sudo arp-scan --interface=eth0 192.168.1.0/24`
|
||||
|
||||
@@ -45,18 +45,24 @@ Specify the network filter, which **significantly** speeds up the scan process.
|
||||
|
||||
**Example value:** `--interface=eth0`
|
||||
|
||||
The adapter will probably be `eth0` or `eth1`. (Check `System Info` > `Network Hardware` or run `iwconfig` in the container to find your interface name(s)).
|
||||
The adapter will probably be `eth0` or `eth1`. (Check `System Info` > `Network Hardware`, or run `iwconfig` in the container to find your interface name(s)).
|
||||
|
||||

|
||||
|
||||
> [!TIP]
|
||||
> As an alternative to `iwconfig`, run `ip -o link show | awk -F': ' '!/lo|vir|docker/ {print $2}'` in your container to find your interface name(s) (e.g.: `eth0`, `eth1`).
|
||||
> As an alternative to `iwconfig`, run `ip -o link show | awk -F': ' '!/lo|vir|docker/ {print $2}'` in your container to find your interface name(s) (e.g.: `eth0`, `eth1`):
|
||||
> ```bash
|
||||
> Synology-NAS:/# ip -o link show | awk -F': ' '!/lo|vir|docker/ {print $2}'
|
||||
> sit0@NONE
|
||||
> eth1
|
||||
> eth0
|
||||
> ```
|
||||
|
||||
### VLANs
|
||||
|
||||
**Example value:** `-vlan=107`
|
||||
**Example value:** `--vlan=107`
|
||||
|
||||
- Append `-vlan=107` to the interface field (e.g.: `eth0 -vlan=107`) for multiple VLANs. More details are available in this [comment](https://github.com/jokob-sk/NetAlertX/issues/170#issuecomment-1419902988).
|
||||
- Append `--vlan=107` to the `SCAN_SUBNETS` field (e.g.: `192.168.1.0/24 --interface=vmbr0 --vlan=107`) for multiple VLANs.
|
||||
|
||||
#### VLANs on a Hyper-V Setup
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 112 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 18 KiB |
@@ -287,11 +287,6 @@ body
|
||||
margin-left: 150px;
|
||||
}
|
||||
|
||||
#settingsPage
|
||||
{
|
||||
display: grid;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.main-header .logo {
|
||||
@@ -893,6 +888,33 @@ height: 50px;
|
||||
} */
|
||||
}
|
||||
|
||||
/* Hide unusable buttons on the settings page for the NEWDEV plugin*/
|
||||
#settingsPage #add_option_NEWDEV_devGroup,
|
||||
#settingsPage #add_option_NEWDEV_devLocation,
|
||||
#settingsPage #add_option_NEWDEV_devOwner,
|
||||
#settingsPage #copy_icons_NEWDEV_devIcon,
|
||||
#settingsPage #add_icon_NEWDEV_devIcon,
|
||||
#settingsPage #add_option_NEWDEV_devType
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#settingsPage
|
||||
{
|
||||
display: grid;
|
||||
}
|
||||
|
||||
|
||||
#settingsPage .small-box .inner .card-title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
.settingswrap
|
||||
{
|
||||
margin-bottom: 100px;
|
||||
@@ -1678,13 +1700,6 @@ input[readonly] {
|
||||
}
|
||||
}
|
||||
|
||||
#settingsPage .small-box .inner .card-title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
.textOverflow
|
||||
{
|
||||
|
||||
@@ -295,48 +295,7 @@ function renderInfoboxes(customData) {
|
||||
});
|
||||
}
|
||||
|
||||
// // -----------------------------------------------------------------------------
|
||||
// // Define a function to filter data based on deviceStatus
|
||||
// function filterDataByStatus(data, status) {
|
||||
// return data.filter(function(item) {
|
||||
// switch (status) {
|
||||
// case 'my_devices':
|
||||
// to_display = getSetting('UI_MY_DEVICES');
|
||||
|
||||
// let result = true;
|
||||
|
||||
// if (!to_display.includes('down') && item.devPresentLastScan === 0 && item.devAlertDown !== 0) {
|
||||
// result = false;
|
||||
// } else if (!to_display.includes('new') && item.devIsNew === 1) {
|
||||
// result = false;
|
||||
// } else if (!to_display.includes('archived') && item.devIsArchived === 1) {
|
||||
// result = false;
|
||||
// } else if (!to_display.includes('offline') && item.devPresentLastScan === 0) {
|
||||
// result = false;
|
||||
// } else if (!to_display.includes('online') && item.devPresentLastScan === 1) {
|
||||
// result = false;
|
||||
// }
|
||||
|
||||
// return result; // Include all items for 'my_devices' status
|
||||
// case 'connected':
|
||||
// return item.devPresentLastScan === 1;
|
||||
// case 'favorites':
|
||||
// return item.devFavorite === 1;
|
||||
// case 'new':
|
||||
// return item.devIsNew === 1;
|
||||
// case 'offline':
|
||||
// return item.devPresentLastScan === 0;
|
||||
// case 'down':
|
||||
// return (item.devPresentLastScan === 0 && item.devAlertDown !== 0);
|
||||
// case 'archived':
|
||||
// return item.devIsArchived === 1;
|
||||
// default:
|
||||
// return true; // Include all items for unknown statuses
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Map column index to column name for GraphQL query
|
||||
function mapColumnIndexToFieldName(index, tableColumnVisible) {
|
||||
// the order is important, don't change it!
|
||||
@@ -377,6 +336,7 @@ function mapColumnIndexToFieldName(index, tableColumnVisible) {
|
||||
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Initializes the main devices list datatable
|
||||
function initializeDatatable (status) {
|
||||
|
||||
if(!status)
|
||||
@@ -808,9 +768,7 @@ function initializeDatatable (status) {
|
||||
// -----------------------------------------------------------------------------
|
||||
function handleLoadingDialog(needsReload = false)
|
||||
{
|
||||
|
||||
// console.log('needsReload:');
|
||||
// console.log(needsReload);
|
||||
// console.log(`needsReload: ${needsReload}`);
|
||||
|
||||
$.get('/php/server/query_logs.php?file=execution_queue.log&nocache=' + Date.now(), function(data) {
|
||||
|
||||
@@ -890,51 +848,56 @@ function getMacsOfShownDevices() {
|
||||
return macs;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Handle custom actions/properties on a device
|
||||
// -----------------------------------------------------------------------------
|
||||
// Handle custom actions/properties on a device
|
||||
function renderCustomProps(custProps, mac) {
|
||||
// Decode and parse the custom properties
|
||||
|
||||
console.log(custProps);
|
||||
if (!isBase64(custProps)) {
|
||||
|
||||
const props = JSON.parse(atob(custProps));
|
||||
let html = "";
|
||||
console.error(`Unable to decode CustomProps for ${mac}`);
|
||||
console.error(custProps);
|
||||
|
||||
} else{
|
||||
const props = JSON.parse(atob(custProps));
|
||||
let html = "";
|
||||
|
||||
props.forEach((propGroup, index) => {
|
||||
const propMap = Object.fromEntries(
|
||||
propGroup.map(prop => Object.entries(prop)[0]) // Convert array of objects to key-value pairs
|
||||
);
|
||||
props.forEach((propGroup, index) => {
|
||||
const propMap = Object.fromEntries(
|
||||
propGroup.map(prop => Object.entries(prop)[0]) // Convert array of objects to key-value pairs
|
||||
);
|
||||
|
||||
if (propMap["CUSTPROP_show"] === true) { // Render if visible
|
||||
let onClickEvent = "";
|
||||
if (propMap["CUSTPROP_show"] === true) { // Render if visible
|
||||
let onClickEvent = "";
|
||||
|
||||
switch (propMap["CUSTPROP_type"]) {
|
||||
case "show_notes":
|
||||
onClickEvent = `showModalOK('${propMap["CUSTPROP_name"]}','${propMap["CUSTPROP_notes"]}')`;
|
||||
break;
|
||||
case "link":
|
||||
onClickEvent = `window.location.href='${propMap["CUSTPROP_args"]}';`;
|
||||
break;
|
||||
case "link_new_tab":
|
||||
onClickEvent = `openInNewTab('${propMap["CUSTPROP_args"]}')`;
|
||||
break;
|
||||
case "run_plugin":
|
||||
onClickEvent = `alert('Not implemented')`;
|
||||
break;
|
||||
case "delete_dev":
|
||||
onClickEvent = `askDelDevDTInline('${mac}')`;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch (propMap["CUSTPROP_type"]) {
|
||||
case "show_notes":
|
||||
onClickEvent = `showModalOK('${propMap["CUSTPROP_name"]}','${propMap["CUSTPROP_notes"]}')`;
|
||||
break;
|
||||
case "link":
|
||||
onClickEvent = `window.location.href='${propMap["CUSTPROP_args"]}';`;
|
||||
break;
|
||||
case "link_new_tab":
|
||||
onClickEvent = `openInNewTab('${propMap["CUSTPROP_args"]}')`;
|
||||
break;
|
||||
case "run_plugin":
|
||||
onClickEvent = `alert('Not implemented')`;
|
||||
break;
|
||||
case "delete_dev":
|
||||
onClickEvent = `askDelDevDTInline('${mac}')`;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
html += `<div class="pointer devicePropAction" onclick="${onClickEvent}" title="${propMap["CUSTPROP_name"]} ${propMap["CUSTPROP_args"]}"> ${atob(propMap["CUSTPROP_icon"])} </div>`;
|
||||
}
|
||||
});
|
||||
|
||||
html += `<div class="pointer devicePropAction" onclick="${onClickEvent}" title="${propMap["CUSTPROP_name"]} ${propMap["CUSTPROP_args"]}"> ${atob(propMap["CUSTPROP_icon"])} </div>`;
|
||||
}
|
||||
});
|
||||
return html;
|
||||
}
|
||||
|
||||
return html;
|
||||
return "Error, check browser Console log"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -410,6 +410,14 @@ function isValidBase64(str) {
|
||||
return invalidCharacters === '';
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Utility function to check if the value is already Base64
|
||||
function isBase64(value) {
|
||||
const base64Regex =
|
||||
/^(?:[A-Za-z0-9+\/]{4})*?(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/;
|
||||
return base64Regex.test(value);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
function isValidJSON(jsonString) {
|
||||
try {
|
||||
|
||||
@@ -191,14 +191,6 @@ function isSHA256(value) {
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Utility function to check if the value is already Base64
|
||||
function isBase64(value) {
|
||||
const base64Regex =
|
||||
/^(?:[A-Za-z0-9+\/]{4})*?(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/;
|
||||
return base64Regex.test(value);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Validation
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
<h3 class="box-title"><?= lang('Gen_Selected_Devices');?></h3>
|
||||
|
||||
</div>
|
||||
<div class="deviceSelector col-md-9 col-sm-12" style="z-index:5"></div>
|
||||
<div class="deviceSelector col-md-11 col-sm-11" style="z-index:5"></div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<button type="button" class="btn btn-default" onclick="markAllSelected()">
|
||||
<i class="fa-solid fa-circle-check"></i> <?= lang('Gen_Add_All');?>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-default col-md-12" onclick="markAllSelected()" title="<?= lang('Gen_Add_All');?>">
|
||||
<i class="fa-solid fa-circle-check"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default" onclick="markAllNotSelected()">
|
||||
<i class="fa-solid fa-circle-xmark"></i> <?= lang('Gen_Remove_All');?>
|
||||
<button type="button" class="btn btn-default col-md-12" onclick="markAllNotSelected()" title="<?= lang('Gen_Remove_All');?>">
|
||||
<i class="fa-solid fa-circle-xmark"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
0
front/php/templates/language/it_it.json
Normal file → Executable file
0
front/php/templates/language/it_it.json
Normal file → Executable file
@@ -148,18 +148,23 @@ def main():
|
||||
foreignKey=freebox["mac"],
|
||||
)
|
||||
for host in hosts:
|
||||
for ip in [ip for ip in host["l3connectivities"] if ip["reachable"]]:
|
||||
mac: str = host["l2ident"]["id"]
|
||||
plugin_objects.add_object(
|
||||
primaryId=mac,
|
||||
secondaryId=ip["addr"],
|
||||
watched1=host["primary_name"],
|
||||
watched2=host["vendor_name"] if host["vendor_name"] else "(unknown)",
|
||||
watched3=map_device_type(host["host_type"]),
|
||||
watched4=datetime.fromtimestamp(ip["last_time_reachable"]),
|
||||
extra="",
|
||||
foreignKey=mac,
|
||||
)
|
||||
# Check if 'l3connectivities' exists and is a list
|
||||
if "l3connectivities" in host and isinstance(host["l3connectivities"], list):
|
||||
for ip in [ip for ip in host["l3connectivities"] if ip.get("reachable")]:
|
||||
mac: str = host.get("l2ident", {}).get("id", "(unknown)")
|
||||
plugin_objects.add_object(
|
||||
primaryId=mac,
|
||||
secondaryId=ip.get("addr", "(unknown)"),
|
||||
watched1=host.get("primary_name", "(unknown)"),
|
||||
watched2=host.get("vendor_name", "(unknown)"),
|
||||
watched3=map_device_type(host.get("host_type", "unknown")),
|
||||
watched4=datetime.fromtimestamp(ip.get("last_time_reachable", 0)),
|
||||
extra="",
|
||||
foreignKey=mac,
|
||||
)
|
||||
else:
|
||||
# Optional: Log or handle hosts without 'l3connectivities'
|
||||
mylog("verbose", [f"[{pluginName}] Host missing 'l3connectivities': {host}"])
|
||||
|
||||
# commit result
|
||||
plugin_objects.write_result_file()
|
||||
|
||||
Reference in New Issue
Block a user