diff --git a/README.md b/README.md index 4a0adeae..62135a33 100755 --- a/README.md +++ b/README.md @@ -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). | All Sponsors | diff --git a/docker-compose.yml b/docker-compose.yml index 23a483a2..4441cbbe 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -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 diff --git a/docs/CUSTOM_PROPERTIES.md b/docs/CUSTOM_PROPERTIES.md index 18c7b3e0..df4110e7 100755 --- a/docs/CUSTOM_PROPERTIES.md +++ b/docs/CUSTOM_PROPERTIES.md @@ -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. diff --git a/docs/SUBNETS.md b/docs/SUBNETS.md index 2a791fac..fec08ac7 100755 --- a/docs/SUBNETS.md +++ b/docs/SUBNETS.md @@ -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 diff --git a/docs/img/SUBNETS/subnets-setting-location.png b/docs/img/SUBNETS/subnets-setting-location.png index 874999e9..a311f4a8 100755 Binary files a/docs/img/SUBNETS/subnets-setting-location.png and b/docs/img/SUBNETS/subnets-setting-location.png differ diff --git a/docs/img/SUBNETS/subnets_vlan.png b/docs/img/SUBNETS/subnets_vlan.png index 5d10dd04..f7e5235b 100755 Binary files a/docs/img/SUBNETS/subnets_vlan.png and b/docs/img/SUBNETS/subnets_vlan.png differ diff --git a/front/css/app.css b/front/css/app.css index dc98aa71..37381d93 100755 --- a/front/css/app.css +++ b/front/css/app.css @@ -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 { diff --git a/front/devices.php b/front/devices.php index 2c7143e8..4449284f 100755 --- a/front/devices.php +++ b/front/devices.php @@ -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 += `