From 6ad90610ea36ff2ee6692ccb4ae197ac3211f385 Mon Sep 17 00:00:00 2001 From: jokob-sk Date: Sat, 11 Jan 2025 20:20:09 +1100 Subject: [PATCH] Docs, small fixes --- docs/SUBNETS.md | 3 +- front/devices.php | 78 ++++++++++++++++--------- front/php/server/db.php | 20 +++++-- front/php/templates/language/en_us.json | 2 +- front/php/templates/language/it_it.json | 2 +- front/php/templates/language/ru_ru.json | 2 +- 6 files changed, 72 insertions(+), 35 deletions(-) mode change 100644 => 100755 front/php/templates/language/it_it.json diff --git a/docs/SUBNETS.md b/docs/SUBNETS.md index fec08ac7..bedc0e95 100755 --- a/docs/SUBNETS.md +++ b/docs/SUBNETS.md @@ -22,7 +22,7 @@ If direct scans are not possible (Wi-Fi Extenders, VPNs and inaccessible network * **Examples for one and two subnets:** * One subnet: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0']` - * Two subnets: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0','192.168.1.0/24 --interface=eth1 -vlan=107']` + * Two subnets: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0','192.168.1.0/24 --interface=eth1 --vlan=107']` If you get timeout messages, decrease the network mask (e.g.: from `/16` to `/24`) or increase the `TIMEOUT` setting (e.g.: `ARPSCAN_RUN_TIMEOUT` to `300` (5-minute timeout)) for the plugin and the interval between scans (e.g.: `ARPSCAN_RUN_SCHD` to `*/10 * * * *` (scans every 10 minutes)). @@ -89,7 +89,6 @@ By default, Hyper-V only allows untagged packets through to the VM interface, bl 2. Within the VM, set up sub-interfaces for each VLAN to enable scanning. On Ubuntu 22.04, Netplan can be used. In /etc/netplan/00-installer-config.yaml, add VLAN definitions: ```yaml - network: ethernets: eth0: diff --git a/front/devices.php b/front/devices.php index 4449284f..7e59b8b1 100755 --- a/front/devices.php +++ b/front/devices.php @@ -201,35 +201,61 @@ function mapIndx(oldIndex) // Query total numbers of Devices by status //------------------------------------------------------------------------------ function getDevicesTotals() { + maxDelay = 180; //cap at 180 seconds - // Fetch data via AJAX - $.ajax({ - url: '/php/server/query_json.php', - type: "GET", - dataType: "json", - data: { - file: 'table_devices_tiles.json', // Pass the file parameter - nocache: Date.now() // Prevent caching with a timestamp - }, - success: function(response) { - if (response && response.data) { - resultJSON = response.data[0]; // Assuming the structure {"data": [ ... ]} - - // Save the result to cache - setCache("getDevicesTotals", JSON.stringify(resultJSON)); + let maxRetries = Math.ceil(Math.log2(maxDelay)); // Calculate maximum retries to cap at maxDelay seconds + let attempt = 0; + let calledUpdateAPI = false; - // Process the fetched data - processDeviceTotals(resultJSON); - } else { - console.error("Invalid response format from API"); - } - }, - error: function(xhr, status, error) { - console.error("Failed to fetch devices data:", error); - } - }); + function fetchDataWithBackoff() { + // Calculate the delay (2^attempt seconds, capped at maxDelay seconds) + const delay = Math.min(2 ** attempt, maxDelay) * 1000; - + // Attempt to fetch data + $.ajax({ + url: '/php/server/query_json.php', + type: "GET", + dataType: "json", + data: { + file: 'table_devices_tiles.json', // Pass the file parameter + nocache: Date.now() // Prevent caching with a timestamp + }, + success: function(response) { + if (response && response.data) { + const resultJSON = response.data[0]; // Assuming the structure {"data": [ ... ]} + + // Save the result to cache + setCache("getDevicesTotals", JSON.stringify(resultJSON)); + + // Process the fetched data + processDeviceTotals(resultJSON); + } else { + console.error("Invalid response format from API"); + } + }, + error: function(xhr, status, error) { + console.error("Failed to fetch devices data (Attempt " + (attempt + 1) + "):", error); + + // try updating the API once + if(calledUpdateAPI == false) + { + calledUpdateAPI = true; + updateApi("devices_tiles"); + } + + // Retry logic + if (attempt < maxRetries) { + attempt++; + setTimeout(fetchDataWithBackoff, delay); + } else { + console.error("Maximum retries reached. Unable to fetch devices data."); + } + } + }); + } + + // Start the first fetch attempt + fetchDataWithBackoff(); } function processDeviceTotals(devicesData) { diff --git a/front/php/server/db.php b/front/php/server/db.php index 56a9e15a..f0ee9f1a 100755 --- a/front/php/server/db.php +++ b/front/php/server/db.php @@ -10,8 +10,12 @@ //------------------------------------------------------------------------------ // DB File Path -$DBFILE = dirname(__FILE__).'/../../../db/app.db'; -$DBFILE_LOCKED_FILE = dirname(__FILE__).'/../../../log/db_is_locked.log'; +// $DBFILE = dirname(__FILE__).'/../../../db/app.db'; +// $DBFILE_LOCKED_FILE = dirname(__FILE__).'/../../../log/db_is_locked.log'; +$scriptDir = realpath(dirname(__FILE__)); // Resolves symlinks to the actual physical path +$DBFILE = $scriptDir . '/../../../db/app.db'; +$DBFILE_LOCKED_FILE = $scriptDir . '/../../../log/db_is_locked.log'; + //------------------------------------------------------------------------------ // check if authenticated @@ -32,6 +36,14 @@ function SQLite3_connect($trytoreconnect = true, $retryCount = 0) { global $db_locked; $db_locked = false; + if (!file_exists($DBFILE)) { + die("Database file not found: $DBFILE"); + } + if (!file_exists(dirname($DBFILE_LOCKED_FILE))) { + die("Log directory not found: " . dirname($DBFILE_LOCKED_FILE)); + } + + // Write unlock status to the locked file file_put_contents($DBFILE_LOCKED_FILE, '0'); @@ -70,7 +82,7 @@ class CustomDatabaseWrapper { private $maxRetries; private $retryDelay; - public function __construct($filename, $flags = SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $maxRetries = 10, $retryDelay = 1000, $encryptionKey = null) { + public function __construct($filename, $flags = SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $maxRetries = 3, $retryDelay = 1000, $encryptionKey = null) { $this->sqlite = new SQLite3($filename, $flags, $encryptionKey); $this->maxRetries = $maxRetries; $this->retryDelay = $retryDelay; @@ -116,7 +128,7 @@ class CustomDatabaseWrapper { file_put_contents($DBFILE_LOCKED_FILE, '0'); $message = 'Error executing query (attempts: ' . $attempts . '), query: ' . $query; - write_notification($message); + // write_notification($message); error_log("Query failed after {$this->maxRetries} attempts: " . $this->sqlite->lastErrorMsg()); } diff --git a/front/php/templates/language/en_us.json b/front/php/templates/language/en_us.json index 8511e850..9129a8cd 100755 --- a/front/php/templates/language/en_us.json +++ b/front/php/templates/language/en_us.json @@ -1,7 +1,7 @@ { "API_CUSTOM_SQL_description": "You can specify a custom SQL query which will generate a JSON file and then expose it via the table_custom_endpoint.json file endpoint.", "API_CUSTOM_SQL_name": "Custom endpoint", - "API_TOKEN_description": "API token for secure communication. Generate one or enter any value. It's sent in the request header and used in the SYNC plugin, GraphQL server and other API endpoints. You can use the API endpoints to create custom integrations as descibed in the a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md\" target=\"_blank\">API documentation.", + "API_TOKEN_description": "API token for secure communication. Generate one or enter any value. It's sent in the request header and used in the SYNC plugin, GraphQL server and other API endpoints. You can use the API endpoints to create custom integrations as descibed in the API documentation.", "API_TOKEN_name": "API token", "API_display_name": "API", "API_icon": "", diff --git a/front/php/templates/language/it_it.json b/front/php/templates/language/it_it.json old mode 100644 new mode 100755 index bb8c43fc..17da5963 --- a/front/php/templates/language/it_it.json +++ b/front/php/templates/language/it_it.json @@ -1,7 +1,7 @@ { "API_CUSTOM_SQL_description": "Puoi specificare una query SQL personalizzata che genererà un file JSON e quindi lo esporrà tramite l'table_custom_endpoint.jsonendpoint del file.", "API_CUSTOM_SQL_name": "Endpoint personalizzato", - "API_TOKEN_description": "Token API per comunicazioni sicure. Generane uno o inserisci un valore qualsiasi. Viene inviato nell'intestazione della richiesta e utilizzato nel plugin SYNC, nel server GraphQL e in altri endpoint API. Puoi utilizzare gli endpoint API per creare integrazioni personalizzate come descritto nella a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md\" target=\"_blank\">documentazione API.", + "API_TOKEN_description": "Token API per comunicazioni sicure. Generane uno o inserisci un valore qualsiasi. Viene inviato nell'intestazione della richiesta e utilizzato nel plugin SYNC, nel server GraphQL e in altri endpoint API. Puoi utilizzare gli endpoint API per creare integrazioni personalizzate come descritto nella documentazione API.", "API_TOKEN_name": "Token API", "API_display_name": "API", "API_icon": "", diff --git a/front/php/templates/language/ru_ru.json b/front/php/templates/language/ru_ru.json index fc1a2d29..9f2f5051 100755 --- a/front/php/templates/language/ru_ru.json +++ b/front/php/templates/language/ru_ru.json @@ -1,7 +1,7 @@ { "API_CUSTOM_SQL_description": "Вы можете указать собственный SQL-запрос, который будет генерировать файл JSON, а затем предоставлять его через конечную точку файла table_custom_endpoint.json.", "API_CUSTOM_SQL_name": "Пользовательская конечная точка", - "API_TOKEN_description": "API-токен для безопасной связи. Сгенерируйте его или введите любое значение. Он передается в заголовке запроса и используется в плагине SYNC, сервере GraphQL и других конечных точках API. Вы можете использовать конечные точки API для создания пользовательских интеграций, как описано в a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md\" target=\"_blank\">документации по API.", + "API_TOKEN_description": "API-токен для безопасной связи. Сгенерируйте его или введите любое значение. Он передается в заголовке запроса и используется в плагине SYNC, сервере GraphQL и других конечных точках API. Вы можете использовать конечные точки API для создания пользовательских интеграций, как описано в документации по API.", "API_TOKEN_name": "API token", "API_display_name": "API", "API_icon": "",