diff --git a/docs/API.md b/docs/API.md index ea5a6aa4..97486102 100755 --- a/docs/API.md +++ b/docs/API.md @@ -63,6 +63,7 @@ http://:/ * [Online History](API_ONLINEHISTORY.md) – Online/offline device records * [GraphQL](API_GRAPHQL.md) – Advanced queries and filtering * [Sync](API_SYNC.md) – Synchronization between multiple NetAlertX instances +* [DB query](API_DBQUERY.md) (⚠ Internal) - Low level database access - use other endpoints if possible See [Testing](API_TESTS.md) for example requests and usage. diff --git a/docs/API_DBQUERY.md b/docs/API_DBQUERY.md new file mode 100755 index 00000000..05c2ae4a --- /dev/null +++ b/docs/API_DBQUERY.md @@ -0,0 +1,141 @@ +# Database Query API + +The **Database Query API** provides direct, low-level access to the NetAlertX database. It allows **read, write, update, and delete** operations against tables, using **base64-encoded** SQL or structured parameters. + +> [!Warning] +> This API is primarily used internally to generate and render the application UI. These endpoints are low-level and powerful, and should be used with caution. Wherever possible, prefer the [standard API endpoints](API.md). Invalid or unsafe queries can corrupt data. +> If you need data in a specific format that is not already provided, please open an issue or pull request with a clear, broadly useful use case. This helps ensure new endpoints benefit the wider community rather than relying on raw database queries. + +--- + +## Authentication + +All `/dbquery/*` endpoints require an API token in the HTTP headers: + +```http +Authorization: Bearer +``` + +If the token is missing or invalid: + +```json +{ "error": "Forbidden" } +``` + +--- + +## Endpoints + +### 1. `POST /dbquery/read` + +Execute a **read-only** SQL query (e.g., `SELECT`). + +#### Request Body + +```json +{ + "rawSql": "U0VMRUNUICogRlJPTSBERVZJQ0VT" // base64 encoded SQL +} +``` + +Decoded SQL: + +```sql +SELECT * FROM Devices; +``` + +#### Response + +```json +{ + "success": true, + "results": [ + { "devMac": "AA:BB:CC:DD:EE:FF", "devName": "Phone" } + ] +} +``` + +--- + +### 2. `POST /dbquery/update` (safer than `/dbquery/write`) + +Update rows in a table by `columnName` + `id`. `/dbquery/update` is parameterized to reduce the risk of SQL injection, while `/dbquery/write` executes raw SQL directly. + +#### Request Body + +```json +{ + "columnName": "devMac", + "id": ["AA:BB:CC:DD:EE:FF"], + "dbtable": "Devices", + "columns": ["devName", "devOwner"], + "values": ["Laptop", "Alice"] +} +``` + +#### Response + +```json +{ "success": true, "updated_count": 1 } +``` + +--- + +### 3. `POST /dbquery/write` + +Execute a **write query** (`INSERT`, `UPDATE`, `DELETE`). + +#### Request Body + +```json +{ + "rawSql": "SU5TRVJUIElOVE8gRGV2aWNlcyAoZGV2TWFjLCBkZXYgTmFtZSwgZGV2Rmlyc3RDb25uZWN0aW9uLCBkZXZMYXN0Q29ubmVjdGlvbiwgZGV2TGFzdElQKSBWQUxVRVMgKCc2QTpCQjo0Qzo1RDo2RTonLCAnVGVzdERldmljZScsICcyMDI1LTA4LTMwIDEyOjAwOjAwJywgJzIwMjUtMDgtMzAgMTI6MDA6MDAnLCAnMTAuMC4wLjEwJyk=" +} + +``` + +Decoded SQL: + +```sql +INSERT INTO Devices (devMac, devName, devFirstConnection, devLastConnection, devLastIP) +VALUES ('6A:BB:4C:5D:6E', 'TestDevice', '2025-08-30 12:00:00', '2025-08-30 12:00:00', '10.0.0.10'); + +``` + +#### Response + +```json +{ "success": true, "affected_rows": 1 } +``` + + +--- + +### 4. `POST /dbquery/delete` + +Delete rows in a table by `columnName` + `id`. + +#### Request Body + +```json +{ + "columnName": "devMac", + "id": ["AA:BB:CC:DD:EE:FF"], + "dbtable": "Devices" +} +``` + +#### Response + +```json +{ "success": true, "deleted_count": 1 } +``` + +--- + +## Notes & Best Practices + +* All queries must be **base64 encoded** when passed as `rawSql`. +* `update` and `delete` endpoints use **structured parameters** to prevent SQL injection. +* Avoid large or complex queries in `read` — paginate results instead. +* Always validate queries in a safe environment before running them via API. diff --git a/front/php/templates/language/ru_ru.json b/front/php/templates/language/ru_ru.json old mode 100644 new mode 100755 index 3079bfca..268befb5 --- a/front/php/templates/language/ru_ru.json +++ b/front/php/templates/language/ru_ru.json @@ -107,7 +107,7 @@ "DevDetail_Network_Node_hover": "Выберите родительское сетевое устройство, к которому подключено текущее устройство, чтобы заполнить дерево сети.", "DevDetail_Network_Port_hover": "Порт, к которому подключено это устройство на родительском сетевом устройстве. Если оставить пустым, в дереве сети отобразится значок Wi-Fi.", "DevDetail_Nmap_Scans": "Ручные сканеры Nmap", - "DevDetail_Nmap_Scans_desc": "Здесь вы можете выполнить сканирование NMAP вручную. Вы также можете запланировать регулярное автоматическое сканирование NMAP с помощью плагина «Службы и порты» (NMAP). Чтобы узнать больше, перейдите в Документацию", + "DevDetail_Nmap_Scans_desc": "Здесь вы можете выполнить сканирование NMAP вручную. Вы также можете запланировать регулярное автоматическое сканирование NMAP с помощью плагина «Службы и порты» (NMAP). Чтобы узнать больше, перейдите в Настройки", "DevDetail_Nmap_buttonDefault": "Сканирование по умолчанию", "DevDetail_Nmap_buttonDefault_text": "Сканирование по умолчанию: Nmap сканирует 1000 верхних портов для каждого запрошенного протокола сканирования. Это перехватывает примерно 93% портов TCP и 49% портов UDP. (около 5 секунд)", "DevDetail_Nmap_buttonDetail": "Детальное сканирование", @@ -301,7 +301,7 @@ "Gen_Cancel": "Отмена", "Gen_Change": "Изменить", "Gen_Copy": "Запустить", - "Gen_CopyToClipboard": "Копировать в буфер обмена", + "Gen_CopyToClipboard": "", "Gen_DataUpdatedUITakesTime": "ОК - Обновление UI может занять некоторое время, если сканирование выполняется.", "Gen_Delete": "Удалить", "Gen_DeleteAll": "Удалить все", @@ -309,9 +309,9 @@ "Gen_Error": "Ошибка", "Gen_Filter": "Фильтр", "Gen_Generate": "Генерировать", - "Gen_InvalidMac": "Неверный Mac-адрес.", + "Gen_InvalidMac": "", "Gen_LockedDB": "ОШИБКА - Возможно, база данных заблокирована. Проверьте инструменты разработчика F12 -> Консоль или повторите попытку позже.", - "Gen_NetworkMask": "Маска сети", + "Gen_NetworkMask": "", "Gen_Offline": "Оффлайн", "Gen_Okay": "OK", "Gen_Online": "Онлайн", @@ -329,7 +329,7 @@ "Gen_SelectIcon": "", "Gen_SelectToPreview": "Выберите для предварительного просмотра", "Gen_Selected_Devices": "Выбранные устройства:", - "Gen_Subnet": "Подсеть", + "Gen_Subnet": "", "Gen_Switch": "Переключить", "Gen_Upd": "Успешное обновление", "Gen_Upd_Fail": "Не удалось обновить", @@ -567,7 +567,7 @@ "Presence_Key_OnlineNow_desc": "Устройство, обнаруженное при последнем сканировании как подключенное к сети.", "Presence_Key_OnlinePast": "В прошлом в сети", "Presence_Key_OnlinePastMiss": "В прошлом в сети (несовпадение)", - "Presence_Key_OnlinePastMiss_desc": "Устройство в прошлом было подключено к сети, но сейчас находится в автономном режиме, однако стартовый сеанс может отсутствовать или иметь противоречивые данные.", + "Presence_Key_OnlinePastMiss_desc": "Устройство в прошлом было подключено к сети, но сейчас находится в автономном режиме, однако стартовый сеанс может отсутствовать или иметь противоречивые данные. (Возможно, это ошибка — отправьте PR, если знаете, как это исправить — здесь я немного запутался в коде)", "Presence_Key_OnlinePast_desc": "Устройство раньше было в сети, но в настоящее время не в сети.", "Presence_Loading": "Загрузка…", "Presence_Shortcut_AllDevices": "Мои устройства", @@ -598,7 +598,7 @@ "Settings_device_Scanners_desync": "⚠ Расписания сканера устройств не синхронизированы.", "Settings_device_Scanners_desync_popup": "Расписания сканеров устройств (*_RUN_SCHD) не совпадают. Это приведет к несогласованным онлайн/оффлайн уведомлениям устройства. Если это не предусмотрено, используйте одно и то же расписание для всех включенных 🔍Сканеров устройств.", "Speedtest_Results": "Результаты теста скорости", - "Systeminfo_AvailableIps": "Доступные IP-адреса", + "Systeminfo_AvailableIps": "", "Systeminfo_CPU": "CPU", "Systeminfo_CPU_Cores": "Ядра CPU:", "Systeminfo_CPU_Name": "Имя CPU:", @@ -677,7 +677,7 @@ "TIMEZONE_description": "Часовой пояс для корректного отображения статистики. Найдите свой часовой пояс здесь.", "TIMEZONE_name": "Часовой пояс", "UI_DEV_SECTIONS_description": "Выберите, какие элементы интерфейса нужно скрыть на страницах «Устройства».", - "UI_DEV_SECTIONS_name": "Скрыть разделы устройств", + "UI_DEV_SECTIONS_name": "Скрыть разделы Устройств", "UI_ICONS_description": "Список предопределенных значков. Действуйте осторожно: предпочтительный способ добавления значков описан в разделе документации по значкам. Вы можете добавить HTML-тег SVG в кодировке Base64 или HTML-тег Font-awesome.", "UI_ICONS_name": "Предопределенные значки", "UI_LANG_description": "Выберите предпочтительный язык пользовательского интерфейса. Помогите перевести или предложите языки на онлайн-портале Weblate.", @@ -737,7 +737,7 @@ "settings_core_label": "Основные", "settings_device_scanners": "Сканеры устройств, используемые для обнаружения устройств, записывающих данные в таблицу базы данных CurrentScan.", "settings_device_scanners_icon": "fa-solid fa-magnifying-glass-plus", - "settings_device_scanners_info": "Загрузите больше сканеров устройств с помощью параметра LOADED_PLUGINS", + "settings_device_scanners_info": "Загрузите еще больше сканеров устройств с помощью параметра LOADED_PLUGINS", "settings_device_scanners_label": "Сканеры устройств", "settings_enabled": "Вкл. настройки", "settings_enabled_icon": "fa-solid fa-toggle-on", @@ -760,4 +760,4 @@ "settings_system_label": "Система", "settings_update_item_warning": "Обновить значение ниже. Будьте осторожны, следуя предыдущему формату. Проверка не выполняется.", "test_event_tooltip": "Сначала сохраните изменения, прежде чем проверять настройки." -} +} \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index d2e7f10d..80c5b867 100755 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -89,6 +89,7 @@ nav: - Online History: API_ONLINEHISTORY.md - Sync: API_SYNC.md - GraphQL: API_GRAPHQL.md + - DB query: API_DBQUERY.md - Tests: API_TESTS.md - Integrations: - Webhook Secret: WEBHOOK_SECRET.md