Compare commits

..

106 Commits

Author SHA1 Message Date
jokob-sk
c6b5f0d18a Better descriptions
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-31 15:19:52 +11:00
jokob-sk
a6322f6cfa Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-10-31 15:19:24 +11:00
jokob-sk
c0bfb0d4e4 Better descriptions 2024-10-31 15:19:18 +11:00
github-actions[bot]
9c42cb0013 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-30 11:53:43 +00:00
Massimo Pissarello
e42c3d8b76 Translated using Weblate (Italian)
Some checks are pending
docker / docker_dev (push) Waiting to run
Currently translated at 100.0% (712 of 712 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2024-10-30 03:08:06 +01:00
BlueTurtle
f13d3c38aa Translated using Weblate (French)
Currently translated at 100.0% (712 of 712 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2024-10-30 03:08:05 +01:00
github-actions[bot]
38b8eaffe1 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-29 11:53:48 +00:00
Anonymous
4be345af45 Translated using Weblate (Chinese (Simplified Han script))
Some checks are pending
docker / docker_dev (push) Waiting to run
Currently translated at 94.3% (672 of 712 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/zh_Hans/
2024-10-29 01:00:22 +00:00
Anonymous
36dd3f9f06 Translated using Weblate (Polish)
Currently translated at 95.0% (677 of 712 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pl/
2024-10-29 01:00:21 +00:00
Anonymous
a4b2fb0abf Translated using Weblate (Portuguese (Brazil))
Currently translated at 33.9% (242 of 712 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pt_BR/
2024-10-29 01:00:21 +00:00
Anonymous
de35cdafda Translated using Weblate (Italian)
Currently translated at 99.8% (711 of 712 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2024-10-29 01:00:20 +00:00
Anonymous
96bce2666f Translated using Weblate (Russian)
Currently translated at 98.4% (701 of 712 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ru/
2024-10-29 01:00:19 +00:00
Anonymous
95d3fc55ab Translated using Weblate (Norwegian Bokmål)
Currently translated at 93.9% (669 of 712 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/nb_NO/
2024-10-29 01:00:18 +00:00
Anonymous
868210598f Translated using Weblate (French)
Currently translated at 98.7% (703 of 712 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2024-10-29 01:00:16 +00:00
Anonymous
fa14e657c9 Translated using Weblate (Spanish)
Currently translated at 99.8% (711 of 712 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/es/
2024-10-29 01:00:15 +00:00
Anonymous
84c1aad700 Translated using Weblate (German)
Currently translated at 92.4% (658 of 712 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/de/
2024-10-29 01:00:14 +00:00
github-actions[bot]
3c6a48617a [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-28 11:53:56 +00:00
jokob-sk
20c9b8c5ca 📚 Better notification docs + exclude New Device eve if disabled Alert Events
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-28 11:22:11 +11:00
jokob-sk
10ed589cd5 📚 Better notification docs + exclude New Device eve if disabled Alert Events 2024-10-28 11:17:34 +11:00
jokob-sk
bb33ab16fd Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-10-28 07:56:44 +11:00
jokob-sk
12c848d3cd Settins time logging + Saving Location issue #862 2024-10-28 07:56:38 +11:00
github-actions[bot]
87a0dbba46 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-27 11:53:46 +00:00
Massimo Pissarello
ea62b1116f Translated using Weblate (Italian)
Currently translated at 100.0% (712 of 712 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2024-10-27 08:00:23 +01:00
gallegonovato
b52c7ae0ed Translated using Weblate (Spanish)
Currently translated at 100.0% (712 of 712 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/es/
2024-10-27 08:00:22 +01:00
github-actions[bot]
f46bfde782 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-26 11:53:45 +00:00
Hosted Weblate
463d7d7524 Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-26 02:33:00 +02:00
Massimo Pissarello
8e4e7bd76d Translated using Weblate (Italian)
Currently translated at 100.0% (706 of 706 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2024-10-26 02:33:00 +02:00
jokob-sk
cac35e2f20 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-10-26 11:32:45 +11:00
jokob-sk
425381a63e 🆕 Presence chart key 2024-10-26 11:32:29 +11:00
github-actions[bot]
9f6e61581e [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-25 11:53:42 +00:00
jokob-sk
9c255c77d1 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-25 08:00:09 +11:00
jokob-sk
c47ac62e9a 🆕 Delete offline after N hours HRS_TO_KEEP_OFFDEV #865 2024-10-25 07:59:53 +11:00
github-actions[bot]
7e2999b28a [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-24 11:53:49 +00:00
jokob-sk
840413843b Network diagram - Alphabetical sorting #860 2024-10-24 22:00:50 +11:00
jokob-sk
4c46b27643 🔌Plugins page rebuild with DataTables 2024-10-24 21:51:16 +11:00
jokob-sk
907a3e1df8 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-24 08:03:02 +11:00
jokob-sk
27131af434 Network diagram - Infinite recursion detection #857 2024-10-24 08:02:58 +11:00
github-actions[bot]
4d35013d3e [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-23 11:53:57 +00:00
github-actions[bot]
4e481f9307 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-22 11:53:41 +00:00
github-actions[bot]
05e4de0dc8 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-21 11:53:55 +00:00
Hosted Weblate
14aa07c69b Merge branch 'origin/main' into Weblate. 2024-10-21 10:50:31 +00:00
Sylvain Pichon
f0c90cef12 Translated using Weblate (French)
Currently translated at 100.0% (704 of 704 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2024-10-21 10:50:30 +00:00
jokob-sk
26503eaf52 🆕 IP clickable in Devices views #856 2024-10-21 21:50:01 +11:00
jokob-sk
c0f14e46ce Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-21 16:51:17 +11:00
jokob-sk
439066510f UNFIMP work - prevent incorrect MAC #848 2024-10-21 16:51:13 +11:00
gallegonovato
500822327c Translated using Weblate (Spanish)
Some checks are pending
docker / docker_dev (push) Waiting to run
Currently translated at 100.0% (704 of 704 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/es/
2024-10-20 14:28:10 +02:00
github-actions[bot]
ed933f91f1 [🤖Automation] Update README with sponsors information 2024-10-20 11:53:35 +00:00
jokob-sk
bbb617ebda SPDTST increase maximum to 1000000 #854 + sync bugfix 2024-10-20 21:37:59 +11:00
jokob-sk
8b1e4635e6 Merge pull request #855 from johnwang16/add_events_for_imported_devs
Some checks are pending
docker / docker_dev (push) Waiting to run
Add events for imported devs - by @johnwang16 🎉
2024-10-20 13:20:15 +11:00
Massimo Pissarello
44e217a924 Translated using Weblate (Italian)
Currently translated at 100.0% (704 of 704 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2024-10-20 04:15:39 +02:00
johnwang16
400edd35d1 refactor redundant joins, bugfix event insert 2024-10-19 21:24:51 -04:00
johnwang16
9d1fccfe29 Add connection event for devices already connected 2024-10-19 15:12:33 -04:00
github-actions[bot]
6bad4764f6 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-19 11:53:37 +00:00
jokob-sk
d09bbbe73e ENV init settings fix
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-19 15:57:40 +11:00
jokob-sk
7d0b583571 Merge pull request #853 from johnwang16/auto_dark_mode
Allow auto light/dark mode matching user OS setting by @johnwang16  🙏
2024-10-19 14:30:32 +11:00
johnwang16
13a2e5ba26 bug fixes 2024-10-18 23:11:14 -04:00
jokob-sk
4af9efa8f7 Added filters to plugins 2024-10-19 13:13:55 +11:00
johnwang16
aa1a18015d Implement ui theme selector 2024-10-18 22:08:58 -04:00
jokob-sk
abd2f66814 🆕Source Plugin Column 2024-10-19 12:03:20 +11:00
johnwang16
7dd77e06d4 consolidate background-image css 2024-10-18 20:38:27 -04:00
jokob-sk
4f859b5671 🔄Sync: Generate token/key buttons #838 2024-10-19 11:20:25 +11:00
jokob-sk
e24903a123 📊Presence: Fix by the amazing @johnwang16 🙏 #814
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-19 10:27:48 +11:00
jokob-sk
367a024860 📚Docs: SyncHub Use case by @richtj999 🙏 #788 2024-10-19 10:09:36 +11:00
jokob-sk
987127302c 📚Docs: SyncHub Use case by @richtj999 🙏 #788 2024-10-19 10:06:31 +11:00
John Wang
8b1e732fa3 initial css copy for auto dark mode 2024-10-18 18:51:15 -04:00
jokob-sk
73b8ea9bfa CSS🖌️: Speedtest background 2024-10-19 09:21:25 +11:00
jokob-sk
77846df299 📚Docs: Notes On WiFi Extenders #852 2024-10-19 08:49:31 +11:00
jokob-sk
c91c31cfee ⚙️ Make Rogue DHCP timeout configurable #851 2024-10-19 08:36:17 +11:00
jokob-sk
ef2a102218 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-10-19 08:36:02 +11:00
jokob-sk
a8cc4de4d0 ⚙️ Make Rogue DHCP timeout configurable #851 2024-10-19 08:35:42 +11:00
gallegonovato
5f45308465 Translated using Weblate (Spanish)
Currently translated at 100.0% (702 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/es/
2024-10-18 22:15:51 +02:00
github-actions[bot]
e62131b832 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-18 11:53:36 +00:00
jokob-sk
68fe5fffee Merge pull request #850 from johnwang16/main
Some checks are pending
docker / docker_dev (push) Waiting to run
Fix network tree offline color for SVG icons - thanks to @johnwang16 🙏
2024-10-18 08:37:17 +11:00
John Wang
8d198b34c4 Merge pull request #1 from johnwang16/fix-nettree-icon-colors
Fix offline color for svg icons
2024-10-17 17:29:28 -04:00
John Wang
166f700425 Fix offline color for svg icons 2024-10-17 17:28:37 -04:00
jokob-sk
775f53d1d7 📚 Speedtest improvements 2024-10-18 08:16:13 +11:00
jokob-sk
3c8dae5868 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-10-18 08:00:31 +11:00
jokob-sk
56f1e6adf8 📚 docs + guess_icon logging 2024-10-18 08:00:27 +11:00
Safeguard
12226cb899 Translated using Weblate (Russian)
Some checks are pending
docker / docker_dev (push) Waiting to run
Currently translated at 100.0% (702 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ru/
2024-10-17 17:11:35 +02:00
wial88
2eb173b567 Translated using Weblate (German)
Currently translated at 93.8% (659 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/de/
2024-10-17 17:11:34 +02:00
github-actions[bot]
4ab8d67d76 [🤖Automation] Update README with sponsors information 2024-10-17 11:53:58 +00:00
jokob-sk
a3aa81f369 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-17 07:47:02 +11:00
jokob-sk
53f798e50e 📚 docs 2024-10-17 07:46:58 +11:00
Hosted Weblate
eeb740f60d Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-16 12:13:00 +00:00
Fabian Affolter
f3fd06725f Translated using Weblate (German)
Currently translated at 92.7% (651 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/de/
2024-10-16 12:12:59 +00:00
jokob-sk
eb16562e85 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-10-16 23:12:45 +11:00
jokob-sk
c77ae32736 📚 docs 2024-10-16 23:12:29 +11:00
github-actions[bot]
7549a98877 [🤖Automation] Update README with sponsors information 2024-10-16 11:53:58 +00:00
github-actions[bot]
02bf561c69 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-15 11:53:34 +00:00
Ettore Atalan
5fba247aaa Translated using Weblate (German)
Some checks are pending
docker / docker_dev (push) Waiting to run
Currently translated at 92.1% (647 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/de/
2024-10-14 21:15:48 +02:00
github-actions[bot]
cd4b556ee2 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-14 11:53:58 +00:00
github-actions[bot]
2471dfaf02 [🤖Automation] Update README with sponsors information
Some checks failed
docker / docker_dev (push) Has been cancelled
2024-10-13 11:53:43 +00:00
Massimo Pissarello
69d9584426 Translated using Weblate (Italian)
Currently translated at 100.0% (702 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2024-10-13 08:15:54 +00:00
Yannick Torrès
930f1a333e Translated using Weblate (French)
Currently translated at 100.0% (702 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2024-10-13 08:15:48 +00:00
github-actions[bot]
3d9bf32ec7 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-12 11:53:53 +00:00
jokob-sk
ff60ea82ea Merge pull request #837 from cvc90/Fix-Relative-URL-in-userNotifications
Changed the "absolute URL" target to "relative URL" in userNotifications.php for viewing reports
2024-10-12 18:03:21 +11:00
Anonymous
cb297aab8d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.8% (673 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/zh_Hans/
2024-10-12 08:27:18 +02:00
Anonymous
7794380411 Translated using Weblate (Polish)
Currently translated at 96.5% (678 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pl/
2024-10-12 08:27:18 +02:00
Anonymous
0c99c42b0a Translated using Weblate (Russian)
Currently translated at 99.4% (698 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ru/
2024-10-12 08:27:18 +02:00
Anonymous
bb4f7616e4 Translated using Weblate (Norwegian Bokmål)
Currently translated at 95.4% (670 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/nb_NO/
2024-10-12 08:27:18 +02:00
Anonymous
1379923f30 Translated using Weblate (French)
Currently translated at 99.4% (698 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2024-10-12 08:27:17 +02:00
Anonymous
60e9684084 Translated using Weblate (Spanish)
Currently translated at 99.4% (698 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/es/
2024-10-12 08:27:17 +02:00
Anonymous
2235a8cf8e Translated using Weblate (German)
Currently translated at 92.7% (651 of 702 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/de/
2024-10-12 08:27:17 +02:00
Carlos V.
15eb19fda1 Update userNotifications.php
Changed the destination "absolute URL" to "relative URL" in reports to fix issues for reverse proxies
2024-10-12 08:24:35 +02:00
jokob-sk
3d51b1cd15 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-10-12 12:30:17 +11:00
jokob-sk
158ed324c2 docs + css 2024-10-12 12:30:00 +11:00
97 changed files with 2359 additions and 943 deletions

View File

@@ -2,7 +2,7 @@
[![Docker Size](https://img.shields.io/docker/image-size/jokobsk/netalertx?label=Size&logo=Docker&color=0aa8d2&logoColor=fff&style=for-the-badge)](https://hub.docker.com/r/jokobsk/netalertx)
[![Docker Pulls](https://img.shields.io/docker/pulls/jokobsk/netalertx?label=Pulls&logo=docker&color=0aa8d2&logoColor=fff&style=for-the-badge)](https://hub.docker.com/r/jokobsk/netalertx)
[![GitHub Release](https://img.shields.io/github/v/release/jokob-sk/NetAlertX?color=0aa8d2&logoColor=fff&logo=GitHub&style=for-the-badge)](https://github.com/jokob-sk/NetAlertX/releases)
[![Discord](https://img.shields.io/discord/1274490466481602755?color=0aa8d2&logoColor=fff&logo=Discord&style=for-the-badge)](https://discord.gg/UQnnHNYV)
[![Discord](https://img.shields.io/discord/1274490466481602755?color=0aa8d2&logoColor=fff&logo=Discord&style=for-the-badge)](https://discord.gg/NczTUTWyRr)
# 🖧🔍 Network scanner & notification framework

View File

@@ -64,7 +64,7 @@ services:
# 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_dark_mode":"True"}
# - APP_CONF_OVERRIDE={"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_theme":"Dark"}
- TZ=${TZ}
- PORT=${PORT}
# ❗ DANGER ZONE BELOW - Setting ALWAYS_FRESH_INSTALL=true will delete the content of the /db & /config folders

View File

@@ -2,7 +2,7 @@
[![Docker Size](https://img.shields.io/docker/image-size/jokobsk/netalertx?label=Size&logo=Docker&color=0aa8d2&logoColor=fff&style=for-the-badge)](https://hub.docker.com/r/jokobsk/netalertx)
[![Docker Pulls](https://img.shields.io/docker/pulls/jokobsk/netalertx?label=Pulls&logo=docker&color=0aa8d2&logoColor=fff&style=for-the-badge)](https://hub.docker.com/r/jokobsk/netalertx)
[![GitHub Release](https://img.shields.io/github/v/release/jokob-sk/NetAlertX?color=0aa8d2&logoColor=fff&logo=GitHub&style=for-the-badge)](https://github.com/jokob-sk/NetAlertX/releases)
[![Discord](https://img.shields.io/discord/1274490466481602755?color=0aa8d2&logoColor=fff&logo=Discord&style=for-the-badge)](https://discord.gg/UQnnHNYV)
[![Discord](https://img.shields.io/discord/1274490466481602755?color=0aa8d2&logoColor=fff&logo=Discord&style=for-the-badge)](https://discord.gg/NczTUTWyRr)
# NetAlertX 🖧🔍 Network scanner & notification framework
@@ -41,7 +41,7 @@ docker run -d --rm --network=host \
| `PORT` |Port of the web interface | `20211` |
| `LISTEN_ADDR` |Set the specific IP Address for the listener address for the nginx webserver (web interface). This could be useful when using multiple subnets to hide the web interface from all untrusted networks. | `0.0.0.0` |
|`TZ` |Time zone to display stats correctly. Find your time zone [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) | `Europe/Berlin` |
|`APP_CONF_OVERRIDE` | JSON override for settings, e.g. `{"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_dark_mode":"True"}` (Experimental 🧪) | `N/A` |
|`APP_CONF_OVERRIDE` | JSON override for settings, e.g. `{"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_theme":"Dark"}` (Experimental 🧪) | `N/A` |
|`ALWAYS_FRESH_INSTALL` | If `true` will delete the content of the `/db` & `/config` folders. For testing purposes. Can be coupled with [watchtower](https://github.com/containrrr/watchtower) to have an always freshly installed `netalertx`/`netalertx-dev` image. | `N/A` |
### Docker paths
@@ -237,4 +237,4 @@ Big thanks to <a href="https://github.com/Macleykun">@Macleykun</a> & for help a
- Bitcoin: `1N8tupjeCK12qRVU2XrV17WvKK7LCawyZM`
- Ethereum: `0x6e2749Cb42F4411bc98501406BdcD82244e3f9C7`
> 📧 Email me at [jokob@duck.com](mailto:jokob@duck.com?subject=NetAlertX) if you want to get in touch or if I should add other sponsorship platforms.
> 📧 Email me at [jokob@duck.com](mailto:jokob@duck.com?subject=NetAlertX) if you want to get in touch or if I should add other sponsorship platforms.

View File

@@ -43,6 +43,10 @@ fi
# OVERRIDE settings: Handling APP_CONF_OVERRIDE
# Check if APP_CONF_OVERRIDE is set
# remove old
rm "${INSTALL_DIR}/config/app_conf_override.json"
if [ -z "$APP_CONF_OVERRIDE" ]; then
echo "APP_CONF_OVERRIDE is not set. Skipping config file creation."
else

View File

@@ -73,7 +73,7 @@ End-result: Partial restore (historical data & configurations from the Maintenan
#### Recovery:
Even with a corrupted database you can recover what I would argue is 99% of the configuration (except of a couple of settings under Maintenance).
Even with a corrupted database you can recover what I would argue is 99% of the configuration.
- map the `/config/app.conf` file as described in the [Setup documentation](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md#docker-paths).
- rename the `devices_<timestamp>.csv` to `devices.csv` and place it in the `/config` folder

View File

@@ -76,3 +76,16 @@ In the above output notice the section logging how many events are produced by t
These values, if formatted correctly, will also show up in the UI:
![Plugins table](/docs/img/DEBUG_PLUGINS/plugin_objects_pihole.png)
### Sharing application state
Sometimes specific log sections are needed to debug issues. The Devices and CurrentScan table data is sometimes needed to figure out what's wrong.
1. Please set `LOG_LEVEL` to `trace` (Disable it once you have the info as this produces big log files).
2. Wait for the issue to occur.
3. Search for `================ DEVICES table content ================` in your logs.
4. Search for `================ CurrentScan table content ================` in your logs.
5. Open a new issue and post (redacted) output into the issue description (or send to the netalertx@gmail.com email if sensitive data present).
6. Please set `LOG_LEVEL` to `debug` or lower.

View File

@@ -49,6 +49,17 @@ services:
# Other service configurations...
```
## 5. Sharing application state
Sometimes specific log sections are needed to debug issues. The Devices and CurrentScan table data is sometimes needed to figure out what's wrong.
1. Please set `LOG_LEVEL` to `trace` (Disable it once you have the info as this produces big log files).
2. Wait for the issue to occur.
3. Search for `================ DEVICES table content ================` in your logs.
4. Search for `================ CurrentScan table content ================` in your logs.
5. Open a new issue and post (redacted) output into the issue description (or send to the netalertx@gmail.com email if sensitive data present).
6. Please set `LOG_LEVEL` to `debug` or lower.
## 📃Common issues
### Permissions

View File

@@ -11,16 +11,15 @@ There are 4 ways how to influence notifications:
> It's recommended to use the same schedule interval for all plugins responsible for scanning devices, otherwise false positives might be reported if different devices are discovered by different plugins. Check the **Settings** > **Enabled settings** section for a warning:
> ![Schedules out-of-sync](/docs/img/NOTIFICATIONS/Schedules_out-of-sync.png)
## Device settings 💻
![Device notification settings](/docs/img/NOTIFICATIONS/Device-notification-settings.png)
There are 4 settings on the device for influencing notifications. You can:
1. Completely disable the scanning of the device
2. **Alert all events**, connections, disconnections, IP changes (noisy, usually not recommended)
3. **Alert down** - alerts when a device goes down. This setting overrides disabled Alert All Events, so you will get a notification of a device going down even if you don't have Alert All Events ticked.
1. **Scan Device** - Completely disable the scanning of the device.
2. **Alert Events** - Enables alerts of connections, disconnections, IP changes.
3. **Alert Down** - Alerts when a device goes down. This setting overrides a disabled **Alert Events** setting, so you will get a notification of a device going down even if you don't have **Alert Events** ticked.
4. **Skip repeated notifications**, if for example you know there is a temporary issue and want to pause the same notification for this device for a given time.
## Plugin settings 🔌
@@ -40,7 +39,7 @@ Click the **Read more in the docs.** Link at the top of each plugin to get more
In Notification Processing settings, you can specify blanket rules. These allow you to specify exceptions to the Plugin and Device settings and will override those.
1. Notify on (`NTFPRCS_INCLUDED_SECTIONS`) allows you to specify which events trigger notifications. Usual setups will have `new_devices`, `down_devices`, and possibly `events` set. Setting `plugin` might be too noisy for most setups. More info in the [NTFPRCS plugin](/front/plugins/notification_processing/README.md)
1. Notify on (`NTFPRCS_INCLUDED_SECTIONS`) allows you to specify which events trigger notifications. Usual setups will have `new_devices`, `down_devices`, and possibly `down_reconnected` set. Including `plugin` (dependenton the Plugin `<plugin>_WATCH` and `<plugin>_REPORT_ON` settings) and `events` (dependent on the on-device **Alert Events** setting) might be too noisy for most setups. More info in the [NTFPRCS plugin](/front/plugins/notification_processing/README.md)
2. Alert down after (`NTFPRCS_alert_down_time`) is useful if you want to wait for some time before the system sends out a down notification for a device. This is related to the on-device **Alert down** setting and only devices with this checked will trigger a down notification.
3. A filter to allow you to set device-specific exceptions to New devices being added to the app.
4. A filter to allow you to set device-specific exceptions to generated Events.

View File

@@ -22,3 +22,10 @@ The database cleanup plugin. Check details and related setting in the [DB Cleanu
### Maintenance (MAINT)
The maintenance plugin. Check details and related setting in the [Maintenance plugin docs](/front/plugins/maintenance/README.md). Make sure the plugin is not failing by checking the logs. Try changing the schedule `MAINT_RUN_SCHD` and the timeout `MAINT_RUN_TIMEOUT` (increase) if the plugin is failing to execute.
## Scan frequency and coverage
The more often you scan the networks the more resources, traffic and DB read/write cycles are executed. Especially on busy networks and lower end hardware, consider increasing scan intervals (`<PLUGIN>_RUN_SCHD`) and timeouts (`<PLUGIN>_RUN_TIMEOUT`).
Also consider decreasing the scanned subnet, e.g. from `/16` to `/24` if need be.

View File

@@ -110,3 +110,21 @@ Please note the accessibility of macvlans when configured on the same computer.
- NetAlertX does not detect the macvlan container when it is running on the same computer.
- NetAlertX recognizes the macvlan container when it is running on a different computer.
### Wi-Fi Extenders
A Wi-Fi extender typically works by creating a separate network or subnet, which can cause certain network scanning tools, like `arp-scan`, to be unable to detect devices behind the extender.
This happens because `arp-scan` uses ARP (Address Resolution Protocol) to map IP addresses to MAC addresses on the local network. Since ARP is a Layer 2 (data link layer) protocol, it usually only works within a single broadcast domain, which is typically limited to a single router or network segment.
When you introduce a Wi-Fi extender, it may isolate devices on different segments of the network, meaning ARP packets cannot easily traverse from one segment (your main network) to another (the network behind the extender).
To scan devices behind the extender, you can try:
- Scanning the specific subnet that the extender uses, if it is separate from the main network.
- Using [supplementing plugins](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md) that use alternate methods. Protocols used by the `SNMPDSC` or `DHCPLSS` plugins have good support and usually can be used as a workaround.
Check the [plugins list](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md) to find a plugin supported by your router and your network setup.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 82 KiB

View File

@@ -12,11 +12,26 @@
----------------------------------------------------------------------------- */
:root {
--color-aqua: #00c0ef;
--color-blue: #0060df;
--color-green: #00a65a;
--color-yellow: #f39c12;
--color-red: #dd4b39;
}
/* -----------------------------------------------------------------------------
Helper Classes
----------------------------------------------------------------------------- */
.pointer
{
cursor: pointer;
}
.question
{
cursor: help;
}
/* -----------------------------------------------------------------------------
Text Classes
----------------------------------------------------------------------------- */
@@ -212,6 +227,12 @@
{
line-height: 30px;
}
body
{
background-image: url('../img/background.png');
}
/* -----------------------------------------------------------------------------
Customized Main Menu
----------------------------------------------------------------------------- */
@@ -772,6 +793,35 @@ height: 50px;
display: inline-grid;
}
/* --------------------------------------------------------- */
/* Presence */
/* --------------------------------------------------------- */
.presencenceKey
{
float: right;
}
.presenceOnlineNow{
background-color: var(--color-green);
}
.presenceOnlinePast{
background-color: var(--color-blue);
}
.presenceOnlinePastMiss{
background-color: var(--color-yellow);
}
.presenceKeyBoxes
{
width: 10px;
height: 10px;
display: inline-block;
/* background: #fff; */
opacity: .75;
}
/* --------------------------------------------------------- */
/* report */
/* --------------------------------------------------------- */
@@ -1052,7 +1102,11 @@ input[readonly] {
.settingsSearchWrap
{
padding:10px;
/* padding:10px; */
/* display: flex; */
justify-content: center; /* Centers horizontally */
align-items: center; /* Centers vertically */
/* height: 60px; */
}
.settings-sticky-bottom-section {
@@ -1062,11 +1116,12 @@ input[readonly] {
/* opacity: 0.8; */
bottom: 30px;
border-radius: 5px;
margin:1px;
/* margin:1px; */
border-width: 1px;
border-style: solid;
border-color: inherit;
/* width: 87%; */
padding: 10px;
}
.settings-sticky-bottom-section:hover {
@@ -1085,7 +1140,7 @@ input[readonly] {
width: 14px;
position: absolute;
right: -6px;
top: 6px;
top: 13px;
}
@@ -1097,9 +1152,9 @@ input[readonly] {
.saveSettingsWrapper button
{
width:70%;
margin-top:20px;
/* margin-top:20px; */
margin-left:15%;
margin-bottom:20px;
/* margin-bottom:20px; */
}
#settingsPage .select2-selection
@@ -1136,7 +1191,6 @@ input[readonly] {
height: 200px; */
background-color: #f3f3f3;
border: 1px solid #ccc;
margin: 20px;
z-index: 10;
}
@@ -1176,11 +1230,6 @@ input[readonly] {
font-size: large;
}
.pointer
{
cursor: pointer;
}
.drag
{
cursor: move; /* fallback if grab cursor is unsupported */
@@ -1203,7 +1252,7 @@ input[readonly] {
background-color:#606060 !important;
}
.networkPageHelp{
.helpIconSmallTopRight{
position: absolute;
font-size: x-small;
margin-bottom: 6px;
@@ -1320,7 +1369,8 @@ input[readonly] {
border: solid;
border-color:cyan;
}
#networkTree .netStatus-Off-line i
#networkTree .netStatus-Off-line i,
#networkTree .netStatus-Off-line svg
{
color: #dd4b39;
}
@@ -1401,7 +1451,17 @@ input[readonly] {
.plugin-content #tabs-content-location
{
margin: 0px;
/* padding-top: 0; */
}
.integrations-plugins .content
{
display: table;
}
.plugin-content .tab-content
{
padding-top: 10px;
}
.plugins-description
@@ -1456,6 +1516,33 @@ input[readonly] {
}
.textOverflow
{
white-space: nowrap; /* Prevent text from wrapping to a new line */
overflow: hidden; /* Hide the overflowed text */
text-overflow: ellipsis; /* Show ellipsis (...) */
}
.table-stretched
{
min-width: -moz-available;
min-width: -webkit-fill-available;
}
.pluginBadge
{
float: right;
}
.pluginBadgeWrap
{
float: right;
display: ruby;
z-index: 1;
position: sticky;
margin-top: 1px;
}
/* -----------------------------------------------------------------------------
Spin
----------------------------------------------------------------------------- */

View File

@@ -17,6 +17,10 @@ html {
background-color: #353c42;
}
body {
background-image: url('../img/boxed-bg-dark.png') !important;
}
body, .bg-yellow, .callout.callout-warning, .alert-warning, .label-warning, .modal-warning .modal-body {
background-color: #353c42 !important;

View File

@@ -0,0 +1,21 @@
@media (prefers-color-scheme: dark) {
.fc-sat {
background-color: #444D56; }
.fc-sun {
background-color: #444D56; }
.fc-today {
background-color: #8D9AAC !important;
border: none !important;
}
.fc-cell-content {
background-color: #272c30;
}
.fc-widget-header {
background-color: #353c42;
}
.fc-unthemed .fc-content, .fc-unthemed .fc-divider, .fc-unthemed .fc-list-heading td, .fc-unthemed .fc-list-view, .fc-unthemed .fc-popover, .fc-unthemed .fc-row, .fc-unthemed tbody, .fc-unthemed td, .fc-unthemed th, .fc-unthemed thead{
border-color: #353c42 !important;
}
}

737
front/css/system-dark-patch.css Executable file
View File

@@ -0,0 +1,737 @@
/* Pi-hole: A black hole for Internet advertisements
* (c) 2020 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license.
*
* The colors used in this theme has been inspired by
* https://github.com/anvyst/adminlte-skin-midnight
*
* Additional fixes For Pi.Alert UI by leiweibau */
@media (prefers-color-scheme: dark) {
:root {
--datatable-bgcolor: rgba(64, 76, 88, 0.8);
}
html {
background-color: #353c42;
}
body {
background-image: url('../img/boxed-bg-dark.png') !important;
}
body, .bg-yellow, .callout.callout-warning, .alert-warning, .label-warning, .modal-warning .modal-body {
background-color: #353c42 !important;
color: #bec5cb !important;
}
h4 {
color: #44def1;
}
.content-header > .breadcrumb > li > a {
color: #bec5cb;
}
.table > thead > tr > th,
.table > tbody > tr > th,
.table > tfoot > tr > th,
.table > thead > tr > td,
.table > tbody > tr > td,
.table > tfoot > tr > td {
border-top: 0;
}
.table > thead > tr.odd,
.table > tbody > tr.odd,
.table > tfoot > tr.odd {
background-color: #2a2f34;
}
.table > thead > tr.odd:hover,
.table > tbody > tr.odd:hover,
.table > tfoot > tr.odd:hover,
.table > thead > tr.even:hover,
.table > tbody > tr.even:hover,
.table > tfoot > tr.even:hover {
background-color: #1e2226;
}
.table-bordered,
.table-bordered > thead > tr > th,
.table-bordered > tbody > tr > th,
.table-bordered > tfoot > tr > th,
.table-bordered > thead > tr > td,
.table-bordered > tbody > tr > td,
.table-bordered > tfoot > tr > td {
border: 1px solid #353c42;
}
.dataTables_wrapper input[type="search"] {
border-radius: 4px;
background-color: #353c42;
border: 0;
color: #bec5cb;
}
.dataTables_paginate .pagination li > a {
background-color: #353c42;
border-color: #353c42;
}
.pagination > .disabled > a,
.pagination > .disabled > a:focus,
.pagination > .disabled > a:hover,
.pagination > .disabled > span,
.pagination > .disabled > span:focus,
.pagination > .disabled > span:hover {
cursor: not-allowed;
color: #bec5cb;
background-color: #353c42;
border-color: #353c42;
}
.pagination > li > a:focus,
.pagination > li > a:hover,
.pagination > li > span:focus,
.pagination > li > span:hover {
z-index: 2;
color: #bec5cb;
background-color: #54606b;
border-color: #54606b;
}
.wrapper,
.main-sidebar,
.left-side {
background-color: #272c30;
}
.user-panel > .info,
.user-panel > .info > a {
color: #fff;
}
.sidebar-menu > li.header {
color: #556068;
background-color: #1e2225;
}
.sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.sidebar-menu > li:hover > a,
.sidebar-menu > li > a:focus,
.sidebar-menu > li.active > a {
color: #fff;
background-color: #22272a;
border-color: #3c8dbc;
}
.sidebar-menu > li > .treeview-menu {
margin: 0 1px;
background-color: #32393e;
}
.sidebar a {
color: #bec5cb;
}
.sidebar a:hover {
text-decoration: none;
}
.treeview-menu > li > a {
color: #949fa8;
}
.treeview-menu > li.active > a,
.treeview-menu > li > a:hover,
.treeview-menu > li > a:focus {
color: #fff;
}
.sidebar-form {
border-radius: 3px;
border: 1px solid #3e464c;
margin: 10px;
}
.sidebar-form input[type="text"],
.sidebar-form .btn {
box-shadow: none;
background-color: #3e464c;
border: 1px solid transparent;
height: 35px;
}
.sidebar-form input[type="text"] {
color: #666;
border-top-left-radius: 2px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: 2px;
}
.sidebar-form input[type="text"]:focus,
.sidebar-form input[type="text"]:focus + .input-group-btn .btn {
background-color: #fff;
color: #666;
}
.sidebar-form input[type="text"]:focus + .input-group-btn .btn {
border-left-color: #fff;
}
.sidebar-form .btn {
color: #999;
border-top-left-radius: 0;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.box,
.box-footer,
.info-box,
.box-comment,
.comment-text,
.comment-text .username {
color: #bec5cb;
background-color: #272c30;
}
.box-comments .box-comment {
border-bottom-color: #353c42;
}
.box-footer {
border-top: 1px solid #353c42;
}
.box-header.with-border {
border-bottom: 1px solid #353c42;
}
.box-solid,
.box {
border: 1px solid #272c30;
}
.box-solid > .box-header,
.box > .box-header {
color: #bec5cb;
}
.box-solid > .box-header .btn,
.box > .box-header .btn {
color: #bec5cb;
}
.box.box-info,
.box.box-primary,
.box.box-success,
.box.box-warning,
.box.box-danger {
border-top-width: 3px;
}
.main-header .navbar {
background-color: #272c30;
}
.main-header .navbar .nav > li > a,
.main-header .navbar .nav > li > .navbar-text {
color: #bec5cb;
max-height: 50px;
}
.main-header .navbar .nav > li > a:hover,
.main-header .navbar .nav > li > a:active,
.main-header .navbar .nav > li > a:focus,
.main-header .navbar .nav .open > a,
.main-header .navbar .nav .open > a:hover,
.main-header .navbar .nav .open > a:focus,
.main-header .navbar .nav > .active > a {
background-color: rgba(0, 0, 0, 0.1);
color: #f6f6f6;
}
.main-header .navbar .sidebar-toggle {
color: #bec5cb;
}
.main-header .navbar .sidebar-toggle:hover {
color: #f6f6f6;
background-color: rgba(0, 0, 0, 0.1);
}
.timeline li .timeline-item {
color: #bec5cb;
background-color: #272c30;
border-color: #353c42;
}
.timeline li .timeline-header {
border-bottom-color: #353c42;
}
.nav-stacked > li > a {
color: #bec5cb;
}
.nav-stacked > li > a:hover {
color: white;
background-color: #1e2226;
}
.content-wrapper,
.right-side {
background-color: #353c42;
}
.main-footer,
.nav-tabs-custom {
background-color: #272c30;
border-top-color: #353c42;
color: #bec5cb;
}
.main-footer .nav-tabs,
.nav-tabs-custom .nav-tabs {
background-color: #30383f;
border-bottom-color: #2f363b;
}
.main-footer .tab-content,
.nav-tabs-custom .tab-content {
background-color: #30383f;
}
.nav-tabs-custom > .nav-tabs {
background: rgba(64, 72, 80, 0.666);
}
.nav-tabs-custom > .nav-tabs > li {
margin-right: 1px;
color: #bec5cb;
}
.nav-tabs-custom > .nav-tabs > li.active > a,
.nav-tabs-custom > .nav-tabs > li.active:hover > a {
border-left-color: #30383f;
border-right-color: #30383f;
background-color: #30383f;
color: #bec5cb;
}
.nav-tabs-custom > .nav-tabs > li:not(.active):hover {
border-top-color: #d2d6de;
background-color: transparent;
}
.nav-tabs-custom > .nav-tabs > li > a {
color: #8e959b;
}
.nav-tabs-custom > .nav-tabs > li > a:focus {
color: #3c8dbc;
}
.nav-tabs-custom > .nav-tabs > li:hover > a,
.nav-tabs-custom > .nav-tabs > li.active:hover > a {
background-color: #353c42;
color: #bec5cb;
}
.list-group {
color: #bec5cb;
background-color: #272c30;
}
.list-group .list-group-item {
border-color: #353c42;
background-color: #272c30;
}
.input-group .input-group-addon {
border-right: 1px solid #272c30;
}
.select2 .select2-selection {
background-color: #353c42;
color: #bec5cb;
border: 1px solid #353c42;
}
.select2 .select2-selection .select2-container--default,
.select2 .select2-selection .select2-selection--single,
.select2 .select2-selection .select2-selection--multiple,
.select2 .select2-selection .select2-selection__rendered {
color: #bec5cb;
}
.select2-dropdown {
background-color: #353c42;
color: #bec5cb;
border: 1px solid #353c42;
}
.select2-dropdown .select2-search__field {
background-color: #272c30;
color: #bec5cb;
border: 1px solid #353c42;
}
.select2-container--default.select2-container--open {
background-color: #272c30;
}
.layout-boxed {
background: url("../../img/boxed-bg-dark.png") repeat fixed;
}
.not-used {
background-color: #eee;
}
.not-used:hover {
background-color: #c5c5c5;
}
.used {
background-color: #fff;
}
.used:hover {
background-color: #ddd;
}
.graphs-grid {
background-color: rgba(255, 255, 255, 0.2);
}
.graphs-ticks {
color: #b8c7ce;
}
.queries-permitted {
background-color: #00a65a;
}
.queries-blocked {
background-color: #999;
}
.progress {
background-color: #333;
}
.bg-green {
background-color: #005c32 !important;
}
.bg-aqua {
background-color: #007997 !important;
}
.bg-yellow {
background-color: #b1720c !important;
}
.bg-red {
background-color: #913225 !important;
}
code,
pre {
padding: 2px 4px;
font-size: 90%;
color: #bec5cb;
background-color: #353c42;
border-radius: 4px;
}
/* Used in the Query Log table */
.text-green-light {
color: #5ca314 !important;
}
.text-green {
color: #00aa60 !important;
}
.text-orange {
color: #b1720c !important;
}
.text-red {
color: #bd2c19 !important;
}
.text-vivid-blue {
color: #007997 !important;
}
td.highlight {
background-color: rgba(255, 204, 0, 0.333);
}
.btn-default {
box-shadow: none;
background-color: #3e464c;
color: #bec5cb;
border: 1px solid #353c42;
}
/* Used in debug log page */
.log-red {
color: #ff4038;
}
.log-green {
color: #4c4;
}
.log-yellow {
color: #fb0;
}
.log-blue {
color: #48f;
}
.log-purple {
color: #b8e;
}
.log-cyan {
color: #0df;
}
.log-gray {
color: #999;
}
#output {
border-color: #505458;
background: #272c30;
}
/* Used by the long-term pages */
.daterangepicker {
background-color: #3e464c;
border-radius: 4px;
border: 1px solid #353c42;
}
.daterangepicker .ranges li:hover {
background-color: #353c42;
}
.daterangepicker .ranges li.active {
background-color: #1e2226; /* Color also used in table pagination */
}
.daterangepicker .calendar-table {
background-color: #3e464c;
border-radius: 4px;
border: 1px solid #353c42;
}
.daterangepicker td.off,
.daterangepicker td.off.in-range,
.daterangepicker td.off.start-date,
.daterangepicker td.off.end-date {
background-color: #485158;
}
.daterangepicker td.available:hover,
.daterangepicker th.available:hover {
background-color: #1e2226;
}
.daterangepicker td.active,
.daterangepicker td.active:hover,
.daterangepicker td.in-range:hover {
background-color: #225e92;
}
.daterangepicker td.in-range {
background-color: #1e2226;
color: #bec5cb;
}
input,
select,
select.form-control,
.form-group .input-group-addon,
.input-group .input-group-addon,
.form-group input,
.input-group input,
.form-group textarea,
.input-group textarea,
.daterangepicker select.hourselect,
.daterangepicker select.minuteselect,
.daterangepicker select.secondselect,
.daterangepicker select.ampmselect,
.form-control,
div.dataTables_wrapper div.dataTables_length select {
background-color: #353c42;
color: #bec5cb;
border: 1px solid #3d444b;
}
.form-control[disabled],
.form-control[readonly],
fieldset[disabled] .form-control {
background-color: #353c42;
opacity: 1;
}
.navbar-custom-menu > .navbar-nav > li > .dropdown-menu {
background-color: #4c5761;
color: #bec5cb;
border: 1px solid #171c20;
}
.table-striped > tbody > tr:nth-of-type(2n + 1) {
background-color: #2d343a;
}
.panel,
.panel-body,
.panel-default > .panel-heading {
background-color: #3e464c;
border-radius: 4px;
border: 1px solid #353c42;
color: #bec5cb;
}
.box.box-solid.box-info,
.box.box-solid.box-info > .box-header {
color: #bec5cb;
background-color: #367fa9 !important;
border: 1px solid #367fa9;
}
input[type="password"]::-webkit-credentials-auto-fill-button {
background: #bfc5ca;
}
input[type="password"]::-webkit-caps-lock-indicator {
filter: invert(100%);
}
.network-never {
background-color: #661b02;
}
.network-recent {
background-color: #114100;
}
.network-old {
background-color: #525200;
}
.network-older {
background-color: #502b00;
}
.network-gradient {
background-image: linear-gradient(to right, #114100 0%, #525200 100%);
}
.icheckbox_polaris,
.icheckbox_futurico,
.icheckbox_minimal-blue {
margin-right: 10px;
}
.iradio_polaris,
.iradio_futurico,
.iradio_minimal-blue {
margin-right: 8px;
}
/* Overlay box with spinners as shown during data collection for graphs */
.box .overlay,
.overlay-wrapper .overlay {
z-index: 50;
background-color: rgba(53, 60, 66, 0.733);
border-radius: 3px;
}
.box .overlay > .fa,
.overlay-wrapper .overlay > .fa,
.navbar-nav > .user-menu > .dropdown-menu > .user-body a {
color: #bec5cb !important;
}
.navbar-nav > .user-menu > .dropdown-menu > .user-footer {
background-color: #353c42bb;
padding: 10px;
}
.modal-content {
background: #272c30;
}
.modal-header {
border-bottom-color: #353c42;
}
.modal-footer {
border-top-color: #353c42;
}
.close {
color: #383838;
}
/*** Fix login input visual misalignment ***/
#loginform,
#loginform input {
color: rgb(120, 127, 133);
}
.login-options input,
.login-options [class*="icheck-"] > input:first-child + input[type="hidden"] + label::before,
.login-options [class*="icheck-"] > input:first-child + label::before {
background: none;
border-color: rgb(120, 127, 133);
}
/*** Additional fixes For Pi.Alert UI ***/
.small-box {
border-radius: 10px;
border-top: 0px;
}
.pa-small-box-aqua .inner {
background-color: rgb(45,108,133);
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.pa-small-box-green .inner {
background-color: rgb(31,76,46);
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.pa-small-box-yellow .inner {
background-color: rgb(151,104,37);
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.pa-small-box-red .inner {
background-color: rgb(120,50,38);
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.pa-small-box-gray .inner {
background-color: #777;
/* color: rgba(20,20,20,30%); */
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.pa-small-box-gray .inner h3 {
color: #bbb;
}
.text-gray-20 {
color: rgba(220,220,220,30%);
}
.bg-gray {
background-color: #888888 !important;
}
.badge.bg-green {
background-color: #00A000 !important;
}
.badge.bg-gray {
background-color: #888 !important;
}
#txtRecord {
background-color: #353c42;
border-color: #888888;
}
.table-hover tbody tr:hover td, .table-hover tbody tr:hover th {
background-color: rgb(189,192,198);
color: #444;
}
.db_info_table_cell:nth-child(1) {background: #272c30}
.db_info_table_cell:nth-child(2) {background: #272c30}
.db_tools_table_cell_a:nth-child(1) {background: #272c30}
.db_tools_table_cell_a:nth-child(2) {background: #272c30}
.db_tools_table_cell_b:nth-child(1) {background: #272c30}
.db_tools_table_cell_b:nth-child(2) {background: #272c30}
.db_info_table {
display: table;
border-spacing: 0em;
font-weight: 400;
font-size: 15px;
width: 100%;
margin: auto;
}
.nav-tabs-custom > .nav-tabs > li:hover > a, .nav-tabs-custom > .nav-tabs > li.active:hover > a {
background-color: #272c30;
color: #bec5cb;
}
.nav-tabs-custom > .nav-tabs > li.active > a, .nav-tabs-custom > .nav-tabs > li.active:hover > a {
border-left-color: #30383f;
border-right-color: #30383f;
background-color: #272c30;
color: #bec5cb;
}
.nav-tabs-custom > .nav-tabs {
background-color: #353c42;
}
.nav-tabs-custom .tab-content {
background-color: #272c30;
}
.top_small_box_gray_text {
color: white !important;
}
/* remove white border that appears on mobile screen sizes */
.box-body {
border: 0px;
}
/* remove white border that appears on mobile screen sizes */
.table-responsive {
border: 0px;
}
.login-page {
background-color: transparent;
}
.login-logo a {
color: white;
}
.login-box-body {
color: #bec5cb;
background-color: #272c30;
}
/* Add border radius to bottom of the status boxes*/
.pa-small-box-footer {
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
.small-box > .inner h3, .small-box > .inner p {
margin-bottom: 0px;
margin-left: 0px;
}
.small-box:hover .icon {
font-size: 3.74em;
}
.small-box .icon {
top: 0.01em;
font-size: 3.25em;
}
.pa_semitransparent-panel{
background-color: #000 !important;
}
}

View File

@@ -325,7 +325,7 @@
</div>
<!-- Network -->
<h4 class="bottom-border-aqua"><?= lang('DevDetail_MainInfo_Network_Title');?><span class="networkPageHelp"> <a target="_blank" href="https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md"><i class="fa fa-circle-question"></i></a><span></h4>
<h4 class="bottom-border-aqua"><?= lang('DevDetail_MainInfo_Network_Title');?><span class="helpIconSmallTopRight"> <a target="_blank" href="https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md"><i class="fa fa-circle-question"></i></a><span></h4>
<div class="form-group" title="<?= lang('DevDetail_Network_Node_hover');?>">
<label class="col-sm-3 control-label"><?= lang('DevDetail_MainInfo_Network');?></label>
<div class="col-sm-9">
@@ -370,7 +370,8 @@
<!-- column 3 -->
<div class="col-lg-4 col-sm-6 col-xs-12">
<h4 class="bottom-border-aqua"><?= lang('DevDetail_EveandAl_Title');?></h4>
<h4 class="bottom-border-aqua"><?= lang('DevDetail_EveandAl_Title');?>
<span class="helpIconSmallTopRight"> <a target="_blank" href="https://github.com/jokob-sk/NetAlertX/blob/main/docs/NOTIFICATIONS.md"><i class="fa fa-circle-question"></i></a><span></h4>
<div class="box-body form-horizontal">
<!-- Scan Cycle -->
@@ -455,7 +456,8 @@
<i style="font-size: 24px;" class="text-yellow glyphicon glyphicon-random"></i> &nbsp &nbsp </span>
<a href="https://github.com/jokob-sk/NetAlertX/blob/main/docs/RANDOM_MAC.md" target="_blank" style="color: #777;">
<i class="fa fa-info-circle"></i> </a>
<i class="fa fa-info-circle"></i>
</a>
</div>
</div>
</div>
@@ -641,8 +643,14 @@
<!-- Dark-Mode Patch -->
<?php
if ($ENABLED_DARKMODE === True) {
echo '<link rel="stylesheet" href="css/dark-patch-cal.css">';
switch ($UI_THEME) {
case "Dark":
echo '<link rel="stylesheet" href="css/dark-patch-cal.css">';
break;
case "System":
echo '<link rel="stylesheet" href="css/system-dark-patch-cal.css">';
break;
}
?>

View File

@@ -167,6 +167,8 @@
// -----------------------------------------------------------------------------
function main () {
showSpinner();
//initialize the table headers in the correct order
var availableColumns = getSettingOptions("UI_device_columns").split(",");
var headersDefaultOrder = availableColumns.map(val => getString(val));
@@ -456,7 +458,8 @@ function initializeDatatable (status) {
item.dev_GUID || "",
item.dev_SyncHubNodeName || "",
item.dev_NetworkSite || "",
item.dev_SSID || ""
item.dev_SSID || "",
item.dev_SourcePlugin || ""
];
var newRow = [];
@@ -544,15 +547,33 @@ function initializeDatatable (status) {
}
} },
// IP address
// IP address
{targets: [mapIndx(8)],
'createdCell': function (td, cellData, rowData, row, col) {
if (!emptyArr.includes(cellData)){
$(td).html (`<span class="anonymizeIp">
<a href="http://${cellData}" class="pointer" target="_blank">
${cellData}
</a>
<a href="https://${cellData}" class="pointer" target="_blank">
<i class="fa fa-lock "></i>
</a>
<span>`);
} else {
$(td).html ('');
}
}
},
// IP address (ordeable)
{targets: [mapIndx(12)],
'createdCell': function (td, cellData, rowData, row, col) {
if (!emptyArr.includes(cellData)){
$(td).html ('<span class="anonymizeIp">'+cellData+'</span>');
} else {
$(td).html ('');
}
} },
if (!emptyArr.includes(cellData)){
$(td).html (`<span class="anonymizeIp">${cellData}<span>`);
} else {
$(td).html ('');
}
}
},
// Favorite
{targets: [mapIndx(4)],

View File

@@ -103,10 +103,14 @@ if (isset ($_SESSION["login"]) == FALSE || $_SESSION["login"] != 1)
<!-- Dark-Mode Patch -->
<?php
if ($ENABLED_DARKMODE === True) {
echo '<link rel="stylesheet" href="css/dark-patch.css">';
$BACKGROUND_IMAGE_PATCH='style="background-image: url(\'img/boxed-bg-dark.png\');"';
} else { $BACKGROUND_IMAGE_PATCH='style="background-image: url(\'img/background.png\');"';}
switch ($UI_THEME) {
case "Dark":
echo '<link rel="stylesheet" href="css/dark-patch.css">';
break;
case "System":
echo '<link rel="stylesheet" href="css/system-dark-patch.css">';
break;
}
?>
<link rel="stylesheet" href="/css/offline-font.css">
</head>

View File

@@ -1186,20 +1186,24 @@ function hideUIelements(settingKey) {
// -----------------------------------------------------------------------------
// apply dark mode
// apply theme
$(document).ready(function() {
// Assume getSetting is a function that returns true or false for dark mode
if (getSetting("UI_dark_mode") === "True") {
// Add the dark mode stylesheet
setCookie("UI_dark_mode", "True")
$('head').append('<link rel="stylesheet" href="css/dark-patch.css">');
// Set the background image for dark mode
$('body').attr('style', 'background-image: url(\'img/boxed-bg-dark.png\');');
let theme = getSetting("UI_theme");
if (theme) {
theme = theme.replace("['","").replace("']","");
// Add the theme stylesheet
setCookie("UI_theme", theme);
switch(theme) {
case "Dark":
$('head').append('<link rel="stylesheet" href="css/dark-patch.css">');
break;
case "System":
$('head').append('<link rel="stylesheet" href="css/system-dark-patch.css">');
break
}
} else {
setCookie("UI_dark_mode", "False")
// Set the background image for light mode
$('body').attr('style', 'background-image: url(\'img/background.png\');');
setCookie("UI_theme", "Light");
}
});

View File

@@ -67,6 +67,35 @@ function initDeviceSelectors(devicesListAll_JSON) {
}, 10);
}
// -------------------------------------------------------------------
// Utility function to generate a random API token in the format t_<random string of specified length>
function generateApiToken(elem, length) {
// Retrieve and parse custom parameters from the element
let params = $(elem).attr("my-customparams")?.split(',').map(param => param.trim());
if (params && params.length >= 1) {
var targetElementID = params[0]; // Get the target element's ID
}
let targetElement = $('#' + targetElementID);
// Function to generate a random string of a specified length
function generateRandomString(len) {
let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < len; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
}
// Generate the token in the format t_<random string of length>
let randomToken = 't_' + generateRandomString(length);
// Set the generated token as the value of the target element
if (targetElement.length) {
targetElement.val(randomToken);
}
}
// ----------------------------------------------
// Updates the icon preview

View File

@@ -19,7 +19,7 @@
<?php require 'php/templates/notification.php'; ?>
<h1 id="pageTitle">
<i class="fa fa-network-wired"></i> <?= lang('Network_Title');?>
<span class="networkPageHelp"> <a target="_blank" href="https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md"><i class="fa fa-circle-question"></i></a><span>
<span class="helpIconSmallTopRight"> <a target="_blank" href="https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md"><i class="fa fa-circle-question"></i></a><span>
</h1>
</section>
@@ -481,21 +481,31 @@
return;
}
devicesListnew = rawData["data"].map(item => { return {
"name":item[0],
"type":item[2],
"icon":item[3],
"mac":item[11],
"parentMac":item[14],
"rowid":item[13],
"status":item[10],
"childrenQty":item[15],
"port":item[18]
}})
devicesListnew = rawData["data"].map(item => {
return {
"name": item[0],
"type": item[2],
"icon": item[3],
"mac": item[11],
"parentMac": item[14],
"rowid": item[13],
"status": item[10],
"childrenQty": item[15],
"port": item[18]
};
}).sort((a, b) => {
// First sort by name alphabetically
const nameCompare = a.name.localeCompare(b.name);
if (nameCompare !== 0) {
return nameCompare;
}
// If names are the same, sort by port numerically
return a.port - b.port;
});
setCache('devicesListNew', JSON.stringify(devicesListnew))
setCache('devicesListNew', JSON.stringify(devicesListnew));
// init global variable
// Init global variable
deviceListGlobal = devicesListnew;
@@ -525,53 +535,57 @@
// ---------------------------------------------------------------------------
function getChildren(node, list, path)
// Recursively get children nodes and build a tree
function getChildren(node, list, path, visited = [])
{
var children = [];
// loop thru all items and find childern...
for(var i in list)
{
//... of the current node
if(list[i].parentMac.toLowerCase() == node.mac.toLowerCase() && !hiddenMacs.includes(list[i].parentMac))
{
visibleNodesCount++
// and process them
children.push(getChildren(list[i], list, path + ((path == "") ? "" : '|') + list[i].parentMac, hiddenMacs))
var children = [];
// Check for infinite recursion by seeing if the node has been visited before
if (visited.includes(node.mac.toLowerCase())) {
console.error("Infinite recursion detected at node:", node.mac);
write_notification("[ERROR] ⚠ Infinite recursion detected. You probably have assigned the Internet node to another children node or to itself. Please open a new issue on GitHub and describe how you did it.", 'interrupt')
return { error: "Infinite recursion detected", node: node.mac };
}
}
// note the total number of leaf nodes to calculate the font scaling
if(children.length == 0)
{
leafNodesCount++
} else
{
parentNodesCount++
}
return {
name: node.name,
path: path,
mac: node.mac,
port: node.port,
id: node.mac,
parentMac: node.parentMac,
icon: node.icon,
type: node.type,
status: node.status,
hasChildren: children.length > 0 || hiddenMacs.includes(node.mac),
hiddenChildren: hiddenMacs.includes(node.mac),
qty: children.length,
children: children
};
// Add current node to visited list
visited.push(node.mac.toLowerCase());
// Loop through all items to find children of the current node
for (var i in list) {
if (list[i].parentMac.toLowerCase() == node.mac.toLowerCase() && !hiddenMacs.includes(list[i].parentMac)) {
visibleNodesCount++;
// Process children recursively, passing a copy of the visited list
children.push(getChildren(list[i], list, path + ((path == "") ? "" : '|') + list[i].parentMac, visited));
}
}
// Track leaf and parent node counts
if (children.length == 0) {
leafNodesCount++;
} else {
parentNodesCount++;
}
return {
name: node.name,
path: path,
mac: node.mac,
port: node.port,
id: node.mac,
parentMac: node.parentMac,
icon: node.icon,
type: node.type,
status: node.status,
hasChildren: children.length > 0 || hiddenMacs.includes(node.mac),
hiddenChildren: hiddenMacs.includes(node.mac),
qty: children.length,
children: children
};
}
// ---------------------------------------------------------------------------
function getHierarchy()

View File

@@ -620,7 +620,8 @@ function getDevicesList() {
array("dev_GUID", 19, 19),
array("dev_SyncHubNodeName", 20, 20),
array("dev_NetworkSite", 21, 21),
array("dev_SSID", 22, 22)
array("dev_SSID", 22, 22),
array("dev_SourcePlugin", 23, 23)
);
if($forceDefaultOrder == FALSE)
@@ -693,7 +694,8 @@ function getDevicesList() {
handleNull($row['dev_GUID']),
handleNull($row['dev_SyncHubNodeName']),
handleNull($row['dev_NetworkSite']),
handleNull($row['dev_SSID'])
handleNull($row['dev_SSID']),
handleNull($row['dev_SourcePlugin'])
);
$newOrder = array();

View File

@@ -576,7 +576,8 @@ function getDevicesColumns(){
"dev_GUID",
"dev_SyncHubNodeName",
"dev_NetworkSite",
"dev_SSID"
"dev_SSID",
"dev_SourcePlugin"
];
return $columns;

View File

@@ -31,6 +31,7 @@
| <a href="https://github.com/jokob-sk/NetAlertX/tree/main/docs#documentation-overview" target="_blank">Docs <i class="fa fa-circle-question"></i></a>
| <a href="https://github.com/jokob-sk/NetAlertX/issues"><i class="fa-solid fa-bug"></i></a>
| <a href="https://github.com/jokob-sk/NetAlertX/"><i class="fa-brands fa-github"></i></a>
| <a href="https://discord.gg/UQnnHNYV"><i class="fa-brands fa-discord"></i></a>
| <a href="mailto:jokob@duck.com?subject=NetAlertX"><i class="fa-solid fa-envelope"></i></a>
| <a href="https://github.com/pucherot/Pi.Alert">&copy;</a>
| <?= lang('Maintenance_built_on');?>: <?php include 'php/templates/build.php'; ?>

View File

@@ -73,10 +73,14 @@
<!-- Dark-Mode Patch -->
<?php
if ($ENABLED_DARKMODE === True) {
echo '<link rel="stylesheet" href="css/dark-patch.css">';
$BACKGROUND_IMAGE_PATCH='style="background-image: url(\'img/boxed-bg-dark.png\');"';
} else { $BACKGROUND_IMAGE_PATCH='style="background-image: url(\'img/background.png\');"';}
switch ($UI_THEME) {
case "Dark":
echo '<link rel="stylesheet" href="css/dark-patch.css">';
break;
case "System":
echo '<link rel="stylesheet" href="css/system-dark-patch.css">';
break;
}
?>
@@ -114,7 +118,7 @@
<!-- ----------------------------------------------------------------------- -->
<!-- Layout Boxed Yellow -->
<body class="hold-transition fixed <?php echo $pia_skin_selected;?> sidebar-mini" <?php echo $BACKGROUND_IMAGE_PATCH;?> onLoad="show_pia_servertime();" >
<body class="hold-transition fixed <?php echo $pia_skin_selected;?> sidebar-mini" onLoad="show_pia_servertime();" >
<!-- Site wrapper -->
<div class="wrapper">

View File

@@ -217,6 +217,7 @@
"Device_TableHead_RowID": "",
"Device_TableHead_Rowid": "",
"Device_TableHead_SSID": "",
"Device_TableHead_SourcePlugin": "",
"Device_TableHead_Status": "",
"Device_TableHead_SyncHubNodeName": "",
"Device_TableHead_Type": "",
@@ -284,6 +285,7 @@
"Gen_Description": "",
"Gen_Error": "",
"Gen_Filter": "",
"Gen_Generate": "",
"Gen_LockedDB": "",
"Gen_Offline": "",
"Gen_Okay": "",
@@ -309,6 +311,8 @@
"General_icon": "",
"HRS_TO_KEEP_NEWDEV_description": "",
"HRS_TO_KEEP_NEWDEV_name": "",
"HRS_TO_KEEP_OFFDEV_description": "",
"HRS_TO_KEEP_OFFDEV_name": "",
"HelpFAQ_Cat_Detail": "",
"HelpFAQ_Cat_Detail_300_head": "",
"HelpFAQ_Cat_Detail_300_text_a": "",
@@ -545,6 +549,12 @@
"Presence_CalHead_week": "",
"Presence_CalHead_year": "",
"Presence_CallHead_Devices": "",
"Presence_Key_OnlineNow": "",
"Presence_Key_OnlineNow_desc": "",
"Presence_Key_OnlinePast": "",
"Presence_Key_OnlinePastMiss": "",
"Presence_Key_OnlinePastMiss_desc": "",
"Presence_Key_OnlinePast_desc": "",
"Presence_Loading": "",
"Presence_Shortcut_AllDevices": "",
"Presence_Shortcut_Archived": "",

View File

@@ -217,6 +217,7 @@
"Device_TableHead_RowID": "",
"Device_TableHead_Rowid": "",
"Device_TableHead_SSID": "",
"Device_TableHead_SourcePlugin": "",
"Device_TableHead_Status": "",
"Device_TableHead_SyncHubNodeName": "",
"Device_TableHead_Type": "",
@@ -284,6 +285,7 @@
"Gen_Description": "",
"Gen_Error": "",
"Gen_Filter": "",
"Gen_Generate": "",
"Gen_LockedDB": "",
"Gen_Offline": "",
"Gen_Okay": "",
@@ -309,6 +311,8 @@
"General_icon": "",
"HRS_TO_KEEP_NEWDEV_description": "",
"HRS_TO_KEEP_NEWDEV_name": "",
"HRS_TO_KEEP_OFFDEV_description": "",
"HRS_TO_KEEP_OFFDEV_name": "",
"HelpFAQ_Cat_Detail": "",
"HelpFAQ_Cat_Detail_300_head": "",
"HelpFAQ_Cat_Detail_300_text_a": "",
@@ -545,6 +549,12 @@
"Presence_CalHead_week": "",
"Presence_CalHead_year": "",
"Presence_CallHead_Devices": "",
"Presence_Key_OnlineNow": "",
"Presence_Key_OnlineNow_desc": "",
"Presence_Key_OnlinePast": "",
"Presence_Key_OnlinePastMiss": "",
"Presence_Key_OnlinePastMiss_desc": "",
"Presence_Key_OnlinePast_desc": "",
"Presence_Loading": "",
"Presence_Shortcut_AllDevices": "",
"Presence_Shortcut_Archived": "",

View File

@@ -11,7 +11,7 @@
"APPRISE_SIZE_name": "Max payload size",
"APPRISE_URL_description": "Apprise notification target URL. For example for Telegram it would be <code>tgram://{bot_token}/{chat_id}</code>.",
"APPRISE_URL_name": "Apprise notification URL",
"About_Design": "Designed for:",
"About_Design": "Entworfen für:",
"About_Exit": "Abmelden",
"About_Title": "Netzwerksicherheitsscanner und Benachrichtigungsframework",
"AppEvents_DateTimeCreated": "protokolliert",
@@ -27,29 +27,29 @@
"AppEvents_ObjectPlugin": "Verknüpfte Plugins",
"AppEvents_ObjectPrimaryID": "Primär ID",
"AppEvents_ObjectSecondaryID": "Sekundär ID",
"AppEvents_ObjectStatus": "",
"AppEvents_ObjectStatus": "Status (zum Log-Zeitpunkt)",
"AppEvents_ObjectStatusColumn": "Statusspalte",
"AppEvents_ObjectType": "Objekttyp",
"AppEvents_Plugin": "Plugin",
"AppEvents_Type": "Typ",
"Apprise_display_name": "Apprise",
"Apprise_icon": "<i class=\"fa fa-bullhorn\"></i>",
"BackDevDetail_Actions_Ask_Run": "Do you want to execute the action?",
"BackDevDetail_Actions_Not_Registered": "Action not registered: ",
"BackDevDetail_Actions_Title_Run": "Run action",
"BackDevDetail_Copy_Ask": "Copy details from device from the dropdown list (Everything on this page will be overwritten)?",
"BackDevDetail_Copy_Title": "Copy details",
"BackDevDetail_Actions_Ask_Run": "Möchtest du die Aktion ausführen?",
"BackDevDetail_Actions_Not_Registered": "Aktion nicht registriert: ",
"BackDevDetail_Actions_Title_Run": "Aktion ausführen",
"BackDevDetail_Copy_Ask": "Details vom Gerät aus der Dropdown-Liste kopieren (alles auf dieser Seite wird überschrieben)?",
"BackDevDetail_Copy_Title": "Details kopieren",
"BackDevDetail_Tools_WOL_error": "Befehl wurde NICHT ausgeführt.",
"BackDevDetail_Tools_WOL_okay": "Befehl wurde ausgeführt.",
"BackDevices_Arpscan_disabled": "Automatischer Arp-Scan deaktiviert.",
"BackDevices_Arpscan_enabled": "Automatischer Arp-Scan aktiviert.",
"BackDevDetail_Tools_WOL_okay": "Der Befehl wurde ausgeführt.",
"BackDevices_Arpscan_disabled": "Arp-Scan deaktiviert",
"BackDevices_Arpscan_enabled": "Arp-Scan aktiviert",
"BackDevices_Backup_CopError": "Die originale Datenbank konnte nicht gesichert werden.",
"BackDevices_Backup_Failed": "Das Backup wurde teilweise ausgeführt. Das Archiv ist entweder leer oder nicht vorhanden.",
"BackDevices_Backup_okay": "Das Backup wurde erfolgreich beendet.",
"BackDevices_Backup_okay": "Die Sicherung wurde erfolgreich mit dem neuen Archiv ausgeführt",
"BackDevices_DBTools_DelActHistory": "Die Anzeige der Netzwerkaktivität wurde zurückgesetzt.",
"BackDevices_DBTools_DelActHistoryError": "Fehler beim Zurücksetzen der Netzwerkaktivitätsanzeige.",
"BackDevices_DBTools_DelDevError_a": "Fehler beim Löschen des Gerätes.",
"BackDevices_DBTools_DelDevError_b": "Fehler beim Löschen der Geräte.",
"BackDevices_DBTools_DelDevError_a": "Fehler beim Löschen des Gerätes",
"BackDevices_DBTools_DelDevError_b": "Fehler beim Löschen der Geräte",
"BackDevices_DBTools_DelDev_a": "Gerät wurde gelöscht",
"BackDevices_DBTools_DelDev_b": "Geräte wurden gelöscht",
"BackDevices_DBTools_DelEvents": "Events wurden gelöscht",
@@ -69,11 +69,11 @@
"BackDevices_darkmode_disabled": "Heller Modus aktiviert",
"BackDevices_darkmode_enabled": "Dunkler Modus aktiviert",
"CLEAR_NEW_FLAG_description": "",
"CLEAR_NEW_FLAG_name": "",
"CLEAR_NEW_FLAG_name": "Neues Flag löschen",
"DAYS_TO_KEEP_EVENTS_description": "Dies ist eine Wartungseinstellung. Spezifiziert wie viele Tage Events gespeichert bleiben. Alle älteren Events werden periodisch gelöscht. Wird auch auf die Plugins History angewendet.",
"DAYS_TO_KEEP_EVENTS_name": "Lösche Events älter als",
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Details von Gerät kopieren",
"DevDetail_Copy_Device_Tooltip": "Copy details from device from the dropdown list. Everything on this page will be overwritten",
"DevDetail_Copy_Device_Tooltip": "Details vom Gerät aus der Dropdown-Liste kopieren. Alles auf dieser Seite wird überschrieben",
"DevDetail_EveandAl_AlertAllEvents": "Melde alle Ereignisse",
"DevDetail_EveandAl_AlertDown": "Melde Down",
"DevDetail_EveandAl_Archived": "Archivierung",
@@ -86,9 +86,9 @@
"DevDetail_EveandAl_Skip": "pausiere wiederhol. Meldungen für",
"DevDetail_EveandAl_Title": "Ereignisse & Alarme einstellen",
"DevDetail_Events_CheckBox": "Blende Verbindungs-Ereignisse aus",
"DevDetail_GoToNetworkNode": "Navigate to the Network page of the given node.",
"DevDetail_GoToNetworkNode": "Zur Netzwerkseite des angegebenen Knotens navigieren.",
"DevDetail_Icon": "Icon",
"DevDetail_Icon_Descr": "Enter a font awesome icon name without the fa- prefix or with complete class, e.g.: fa fa-brands fa-apple.",
"DevDetail_Icon_Descr": "",
"DevDetail_Loading": "Laden ...",
"DevDetail_MainInfo_Comments": "Notiz",
"DevDetail_MainInfo_Favorite": "Favorit",
@@ -97,7 +97,7 @@
"DevDetail_MainInfo_Name": "Name",
"DevDetail_MainInfo_Network": "<i class=\"fa fa-server\"></i> Knoten (MAC)",
"DevDetail_MainInfo_Network_Port": "<i class=\"fa fa-ethernet\"></i> Port",
"DevDetail_MainInfo_Network_Site": "",
"DevDetail_MainInfo_Network_Site": "Seite",
"DevDetail_MainInfo_Network_Title": "<i class=\"fa fa-network-wired\"></i> Network",
"DevDetail_MainInfo_Owner": "Eigen&shy;tümer",
"DevDetail_MainInfo_SSID": "SSID",
@@ -106,7 +106,7 @@
"DevDetail_MainInfo_Vendor": "Hersteller",
"DevDetail_MainInfo_mac": "MAC",
"DevDetail_Network_Node_hover": "Wählen Sie das Elternnetzgerät aus, an das das aktuelle Gerät angeschlossen ist, um den Netzwerkbaum zu erstellen.",
"DevDetail_Network_Port_hover": "The port this device is connected to on the parent network device. If left empty a wifi icon is displayed in the Network tree.",
"DevDetail_Network_Port_hover": "Der Port, mit dem dieses Gerät am übergeordneten Netzwerkgerät verbunden ist. Bleibt er leer, wird ein WLAN-Symbol in der Netzwerkstruktur angezeigt.",
"DevDetail_Nmap_Scans": "Nmap Scans",
"DevDetail_Nmap_Scans_desc": "Hier kannst du manuelle NMAP Scans starten. Reguläre automatische NMAP Scans können mit dem Services & Ports (NMAP) Plugin geplant werden. Gehe zu den <a href='/settings.php' target='_blank'>Einstellungen</a> um erfahren",
"DevDetail_Nmap_buttonDefault": "Standard Scan",
@@ -137,7 +137,7 @@
"DevDetail_SessionTable_Disconnection": "Trennung",
"DevDetail_SessionTable_Duration": "Dauer",
"DevDetail_SessionTable_IP": "IP",
"DevDetail_SessionTable_Order": "Order",
"DevDetail_SessionTable_Order": "Reihenfolge",
"DevDetail_Shortcut_CurrentStatus": "aktueller Status",
"DevDetail_Shortcut_DownAlerts": "Down Meldungen",
"DevDetail_Shortcut_Presence": "Anwesenheit",
@@ -161,7 +161,7 @@
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Anwesenheit",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sitzungen",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Tools",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Werkzeuge",
"DevDetail_Tab_Tools_Internet_Info_Description": "Das Internet-Info-Tool zeigt Informationen über die Internetverbindung an, wie z. B. IP-Adresse, Stadt, Land, Ortsvorwahl und Zeitzone.",
"DevDetail_Tab_Tools_Internet_Info_Error": "Es ist ein Fehler aufgetreten",
"DevDetail_Tab_Tools_Internet_Info_Start": "Internet-Info starten",
@@ -181,24 +181,24 @@
"DevDetail_Tools_WOL_noti": "Wake-on-LAN",
"DevDetail_Tools_WOL_noti_text": "Der Wake-on-LAN Befehl wurde and die Broadcast Adresse gesendet. Wenn sich das zu startende Gerät nicht im gleichen Subnet / VLan wie NetAlertX befindet, wird das Gerät nicht reagieren.",
"DevDetail_Type_hover": "Der Type des Gerätes. If you select any of the pre-defined network devices (e.g.: AP, Firewall, Router, Switch...) they will show up in the Network tree configuration as possible parent network nodes.",
"DevDetail_Vendor_hover": "Vendor should be auto-detected. You can overwrite or add your custom value.",
"DevDetail_Vendor_hover": "Der Anbieter sollte automatisch erkannt werden. Du kannst den Wert überschreiben oder deinen eigenen Wert hinzufügen.",
"DevDetail_WOL_Title": "<i class=\"fa fa-power-off\"></i> Wake-on-LAN",
"DevDetail_button_AddIcon": "Neues Symbol Hinzufügen",
"DevDetail_button_AddIcon_Help": "Füge ein HTML SVG Tag oder Font Awesome HTML Tag ein. Siehe <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/ICONS.md\" target=\"_blank\">Icon Dokumentation</a> für details.",
"DevDetail_button_AddIcon_Tooltip": "Neues Icon zu diesem Gerät hinzufügen, welches es noch nicht im dropdown gibt.",
"DevDetail_button_Delete": "Lösche Gerät",
"DevDetail_button_DeleteEvents": "Lösche Events",
"DevDetail_button_Delete": "Gerät löschen",
"DevDetail_button_DeleteEvents": "Ereignisse löschen",
"DevDetail_button_DeleteEvents_Warning": "Sind Sie sicher, dass Sie alle Ereignisse dieses Geräts löschen möchten? (dies löscht den Ereignisverlauf und die Sitzungen und könnte bei ständigen (anhaltenden) Benachrichtigungen helfen)",
"DevDetail_button_OverwriteIcons": "Overwrite Icons",
"DevDetail_button_OverwriteIcons_Tooltip": "Overwrite icons of all devices with the same device type",
"DevDetail_button_OverwriteIcons_Warning": "Are you sure you want to overwrite all icons of all devices with the same device type as the current device type?",
"DevDetail_button_OverwriteIcons": "Symbole überschreiben",
"DevDetail_button_OverwriteIcons_Tooltip": "Symbole aller Geräte mit demselben Gerätetyp überschreiben",
"DevDetail_button_OverwriteIcons_Warning": "Bist du sicher, dass du alle Symbole aller Geräte mit dem gleichen Gerätetyp wie dem aktuellen Gerätetyp überschreiben willst?",
"DevDetail_button_Reset": "Verwerfen",
"DevDetail_button_Save": "Speichern",
"Device_MultiEdit": "Mehrfach-bearbeiten",
"Device_MultiEdit_Backup": "",
"Device_MultiEdit_Fields": "Felder bearbeiten:",
"Device_MultiEdit_MassActions": "Massen aktionen:",
"Device_MultiEdit_Tooltip": "",
"Device_MultiEdit_Tooltip": "Achtung! Beim Drücken werden alle Werte auf die oben ausgewählten Geräte übertragen.",
"Device_Searchbox": "Suche",
"Device_Shortcut_AllDevices": "Meine Geräte",
"Device_Shortcut_Archived": "Archiviert",
@@ -209,26 +209,27 @@
"Device_Shortcut_Favorites": "Favoriten",
"Device_Shortcut_NewDevices": "Neue Geräte",
"Device_Shortcut_OnlineChart": "Gerätepräsenz im Laufe der Zeit",
"Device_TableHead_Connected_Devices": "Verbundene Geräte",
"Device_TableHead_Connected_Devices": "Verbindungen",
"Device_TableHead_Favorite": "Favorit",
"Device_TableHead_FirstSession": "Erste Sitzung",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Gruppe",
"Device_TableHead_Icon": "Icon",
"Device_TableHead_LastIP": "Letzte IP",
"Device_TableHead_LastIPOrder": "Last IP Order",
"Device_TableHead_LastIPOrder": "Letzte erhaltene IP",
"Device_TableHead_LastSession": "Zuletzt offline",
"Device_TableHead_Location": "Standort",
"Device_TableHead_MAC": "MAC",
"Device_TableHead_MAC": "Zufälliger MAC",
"Device_TableHead_MAC_full": "Gesamte MAC",
"Device_TableHead_Name": "Name",
"Device_TableHead_NetworkSite": "",
"Device_TableHead_NetworkSite": "Netzwerkseite",
"Device_TableHead_Owner": "Eigentümer",
"Device_TableHead_Parent_MAC": "Übergeordnete MAC",
"Device_TableHead_Port": "Port",
"Device_TableHead_RowID": "Zeilen ID",
"Device_TableHead_Rowid": "Zeilennummer",
"Device_TableHead_SSID": "SSID",
"Device_TableHead_SourcePlugin": "",
"Device_TableHead_Status": "Status",
"Device_TableHead_SyncHubNodeName": "Synchronisationsknoten",
"Device_TableHead_Type": "Typ",
@@ -240,10 +241,10 @@
"Device_Tablelenght": "Zeige _MENU_ Einträge",
"Device_Tablelenght_all": "Alle",
"Device_Title": "Geräte",
"Donations_Others": "Others",
"Donations_Platforms": "Sponsor platforms",
"Donations_Others": "Andere",
"Donations_Platforms": "Sponsor-Platformen",
"Donations_Text": "Hey 👋! </br> Thanks for clicking on this menu item 😅 </br> </br> I'm trying to collect some donations to make you better software. Also, it would help me not to get burned out. Me burning out might mean end of support for this app. Any small (recurring or not) sponsorship makes me want ot put more effort into this app. I don't want to lock features (new plugins) behind paywalls 🔐. </br> Currently, I'm waking up 2h before work so I contribute to the app a bit. If I had some recurring income I could shorten my workweek and in the remaining time fully focus on NetAlertX. You'd get more functionality, a more polished app and less bugs. </br> </br> Thanks for reading - I'm super grateful for any support ❤🙏 </br> </br> TL;DR: By supporting me you get: </br> </br> <ul><li>Regular updates to keep your data and family safe 🔄</li><li>Less bugs 🐛🔫</li><li>Better and more functionality</li><li>I don't get burned out 🔥🤯</li><li>Less rushed releases 💨</li><li>Better docs📚</li><li>Quicker and better support with issues 🆘</li><li>Less grumpy me 😄</li></ul> </br> 📧Email me to <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> if you want to get in touch or if I should add other sponsorship platforms. </br>",
"Donations_Title": "Donations",
"Donations_Title": "Spenden",
"ENABLE_PLUGINS_description": "NOTUSED Enables the <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a> functionality. Loading plugins requires more hardware resources so you might want to disable them on low-powered system.",
"ENABLE_PLUGINS_name": "NOTUSED Enable Plugins",
"Email_display_name": "Email",
@@ -268,11 +269,11 @@
"Events_TableHead_Device": "Gerät",
"Events_TableHead_Disconnection": "Trennung",
"Events_TableHead_Duration": "Dauer",
"Events_TableHead_DurationOrder": "Duration Order",
"Events_TableHead_DurationOrder": "Dauer-Reihenfolge",
"Events_TableHead_EventType": "Ereignis Typ",
"Events_TableHead_IP": "IP",
"Events_TableHead_IPOrder": "IP Order",
"Events_TableHead_Order": "Order",
"Events_TableHead_IPOrder": "IP-Reihenfolge",
"Events_TableHead_Order": "Reihenfolge",
"Events_TableHead_Owner": "Eigentümer",
"Events_TableHead_PendingAlert": "Ausstehender Alarm",
"Events_Table_info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
@@ -288,14 +289,15 @@
"Gen_AreYouSure": "Sind Sie sich sicher?",
"Gen_Backup": "Sichern",
"Gen_Cancel": "Abbrechen",
"Gen_Change": "",
"Gen_Copy": "Run",
"Gen_Change": "Ändern",
"Gen_Copy": "Ausführen",
"Gen_DataUpdatedUITakesTime": "OK Es kann einen Moment dauern, bis die Benutzeroberfläche aktualisiert wird, während ein Scan ausgeführt wird.",
"Gen_Delete": "Löschen",
"Gen_DeleteAll": "Delete all",
"Gen_Description": "",
"Gen_DeleteAll": "Alles löschen",
"Gen_Description": "Beschreibung",
"Gen_Error": "Fehler",
"Gen_Filter": "Filter",
"Gen_Generate": "",
"Gen_LockedDB": "ERROR - DB eventuell gesperrt - Nutze die Konsole in den Entwickler Werkzeugen (F12) zur Überprüfung oder probiere es später erneut.",
"Gen_Offline": "Offline",
"Gen_Okay": "Ok",
@@ -304,11 +306,11 @@
"Gen_Remove_All": "Alle entfernen",
"Gen_Remove_Last": "Letzte entfernen",
"Gen_Restore": "Wiederherstellen",
"Gen_Run": "Run",
"Gen_Run": "Ausführen",
"Gen_Save": "Speichern",
"Gen_Saved": "Gespeichert",
"Gen_Search": "Suchen",
"Gen_SelectToPreview": "",
"Gen_SelectToPreview": "Zur Vorschau auswählen",
"Gen_Selected_Devices": "Ausgewählte Geräte:",
"Gen_Switch": "Umschalten",
"Gen_Upd": "Aktualisierung erfolgreich",
@@ -319,8 +321,10 @@
"Gen_Work_In_Progress": "Keine Finalversion, feedback bitte unter: https://github.com/jokob-sk/NetAlertX/issues",
"General_display_name": "Allgemein",
"General_icon": "<i class=\"fa fa-gears\"></i>",
"HRS_TO_KEEP_NEWDEV_description": "Dies ist eine Wartungseinstellung. Wenn aktiviert (<code>0</code> bedeutet deaktiviert), werden als <b>\"Neues Gerät\"</b> markierte Geräte gelöscht, wenn ihre <b>erste Sitzung</b> länger her ist als in dieser Einstellung angegeben. Verwenden Sie diese Einstellung, wenn Sie <b>Neue Geräte</b> nach <code>X</code> Stunden automatisch löschen wollen.",
"HRS_TO_KEEP_NEWDEV_name": "Neue Geräte speichern für",
"HRS_TO_KEEP_NEWDEV_description": "Dies ist eine Wartungseinstellung <b>DELETING devices</b>. Wenn aktiviert (<code>0</code> bedeutet deaktiviert), werden als <b>\"Neues Gerät\"</b> markierte Geräte gelöscht, wenn ihre <b>erste Sitzung</b> länger her ist als in dieser Einstellung angegeben. Verwenden Sie diese Einstellung, wenn Sie <b>Neue Geräte</b> nach <code>X</code> Stunden automatisch löschen wollen.",
"HRS_TO_KEEP_NEWDEV_name": "Neue Geräte löschen nach",
"HRS_TO_KEEP_OFFDEV_description": "",
"HRS_TO_KEEP_OFFDEV_name": "",
"HelpFAQ_Cat_Detail": "Detailansicht",
"HelpFAQ_Cat_Detail_300_head": "Was bedeutet ",
"HelpFAQ_Cat_Detail_300_text_a": "meint ein Netzwerkgerät (ein Gerät vom Typ AP, Gateway, Firewall, Hypervisor, Powerline, Switch, WLAN, PLC, Router, USB-LAN-Adapter oder Internet). Benutzerdefinierte Typen können über die <code>NETWORK_DEVICE_TYPES</code> Einstellung hinzugefügt werden.",
@@ -339,13 +343,13 @@
"HelpFAQ_Cat_General_100_head": "Die Uhr oben rechts und die Zeiten der Events/Anwesenheit stimmen nicht überein (Zeitverschiebung).",
"HelpFAQ_Cat_General_100_text_a": "Auf deinem PC ist für die PHP Umgebung folgende Zeitzone voreingestellt:",
"HelpFAQ_Cat_General_100_text_b": "Sollte dies nicht die Zeitzone sein, in der du dich aufhältst, solltest du die Zeitzone in der PHP Konfigurationsdatei anpassen. Diese findest du in diesem Verzeichnis:",
"HelpFAQ_Cat_General_100_text_c": "Suche in dieser Datei nach dem Eintrag 'date.timezone', entferne ggf. das führende ';' und trage die gewünschte Zeitzone ein. Eine Liste mit den unterstützten Zeitzonen findest du hier (<a href=\"https://www.php.net/manual/de/timezones.php\" target=\"blank\">Link</a>).",
"HelpFAQ_Cat_General_100_text_c": "Suche in dieser Datei nach dem Eintrag 'date.timezone', entferne ggf. das führende ';' und trage die gewünschte Zeitzone ein. Eine Liste mit den unterstützten Zeitzonen findest du hier: (<a href=\"https://www.php.net/manual/de/timezones.php\" target=\"blank\">Link</a>)",
"HelpFAQ_Cat_General_101_head": "Mein Netzwerk scheint langsamer zu werden, Streaming ruckelt.",
"HelpFAQ_Cat_General_101_text": "Es kann durchaus sein, das leistungsschwache Geräte mit der Art und Weise, wie NetAlertX neue Geräte im Netzwerk erkennt, an ihre Leistungsgrenzen kommen. Dies verstärkt sich noch einmal, <br/> wenn diese Geräte per WLAN mit dem Netzwerk kommunizieren. Lösungen wären hier, wenn möglich ein Wechsel auf eine Kabelverbindung oder, falls das Geräte nur einen begrenzten Zeitraum genutzt <br/> werden soll, den arp-Scan auf der Wartungsseite zu pausieren.",
"HelpFAQ_Cat_General_102_head": "Ich bekomme die Meldung, dass die Datenbank schreibgeschützt (read only) ist.",
"HelpFAQ_Cat_General_102_text": "Prüfe im NetAlertX verzeichnis ob der Ordner der Datenbank (db) die richtigen Rechte zugewiesen bekommen hat:<br> <span class=\"text-danger help_faq_code\">drwxrwx--- 2 (dein Username) www-data</span><br> Sollte die Berechtigung nicht stimmen, kannst du sie mit folgenden Befehlen im Terminal oder der Konsole wieder setzen:<br> <span class=\"text-danger help_faq_code\"> sudo chgrp -R www-data /app/db<br> chmod -R 770 /app/db </span><br> Wenn die Datenbank danach noch immer schreibgeschützt ist, versuche eine erneute Installation, oder das Zuückspielen eines Datenbank-Backups über die Wartungsseite.",
"HelpFAQ_Cat_General_102docker_head": "(🐳 Docker only) Database issues (AJAX errors, read-only, not found)",
"HelpFAQ_Cat_General_102docker_text": "Double-check you have followed the <a href=\"https://github.com/jokob-sk/NetAlertX/tree/main/dockerfiles\">dockerfile readme (most up-to-date info)</a>. <br/> <br/> <ul data-sourcepos=\"49:4-52:146\" dir=\"auto\"> <li data-sourcepos=\"49:4-49:106\">Download the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/db/app.db\">original DB from GitHub</a>.</li> <li data-sourcepos=\"50:4-50:195\">Map the <code>app.db</code> file (<g-emoji class=\"g-emoji\" alias=\"warning\" fallback-src=\"https://github.githubassets.com/images/icons/emoji/unicode/26a0.png\">⚠</g-emoji> not folder) from above to <code>/app/db/app.db</code> (see <a href=\"https://github.com/jokob-sk/NetAlertX/tree/main/dockerfiles#-examples\">Examples</a> for details).</li><li data-sourcepos=\"51:4-51:161\">If facing issues (AJAX errors, can not write to DB, etc,) make sure permissions are set correctly, alternatively check the logs under <code>/app/front/log</code>.</li> <li data-sourcepos=\"52:4-52:146\">To solve permission issues you can also try to create a DB backup and then run a DB Restore via the <strong>Maintenance &gt; Backup/Restore</strong> section.</li> <li data-sourcepos=\"53:4-53:228\">If the database is in read-only mode you can solve this by setting the owner and group by executing the following command on the host system: <code>docker exec netalertx chown -R www-data:www-data /app/db/app.db</code>.</li></ul>",
"HelpFAQ_Cat_General_102docker_text": "",
"HelpFAQ_Cat_General_103_head": "Die Login-Seite erscheint nicht, auch nicht nach der Passwortänderung.",
"HelpFAQ_Cat_General_103_text": "Neben dem Passwort, muss in der Konfigurationsdatei <span class=\"text-danger help_faq_code\">/app/config/app.conf</span> auch der Parameter <span class=\"text-danger help_faq_code\">PIALERT_WEB_PROTECTION</span> auf <span class=\"text-danger help_faq_code\">True</span> gesetzt sein.",
"HelpFAQ_Cat_Network_600_head": "Was bringt mir diese Seite?",
@@ -367,7 +371,7 @@
"Login_Info": "",
"Login_Psw-box": "Passwort",
"Login_Psw_alert": "Sicherheitshinweis!",
"Login_Psw_folder": "im Ordner /app/config",
"Login_Psw_folder": "im Konfigurationsordner.",
"Login_Psw_new": "neues_passwort",
"Login_Psw_run": "Um das Passwort zu ändern nutze:",
"Login_Remember": "Passwort speichern",
@@ -407,8 +411,8 @@
"Maintenance_Tool_ImportPastedCSV": "CSV-Import (Einfügen)",
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
"Maintenance_Tool_ImportPastedCSV_text": "",
"Maintenance_Tool_arpscansw": "arp-Scan stoppen/starten",
"Maintenance_Tool_arpscansw_noti": "arp-Scan stoppen/starten",
"Maintenance_Tool_arpscansw": "ARP-Scan umschalten (ein/aus)",
"Maintenance_Tool_arpscansw_noti": "ARP-Scan ein- oder ausschalten",
"Maintenance_Tool_arpscansw_noti_text": "Wenn der Scan aus ist, bleibt er so lange aus bis er wieder aktiviert wird.",
"Maintenance_Tool_arpscansw_text": "Schaltet den arp-Scan an oder aus. Wenn der Scan aus ist, bleibt er so lange aus bis er wieder aktiviert wird. Bereits laufende Scans werden dabei nicht beendet.",
"Maintenance_Tool_backup": "DB Sicherung",
@@ -433,7 +437,7 @@
"Maintenance_Tool_del_allevents30_noti": "Ereignisse löschen",
"Maintenance_Tool_del_allevents30_noti_text": "Sind Sie sich sicher, dass Sie alle Ereignisse älter als 30 Tage löschen wollen? Dies setzt die Präsenz aller Geräte zurück.",
"Maintenance_Tool_del_allevents30_text": "Machen Sie ein Backup, bevor Sie diese Funk­tion nutzen. Der Vor­gang kann ohne Back­up nicht rück­gängig gemacht werden. Alle Ereignisse älter als 30 Tage werden aus der Datenbank ge­löscht. Dies setzt auch die Anwesenheit zu­rück. Es kann ab dem Moment zu ungültigen Sitzungen kommen. Ein Scan, während das betreffende Gerät online ist, sollte das Problem lösen.",
"Maintenance_Tool_del_allevents_noti": "Alle Ereignisse löschen",
"Maintenance_Tool_del_allevents_noti": "Ereignisse löschen",
"Maintenance_Tool_del_allevents_noti_text": "Sind Sie sicher, dass Sie alle Ereignisse aus der Datenbank löschen wollen. Dies setzt die Anwesenheit aller Geräte zurück.",
"Maintenance_Tool_del_allevents_text": "Machen Sie ein Backup, bevor Sie diese Funk&shy;tion nutzen. Der Vor&shy;gang kann ohne Back&shy;up nicht rück&shy;gängig gemacht werden. Alle Ereignisse werden aus der Datenbank ge&shy;löscht. Dies setzt auch die Anwesenheit zu&shy;rück. Es kann ab dem Moment zu ungültigen Sitzungen kommen. Ein Scan, während das betreffende Gerät online ist, sollte das Problem lösen.",
"Maintenance_Tool_del_empty_macs": "Alle Geräte ohne MAC löschen",
@@ -446,7 +450,7 @@
"Maintenance_Tool_del_unknowndev_noti": "Lösche (unknown) Geräte",
"Maintenance_Tool_del_unknowndev_noti_text": "Sind Sie sicher, dass Sie alle (unknown) Geräte aus der Datenbank löschen wollen?",
"Maintenance_Tool_del_unknowndev_text": "Machen Sie ein Backup, bevor Sie diese Funk&shy;tion nutzen. Der Vor&shy;gang kann ohne Back&shy;up nicht rück&shy;gängig gemacht werden. Alle Gräte mit dem Namen (unknown) werden aus der Datenbank ge&shy;löscht.",
"Maintenance_Tool_displayed_columns_text": "Ändere die Sichtbarkeit und Anordnung der Spalten in der <a href=\"devices.php\"><b> <i class=\"fa fa-laptop\"></i> Geräte</b></a>-Seite. (Drag-and-Drop funktioniert nicht einwandfrei, ist aber verwendbar. Ich habe <a href=\"https://github.com/jokob-sk/NetAlertX/commit/94b32f0f7332879f5a7d2af05dafa2e5d5cfa5da\">3 Stunden</a> versucht das zu beheben, werde es aber nicht weiter verfolgen. Über einen PR mit einem Fix würde ich mich freuen :) ).",
"Maintenance_Tool_displayed_columns_text": "Ändere die Sichtbarkeit und Anordnung der Spalten in der <a href=\"devices.php\"><b> <i class=\"fa fa-laptop\"></i> Geräte</b></a>-Seite.",
"Maintenance_Tool_drag_me": "Zieh mich um die Anordnung der Spalten zu ändern.",
"Maintenance_Tool_order_columns_text": "",
"Maintenance_Tool_purgebackup": "Sicherungen aufräumen",
@@ -458,14 +462,14 @@
"Maintenance_Tool_restore_noti_text": "Sind Sie sicher, dass Sie die Datenbank aus der neusten Sicherung wiederherstellen möchten? Prüfen Sie, dass gerade keine Scans stattfinden.",
"Maintenance_Tool_restore_text": "Das neuste Backup kann über diese Funk&shy;tion wiederhergestellt werden. Ältere Sicher&shy;ungen müssen manuell wieder&shy;hergestellt wer&shy;den. Es empfiehlt sich eine Integritäts&shy;prüfung nach der Wieder&shy;her&shy;stellung zu machen, falls die Datenbank bei der Sicherung geöffnet war.",
"Maintenance_Tool_upgrade_database_noti": "Aktualisiere Datenbank",
"Maintenance_Tool_upgrade_database_noti_text": "Machen Sie ein Backup, bevor Sie diese Funk&shy;tion nutzen.",
"Maintenance_Tool_upgrade_database_noti_text": "",
"Maintenance_Tool_upgrade_database_text": "Mit dieser Schaltfläche wird die Datenbank aktualisiert, um das Diagramm der Netzwerkaktivitäten der letzten 12 Stunden zu aktivieren. Bitte sichern Sie Ihre Datenbank, falls Probleme auftreten.",
"Maintenance_Tools_Tab_BackupRestore": "Sicherg. / Wiederherstellg.",
"Maintenance_Tools_Tab_Logging": "Logs",
"Maintenance_Tools_Tab_BackupRestore": "Sichern / Wiederherstellen",
"Maintenance_Tools_Tab_Logging": "Protokolle",
"Maintenance_Tools_Tab_Settings": "Einstellungen",
"Maintenance_Tools_Tab_Tools": "Werkzeuge",
"Maintenance_Tools_Tab_UISettings": "UI Einstellungen",
"Maintenance_arp_status": "Scan Status",
"Maintenance_arp_status": "Scan-Status",
"Maintenance_arp_status_off": "ist im Moment deaktiviert",
"Maintenance_arp_status_on": "Scan(s) sind gerade aktiv",
"Maintenance_built_on": "Erstellt am",
@@ -501,7 +505,7 @@
"NTFY_icon": "<i class=\"fa fa-terminal\"></i>",
"Navigation_About": "Über",
"Navigation_Devices": "Geräte",
"Navigation_Donations": "Donations",
"Navigation_Donations": "Spenden",
"Navigation_Events": "Ereignisse",
"Navigation_Flows": "Flows",
"Navigation_HelpFAQ": "Hilfe / FAQ",
@@ -539,7 +543,7 @@
"Network_ManageEdit_ID_text": "-- Gerät wählen --",
"Network_ManageEdit_Name": "Neuer Name",
"Network_ManageEdit_Name_text": "Name ohne Sonderzeichen",
"Network_ManageEdit_Port": "Neue Portanzahl",
"Network_ManageEdit_Port": " Neue Portanzahl",
"Network_ManageEdit_Port_text": "bei WLAN oder Powerline leer lassen",
"Network_ManageEdit_Submit": "Speichern",
"Network_ManageEdit_Type": "Neuer Typ",
@@ -564,21 +568,21 @@
"PIALERT_WEB_PASSWORD_description": "Das Standardpasswort ist <code>123456</code>. Um das Passwort zu ändern, entweder <code>/app/back/pialert-cli</code> im Container starten oder <a onclick=\"toggleAllSettings()\" href=\"#SETPWD_RUN\"><code>SETPWD_RUN</code> Set password plugin</a> nutzen.",
"PIALERT_WEB_PASSWORD_name": "Login-Passwort",
"PIALERT_WEB_PROTECTION_description": "Ein Loginfenster wird angezeigt wenn aktiviert. Untere Beschreibung genau durchlesen falls Sie sich aus Ihrer Instanz aussperren.",
"PIALERT_WEB_PROTECTION_name": "Login aktivieren",
"PIALERT_WEB_PROTECTION_name": "Anmeldung aktivieren",
"PLUGINS_KEEP_HIST_description": "Wie viele Plugin Scanresultate behalten werden (pro Plugin, nicht gerätespezifisch).",
"PLUGINS_KEEP_HIST_name": "Plugins Verlauf",
"PUSHSAFER_TOKEN_description": "Your secret Pushsafer API key (token).",
"PUSHSAFER_TOKEN_name": "Pushsafer token",
"PUSHSAFER_display_name": "Pushsafer",
"PUSHSAFER_icon": "<i class=\"fa fa-bell\"></i>",
"Plugins_DeleteAll": "Delete all (filters are ignored)",
"Plugins_DeleteAll": "Alles löschen (Filter werden ignoriert)",
"Plugins_Filters_Mac": "Mac Filter",
"Plugins_History": "Events History",
"Plugins_Obj_DeleteListed": "",
"Plugins_Objects": "Plugin Objects",
"Plugins_History": "Verlauf der Ereignisse",
"Plugins_Obj_DeleteListed": "Aufgelistete Objekte löschen",
"Plugins_Objects": "Plugin-Objekte",
"Plugins_Out_of": "von",
"Plugins_Unprocessed_Events": "Unprocessed Events",
"Plugins_no_control": "No form control was found to render this value.",
"Plugins_Unprocessed_Events": "Unverarbeitete Ereignisse",
"Plugins_no_control": "",
"Presence_CalHead_day": "Tag",
"Presence_CalHead_lang": "de",
"Presence_CalHead_month": "Monat",
@@ -586,6 +590,12 @@
"Presence_CalHead_week": "Woche",
"Presence_CalHead_year": "Jahr",
"Presence_CallHead_Devices": "Geräte",
"Presence_Key_OnlineNow": "",
"Presence_Key_OnlineNow_desc": "",
"Presence_Key_OnlinePast": "",
"Presence_Key_OnlinePastMiss": "",
"Presence_Key_OnlinePastMiss_desc": "",
"Presence_Key_OnlinePast_desc": "",
"Presence_Loading": "Laden...",
"Presence_Shortcut_AllDevices": "Meine Geräte",
"Presence_Shortcut_Archived": "Archiviert",
@@ -603,7 +613,7 @@
"REPORT_FROM_description": "Notification email subject line. Some SMTP servers need this to be an email.",
"REPORT_FROM_name": "Email subject",
"REPORT_MAIL_description": "If enabled an email is sent out with a list of changes you nove subscribed to. Please also fill out all remaining settings related to the SMTP setup below. If facing issues, set <code>LOG_LEVEL</code> to <code>debug</code> and check the <a href=\"/maintenance.php#tab_Logging\">error log</a>.",
"REPORT_MAIL_name": "Enable email",
"REPORT_MAIL_name": "E-Mail aktivieren",
"REPORT_MQTT_description": "Enable sending notifications via <a target=\"_blank\" href=\"https://www.home-assistant.io/integrations/mqtt/\">MQTT</a> to your Home Assistance instance.",
"REPORT_MQTT_name": "Enable MQTT",
"REPORT_NTFY_description": "Enable sending notifications via <a target=\"_blank\" href=\"https://ntfy.sh/\">NTFY</a>.",
@@ -615,10 +625,10 @@
"REPORT_TO_name": "Send email to",
"REPORT_WEBHOOK_description": "Enable webhooks for notifications. Webhooks help you to connect to a lot of 3rd party tools, such as IFTTT, Zapier or <a href=\"https://n8n.io/\" target=\"_blank\">n8n</a> to name a few. Check out this simple <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/WEBHOOK_N8N.md\" target=\"_blank\">n8n guide here</a> to get started. If enabled, configure related settings below.",
"REPORT_WEBHOOK_name": "Enable Webhooks",
"RandomMAC_hover": "Autodetected - indicates if the device randomizes it's MAC address.",
"RandomMAC_hover": "Automatisch erkannt - gibt an, ob das Gerät seine MAC-Adresse zufällig ermittelt.",
"Reports_Sent_Log": "Protokoll gesendeter Berichte",
"SCAN_SUBNETS_description": "",
"SCAN_SUBNETS_name": "",
"SCAN_SUBNETS_name": "scan Netzwerke",
"SMTP_FORCE_SSL_description": "Force SSL when connecting to your SMTP server.",
"SMTP_FORCE_SSL_name": "Force SSL",
"SMTP_PASS_description": "The SMTP server password. ",
@@ -634,10 +644,10 @@
"SMTP_USER_description": "The user name used to login into the SMTP server (sometimes a full email address).",
"SMTP_USER_name": "SMTP user",
"SYSTEM_TITLE": "Systeminformationen",
"Setting_Override": "Override value",
"Setting_Override_Description": "Enabling this option will override an App supplied default value with the value specified above.",
"Settings_Metadata_Toggle": "Show/hide metadata for the given setting.",
"Settings_Show_Description": "",
"Setting_Override": "Wert überschreiben",
"Setting_Override_Description": "",
"Settings_Metadata_Toggle": "Metadaten für die angegebene Einstellung anzeigen/ausblenden.",
"Settings_Show_Description": "Beschreibung der Einstellung anzeigen.",
"Settings_device_Scanners_desync": "⚠ Die Zeitpläne des Gerätescanners sind nicht synchronisiert.",
"Settings_device_Scanners_desync_popup": "",
"Speedtest_Results": "Ergebnisse des Geschwindigkeitstests",
@@ -721,19 +731,19 @@
"UI_DEV_SECTIONS_description": "Auswählen, welche Elemente in der Geräteseite versteckt werden sollen.",
"UI_DEV_SECTIONS_name": "Geräteauswahl verstecken",
"UI_ICONS_description": "",
"UI_ICONS_name": "Vorgefertigte Icons",
"UI_LANG_description": "Bevorzugte Oberflächensprache auswählen. Du möchtest beim Übersetzen helfen? Gerne hier: <a href=\"https://hosted.weblate.org/projects/pialert/core/\" target=\"_blank\">Weblate</a>.",
"UI_LANG_name": "UI Sprache",
"UI_ICONS_name": "Vordefinierte Symbole",
"UI_LANG_description": "Bevorzugte Oberflächensprache auswählen. Du möchtest beim Übersetzen helfen? Gerne hier: <a href=\"https://hosted.weblate.org/projects/pialert/core/\" target=\"_blank\">Weblate</a>.",
"UI_LANG_name": "Sprache der Benutzeroberfläche",
"UI_MY_DEVICES_description": "",
"UI_MY_DEVICES_name": "In \"Meine Geräte\" anzeigen",
"UI_NOT_RANDOM_MAC_description": "",
"UI_NOT_RANDOM_MAC_name": "",
"UI_PRESENCE_description": "Auswählen, welche Status im <b>Gerätepräsenz im Laufe der Zeit</b>-Diagramm in der <a href=\"/devices.php\" target=\"_blank\">Geräte</a>-Seite angzeigt werden sollen. (<code>STRG + klicken</code> zum aus-/abwählen).",
"UI_NOT_RANDOM_MAC_name": "Nicht als zufällig markieren",
"UI_PRESENCE_description": "Auswählen, welche Status im <b>Gerätepräsenz im Laufe der Zeit</b>-Diagramm in der <a href=\"/devices.php\" target=\"_blank\">Geräte</a>-Seite angzeigt werden sollen.",
"UI_PRESENCE_name": "Anzeige im Präsenzdiagramm",
"UI_REFRESH_description": "",
"UI_REFRESH_name": "Automatisch Aktualisieren",
"UI_REFRESH_name": "Benutzeroberfläche automatisch auffrischen",
"VERSION_description": "",
"VERSION_name": "",
"VERSION_name": "Version oder Zeitstempel",
"WEBHOOK_PAYLOAD_description": "The Webhook payload data format for the <code>body</code> > <code>attachments</code> > <code>text</code> attribute in the payload json. See an example of the payload <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/front/report_templates/webhook_json_sample.json\">here</a>. (e.g.: for discord use <code>text</code>)",
"WEBHOOK_PAYLOAD_name": "Payload type",
"WEBHOOK_REQUEST_METHOD_description": "The HTTP request method to be used for the webhook call.",
@@ -748,13 +758,13 @@
"Webhooks_icon": "<i class=\"fa fa-circle-nodes\"></i>",
"devices_old": "Aktualisiert...",
"general_event_description": "Das Ereignis, das Sie ausgelöst haben, könnte eine Weile dauern, bis Hintergrundprozesse abgeschlossen sind. Die Ausführung endet, wenn die unten ausgeführte Warteschlangen abgearbeitet ist. (Siehe <a href='/maintenance.php#tab_Logging'>error log</a>, wenn Probleme auftreten.)<br/> <br/> Ausführungsschlange:",
"general_event_title": "Executing an ad-hoc event",
"general_event_title": "",
"report_guid": "",
"report_guid_missing": "",
"report_select_format": "Format auswählen:",
"report_time": "Benachrichtigungszeit:",
"run_event_icon": "fa-play",
"run_event_tooltip": "Enable the setting and save your changes at first before you run it.",
"run_event_icon": "",
"run_event_tooltip": "Aktiviere die Einstellung und speichere deine Änderungen, bevor du sie ausführst.",
"settings_core_icon": "",
"settings_core_label": "Kern",
"settings_device_scanners": "",
@@ -763,23 +773,23 @@
"settings_device_scanners_label": "Gerätescanner",
"settings_enabled": "Aktive Einstellungen",
"settings_enabled_icon": "",
"settings_expand_all": "Expand all",
"settings_expand_all": "Alles ausklappen",
"settings_imported": "Die letzten Einstellungen wurden aus der Datei app.conf importiert",
"settings_imported_label": "Einstellungen importiert",
"settings_missing": "",
"settings_missing_block": "",
"settings_old": "Importing settings and re-initializing...",
"settings_old": "",
"settings_other_scanners": "",
"settings_other_scanners_icon": "",
"settings_other_scanners_label": "Andere Scanner",
"settings_publishers": "",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "",
"settings_publishers_icon": "",
"settings_publishers_info": "Lade mehr Veröffentlicher mit den <a href=\"/settings.php#LOADED_PLUGINS\">geladene Plugins</a>-Einstellungen",
"settings_publishers_label": "Veröffentlicher",
"settings_saved": "",
"settings_saved": "<br/>Einstellungen gespeichert. <br/> Wird geladen... <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
"settings_system_icon": "",
"settings_system_label": "System",
"settings_update_item_warning": "",
"test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Save your changes at first before you test your settings."
"test_event_icon": "",
"test_event_tooltip": "Speichere die Änderungen, bevor Sie die Einstellungen testen."
}

View File

@@ -62,7 +62,7 @@
"DAYS_TO_KEEP_EVENTS_name": "Delete events older than",
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copy details from device",
"DevDetail_Copy_Device_Tooltip": "Copy details from device from the dropdown list. Everything on this page will be overwritten",
"DevDetail_EveandAl_AlertAllEvents": "Alert All Events",
"DevDetail_EveandAl_AlertAllEvents": "Alert Events",
"DevDetail_EveandAl_AlertDown": "Alert Down",
"DevDetail_EveandAl_Archived": "Archived",
"DevDetail_EveandAl_NewDevice": "New Device",
@@ -217,6 +217,7 @@
"Device_TableHead_RowID": "Row ID",
"Device_TableHead_Rowid": "Row ID",
"Device_TableHead_SSID": "SSID",
"Device_TableHead_SourcePlugin": "Source Plugin",
"Device_TableHead_Status": "Status",
"Device_TableHead_SyncHubNodeName": "Sync Node",
"Device_TableHead_Type": "Type",
@@ -284,6 +285,7 @@
"Gen_Description": "Description",
"Gen_Error": "Error",
"Gen_Filter": "Filter",
"Gen_Generate": "Generate",
"Gen_LockedDB": "ERROR - DB might be locked - Check F12 Dev tools -> Console or try later.",
"Gen_Offline": "Offline",
"Gen_Okay": "Ok",
@@ -309,6 +311,8 @@
"General_icon": "<i class=\"fa fa-gears\"></i>",
"HRS_TO_KEEP_NEWDEV_description": "This is a maintenance setting <b>DELETING devices</b>. If enabled (<code>0</code> is disabled), devices marked as <b>New Device</b> will be deleted if their <b>First Session</b> time was older than the specified hours in this setting. Use this setting if you want to auto-delete <b>New Devices</b> after <code>X</code> hours.",
"HRS_TO_KEEP_NEWDEV_name": "Delete new devices after",
"HRS_TO_KEEP_OFFDEV_description": "This is a maintenance setting <b>DELETING devices</b>. If enabled (<code>0</code> is disabled), devices that are <b>Offline</b> and their <b>Last Offline</b> date time is older than the specified hours in this setting. Use this setting if you want to auto-delete <b>Offline Devices</b> after <code>X</code> hours being offline.",
"HRS_TO_KEEP_OFFDEV_name": "Delete offline devices after",
"HelpFAQ_Cat_Detail": "Details",
"HelpFAQ_Cat_Detail_300_head": "What means ",
"HelpFAQ_Cat_Detail_300_text_a": "means a network device (a device of the type AP, Gateway, Firewall, Hypervisor, Powerline, Switch, WLAN, PLC, Router,USB LAN Adapter, USB WIFI Adapter, or Internet). Custom types can be added via the <code>NETWORK_DEVICE_TYPES</code> setting.",
@@ -545,6 +549,12 @@
"Presence_CalHead_week": "week",
"Presence_CalHead_year": "year",
"Presence_CallHead_Devices": "Devices",
"Presence_Key_OnlineNow": "Now online",
"Presence_Key_OnlineNow_desc": "Device detected in the last scan as online.",
"Presence_Key_OnlinePast": "Past online",
"Presence_Key_OnlinePastMiss": "Past online (miss-match)",
"Presence_Key_OnlinePastMiss_desc": "Device online in the past, but currently offline, but the start session might be missing or has conflicting data. (might be a bug - please submit a PR if you know how to fix it - I'm a bit lost in code here)",
"Presence_Key_OnlinePast_desc": "Device online in the past, but currently offline.",
"Presence_Loading": "Loading...",
"Presence_Shortcut_AllDevices": "My Devices",
"Presence_Shortcut_Archived": "Archived",

View File

@@ -227,6 +227,7 @@
"Device_TableHead_RowID": "Row ID",
"Device_TableHead_Rowid": "Row ID",
"Device_TableHead_SSID": "SSID",
"Device_TableHead_SourcePlugin": "Fuente del plugin",
"Device_TableHead_Status": "Situación",
"Device_TableHead_SyncHubNodeName": "Nodo de sincronización",
"Device_TableHead_Type": "Tipo",
@@ -291,9 +292,10 @@
"Gen_DataUpdatedUITakesTime": "Correcto - La interfaz puede tardar en actualizarse si se está ejecutando un escaneo.",
"Gen_Delete": "Eliminar",
"Gen_DeleteAll": "Eliminar todo",
"Gen_Description": "",
"Gen_Description": "Descripción",
"Gen_Error": "Error",
"Gen_Filter": "Filtro",
"Gen_Generate": "Generar",
"Gen_LockedDB": "Fallo - La base de datos puede estar bloqueada - Pulsa F1 -> Ajustes de desarrolladores -> Consola o prueba más tarde.",
"Gen_Offline": "Desconectado",
"Gen_Okay": "Aceptar",
@@ -319,6 +321,8 @@
"General_icon": "<i class=\"fa fa-gears\"></i>",
"HRS_TO_KEEP_NEWDEV_description": "Se trata de una configuración de mantenimiento <b>BORRAR dispositivos</b>. Si está activado (<code>0</code> está desactivado), los dispositivos marcados como <b>Nuevo dispositivo</b> se eliminarán si su fecha de <b>primera sesión</b> es anterior a las horas especificadas en este ajuste. Use este ajuste si desea eliminar automáticamente <b>Nuevos dispositivos</b> después de <code>X</code> horas.",
"HRS_TO_KEEP_NEWDEV_name": "Eliminar nuevos dispositivos después",
"HRS_TO_KEEP_OFFDEV_description": "Se trata de una configuración de mantenimiento <b>BORRAR dispositivos</b>. Si está activado (<code>0</code> está desactivado), los dispositivos que están <b>sin conexión</b> y su fecha de <b>última conexión</b> son anteriores a las horas especificadas en este ajuste. Use este ajuste si desea eliminar automáticamente <b>los dispositivos sin conexión</b> después de que el <code>X</code> horas esté sin conexión.",
"HRS_TO_KEEP_OFFDEV_name": "Borrar dispositivos sin conexión después de",
"HelpFAQ_Cat_Detail": "Detalles",
"HelpFAQ_Cat_Detail_300_head": "¿Qué significa? ",
"HelpFAQ_Cat_Detail_300_text_a": "significa un dispositivo de red (un dispositivo del tipo AP, Gateway, Firewall, Hypervisor, Powerline, Switch, WLAN, PLC, Router,Adaptador LAN USB, Adaptador WIFI USB o Internet). Los tipos personalizados pueden añadirse mediante el ajuste <code>NETWORK_DEVICE_TYPES</code>.",
@@ -584,6 +588,12 @@
"Presence_CalHead_week": "semana",
"Presence_CalHead_year": "año",
"Presence_CallHead_Devices": "Dispositivos",
"Presence_Key_OnlineNow": "En línea",
"Presence_Key_OnlineNow_desc": "Dispositivo detectado en el último escaneo como conectado.",
"Presence_Key_OnlinePast": "Anterior en línea",
"Presence_Key_OnlinePastMiss": "Anterior en línea (miss-match)",
"Presence_Key_OnlinePastMiss_desc": "Dispositivo en línea en el pasado, pero actualmente desconectado, pero la sesión de inicio podría estar faltando o tiene datos conflictivos. (Puede ser un error - por favor envíe un PR si sabe cómo solucionarlo - estoy un poco perdido en código)",
"Presence_Key_OnlinePast_desc": "Dispositivo en línea en el pasado, pero actualmente no conectado.",
"Presence_Loading": "Cargando...",
"Presence_Shortcut_AllDevices": "Mis dispositivos",
"Presence_Shortcut_Archived": "Archivado(s)",
@@ -635,7 +645,7 @@
"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.",
"Settings_Show_Description": "",
"Settings_Show_Description": "Mostrar descripción de la configuración.",
"Settings_Title": "<i class=\"fa fa-cog\"> Configuración</i>",
"Settings_device_Scanners_desync": "⚠ Los horarios del escáner de los dispositivos no están sincronizados.",
"Settings_device_Scanners_desync_popup": "Los horarios de escáneres de dispositivos (<code> *_RUN_SCHD</code> ) no son lo mismo. Esto resultará en notificaciones inconsistentes del dispositivo en línea/fuera de línea. A menos que sea así, utilice el mismo horario para todos los habilitados.<b> 🔍Escáneres de dispositivos</b> .",
@@ -723,11 +733,11 @@
"UI_ICONS_name": "Iconos predefinidos",
"UI_LANG_description": "Seleccione el idioma preferido para la interfaz de usuario. Ayude a traducir o sugiera idiomas en el portal en línea de <a href=\"https://hosted.weblate.org/projects/pialert/core/\" target=\"_blank\">Weblate</a>.",
"UI_LANG_name": "Idioma de interfaz",
"UI_MY_DEVICES_description": "Dispositivos cuyos estados deben mostrarse en la vista por defecto <b>Mis dispositivos</b>. (<code>CTRL + Click</code> para seleccionar/deseleccionar)",
"UI_MY_DEVICES_description": "Dispositivos cuyos estados deben mostrarse en la vista por defecto <b>Mis dispositivos</b>.",
"UI_MY_DEVICES_name": "Mostrar en Mis dispositivos",
"UI_NOT_RANDOM_MAC_description": "Prefijos Mac que no deberían marcarse como dispositivos aleatorios. Introduzca por ejemplo <code>52</code> para excluir los dispositivos que empiecen por <code>52:xx:xx:xx:xx</code> para ser marcados como dispositivos con una dirección MAC aleatoria.",
"UI_NOT_RANDOM_MAC_name": "No marcar como aleatoria",
"UI_PRESENCE_description": "Elige que estados del dispositivo deben mostrarse en la gráfica de <b>Presencia del dispositivo a lo largo del tiempo</b> de la página de <a href=\"/devices.php\" target=\"_blank\">Dispositivos</a>. (<code>CTRL + Clic</code> para seleccionar / deseleccionar)",
"UI_PRESENCE_description": "Elige que estados del dispositivo deben mostrarse en la gráfica de <b>Presencia del dispositivo a lo largo del tiempo</b> de la página de <a href=\"/devices.php\" target=\"_blank\">Dispositivos</a>.",
"UI_PRESENCE_name": "Mostrar en el gráfico de presencia",
"UI_REFRESH_description": "Ingrese el número de segundos después de los cuales se recarga la interfaz de usuario. Ajustado a <code> 0 </code> para desactivar.",
"UI_REFRESH_name": "Actualización automática de la interfaz de usuario",

View File

@@ -56,13 +56,13 @@
"BackDevices_Restore_okay": "Restauration exécutée avec succès.",
"BackDevices_darkmode_disabled": "Mode sombre désactivé",
"BackDevices_darkmode_enabled": "Mode sombre activé",
"CLEAR_NEW_FLAG_description": "Si activé (<code>0</code> est activé), les appareils marqués comme <b>Nouvel appareil</b> seront démarqués si la durée limite (spécifiée en heures) dépasse la durée de la <b>Première Session</b>.",
"CLEAR_NEW_FLAG_description": "Si activé (<code>0</code> est désactivé), les appareils marqués comme <b>Nouvel appareil</b> seront démarqués si la limite de temps (spécifiée en heures) dépasse la durée de <b>Première Session</b>.",
"CLEAR_NEW_FLAG_name": "Supprime le nouveau drapeau",
"DAYS_TO_KEEP_EVENTS_description": "Il s'agit d'un paramètre de maintenance. Il indique le nombre de jours pendant lesquels les entrées d'événements seront conservées. Tous les événements plus anciens seront supprimés périodiquement. S'applique également à l'historique des événements du plugin.",
"DAYS_TO_KEEP_EVENTS_name": "Supprimer les événements plus anciens que",
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copier les détails de l'appareil",
"DevDetail_Copy_Device_Tooltip": "Copier les détails de l'appareil dans la liste déroulante. Tout ce qui se trouve sur cette page sera remplacé",
"DevDetail_EveandAl_AlertAllEvents": "Alerter de tous les événements",
"DevDetail_EveandAl_AlertAllEvents": "Alerter les événements",
"DevDetail_EveandAl_AlertDown": "Alerte de panne",
"DevDetail_EveandAl_Archived": "Archivés",
"DevDetail_EveandAl_NewDevice": "Nouvel appareil",
@@ -76,7 +76,7 @@
"DevDetail_Events_CheckBox": "Masquer les événements de connexion",
"DevDetail_GoToNetworkNode": "Naviguer à la page Réseau pour le nœud sélectionné.",
"DevDetail_Icon": "Icône",
"DevDetail_Icon_Descr": "Renseigner le nom d'une icône Font Awesome sans le préfixe fa- ou la classe complète; par ex. fa fa-brands fa-apple.",
"DevDetail_Icon_Descr": "Renseigner le nom d'une icône Font Awesome sans le préfixe fa- ou la classe complète, par ex. fa fa-brands fa-apple.",
"DevDetail_Loading": "Chargement…",
"DevDetail_MainInfo_Comments": "Observations",
"DevDetail_MainInfo_Favorite": "Favori",
@@ -95,7 +95,7 @@
"DevDetail_MainInfo_mac": "MAC",
"DevDetail_Network_Node_hover": "Sélectionner l'appareil du réseau principal auquel cet appareil est connecté afin de compléter l'arborescence du Réseau.",
"DevDetail_Network_Port_hover": "Le port auquel cet appareil est connecté sur l'appareil du réseau principal. Si vide, une icône Wifi est affichée dans l'arborescence du Réseau.",
"DevDetail_Nmap_Scans": "Scans NMAP manuels",
"DevDetail_Nmap_Scans": "Scans manuels via Nmap",
"DevDetail_Nmap_Scans_desc": "Vous pouvez lancer des scans NMAP manuels. Vous pouvez aussi programmer des sans réguliers via le plugin Services & Ports (NMAP). Aller dans les <a href='/settings.php' target='_blank'>Paramètres</a> pour plus de details",
"DevDetail_Nmap_buttonDefault": "Scan par défaut",
"DevDetail_Nmap_buttonDefault_text": "Scan par défaut : NMAP scanne les 1 000 premiers ports pour chaque demande de scan de protocole. Cela couvre environ 93% des ports TCP et 49% des ports UDP (environ 5 secondes)",
@@ -217,6 +217,7 @@
"Device_TableHead_RowID": "ID de colonne",
"Device_TableHead_Rowid": "ID de colonne",
"Device_TableHead_SSID": "SSID",
"Device_TableHead_SourcePlugin": "Source du plugin",
"Device_TableHead_Status": "État",
"Device_TableHead_SyncHubNodeName": "Noeud de synchro",
"Device_TableHead_Type": "Type",
@@ -281,9 +282,10 @@
"Gen_DataUpdatedUITakesTime": "OK - cela peut prendre du temps à l'interface pour se mettre à jour si un scan est en cours.",
"Gen_Delete": "Supprimer",
"Gen_DeleteAll": "Supprimer tous",
"Gen_Description": "",
"Gen_Description": "Description",
"Gen_Error": "Erreur",
"Gen_Filter": "Filtrer",
"Gen_Generate": "Générer",
"Gen_LockedDB": "Erreur - La base de données est peut-être verrouillée - Vérifier avec les outils de dév via F12 -> Console ou essayer plus tard.",
"Gen_Offline": "Hors ligne",
"Gen_Okay": "OK",
@@ -307,8 +309,10 @@
"Gen_Work_In_Progress": "Travaux en cours, c'est le bon moment pour faire un retour via la liste d'anomalies sur Github https://github.com/jokob-sk/NetAlertX/issues",
"General_display_name": "Général",
"General_icon": "<i class=\"fa fa-gears\"></i>",
"HRS_TO_KEEP_NEWDEV_description": "Paramétrage de maintenance. S'il est activé (<code>0</code> s'il est désactivé), les appareils marqués comme <b>Nouvel appareil</b> seront supprimés si leur durée depuis la <b>première session</b> est plus ancienne que le nombre d'heures paramétré. Utilisez ce paramétrage si vous voulez supprimer automatiquement les <b>Nouveaux appareils</b> après <code>X</code> heures.",
"HRS_TO_KEEP_NEWDEV_description": "Paramètre de maintenance. S'il est activé (<code>0</code> s'il est désactivé), les appareils marqués comme <b>Nouvel appareil</b> seront supprimés si leur durée depuis la <b>première session</b> est plus ancienne que le nombre d'heures paramétré. Utilisez ce paramétrage si vous voulez supprimer automatiquement les <b>Nouveaux appareils</b> après <code>X</code> heures.",
"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 <b>SUPPRIMER des appareils</b>. Si cette option est activée (<code>0</code> est désactivé), les appareils qui sont <b>Hors ligne</b> et dont la <b>dernière heure hors ligne</b> est plus ancienne que les heures spécifiées dans ce paramètre. Utilisez ce paramètre si vous souhaitez supprimer automatiquement <b>Appareils hors ligne</b> après <code>X</code> heures de déconnexion.",
"HRS_TO_KEEP_OFFDEV_name": "Supprimez les appareils hors ligne après",
"HelpFAQ_Cat_Detail": "Détails",
"HelpFAQ_Cat_Detail_300_head": "Que signifie ",
"HelpFAQ_Cat_Detail_300_text_a": "signifie que cela représente un équipement réseau (Access Point, Gateway, Firewall, Hyperviseur, Powerline, Switch, WLAN, CPL, adaptateur Ethernet USB, adaptateur Wifi USB, Internet). Les types d'appareils personnalisés peuvent être ajoutés via le paramètre <code>NETWORK_DEVICE_TYPES</code>.",
@@ -545,6 +549,12 @@
"Presence_CalHead_week": "semaine",
"Presence_CalHead_year": "année",
"Presence_CallHead_Devices": "Appareils",
"Presence_Key_OnlineNow": "Maintenant en ligne",
"Presence_Key_OnlineNow_desc": "Appareil détecté comme étant en ligne lors de la dernière analyse.",
"Presence_Key_OnlinePast": "Passé en ligne",
"Presence_Key_OnlinePastMiss": "Passé en ligne (correspondance manquée)",
"Presence_Key_OnlinePastMiss_desc": "Appareil en ligne dans le passé, mais actuellement hors ligne, mais la session de démarrage pourrait être manquante ou avoir des données contradictoires. (il s'agit peut-être d'un bogue - veuillez soumettre un PR si vous savez comment le corriger - je suis un peu perdu dans le code ici)",
"Presence_Key_OnlinePast_desc": "Appareil en ligne dans le passé, mais actuellement hors ligne.",
"Presence_Loading": "Chargement …",
"Presence_Shortcut_AllDevices": "Mes appareils",
"Presence_Shortcut_Archived": "Archivés",
@@ -568,7 +578,7 @@
"Setting_Override": "Remplacer la valeur",
"Setting_Override_Description": "Activer cette option va remplacer la valeur fournie par défaut par une application par la valeur renseignée au-dessus.",
"Settings_Metadata_Toggle": "Afficher/masquer les méta données pour le paramètre sélectionné.",
"Settings_Show_Description": "",
"Settings_Show_Description": "Montrer la description de la configuration.",
"Settings_device_Scanners_desync": "⚠ La planification des différents scanners d'appareils est désynchronisée.",
"Settings_device_Scanners_desync_popup": "La planification des scanners (<code>*_RUN_SCHD</code>) n'est pas identique entre scanners. Cela va entraîner des notifications en ligne/hors-ligne non cohérentes. À moins que cela soit attendu, utilisez la même planification pour tous les <b>🔍scanners d'appareils</b> activés.",
"Speedtest_Results": "Résultats du test de débit",
@@ -655,11 +665,11 @@
"UI_ICONS_name": "Icones prédéfinies",
"UI_LANG_description": "Sélectionnez votre langue préféré de linterface. Aidez à traduire ou suggérez des langues dans le portail en ligne de <a href=\"https://hosted.weblate.org/projects/pialert/core/\" target=\"_blank\">Weblate</a>.",
"UI_LANG_name": "Langue de l'interface graphique",
"UI_MY_DEVICES_description": "Les états autorisant les appareils à être affichés par défaut dans la vue <b>Mes appareils</b>. (<code>CTRL + Clic</code> pour sélectionner/desélectionner",
"UI_MY_DEVICES_description": "Les états autorisant les appareils à être affichés par défaut dans la vue <b>Mes appareils</b>.",
"UI_MY_DEVICES_name": "Afficher dans la vue de mes appareils",
"UI_NOT_RANDOM_MAC_description": "Les préfixes d'adresses MAC à ne pas considérer comme généré aléatoirement pour les appareils. Renseignez par exemple <code>52</code> pour que les appareils commençant par <code>52:xx:xx:xx:xx:xx</code> ne soient pas considérés comme disposant d'une adresse MAC aléatoire.",
"UI_NOT_RANDOM_MAC_name": "Ne pas marquer comme aléatoire",
"UI_PRESENCE_description": "Sélectionner les états qui doivent être affichés dans le graphique de <b>Présence des appareils</b> de la page <a href=\"/devices.php\" target=\"_blank\">Appareils</a>. (<code>CTRL + Clic</code> pour sélectionner/désélectionner)",
"UI_PRESENCE_description": "Sélectionner les états qui doivent être affichés dans le graphique de <b>Présence des appareils</b> de la page <a href=\"/devices.php\" target=\"_blank\">Appareils</a>.",
"UI_PRESENCE_name": "Afficher dans le graphique de présence",
"UI_REFRESH_description": "Renseignez le nombre de secondes après lequel rafraîchir l'interface graphique. Renseignez <code>0</code> pour désactiver.",
"UI_REFRESH_name": "Rafraîchir automatiquement l'interface graphique",

18
front/php/templates/language/it_it.json Normal file → Executable file
View File

@@ -62,7 +62,7 @@
"DAYS_TO_KEEP_EVENTS_name": "Elimina eventi più vecchi di",
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copia dettagli dal dispositivo",
"DevDetail_Copy_Device_Tooltip": "Copia i dettagli dal dispositivo dall'elenco a discesa. Tutto in questa pagina verrà sovrascritto",
"DevDetail_EveandAl_AlertAllEvents": "Notifica tutti gli eventi",
"DevDetail_EveandAl_AlertAllEvents": "Notifica eventi",
"DevDetail_EveandAl_AlertDown": "Avviso disconnessione",
"DevDetail_EveandAl_Archived": "Archiviato",
"DevDetail_EveandAl_NewDevice": "Nuovo dispositivo",
@@ -217,6 +217,7 @@
"Device_TableHead_RowID": "ID riga",
"Device_TableHead_Rowid": "ID riga",
"Device_TableHead_SSID": "SSID",
"Device_TableHead_SourcePlugin": "Plugin sorgente",
"Device_TableHead_Status": "Stato",
"Device_TableHead_SyncHubNodeName": "Sincronizza nodo",
"Device_TableHead_Type": "Tipo",
@@ -284,6 +285,7 @@
"Gen_Description": "Descrizione",
"Gen_Error": "Errore",
"Gen_Filter": "Filtro",
"Gen_Generate": "Genera",
"Gen_LockedDB": "ERRORE: il DB potrebbe essere bloccato, controlla F12 Strumenti di sviluppo -> Console o riprova più tardi.",
"Gen_Offline": "Offline",
"Gen_Okay": "Ok",
@@ -309,6 +311,8 @@
"General_icon": "<i class=\"fa fa-gears\"></i>",
"HRS_TO_KEEP_NEWDEV_description": "Questa è un'impostazione di manutenzione <b>ELIMINAZIONE dispositivi</b>. Se abilitata (<code>0</code> è disabilitata), tutti i dispositivi marcati con <b>Nuovo dispositivo</b> verranno eliminati se l'orario della <b>Prima sessione</b> è precedente all'orario di questa impostazione. Usa questa impostazione se vuoi eliminare automaticamente i <b>Nuovi dispositivi</b> dopo <code>X</code> ore.",
"HRS_TO_KEEP_NEWDEV_name": "Elimina nuovi dispositivi dopo",
"HRS_TO_KEEP_OFFDEV_description": "Questa è un'impostazione di manutenzione <b>ELIMINAZIONE dispositivi</b>. Se abilitata (<code>0</code> è disabilitata), i dispositivi che sono <b>Offline</b> e la loro data e ora <b>Ultima offline</b> sono più vecchi delle ore specificate in questa impostazione. Usa questa impostazione se vuoi eliminare automaticamente <b>Dispositivi offline</b> dopo <code>X</code> ore trascorse offline.",
"HRS_TO_KEEP_OFFDEV_name": "Elimina dispositivi offline dopo",
"HelpFAQ_Cat_Detail": "Dettagli",
"HelpFAQ_Cat_Detail_300_head": "Cosa significa ",
"HelpFAQ_Cat_Detail_300_text_a": "indica un dispositivo di rete (un dispositivo di tipo AP, Gateway, Firewall, Hypervisor, Powerline, Switch, WLAN, PLC, Router, USB LAN Adapter, USB WIFI Adapter, o Internet). Tipi personalizzati possono essere aggiunti attraverso l'impostazione <code>NETWORK_DEVICE_TYPES</code>.",
@@ -545,6 +549,12 @@
"Presence_CalHead_week": "settimana",
"Presence_CalHead_year": "anno",
"Presence_CallHead_Devices": "Dispositivi",
"Presence_Key_OnlineNow": "Online adesso",
"Presence_Key_OnlineNow_desc": "Dispositivo rilevato durante l'ultima scansione come online.",
"Presence_Key_OnlinePast": "Online in passato",
"Presence_Key_OnlinePastMiss": "Online in passato (non corrispondente)",
"Presence_Key_OnlinePastMiss_desc": "Dispositivo online in passato, ma attualmente offline, ma la sessione di avvio potrebbe essere mancante o presentare dati in conflitto. (potrebbe trattarsi di un bug: invia una PR se sai come risolverlo, sono un po' perso nel codice qui)",
"Presence_Key_OnlinePast_desc": "Dispositivo online in passato, ma attualmente offline.",
"Presence_Loading": "Caricamento...",
"Presence_Shortcut_AllDevices": "Miei dispositivi",
"Presence_Shortcut_Archived": "Archiviati",
@@ -655,11 +665,11 @@
"UI_ICONS_name": "Icone predefinite",
"UI_LANG_description": "Seleziona la lingua preferita dell'interfaccia utente. Aiuta nella traduzione o suggerisci una nuova lingua sul portale online di <a href=\"https://hosted.weblate.org/projects/pialert/core/\" target=\"_blank\">Weblate</a>.",
"UI_LANG_name": "Lingua UI",
"UI_MY_DEVICES_description": "Dispositivi i cui stati devono essere visualizzati nella visualizzazione predefinita <b>Miei dispositivi</b>. (<code>CTRL + clic</code> per selezionare/deselezionare)",
"UI_MY_DEVICES_description": "Dispositivi i cui stati devono essere visualizzati nella visualizzazione predefinita <b>Miei dispositivi</b>.",
"UI_MY_DEVICES_name": "Mostra nella vista Miei dispositivi",
"UI_NOT_RANDOM_MAC_description": "Prefissi MAC che non devono essere contrassegnati come dispositivi casuali. Inserisci ad esempio <code>52</code> per escludere i dispositivi che iniziano con <code>52:xx:xx:xx:xx:xx</code> dall'essere contrassegnati come dispositivi con un indirizzo MAC casuale.",
"UI_NOT_RANDOM_MAC_name": "Non segnalare come casuale",
"UI_PRESENCE_description": "Seleziona quali stati devono essere mostrati nel grafico <b>Presenza dispositivo</b> nella pagina <a href=\"/devices.php\" target=\"_blank\">Dispositivi</a>. (<code>CTRL + clic</code> per selezionare/deselezionare)",
"UI_PRESENCE_description": "Seleziona quali stati devono essere mostrati nel grafico <b>Presenza dispositivo</b> nella pagina <a href=\"/devices.php\" target=\"_blank\">Dispositivi</a>.",
"UI_PRESENCE_name": "Mostra nel grafico delle presenze",
"UI_REFRESH_description": "Inserisci il numero di secondi dopo il quale la UI si ricarica. Imposta a <code>0</code> per disabilitare.",
"UI_REFRESH_name": "Aggiorna automaticamente la UI",
@@ -701,4 +711,4 @@
"settings_update_item_warning": "Aggiorna il valore qui sotto. Fai attenzione a seguire il formato precedente. <b>La convalida non viene eseguita.</b>",
"test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni."
}
}

View File

@@ -217,6 +217,7 @@
"Device_TableHead_RowID": "Rad ID",
"Device_TableHead_Rowid": "Rad ID",
"Device_TableHead_SSID": "",
"Device_TableHead_SourcePlugin": "",
"Device_TableHead_Status": "Status",
"Device_TableHead_SyncHubNodeName": "Synkroniser Node",
"Device_TableHead_Type": "Type",
@@ -284,6 +285,7 @@
"Gen_Description": "",
"Gen_Error": "Feil",
"Gen_Filter": "Filter",
"Gen_Generate": "",
"Gen_LockedDB": "FEIL - DB kan være låst - Sjekk F12 Dev tools -> Konsoll eller prøv senere.",
"Gen_Offline": "Frakoblet",
"Gen_Okay": "Ok",
@@ -309,6 +311,8 @@
"General_icon": "<i class=\"fa fa-gears\"></i>",
"HRS_TO_KEEP_NEWDEV_description": "Dette er en vedlikeholdsinnstilling. Hvis aktivert (<code>0</code> er deaktivert), vil enheter merket som <b>Ny Enhet</b> bli slettet hvis tiden deres for <b>Første økt</b> var eldre enn de angitte timene i denne innstilling. Bruk denne innstillingen hvis du vil automatisk slette <b>Nye Enheter</b> etter <code>X</code> timer.",
"HRS_TO_KEEP_NEWDEV_name": "Behold nye enheter for",
"HRS_TO_KEEP_OFFDEV_description": "",
"HRS_TO_KEEP_OFFDEV_name": "",
"HelpFAQ_Cat_Detail": "Detaljer",
"HelpFAQ_Cat_Detail_300_head": "Hva betyr ",
"HelpFAQ_Cat_Detail_300_text_a": "betyr en nettverksenhet (en enhet av typen AP, Gateway, Brannmur, Hypervisor, Powerline, Switch, WLAN, PLS, ruter, USB LAN-adapter, USB WIFI-adapter eller Internett). Egendefinerte typer kan legges til via <code>NETWORK_DEVICE_TYPES</code>-innstillingen.",
@@ -545,6 +549,12 @@
"Presence_CalHead_week": "uke",
"Presence_CalHead_year": "år",
"Presence_CallHead_Devices": "Enheter",
"Presence_Key_OnlineNow": "",
"Presence_Key_OnlineNow_desc": "",
"Presence_Key_OnlinePast": "",
"Presence_Key_OnlinePastMiss": "",
"Presence_Key_OnlinePastMiss_desc": "",
"Presence_Key_OnlinePast_desc": "",
"Presence_Loading": "Laster...",
"Presence_Shortcut_AllDevices": "Mine enheter",
"Presence_Shortcut_Archived": "Arkivert",

View File

@@ -217,6 +217,7 @@
"Device_TableHead_RowID": "ID wiersza",
"Device_TableHead_Rowid": "ID wiersza",
"Device_TableHead_SSID": "SSID",
"Device_TableHead_SourcePlugin": "",
"Device_TableHead_Status": "Status",
"Device_TableHead_SyncHubNodeName": "Węzeł Synchronizacji",
"Device_TableHead_Type": "Typ",
@@ -284,6 +285,7 @@
"Gen_Description": "",
"Gen_Error": "Błąd",
"Gen_Filter": "Filtr",
"Gen_Generate": "",
"Gen_LockedDB": "BŁĄD - BAZA DANYCH może być zablokowana - Sprawdź F12 narzędzia dewelopera -> Konsola lub spróbuj ponownie później.",
"Gen_Offline": "Wyłączone",
"Gen_Okay": "Ok",
@@ -309,6 +311,8 @@
"General_icon": "<i class=\"fa fa-gears\"></i>",
"HRS_TO_KEEP_NEWDEV_description": "To jest ustawienie konserwacyjne. Jeżeli uruchomione (<code>0</code> jest wyłączone), urządzenie oznaczone jako <b>Nowe Urządzenie</b> zostanie usunięte jeżeli czas <b>Pierwszej Sesji</b> jest starszy niż godzina podana w tym ustawieniu. Uzyj tego ustawienia jeżeli chcesz automatycznie usuwać <b>Nowe Urządzenia</b> po <code>X</code> godzinach.",
"HRS_TO_KEEP_NEWDEV_name": "Trzymaj nowe urządzenia przez",
"HRS_TO_KEEP_OFFDEV_description": "",
"HRS_TO_KEEP_OFFDEV_name": "",
"HelpFAQ_Cat_Detail": "Szczegóły",
"HelpFAQ_Cat_Detail_300_head": "Co oznacza ",
"HelpFAQ_Cat_Detail_300_text_a": "oznacza urządzenie sieciowe (urządzenie typu AP, Gateway, Zapora sieciowa, Hypervisor, Powerline, Switch, WLAN, PLC, Ruter, Adapter USB LAN, Adapter USB WIFI, oraz Internet). Własny typ może zostać dodany poprzez ustawienie <code>NETWORK_DEVICE_TYPE</code>.",
@@ -545,6 +549,12 @@
"Presence_CalHead_week": "tydzień",
"Presence_CalHead_year": "rok",
"Presence_CallHead_Devices": "Urządzenia",
"Presence_Key_OnlineNow": "",
"Presence_Key_OnlineNow_desc": "",
"Presence_Key_OnlinePast": "",
"Presence_Key_OnlinePastMiss": "",
"Presence_Key_OnlinePastMiss_desc": "",
"Presence_Key_OnlinePast_desc": "",
"Presence_Loading": "Wczytywanie...",
"Presence_Shortcut_AllDevices": "Moje Urządzenia",
"Presence_Shortcut_Archived": "Zarchiwizowane",

View File

@@ -217,6 +217,7 @@
"Device_TableHead_RowID": "ID da linha",
"Device_TableHead_Rowid": "ID da linha",
"Device_TableHead_SSID": "SSID",
"Device_TableHead_SourcePlugin": "",
"Device_TableHead_Status": "Status",
"Device_TableHead_SyncHubNodeName": "Nó de sincronização",
"Device_TableHead_Type": "Tipo",
@@ -284,6 +285,7 @@
"Gen_Description": "",
"Gen_Error": "Erro",
"Gen_Filter": "Filtro",
"Gen_Generate": "",
"Gen_LockedDB": "ERRO - O banco de dados pode estar bloqueado - Verifique F12 Ferramentas de desenvolvimento -> Console ou tente mais tarde.",
"Gen_Offline": "Offline",
"Gen_Okay": "Ok",
@@ -309,6 +311,8 @@
"General_icon": "<i class=\"fa fa-gears\"></i>",
"HRS_TO_KEEP_NEWDEV_description": "Esta é uma configuração de manutenção. Se habilitada (<code>0</code> is disabled), dispositivos marcados como <b>Novo Dispositivo</b> serão excluídos se o tempo de <b>Primeira Sessão</b> for mais antigo que as horas especificadas nesta configuração. Use esta configuração se quiser excluir automaticamente <b>Novos Dispositivos</b> após <code>X</code> horas.",
"HRS_TO_KEEP_NEWDEV_name": "Manter novos dispositivos por",
"HRS_TO_KEEP_OFFDEV_description": "",
"HRS_TO_KEEP_OFFDEV_name": "",
"HelpFAQ_Cat_Detail": "Detalhes",
"HelpFAQ_Cat_Detail_300_head": "O que significa ",
"HelpFAQ_Cat_Detail_300_text_a": "Significa um dispositivo de rede (um dispositivo do tipo AP, Gateway, Firewall, Hypervisor, Powerline, Switch, WLAN, PLC, Roteador, Adaptador LAN USB, Adaptador Wi-Fi USB ou Internet). Tipos personalizados podem ser adicionados através da configuração <code>NETWORK_DEVICE_TYPES</code>.",
@@ -545,6 +549,12 @@
"Presence_CalHead_week": "",
"Presence_CalHead_year": "",
"Presence_CallHead_Devices": "",
"Presence_Key_OnlineNow": "",
"Presence_Key_OnlineNow_desc": "",
"Presence_Key_OnlinePast": "",
"Presence_Key_OnlinePastMiss": "",
"Presence_Key_OnlinePastMiss_desc": "",
"Presence_Key_OnlinePast_desc": "",
"Presence_Loading": "",
"Presence_Shortcut_AllDevices": "",
"Presence_Shortcut_Archived": "",

View File

@@ -71,7 +71,7 @@
"DevDetail_EveandAl_ScanCycle": "Сканировать устройство",
"DevDetail_EveandAl_ScanCycle_a": "Сканировать Устройство",
"DevDetail_EveandAl_ScanCycle_z": "Не сканировать устройство",
"DevDetail_EveandAl_Skip": "Пропустить повторные уведомления для",
"DevDetail_EveandAl_Skip": "Пропустить повторные уведомления",
"DevDetail_EveandAl_Title": "<i class=\"fa fa-bolt\"></i> Конфигурация событий и оповещений",
"DevDetail_Events_CheckBox": "Скрыть события подключения",
"DevDetail_GoToNetworkNode": "Перейти на страницу Сеть данного узла.",
@@ -116,7 +116,7 @@
"DevDetail_Run_Actions_Tooltip": "Выполнить действие на текущем устройстве из раскрывающегося списка.",
"DevDetail_SessionInfo_FirstSession": "Первый сеанс",
"DevDetail_SessionInfo_LastIP": "Последний IP",
"DevDetail_SessionInfo_LastSession": "Последние в оффлайн",
"DevDetail_SessionInfo_LastSession": "Последний оффлайн",
"DevDetail_SessionInfo_StaticIP": "Статический IP",
"DevDetail_SessionInfo_Status": "Статус",
"DevDetail_SessionInfo_Title": "<i class=\"fa fa-calendar\"></i> Информация о сеансе",
@@ -196,7 +196,7 @@
"Device_Shortcut_DownOnly": "Выключены",
"Device_Shortcut_Favorites": "Избранные",
"Device_Shortcut_NewDevices": "Новые устройства",
"Device_Shortcut_OnlineChart": "Присутствие устройства",
"Device_Shortcut_OnlineChart": "Присутствие устройств",
"Device_TableHead_Connected_Devices": "Соединения",
"Device_TableHead_Favorite": "Избранное",
"Device_TableHead_FirstSession": "Первый сеанс",
@@ -210,13 +210,14 @@
"Device_TableHead_MAC": "Случайный MAC-адрес",
"Device_TableHead_MAC_full": "Полный MAC-адрес",
"Device_TableHead_Name": "Имя",
"Device_TableHead_NetworkSite": "Сайт сети",
"Device_TableHead_NetworkSite": "Сайт устройства",
"Device_TableHead_Owner": "Владелец",
"Device_TableHead_Parent_MAC": "MAC род. узла",
"Device_TableHead_Port": "Порт",
"Device_TableHead_RowID": "ID строки",
"Device_TableHead_Rowid": "ID строки",
"Device_TableHead_SSID": "SSID",
"Device_TableHead_SourcePlugin": "",
"Device_TableHead_Status": "Статус",
"Device_TableHead_SyncHubNodeName": "Узел синхронизации",
"Device_TableHead_Type": "Тип",
@@ -281,9 +282,10 @@
"Gen_DataUpdatedUITakesTime": "ОК - Обновление UI может занять некоторое время, если сканирование выполняется.",
"Gen_Delete": "Удалить",
"Gen_DeleteAll": "Удалить все",
"Gen_Description": "",
"Gen_Description": "Описание",
"Gen_Error": "Ошибка",
"Gen_Filter": "Фильтр",
"Gen_Generate": "",
"Gen_LockedDB": "ОШИБКА - Возможно, база данных заблокирована. Проверьте инструменты разработчика F12 -> Консоль или повторите попытку позже.",
"Gen_Offline": "Оффлайн",
"Gen_Okay": "OK",
@@ -309,6 +311,8 @@
"General_icon": "<i class=\"fa fa-gears\"></i>",
"HRS_TO_KEEP_NEWDEV_description": "Это настройка обслуживания <b>УДАЛЕНИЕ устройств</b>. Если этот параметр включен (<code>0</code> отключен), устройства, помеченные как <b>Новое устройство</b>, будут удалены, если время их <b>Первого сеанса</b> было старше указанных в этой настройке часов. Используйте этот параметр, если вы хотите автоматически удалять <b>Новые устройства</b> через <code>X</code> часов.",
"HRS_TO_KEEP_NEWDEV_name": "Удалить новые устройства после",
"HRS_TO_KEEP_OFFDEV_description": "",
"HRS_TO_KEEP_OFFDEV_name": "",
"HelpFAQ_Cat_Detail": "Подробности",
"HelpFAQ_Cat_Detail_300_head": "Что значит ",
"HelpFAQ_Cat_Detail_300_text_a": "означает сетевое устройство (типа AP, шлюз, межсетевой экран, гипервизор, Powerline, коммутатор, WLAN, PLC, маршрутизатор, USB-адаптер локальной сети, USB-адаптер Wi-Fi или Интернет). Пользовательские типы можно добавить с помощью параметра <code>NETWORK_DEVICE_TYPES</code>.",
@@ -364,7 +368,7 @@
"Login_Toggle_Alert_headline": "Предупреждение о пароле!",
"Login_Toggle_Info": "Информация о пароле",
"Login_Toggle_Info_headline": "Информация о пароле",
"Maint_PurgeLog": "Журнал очистки",
"Maint_PurgeLog": "Очистить журнал",
"Maint_RestartServer": "Перезапустить сервер",
"Maint_Restart_Server_noti_text": "Вы уверены, что хотите перезапустить внутренний сервер? Это может привести к несогласованности работы приложения. Сначала создайте резервную копию настроек. <br/> <br/> Примечание: Это может занять несколько минут.",
"Maintenance_Running_Version": "Установленная версия",
@@ -402,7 +406,7 @@
"Maintenance_Tool_del_alldev_noti": "Удалить устройства",
"Maintenance_Tool_del_alldev_noti_text": "Вы уверены, что хотите удалить все устройства?",
"Maintenance_Tool_del_alldev_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Все устройства будут удалены из базы данных.",
"Maintenance_Tool_del_allevents": "Удалить события (Сбросить присутствие)",
"Maintenance_Tool_del_allevents": "Удалить события (Сброс присутствия)",
"Maintenance_Tool_del_allevents30": "Удалить все события старше 30 дней",
"Maintenance_Tool_del_allevents30_noti": "Удалить события",
"Maintenance_Tool_del_allevents30_noti_text": "Вы уверены, что хотите удалить все события старше 30 дней? Это сбрасывает состояние присутствия всех устройств.",
@@ -410,13 +414,13 @@
"Maintenance_Tool_del_allevents_noti": "Удалить события",
"Maintenance_Tool_del_allevents_noti_text": "Вы уверены, что хотите удалить все события? Это сбрасывает состояние присутствия всех устройств.",
"Maintenance_Tool_del_allevents_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Все события в базе данных будут удалены. В этот момент присутствие всех устройств будет сброшено. Это может привести к недействительным сеансам. Это означает, что устройства отображаются как «присутствующие», хотя они находятся в автономном режиме. Сканирование, когда рассматриваемое устройство находится в сети, решает проблему.",
"Maintenance_Tool_del_empty_macs": "Удалить устройства с пустыми MAC-адресами",
"Maintenance_Tool_del_empty_macs": "Удалить устройства с пустыми MAC",
"Maintenance_Tool_del_empty_macs_noti": "Удалить устройства",
"Maintenance_Tool_del_empty_macs_noti_text": "Вы уверены, что хотите удалить все устройства с пустыми MAC-адресами?<br>(возможно, вы предпочитаете заархивировать их)",
"Maintenance_Tool_del_empty_macs_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Все устройства без MAC-адресов будут удалены из базы данных.",
"Maintenance_Tool_del_selecteddev": "Удалить выбранные устройства",
"Maintenance_Tool_del_selecteddev_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Выбранные устройства будут удалены из базы данных.",
"Maintenance_Tool_del_unknowndev": "Удалить (неизвестные) устройства",
"Maintenance_Tool_del_unknowndev": "Удалить неизвестные устройства",
"Maintenance_Tool_del_unknowndev_noti": "Удалить (неизвестные) устройства",
"Maintenance_Tool_del_unknowndev_noti_text": "Вы уверены, что хотите удалить все (неизвестные) и (имя не найдено) устройства?",
"Maintenance_Tool_del_unknowndev_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Все названные устройства (неизвестные) будут удалены из базы данных.",
@@ -475,7 +479,7 @@
"Navigation_Notifications": "Уведомления",
"Navigation_Plugins": "Плагины",
"Navigation_Presence": "Присутствие",
"Navigation_Report": "Отправить отчеты",
"Navigation_Report": "Отчеты",
"Navigation_Settings": "Настройки",
"Navigation_SystemInfo": "О системе",
"Navigation_Workflows": "Рабочие процессы",
@@ -545,6 +549,12 @@
"Presence_CalHead_week": "неделя",
"Presence_CalHead_year": "год",
"Presence_CallHead_Devices": "Устройства",
"Presence_Key_OnlineNow": "",
"Presence_Key_OnlineNow_desc": "",
"Presence_Key_OnlinePast": "",
"Presence_Key_OnlinePastMiss": "",
"Presence_Key_OnlinePastMiss_desc": "",
"Presence_Key_OnlinePast_desc": "",
"Presence_Loading": "Загрузка...",
"Presence_Shortcut_AllDevices": "Мои устройства",
"Presence_Shortcut_Archived": "Архив",
@@ -561,14 +571,14 @@
"REPORT_MAIL_name": "Включить эл. почту",
"REPORT_TITLE": "Отчет",
"RandomMAC_hover": "Автоматически обнаружено — указывает, рандомизирует ли устройство свой MAC-адрес.",
"Reports_Sent_Log": "Отправить журнал логов",
"Reports_Sent_Log": "Отправленные уведомления",
"SCAN_SUBNETS_description": "Большинство сетевых сканеров (ARP-SCAN, NMAP, NSLOOKUP, DIG, PHOLUS) полагаются на сканирование определенных сетевых интерфейсов и подсетей. Дополнительную информацию по этому параметру можно найти в <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md\" target=\"_blank\">документации по подсетям</a>, особенно VLAN, какие VLAN поддерживаются или как разобраться в маске сети и своем интерфейсе. <br/> <br/> Альтернативой сетевым сканерам является включение некоторых других сканеров/импортеров устройств, которые не полагаются на NetAlert<sup>X</sup>, имеющий доступ к сети (UNIFI, dhcp.leases , PiHole и др.). <br/> <br/> Примечание. Само время сканирования зависит от количества проверяемых IP-адресов, поэтому тщательно настройте его, указав соответствующую маску сети и интерфейс.",
"SCAN_SUBNETS_name": "Сети для сканирования",
"SYSTEM_TITLE": "Системная информация",
"Setting_Override": "Переопределить значение",
"Setting_Override_Description": "Включение этой опции приведет к переопределению значения по умолчанию, предоставленного приложением, на значение, указанное выше.",
"Settings_Metadata_Toggle": "Показать/скрыть метаданные для данного параметра.",
"Settings_Show_Description": "",
"Settings_Show_Description": "Показать описание настройки.",
"Settings_device_Scanners_desync": "⚠ Расписания сканера устройств не синхронизированы.",
"Settings_device_Scanners_desync_popup": "Расписания сканеров устройств (<code>*_RUN_SCHD</code>) не совпадают. Это приведет к несогласованным онлайн/оффлайн уведомлениям устройства. Если это не предусмотрено, используйте одно и то же расписание для всех включенных <b>🔍Сканеров устройств</b>.",
"Speedtest_Results": "Результаты теста скорости",
@@ -655,11 +665,11 @@
"UI_ICONS_name": "Предопределенные значки",
"UI_LANG_description": "Выберите предпочтительный язык пользовательского интерфейса. Помогите перевести или предложите языки на онлайн-портале <a href=\"https://hosted.weblate.org/projects/pialert/core/\" target=\"_blank\">Weblate</a>.",
"UI_LANG_name": "Язык интерфейса",
"UI_MY_DEVICES_description": "Устройства, статусы которых должны отображаться в <b>Мои устройства</b> по умолчанию. (<code>CTRL + Click</code>, чтобы выбрать/отменить выбор)",
"UI_MY_DEVICES_description": "Устройства, статусы которых должны отображаться в стандартном представлении <b>Мои устройства</b>.",
"UI_MY_DEVICES_name": "Показать в «Мои устройства»",
"UI_NOT_RANDOM_MAC_description": "Префиксы Mac, которые не следует помечать как случайные устройства. Введите, например, <code>52</code>, чтобы исключить устройства, начинающиеся с <code>52:xx:xx:xx:xx:xx</code>, из метки как устройства со случайным MAC-адресом.",
"UI_NOT_RANDOM_MAC_name": "Не отмечать как случайные",
"UI_PRESENCE_description": "Выберите, какие статусы должны отображаться на диаграмме <b>Присутствие устройства</b> · · на странице <a href=\"/devices.php\" target=\"_blank\">Устройства</a>. (<code>CTRL + Click</code>, чтобы выбрать/отменить выбор)",
"UI_PRESENCE_description": "Выберите, какие статусы должны отображаться в диаграмме <b>Присутствие устройств</b>- на странице <a href=\"/devices.php\" target=\"_blank\">Устройства</a>.",
"UI_PRESENCE_name": "Показать в диаграмме присутствия",
"UI_REFRESH_description": "Введите количество секунд, по истечении которых пользовательский интерфейс перезагружается. Установите значение <code>0</code>, чтобы отключить.",
"UI_REFRESH_name": "Автоматическое обновление интерфейса",
@@ -668,7 +678,7 @@
"devices_old": "Актуализируется...",
"general_event_description": "Событие, которое вы инициировали, может занять некоторое время, прежде чем фоновые процессы завершатся. Выполнение завершится, как только очередь выполнения, указанная ниже, опустеет (Проверьте <a href='/maintenance.php#tab_Logging'>журнал ошибок</a> при возникновении проблем). <br/> <br/>· · Очередь выполнения:",
"general_event_title": "Выполнение специального события",
"report_guid": "Руководство по уведомлениям:",
"report_guid": "Идентификатор уведомления:",
"report_guid_missing": "Связанное уведомление не найдено. Между недавно отправленными уведомлениями и их доступностью существует небольшая задержка. Обновите страницу и кэшируйте ее через несколько секунд. Также возможно, что выбранное уведомление было удалено во время обслуживания, как указано в настройке <code>DBCLNP_NOTIFI_HIST</code>. <br/> <br/>Вместо этого отображается последнее уведомление. Отсутствующее уведомление имеет следующий GUID:",
"report_select_format": "Выбрать формат:",
"report_time": "Время уведомления:",

View File

@@ -217,6 +217,7 @@
"Device_TableHead_RowID": "",
"Device_TableHead_Rowid": "",
"Device_TableHead_SSID": "",
"Device_TableHead_SourcePlugin": "",
"Device_TableHead_Status": "Durum",
"Device_TableHead_SyncHubNodeName": "",
"Device_TableHead_Type": "",
@@ -284,6 +285,7 @@
"Gen_Description": "",
"Gen_Error": "Hata",
"Gen_Filter": "Filtre",
"Gen_Generate": "",
"Gen_LockedDB": "",
"Gen_Offline": "Çevrimdışı",
"Gen_Okay": "Tamam",
@@ -309,6 +311,8 @@
"General_icon": "<i class=\"fa fa-gears\"></i>",
"HRS_TO_KEEP_NEWDEV_description": "",
"HRS_TO_KEEP_NEWDEV_name": "",
"HRS_TO_KEEP_OFFDEV_description": "",
"HRS_TO_KEEP_OFFDEV_name": "",
"HelpFAQ_Cat_Detail": "Detaylar",
"HelpFAQ_Cat_Detail_300_head": "",
"HelpFAQ_Cat_Detail_300_text_a": "",
@@ -545,6 +549,12 @@
"Presence_CalHead_week": "hafta",
"Presence_CalHead_year": "yıl",
"Presence_CallHead_Devices": "Cihazlar",
"Presence_Key_OnlineNow": "",
"Presence_Key_OnlineNow_desc": "",
"Presence_Key_OnlinePast": "",
"Presence_Key_OnlinePastMiss": "",
"Presence_Key_OnlinePastMiss_desc": "",
"Presence_Key_OnlinePast_desc": "",
"Presence_Loading": "Yükleniyor...",
"Presence_Shortcut_AllDevices": "Cihazlarım",
"Presence_Shortcut_Archived": "",

View File

@@ -217,6 +217,7 @@
"Device_TableHead_RowID": "排行",
"Device_TableHead_Rowid": "排行",
"Device_TableHead_SSID": "SSID",
"Device_TableHead_SourcePlugin": "",
"Device_TableHead_Status": "状态",
"Device_TableHead_SyncHubNodeName": "同步节点",
"Device_TableHead_Type": "类型",
@@ -284,6 +285,7 @@
"Gen_Description": "",
"Gen_Error": "错误",
"Gen_Filter": "筛选",
"Gen_Generate": "",
"Gen_LockedDB": "错误 - DB 可能被锁定 - 检查 F12 开发工具 -> 控制台或稍后重试。",
"Gen_Offline": "离线",
"Gen_Okay": "Ok",
@@ -309,6 +311,8 @@
"General_icon": "<i class=\"fa fa-gears\"></i>",
"HRS_TO_KEEP_NEWDEV_description": "这是一项维护设置。如果启用(<code>0</code> 为禁用),则标记为<b>新设备</b>的设备(如果其<b>首次会话</b>时间早于此设置中指定的小时数)将被删除。如果您想在 <code>X</code> 小时后自动删除<b>新设备</b>,请使用此设置。",
"HRS_TO_KEEP_NEWDEV_name": "保留新设备",
"HRS_TO_KEEP_OFFDEV_description": "",
"HRS_TO_KEEP_OFFDEV_name": "",
"HelpFAQ_Cat_Detail": "详细",
"HelpFAQ_Cat_Detail_300_head": "含义 ",
"HelpFAQ_Cat_Detail_300_text_a": "表示网络设备AP、网关、防火墙、虚拟机管理程序、电力线、交换机、WLAN、PLC、路由器、USB LAN 适配器、USB WIFI 适配器或 Internet 类型的设备)。可以通过 <code>NETWORK_DEVICE_TYPES</code> 设置添加自定义类型。",
@@ -545,6 +549,12 @@
"Presence_CalHead_week": "星期",
"Presence_CalHead_year": "年",
"Presence_CallHead_Devices": "设备",
"Presence_Key_OnlineNow": "",
"Presence_Key_OnlineNow_desc": "",
"Presence_Key_OnlinePast": "",
"Presence_Key_OnlinePastMiss": "",
"Presence_Key_OnlinePastMiss_desc": "",
"Presence_Key_OnlinePast_desc": "",
"Presence_Loading": "加载中...",
"Presence_Shortcut_AllDevices": "我的设备",
"Presence_Shortcut_Archived": "已归档",

View File

@@ -4,12 +4,12 @@
// ## GUI settings processing start
// ###################################
if( isset($_COOKIE['UI_dark_mode']))
if( isset($_COOKIE['UI_theme']))
{
$ENABLED_DARKMODE = $_COOKIE['UI_dark_mode'] == "True";
$UI_THEME = $_COOKIE['UI_theme'];
}else
{
$ENABLED_DARKMODE = False;
$UI_THEME = "Light";
}
$pia_skin_selected = 'skin-blue';
@@ -18,4 +18,4 @@ $pia_skin_selected = 'skin-blue';
// ## GUI settings processing end
// ###################################
?>
?>

View File

@@ -5,7 +5,7 @@
?>
<!-- Page ------------------------------------------------------------------ -->
<div class="content-wrapper">
<div class="content-wrapper integrations-plugins">
<!-- Content header--------------------------------------------------------- -->
<section class="content-header">

View File

@@ -1,6 +1,6 @@
# 🔌 Plugins
NetAlertX supports additional plugins to extend its functionality, each with its own settings and options. Plugins can be loaded via the General -> `LOADED_PLUGINS` setting by using Ctrl + Click. For custom plugin development, refer to the [Plugin development guide](/docs/PLUGINS_DEV.md).
NetAlertX supports additional plugins to extend its functionality, each with its own settings and options. Plugins can be loaded via the General -> `LOADED_PLUGINS` setting. For custom plugin development, refer to the [Plugin development guide](/docs/PLUGINS_DEV.md).
>[!NOTE]
> Please check this [Plugins debugging guide](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEBUG_PLUGINS.md) and the corresponding Plugin documentation in the below table if you are facing issues.
@@ -16,7 +16,6 @@ NetAlertX supports additional plugins to extend its functionality, each with its
4. Fine-tune [Notifications](/docs/NOTIFICATIONS.md)
5. [Backup your setup](/docs/BACKUPS.md)
6. Contribute and [Create custom plugins](/docs/PLUGINS_DEV.md)
7. Consider [donating](https://github.com/jokob-sk/NetAlertX?tab=readme-ov-file#-sponsors) to keep me going
## 📑 Available Plugins

View File

@@ -313,6 +313,21 @@
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Object_PrimaryID",
"mapped_to_column": "cur_MAC",

View File

@@ -33,19 +33,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
"string": "Index"
}
]
},
@@ -104,7 +100,7 @@
},
{
"column": "DateTimeCreated",
"css_classes": "col-sm-2",
"css_classes": "col-sm-3",
"show": true,
"type": "label",
"default_value": "",
@@ -145,7 +141,7 @@
"options": [
{
"type": "eval",
"param": "`<a href='/report.php?guid=${value}'>${value}</a>`"
"param": "`<a href='/report.php?guid=${value}'>Link</a>`"
}
],
"localized": ["name"],

View File

@@ -33,19 +33,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
"string": "Index"
}
]
},

View File

@@ -111,7 +111,7 @@ def send(pHTML, pText):
mylog('debug', [f'[{pluginName}] SMTP_REPORT_TO: {hide_email(str(get_setting_value("SMTP_REPORT_TO")))} SMTP_USER: {hide_email(str(get_setting_value("SMTP_USER")))}'])
subject, from_email, to_email, message_html, message_text = sanitize_email_content('Net AlertX Report', get_setting_value("SMTP_REPORT_FROM"), get_setting_value("SMTP_REPORT_TO"), pHTML, pText)
subject, from_email, to_email, message_html, message_text = sanitize_email_content('NetAlertX Report', get_setting_value("SMTP_REPORT_FROM"), get_setting_value("SMTP_REPORT_TO"), pHTML, pText)
# Compose email
msg = MIMEMultipart('alternative')

View File

@@ -49,19 +49,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
"string": "Index"
}
]
},

View File

@@ -33,19 +33,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
"string": "Index"
}
]
},

View File

@@ -33,19 +33,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
"string": "Index"
}
]
},

View File

@@ -33,19 +33,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
"string": "Index"
}
]
},

View File

@@ -29,19 +29,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
"string": "Index"
}
]
},

View File

@@ -33,19 +33,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
"string": "Index"
}
]
},

View File

@@ -367,6 +367,21 @@
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Object_PrimaryID",
"mapped_to_column": "cur_MAC",
@@ -443,7 +458,7 @@
"column": "Dummy",
"mapped_to_column": "cur_ScanMethod",
"mapped_to_column_data": {
"value": "arp-scan"
"value": "ARPSCAN"
},
"css_classes": "col-sm-2",
"show": true,

View File

@@ -28,6 +28,7 @@ CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log')
pluginName = 'ARPSCAN'
def main():
@@ -58,7 +59,7 @@ def main():
userSubnetsParam = base64.b64decode(userSubnetsParamBase64).decode('ascii')
# Print the decoded subnet information.
mylog('verbose', ['[ARP Scan] userSubnetsParam: ', userSubnetsParam])
mylog('verbose', [f'[{pluginName}] userSubnetsParam: ', userSubnetsParam])
# Check if the decoded subnet information contains multiple subnets separated by commas.
# If it does, split the string into a list of individual subnets.
@@ -86,7 +87,7 @@ def main():
watched2 = handleEmpty(device.get('hw', '')), # Vendor (assuming it's in the 'hw' field)
watched3 = handleEmpty(device.get('interface', '')), # Add the interface
watched4 = '',
extra = 'arp-scan',
extra = pluginName,
foreignKey = "")
plugin_objects.write_result_file()
@@ -105,7 +106,7 @@ def execute_arpscan(userSubnets):
arpscan_output = execute_arpscan_on_interface (interface)
mylog('verbose', ['[ARP Scan] arpscan_output: ', arpscan_output])
mylog('verbose', [f'[{pluginName}] arpscan_output: ', arpscan_output])
# Search IP + MAC + Vendor as regular expresion
re_ip = r'(?P<ip>((2[0-5]|1[0-9]|[0-9])?[0-9]\.){3}((2[0-5]|1[0-9]|[0-9])?[0-9]))'
@@ -132,10 +133,10 @@ def execute_arpscan(userSubnets):
unique_devices.append(device)
# return list
mylog('verbose', ['[ARP Scan] Found: Devices without duplicates ', len(unique_devices) ])
mylog('verbose', [f'[{pluginName}] Found: Devices without duplicates ', len(unique_devices) ])
mylog('verbose', ["Devices List len:", len(devices_list)]) # Add this line to print devices_list
mylog('verbose',["Devices List:", devices_list]) # Add this line to print devices_list
mylog('verbose', [f'[{pluginName}] Devices List len:', len(devices_list)])
mylog('verbose', [f'[{pluginName}] Devices List:', devices_list])
return devices_list

View File

@@ -6,6 +6,15 @@
"data_source": "script",
"execution_order" : "Layer_3",
"show_ui": true,
"data_filters": [
{
"compare_column": "Object_PrimaryID",
"compare_operator": "==",
"compare_field_id": "txtMacFilter",
"compare_js_template": "'{value}'.toString()",
"compare_use_quotes": true
}
],
"localized": ["display_name", "description", "icon"],
"display_name": [
{
@@ -196,6 +205,21 @@
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Object_PrimaryID",
"css_classes": "col-sm-2",

View File

@@ -34,6 +34,7 @@ def main():
PLUGINS_KEEP_HIST = int(get_setting_value("PLUGINS_KEEP_HIST"))
HRS_TO_KEEP_NEWDEV = int(get_setting_value("HRS_TO_KEEP_NEWDEV"))
HRS_TO_KEEP_OFFDEV = int(get_setting_value("HRS_TO_KEEP_OFFDEV"))
DAYS_TO_KEEP_EVENTS = int(get_setting_value("DAYS_TO_KEEP_EVENTS"))
PHOLUS_DAYS_DATA = get_setting_value("PHOLUS_DAYS_DATA")
CLEAR_NEW_FLAG = get_setting_value("CLEAR_NEW_FLAG")
@@ -42,7 +43,7 @@ def main():
# Execute cleanup/upkeep
cleanup_database(fullDbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP_NEWDEV, PLUGINS_KEEP_HIST, CLEAR_NEW_FLAG)
cleanup_database(fullDbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP_NEWDEV, HRS_TO_KEEP_OFFDEV, PLUGINS_KEEP_HIST, CLEAR_NEW_FLAG)
mylog('verbose', [f'[{pluginName}] Cleanup complete'])
@@ -51,7 +52,7 @@ def main():
#===============================================================================
# Cleanup / upkeep database
#===============================================================================
def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP_NEWDEV, PLUGINS_KEEP_HIST, CLEAR_NEW_FLAG):
def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP_NEWDEV, HRS_TO_KEEP_OFFDEV, PLUGINS_KEEP_HIST, CLEAR_NEW_FLAG):
"""
Cleaning out old records from the tables that don't need to keep all data.
"""
@@ -143,6 +144,14 @@ def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP
query = f"""DELETE FROM Devices WHERE dev_NewDevice = 1 AND dev_FirstConnection < date('now', '-{str(HRS_TO_KEEP_NEWDEV)} hour')"""
mylog('verbose', [f'[{pluginName}] Query: {query} '])
cursor.execute (query)
# -----------------------------------------------------
# Cleanup Offline Devices
if HRS_TO_KEEP_OFFDEV != 0:
mylog('verbose', [f'[{pluginName}] Devices: Delete all New Devices older than {str(HRS_TO_KEEP_OFFDEV)} hours (HRS_TO_KEEP_OFFDEV setting)'])
query = f"""DELETE FROM Devices WHERE dev_PresentLastScan = 0 AND dev_LastConnection < date('now', '-{str(HRS_TO_KEEP_OFFDEV)} hour'))"""
mylog('verbose', [f'[{pluginName}] Query: {query} '])
cursor.execute (query)
# -----------------------------------------------------
# Clear New Flag

View File

@@ -498,6 +498,21 @@
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Object_PrimaryID",
"css_classes": "col-sm-2",

View File

@@ -66,23 +66,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
},
{
"language_code": "de_de",
"string": "N/A"
"string": "Index"
}
]
},

View File

@@ -42,19 +42,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
"string": "Index"
}
]
},
@@ -424,7 +420,7 @@
}
]
},
"default_value": 10,
"default_value": 20,
"options": [],
"localized": ["name", "description"],
"name": [

View File

@@ -27,7 +27,7 @@ def main():
last_run_logfile.write("")
plugin_objects = Plugin_Objects(RESULT_FILE)
timeoutSec = 10
timeoutSec = get_setting_value('DHCPSRVS_RUN_TIMEOUT')
nmapArgs = ['sudo', 'nmap', '--script', 'broadcast-dhcp-discover']
@@ -42,6 +42,9 @@ def main():
newEntries = []
for line in newLines:
mylog('verbose', [f'[DHCPSRVS] Processing line: {line} '])
if 'Response ' in line and ' of ' in line:
newEntries.append(Plugin_Object())
elif 'Server Identifier' in line:
@@ -67,6 +70,7 @@ def main():
newEntries[-1].extra += ',' + newVal
for e in newEntries:
plugin_objects.add_object(
primaryId=e.primaryId,
secondaryId=e.secondaryId,
@@ -80,7 +84,7 @@ def main():
plugin_objects.write_result_file()
except Exception as e:
mylog('none', ['Error in main:', str(e)])
mylog('verbose', ['[DHCPSRVS] Error in main:', str(e)])
if __name__ == '__main__':
main()

View File

@@ -666,7 +666,7 @@
"description": [
{
"language_code": "en_us",
"string": "Indicates whether events related to the device should trigger alerts. The default value of the <code>Alert All Events</code> checkbox."
"string": "Indicates whether events related to the device should trigger alerts. The default value of the <code>Alert Events</code> checkbox. Down and New Device notifications are always sent unless unselected in <code>NTFPRCS_INCLUDED_SECTIONS</code>."
}
]
},

View File

@@ -390,6 +390,21 @@
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Object_PrimaryID",
"mapped_to_column": "cur_MAC",

View File

@@ -41,23 +41,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
},
{
"language_code": "de_de",
"string": "N/A"
"string": "Index"
}
]
},
@@ -188,8 +180,8 @@
"hexColor": "#7D862D"
},
{
"maximum": 100,
"hexColor": "#05483C"
"maximum": 1000000,
"hexColor": "#82a39d"
}
],
"localized": ["name"],
@@ -224,8 +216,8 @@
"hexColor": "#7D862D"
},
{
"maximum": 100,
"hexColor": "#05483C"
"maximum": 1000000,
"hexColor": "#82a39d"
}
],
"localized": ["name"],

View File

@@ -46,17 +46,19 @@ def main():
def run_speedtest():
try:
st = speedtest.Speedtest()
st = speedtest.Speedtest(secure=True)
st.get_best_server()
download_speed = round(st.download() / 10**6, 2) # Convert to Mbps
upload_speed = round(st.upload() / 10**6, 2) # Convert to Mbps
mylog('verbose', [f"[INTRSPD] Result (down|up): {str(download_speed)} Mbps|{upload_speed} Mbps"])
return {
'download_speed': download_speed,
'upload_speed': upload_speed,
}
except Exception as e:
mylog('verbose', [f"Error running speedtest: {str(e)}"])
mylog('verbose', [f"[INTRSPD] Error running speedtest: {str(e)}"])
return {
'download_speed': -1,
'upload_speed': -1,

View File

@@ -253,6 +253,21 @@
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Object_PrimaryID",
"mapped_to_column": "cur_MAC",

View File

@@ -6,6 +6,15 @@
"data_source": "script",
"execution_order" : "Layer_3",
"show_ui": true,
"data_filters": [
{
"compare_column": "Object_PrimaryID",
"compare_operator": "==",
"compare_field_id": "txtMacFilter",
"compare_js_template": "'{value}'.toString()",
"compare_use_quotes": true
}
],
"localized": ["display_name", "description", "icon"],
"display_name": [
{
@@ -204,6 +213,21 @@
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Object_PrimaryID",
"css_classes": "col-sm-2",

View File

@@ -700,7 +700,7 @@
"description": [
{
"language_code": "en_us",
"string": "Indicates whether events related to the device should trigger alerts. The default value of the <code>Alert All Events</code> checkbox."
"string": "Indicates whether events related to the device should trigger alerts. The default value of the <code>Alert Events</code> checkbox. Down and New Device notifications are always sent unless unselected in <code>NTFPRCS_INCLUDED_SECTIONS</code>."
}
]
},
@@ -863,7 +863,7 @@
{
"name": "value",
"type": "sql",
"value": "SELECT DISTINCT '' as id, '❌None' as name UNION SELECT dev_Location as id, dev_Location as name FROM (SELECT dev_Location FROM Devices where dev_Location not in (null, 'null', '') UNION SELECT 'Bathroom' UNION SELECT 'Bedroom' UNION SELECT 'Dining room' UNION SELECT 'Hall' UNION SELECT 'Kitchen' UNION SELECT 'Laundry' UNION SELECT 'Living room' UNION SELECT 'Study' UNION SELECT 'Attic' UNION SELECT 'Basement' UNION SELECT 'Garage' UNION SELECT 'Back yard' UNION SELECT 'Garden' UNION SELECT 'Terrace') AS all_devices ORDER BY id; "
"value": "SELECT DISTINCT '' AS id, '❌None' AS name UNION SELECT dev_Location AS id, dev_Location AS name FROM Devices WHERE dev_Location NOT IN ('', 'null') AND dev_Location IS NOT NULL UNION SELECT 'Bathroom' AS id, 'Bathroom' AS name UNION SELECT 'Bedroom', 'Bedroom' UNION SELECT 'Dining room', 'Dining room' UNION SELECT 'Hall', 'Hall' UNION SELECT 'Kitchen', 'Kitchen' UNION SELECT 'Laundry', 'Laundry' UNION SELECT 'Living room', 'Living room' UNION SELECT 'Study', 'Study' UNION SELECT 'Attic', 'Attic' UNION SELECT 'Basement', 'Basement' UNION SELECT 'Garage', 'Garage' UNION SELECT 'Back yard', 'Back yard' UNION SELECT 'Garden', 'Garden' UNION SELECT 'Terrace', 'Terrace' ORDER BY id;"
}
],
"localized": ["name", "description"],

View File

@@ -343,6 +343,21 @@
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Object_PrimaryID",
"mapped_to_column": "cur_MAC",

View File

@@ -74,15 +74,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
"string": "Index"
}
]
},

View File

@@ -7,7 +7,7 @@ Plugin supplying settings for Notification Processing.
- `new_devices` - if a new device is detected
- `down_devices` - if a device with **Alert down** enabled (on a specific Device) disconnects
- `down_reconnected` - if a device, previously marked down and notified on, reconnects
- `events` - if an event for a device that has **Alert All Events** enabled, is triggered
- `events` - if an event for a device that has **Alert Events** enabled, is triggered
- `plugins` - if an event for a plugin, is triggered

View File

@@ -6,6 +6,15 @@
"enabled": true,
"data_source": "script",
"show_ui": true,
"data_filters": [
{
"compare_column": "Object_PrimaryID",
"compare_operator": "==",
"compare_field_id": "txtMacFilter",
"compare_js_template": "'{value}'.toString()",
"compare_use_quotes": true
}
],
"localized": ["display_name", "description", "icon"],
"display_name": [
{
@@ -204,6 +213,21 @@
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Object_PrimaryID",
"css_classes": "col-sm-2",

View File

@@ -447,6 +447,21 @@
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Object_PrimaryID",
"mapped_to_column": "cur_MAC",

View File

@@ -323,6 +323,21 @@
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Object_PrimaryID",
"mapped_to_column": "MAC",

View File

@@ -278,6 +278,21 @@
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Object_PrimaryID",
"mapped_to_column": "cur_MAC",

View File

@@ -80,7 +80,14 @@ def is_typical_router_ip(ip_address):
# -------------------------------------------------------------------
# Check if a valid MAC address
def is_mac(input):
return re.match("[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", input.lower())
input_str = str(input).lower() # Convert to string and lowercase so non-string values won't raise errors
isMac = bool(re.match("[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", input_str))
if not isMac: # If it's not a MAC address, log the input
mylog('verbose', [f'[is_mac] not a MAC: {input_str}'])
return isMac
# -------------------------------------------------------------------
def decodeBase64(inputParamBase64):

View File

@@ -66,19 +66,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
"string": "Index"
}
]
},

View File

@@ -61,3 +61,66 @@ The plugin operates in three different modes based on the configuration settings
- It is recommended to use Device synchronization primarily. Plugin data synchronization is more suitable for specific use cases.
![Sync Hub Setup Diagram](/front/plugins/sync/sync_hub.png)
### Example use case: Network Setup with Multiple VLANs and VM Scanning
> Thank you to [@richtj999](https://github.com/richtj999) for the use case 🙏
I have 6 VLANs, all isolated by a firewall, except for one VLAN that has access to all the others.
Initially, I had one virtual machine (VM) with 6 network cards, one for each VLAN. While this setup worked, it introduced delays due to other concurrent scans. To optimize this, I switched to a multi-VM setup:
- I created 6 VMs, each attached to a single VLAN.
- One VM acts as the "server," and the other 5 as "clients."
- The server has access to all VLANs (via firewall rules) and collects data from the client VMs, which each scan their own VLAN.
#### Summary
- **Single VM on six VLANs**: Slower because one VM scans all networks.
- **Six VMs on six VLANs**: Faster because each VM scans its own network, sending the results to the server.
#### Example Setup
- **VM1 ("Server")**: Network 1 (can access all networks) - IP: `10.10.10.106`
Receives data from all NetAlertX clients and scans network 1.
- **VM2 ("Client")**: Network 2 (can access only network 2) - IP: `192.168.x.x`
Scans network 2; VM1 retrieves this data.
- **VM3 ("Client")**: Network 3 (can access only network 3) - IP: `192.168.x.x`
Scans network 3; VM1 retrieves this data.
- **VM4 ("Client")**: Network 4 (can access only network 4) - IP: `192.168.x.x`
Scans network 4; VM1 retrieves this data.
- **VM5 ("Client")**: Network 5 (can access only network 5) - IP: `192.168.x.x`
Scans network 5; VM1 retrieves this data.
- **VM6 ("Client")**: Network 6 (can access only network 6) - IP: `192.168.x.x`
Scans network 6; VM1 retrieves this data.
---
#### How to Set It Up
##### Server (VM1)
1. Go to **Settings > System > Sync Hub**.
2. Set the schedule (5 minutes works for me).
3. **API Token**: Use any string, but it must match the clients (e.g., `abc123`).
4. **Encryption Key**: Use any string, but it must match the clients (e.g., `abc123`).
5. Under **Nodes**, add the full URL for each client, e.g., `http://192.168.1.20.20211/`.
6. **Node Name**: Leave blank.
7. Check **Sync Devices**.
##### Clients (VM2, VM3, VM4, VM5, VM6)
1. Go to **Settings > System > Sync Hub**.
2. Set **When to run** to "Always after scan."
3. **API Token**: Use the same token as the server (e.g., `abc123`).
4. **Encryption Key**: Use the same key as the server (e.g., `abc123`).
5. Leave **Nodes** blank.
6. Set **Node Name** to a unique, memorable name for each client.
7. Check **Sync Devices**.

View File

@@ -47,7 +47,7 @@
},
"default_value": "unused",
"options": [
"options": [
"unused",
"once",
"schedule",
@@ -115,7 +115,22 @@
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
{
"elementType": "input",
"elementHasInputValue": 1,
"elementOptions": [{ "cssClasses": "col-xs-12" }],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "getStringKey": "Gen_Generate" },
{ "customParams": "SYNC_api_token" },
{ "onClick": "generateApiToken(this, 20)" },
{ "cssClasses": "col-xs-12" }
],
"transformers": []
}
]
},
"maxLength": 50,
@@ -131,7 +146,7 @@
"description": [
{
"language_code": "en_us",
"string": "API token to secure communication. It's sent in the request header. The API token needs to be the same on the hub and on the nodes."
"string": "API token to secure communication, you can generate one or enter any value. It's sent in the request header. The API token needs to be the same on the hub and on the nodes."
}
]
},
@@ -140,7 +155,22 @@
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
{
"elementType": "input",
"elementHasInputValue": 1,
"elementOptions": [{ "cssClasses": "col-xs-12" }],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "getStringKey": "Gen_Generate" },
{ "customParams": "SYNC_encryption_key" },
{ "onClick": "generateApiToken(this, 30)" },
{ "cssClasses": "col-xs-12" }
],
"transformers": []
}
]
},
"maxLength": 50,
@@ -159,7 +189,8 @@
"string": "Encryption key used to encrypt the data before sending and for decryption on the hub. The key needs to be the same on the hub and on the nodes."
}
]
},{
},
{
"function": "nodes",
"type": {
"dataType": "array",
@@ -440,6 +471,21 @@
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Object_PrimaryID",
"mapped_to_column": "cur_MAC",

View File

@@ -346,7 +346,8 @@
"Device_TableHead_Type",
"Device_TableHead_LastIP",
"Device_TableHead_Status",
"Device_TableHead_MAC_full"
"Device_TableHead_MAC_full",
"Device_TableHead_SourcePlugin"
],
"options": [
"Device_TableHead_Name",
@@ -371,7 +372,8 @@
"Device_TableHead_GUID",
"Device_TableHead_SyncHubNodeName",
"Device_TableHead_NetworkSite",
"Device_TableHead_SSID"
"Device_TableHead_SSID",
"Device_TableHead_SourcePlugin"
],
"localized": ["name", "description"],
"name": [
@@ -456,35 +458,35 @@
"description": [
{
"language_code": "en_us",
"string": "Hide Device tiles with zero results."
"string": "Hide Tiles in the Devices pages with zero results."
}
]
},
{
"function": "dark_mode",
"function": "theme",
"type": {
"dataType": "boolean",
"dataType": "array",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"elementType": "select",
"elementOptions": [{ "multiple": "false", "orderable": "false" }],
"transformers": []
}
]
},
"default_value": false,
"options": [],
"default_value": "Light",
"options": ["Light","Dark","System"],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Dark mode"
"string": "Theme"
}
],
"description": [
{
"language_code": "en_us",
"string": "Enable dark mode."
"string": "UI theme to use. System will auto switch between Light and Dark."
}
]
}

View File

@@ -385,6 +385,21 @@
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Watched_Value1",
"mapped_to_column": "cur_Name",

View File

@@ -12,9 +12,16 @@ Specify the following settings in the Settings section of NetAlertX:
- `UNFIMP_sites` - Name of the sites (usually 'default', check the URL in your UniFi controller UI if unsure. The site id is in the following part of the URL: `https://192.168.1.1:8443/manage/site/this-is-the-site-id/settings/`).
- `UNFIMP_protocol` - https:// or http://
- `UNFIMP_port` - Usually `8443` or `8843`
- `UNFIMP_version` - e.g. `UDMP-unifiOS` is used for the "Cloud Gateway Ultra"
- `UNFIMP_version` - see below table for details
#### Version table
| Controller | `UNFIMP_version` |
| ------------------------------------------------------ | ------------------------- |
| Cloud Gateway Ultra / UCK cloudkey V2 plus (v4.0.18) | `UDMP-unifiOS` |
| Docker hosted | `v5` |
### Notes
- It is recommended to create a read-only user in your UniFi controller

View File

@@ -83,25 +83,17 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
},
{
"language_code": "de_de",
"string": "N/A"
"string": "Index"
}
],
"options": [],
"show": false,
"type": "label"
]
},
{
"column": "Plugin",

View File

@@ -19,7 +19,7 @@ from pyunifi.controller import Controller
INSTALL_PATH="/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, rmBadChars, is_typical_router_ip
from plugin_helper import Plugin_Object, Plugin_Objects, rmBadChars, is_typical_router_ip, is_mac
from logger import mylog
from helper import timeNowTZ, get_setting_value, normalize_string
import conf
@@ -165,31 +165,37 @@ def collect_details(device_type, devices, online_macs, processed_macs, plugin_ob
name = get_name(get_unifi_val(device, 'name'), get_unifi_val(device, 'hostname'))
ipTmp = get_ip(get_unifi_val(device, 'lan_ip'), get_unifi_val(device, 'last_ip'), get_unifi_val(device, 'fixed_ip'), get_unifi_val(device, 'ip'))
macTmp = device['mac']
status = 1 if macTmp in online_macs else device.get('state', 0)
deviceType = device_type.get(device.get('type'), '')
parentMac = get_parent_mac(get_unifi_val(device, 'uplink_mac'), get_unifi_val(device, 'ap_mac'), get_unifi_val(device, 'sw_mac'))
# override parent MAC if this is a router
if parentMac == 'null' and is_typical_router_ip(ipTmp):
parentMac = 'Internet'
# continue only if valid MAC address
if is_mac(macTmp):
status = 1 if macTmp in online_macs else device.get('state', 0)
deviceType = device_type.get(device.get('type'), '')
parentMac = get_parent_mac(get_unifi_val(device, 'uplink_mac'), get_unifi_val(device, 'ap_mac'), get_unifi_val(device, 'sw_mac'))
# override parent MAC if this is a router
if parentMac == 'null' and is_typical_router_ip(ipTmp):
parentMac = 'Internet'
# Add object only if not processed
if macTmp not in processed_macs and ( status == 1 or force_import is True ):
plugin_objects.add_object(
primaryId=macTmp,
secondaryId=ipTmp,
watched1=normalize_string(name),
watched2=get_unifi_val(device, 'oui', device_vendor),
watched3=deviceType,
watched4=status,
extra=get_unifi_val(device, 'connection_network_name', ''),
foreignKey="",
helpVal1=parentMac,
helpVal2=get_port(get_unifi_val(device, 'sw_port'), get_unifi_val(device, 'uplink_remote_port')),
helpVal3=device_label,
helpVal4="",
)
processed_macs.append(macTmp)
# Add object only if not processed
if macTmp not in processed_macs and ( status == 1 or force_import is True ):
plugin_objects.add_object(
primaryId=macTmp,
secondaryId=ipTmp,
watched1=normalize_string(name),
watched2=get_unifi_val(device, 'oui', device_vendor),
watched3=deviceType,
watched4=status,
extra=get_unifi_val(device, 'connection_network_name', ''),
foreignKey="",
helpVal1=parentMac,
helpVal2=get_port(get_unifi_val(device, 'sw_port'), get_unifi_val(device, 'uplink_remote_port')),
helpVal3=device_label,
helpVal4="",
)
processed_macs.append(macTmp)
else:
mylog('verbose', [f'[{pluginName}] Skipping, not a valid MAC address: {macTmp}'])
# -----------------------------------------------------------------------------
def get_unifi_val(obj, key, default='null'):
if isinstance(obj, dict):

View File

@@ -302,23 +302,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
},
{
"language_code": "de_de",
"string": "N/A"
"string": "Index"
}
]
},

View File

@@ -57,19 +57,15 @@
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
"string": "Index"
}
]
},

View File

@@ -1,44 +1,51 @@
<!-- ----------------------------------------------------------------------- -->
<!-- Datatable -->
<link rel="stylesheet" href="lib/AdminLTE/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css">
<link rel="stylesheet" href="lib/AdminLTE/bower_components/datatables.net/css/select.dataTables.min.css">
<script src="lib/AdminLTE/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
<script src="lib/AdminLTE/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
<script src="lib/AdminLTE/bower_components/datatables.net/js/dataTables.select.min.js"></script>
<!-- Main content ---------------------------------------------------------- -->
<section class="content">
<div class="plugin-filters">
<div class="input-group col-sm-4">
<label class="control-label col-sm-3"><?= lang('Plugins_Filters_Mac');?></label>
<input class="form-control col-sm-3" id="txtMacFilter" type="text" value="--" readonly>
</div>
<div class="plugin-filters">
<div class="input-group col-sm-12">
<label class="col-sm-3"><?= lang('Plugins_Filters_Mac');?></label>
<input class="col-sm-3" id="txtMacFilter" type="text" value="--" readonly>
</div>
<div class="nav-tabs-custom plugin-content" style="margin-bottom: 0px;">
<ul id="tabs-location" class="nav nav-tabs col-sm-2 ">
<!-- PLACEHOLDER -->
</ul>
<div id="tabs-content-location" class="tab-content col-sm-10">
<!-- PLACEHOLDER -->
</div>
</div>
<div class="nav-tabs-custom plugin-content" style="margin-bottom: 0px;">
<ul id="tabs-location" class="nav nav-tabs col-sm-2 ">
<!-- PLACEHOLDER -->
</ul>
<div id="tabs-content-location" class="tab-content col-sm-10">
<!-- PLACEHOLDER -->
</div>
</section>
<script defer>
<script>
// -----------------------------------------------------------------------------
// Initializes fields based on current MAC
function initFields() {
var urlParams = new URLSearchParams(window.location.search);
mac = urlParams.get ('mac');
var urlParams = new URLSearchParams(window.location.search);
mac = urlParams.get ('mac');
// if the current mac has changed, reinitialize the data
if(mac != undefined && $("#txtMacFilter").val() != mac)
{
$("#txtMacFilter").val(mac);
// if the current mac has changed, reinitialize the data
if(mac != undefined && $("#txtMacFilter").val() != mac)
{
$("#txtMacFilter").val(mac);
getData();
}
getData();
}
}
@@ -46,142 +53,145 @@ function initFields() {
// Checking if current MAC has changed and triggering an updated if needed
function updater() {
initFields()
initFields()
// loop
setTimeout(function() {
updater();
}, 500);
// loop
setTimeout(function() {
updater();
}, 500);
}
// -----------------------------------------------------------------------------
// Get form control according to the column definition from config.json > database_column_definitions
function getFormControl(dbColumnDef, value, index) {
function getFormControl(dbColumnDef, value, index) {
result = ''
result = ''
// Check if mapped_to_column_data exists and has a value to override the supplied value which is most likely `undefined`
if (dbColumnDef.mapped_to_column_data && dbColumnDef.mapped_to_column_data.value) {
value = dbColumnDef.mapped_to_column_data.value;
}
// Check if mapped_to_column_data exists and has a value to override the supplied value which is most likely `undefined`
if (dbColumnDef.mapped_to_column_data && dbColumnDef.mapped_to_column_data.value) {
value = dbColumnDef.mapped_to_column_data.value;
}
result = processColumnValue(dbColumnDef, value, index, dbColumnDef.type)
result = processColumnValue(dbColumnDef, value, index, dbColumnDef.type)
return result;
return result;
}
// -----------------------------------------------------------------------------
// Process column value
function processColumnValue(dbColumnDef, value, index, type) {
if (type.includes('.')) {
const typeParts = type.split('.');
// recursion
for (const typePart of typeParts) {
value = processColumnValue(dbColumnDef, value, index, typePart)
}
const typeParts = type.split('.');
// recursion
for (const typePart of typeParts) {
value = processColumnValue(dbColumnDef, value, index, typePart)
}
} else{
// pick form control based on the supplied type
switch(type)
{
case 'label':
value = `<span>${value}<span>`;
break;
case 'textarea_readonly':
value = `<textarea cols="70" rows="3" wrap="off" readonly style="white-space: pre-wrap;">
${value.replace(/^b'(.*)'$/gm, '$1').replace(/\\n/g, '\n').replace(/\\r/g, '\r')}
</textarea>`;
break;
case 'textbox_save':
// pick form control based on the supplied type
switch(type)
{
case 'label':
value = `<span>${value}<span>`;
break;
case 'none':
value = `${value}`;
break;
case 'textarea_readonly':
value = `<textarea cols="70" rows="3" wrap="off" readonly style="white-space: pre-wrap;">
${value.replace(/^b'(.*)'$/gm, '$1').replace(/\\n/g, '\n').replace(/\\r/g, '\r')}
</textarea>`;
break;
case 'textbox_save':
value = value == 'null' ? '' : value; // hide 'null' values
value = value == 'null' ? '' : value; // hide 'null' values
id = `${dbColumnDef.column}_${index}`
id = `${dbColumnDef.column}_${index}`
value = `<span class="form-group">
<div class="input-group">
<input class="form-control" type="text" value="${value}" id="${id}" data-my-column="${dbColumnDef.column}" data-my-index="${index}" name="${dbColumnDef.column}">
<span class="input-group-addon"><i class="fa fa-save pointer" onclick="genericSaveData('${id}');"></i></span>
</div>
<span>`;
break;
case 'url':
value = `<span><a href="${value}" target="_blank">${value}</a><span>`;
break;
case 'url_http_https':
value = `<span>
<a href="http://${value}" target="_blank">
<i class="fa fa-lock-open "></i>
</a>
/
<a href="https://${value}" target="_blank">
<i class="fa fa-lock "></i>
</a>
<span>`;
break;
case 'device_name_mac':
value = createDeviceLink(value);
break;
case 'device_mac':
value = `<span class="anonymizeMac"><a href="/deviceDetails.php?mac=${value}" target="_blank">${value}</a><span>`;
break;
case 'device_ip':
value = `<span class="anonymizeIp"><a href="#" onclick="navigateToDeviceWithIp('${value}')" >${value}</a><span>`;
break;
case 'threshold':
value = `<span class="form-group">
<div class="input-group">
<input class="form-control" type="text" value="${value}" id="${id}" data-my-column="${dbColumnDef.column}" data-my-index="${index}" name="${dbColumnDef.column}">
<span class="input-group-addon"><i class="fa fa-save pointer" onclick="genericSaveData('${id}');"></i></span>
</div>
<span>`;
break;
case 'url':
value = `<span><a href="${value}" target="_blank">${value}</a><span>`;
break;
case 'url_http_https':
value = `<span>
<a href="http://${value}" target="_blank">
<i class="fa fa-lock-open "></i>
</a>
/
<a href="https://${value}" target="_blank">
<i class="fa fa-lock "></i>
</a>
<span>`;
break;
case 'device_name_mac':
value = createDeviceLink(value);
break;
case 'device_mac':
value = `<span class="anonymizeMac"><a href="/deviceDetails.php?mac=${value}" target="_blank">${value}</a><span>`;
break;
case 'device_ip':
value = `<span class="anonymizeIp"><a href="#" onclick="navigateToDeviceWithIp('${value}')" >${value}</a><span>`;
break;
case 'threshold':
valueTmp = ''
valueTmp = ''
$.each(dbColumnDef.options, function(index, obj) {
if(Number(value) < Number(obj.maximum) && valueTmp == '')
{
valueTmp = `<div style="background-color:${obj.hexColor}">${value}</div>`
// return;
}
});
$.each(dbColumnDef.options, function(index, obj) {
if(Number(value) < Number(obj.maximum) && valueTmp == '')
{
valueTmp = `<div style="background-color:${obj.hexColor}">${value}</div>`
// return;
}
});
value = valueTmp;
value = valueTmp;
break;
case 'replace':
$.each(dbColumnDef.options, function(index, obj) {
if(value == obj.equals)
{
value = `<span title="${value}">${obj.replacement}</span>`
}
});
break;
case 'regex':
for (const option of dbColumnDef.options) {
if (option.type === type) {
const regexPattern = new RegExp(option.param);
const match = value.match(regexPattern);
if (match) {
// Return the first match
value = match[0];
}
}
}
break;
case 'eval':
for (const option of dbColumnDef.options) {
if (option.type === type) {
// console.log(option.param)
value = eval(option.param);
}
}
break;
default:
value = value + `<div style='text-align:center' title="${getString("Plugins_no_control")}"><i class='fa-solid fa-circle-question'></i></div>` ;
}
break;
case 'replace':
$.each(dbColumnDef.options, function(index, obj) {
if(value == obj.equals)
{
value = `<span title="${value}">${obj.replacement}</span>`
}
});
break;
case 'regex':
for (const option of dbColumnDef.options) {
if (option.type === type) {
const regexPattern = new RegExp(option.param);
const match = value.match(regexPattern);
if (match) {
// Return the first match
value = match[0];
}
}
}
break;
case 'eval':
for (const option of dbColumnDef.options) {
if (option.type === type) {
// console.log(option.param)
value = eval(option.param);
}
}
break;
default:
value = value + `<div style='text-align:center' title="${getString("Plugins_no_control")}"><i class='fa-solid fa-circle-question'></i></div>` ;
}
}
// Default behavior if no match is found
@@ -193,30 +203,30 @@ function processColumnValue(dbColumnDef, value, index, type) {
// -----------------------------------------------------------------------------
// Update the corresponding DB column and entry
function genericSaveData (id) {
columnName = $(`#${id}`).attr('data-my-column')
index = $(`#${id}`).attr('data-my-index')
columnValue = $(`#${id}`).val()
columnName = $(`#${id}`).attr('data-my-column')
index = $(`#${id}`).attr('data-my-index')
columnValue = $(`#${id}`).val()
console.log(columnName)
console.log(index)
console.log(columnValue)
console.log(columnName)
console.log(index)
console.log(columnValue)
$.get(`php/server/dbHelper.php?action=update&dbtable=Plugins_Objects&columnName=Index&id=${index}&columns=UserData&values=${columnValue}`, function(data) {
// var result = JSON.parse(data);
// console.log(data)
$.get(`php/server/dbHelper.php?action=update&dbtable=Plugins_Objects&columnName=Index&id=${index}&columns=UserData&values=${columnValue}`, function(data) {
// var result = JSON.parse(data);
// console.log(data)
if(sanitize(data) == 'OK')
{
showMessage('<?= lang('Gen_DataUpdatedUITakesTime');?>')
// Remove navigation prompt "Are you sure you want to leave..."
window.onbeforeunload = null;
} else
{
showMessage('<?= lang('Gen_LockedDB');?>')
}
if(sanitize(data) == 'OK')
{
showMessage('<?= lang('Gen_DataUpdatedUITakesTime');?>')
// Remove navigation prompt "Are you sure you want to leave..."
window.onbeforeunload = null;
} else
{
showMessage('<?= lang('Gen_LockedDB');?>')
}
});
});
}
@@ -228,361 +238,287 @@ pluginHistory = []
function getData(){
$.get('api/plugins.json', function(res) {
pluginDefinitions = res["data"];
// Show the loading spinner while generating
showSpinner();
$.get('api/table_plugins_events.json', function(res) {
pluginUnprocessedEvents = res["data"];
$.get('api/table_plugins_objects.json', function(res) {
pluginObjects = res["data"];
$.get('api/table_plugins_history.json', function(res) {
pluginHistory = res["data"];
generateTabs()
});
});
});
});
}
// -----------------------------------------------------------------------------
function generateTabs()
{
showSpinner()
$.get('api/plugins.json', function(res) {
activetab = 'active'
pluginDefinitions = res["data"];
// clear previous headers data
$('#tabs-location').html("");
// clear previous content data
$('#tabs-content-location').html("");
$.get('api/table_plugins_events.json', function(res) {
$.each(pluginDefinitions, function(index, pluginObj) {
pluginUnprocessedEvents = res["data"];
// console.log(pluginObj)
$.get('api/table_plugins_objects.json', function(res) {
if(pluginObj.show_ui) // hiding plugins where specified
{
prefix = pluginObj.unique_prefix;
$('#tabs-location').append(
`<li class=" left-nav ${activetab}">
<a class=" col-sm-12 " href="#${prefix}" data-plugin-prefix="${prefix}" id="${prefix}_id" data-toggle="tab" >
${getString(`${prefix}_icon`)} ${getString(`${prefix}_display_name`)}
</a>
</li>`
);
activetab = '' // only first tab is active
}
});
pluginObjects = res["data"];
$.get('api/table_plugins_history.json', function(res) {
activetab = 'active'
$.each(pluginDefinitions, function(index, pluginObj) {
pluginHistory = res["data"];
headersHtml = ""
colDefinitions = []
evRows = ""
obRows = ""
hiRows = ""
prefix = pluginObj.unique_prefix;
generateTabs()
// Generate the header
$.each(pluginObj["database_column_definitions"], function(index, colDef){
if(colDef.show == true) // select only the ones to show
{
colDefinitions.push(colDef)
headersHtml += `<th class="${colDef.css_classes}" >${getString(`${prefix}_${colDef.column}_name` )}</th>`
}
});
// Generate the event rows
var eveCount = 0;
for(i=0;i<pluginUnprocessedEvents.length;i++)
{
if(pluginUnprocessedEvents[i].Plugin == prefix)
{
clm = ""
for(j=0;j<colDefinitions.length;j++)
{
clm += '<td>'+ pluginUnprocessedEvents[i][colDefinitions[j].column] +'</td>'
}
evRows += `<tr data-my-index="${pluginUnprocessedEvents[i]["Index"]}" >${clm}</tr>`
eveCount++;
}
}
// Generate the history rows
var histCount = 0
var histCountDisplayed = 0
for(i=0;i < pluginHistory.length ;i++)
{
if(pluginHistory[i].Plugin == prefix)
{
if(histCount < 50) // only display 50 entries to optimize performance
{
clm = ""
for(j=0;j<colDefinitions.length;j++)
{
clm += '<td>'+ pluginHistory[i][colDefinitions[j].column] +'</td>'
}
hiRows += `<tr data-my-index="${pluginHistory[i]["Index"]}" >${clm}</tr>`
histCountDisplayed++;
}
histCount++; // count and display the total
}
}
// Generate the object rows
var obCount = 0;
for(var i=0;i<pluginObjects.length;i++)
{
if(pluginObjects[i].Plugin == prefix)
{
if(shouldBeShown(pluginObjects[i], pluginObj)) // filter TODO
{
clm = ""
for(var j=0;j<colDefinitions.length;j++)
{
clm += '<td>'+ getFormControl(colDefinitions[j], pluginObjects[i][colDefinitions[j].column], pluginObjects[i]["Index"], colDefinitions, pluginObjects[i]) +'</td>'
}
obRows += `<tr data-my-index="${pluginObjects[i]["Index"]}" >${clm}</tr>`
obCount++;
}
}
}
// Generate the HTML
$('#tabs-content-location').append(
`
<div id="${prefix}" class="tab-pane ${activetab}">
<div class="nav-tabs-custom" style="margin-bottom: 0px">
<ul class="nav nav-tabs">
<li class="active" >
<a href="#objectsTarget_${prefix}" data-toggle="tab" >
<i class="fa fa-cube"></i> <?= lang('Plugins_Objects');?> (${obCount})
</a>
</li>
<li >
<a href="#eventsTarget_${prefix}" data-toggle="tab" >
<i class="fa fa-bolt"></i> <?= lang('Plugins_Unprocessed_Events');?> (${eveCount})
</a>
</li>
<li >
<a href="#historyTarget_${prefix}" data-toggle="tab" >
<i class="fa fa-clock"></i> <?= lang('Plugins_History');?> (${histCountDisplayed} <?= lang('Plugins_Out_of');?> ${histCount})
</a>
</li>
<ul>
</div>
<div class="tab-content">
<div id="objectsTarget_${prefix}" class="tab-pane ${activetab}">
<table class="table table-striped" data-my-dbtable="Plugins_Objects">
<tbody>
<tr>
${headersHtml}
</tr>
${obRows}
</tbody>
</table>
<div class="plugin-obj-purge">
<button class="btn btn-primary" onclick="purgeAll('${prefix}', 'Plugins_Objects' )"><?= lang('Plugins_DeleteAll');?></button>
<button class="btn btn-danger " onclick="deleteListed('${prefix}', 'Plugins_Objects' )"><?= lang('Plugins_Obj_DeleteListed');?></button>
</div>
</div>
<div id="eventsTarget_${prefix}" class="tab-pane">
<table class="table table-striped" data-my-dbtable="Plugins_Events">
<tbody>
<tr>
${headersHtml}
</tr>
${evRows}
</tbody>
</table>
<div class="plugin-obj-purge">
<button class="btn btn-primary" onclick="purgeAll('${prefix}', 'Plugins_Events' )"><?= lang('Plugins_DeleteAll');?></button>
</div>
</div>
<div id="historyTarget_${prefix}" class="tab-pane">
<table class="table table-striped" data-my-dbtable="Plugins_History">
<tbody>
<tr>
${headersHtml}
</tr>
${hiRows}
</tbody>
</table>
<div class="plugin-obj-purge">
<button class="btn btn-primary" onclick="purgeAll('${prefix}', 'Plugins_History' )"><?= lang('Plugins_DeleteAll');?></button>
</div>
</div>
</div>
<div class='plugins-description'>
${getString(prefix + '_description')}
<span>
<a href="https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/${pluginObj.code_name}" target="_blank"><?= lang('Gen_ReadDocs');?></a>
</span>
</div>
</div>
`);
activetab = '' // only first tab is active
});
});
initTabs()
});
}
// --------------------------------------------------------
// Handle active / selected tabs
// handle first tab (objectsTarget_) display
function initTabs() {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var target = $(e.target).attr("href").split('_').pop();
function generateTabs() {
var pref = target.includes('_') ? target.split('_')[1] : target.split('#')[1];
// Reset the tabs by clearing previous headers and content
resetTabs();
// Sort pluginDefinitions by unique_prefix alphabetically
pluginDefinitions.sort((a, b) => a.unique_prefix.localeCompare(b.unique_prefix));
// Iterate over the sorted pluginDefinitions to create tab headers and content
pluginDefinitions.forEach(pluginObj => {
if (pluginObj.show_ui) {
stats = createTabContent(pluginObj); // Create the content for each tab
createTabHeader(pluginObj, stats); // Create the header for each tab
}
});
hideSpinner()
}
function resetTabs() {
// Clear any existing tab headers and content from the DOM
$('#tabs-location').empty();
$('#tabs-content-location').empty();
}
function createTabHeader(pluginObj, stats) {
const prefix = pluginObj.unique_prefix; // Get the unique prefix for the plugin
// Determine the active class for the first tab
const activeClass = pluginDefinitions.indexOf(pluginObj) === 0 ? 'active' : '';
// Append the tab header to the tabs location
$('#tabs-location').append(`
<li class="left-nav ${activeClass} ">
<a class="col-sm-12 textOverflow" href="#${prefix}" data-plugin-prefix="${prefix}" id="${prefix}_id" data-toggle="tab">
${getString(`${prefix}_icon`)} ${getString(`${prefix}_display_name`)}
var everythingHidden = true;
if ($('#objectsTarget_' + pref) && $('#historyTarget_' + pref) && $('#eventsTarget_' + pref)) {
var isObjectsInactive = !$('#objectsTarget_' + pref).hasClass('active');
var isHistoryInactive = !$('#historyTarget_' + pref).hasClass('active');
var isEventsInactive = !$('#eventsTarget_' + pref).hasClass('active');
everythingHidden = isObjectsInactive && isHistoryInactive && isEventsInactive;
}
if (target === '#' + pref && everythingHidden) {
var objectsTarget = $('#objectsTarget_' + pref);
if (objectsTarget.length && !objectsTarget.hasClass('active')) {
objectsTarget.addClass('active');
}
}
});
// hide spinning icon
hideSpinner()
</a>
${stats.objectDataCount > 0 ? `<div class="pluginBadgeWrap"><span title="" class="badge pluginBadge" >${stats.objectDataCount}</span></div>` : ""}
</li>
`);
}
function createTabContent(pluginObj) {
const prefix = pluginObj.unique_prefix; // Get the unique prefix for the plugin
const colDefinitions = getColumnDefinitions(pluginObj); // Get column definitions for DataTables
// Get data for events, objects, and history related to the plugin
const objectData = getObjectData(prefix, colDefinitions, pluginObj);
const eventData = getEventData(prefix, colDefinitions);
const historyData = getHistoryData(prefix, colDefinitions, pluginObj);
// Append the content structure for the plugin's tab to the content location
$('#tabs-content-location').append(`
<div id="${prefix}" class="tab-pane ${pluginDefinitions.indexOf(pluginObj) === 0 ? 'active' : ''}">
${generateTabNavigation(prefix, objectData.length, eventData.length, historyData.length)} <!-- Create tab navigation -->
<div class="tab-content">
${generateDataTable(prefix, 'Objects', objectData, colDefinitions)}
${generateDataTable(prefix, 'Events', eventData, colDefinitions)}
${generateDataTable(prefix, 'History', historyData, colDefinitions)}
</div>
<div class='plugins-description'>
${getString(`${prefix}_description`)} <!-- Display the plugin description -->
<span><a href="https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/${pluginObj.code_name}" target="_blank">${getString('Gen_ReadDocs')}</a></span> <!-- Link to documentation -->
</div>
</div>
`);
// Initialize DataTables for the respective sections
initializeDataTables(prefix, objectData, eventData, historyData, colDefinitions);
return {
"objectDataCount": objectData.length,
"eventDataCount": eventData.length,
"historyDataCount": historyData.length
}
}
function getColumnDefinitions(pluginObj) {
// Filter and return only the columns that are set to show in the UI
return pluginObj["database_column_definitions"].filter(colDef => colDef.show);
}
function getEventData(prefix, colDefinitions) {
// Extract event data specific to the plugin and format it for DataTables
return pluginUnprocessedEvents
.filter(event => event.Plugin === prefix) // Filter events for the specific plugin
.map(event => colDefinitions.map(colDef => event[colDef.column] || '')); // Map to the defined columns
}
function getObjectData(prefix, colDefinitions, pluginObj) {
// Extract object data specific to the plugin and format it for DataTables
return pluginObjects
.filter(object => object.Plugin === prefix && shouldBeShown(object, pluginObj)) // Filter objects for the specific plugin
.map(object => colDefinitions.map(colDef => getFormControl(colDef, object[colDef.column], object["Index"], colDefinitions, object))); // Map to the defined columns
}
function getHistoryData(prefix, colDefinitions, pluginObj) {
// Extract history data for the plugin, limiting to the first 50 entries for performance
return pluginHistory
.filter((history, index) => history.Plugin === prefix && index < 50) // Filter history for the specific plugin
.map(history => colDefinitions.map(colDef => history[colDef.column] || '')); // Map to the defined columns
}
function generateTabNavigation(prefix, objectCount, eventCount, historyCount) {
// Create navigation tabs for Objects, Unprocessed Events, and History
return `
<div class="nav-tabs-custom" style="margin-bottom: 0px">
<ul class="nav nav-tabs">
<li class="active">
<a href="#objectsTarget_${prefix}" data-toggle="tab"><i class="fa fa-cube"></i> ${getString('Plugins_Objects')} (${objectCount})</a>
</li>
<li>
<a href="#eventsTarget_${prefix}" data-toggle="tab"><i class="fa fa-bolt"></i> ${getString('Plugins_Unprocessed_Events')} (${eventCount})</a>
</li>
<li>
<a href="#historyTarget_${prefix}" data-toggle="tab"><i class="fa fa-clock"></i> ${getString('Plugins_History')} (${historyCount})</a>
</li>
</ul>
</div>
`;
}
function generateDataTable(prefix, tableType, data, colDefinitions) {
// Generate HTML for a DataTable and associated buttons for a given table type
const headersHtml = colDefinitions.map(colDef => `<th class="${colDef.css_classes}">${getString(`${prefix}_${colDef.column}_name`)}</th>`).join('');
return `
<div id="${tableType.toLowerCase()}Target_${prefix}" class="tab-pane ${tableType == "Objects" ? "active":""}">
<table id="${tableType.toLowerCase()}Table_${prefix}" class="display table table-striped table-stretched" data-my-dbtable="Plugins_${tableType}">
<thead><tr>${headersHtml}</tr></thead>
</table>
<div class="plugin-obj-purge">
<button class="btn btn-primary" onclick="purgeAll('${prefix}', 'Plugins_${tableType}' )"><?= lang('Plugins_DeleteAll');?></button>
${tableType !== 'Events' ? `<button class="btn btn-danger" onclick="deleteListed('${prefix}', 'Plugins_${tableType}' )"><?= lang('Plugins_Obj_DeleteListed');?></button>` : ''}
</div>
</div>
`;
}
function initializeDataTables(prefix, objectData, eventData, historyData, colDefinitions) {
// Common settings for DataTables initialization
const commonDataTableSettings = {
orderable: false, // Disable ordering
createdRow: function(row, data) {
$(row).attr('data-my-index', data[0]); // Set data attribute for indexing
}
};
// Initialize DataTable for Objects
$(`#objectsTable_${prefix}`).DataTable({
data: objectData,
columns: colDefinitions.map(colDef => ({ title: getString(`${prefix}_${colDef.column}_name`) })), // Column titles
...commonDataTableSettings // Spread common settings
});
// Initialize DataTable for Unprocessed Events
$(`#eventsTable_${prefix}`).DataTable({
data: eventData,
columns: colDefinitions.map(colDef => ({ title: getString(`${prefix}_${colDef.column}_name`) })), // Column titles
...commonDataTableSettings // Spread common settings
});
// Initialize DataTable for History
$(`#historyTable_${prefix}`).DataTable({
data: historyData,
columns: colDefinitions.map(colDef => ({ title: getString(`${prefix}_${colDef.column}_name`) })), // Column titles
...commonDataTableSettings // Spread common settings
});
}
// --------------------------------------------------------
// Filter method that determines if an entry should be shown
function shouldBeShown(entry, pluginObj)
{
if (pluginObj.hasOwnProperty('data_filters')) {
let dataFilters = pluginObj.data_filters;
{
if (pluginObj.hasOwnProperty('data_filters')) {
let dataFilters = pluginObj.data_filters;
// Loop through 'data_filters' array and appply filters on individual plugin entries
for (let i = 0; i < dataFilters.length; i++) {
compare_field_id = dataFilters[i].compare_field_id;
compare_column = dataFilters[i].compare_column;
compare_operator = dataFilters[i].compare_operator;
compare_js_template = dataFilters[i].compare_js_template;
compare_use_quotes = dataFilters[i].compare_use_quotes;
compare_field_id_value = $(`#${compare_field_id}`).val();
// Loop through 'data_filters' array and appply filters on individual plugin entries
for (let i = 0; i < dataFilters.length; i++) {
compare_field_id = dataFilters[i].compare_field_id;
compare_column = dataFilters[i].compare_column;
compare_operator = dataFilters[i].compare_operator;
compare_js_template = dataFilters[i].compare_js_template;
compare_use_quotes = dataFilters[i].compare_use_quotes;
compare_field_id_value = $(`#${compare_field_id}`).val();
// apply filter i sthe filter field has a valid value
if(compare_field_id_value != undefined && compare_field_id_value != '--')
{
// valid value
// resolve the left and right part of the comparison
let left = compare_js_template.replace('{value}', `${compare_field_id_value}`)
let right = compare_js_template.replace('{value}', `${entry[compare_column]}`)
// apply filter i sthe filter field has a valid value
if(compare_field_id_value != undefined && compare_field_id_value != '--')
{
// valid value
// resolve the left and right part of the comparison
let left = compare_js_template.replace('{value}', `${compare_field_id_value}`)
let right = compare_js_template.replace('{value}', `${entry[compare_column]}`)
// include wrapper quotes if specified
compare_use_quotes ? quotes = '"' : quotes = ''
// include wrapper quotes if specified
compare_use_quotes ? quotes = '"' : quotes = ''
result = eval(
quotes + `${eval(left)}` + quotes +
` ${compare_operator} ` +
quotes + `${eval(right)}` + quotes
);
result = eval(
quotes + `${eval(left)}` + quotes +
` ${compare_operator} ` +
quotes + `${eval(right)}` + quotes
);
return result;
}
}
return result;
}
}
return true;
}
return true;
}
// --------------------------------------------------------
// Data cleanup/purge functionality
plugPrefix = ''
dbTable = ''
dbTable = ''
function purgeAll(callback) {
plugPrefix = arguments[0]; // plugin prefix
dbTable = arguments[1]; // DB table
dbTable = arguments[1]; // DB table
// Ask
showModalWarning('<?= lang('Gen_Purge');?>' + ' ' + plugPrefix + ' ' + dbTable , '<?= lang('Gen_AreYouSure');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', "purgeAllExecute");
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', "purgeAllExecute");
}
// --------------------------------------------------------
function purgeAllExecute() {
$.ajax({
method: "POST",
url: "php/server/dbHelper.php",
data: { action: "delete", dbtable: dbTable, columnName: 'Plugin', id:plugPrefix },
success: function(data, textStatus) {
showModalOk ('Result', data );
}
})
$.ajax({
method: "POST",
url: "php/server/dbHelper.php",
data: { action: "delete", dbtable: dbTable, columnName: 'Plugin', id:plugPrefix },
success: function(data, textStatus) {
showModalOk ('Result', data );
}
})
}
// --------------------------------------------------------
function deleteListed(plugPrefix, dbTable) {
idArr = $(`#${plugPrefix} table[data-my-dbtable="${dbTable}"] tr[data-my-index]`).map(function(){return $(this).attr("data-my-index");}).get();
idArr = $(`#${plugPrefix} table[data-my-dbtable="${dbTable}"] tr[data-my-index]`).map(function(){return $(this).attr("data-my-index");}).get();
console.log(idArr);
console.log(idArr);
$.ajax({
method: "POST",
url: "php/server/dbHelper.php",
data: { action: "delete", dbtable: dbTable, columnName: 'Index', id:idArr.toString() },
success: function(data, textStatus) {
updateApi("plugins_objects")
showModalOk ('Result', data );
}
})
$.ajax({
method: "POST",
url: "php/server/dbHelper.php",
data: { action: "delete", dbtable: dbTable, columnName: 'Index', id:idArr.toString() },
success: function(data, textStatus) {
updateApi("plugins_objects")
showModalOk ('Result', data );
}
})
}

View File

@@ -170,6 +170,17 @@
<!-- box-header -->
<div class="box-header">
<h3 id="tableDevicesTitle" class="box-title text-gray">Devices</h3>
<div class="presencenceKey">
<span class="question" title="<?= lang('Presence_Key_OnlineNow_desc');?>">
<div class="presenceOnlineNow presenceKeyBoxes"></div> <?= lang('Presence_Key_OnlineNow');?>
</span>
<span class="question" title="<?= lang('Presence_Key_OnlinePast_desc');?>">
<div class="presenceOnlinePast presenceKeyBoxes"></div> <?= lang('Presence_Key_OnlinePast');?>
</span>
<span class="question" title="<?= lang('Presence_Key_OnlinePastMiss_desc');?>">
<div class="presenceOnlinePastMiss presenceKeyBoxes"></div> <?= lang('Presence_Key_OnlinePastMiss');?>
</span>
</div>
</div>
<!-- box-body -->
@@ -216,8 +227,13 @@
<!-- Dark-Mode Patch -->
<?php
if ($ENABLED_DARKMODE === True) {
echo '<link rel="stylesheet" href="css/dark-patch-cal.css">';
switch ($UI_THEME) {
case "Dark":
echo '<link rel="stylesheet" href="css/dark-patch-cal.css">';
break;
case "System":
echo '<link rel="stylesheet" href="css/system-dark-patch-cal.css">';
break;
}
?>

View File

@@ -13,7 +13,7 @@
<table align=center width=100% cellpadding=0 cellspacing=0 style="border-radius: 5px;">
<tr>
<td bgcolor=#3c8dbc align=center style="padding: 20px 10px 10px 10px; font-size: 30px; font-weight: bold; color:#ffffff; border-top-right-radius: 5px; border-top-left-radius: 5px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
Net Alert<sup>x</sup>
Net<b>Alert</b><sup>x</sup>
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" height="24pt" viewBox="0 0 30 30" width="24pt">
<g fill="#000000" stroke="none" transform="translate(0.000000,30) scale(0.02,-0.02)">
<path d="M605 1473 c-16 -3 -34 -9 -39 -14 -6 -5 -20 -9 -33 -9 -13 0 -23 -5 -23 -10 0 -5 -3 -9 -7 -8 -14 4 -53 -13 -53 -22 0 -5 -6 -7 -14 -4 -7 3 -27 -6 -44 -20 -16 -15 -34 -26 -39 -26 -6 0 -18 -10 -29 -21 -10 -12 -29 -25 -42 -30 -13 -5 -21 -13 -18 -18 3 -5 -4 -11 -15 -14 -12 -3 -18 -10 -15 -15 3 -5 -6 -14 -19 -20 -14 -7 -25 -18 -25 -27 0 -8 -5 -15 -12 -15 -9 0 -9 -3 -1 -11 9 -9 29 4 80 51 37 34 87 75 110 90 44 30 167 90 184 90 18 0 89 40 89 50 0 6 -1 9 -2 9 -2 -1 -16 -4 -33 -6z"></path>

View File

@@ -22,7 +22,7 @@
<table align=center width=100% cellpadding=0 cellspacing=0 style="border-radius: 5px;">
<tr>
<td bgcolor=#3c8dbc align=center style="padding: 20px 10px 10px 10px; font-size: 30px; font-weight: bold; color:#ffffff; border-top-right-radius: 5px; border-top-left-radius: 5px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
Net Alert<sup>x</sup>
Net<b>Alert</b><sup>x</sup>
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" height="24pt" viewBox="0 0 30 30" width="24pt">
<g fill="#000000" stroke="none" transform="translate(0.000000,30) scale(0.02,-0.02)">
<path d="M605 1473 c-16 -3 -34 -9 -39 -14 -6 -5 -20 -9 -33 -9 -13 0 -23 -5 -23 -10 0 -5 -3 -9 -7 -8 -14 4 -53 -13 -53 -22 0 -5 -6 -7 -14 -4 -7 3 -27 -6 -44 -20 -16 -15 -34 -26 -39 -26 -6 0 -18 -10 -29 -21 -10 -12 -29 -25 -42 -30 -13 -5 -21 -13 -18 -18 3 -5 -4 -11 -15 -14 -12 -3 -18 -10 -15 -15 3 -5 -6 -14 -19 -20 -14 -7 -25 -18 -25 -27 0 -8 -5 -15 -12 -15 -9 0 -9 -3 -1 -11 9 -9 29 4 80 51 37 34 87 75 110 90 44 30 167 90 184 90 18 0 89 40 89 50 0 6 -1 9 -2 9 -2 -1 -16 -4 -33 -6z"></path>

View File

@@ -22,7 +22,7 @@
<table align=center width=100% cellpadding=0 cellspacing=0 style="border-radius: 5px;">
<tr>
<td bgcolor=#3c8dbc align=center style="padding: 20px 10px 10px 10px; font-size: 30px; font-weight: bold; color:#ffffff; border-top-right-radius: 5px; border-top-left-radius: 5px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
Net Alert<sup>x</sup>
Net<b>Alert</b><sup>x</sup>
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" height="24pt" viewBox="0 0 30 30" width="24pt">
<g fill="#000000" stroke="none" transform="translate(0.000000,30) scale(0.02,-0.02)">
<path d="M605 1473 c-16 -3 -34 -9 -39 -14 -6 -5 -20 -9 -33 -9 -13 0 -23 -5 -23 -10 0 -5 -3 -9 -7 -8 -14 4 -53 -13 -53 -22 0 -5 -6 -7 -14 -4 -7 3 -27 -6 -44 -20 -16 -15 -34 -26 -39 -26 -6 0 -18 -10 -29 -21 -10 -12 -29 -25 -42 -30 -13 -5 -21 -13 -18 -18 3 -5 -4 -11 -15 -14 -12 -3 -18 -10 -15 -15 3 -5 -6 -14 -19 -20 -14 -7 -25 -18 -25 -27 0 -8 -5 -15 -12 -15 -9 0 -9 -3 -1 -11 9 -9 29 4 80 51 37 34 87 75 110 90 44 30 167 90 184 90 18 0 89 40 89 50 0 6 -1 9 -2 9 -2 -1 -16 -4 -33 -6z"></path>

View File

@@ -145,10 +145,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
<section class=" settings-sticky-bottom-section col-sm-10 col-xs-12">
<div class="col-xs-8 settingsSearchWrap form-group has-success bg-white color-palette ">
<div class ="col-xs-8">
<i class="fa-solid fa-filter"></i> <?= lang("Gen_Filter");?>
</div>
<div class="col-xs-8 settingsSearchWrap has-success bg-white color-palette ">
<div class ="col-xs-12">
<input type="text" id="settingsSearch" class="form-control input-xs col-xs-12" placeholder="Filter Settings...">
@@ -471,6 +468,8 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
// Parse the setType JSON string into an object
let inputHtml = '';
console.log(setType);
const setTypeObject = JSON.parse(setType.replace(/'/g, '"'));
const dataType = setTypeObject.dataType;
@@ -798,6 +797,8 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
// Reloads the current page
// setTimeout("clearCache()", 5000);
write_notification(`[Settings] Settings saved by the user`, 'info')
clearCache()
} else{
// something went wrong

View File

@@ -127,7 +127,7 @@ require 'php/templates/header.php';
"render": function(data, type, row) {
if (data.includes("Report:")) {
var guid = data.split(":")[1].trim();
return `<a href="/report.php?guid=${guid}">Go to Report</a>`;
return `<a href="report.php?guid=${guid}">Go to Report</a>`;
} else {
return data;
}

View File

@@ -213,6 +213,17 @@ class DB():
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_SyncHubNodeName" TEXT
""")
# dev_SourcePlugin column
dev_SourcePlugin_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SourcePlugin'
""").fetchone()[0] == 0
if dev_SourcePlugin_missing :
mylog('verbose', ["[upgradeDB] Adding dev_SourcePlugin to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_SourcePlugin" TEXT
""")
# -------------------------------------------------------------------------
# Settings table setup
@@ -538,7 +549,8 @@ class DB():
cur_SSID STRING(250),
cur_NetworkNodeMAC STRING(250),
cur_PORT STRING(250),
cur_Type STRING(250)
cur_Type STRING(250),
UNIQUE(cur_MAC)
);
""")
@@ -566,9 +578,38 @@ class DB():
WHERE e.row_num = 1;
""")
self.commitDB()
# handling the Convert_Events_to_Sessions / Sessions screens
self.sql.execute("""DROP VIEW IF EXISTS Convert_Events_to_Sessions;""")
self.sql.execute("""CREATE VIEW Convert_Events_to_Sessions AS SELECT EVE1.eve_MAC,
EVE1.eve_IP,
EVE1.eve_EventType AS eve_EventTypeConnection,
EVE1.eve_DateTime AS eve_DateTimeConnection,
CASE WHEN EVE2.eve_EventType IN ('Disconnected', 'Device Down') OR
EVE2.eve_EventType IS NULL THEN EVE2.eve_EventType ELSE '<missing event>' END AS eve_EventTypeDisconnection,
CASE WHEN EVE2.eve_EventType IN ('Disconnected', 'Device Down') THEN EVE2.eve_DateTime ELSE NULL END AS eve_DateTimeDisconnection,
CASE WHEN EVE2.eve_EventType IS NULL THEN 1 ELSE 0 END AS eve_StillConnected,
EVE1.eve_AdditionalInfo
FROM Events AS EVE1
LEFT JOIN
Events AS EVE2 ON EVE1.eve_PairEventRowID = EVE2.RowID
WHERE EVE1.eve_EventType IN ('New Device', 'Connected','Down Reconnected')
UNION
SELECT eve_MAC,
eve_IP,
'<missing event>' AS eve_EventTypeConnection,
NULL AS eve_DateTimeConnection,
eve_EventType AS eve_EventTypeDisconnection,
eve_DateTime AS eve_DateTimeDisconnection,
0 AS eve_StillConnected,
eve_AdditionalInfo
FROM Events AS EVE1
WHERE (eve_EventType = 'Device Down' OR
eve_EventType = 'Disconnected') AND
EVE1.eve_PairEventRowID IS NULL;
""")
self.commitDB()
# Init the AppEvent database table
AppEvent_obj(self)

View File

@@ -93,10 +93,7 @@ def save_scanned_devices (db):
# Proceed if variable contains valid MAC
if check_mac_or_internet(local_mac):
# Check if local mac has been detected with other methods
sql.execute (f"SELECT COUNT(*) FROM CurrentScan WHERE cur_MAC = '{local_mac}'")
if sql.fetchone()[0] == 0 :
sql.execute (f"""INSERT INTO CurrentScan (cur_MAC, cur_IP, cur_Vendor, cur_ScanMethod) VALUES ( '{local_mac}', '{local_ip}', Null, 'local_MAC') """)
sql.execute (f"""INSERT OR IGNORE INTO CurrentScan (cur_MAC, cur_IP, cur_Vendor, cur_ScanMethod) VALUES ( '{local_mac}', '{local_ip}', Null, 'local_MAC') """)
#-------------------------------------------------------------------------------
def print_scan_stats(db):
@@ -229,7 +226,7 @@ def create_new_devices (db):
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Location'))}'"""
# Fetch data from CurrentScan skipping ignored devices by IP and MAC
query = f"""SELECT cur_MAC, cur_Name, cur_Vendor, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type
query = f"""SELECT cur_MAC, cur_Name, cur_Vendor, cur_ScanMethod, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type
FROM CurrentScan """
@@ -237,7 +234,7 @@ def create_new_devices (db):
current_scan_data = sql.execute(query).fetchall()
for row in current_scan_data:
cur_MAC, cur_Name, cur_Vendor, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type = row
cur_MAC, cur_Name, cur_Vendor, cur_ScanMethod, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type = row
# Handle NoneType
cur_Name = cur_Name.strip() if cur_Name else '(unknown)'
@@ -262,6 +259,7 @@ def create_new_devices (db):
dev_NetworkSite,
dev_SSID,
dev_DeviceType,
dev_SourcePlugin,
{newDevColumns}
)
VALUES
@@ -279,6 +277,7 @@ def create_new_devices (db):
'{sanitize_SQL_input(cur_NetworkSite)}',
'{sanitize_SQL_input(cur_SSID)}',
'{sanitize_SQL_input(cur_Type)}',
'{sanitize_SQL_input(cur_ScanMethod)}',
{newDevDefaults}
)"""
@@ -459,7 +458,7 @@ def update_devices_data_from_scan (db):
default_icon = get_setting_value('NEWDEV_dev_Icon')
for device in sql.execute (query) :
# Conditional logic for dev_Icon guessing
# Conditional logic for dev_Icon guessing
dev_Icon = guess_icon(device['dev_Vendor'], device['dev_MAC'], device['dev_LastIP'], device['dev_Name'], default_icon)
recordsToUpdate.append ([dev_Icon, device['dev_MAC']])
@@ -677,7 +676,10 @@ icons = {
#-------------------------------------------------------------------------------
# Guess device icon
def guess_icon(vendor, mac, ip, name, default):
def guess_icon(vendor, mac, ip, name, default):
mylog('debug', [f"[guess_icon] Guessing icon for (vendor|mac|ip|name): ('{vendor}'|'{mac}'|{ip}|{name})"])
result = default
mac = mac.upper()
vendor = vendor.lower() if vendor else "unknown"
@@ -706,7 +708,7 @@ def guess_icon(vendor, mac, ip, name, default):
result = icons.get("microchip")
# Guess icon based on MAC address patterns
elif mac == "INTERNET": # Apple
elif mac == "INTERNET":
result = icons.get("globe")
elif mac.startswith("00:1A:79"): # Apple
result = icons.get("apple")
@@ -764,4 +766,4 @@ def guess_type(vendor, mac, ip, name, default):
result = "Router"
return result

View File

@@ -48,6 +48,7 @@ def ccd(key, default, config_dir, name, inputtype, options, group, events=None,
# Single quotes might break SQL queries, replacing them
if inputtype == 'text':
result = result.replace('\'', "{s-quote}")
# Create the tuples
sql_safe_tuple = (key, name, desc, str(inputtype), options, regex, str(result), group, str(events), overriddenByEnv)
@@ -145,6 +146,7 @@ def importConfigs (db, all_plugins):
conf.REPORT_DASHBOARD_URL = ccd('REPORT_DASHBOARD_URL', 'http://netalertx/' , c_d, 'NetAlertX URL', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General')
conf.DAYS_TO_KEEP_EVENTS = ccd('DAYS_TO_KEEP_EVENTS', 90 , c_d, 'Delete events days', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', '[]', 'General')
conf.HRS_TO_KEEP_NEWDEV = ccd('HRS_TO_KEEP_NEWDEV', 0 , c_d, 'Keep new devices for', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
conf.HRS_TO_KEEP_OFFDEV = ccd('HRS_TO_KEEP_OFFDEV', 0 , c_d, 'Keep offline devices for', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
conf.CLEAR_NEW_FLAG = ccd('CLEAR_NEW_FLAG', 0 , c_d, 'Clear new flag', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
conf.API_CUSTOM_SQL = ccd('API_CUSTOM_SQL', 'SELECT * FROM Devices WHERE dev_PresentLastScan = 0' , c_d, 'Custom endpoint', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General')
conf.VERSION = ccd('VERSION', '' , c_d, 'Version', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{ "readonly": "true" }] ,"transformers": []}]}', '', 'General')
@@ -295,10 +297,10 @@ def importConfigs (db, all_plugins):
mylog('none', ['[Config] Plugins to load: ', loaded_plugins_prefixes])
conf.plugins_once_run = False
# -----------------
# Plugins END
# -----------------
# HANDLE APP_CONF_OVERRIDE via app_conf_override.json
# Assuming fullConfFolder is defined elsewhere
app_conf_override_path = fullConfFolder + '/app_conf_override.json'
@@ -310,23 +312,24 @@ def importConfigs (db, all_plugins):
# Loop through settings_override dictionary
for setting_name, value in settings_override.items():
# Ensure the value is treated as a string and passed directly
if isinstance(value, str):
# Log the value being passed
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
mylog('debug', [f"[Config] Setting override {setting_name} with value: {value}"])
ccd(setting_name, value, c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True, 1)
else:
# Convert to string and log
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
mylog('debug', [f"[Config] Setting override {setting_name} with value: {str(value)}"])
ccd(setting_name, str(value), c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True, 1)
if isinstance(value, str) == False:
value = str(value)
# Log the value being passed
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
mylog('debug', [f"[Config] Setting override {setting_name} with value: {value}"])
ccd(setting_name, value, c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True, 1)
except json.JSONDecodeError:
mylog('none', [f"[Config] [ERROR] Setting override decoding JSON from {app_conf_override_path}"])
else:
mylog('debug', [f"[Config] File {app_conf_override_path} does not exist."])
# -----------------
# HANDLE APP was upgraded message - clear cache
# Check if app was upgraded
with open(applicationPath + '/front/buildtimestamp.txt', 'r') as f:
@@ -346,6 +349,9 @@ def importConfigs (db, all_plugins):
write_notification(f'[Upgrade] : App upgraded 🚀 Please clear the cache: <ol> <li>Click OK below</li> <li>Clear the browser cache (shift + browser refresh button)</li> <li> Clear app cache with the 🔄 (reload) button in the header</li><li>Go to Settings and click Save</li> </ol> Check out new features and what has changed in the <a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank">📓 release notes</a>.', 'interrupt', timeNowTZ())
# -----------------
# Initialization finished, update DB and API endpoints
# Insert settings into the DB
sql.execute ("DELETE FROM Settings")
# mylog('debug', [f"[Config] conf.mySettingsSQLsafe : '{conf.mySettingsSQLsafe}'"])
@@ -364,8 +370,12 @@ def importConfigs (db, all_plugins):
conf.lastImportedConfFile = os.path.getmtime(config_file)
updateState("Config imported", conf.lastImportedConfFile, conf.lastImportedConfFile, False)
mylog('minimal', '[Config] Imported new config')
msg = '[Config] Imported new settings config'
mylog('minimal', msg)
# front end app log loggging
write_notification(msg, 'info', timeNowTZ())
return all_plugins

View File

@@ -206,10 +206,9 @@ def insert_events (db):
END,
'',
1
FROM LatestEventsPerMAC AS d
JOIN CurrentScan AS c ON d.dev_MAC = c.cur_MAC
LEFT JOIN LatestEventsPerMAC AS last_event ON d.dev_MAC = last_event.eve_MAC
WHERE d.dev_PresentLastScan = 0
FROM CurrentScan AS c
LEFT JOIN LatestEventsPerMAC AS last_event ON c.cur_MAC = last_event.eve_MAC
WHERE last_event.dev_PresentLastScan = 0 OR last_event.eve_MAC IS NULL
""")
# Check disconnections

View File

@@ -747,7 +747,7 @@ def process_plugin_events(db, plugin, pluginsState, plugEventsArr):
sqlParams.append(tuple(tmpList))
# Generate the SQL INSERT query using the collected information.
q = f'INSERT into {dbTable} ({columnsStr}) VALUES ({valuesStr})'
q = f'INSERT OR IGNORE INTO {dbTable} ({columnsStr}) VALUES ({valuesStr})'
# Log a debug message showing the generated SQL query for mapping.
mylog('debug', ['[Plugins] SQL query for mapping: ', q])

View File

@@ -46,7 +46,7 @@ def get_notifications (db):
# Disable reporting on events for devices where reporting is disabled based on the MAC address
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
WHERE eve_PendingAlertEmail = 1 AND eve_EventType not in ('Device Down', 'Down Reconnected') AND eve_MAC IN
WHERE eve_PendingAlertEmail = 1 AND eve_EventType not in ('Device Down', 'Down Reconnected', 'New Device' ) AND eve_MAC IN
(
SELECT dev_MAC FROM Devices WHERE dev_AlertEvents = 0
)""")