Skip to content

Commit

Permalink
docs + freebox parsing issue #927
Browse files Browse the repository at this point in the history
  • Loading branch information
jokob-sk committed Jan 3, 2025
1 parent e6d2a1c commit bd19858
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 135 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,7 @@ Get notified about a new release, what new functionality you can use and about b

[![GitHub Sponsors](https://img.shields.io/github/sponsors/jokob-sk?style=social)](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 |
Expand Down
8 changes: 3 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: "3"
services:
netalertx:
privileged: true
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions docs/CUSTOM_PROPERTIES.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Custom Properties for Network Devices
# Custom Properties for Devices

![Custom Properties](/docs/img/CUSTOM_PROPERTIES/Device_Custom_Properties.png)

## 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.
Expand Down
16 changes: 11 additions & 5 deletions docs/SUBNETS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`

Expand Down Expand Up @@ -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)).

![Network hardware](/docs/img/SUBNETS/system_info-network_hardware.png)

> [!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
Expand Down
Binary file modified docs/img/SUBNETS/subnets-setting-location.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/SUBNETS/subnets_vlan.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 27 additions & 12 deletions front/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,6 @@ body
margin-left: 150px;
}

#settingsPage
{
display: grid;
}


@media (max-width: 767px) {
.main-header .logo {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1678,13 +1700,6 @@ input[readonly] {
}
}

#settingsPage .small-box .inner .card-title {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: white;
}


.textOverflow
{
Expand Down
127 changes: 45 additions & 82 deletions front/devices.php
Original file line number Diff line number Diff line change
Expand Up @@ -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!
Expand Down Expand Up @@ -377,6 +336,7 @@ function mapColumnIndexToFieldName(index, tableColumnVisible) {


// ---------------------------------------------------------
// Initializes the main devices list datatable
function initializeDatatable (status) {

if(!status)
Expand Down Expand Up @@ -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) {

Expand Down Expand Up @@ -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);

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
);

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;
if (!isBase64(custProps)) {

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
);

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;
}

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"
}


Expand Down
8 changes: 8 additions & 0 deletions front/js/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
8 changes: 0 additions & 8 deletions front/js/settings_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
// -------------------------------------------------------------------
Expand Down
12 changes: 6 additions & 6 deletions front/multiEditCore.php
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down
Empty file modified front/php/templates/language/it_it.json
100644 → 100755
Empty file.
29 changes: 17 additions & 12 deletions front/plugins/freebox/freebox.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit bd19858

Please sign in to comment.