From 5c4aa85b34350a098e2917d74113f51da54a76db Mon Sep 17 00:00:00 2001 From: "Jokob @NetAlertX" <96159884+jokob-sk@users.noreply.github.com> Date: Thu, 20 Aug 2026 03:09:50 +0000 Subject: [PATCH 1/9] FE: Implement pause/resume functionality for automatic scans with API endpoints and UI updates --- front/js/sse_manager.js | 7 + front/php/templates/header.php | 48 ++++ front/php/templates/language/en_us.json | 2 + server/__main__.py | 230 ++++++++++-------- server/api_server/api_server_start.py | 41 ++++ server/api_server/openapi/schemas.py | 20 ++ server/app_state.py | 18 +- .../test_scan_pause_endpoints.py | 116 +++++++++ 8 files changed, 374 insertions(+), 108 deletions(-) create mode 100644 test/api_endpoints/test_scan_pause_endpoints.py diff --git a/front/js/sse_manager.js b/front/js/sse_manager.js index ae9c69039..c8536a2a5 100644 --- a/front/js/sse_manager.js +++ b/front/js/sse_manager.js @@ -186,6 +186,13 @@ class NetAlertXStateManager { })); } + // 6. Dispatch pause state update for the header Pause/Resume button + if (appState["pause_until"] !== undefined) { + document.dispatchEvent(new CustomEvent('nax:pauseStateUpdate', { + detail: { pauseUntil: appState["pause_until"] } + })); + } + // console.log("[NetAlertX State] UI updated via jQuery"); } catch (e) { console.error("[NetAlertX State] Failed to update state display:", e); diff --git a/front/php/templates/header.php b/front/php/templates/header.php index 0337c08f7..0c2b319ce 100755 --- a/front/php/templates/header.php +++ b/front/php/templates/header.php @@ -213,6 +213,12 @@ function update_servertime() { 0 + +
0 is disabled), devices that are Offline and their Last Connection date time is older than the specified hours in this setting, will be deleted. Use this setting if you want to auto-delete Offline devices after X hours being offline.",
"HRS_TO_KEEP_OFFDEV_name": "Delete offline devices after",
+ "Header_PauseScans_Tooltip": "Pause automatic scans for 10 minutes",
+ "Header_ResumeScans_Tooltip": "Resume automatic scans",
"LOADED_PLUGINS_description": "Which Plugins to load. Adding plugins might slow the application. Read more about which plugins need to be enabled, types, or scanning options in the plugins docs. Unloaded plugins will lose your settings. Only disabled plugins can be unloaded.",
"LOADED_PLUGINS_name": "Loaded plugins",
"LOG_LEVEL_description": "This setting will enable more verbose logging. Useful for debugging events writing into the database.",
diff --git a/server/__main__.py b/server/__main__.py
index 4534f9112..9f367e268 100755
--- a/server/__main__.py
+++ b/server/__main__.py
@@ -18,6 +18,7 @@
import sys
import time
import datetime
+import math
from pathlib import Path
# Register NetAlertX modules
@@ -25,7 +26,7 @@
from const import fullConfPath, sql_new_devices
from logger import mylog
from helper import filePermissions
-from utils.datetime_utils import timeNowUTC
+from utils.datetime_utils import timeNowUTC, is_datetime_future, normalizeTimeStamp
from app_state import updateState
from api import update_api, check_activity, update_GUI_port
from scan.session_events import process_scan
@@ -97,6 +98,10 @@ def main():
all_plugins = None
pm = None
+ # Tracks the last "remaining minutes" value broadcast while paused, so we only
+ # call updateState() when the displayed countdown minute actually changes.
+ last_paused_minute_broadcast = None
+
# -- SETTINGS BACKWARD COMPATIBILITY START --
# rename settings that have changed names due to code cleanup or migration to plugins
renameSettings(Path(fullConfPath))
@@ -122,113 +127,130 @@ def main():
# Update API endpoints
update_api(db, all_plugins, False)
- # proceed if 1 minute passed
- if conf.last_scan_run + datetime.timedelta(minutes=1) < conf.loop_start_time:
- # last time any scan or maintenance/upkeep was run
- conf.last_scan_run = loop_start_time
-
- # Header (also broadcasts last_scan_run to frontend via SSE / app_state.json)
- updateState("Process: Start",
- last_scan_run=loop_start_time.replace(microsecond=0).isoformat(),
- next_scan_time="")
-
- # Timestamp
- startTime = loop_start_time
- startTime = startTime.replace(microsecond=0)
-
- # Check if any plugins need to run on schedule
- pm.run_plugin_scripts("schedule")
-
- # Compute the next scheduled run time AFTER schedule check (which updates last_next_schedule)
- # Only device_scanner plugins have meaningful next_scan times for user display
- scanner_prefixes = {p["unique_prefix"] for p in all_plugins if p.get("plugin_type") == "device_scanner"}
- scanner_next = [s.last_next_schedule for s in conf.mySchedules if s.service in scanner_prefixes]
-
- # Get the earliest next scan time across all device scanners and broadcast.
- # updateState validates the value is in the future before storing/broadcasting.
- if scanner_next:
- next_scan_dt = min(scanner_next)
- updateState(next_scan_time=next_scan_dt.replace(microsecond=0).isoformat())
-
- # determine run/scan type based on passed time
- # --------------------------------------------
-
- # Runs plugin scripts which are set to run every time after a scans finished
- pm.run_plugin_scripts("always_after_scan")
-
- # process all the scanned data into new devices
- processScan = updateState("Check scan").processScan
- mylog("debug", [f"[MAIN] processScan: {processScan}"])
-
- if processScan is True:
- mylog("debug", "[MAIN] start processing scan results")
- process_scan(db)
- updateState("Scan processed", None, None, None, None, False)
-
- # Name resolution
- # --------------------------------------------
-
- # Check if new devices found (created by process_scan)
- sql.execute(sql_new_devices)
- newDevices = sql.fetchall()
- db.commitDB()
-
- # If new devices were found, run all plugins registered to be run when new devices are found
- # Run these before name resolution so plugins like NSLOOKUP that are configured
- # for `on_new_device` can populate names used in the notifications below.
- if len(newDevices) > 0:
- pm.run_plugin_scripts("on_new_device")
-
- # run plugins before notification processing (e.g. Plugins to discover device names)
- pm.run_plugin_scripts("before_name_updates")
-
- # Resolve devices names (will pick up results from on_new_device plugins above)
- mylog("debug", "[Main] Resolve devices names")
- update_devices_names(pm)
-
- # Notification handling
- # ----------------------------------------
-
- # send all configured notifications
- final_json = get_notifications(db)
-
- # Write the notifications into the DB
- notification = NotificationInstance(db)
- notificationObj = notification.create(final_json, "")
-
- # ------------------------------------------------------------------------------
- # Run all enabled publisher gateways (notification delivery)
- # ------------------------------------------------------------------------------
- # Design notes:
- # - The eve_PendingAlertEmail flag is only cleared *after* a notification is sent.
- # - If no notification is sent (HasNotifications == False), the flag stays set,
- # meaning the event may still trigger alerts later depending on user settings
- # (e.g. down-event reporting, delay timers, plugin conditions).
- # - A pending flag means “still under evaluation,” not “missed.”
- # It will clear automatically once its event is included in a sent alert.
- # ------------------------------------------------------------------------------
- if notificationObj.HasNotifications:
- pm.run_plugin_scripts("on_notification")
- notification.setAllProcessed()
-
- # Only clear pending email flags and plugins_events once notifications are sent.
- notification.clearPendingEmailFlag()
+ # Pause gate: skip the automatic scheduled-scan block below while paused.
+ # Manually-triggered scans (handled by check_and_run_user_event() above) are unaffected.
+ pause_until_dt = normalizeTimeStamp(updateState().pause_until)
- else:
- # If there are no notifications to process,
- # we still need to clear all plugin events to prevent database growth if
- # no notification gateways are configured
- notification.clearPluginEvents()
- mylog("verbose", ["[Notification] No changes to report"])
+ if pause_until_dt and is_datetime_future(pause_until_dt):
+ remaining_minutes = math.ceil((pause_until_dt - timeNowUTC(as_string=False)).total_seconds() / 60)
- # Commit SQL
- db.commitDB()
+ if remaining_minutes != last_paused_minute_broadcast:
+ updateState(f"Process: Paused for {remaining_minutes} min")
+ last_paused_minute_broadcast = remaining_minutes
- mylog("verbose", ["[MAIN] Process: Idle"])
else:
- # do something
- # mylog('verbose', ['[MAIN] Waiting to start next loop'])
- updateState("Process: Idle")
+ if last_paused_minute_broadcast is not None:
+ # Pause expired naturally (not via /scan/resume) - clear it and resume normal state
+ updateState("Process: Idle", pause_until="")
+ last_paused_minute_broadcast = None
+
+ # proceed if 1 minute passed
+ if conf.last_scan_run + datetime.timedelta(minutes=1) < conf.loop_start_time:
+ # last time any scan or maintenance/upkeep was run
+ conf.last_scan_run = loop_start_time
+
+ # Header (also broadcasts last_scan_run to frontend via SSE / app_state.json)
+ updateState("Process: Start",
+ last_scan_run=loop_start_time.replace(microsecond=0).isoformat(),
+ next_scan_time="")
+
+ # Timestamp
+ startTime = loop_start_time
+ startTime = startTime.replace(microsecond=0)
+
+ # Check if any plugins need to run on schedule
+ pm.run_plugin_scripts("schedule")
+
+ # Compute the next scheduled run time AFTER schedule check (which updates last_next_schedule)
+ # Only device_scanner plugins have meaningful next_scan times for user display
+ scanner_prefixes = {p["unique_prefix"] for p in all_plugins if p.get("plugin_type") == "device_scanner"}
+ scanner_next = [s.last_next_schedule for s in conf.mySchedules if s.service in scanner_prefixes]
+
+ # Get the earliest next scan time across all device scanners and broadcast.
+ # updateState validates the value is in the future before storing/broadcasting.
+ if scanner_next:
+ next_scan_dt = min(scanner_next)
+ updateState(next_scan_time=next_scan_dt.replace(microsecond=0).isoformat())
+
+ # determine run/scan type based on passed time
+ # --------------------------------------------
+
+ # Runs plugin scripts which are set to run every time after a scans finished
+ pm.run_plugin_scripts("always_after_scan")
+
+ # process all the scanned data into new devices
+ processScan = updateState("Check scan").processScan
+ mylog("debug", [f"[MAIN] processScan: {processScan}"])
+
+ if processScan is True:
+ mylog("debug", "[MAIN] start processing scan results")
+ process_scan(db)
+ updateState("Scan processed", None, None, None, None, False)
+
+ # Name resolution
+ # --------------------------------------------
+
+ # Check if new devices found (created by process_scan)
+ sql.execute(sql_new_devices)
+ newDevices = sql.fetchall()
+ db.commitDB()
+
+ # If new devices were found, run all plugins registered to be run when new devices are found
+ # Run these before name resolution so plugins like NSLOOKUP that are configured
+ # for `on_new_device` can populate names used in the notifications below.
+ if len(newDevices) > 0:
+ pm.run_plugin_scripts("on_new_device")
+
+ # run plugins before notification processing (e.g. Plugins to discover device names)
+ pm.run_plugin_scripts("before_name_updates")
+
+ # Resolve devices names (will pick up results from on_new_device plugins above)
+ mylog("debug", "[Main] Resolve devices names")
+ update_devices_names(pm)
+
+ # Notification handling
+ # ----------------------------------------
+
+ # send all configured notifications
+ final_json = get_notifications(db)
+
+ # Write the notifications into the DB
+ notification = NotificationInstance(db)
+ notificationObj = notification.create(final_json, "")
+
+ # ------------------------------------------------------------------------------
+ # Run all enabled publisher gateways (notification delivery)
+ # ------------------------------------------------------------------------------
+ # Design notes:
+ # - The eve_PendingAlertEmail flag is only cleared *after* a notification is sent.
+ # - If no notification is sent (HasNotifications == False), the flag stays set,
+ # meaning the event may still trigger alerts later depending on user settings
+ # (e.g. down-event reporting, delay timers, plugin conditions).
+ # - A pending flag means “still under evaluation,” not “missed.”
+ # It will clear automatically once its event is included in a sent alert.
+ # ------------------------------------------------------------------------------
+ if notificationObj.HasNotifications:
+ pm.run_plugin_scripts("on_notification")
+ notification.setAllProcessed()
+
+ # Only clear pending email flags and plugins_events once notifications are sent.
+ notification.clearPendingEmailFlag()
+
+ else:
+ # If there are no notifications to process,
+ # we still need to clear all plugin events to prevent database growth if
+ # no notification gateways are configured
+ notification.clearPluginEvents()
+ mylog("verbose", ["[Notification] No changes to report"])
+
+ # Commit SQL
+ db.commitDB()
+
+ mylog("verbose", ["[MAIN] Process: Idle"])
+ else:
+ # do something
+ # mylog('verbose', ['[MAIN] Waiting to start next loop'])
+ updateState("Process: Idle")
# WORKFLOWS handling
# ----------------------------------------
diff --git a/server/api_server/api_server_start.py b/server/api_server/api_server_start.py
index 24b55c717..c214463d4 100755
--- a/server/api_server/api_server_start.py
+++ b/server/api_server/api_server_start.py
@@ -1,6 +1,7 @@
import threading
import sys
import os
+from datetime import timedelta
# flake8: noqa: E402
@@ -18,6 +19,7 @@
from helper import get_setting_value, get_env_setting_value, getBuildTimeStampAndVersion # noqa: E402 [flake8 lint suppression]
from db.db_helper import get_date_from_period # noqa: E402 [flake8 lint suppression]
from app_state import updateState # noqa: E402 [flake8 lint suppression]
+from utils.datetime_utils import timeNowUTC # noqa: E402 [flake8 lint suppression]
from .graphql_endpoint import devicesSchema # noqa: E402 [flake8 lint suppression]
from .history_endpoint import delete_online_history # noqa: E402 [flake8 lint suppression]
@@ -82,6 +84,7 @@
DeviceImportResponse, UpdateDeviceColumnRequest,
LockDeviceFieldRequest, UnlockDeviceFieldsRequest,
CopyDeviceRequest, TriggerScanRequest,
+ PauseScanRequest, PauseScanResponse, ResumeScanResponse,
OpenPortsRequest,
OpenPortsResponse, WakeOnLanRequest,
WakeOnLanResponse, TracerouteRequest,
@@ -1168,6 +1171,44 @@ def api_trigger_scan(payload=None):
return jsonify({"success": True, "message": f"Scan triggered for type: {scan_type}"}), 200
+@app.route("/scan/pause", methods=["POST"])
+@validate_request(
+ operation_id="pause_scan_scheduler",
+ summary="Pause Scan Scheduler",
+ description="Pause the automatic scheduled scan loop for a number of minutes. "
+ "Manually-triggered scans (e.g. /nettools/trigger-scan) are not affected.",
+ request_model=PauseScanRequest,
+ response_model=PauseScanResponse,
+ tags=["nettools"],
+ validation_error_code=400,
+ auth_callable=is_authorized
+)
+def api_pause_scan(payload=None):
+ minutes = payload.minutes
+
+ pause_until = (timeNowUTC(as_string=False) + timedelta(minutes=minutes)).replace(microsecond=0).isoformat()
+
+ updateState(f"Process: Paused for {minutes} min", pause_until=pause_until)
+
+ return jsonify({"success": True, "message": f"Scans paused for {minutes} minutes", "pause_until": pause_until}), 200
+
+
+@app.route("/scan/resume", methods=["POST"])
+@validate_request(
+ operation_id="resume_scan_scheduler",
+ summary="Resume Scan Scheduler",
+ description="Clear any active scan pause and resume the automatic scan scheduler. Idempotent — "
+ "succeeds even if scans were not paused.",
+ response_model=ResumeScanResponse,
+ tags=["nettools"],
+ auth_callable=is_authorized
+)
+def api_resume_scan(payload=None):
+ updateState("Process: Idle", pause_until="")
+
+ return jsonify({"success": True, "message": "Scans resumed", "pause_until": ""}), 200
+
+
# def trigger_scan(scan_type):
# """Trigger a network scan by adding it to the execution queue."""
# if scan_type not in ["ARPSCAN", "NMAPDEV", "NMAP"]:
diff --git a/server/api_server/openapi/schemas.py b/server/api_server/openapi/schemas.py
index 86baa66ee..8103a383b 100644
--- a/server/api_server/openapi/schemas.py
+++ b/server/api_server/openapi/schemas.py
@@ -519,6 +519,26 @@ class TriggerScanResponse(BaseResponse):
scan_type: Optional[str] = Field(None, description="Type of scan that was triggered")
+class PauseScanRequest(BaseModel):
+ """Request to pause the automatic scan scheduler for a number of minutes."""
+ minutes: int = Field(
+ ...,
+ ge=1,
+ le=1440,
+ description="Number of minutes to pause automatic scans for (1-1440)"
+ )
+
+
+class PauseScanResponse(BaseResponse):
+ """Response for pausing the automatic scan scheduler."""
+ pause_until: Optional[str] = Field(None, description="ISO timestamp scans are paused until")
+
+
+class ResumeScanResponse(BaseResponse):
+ """Response for resuming the automatic scan scheduler."""
+ pause_until: Optional[str] = Field(None, description="Always empty; confirms the pause was cleared")
+
+
class OpenPortsRequest(BaseModel):
"""Request for getting open ports."""
target: str = Field(
diff --git a/server/app_state.py b/server/app_state.py
index aab57cda7..ba1bef4e0 100755
--- a/server/app_state.py
+++ b/server/app_state.py
@@ -45,7 +45,8 @@ def __init__(
appVersion=None,
buildTimestamp=None,
last_scan_run=None,
- next_scan_time=None
+ next_scan_time=None,
+ pause_until=None
):
"""
Initialize the application state, optionally overwriting previous values.
@@ -93,6 +94,7 @@ def __init__(
self.buildTimestamp = previousState.get("buildTimestamp", "")
self.last_scan_run = previousState.get("last_scan_run", "")
self.next_scan_time = previousState.get("next_scan_time", "")
+ self.pause_until = previousState.get("pause_until", "")
else: # init first time values
self.settingsSaved = 0
self.settingsImported = 0
@@ -107,6 +109,7 @@ def __init__(
self.buildTimestamp = ""
self.last_scan_run = ""
self.next_scan_time = ""
+ self.pause_until = ""
# Overwrite with provided parameters if supplied
if settingsSaved is not None:
@@ -148,6 +151,9 @@ def __init__(
self.next_scan_time = next_scan_time
else:
self.next_scan_time = ""
+ # "" explicitly clears the pause (resume); a truthy value sets/extends it
+ if pause_until is not None:
+ self.pause_until = pause_until
# check for new version every hour and if currently not running new version
if self.isNewVersion is False and self.isNewVersionChecked + 3600 < int(
timeNowUTC(as_string=False).timestamp()
@@ -182,7 +188,8 @@ def __init__(
appVersion=self.appVersion,
buildTimestamp=self.buildTimestamp,
last_scan_run=self.last_scan_run,
- next_scan_time=self.next_scan_time
+ next_scan_time=self.next_scan_time,
+ pause_until=self.pause_until
)
except Exception as e:
mylog("none", [f"[app_state] SSE broadcast: {e}"])
@@ -202,7 +209,8 @@ def updateState(newState = None,
appVersion=None,
buildTimestamp=None,
last_scan_run=None,
- next_scan_time=None):
+ next_scan_time = None,
+ pause_until = None):
"""
Convenience method to create or update the app state.
@@ -218,6 +226,7 @@ def updateState(newState = None,
buildTimestamp (str, optional): Build timestamp.
last_scan_run (str, optional): ISO timestamp of last backend scan run.
next_scan_time (str, optional): ISO timestamp of next scheduled device_scanner run.
+ pause_until (str, optional): ISO timestamp scans are paused until; "" clears the pause.
Returns:
app_state_class: Updated state object.
@@ -233,7 +242,8 @@ def updateState(newState = None,
appVersion,
buildTimestamp,
last_scan_run,
- next_scan_time
+ next_scan_time,
+ pause_until
)
diff --git a/test/api_endpoints/test_scan_pause_endpoints.py b/test/api_endpoints/test_scan_pause_endpoints.py
new file mode 100644
index 000000000..470225067
--- /dev/null
+++ b/test/api_endpoints/test_scan_pause_endpoints.py
@@ -0,0 +1,116 @@
+import pytest
+from unittest.mock import patch, MagicMock
+
+from api_server.api_server_start import app
+from helper import get_setting_value
+
+
+@pytest.fixture(scope="session")
+def api_token():
+ return get_setting_value("API_TOKEN")
+
+
+@pytest.fixture
+def client():
+ with app.test_client() as client:
+ yield client
+
+
+def auth_headers(token):
+ return {"Authorization": f"Bearer {token}"}
+
+
+# --- /scan/pause ---
+
+
+@patch("api_server.api_server_start.updateState")
+def test_pause_scan_success(mock_update_state, client, api_token):
+ """Valid minutes value pauses scans and returns a future pause_until timestamp."""
+ mock_update_state.return_value = MagicMock()
+
+ response = client.post("/scan/pause", json={"minutes": 10}, headers=auth_headers(api_token))
+
+ assert response.status_code == 200
+ data = response.get_json()
+ assert data["success"] is True
+ assert "pause_until" in data and data["pause_until"]
+
+ mock_update_state.assert_called_once()
+ args, kwargs = mock_update_state.call_args
+ assert args[0] == "Process: Paused for 10 min"
+ assert kwargs["pause_until"] == data["pause_until"]
+
+
+@patch("api_server.api_server_start.updateState")
+def test_pause_scan_default_minutes_used(mock_update_state, client, api_token):
+ """The header button's default 10-minute pause request is accepted."""
+ mock_update_state.return_value = MagicMock()
+
+ response = client.post("/scan/pause", json={"minutes": 10}, headers=auth_headers(api_token))
+
+ assert response.status_code == 200
+ assert response.get_json()["success"] is True
+
+
+@pytest.mark.parametrize("minutes", [0, -5, 1441, "ten"])
+def test_pause_scan_invalid_minutes(client, api_token, minutes):
+ """Out-of-bounds or non-integer minutes values are rejected with a 400."""
+ response = client.post("/scan/pause", json={"minutes": minutes}, headers=auth_headers(api_token))
+
+ assert response.status_code == 400
+ data = response.get_json()
+ assert data["success"] is False
+
+
+def test_pause_scan_missing_minutes(client, api_token):
+ """Missing 'minutes' field is rejected with a 400."""
+ response = client.post("/scan/pause", json={}, headers=auth_headers(api_token))
+
+ assert response.status_code == 400
+ assert response.get_json()["success"] is False
+
+
+def test_pause_scan_requires_auth(client):
+ """Unauthenticated requests are rejected."""
+ response = client.post("/scan/pause", json={"minutes": 10})
+
+ assert response.status_code == 403
+
+
+# --- /scan/resume ---
+
+
+@patch("api_server.api_server_start.updateState")
+def test_resume_scan_success(mock_update_state, client, api_token):
+ """Resume clears the pause and reports pause_until as empty."""
+ mock_update_state.return_value = MagicMock()
+
+ response = client.post("/scan/resume", headers=auth_headers(api_token))
+
+ assert response.status_code == 200
+ data = response.get_json()
+ assert data["success"] is True
+ assert data["pause_until"] == ""
+
+ mock_update_state.assert_called_once_with("Process: Idle", pause_until="")
+
+
+@patch("api_server.api_server_start.updateState")
+def test_resume_scan_idempotent_when_not_paused(mock_update_state, client, api_token):
+ """Calling resume when scans are not paused still succeeds (idempotent)."""
+ mock_update_state.return_value = MagicMock()
+
+ response = client.post("/scan/resume", headers=auth_headers(api_token))
+ response2 = client.post("/scan/resume", headers=auth_headers(api_token))
+
+ assert response.status_code == 200
+ assert response2.status_code == 200
+ assert response.get_json()["success"] is True
+ assert response2.get_json()["success"] is True
+
+
+def test_resume_scan_requires_auth(client):
+ """Unauthenticated requests are rejected."""
+ response = client.post("/scan/resume")
+
+ assert response.status_code == 403
From 7a21bad8bec6828c38b923732c643c806e6e043c Mon Sep 17 00:00:00 2001
From: jokob-sk 0 està desactivat), els dispositius que estan Offline i el seu temps Last Offline es més vell que les hores especificades en aquest paràmetre, s'esborraran. Faci servir aquest paràmetre si vol auto-eliminar Dispositius Offline després de X hores sense connexió.",
"HRS_TO_KEEP_OFFDEV_name": "Eliminar dispositius fora de línia després",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "Quins Plugins carregar. Afegir plugins podria alentir l'aplicació. Llegir més sobre quins connectors necessiten estar habilitats, els tipus, o les opcions d'escaneig dins del documents de connectors. Els connectors descarregats perdran els vostres paràmetres. Només desactivats es poden eliminar els connectors.",
"LOADED_PLUGINS_name": "Connectors carregats",
"LOG_LEVEL_description": "Aquest paràmetre permetrà un registre més detallat. Útil per a la depuració d'esdeveniments d'escriptura a la base de dades.",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "La majoria dels escàners en xarxa (ARP-SCAN, NMAP, NSLOOKUP, DIG) es basen en l'exploració d'interfícies de xarxa específiques i subxarxes. Comproveu la documentació de subxarxes per ajudar en aquesta configuració, especialment VLANs, i quines VLANs són compatibles, o com esbrinar la màscara de xarxa i la seva interfície. 0 zakázáno), zařízení Offline a data jejich Posledního připojení starší, než uvedené hodiny v tomto nastavení, budou odstraněna. Toto nastavení použijte, pokud chcete automaticky mazat Offline zařízení po uplynutí X hodin offline.",
"HRS_TO_KEEP_OFFDEV_name": "Odstranit offline zařízení po",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "Které zásuvné moduly načíst. Přidávání modulů může aplikaci zpomalit. Přečtěte si více o tom, které, které je třeba, aby byly povolené, o jejich typech nebo o předvolbách skenování v dokumentaci k zásuvným modulům. Odpojené moduly ztratí vaše nastavení. Odpojit je možné pouze deaktivované moduly.",
"LOADED_PLUGINS_name": "Načtené moduly",
"LOG_LEVEL_description": "Toto nastavení zapne podrobnější zaznamenávání událostí. To je užitečné pro ladění událostí zapisujících do databáze.",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "Většina skenerů sítí (ARP-SCAN, NMAP, NSLOOKUP, DIG) spoléhá na skenování konkrétních síťových rozhraní a podsítí. Podívejte se do dokumentace k podsítím ohledně pokynů k tomuto uspořádání, zejména VLAN sítím, ohledně toho, které VLAN sítě jsou podporovány nebo jak nastavit masku sítě na svém rozhraní. 0 is disabled), devices that are Offline and their Last Connection date time is older than the specified hours in this setting, will be deleted. Use this setting if you want to auto-delete Offline devices after X hours being offline.",
"HRS_TO_KEEP_OFFDEV_name": "Delete offline devices after",
- "Header_PauseScans_Tooltip": "Pause automatic scans for 10 minutes",
+ "Header_PauseScans_Tooltip": "Pause automatic scans",
"Header_ResumeScans_Tooltip": "Resume automatic scans",
"LOADED_PLUGINS_description": "Which Plugins to load. Adding plugins might slow the application. Read more about which plugins need to be enabled, types, or scanning options in the plugins docs. Unloaded plugins will lose your settings. Only disabled plugins can be unloaded.",
"LOADED_PLUGINS_name": "Loaded plugins",
@@ -647,6 +647,8 @@
"SCAN_SUBNETS_description": "Most on-network scanners (ARP-SCAN, NMAP, NSLOOKUP, DIG) rely on scanning specific network interfaces and subnets. Check the subnets documentation for help on this setting, especially VLANs, what VLANs are supported, or how to figure out the network mask and your interface. 0 está desactivado), los dispositivos que están Sin Conexión y su fecha de Última Conexión es anterior a las horas especificadas en este ajuste se eliminarán. Use este ajuste si desea eliminar automáticamente los dispositivos sin conexión después de que el X horas esté sin conexión.",
"HRS_TO_KEEP_OFFDEV_name": "Borrar dispositivos sin conexión después de",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "¿Qué plugins cargar?. Agregar plugins puede ralentizar la aplicación. Obtén más información sobre los complementos que deben habilitarse, los tipos o las opciones de escaneo en los documentos de plugins. Los plugins descargados perderán tu configuración. Solo se pueden descargar los complementos deshabilitados.",
"LOADED_PLUGINS_name": "Plugins cargados",
"LOG_LEVEL_description": "Esto hará que el registro tenga más información. Util para depurar que eventos se van guardando en la base de datos.",
@@ -704,6 +706,8 @@
"SMTP_USER_description": "El nombre de usuario utilizado para iniciar sesión en el servidor SMTP (a veces, una dirección de correo electrónico completa).",
"SMTP_USER_name": "Nombre de usuario SMTP",
"SYSTEM_TITLE": "Información del sistema",
+ "Scans_Paused": "",
+ "Scans_Resumed": "",
"Setting_Override": "Sobreescribir el valor",
"Setting_Override_Description": "Habilitar esta opción anulará un valor predeterminado proporcionado por la aplicación con el valor especificado anteriormente.",
"Settings_Metadata_Toggle": "Mostrar/ocultar los metadatos de la configuración.",
diff --git a/front/php/templates/language/fa_fa.json b/front/php/templates/language/fa_fa.json
index 0835e9dad..53fb364b2 100644
--- a/front/php/templates/language/fa_fa.json
+++ b/front/php/templates/language/fa_fa.json
@@ -387,6 +387,8 @@
"HRS_TO_KEEP_NEWDEV_name": "",
"HRS_TO_KEEP_OFFDEV_description": "",
"HRS_TO_KEEP_OFFDEV_name": "",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "",
"LOADED_PLUGINS_name": "",
"LOG_LEVEL_description": "",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "",
"SCAN_SUBNETS_name": "",
"SYSTEM_TITLE": "",
+ "Scans_Paused": "",
+ "Scans_Resumed": "",
"Setting_Override": "",
"Setting_Override_Description": "",
"Settings_Metadata_Toggle": "",
diff --git a/front/php/templates/language/fi_fi.json b/front/php/templates/language/fi_fi.json
index 3e01e76d6..abbeaad76 100644
--- a/front/php/templates/language/fi_fi.json
+++ b/front/php/templates/language/fi_fi.json
@@ -387,6 +387,8 @@
"HRS_TO_KEEP_NEWDEV_name": "",
"HRS_TO_KEEP_OFFDEV_description": "",
"HRS_TO_KEEP_OFFDEV_name": "",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "",
"LOADED_PLUGINS_name": "",
"LOG_LEVEL_description": "",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "",
"SCAN_SUBNETS_name": "",
"SYSTEM_TITLE": "",
+ "Scans_Paused": "",
+ "Scans_Resumed": "",
"Setting_Override": "",
"Setting_Override_Description": "",
"Settings_Metadata_Toggle": "",
diff --git a/front/php/templates/language/fr_fr.json b/front/php/templates/language/fr_fr.json
index 300815994..41221ac23 100644
--- a/front/php/templates/language/fr_fr.json
+++ b/front/php/templates/language/fr_fr.json
@@ -387,6 +387,8 @@
"HRS_TO_KEEP_NEWDEV_name": "Supprimer les nouveaux appareils après",
"HRS_TO_KEEP_OFFDEV_description": "Il s'agit d'un paramètre de maintenance SUPPRIMER des appareils. Si cette option est activée (0 est désactivé), les appareils qui sont Hors ligne et dont la dernière connexion est plus ancienne que les heures spécifiées dans ce paramètre. Utilisez ce paramètre si vous souhaitez supprimer automatiquement Appareils hors ligne après X heures de déconnexion.",
"HRS_TO_KEEP_OFFDEV_name": "Supprimez les appareils hors ligne après",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "Affiche les plugins chargés. Ajouter des plugins peut ralentir l'application. Obtenez plus d'informations dur quels plugins dont à activer, ou les options de scan dans la documentation des plugins. Décharger des plugins leur fait perdre leurs paramètres. Seuls les plugins désactivés peuvent être déchargés.",
"LOADED_PLUGINS_name": "Plugins chargés",
"LOG_LEVEL_description": "Ce paramètre active une journalisation dans les logs plus verbeuse. Cela est utile pour identifier les événements écrivant dans la base de données.",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "La plupart des scanners sur le réseau (scan ARP, NMAP, Nslookup, DIG) se base sur le scan d'une partie spécifique des interfaces réseau ou de sous-réseau. Consulter la documentation des sous-réseaux pour plus d'aide sur ce paramètre, notamment pour des VLAN, lesquels sont supportés ou sur comment identifier le masque réseau et votre interface réseau. 0 è disabilitata), i dispositivi Offline la cui data e ora di Ultima connessione sono antecedenti alle ore specificate in questa impostazione, verranno eliminati. Utilizza questa impostazione se vuoi eliminare automaticamente i Dispositivi offline dopo X ore trascorse offline.",
"HRS_TO_KEEP_OFFDEV_name": "Elimina dispositivi offline dopo",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "Quali Plugin caricare. L'aggiunta di plugin potrebbe rallentare l'applicazione. Leggi di più su quali plugin necessitano di essere abilitati, tipi e opzioni di scansione nella documentazione plugin. I plugin disinstallati perdono la loro configurazione. Solo i plugin disabilitati possono essere disinstallati.",
"LOADED_PLUGINS_name": "Plugin caricati",
"LOG_LEVEL_description": "Questa impostazione abilita un log più dettagliato. Utile per il debug degli eventi salvati nel database.",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "La maggior parte degli scanner di rete (ARP-SCAN, NMAP, NSLOOKUP, DIG) si basano sulla scansione di interfacce di rete e sottoreti specifiche. Consulta la documentazione sulle sottoreti per assistenza su questa impostazione, in particolare VLAN, quali VLAN sono supportate o come individuare la maschera di rete e l'interfaccia. 0 で無効)、オフライン 状態のデバイスの内、最終接続日時 が指定された時間より古いものは削除されます。オフラインデバイス を X 時間経過後に自動削除したい場合に使用してください。",
"HRS_TO_KEEP_OFFDEV_name": "オフラインデバイスを削除する",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "読み込まれたプラグイン。プラグインの追加はアプリケーションの速度を低下させる可能性があります。有効化が必要なプラグインの種類やスキャンオプションについては、プラグインのドキュメント を参照してください。読み込まれなかったプラグインの設定は失われます。読み込まない設定にできるのは 無効化 されたプラグインのみです。",
"LOADED_PLUGINS_name": "読み込まれたプラグイン",
"LOG_LEVEL_description": "この設定により、より詳細なログ出力が有効になります。データベースへのイベント書き込みのデバッグに有用です。",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "ほとんどのネットワーク内スキャナー(ARP-SCAN、NMAP、NSLOOKUP、DIG)は、特定のネットワークインターフェースとサブネットをスキャンすることに依存しています。この設定に関するヘルプについては、サブネットのドキュメント を確認してください。特にVLAN、サポートされているVLANの種類、ネットワークマスクとインターフェースの確認方法についてです。deaktiverte plugins kan lastes ut.",
"LOADED_PLUGINS_name": "Lastede plugins",
"LOG_LEVEL_description": "Denne innstillingen vil aktivere mer detaljert logging. Nyttig for feilsøking av hendelser som skrives inn i databasen.",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "De fleste skannere på nettet (ARP-Scan, NMAP, NSlookup, Dig) er avhengige av å skanne spesifikke nettverksgrensesnitt og undernett. Sjekk subnett dokumentasjonen for hjelp på denne innstillingen, spesielt VLAN-er, hvilke VLAN-er som støttes, eller hvordan du kan finne ut nettverksmasken og grensesnittet ditt. 0 oznacza wyłączone), urządzenia, które są Offline i których ostatnie połączenie miało miejsce wcześniej niż określona liczba godzin w tym ustawieniu, zostaną usunięte. Skorzystaj z tej opcji, jeśli chcesz automatycznie usuwać urządzenia offline po X godzinach braku aktywności.",
"HRS_TO_KEEP_OFFDEV_name": "Usuń urządzenia niedostępne po",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "Które wtyczki mają zostać załadowane. Dodanie wtyczek może spowolnić działanie aplikacji. Więcej informacji o tym, które wtyczki należy włączyć, jakie są ich typy oraz dostępne opcje skanowania znajdziesz w dokumentacji wtyczek. Wtyczki, które nie zostaną załadowane, utracą swoje ustawienia. Tylko wtyczki oznaczone jako disabled mogą zostać pominięte przy ładowaniu.",
"LOADED_PLUGINS_name": "Załadowane wtyczki",
"LOG_LEVEL_description": "To ustawienie włącza bardziej szczegółowe logowanie. Przydatne do debugowania zdarzeń zapisywanych w bazie danych.",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "Większość skanerów sieciowych (ARP-SCAN, NMAP, NSLOOKUP, DIG) polega na skanowaniu określonych interfejsów sieciowych i podsieci. Zapoznaj się z dokumentacją podsieci, aby uzyskać pomoc w konfiguracji tego ustawienia, szczególnie w kontekście VLAN-ów, jakie VLAN-y są obsługiwane, lub jak ustalić maskę sieciową i interfejs. 0 está desabilitado), dispositivos que estão Offline e sua data e hora Last Offline são mais antigas que as horas especificadas nesta configuração, serão deletados. Use esta configuração se você quiser remover automaticamente Dispositivos Offline após X horas offline.",
"HRS_TO_KEEP_OFFDEV_name": "Eliminar dispositivos offline após",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "Quais plugins carregar. Adicionar plugins pode deixar o aplicativo lento. Leia mais sobre quais plugins precisam ser habilitados, tipos ou opções de escaneamento na documentação de plugins. Plugins descarregados perderão as suas configurações. Somente plugins desabilitados podem ser descarregados.",
"LOADED_PLUGINS_name": "Plugins carregados",
"LOG_LEVEL_description": "Esta definição permite um registo mais detalhado. Útil para depurar eventos gravados na base de dados.",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "",
"SCAN_SUBNETS_name": "",
"SYSTEM_TITLE": "",
+ "Scans_Paused": "",
+ "Scans_Resumed": "",
"Setting_Override": "",
"Setting_Override_Description": "",
"Settings_Metadata_Toggle": "",
diff --git a/front/php/templates/language/pt_pt.json b/front/php/templates/language/pt_pt.json
index 931bd9d1d..4ba807744 100644
--- a/front/php/templates/language/pt_pt.json
+++ b/front/php/templates/language/pt_pt.json
@@ -387,6 +387,8 @@
"HRS_TO_KEEP_NEWDEV_name": "Remover novos dispostivos depois",
"HRS_TO_KEEP_OFFDEV_description": "Isto é uma definição de manutenção ELIMINAR dispositivos. Se ativado (0 é desativado), dispositivos que estão Offline e a sua data de Última conexão foi mais antigo que as horas especificadas nesta definição, será eliminado. Use esta definição se quer auto-eliminar Dispositivos Offline após X horas de estarem offline.",
"HRS_TO_KEEP_OFFDEV_name": "Apagar dispositivos offline após",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "Quais plugins carregar. Adicionar plugins pode deixar a aplicação lenta. Leia mais sobre quais plugins precisam ser ativados, tipos ou opções de escaneamento na documentação de plugins. Plugins descarregados perderão as suas configurações. Somente plugins desativados podem ser descarregados.",
"LOADED_PLUGINS_name": "Plugins carregados",
"LOG_LEVEL_description": "Esta definição permite um registo mais detalhado. Útil para depurar eventos gravados na base de dados.",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "A maior parte dos scanners on-network (ARP-SCAN, NMAP, NSLOOKUP, DIG) baseiam-se em scanear interfaces de rede específicas e subredes. Veja a documentação de subredes para ajudar com esta definição, especialmente VLANs, quais VLANs são suportadas, ou como descobrir a máscara de rede e a sua interface. 0 отключен), устройства, которые находятся в Offline и их дата и время последнего подключения старше, чем часы, указанные в этом параметре. Используйте этот параметр, если вы хотите автоматически удалять Offline устройства после X часов отсутствия в сети.",
"HRS_TO_KEEP_OFFDEV_name": "Удалить устройства Offline после",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "Какие плагины загружать. Добавление плагинов может замедлить работу приложения. Подробнее о том, какие плагины необходимо включить, их типах или параметрах сканирования, читайте в Документация по плагинам. Выгруженные плагины потеряют ваши настройки. Можно выгрузить только отключенные плагины.",
"LOADED_PLUGINS_name": "Загруженные плагины",
"LOG_LEVEL_description": "Этот параметр включит более подробное ведение журнала. Полезно для отладки записи событий в базу данных.",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "Большинство сетевых сканеров (ARP-SCAN, NMAP, NSLOOKUP, DIG) полагаются на сканирование определенных сетевых интерфейсов и подсетей. Дополнительную информацию по этому параметру можно найти в документации по подсетям, особенно VLAN, какие VLAN поддерживаются или как разобраться в маске сети и своем интерфейсе. 0 devre dışıdır), Çevrimdışı olan ve Son Çevrimdışı tarihi belirtilen saatten daha eski olan cihazlar silinecektir. Bu ayarı, X saat çevrimdışı olduktan sonra Çevrimdışı Cihazları otomatik olarak silmek için kullanabilirsiniz.",
"HRS_TO_KEEP_OFFDEV_name": "Çevrimdışı Cihazları Silmeden Önce",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "Hangi Eklentilerin Yükleneceği. Eklenti eklemek, uygulamanın hızını yavaşlatabilir. Hangi eklentilerin etkinleştirilmesi gerektiği, türler veya tarama seçenekleri hakkında daha fazla bilgi için eklentiler belgelerini okuyun. Yüklenmeyen eklentiler, ayarlarınızı kaybedecektir. Sadece devre dışı bırakılmış eklentiler yüklenebilir.",
"LOADED_PLUGINS_name": "Yüklenen Eklentiler",
"LOG_LEVEL_description": "Bu ayar, daha ayrıntılı günlüklemeyi etkinleştirecektir. Veritabanına yazılan olayları hata ayıklamak için faydalıdır.",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "",
"SCAN_SUBNETS_name": "",
"SYSTEM_TITLE": "",
+ "Scans_Paused": "",
+ "Scans_Resumed": "",
"Setting_Override": "",
"Setting_Override_Description": "",
"Settings_Metadata_Toggle": "",
diff --git a/front/php/templates/language/uk_ua.json b/front/php/templates/language/uk_ua.json
index bfd006715..ee5ea9901 100644
--- a/front/php/templates/language/uk_ua.json
+++ b/front/php/templates/language/uk_ua.json
@@ -387,6 +387,8 @@
"HRS_TO_KEEP_NEWDEV_name": "Видаліть нові пристрої після",
"HRS_TO_KEEP_OFFDEV_description": "Це налаштування обслуговування ВИДАЛЕННЯ пристроїв. Якщо ввімкнено (0 вимкнено), пристрої, які офлайн, та їх Останнє підключення дата та час старіші за вказані години в цьому налаштуванні, будуть видалені. Використовуйте це налаштування, якщо ви хочете автоматично видаляти офлайн-пристрої після X годин перебування в мережі.",
"HRS_TO_KEEP_OFFDEV_name": "Видаліть офлайн-пристрої після",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "Які плагіни завантажити. Додавання плагінів може уповільнити роботу програми. Дізнайтеся більше про те, які плагіни потрібно ввімкнути, типи чи параметри сканування в документи плагінів. Вивантажені плагіни втратять налаштування. Лише вимкнені плагіни можна вивантажити.",
"LOADED_PLUGINS_name": "Завантажені плагіни",
"LOG_LEVEL_description": "Цей параметр увімкне докладніше журналювання. Корисно для налагодження запису подій у базу даних.",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "Більшість мережевих сканерів (ARP-SCAN, NMAP, NSLOOKUP, DIG) покладаються на сканування конкретних мережевих інтерфейсів і підмереж. Перегляньте документацію підмереж, щоб отримати допомогу щодо цього налаштування, особливо VLAN, які VLAN підтримуються або як визначити маску мережі та ваш інтерфейс. 0是禁用),任何上次连接时间比设置里存的指定时间长的离线设备都会被删除。要是您想在X小时后自动删除离线设备,请用这个设置。",
"HRS_TO_KEEP_OFFDEV_name": "保留离线设备",
+ "Header_PauseScans_Tooltip": "",
+ "Header_ResumeScans_Tooltip": "",
"LOADED_PLUGINS_description": "加载哪些插件。添加插件可能会降低应用程序的速度。在插件文档中详细了解需要启用哪些插件、插件类型或扫描选项。卸载插件将丢失您的设置。只有已禁用的插件才能卸载。",
"LOADED_PLUGINS_name": "已加载插件",
"LOG_LEVEL_description": "此设置将启用更详细的日志记录。对于调试写入数据库的事件很有用。",
@@ -645,6 +647,8 @@
"SCAN_SUBNETS_description": "大多数网络扫描器(ARP-SCAN、NMAP、NSLOOKUP、DIG)依赖于扫描特定的网络接口和子网。查看子网文档以获取有关此设置的帮助,尤其是 VLAN、支持哪些 VLAN,或者如何确定网络掩码和接口。1 to 1440."
+ }
+ ]
+ },
{
"function": "REFRESH",
"type": {
@@ -271,7 +300,7 @@
"description": [
{
"language_code": "en_us",
- "string": "Default number of items shown in tables per page, for example in teh Devices lists."
+ "string": "Default number of items shown in tables per page, for example in the Devices lists."
}
]
},
From 9eedaaeade0116ad6209c7add3bdecc4e2ff7fe8 Mon Sep 17 00:00:00 2001
From: jokob-sk