Compare commits

..

107 Commits

Author SHA1 Message Date
Hosted Weblate
4453ea59af Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-18 10:29:26 +02:00
Joe Erd
31ecd6ac8c Translated using Weblate (German)
Currently translated at 89.8% (621 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/de/
2024-07-18 10:29:24 +02:00
Anonymous
8e8493f638 Translated using Weblate (Polish)
Currently translated at 98.6% (682 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pl/
2024-07-18 10:29:17 +02:00
Anonymous
adf24cebb6 Translated using Weblate (Italian)
Currently translated at 99.2% (686 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2024-07-18 10:29:17 +02:00
Anonymous
5ac609e68e Translated using Weblate (Russian)
Currently translated at 99.1% (685 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ru/
2024-07-18 10:29:17 +02:00
Joe Erd
7f0debb04a Translated using Weblate (Norwegian Bokmål)
Currently translated at 97.5% (674 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/nb_NO/
2024-07-18 10:29:17 +02:00
Anonymous
a51571bd70 Translated using Weblate (Spanish)
Currently translated at 99.2% (686 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/es/
2024-07-18 10:29:17 +02:00
Joe Erd
3af1f67956 Translated using Weblate (German)
Currently translated at 89.7% (620 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/de/
2024-07-18 10:29:17 +02:00
Joe Erd
9143b90bdf Translated using Weblate (English (United States))
Currently translated at 100.0% (691 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/en_US/
2024-07-18 10:29:16 +02:00
jokob-sk
a892b8b5fb 📚Docs 2024-07-18 18:10:36 +10:00
jokob-sk
db621a110e PasteCSV fix + code cleanup 2024-07-18 17:53:48 +10:00
jokob-sk
4a3598e840 Merge pull request #737 from FlyingToto/main 2024-07-18 17:25:41 +10:00
Hosted Weblate
a19e268ea7 Merge branch 'origin/main' into Weblate. 2024-07-18 06:09:15 +02:00
FlyingToto
e9319cace3 Translated using Weblate (French)
Currently translated at 47.6% (328 of 688 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2024-07-18 04:09:11 +00:00
ffsb
74b2432729 removed gitguardian secrets 2024-07-17 21:31:10 -04:00
ffsb
d65b07685f ready for pr 2024-07-17 18:28:21 -04:00
ffsb
a8dc4099e8 0.6 works but with port=null and ssid=null 2024-07-17 17:58:43 -04:00
github-actions[bot]
9c368982ce [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-17 11:53:41 +00:00
FlyingToto
662394618b Merge branch 'jokob-sk:main' into main 2024-07-16 17:57:44 -04:00
ffsb
147166e46e 0.4 saving api to files 2024-07-16 17:47:34 -04:00
github-actions[bot]
fb8a7432cd [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-16 11:53:35 +00:00
jokob-sk
fa00fa3004 Update i-have-an-issue.yml 2024-07-16 20:31:48 +10:00
jokob-sk
294cfe80f2 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-07-16 20:27:39 +10:00
jokob-sk
b45e82b2a0 NEWDEV_LESS_NAME_CLEANUP + Internet ParentNode fix + 📚Docs 2024-07-16 20:27:15 +10:00
ffsb
bf2ce3262d 0.2 added retries 2024-07-15 16:30:24 -04:00
github-actions[bot]
f468903b00 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-15 11:53:43 +00:00
ffsb
d706a156c0 after fixing order of execution 2024-07-14 09:46:14 -04:00
ffsb
71c631d784 after fixing the order of execution. 2024-07-14 09:45:25 -04:00
github-actions[bot]
460d2f4658 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-14 11:53:49 +00:00
jokob-sk
f502d93854 📩Import Pasted CSV + 📚Docs 2024-07-14 21:37:11 +10:00
jokob-sk
68fb1b7cbb 🔌Plugin execution order 2024-07-14 20:48:10 +10:00
jokob-sk
942908d074 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-14 11:04:31 +10:00
jokob-sk
1aeed6b433 More logging od CurrentScan/Device tables + cleanup 2024-07-14 10:54:48 +10:00
github-actions[bot]
698876065c [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-13 11:53:54 +00:00
jokob-sk
7e554242c2 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-12 21:59:52 +10:00
jokob-sk
129ae92141 Italian translation fix 2024-07-12 21:59:34 +10:00
github-actions[bot]
25647023d0 [🤖Automation] Update README with sponsors information 2024-07-12 11:53:33 +00:00
Hosted Weblate
fe752192e1 Merge branch 'origin/main' into Weblate. 2024-07-12 11:09:22 +02:00
Safeguard
0ea0cd5ee0 Translated using Weblate (Russian)
Currently translated at 99.8% (687 of 688 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ru/
2024-07-12 11:09:16 +02:00
gallegonovato
bac78e926d Translated using Weblate (Spanish)
Currently translated at 100.0% (688 of 688 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/es/
2024-07-12 11:09:15 +02:00
jokob-sk
d6125ef4e2 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-11 22:35:21 +10:00
jokob-sk
bf90ee81c7 Name cleanup + nbtscan improvements 2024-07-11 22:35:04 +10:00
github-actions[bot]
ae74f1f538 [🤖Automation] Update README with sponsors information 2024-07-11 11:53:44 +00:00
jokob-sk
3ae0daad3c 🌳Network tree improvements 2024-07-11 19:28:50 +10:00
jokob-sk
8e7e0afb1e 🔌NBTSCAN plugin #693
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-11 15:56:29 +10:00
jokob-sk
d7d7306a85 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-07-11 15:31:09 +10:00
jokob-sk
4b26044427 🔌NBTSCAN plugin #693 2024-07-11 15:30:18 +10:00
jokob-sk
0a9ae5e9d9 🔌NBTSCAN plugin #693 2024-07-11 15:27:37 +10:00
github-actions[bot]
ade1d9997f [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-10 11:53:47 +00:00
jokob-sk
578b992c5a ⚙ Settings + 🔧 Maintenance improvements 2024-07-10 17:59:51 +10:00
jokob-sk
52b293a662 🔷 regex fix
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-10 12:48:05 +10:00
jokob-sk
bd52536107 ⚙ transformers fix 2024-07-10 12:22:35 +10:00
jokob-sk
9f44c0de01 ⚙ NAME_CLEANUP_REGEX #735 #728 2024-07-10 11:27:21 +10:00
jokob-sk
41b5de9292 ⚙ NAME_CLEANUP_REGEX test
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-09 23:30:09 +10:00
jokob-sk
95d5dbcf68 🔌 MQTT - do not send UNKNOWN + expose DEVICES_SQL 2024-07-09 23:09:42 +10:00
jokob-sk
0eff7cc3f1 📚 Readme 2024-07-09 22:10:36 +10:00
jokob-sk
f31c55d6c4 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-07-09 21:55:30 +10:00
jokob-sk
6049ba00c7 ⚙ Settings rework 3 - json linter 2024-07-09 21:54:55 +10:00
github-actions[bot]
8e4bd246df [🤖Automation] Update README with sponsors information 2024-07-09 11:53:46 +00:00
jokob-sk
07164429d5 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-07-09 20:28:09 +10:00
jokob-sk
cac33fde2b ⚙ Settings rework 2 2024-07-09 20:27:48 +10:00
github-actions[bot]
5f71e9fc92 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-08 11:53:49 +00:00
jokob-sk
d834708220 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks failed
docker / docker_dev (push) Has been cancelled
2024-07-07 23:11:45 +10:00
jokob-sk
6ea3d14480 ⚙ Settings rework 2024-07-07 23:11:30 +10:00
github-actions[bot]
0a11ec5379 [🤖Automation] Update README with sponsors information 2024-07-07 11:54:02 +00:00
github-actions[bot]
b65c8022d6 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-06 11:53:46 +00:00
jokob-sk
55440090fe 🔌 Omada work #708
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-06 10:22:50 +10:00
jokob-sk
75bcf42225 🔌 Omada work #708 2024-07-06 10:02:33 +10:00
jokob-sk
6db9cd2f61 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-05 23:54:22 +10:00
jokob-sk
eff98257d6 🔌 Omada work #708 2024-07-05 23:53:55 +10:00
github-actions[bot]
2f97c8fd55 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-05 11:53:39 +00:00
jokob-sk
f03f3f33b1 🐛 PHOLUS, NSLOOKUP scans could not be disabled #726 2024-07-05 20:42:40 +10:00
jokob-sk
457059cae8 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-07-05 20:33:13 +10:00
jokob-sk
5afc82f33e 🐛 ARPSCAN & INTNT scans could not be disabled #726 2024-07-05 20:32:54 +10:00
github-actions[bot]
06e24b4585 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-04 11:53:45 +00:00
jokob-sk
482902f6e4 🔌 SNMP work #718
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-04 16:55:57 +10:00
jokob-sk
6e6b99fa46 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-04 12:21:55 +10:00
jokob-sk
30f4cba3e5 🔌 Omada work #708 2024-07-04 12:21:37 +10:00
github-actions[bot]
e9c0bf151f [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-03 11:53:51 +00:00
jokob-sk
70d117cb6d 📋Copy from device #721
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-03 09:07:33 +10:00
jokob-sk
624e30842a Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-07-03 08:26:38 +10:00
jokob-sk
7c22f209d1 getValueWithMac 2024-07-03 08:26:00 +10:00
github-actions[bot]
760a3c981f [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-02 11:53:40 +00:00
jokob-sk
b86ab576bd SNMP enhancements #718
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-02 19:39:33 +10:00
jokob-sk
1b6e806830 SNMP enhancements #718 2024-07-02 19:17:52 +10:00
github-actions[bot]
612ff7c293 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-01 11:53:57 +00:00
jokob-sk
74fc7ecdbf Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-07-01 21:08:02 +10:00
jokob-sk
b6451e6e76 ▶ Ad-hoc event bug fix 2024-07-01 21:07:51 +10:00
Hosted Weblate
55e7bed5a8 Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-07-01 12:10:48 +02:00
TheOrchestratorOfChaos
10b6c9836b Translated using Weblate (Polish)
Currently translated at 99.4% (684 of 688 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pl/
2024-07-01 12:10:30 +02:00
Massimo Pissarello
158ff2453b Translated using Weblate (Italian)
Currently translated at 100.0% (688 of 688 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2024-07-01 12:10:30 +02:00
gallegonovato
6b92d9f862 Translated using Weblate (Spanish)
Currently translated at 99.7% (686 of 688 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/es/
2024-07-01 12:10:30 +02:00
github-actions[bot]
2fb6e8fb12 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-06-30 11:53:49 +00:00
jokob-sk
15d16dcd81 📚Docs 2024-06-30 21:37:14 +10:00
jokob-sk
28a5b6af2a 📚Docs 2024-06-30 21:24:31 +10:00
jokob-sk
651b346a27 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-06-30 21:18:27 +10:00
jokob-sk
df90060adf 💻 Plugin Boilerplate update 2024-06-30 21:17:52 +10:00
Hosted Weblate
d3228b2d55 Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-06-30 06:09:38 +02:00
Massimo Pissarello
83edfa66d2 Translated using Weblate (Italian)
Currently translated at 100.0% (685 of 685 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2024-06-30 06:09:36 +02:00
jokob-sk
40c5be3758 📚Docs + Omada work #708 2024-06-30 12:16:43 +10:00
jokob-sk
e2d0914334 📃More logging + updated default plugins to load
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-06-29 23:42:51 +10:00
jokob-sk
0b5cf66451 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-06-29 22:54:58 +10:00
jokob-sk
974427f392 📚Docs + Removing +TZ from dev_LastConnection 2024-06-29 22:54:34 +10:00
github-actions[bot]
9d0e6a5a5d [🤖Automation] Update README with sponsors information 2024-06-29 11:53:55 +00:00
jokob-sk
08b163ebe4 🛠Maintenance refactor
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-06-29 14:39:12 +10:00
jokob-sk
709408ca2a Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-06-29 10:28:23 +10:00
jokob-sk
eae93ef6b2 📚Docs + Omada work #708 2024-06-29 10:28:14 +10:00
115 changed files with 6793 additions and 1932 deletions

View File

@@ -1,5 +1,5 @@
name: Bug Report
description: 'When submitting an issue enable debug and have a look at the docs.'
description: 'When submitting an issue enable LOG_LEVEL="trace" and have a look at the docs.'
labels: ['bug 🐛']
body:
- type: checkboxes
@@ -64,7 +64,7 @@ body:
***Generally speaking, all bug reports should have logs provided.***
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
Additionally, any additional info? Screenshots? References? Anything that will give us more context about the issue you are encountering!
You can use `tail -100 /app/front/log/app.log` in the container if you have troubles getting to the log files.
You can use `tail -100 /app/front/log/app.log` in the container if you have trouble getting to the log files.
validations:
required: false
- type: checkboxes

View File

@@ -15,7 +15,7 @@ ENV PATH="/opt/venv/bin:$PATH"
COPY . ${INSTALL_DIR}/
RUN pip install tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython \
RUN pip install netifaces tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython \
&& bash -c "find ${INSTALL_DIR} -type d -exec chmod 750 {} \;" \
&& bash -c "find ${INSTALL_DIR} -type f -exec chmod 640 {} \;" \
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"
@@ -40,15 +40,20 @@ ENV S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0
RUN apk update --no-cache \
&& apk add --no-cache bash zip lsblk gettext-envsubst sudo mtr tzdata s6-overlay \
&& apk add --no-cache curl arp-scan iproute2 iproute2-ss nmap nmap-scripts traceroute net-tools net-snmp-tools bind-tools awake ca-certificates \
&& apk add --no-cache curl arp-scan iproute2 iproute2-ss nmap nmap-scripts traceroute nbtscan net-tools net-snmp-tools bind-tools awake ca-certificates \
&& apk add --no-cache sqlite php83 php83-fpm php83-cgi php83-curl php83-sqlite3 php83-session \
&& apk add --no-cache python3 nginx \
&& apk add --no-cache dcron \
&& ln -s /usr/bin/awake /usr/bin/wakeonlan \
&& bash -c "install -d -m 750 -o nginx -g www-data ${INSTALL_DIR} ${INSTALL_DIR}" \
&& rm -f /etc/nginx/http.d/default.conf
COPY --from=builder --chown=nginx:www-data ${INSTALL_DIR}/ ${INSTALL_DIR}/
# Add crontab file
COPY install/crontab /etc/crontabs/root
# Start all required services
RUN ${INSTALL_DIR}/dockerfiles/pre-setup.sh
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=2 \

View File

@@ -33,7 +33,7 @@ COPY --chmod=775 --chown=${USER_ID}:${USER_GID} . ${INSTALL_DIR}/
RUN apt-get install -y \
tini snmp ca-certificates curl libwww-perl arp-scan perl apt-utils cron sudo \
nginx-light php php-cgi php-fpm php-sqlite3 php-curl sqlite3 dnsutils net-tools php-openssl \
python3 python3-dev iproute2 nmap python3-pip zip systemctl usbutils traceroute
python3 python3-dev iproute2 nmap python3-pip zip systemctl usbutils traceroute nbtscan
# Alternate dependencies
RUN apt-get install nginx nginx-core mtr php-fpm php8.2-fpm php-cli php8.2 php8.2-sqlite3 -y

View File

@@ -1,4 +1,4 @@
# 💻🔍 Network security scanner & notification framework
# 💻🔍 Network scanner & notification framework
Get visibility of what's going on on your WIFI/LAN network. Schedule scans for devices, port changes and get alerts if unknown devices or changes are found. Write your own [Plugins](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) with auto-generated UI and in-build notification system. Build out and easily maintain your network source of truth (NSoT).
@@ -18,7 +18,7 @@ Get visibility of what's going on on your WIFI/LAN network. Schedule scans for d
![network_setup][network_setup]
Head to [https://netalertx.com/](https://netalertx.com/) for more screenshots.
Head to [https://netalertx.com/](https://netalertx.com/) for more gifs and screenshots 📷.
<details>
<summary>📷 Click for more screenshots</summary>
@@ -36,13 +36,13 @@ Head to [https://netalertx.com/](https://netalertx.com/) for more screenshots.
Most of us don't know what's going on on our home network, but we want our family and data to be safe. _Command-line tools_ are great, but the output can be _hard to understand_ and action if you are not a network specialist.
Net <b>Alert</b><sup>x</sup> gives you peace of mind. _Visualize and immediately report 📬_ what is going on in your network - this is the first step to enhance your _network security 🔐_.
Net<b>Alert</b><sup>x</sup> gives you peace of mind. _Visualize and immediately report 📬_ what is going on in your network - this is the first step to enhance your _network security 🔐_.
Net <b>Alert</b><sup>x</sup> combines several network and other scanning tools 🔍 with notifications 📧 into one user-friendly package 📦.
Net<b>Alert</b><sup>x</sup> combines several network and other scanning tools 🔍 with notifications 📧 into one user-friendly package 📦.
Set up a _kill switch ☠_ for your network via a smart plug with the available [Home Assistant](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HOME_ASSISTANT.md) integration. Implement custom automations with the [CSV device Exports 📤](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/csv_backup), [Webhooks](https://github.com/jokob-sk/NetAlertX/blob/main/docs/WEBHOOK_N8N.md), or [API endpoints](https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md) features.
Extend the app if you want to create your own scanner [Plugin](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) and handle the results and notifications in Net <b>Alert</b><sup>x</sup>.
Extend the app if you want to create your own scanner [Plugin](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) and handle the results and notifications in Net<b>Alert</b><sup>x</sup>.
Looking forward to your contributions if you decide to share your work with the community ❤.
@@ -92,18 +92,20 @@ Thank you to all the wonderful people who are sponsoring this project.
<!-- SPONSORS-LIST DO NOT MODIFY BELOW -->
| All Sponsors |
|---|
| [fama-lama](https://github.com/fama-lama) |
| [iptvcld](https://github.com/iptvcld) |
<!-- SPONSORS-LIST DO NOT MODIFY ABOVE -->
| [![GitHub](https://i.imgur.com/emsRCPh.png)](https://github.com/sponsors/jokob-sk) | [![Buy Me A Coffee](https://i.imgur.com/pIM6YXL.png)](https://www.buymeacoffee.com/jokobsk) | [![Patreon](https://i.imgur.com/MuYsrq1.png)](https://www.patreon.com/user?u=84385063) |
| --- | --- | --- |
<details>
<summary>Click for more ways to donate</summary>
<hr>
| [![GitHub](https://i.imgur.com/emsRCPh.png)](https://github.com/sponsors/jokob-sk) | [![Buy Me A Coffee](https://i.imgur.com/pIM6YXL.png)](https://www.buymeacoffee.com/jokobsk) | [![Patreon](https://i.imgur.com/MuYsrq1.png)](https://www.patreon.com/user?u=84385063) |
| --- | --- | --- |
- Bitcoin: `1N8tupjeCK12qRVU2XrV17WvKK7LCawyZM`
- Ethereum: `0x6e2749Cb42F4411bc98501406BdcD82244e3f9C7`

View File

@@ -3,13 +3,12 @@
# Generated: 2022-12-30_22-19-40 #
# #
# Config file for the LAN intruder detection app: #
# https://github.com/jokob-sk/NetAlertX #
# https://github.com/jokob-sk/NetAlertX #
# #
#-----------------AUTOGENERATED FILE-----------------#
# 🔺 Use the Settings UI - only edit when necessary 🔺
# General
#---------------------------
# Scan using interface eth0
@@ -19,15 +18,23 @@
# SCAN_SUBNETS = [ '192.168.1.0/24 --interface=eth1', '192.168.1.0/24 --interface=eth0' ]
SCAN_SUBNETS=['192.168.1.0/24 --interface=eth1']
TIMEZONE='Europe/Berlin'
LOADED_PLUGINS = ['ARPSCAN','CSVBCKP','DBCLNP', 'INTRNT','MAINT','NEWDEV','NSLOOKUP','NTFPRCS', 'PHOLUS','SETPWD','SMTP', 'SYNC', 'VNDRPDT', 'WORKFLOWS']
DAYS_TO_KEEP_EVENTS=90
# Used for generating links in emails. Make sure not to add a trailing slash!
REPORT_DASHBOARD_URL='http://netalertx'
# Make sure at least these scanners are enabled for new installs, other defaults are taken from the config.json
INTRNT_RUN='schedule'
ARPSCAN_RUN='schedule'
PHOLUS_RUN='on_new_device'
NSLOOKUP_RUN='before_name_updates'
# Email
#---------------------------
# Email
#-------------------------------------
# (add SMTP to LOADED_PLUGINS to load)
#-------------------------------------
SMTP_RUN='disabled' # use 'on_notification' to enable
SMTP_SERVER='smtp.gmail.com'
SMTP_PORT=587
@@ -39,8 +46,10 @@ SMTP_PASS='password'
SMTP_SKIP_TLS=False
# Webhooks
#---------------------------
# Webhook
#-------------------------------------
# (add WEBHOOK to LOADED_PLUGINS to load)
#-------------------------------------
WEBHOOK_RUN='disabled' # use 'on_notification' to enable
WEBHOOK_URL='http://n8n.local:5555/webhook-test/aaaaaaaa-aaaa-aaaa-aaaaa-aaaaaaaaaaaa'
WEBHOOK_PAYLOAD='json' # webhook payload data format for the "body > attachements > text" attribute
@@ -50,15 +59,19 @@ WEBHOOK_PAYLOAD='json' # webhook payload data format for the "bo
WEBHOOK_REQUEST_METHOD='GET'
# Apprise
#---------------------------
# Apprise
#-------------------------------------
# (add APPRISE to LOADED_PLUGINS to load)
#-------------------------------------
APPRISE_RUN='disabled' # use 'on_notification' to enable
APPRISE_HOST='http://localhost:8000/notify'
APPRISE_URL='mailto://smtp-relay.sendinblue.com:587?from=user@gmail.com&name=apprise&user=user@gmail.com&pass=password&to=user@gmail.com'
# NTFY
#---------------------------
#-------------------------------------
# (add NTFY to LOADED_PLUGINS to load)
#-------------------------------------
NTFY_RUN='disabled' # use 'on_notification' to enable
NTFY_HOST='https://ntfy.sh'
NTFY_TOPIC='replace_my_secure_topicname_91h889f28'
@@ -66,14 +79,18 @@ NTFY_USER='user'
NTFY_PASSWORD='passw0rd'
# PUSHSAFER
#---------------------------
# PUSHSAFER
#-------------------------------------
# (add PUSHSAFER to LOADED_PLUGINS to load)
#-------------------------------------
PUSHSAFER_RUN='disabled' # use 'on_notification' to enable
PUSHSAFER_TOKEN='ApiKey'
# MQTT
#---------------------------
# MQTT
#-------------------------------------
# (add MQTT to LOADED_PLUGINS to load)
#-------------------------------------
MQTT_RUN='disabled' # use 'on_notification' to enable
MQTT_BROKER='192.168.1.2'
MQTT_PORT=1883

13
back/cron_script.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
export INSTALL_DIR=/app
LOG_FILE="${INSTALL_DIR}/front/log/execution_queue.log"
# Check if there are any entries with cron_restart_backend
if grep -q "cron_restart_backend" "$LOG_FILE"; then
# Kill all python processes and restart the server
pkill -f "python " && (python ${INSTALL_DIR}/server > /dev/null 2>&1 &) && echo 'done'
# Remove all lines containing cron_restart_backend from the log file
sed -i '/cron_restart_backend/d' "$LOG_FILE"
fi

View File

@@ -4,7 +4,7 @@
![GitHub Release](https://img.shields.io/github/v/release/jokob-sk/NetAlertX?color=0aa8d2&logoColor=fff&logo=GitHub)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/jokob-sk?style=social)](https://github.com/sponsors/jokob-sk)
# NetAlertX 💻🔍 Network security scanner & notification framework
# NetAlertX 💻🔍 Network scanner & notification framework
| 🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/netalertx) | 📑 [Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) |🆕 [Release notes](https://github.com/jokob-sk/NetAlertX/releases) | 📚 [All Docs](https://github.com/jokob-sk/NetAlertX/tree/main/docs) |
|----------------------|----------------------| ----------------------| ----------------------|
@@ -13,6 +13,8 @@
<img src="https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/docs/img/GENERAL/github_social_image.jpg" width="1000px" />
</a>
Head to [https://netalertx.com/](https://netalertx.com/) for more gifs and screenshots 📷.
> [!NOTE]
> There is also an experimental 🧪 [bare-metal install](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HW_INSTALL.md) method available.
@@ -81,16 +83,17 @@ These are the most important settings to get at least some output in your Device
#### 🧭 Community guides
Use the official installation guides at first and use community content as suplementary material. Open an issue if you'd like to add your link to the list 🙏
Use the official installation guides at first and use community content as supplementary material. Open an issue if you'd like to add your link to the list 🙏
- 📄 [How to Install Pi.Alert on Your Synology NAS - Marius hosting (English)](https://mariushosting.com/how-to-install-pi-alert-on-your-synology-nas/) (Updated frequently)
- 📄 [Using the PiAlert Network Security Scanner on a Raspberry Pi - PiMyLifeUp (English)](https://pimylifeup.com/raspberry-pi-pialert/)
- [How to Setup Pi.Alert on Your Synology NAS - Digital Aloha (English)](https://www.youtube.com/watch?v=M4YhpuRFaUg)
- [Home Lab Network Monitoring - Scotti-BYTE Enterprise Consulting Services](https://www.youtube.com/watch?v=0DryhzrQSJA) (July 2024)
- 📄 [How to Install NetAlertX on Your Synology NAS - Marius hosting](https://mariushosting.com/how-to-install-pi-alert-on-your-synology-nas/) (Updated frequently)
- 📄 [Using the PiAlert Network Security Scanner on a Raspberry Pi - PiMyLifeUp](https://pimylifeup.com/raspberry-pi-pialert/)
- ▶ [How to Setup Pi.Alert on Your Synology NAS - Digital Aloha](https://www.youtube.com/watch?v=M4YhpuRFaUg)
- 📄 [시놀/헤놀에서 네트워크 스캐너 Pi.Alert Docker로 설치 및 사용하기 (Korean)](https://blog.dalso.org/article/%EC%8B%9C%EB%86%80-%ED%97%A4%EB%86%80%EC%97%90%EC%84%9C-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%8A%A4%EC%BA%90%EB%84%88-pi-alert-docker%EB%A1%9C-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9) (July 2023)
- 📄 [网络入侵探测器Pi.Alert (Chinese)](https://codeantenna.com/a/VgUvIAjZ7J) (May 2023)
- ▶ [Pi.Alert auf Synology & Docker by - Jürgen Barth (German)](https://www.youtube.com/watch?v=-ouvA2UNu-A) (March 2023)
- ▶ [Top Docker Container for Home Server Security - VirtualizationHowto (English)](https://www.youtube.com/watch?v=tY-w-enLF6Q) (March 2023)
- ▶ [Pi.Alert or WatchYourLAN can alert you to unknown devices appearing on your WiFi or LAN network - Danie van der Merwe (English)](https://www.youtube.com/watch?v=v6an9QG2xF0) (November 2022)
- ▶ [Top Docker Container for Home Server Security - VirtualizationHowto](https://www.youtube.com/watch?v=tY-w-enLF6Q) (March 2023)
- ▶ [Pi.Alert or WatchYourLAN can alert you to unknown devices appearing on your WiFi or LAN network - Danie van der Merwe](https://www.youtube.com/watch?v=v6an9QG2xF0) (November 2022)
> Ordered by last update time.

View File

@@ -38,4 +38,6 @@ touch /etc/s6-overlay/s6-rc.d/user/contents.d/{SetupOneshot,php-fpm,nginx,$APP_N
touch /etc/s6-overlay/s6-rc.d/nginx/dependencies.d/php-fpm
touch /etc/s6-overlay/s6-rc.d/$APP_NAME/dependencies.d/nginx
rm -f $0

View File

@@ -109,6 +109,10 @@ if [ ! -f "${INSTALL_DIR}/front/buildtimestamp.txt" ]; then
chown nginx:www-data "${INSTALL_DIR}/front/buildtimestamp.txt"
fi
# Start crond service in the background
echo "[INSTALL] Starting crond service..."
crond -f -d 8 > /dev/null 2>&1 &
echo -e "
[ENV] PATH is ${PATH}
[ENV] PORT is ${PORT}

View File

@@ -6,7 +6,7 @@ Please follow tips 1 - 4 to get a more detailed error.
When debugging an issue always set the highest log level:
`LOG_LEVEL='debug'`
`LOG_LEVEL='trace'`
## 2. Surfacing errors when container restarts 🔁

View File

@@ -1,9 +1,5 @@
## 🌟 Create a custom plugin: Overview
| ![Screen 1][screen1] | ![Screen 2][screen2] | ![Screen 3][screen3] |
|----------------------|----------------------| ----------------------|
| ![Screen 4][screen4] | ![Screen 5][screen5] |
NetAlertX comes with a plugin system to feed events from third-party scripts into the UI and then send notifications, if desired. The highlighted core functionality this plugin system supports, is:
* dynamic creation of a simple UI to interact with the discovered objects,
@@ -12,7 +8,19 @@ NetAlertX comes with a plugin system to feed events from third-party scripts int
* different column types for reported values to e.g. link back to a device
* import objects into existing NetAlertX database tables
> (Currently, update/overwriting of existing objects is not supported.)
> (Currently, update/overwriting of existing objects is only supported for devices via the `CurrentScan` table.)
### 🎥 Watch the video:
[![Watch the video](/docs/img/YouTube_thumbnail.png)](https://youtu.be/cdbxlwiWhv8)
### 📸 Screenshots
| ![Screen 1][screen1] | ![Screen 2][screen2] | ![Screen 3][screen3] |
|----------------------|----------------------| ----------------------|
| ![Screen 4][screen4] | ![Screen 5][screen5] |
## Use cases
Example use cases for plugins could be:
@@ -83,6 +91,16 @@ More on specifics below.
The `config.json` file is the manifest of the plugin. It contains mainly settings definitions and the mapping of Plugin objects to NetAlertX objects.
## Execution order
The execution order is used to specify wwhen a plugin is executed. This is useful if a plugin has access and surfaces more information than others. If a device is detected by 2 plugins and inserted into the `CurrentScan` table, the plugin with the higher priority (e.g.: `Level_0` is a higher priority than `Level_1`) will insert it's values first. These values (devices) will be then prioritized over any values inserted later.
```json
{
"execution_order" : "Layer_0"
}
```
## Supported data sources
Currently, these data sources are supported (valid `data_source` value).
@@ -183,7 +201,7 @@ This SQL query is executed on the `app.db` SQLite database file.
> ```json
> {
> "function": "CMD",
> "type": "text",
> "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]},
> "default_value":"SELECT dv.dev_Name as Object_PrimaryID, cast(dv.dev_LastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID, datetime() as DateTime, ns.Service as Watched_Value1, ns.State as Watched_Value2, 'null' as Watched_Value3, 'null' as Watched_Value4, ns.Extra as Extra FROM (SELECT * FROM Nmap_Scan) ns LEFT JOIN (SELECT dev_Name, dev_MAC, dev_LastIP FROM Devices) dv ON ns.MAC = dv.dev_MAC",
> "options": [],
> "localized": ["name", "description"],
@@ -214,7 +232,7 @@ For example for `PIHOLE` (`"unique_prefix": "PIHOLE"`) it is `EXTERNAL_PIHOLE.`.
> ...
>{
> "function": "DB_PATH",
> "type": "readonly",
> "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]},
> "default_value":"/etc/pihole/pihole-FTL.db",
> "options": [],
> "localized": ["name", "description"],
@@ -239,7 +257,7 @@ The actual SQL query you want to execute is then stored as a `CMD` setting, simi
>```json
>{
> "function": "CMD",
> "type": "text",
> "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]},
> "default_value":"SELECT hwaddr as Object_PrimaryID, cast('http://' || (SELECT ip FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC, ip LIMIT 1) as VARCHAR(100)) || ':' || cast( SUBSTR((SELECT name FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC, ip LIMIT 1), 0, INSTR((SELECT name FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC, ip LIMIT 1), '/')) as VARCHAR(100)) as Object_SecondaryID, datetime() as DateTime, macVendor as Watched_Value1, lastQuery as Watched_Value2, (SELECT name FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC, ip LIMIT 1) as Watched_Value3, 'null' as Watched_Value4, '' as Extra, hwaddr as ForeignKey FROM EXTERNAL_PIHOLE.network WHERE hwaddr NOT LIKE 'ip-%' AND hwaddr <> '00:00:00:00:00:00'; ",
> "options": [],
> "localized": ["name", "description"],
@@ -417,7 +435,7 @@ The `params` array in the `config.json` is used to enable the user to change the
```json
{
"function": "CMD",
"type": "text",
"type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]},
"default_value":"python3 /app/front/plugins/website_monitor/script.py urls={urls}",
"options": [],
"localized": ["name", "description"],
@@ -500,18 +518,7 @@ Required attributes are:
| -------- | ----------- |
| `"function"` | Specifies the function the setting drives or a simple unique code name. See Supported settings function values for options. |
| `"type"` | Specifies the form control used for the setting displayed in the Settings page and what values are accepted. Supported options include: |
| | - `text` |
| | - `integer` |
| | - `boolean` |
| | - `password` |
| | - `readonly` |
| | - `integer.select` |
| | - `text.select` |
| | - `text.multiselect` |
| | - `list` |
| | - `list.select` |
| | - `integer.checkbox` |
| | - `text.template` |
| | - `{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{"type":"password"}] ,"transformers": ["sha256"]}]}` |
| `"localized"` | A list of properties on the current JSON level that need to be localized. |
| `"name"` | Displayed on the Settings page. An array of localized strings. See Localized strings below. |
| `"description"` | Displayed on the Settings page. An array of localized strings. See Localized strings below. |
@@ -554,7 +561,7 @@ You can have any `"function": "my_custom_name"` custom name, however, the ones l
> ```json
> {
> "function": "RUN",
> "type": "text.select",
> "type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]},
> "default_value":"disabled",
> "options": ["disabled", "once", "schedule", "always_after_scan", "on_new_device"],
> "localized": ["name", "description"],
@@ -619,7 +626,7 @@ The UI will adjust how columns are displayed in the UI based on the resolvers de
```json
"function": "dev_DeviceType",
"type": "text.select",
"type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]},
"maxLength": 30,
"default_value": "",
"options": ["{value}"],

View File

@@ -19,7 +19,6 @@ When opening an issue please:
Check for browser console (F12 browser dev console) errors + check different browsers.
## 3. Clear the app cache and cached JavaScript files
Refresh the browser cache (usually shoft + refresh), try a private window, or different browsers. Please also refresh the app cache by clicking the 🔃 (reload) button in the header of the application.
@@ -28,11 +27,15 @@ Refresh the browser cache (usually shoft + refresh), try a private window, or di
If you have any reverse proxy or similar, try disabling it.
## 5. Post your docker start details
## 5. Disable your firewall
If you are using a firewall, try to temporarily disabling it.
## 6. Post your docker start details
If you haven't, post your docker compose/run command.
## 6. Check for errors in your PHP/NGINX error logs
## 7. Check for errors in your PHP/NGINX error logs
In the container execute:
@@ -40,8 +43,7 @@ In the container execute:
`cat /app/front/log/app.php_errors.log`
## 7. Make sure permissions are correct
## 8. Make sure permissions are correct
> [!TIP]
> You can try to start the container without mapping the `/app/config` and `/app/db` dirs and if the UI shows up then the issue is most likely related to your file system permissions or file ownership.

BIN
docs/img/YouTube_thumbnail.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

View File

@@ -25,13 +25,33 @@
color:white;
background-color: black;
font-family: 'Courier New', monospace;
font-size: .85em;
}
.logs-row textarea
{
width: 100%;
}
#tab_Logging .actions{
display:contents;
position: relative;
padding: 0.4em
}
#tab_Logging .actions .toggle{
margin: 0.5em;
height: 3em;
}
.logs-row .button{
margin: 2px;
}
.logs-row
{
align-content: center;
width: 100%;
display: grid;
margin: 5px;
}
.logs-size
@@ -48,12 +68,11 @@
}
.logs-small
{
height: 100px;
height: 150px;
}
.log-file
{
width: 145px;
display: inline-grid;
font-size: 20px;
}
.log-purge
@@ -213,9 +232,15 @@
.content-wrapper,
.right-side,
.main-footer {
margin-left: 150px;
margin-left: 150px;
}
#settingsPage
{
display: grid;
}
@media (max-width: 767px) {
.main-header .logo {
width: 100%;
@@ -230,6 +255,15 @@
.main-footer {
margin-left: 0px;
}
.fixed .content-wrapper, .fixed .right-side {
padding-top: 50px;
}
.main-sidebar {
padding-top: 50px;
}
.content-header {
display: none;
}
}
.sidebar-open .content-wrapper,
@@ -1111,7 +1145,7 @@ input[readonly] {
color: white;
}
#dropdownIcon li svg, #dropdownIcon li i{
#dropdownIcon li svg, #dropdownIcon li i, .dropdownIcon li svg, .dropdownIcon li i, .icon-maxsize svg, .icon-maxsize i{
height: 1.5em !important;
}
@@ -1246,6 +1280,21 @@ input[readonly] {
cursor: pointer;
}
.networkNodeTabHeaders
{
max-width: 200px;
text-overflow: ellipsis;
overflow: hidden;
text-wrap: nowrap;
}
@media (max-width: 767px) {
.networkNodeTabHeaders .node-name
{
display: none;
}
}
/* ----------------------------------------------------------------- */
/* PLUGINS page */

View File

@@ -824,20 +824,20 @@ function initializeCombos () {
initializeCombo ( '#dropdownDevices', 'getDevices', 'txtFromDevice', false);
// Initiate dropdown
// function initSettingDropdown(settingKey, // Identifier for the setting
// valuesArray, // Array of values to be pre-selected in the dropdown
// targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced)
// callbackToGenerateEntries, // Callback function to generate entries based on options
// targetField, // Target field or element where selected value should be applied or updated
// nameTransformer) // callback to transform name
// generateSetOptions(settingKey, // Identifier for the setting
// valuesArray, // Array of values to be pre-selected in the dropdown
// targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced)
// callbackToGenerateEntries, // Callback function to generate entries based on options
// targetField, // Target field or element where selected value should be applied or updated
// nameTransformer) // callback to transform name
initSettingDropdown("NEWDEV_dev_Icon", [], "dropdownIcon_tmp", genListWithInputSet, 'txtIcon', atob )
initSettingDropdown("NEWDEV_dev_DeviceType", [], "dropdownDeviceType_tmp", genListWithInputSet, 'txtDeviceType' )
initSettingDropdown("NEWDEV_dev_Owner", [], "dropdownOwner_tmp", genListWithInputSet, 'txtOwner' )
initSettingDropdown("NEWDEV_dev_Group", [], "dropdownGroup_tmp", genListWithInputSet, 'txtGroup' )
initSettingDropdown("NEWDEV_dev_Location", [], "dropdownLocation_tmp", genListWithInputSet, 'txtLocation' )
initSettingDropdown("NEWDEV_dev_Network_Node_MAC_ADDR", [], "dropdownNetworkNodeMac_tmp", genListWithInputSet, 'txtNetworkNodeMac' )
generateOptionsOrSetOptions("NEWDEV_dev_Icon", [], "dropdownIcon_tmp", genListWithInputSet, 'txtIcon', ["base64"])
generateOptionsOrSetOptions("NEWDEV_dev_DeviceType", [], "dropdownDeviceType_tmp", genListWithInputSet, 'txtDeviceType' )
generateOptionsOrSetOptions("NEWDEV_dev_Owner", [], "dropdownOwner_tmp", genListWithInputSet, 'txtOwner' )
generateOptionsOrSetOptions("NEWDEV_dev_Group", [], "dropdownGroup_tmp", genListWithInputSet, 'txtGroup' )
generateOptionsOrSetOptions("NEWDEV_dev_Location", [], "dropdownLocation_tmp", genListWithInputSet, 'txtLocation' )
generateOptionsOrSetOptions("NEWDEV_dev_Network_Node_MAC_ADDR", [], "dropdownNetworkNodeMac_tmp", genListWithInputSet, 'txtNetworkNodeMac' )
// Initialize static combos
initializeComboSkipRepeated ();

View File

@@ -336,6 +336,7 @@ function getDevicesTotals(devicesData) {
}
//------------------------------------------------------------------------------
// Render the info boxes/tiles on top
function renderInfoboxes(customData) {
$.ajax({
url: 'php/components/tile_cards.php', // PHP script URL

View File

@@ -147,19 +147,6 @@
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion_det" href="#collapse301">
<?= lang('HelpFAQ_Cat_Detail_301_head_a');?> "<?= lang('DevDetail_EveandAl_ScanCycle');?>" <?= lang('HelpFAQ_Cat_Detail_301_head_b');?></a>
</h4>
</div>
<div id="collapse301" class="panel-collapse collapse" style="font-size: 16px;">
<div class="panel-body">
<?= lang('HelpFAQ_Cat_Detail_301_text');?>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">

View File

@@ -124,8 +124,10 @@ function cacheSettings()
settingsData.forEach((set) => {
resolvedOptions = createArray(set.Options)
resolvedOptionsOld = resolvedOptions
setPlugObj = {};
options_params = [];
resolved = ""
// proceed only if first option item contains something to resolve
if( !set.Code_Name.includes("__metadata") &&
@@ -158,7 +160,7 @@ function cacheSettings()
}
}
setCache(`pia_set_${set.Code_Name}`, set.Value)
setCache(`pia_set_${set.Code_Name}`, set.Value)
setCache(`pia_set_opt_${set.Code_Name}`, resolvedOptions)
});
}).then(() => handleSuccess('cacheSettings', resolve())).catch(() => handleFailure('cacheSettings', reject("cacheSettings already completed"))); // handle AJAX synchronization
@@ -179,6 +181,7 @@ function getSettingOptions (key) {
if (result == "")
{
console.log(`Setting options with key "${key}" not found`)
result = []
}
return result;
@@ -743,10 +746,14 @@ function isRandomMAC(mac)
// ---------------------------------------------------------
// Generate an array object from a string representation of an array
function createArray(input) {
// Empty array
if (input === '[]') {
return [];
// Is already array, return
if (Array.isArray(input)) {
return input;
}
// Empty array
if (input === '[]' || input === '') {
return [];
}
// Regex pattern for brackets
const patternBrackets = /(^\s*\[)|(\]\s*$)/g;
@@ -945,7 +952,8 @@ function updateApi()
{
// value has to be in format event|param. e.g. run|ARPSCAN
action = `update_api|devices,appevents`
action = `${getGuid()}|update_api|devices,appevents`
$.ajax({
method: "POST",

View File

@@ -2,51 +2,108 @@
// General utilities to interact with the database
// -----------------------------------------------------------------------------
// // Call to render lists
// renderList(
// options,
// callbackToGenerateEntries,
// valuesArray,
// placeholder,
// targetField,
// transformers
// );
// --------------------------------------------------
// Read data and place intotarget location, callback processies the results
function readData(sqlQuery, processDataCallback, valuesArray, targetLocation, targetField, nameTransformer) {
var apiUrl = `php/server/dbHelper.php?action=read&rawSql=${encodeURIComponent(sqlQuery)}`;
$.get(apiUrl, function(data) {
// Process the JSON data using the provided callback function
function renderList(
options,
processDataCallback,
valuesArray,
placeholder,
targetField,
transformers
) {
// Check if there are options provided
if (options.length > 0) {
// Determine if the first option's name is an SQL query
const sqlQuery = isSQLQuery(options[0].name) ? options[0].name : "";
data = JSON.parse(data)
// If there is an SQL query, fetch additional options
if (sqlQuery) {
// remove first item containing the SQL query
options.shift();
var htmlResult = processDataCallback(data, valuesArray, targetField, nameTransformer);
const apiUrl = `php/server/dbHelper.php?action=read&rawSql=${encodeURIComponent(sqlQuery)}`;
// Place the resulting HTML into the specified placeholder div
$("#" + targetLocation).replaceWith(htmlResult);
});
$.get(apiUrl, function (sqlOptionsData) {
// Parse the returned SQL data
const sqlOption = JSON.parse(sqlOptionsData);
// Concatenate options from SQL query with the supplied options
options = options.concat(sqlOption);
// Process the combined options
setTimeout(() => {
processDataCallback(
options,
valuesArray,
targetField,
transformers,
placeholder
);
}, 1);
});
} else {
// No SQL query, directly process the supplied options
setTimeout(() => {
processDataCallback(
options,
valuesArray,
targetField,
transformers,
placeholder
);
}, 1);
}
} else {
// No options provided, directly process with empty options
setTimeout(() => {
processDataCallback(
options,
valuesArray,
targetField,
transformers,
placeholder
);
}, 1);
}
}
// --------------------------------------------------
// Check if database is locked
function checkDbLock() {
$.ajax({
url: 'log/db_is_locked.log', // Replace with the actual path to your PHP file
type: 'GET',
success: function(response) {
// console.log(response);
if (response == 0) {
// console.log('Database is not locked');
$(".header-status-locked-db").hide()
} else {
console.log('🟥 Database is locked:');
console.log(response);
$(".header-status-locked-db").show()
}
},
error: function() {
console.log('🟥 Error checking database lock status');
$(".header-status-locked-db").show()
}
});
$.ajax({
url: "log/db_is_locked.log", // Replace with the actual path to your PHP file
type: "GET",
success: function (response) {
console.log(response);
if (response == 0) {
// console.log('Database is not locked');
$(".header-status-locked-db").hide();
} else {
console.log("🟥 Database is locked:");
console.log(response);
$(".header-status-locked-db").show();
}
},
error: function () {
console.log("🟥 Error checking database lock status");
$(".header-status-locked-db").show();
},
});
}
setInterval(checkDbLock(), 1000);

View File

@@ -337,7 +337,7 @@ const phpEndpoint = 'php/server/utilNotification.php';
// --------------------------------------------------
// Write a notification
function writeNotification(content, level) {
function write_notification(content, level) {
$.ajax({
url: phpEndpoint, // Change this to the path of your PHP script

File diff suppressed because it is too large Load Diff

View File

@@ -78,42 +78,50 @@ function initDeviceSelectors() {
// -----------------------------------------------------------------------------
// Initiate dropdown
function initSettingDropdown(settingKey, // Identifier for the setting
valuesArray, // Array of values to be pre-selected in the dropdown
targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced)
callbackToGenerateEntries, // Callback function to generate entries based on options
targetField, // Target field or element where selected value should be applied or updated
nameTransformer) // callback to transform the name (e.g. base64)
{
// // -----------------------------------------------------------------------------
// // (ASYNC) Initiate dropdown
// function generateSetOptions(settingKey, // Identifier for the setting
// valuesArray, // Array of values to be pre-selected in the dropdown
// targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced)
// callbackToGenerateEntries, // Callback function to generate entries based on options
// targetField, // Target field or element where selected value should be applied or updated
// nameTransformer) // callback to transform the name (e.g. base64)
// {
var optionsHtml = ""
// var optionsHtml = ""
// NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
optionsArray = createArray(getSettingOptions(settingKey))
// // NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
// optionsArray = createArray(getSettingOptions(settingKey))
// check if the result is a SQL query
if(isSQLQuery(optionsArray[0]))
{
readData(optionsArray[0], callbackToGenerateEntries, valuesArray, targetLocation, targetField, nameTransformer);
} else // this should be already an array, e.g. from a setting or pre-defined
{
optionsArray.forEach(option => {
let selected = valuesArray.includes(option) ? 'selected' : '';
optionsHtml += `<option value="${option}" ${selected}>${option}</option>`;
});
// Replace the specified placeholder div with the resulting HTML
setTimeout(() => {
// // check if the result is a SQL query
// if(optionsArray.length > 0 && isSQLQuery(optionsArray[0]))
// {
$("#" + targetLocation).replaceWith(optionsHtml);
// if (settingKey == "NEWDEV_dev_Network_Node_MAC_ADDR") {
// console.log("isSQLQuery in generateSetOptions");
// }
// readData(optionsArray[0], callbackToGenerateEntries, valuesArray, targetLocation, targetField, nameTransformer);
// } else // this should be already an array, e.g. from a setting or pre-defined
// {
// optionsArray.forEach(option => {
// let selected = valuesArray.includes(option) ? 'selected' : '';
// optionsHtml += `<option value="${option}" ${selected}>${option}</option>`;
// });
// // Replace the specified placeholder div with the resulting HTML
// setTimeout(() => {
// $("#" + targetLocation).replaceWith(optionsHtml);
}, 50);
}
}
// }, 50);
// }
// }
// -----------------------------------------------------------------------------
@@ -145,86 +153,6 @@ function hideUIelements(settingKey) {
}
// -----------------------------------------------------------------------------
// Data processors
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Processor to generate options for a dropdown menu
function generateDropdownOptions(data, valuesArray, targetField, nameTransformer) {
var optionsHtml = "";
data.forEach(function(item) {
labelName = item.name
// console.log(nameTransformer);
// console.log(labelName);
// if(nameTransformer && nameTransformer != '' && labelName != '❌None')
// {
// console.log(labelName);
// labelName = nameTransformer(labelName)
// console.log(labelName);
// }
let selected = valuesArray.includes(item.id) ? 'selected' : '';
optionsHtml += `<option value="${item.id}" ${selected}>${labelName}</option>`;
});
return `${optionsHtml}`;
}
// -----------------------------------------------------------------------------
// Processor to generate a list
function generateList(data, valuesArray, targetField, nameTransformer) {
var listHtml = "";
data.forEach(function(item) {
labelName = item.name
if(nameTransformer && nameTransformer != '' && labelName != '❌None')
{
labelName = nameTransformer(labelName)
}
let selected = valuesArray.includes(item.id) ? 'selected' : '';
listHtml += `<li ${selected}>${labelName}</li>`;
});
return listHtml;
}
// -----------------------------------------------------------------------------
// Processor to generate a list in the deviceDetails page
function genListWithInputSet(data, valuesArray, targetField, nameTransformer) {
var listHtml = "";
console.log(data);
data.forEach(function(item) {
let selected = valuesArray.includes(item.id) ? 'selected' : '';
// console.log(item);
labelName = item.name
if(nameTransformer && nameTransformer != '' && labelName != '❌None')
{
labelName = nameTransformer(labelName)
}
listHtml += `<li ${selected}>
<a href="javascript:void(0)" onclick="setTextValue('${targetField}','${item.id}')">${labelName}</a>
</li>`;
});
return listHtml;
}
// -----------------------------------------------------------------------------
@@ -306,6 +234,57 @@ function getCellValue(row, index) {
return $(row).children('td').eq(index).text();
}
// -----------------------------------------------------------------------------
// handling events on the backend initiated by the front end START
// -----------------------------------------------------------------------------
modalEventStatusId = 'modal-message-front-event'
// --------------------------------------------------------
// Calls a backend function to add a front-end event (specified by the attributes 'data-myevent' and 'data-myparam-plugin' on the passed element) to an execution queue
function addToExecutionQueue_settingEvent(element)
{
// value has to be in format event|param. e.g. run|ARPSCAN
action = `${getGuid()}|${$(element).attr('data-myevent')}|${$(element).attr('data-myparam-plugin')}`
$.ajax({
method: "POST",
url: "php/server/util.php",
data: { function: "addToExecutionQueue", action: action },
success: function(data, textStatus) {
// showModalOk ('Result', data );
// show message
showModalOk(getString("general_event_title"), `${getString("general_event_description")} <br/> <br/> <code id='${modalEventStatusId}'></code>`);
updateModalState()
}
})
}
// --------------------------------------------------------
// Updating the execution queue in in modal pop-up
function updateModalState() {
setTimeout(function() {
// Fetch the content from the log file using an AJAX request
$.ajax({
url: '/log/execution_queue.log',
type: 'GET',
success: function(data) {
// Update the content of the HTML element (e.g., a div with id 'logContent')
$('#'+modalEventStatusId).html(data);
updateModalState();
},
error: function() {
// Handle error, such as the file not being found
$('#logContent').html('Error: Log file not found.');
}
});
}, 2000);
}
// -----------------------------------------------------------------------------
// initialize

View File

@@ -370,9 +370,27 @@ $db->close();
</div>
<div class="tab-pane" id="tab_BackupRestore">
<div class="db_info_table">
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnExportCSV" onclick="ExportCSV()"><?= lang('Maintenance_Tool_ExportCSV');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ExportCSV_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnPiaBackupDBtoArchive" onclick="askPiaBackupDBtoArchive()"><?= lang('Maintenance_Tool_backup');?></button>
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportCSV" onclick="askImportCSV()"><?= lang('Maintenance_Tool_ImportCSV');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ImportCSV_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportPastedCSV" onclick="askImportPastedCSV()"><?= lang('Maintenance_Tool_ImportPastedCSV');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ImportPastedCSV_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnPiaBackupDBtoArchive" onclick="askPiaBackupDBtoArchive()"><?= lang('Maintenance_Tool_backup');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_backup_text');?></div>
</div>
@@ -388,146 +406,54 @@ $db->close();
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_purgebackup_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnExportCSV" onclick="askExportCSV()"><?= lang('Maintenance_Tool_ExportCSV');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ExportCSV_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportCSV" onclick="askImportCSV()"><?= lang('Maintenance_Tool_ImportCSV');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ImportCSV_text');?></div>
</div>
</div>
</div>
<!-- ---------------------------Logging-------------------------------------------- -->
<div class="tab-pane" id="tab_Logging">
<div class="db_info_table">
<div class="log-area box box-solid box-primary">
<div class="row logs-row">
<textarea id="app_log" class="logs" cols="70" rows="10" wrap='off' readonly >
<?php
if(filesize("./log/app.log") > 2000000)
{
echo file_get_contents( "./log/app.log", false, null, -2000000);
}
else{
echo file_get_contents( "./log/app.log" );
}
?>
</textarea>
</div>
<div class="row logs-row" >
<div>
<div class="log-file">app.log <div class="logs-size"><?php echo number_format((filesize("./log/app.log") / 1000000),2,",",".") . ' MB';?>
<span class="span-padding"><a href="./log/app.log" target="_blank"><i class="fa fa-download"></i> </a></span>
</div></div>
<button class="btn btn-primary col-sm-2 col-xs-2" onclick="restartBackend()">Not working: Restart Backend</button>
<div class="log-purge">
<button class="btn btn-primary " onclick="logManage('app.log','cleanLog')"><?= lang('Gen_Purge');?></button>
</div>
</div>
</div>
</div>
<div class="log-area box box-solid box-primary">
<div class="row logs-row">
<textarea id="app_front_log" class="logs" cols="70" rows="10" wrap='off' readonly><?php echo file_get_contents( "./log/app_front.log" ); ?>
</textarea>
</div>
<div class="row logs-row" >
<div>
<div class="log-file">app_front.log<div class="logs-size"><?php echo number_format((filesize("./log/app_front.log") / 1000000),2,",",".") . ' MB';?>
<span class="span-padding"><a href="./log/app_front.log"><i class="fa fa-download"></i> </a></span>
</div></div>
<div class="log-purge">
<button class="btn btn-primary" onclick="logManage('app_front.log','cleanLog')"><?= lang('Gen_Purge');?></button>
</div>
</div>
</div>
</div>
<div class="log-area box box-solid box-primary">
<div class="row logs-row">
<textarea id="app_php_log" class="logs" cols="70" rows="10" wrap='off' readonly><?php echo file_get_contents( "./log/app.php_errors.log" ); ?>
</textarea>
</div>
<div class="row logs-row" >
<div>
<div class="log-file">app.php_errors.log<div class="logs-size"><?php echo number_format((filesize("./log/app.php_errors.log") / 1000000),2,",",".") . ' MB';?>
<span class="span-padding"><a href="./log/app.php_errors.log"><i class="fa fa-download"></i> </a></span>
</div></div>
<div class="log-purge">
<button class="btn btn-primary" onclick="logManage('app.php_errors.log','cleanLog')"><?= lang('Gen_Purge');?></button>
</div>
</div>
</div>
</div>
<div class="log-area box box-solid box-primary ">
<div class="row logs-row">
<textarea id="nginx_error_log" class="logs logs-small" cols="70" rows="10" wrap='off' readonly><?php echo file_get_contents( "/var/log/nginx/error.log" ); ?>
</textarea>
</div>
<div class="row logs-row" >
<div>
<div class="log-file" title="/var/log/nginx/error.log">nginx/error.log</div>
<span class="span-padding"><a href="/var/log/nginx/error.log"><i class="fa fa-download"></i> </a></span>
</div>
</div>
</div>
<div class="log-area box box-solid box-primary">
<div class="row logs-row">
<textarea id="stdout_log" class="logs logs-small" cols="70" rows="10" wrap='off' readonly><?php echo file_get_contents( "./log/stdout.log" ); ?>
</textarea>
</div>
<div class="row logs-row" >
<div>
<div class="log-file">stdout.log<div class="logs-size"><?php echo number_format((filesize("./log/stdout.log") / 1000000),2,",",".") . ' MB';?>
<span class="span-padding"><a href="./log/stdout.log"><i class="fa fa-download"></i> </a></span>
</div></div>
<div class="log-purge">
<button class="btn btn-primary" onclick="logManage('stdout.log','cleanLog')"><?= lang('Gen_Purge');?></button>
</div>
</div>
</div>
</div>
<div class="log-area box box-solid box-primary">
<div class="row logs-row">
<textarea id="stderr_log" class="logs logs-small" cols="70" rows="10" wrap='off' readonly><?php echo file_get_contents( "./log/stderr.log" ); ?>
</textarea>
</div>
<div class="row logs-row" >
<div>
<div class="log-file">stderr.log<div class="logs-size"><?php echo number_format((filesize("./log/stderr.log") / 1000000),2,",",".") . ' MB';?>
<span class="span-padding"><a href="./log/stderr.log"><i class="fa fa-download"></i> </a></span>
</div></div>
<div class="log-purge">
<button class="btn btn-primary" onclick="logManage('stderr.log','cleanLog')"><?= lang('Gen_Purge');?></button>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row actions">
<div class="col-sm-2">
<div class="form-check toggle">
<label class="form-check-label pointer" for="logsAutoRefresh">
<input class="form-check-input" type="checkbox" id="logsAutoRefresh" onchange="toggleAutoRefresh()" />
Auto-refresh
</label>
</div>
</div>
<!-- ---------------------------Bulk edit -------------------------------------------- -->
<div class="tab-pane" id="tab_multiEdit">
<div class="db_info_table">
<div class="box box-solid">
<?php
require 'multiEditCore.php';
?>
<div class="col-sm-2">
<div class="form-check toggle">
<label class="form-check-label pointer" for="logsAutoScroll">
<input class="form-check-input" type="checkbox" checked id="logsAutoScroll" />
Auto-scroll
</label>
</div>
</div>
<div class="col-sm-8">
<div class="form-inline toggle">
<input class="form-control" type="text" id="logsFilter" oninput="applyFilter()" placeholder="Filter lines with text..." />
</div>
</div>
</div>
</div>
<div class="db_info_table">
<div id="logsPlc"></div>
</div>
</div>
<!-- ---------------------------Bulk edit -------------------------------------------- -->
<div class="tab-pane" id="tab_multiEdit">
<div class="db_info_table">
<div class="box box-solid">
<?php
require 'multiEditCore.php';
?>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ------------------------------------------------------------------------------ -->
</div>
<!-- ------------------------------------------------------------------------------ -->
</div>
@@ -558,7 +484,6 @@ $db->close();
<script>
var emptyArr = ['undefined', "", undefined, null];
@@ -566,76 +491,92 @@ var selectedTab = 'tab_Settings_id';
initializeTabs();
// -----------------------------------------------------------
// delete devices with emty macs
function askDeleteDevicesWithEmptyMACs () {
// Ask
showModalWarning('<?= lang('Maintenance_Tool_del_empty_macs_noti');?>', '<?= lang('Maintenance_Tool_del_empty_macs_noti_text');?>',
'Cancel', 'Delete', 'deleteDevicesWithEmptyMACs');
}
// -----------------------------------------------------------
function deleteDevicesWithEmptyMACs()
{
// Delete device
$.get('php/server/devices.php?action=deleteAllWithEmptyMACs', function(msg) {
showMessage (msg);
write_notification(`[Maintenance] All devices witout a Mac manually deleted`, 'info')
});
}
// -----------------------------------------------------------
// delete all devices
function askDeleteAllDevices () {
// Ask
showModalWarning('<?= lang('Maintenance_Tool_del_alldev_noti');?>', '<?= lang('Maintenance_Tool_del_alldev_noti_text');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteAllDevices');
}
// -----------------------------------------------------------
function deleteAllDevices()
{
// Delete device
$.get('php/server/devices.php?action=deleteAllDevices', function(msg) {
showMessage (msg);
write_notification(`[Maintenance] All devices manually deleted`, 'info')
});
}
// -----------------------------------------------------------
// delete all (unknown) devices
function askDeleteUnknown () {
// Ask
showModalWarning('<?= lang('Maintenance_Tool_del_unknowndev_noti');?>', '<?= lang('Maintenance_Tool_del_unknowndev_noti_text');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteUnknownDevices');
}
// -----------------------------------------------------------
function deleteUnknownDevices()
{
// Execute
$.get('php/server/devices.php?action=deleteUnknownDevices', function(msg) {
showMessage (msg);
write_notification(`[Maintenance] Unknown devices manually deleted`, 'info')
});
}
// -----------------------------------------------------------
// delete all Events
function askDeleteEvents () {
// Ask
showModalWarning('<?= lang('Maintenance_Tool_del_allevents_noti');?>', '<?= lang('Maintenance_Tool_del_allevents_noti_text');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteEvents');
}
// -----------------------------------------------------------
function deleteEvents()
{
// Execute
$.get('php/server/devices.php?action=deleteEvents', function(msg) {
showMessage (msg);
write_notification(`[Maintenance] Events manually deleted (all)`, 'info')
});
}
// -----------------------------------------------------------
// delete all Events older than 30 days
function askDeleteEvents30 () {
// Ask
showModalWarning('<?= lang('Maintenance_Tool_del_allevents30_noti');?>', '<?= lang('Maintenance_Tool_del_allevents30_noti_text');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteEvents30');
}
// -----------------------------------------------------------
function deleteEvents30()
{
// Execute
$.get('php/server/devices.php?action=deleteEvents30', function(msg) {
showMessage (msg);
write_notification(`[Maintenance] Events manually deleted (last 30 days kep)`, 'info')
});
}
// -----------------------------------------------------------
// delete History
function askDeleteActHistory () {
// Ask
@@ -650,6 +591,7 @@ function deleteActHistory()
});
}
// -----------------------------------------------------------
// Backup DB to Archive
function askPiaBackupDBtoArchive () {
// Ask
@@ -664,6 +606,7 @@ function PiaBackupDBtoArchive()
});
}
// -----------------------------------------------------------
// Restore DB from Archive
function askPiaRestoreDBfromArchive () {
// Ask
@@ -678,6 +621,7 @@ function PiaRestoreDBfromArchive()
});
}
// -----------------------------------------------------------
// Purge Backups
function askPiaPurgeDBBackups() {
// Ask
@@ -692,34 +636,47 @@ function PiaPurgeDBBackups()
});
}
// Restart Backend
function restartBackend() {
// Execute
$.ajax({
method: "POST",
url: "php/server/util.php",
data: { function: 'restartBackend' },
success: function(data, textStatus) {
showModalOk ('Result', data );
}
})
// -----------------------------------------------------------
// Restart Backend Python Server
function askRestartBackend() {
// Ask
showModalWarning('<?= lang('Maint_RestartServer');?>', '<?= lang('Maint_Restart_Server_noti_text');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Maint_RestartServer');?>', 'restartBackend');
}
// Export CSV
function askExportCSV() {
// Ask
showModalWarning('<?= lang('Maintenance_Tool_ExportCSV_noti');?>', '<?= lang('Maintenance_Tool_ExportCSV_noti_text');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', 'ExportCSV');
// -----------------------------------------------------------
function restartBackend() {
modalEventStatusId = 'modal-message-front-event'
// Execute
$.ajax({
method: "POST",
url: "php/server/util.php",
data: { function: "addToExecutionQueue", action: `${getGuid()}|cron_restart_backend` },
success: function(data, textStatus) {
// showModalOk ('Result', data );
// show message
showModalOk(getString("general_event_title"), `${getString("general_event_description")} <br/> <br/> <code id='${modalEventStatusId}'></code>`);
updateModalState()
write_notification('[Maintenance] App manually restarted', 'info')
}
})
}
// -----------------------------------------------------------
// Export CSV
function ExportCSV()
{
// Execute
openInNewTab("php/server/devices.php?action=ExportCSV")
}
// -----------------------------------------------------------
// Import CSV
function askImportCSV() {
// Ask
@@ -731,6 +688,27 @@ function ImportCSV()
// Execute
$.get('php/server/devices.php?action=ImportCSV', function(msg) {
showMessage (msg);
write_notification(`[Maintenance] Devices imported from CSV file`, 'info')
});
}
// -----------------------------------------------------------
// Import pasted CSV
function askImportPastedCSV() {
// Add new icon as base64 string
showModalInput ('<i class="fa fa-square-plus pointer"></i> <?= lang('Maintenance_Tool_ImportCSV_noti');?>', '<?= lang('Maintenance_Tool_ImportPastedCSV_noti_text');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', 'ImportPastedCSV');
}
function ImportPastedCSV()
{
var csv = $('#modal-input-textarea').val();
csvBase64 = btoa(csv)
// Execute
$.post('php/server/devices.php?action=ImportCSV', { content: csvBase64 }, function(msg) {
showMessage(msg);
write_notification(`[Maintenance] Devices imported from pasted content`, 'info');
});
}
@@ -800,41 +778,29 @@ function performLogManage() {
data: { function: logFileAction, settings: targetLogFile },
success: function(data, textStatus) {
showModalOk ('Result', data );
write_notification(`[Maintenance] Log file "${targetLogFile}" manually purged`, 'info')
}
})
}
// --------------------------------------------------------
// scroll down the log areas
function scrollDown()
{
setTimeout(() => {
function scrollDown() {
var elementToCheck = $("#tab_Logging_id");
// Check if the parent <li> is active
if (elementToCheck.parent().hasClass("active")) {
{
var areaIDs = ['app_log', 'app_front_log', 'IP_changes_log', 'stdout_log', 'stderr_log', 'app_pholus_log', 'app_pholus_lastrun_log', 'app_php_log'];
for (let i = 0; i < areaIDs.length; i++) {
var textAreas = $("#logsPlc textarea");
var tempArea = $('#' + areaIDs[i]);
if (tempArea.length > 0)
{
$(tempArea[0]).scrollTop(tempArea[0].scrollHeight);
}
}
}
textAreas.each(function() {
$(this).scrollTop(this.scrollHeight);
});
}
}, 200);
}
// --------------------------------------------------------
// Manage displayed columns
// --------------------------------------------------------
@@ -951,14 +917,77 @@ function initializeTabs () {
}, 50);
}
//------------------------------------------------------------------------------
// Logs render functionality
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Manages the auto-refresh functionality for the logs
let intervalId;
// load footer asynchronously not to block the page load/other sections
function toggleAutoRefresh() {
const checkbox = $('#logsAutoRefresh')[0];
if (checkbox.checked) {
intervalId = setInterval(renderLogs, 1000);
} else {
clearInterval(intervalId);
}
}
//------------------------------------------------------------------------------
// Manages thefilter application
function applyFilter() {
const filterText = $("#logsFilter").val().toLowerCase();
$(".logs").each(function() {
const originalText = $(this).data('originalText') || $(this).val();
if (!$(this).data('originalText')) {
$(this).data('originalText', originalText);
}
const filteredLines = originalText.split('\n').filter(line =>
line.toLowerCase().includes(filterText)
);
$(this).val(filteredLines.join('\n'));
});
}
//------------------------------------------------------------------------------
// Renders all the logs
function renderLogs(customData) {
$.ajax({
url: 'php/components/logs.php', // PHP script URL
type: 'POST', // Use POST method to send data
dataType: 'html', // Expect HTML response
// data: { items: JSON.stringify(customData) }, // Send customData as JSON
success: function(response) {
$('#logsPlc').html(response); // Replace container content with fetched HTML
applyFilter();
if($('#logsAutoScroll')[0].checked)
{
scrollDown(); // scroll down the logs
}
},
error: function(xhr, status, error) {
console.error('Error fetching infoboxes:', error);
}
});
}
//------------------------------------------------------------------------------
// Init
window.onload = function asyncFooter()
{
initializeSelectedColumns();
scrollDown();
initializeTabs();
renderLogs();
// initializeTabs();
$("#lastCommit").append('<a href="https://github.com/jokob-sk/NetAlertX/commits" target="_blank"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/jokob-sk/netalertx/main?logo=github"></a>');
@@ -967,10 +996,6 @@ window.onload = function asyncFooter()
}
// scroll to the latest log entrie sat teh bottom of the file
</script>

View File

@@ -1,7 +1,5 @@
<div class="col-md-12">
<div class="callout callout-warning">
<h4><?= lang('Gen_Warning');?></h4>
@@ -102,26 +100,35 @@
// Append form groups to the column
for (let j = i * elementsPerColumn; j < Math.min((i + 1) * elementsPerColumn, columns.length); j++) {
let inputType;
const setTypeObject = JSON.parse(columns[j].Type.replace(/'/g, '"'));
// console.log(setTypeObject);
const lastElementObj = setTypeObject.elements[setTypeObject.elements.length - 1]
switch (columns[j].Type) {
case 'integer.checkbox':
case 'checkbox':
inputType = 'checkbox';
break;
case 'text.select':
inputType = 'text.select';
break;
default:
inputType = 'text';
break;
}
if (inputType === 'text.select') {
const { elementType, elementOptions = [], transformers = [] } = lastElementObj;
const {
inputType,
readOnly,
isMultiSelect,
cssClasses,
placeholder,
suffix,
sourceIds,
separator,
editable,
valRes,
getStringKey,
onClick
} = handleElementOptions('none', elementOptions, transformers, val = "");
targetLocation = columns[j].Code_Name + "_initSettingDropdown"
// console.log(setTypeObject);
// console.log(inputType);
initSettingDropdown(columns[j].Code_Name, [], targetLocation, generateDropdownOptions)
// render based on element type
if (lastElementObj.elementType === 'select') {
targetLocation = columns[j].Code_Name + "_generateSetOptions"
generateOptionsOrSetOptions(columns[j].Code_Name, [], targetLocation, generateOptions)
// Handle Icons as tehy need a preview
if(columns[j].Code_Name == 'NEWDEV_dev_Icon')
@@ -147,15 +154,11 @@
}
} else {
} else if (lastElementObj.elementType === 'input'){
// Add classes specifically for checkboxes
if (inputType === 'checkbox') {
inputClass = 'checkbox';
} else {
inputClass = 'form-control';
}
inputType === 'checkbox' ? inputClass = 'checkbox' : inputClass = 'form-control';
input = `<input class="${inputClass}"
id="${columns[j].Code_Name}"
@@ -290,7 +293,7 @@ function executeAction(action, whereColumnName, key, targetColumns, newTargetCol
// update API endpoints to refresh the UI
updateApi()
writeNotification(`[Multi edit] Executed "${action}" on Columns "${targetColumns}" matching "${key}"`, 'info')
write_notification(`[Multi edit] Executed "${action}" on Columns "${targetColumns}" matching "${key}"`, 'info')
} else {
showMessage(getString('Gen_LockedDB'));
@@ -317,7 +320,7 @@ function deleteSelectedDevices()
{
macs_tmp = selectorMacs()
executeAction('delete', 'dev_MAC', macs_tmp )
writeNotification('[Multi edit] Manually deleted devices with MACs:' + macs_tmp, 'info')
write_notification('[Multi edit] Manually deleted devices with MACs:' + macs_tmp, 'info')
}

View File

@@ -50,10 +50,10 @@
$decoded_icon = base64_decode($icon);
$idFromMac = str_replace(":", "_", $node_mac);
$str_tab_header = '<li class="'.$activetab.'">
$str_tab_header = '<li class="networkNodeTabHeaders '.$activetab.' " >
<a href="#'.$idFromMac.'" data-mytabmac="'.$node_mac.'" id="'.$idFromMac.'_id" data-toggle="tab" >' // _id is added so it doesn't conflict with AdminLTE tab behavior
.'<div class="icon">'.$decoded_icon.' </div>'.$node_name.' ' .$str_port.$node_badge.
<a href="#'.$idFromMac.'" data-mytabmac="'.$node_mac.'" id="'.$idFromMac.'_id" data-toggle="tab" title="'.$node_name.' ">' // _id is added so it doesn't conflict with AdminLTE tab behavior
.'<div class="icon">'.$decoded_icon.' </div> <span class="node-name">'.$node_name.'</span>' .$str_port.$node_badge.
'</a>
</li>';
@@ -464,7 +464,7 @@
<script src="lib/treeviz/require.js"></script>
<script>
<script defer>
$.get('php/server/devices.php?action=getDevicesList&status=all&forceDefaultOrder', function(data) {
rawData = JSON.parse (data)
@@ -528,8 +528,10 @@
for(var i in list)
{
//... of the current node
if(list[i].parentMac == node.mac && !hiddenMacs.includes(list[i].parentMac))
if(list[i].parentMac.toLowerCase() == node.mac.toLowerCase() && !hiddenMacs.includes(list[i].parentMac))
{
visibleNodesCount++
// and process them
@@ -546,7 +548,6 @@
{
parentNodesCount++
}
return {
name: node.name,
@@ -570,7 +571,6 @@
function getHierarchy()
{
for(i in deviceListGlobal)
{
if(deviceListGlobal[i].mac == 'Internet')
@@ -615,10 +615,10 @@
}
// ---------------------------------------------------------------------------
// Handle network node click - select correct tab in teh bottom table
// Handle network node click - select correct tab in the bottom table
function handleNodeClick(event)
{
console.log(event.target.offsetParent.offsetParent)
// console.log(event.target.offsetParent.offsetParent)
const targetTabMAC = $(event.target.offsetParent.offsetParent).attr("data-mytreemacmain");
@@ -630,14 +630,24 @@
// ---------------------------------------------------------------------------
var myTree;
var visibleTreeArea = $(window).height()-135;
var treeAreaHeight = visibleTreeArea > 800 ? 800 : visibleTreeArea;
var visibleTreeArea = $(window).height()-155;
var nodeWidth = 160;
var emSize;
var nodeHeight;
var sizeCoefficient = 1
function initTree(myHierarchy)
{
console.log(myHierarchy)
// calculate the drawing area based on teh tree width and available screen size
var treeAreaHeight = visibleTreeArea > 800 ? 800 : visibleTreeArea;
let screenWidth = $('.content-header').width();
let treeWidth = (nodeWidth + 20) * parentNodesCount;
let treeAreaWidth = screenWidth < treeWidth ? treeWidth : screenWidth;
// init the drawing area size
$("#networkTree").attr('style', `height:${treeAreaHeight}px; width:${treeAreaWidth}px`)
if(myHierarchy.type == "")
{
@@ -654,7 +664,7 @@
// nodeHeight = ((emSize*100*0.30).toFixed(0))
nodeHeight = ((emSize*100*0.30).toFixed(0))
$("#networkTree").attr('style', `height:${treeAreaHeight}px; width:${$('.content-header').width()}px`)
console.log(Treeviz);
myTree = Treeviz.create({
htmlId: "networkTree",
@@ -703,7 +713,7 @@
>
<div class="netNodeText">
<strong>${devicePort} ${deviceIcon}
<span class="spanNetworkTree anonymizeDev">${nodeData.data.name}</span>
<span class="spanNetworkTree anonymizeDev" >${nodeData.data.name}</span>
</strong>
${collapseExpandHtml}
</div>
@@ -718,8 +728,8 @@
secondaryAxisNodeSpacing: 0.3,
nodeHeight: nodeHeight.toString(),
marginTop: '5',
hasZoom: false,
hasPan: false,
hasZoom: true,
hasPan: true,
// marginLeft: '15',
idKey: "id",
hasFlatData: false,
@@ -728,8 +738,8 @@
onNodeClick: (nodeData) => handleNodeClick(nodeData),
relationnalField: "children",
});
console.log(myHierarchy)
myTree.refresh(myHierarchy);

94
front/php/components/logs.php Executable file
View File

@@ -0,0 +1,94 @@
<?php
require '../server/init.php';
// Function to render the log area component
function renderLogArea($params) {
$fileName = isset($params['fileName']) ? $params['fileName'] : '';
$filePath = isset($params['filePath']) ? $params['filePath'] : '';
$textAreaCssClass = isset($params['textAreaCssClass']) ? $params['textAreaCssClass'] : '';
$buttons = isset($params['buttons']) ? $params['buttons'] : [];
$content = "";
if (filesize($filePath) > 2000000) {
$content = file_get_contents($filePath, false, null, -2000000);
} else {
$content = file_get_contents($filePath);
}
// Prepare the download button HTML if filePath starts with /app/front
$downloadButtonHtml = '';
if (strpos($filePath, '/app/front') === 0) {
$downloadButtonHtml = '
<span class="span-padding">
<a href="' . htmlspecialchars(str_replace('/app/front', '', $filePath)) . '" target="_blank">
<i class="fa fa-download"></i>
</a>
</span>';
}
// Prepare buttons HTML
$buttonsHtml = '';
$totalButtons = count($buttons);
if ($totalButtons > 0) {
$colClass = 12 / $totalButtons;
// Use $colClass in your HTML generation or further logic
} else {
// Handle case where $buttons array is empty
$colClass = 12;
}
foreach ($buttons as $button) {
$labelStringCode = isset($button['labelStringCode']) ? $button['labelStringCode'] : '';
$event = isset($button['event']) ? $button['event'] : '';
$buttonsHtml .= '
<div class="button-wrap col-sm-' . $colClass . ' col-xs-' . $colClass . '">
<button class="btn btn-primary col-sm-12 col-xs-12" onclick="' . htmlspecialchars($event) . '">' . lang($labelStringCode) . '</button>
</div>';
}
// Render the log area HTML
$html = '
<div class="log-area box box-solid box-primary">
<div class="row logs-row col-sm-12 col-xs-12">
<textarea class="' . htmlspecialchars($textAreaCssClass) . '" cols="70" rows="20" wrap="off" readonly>'
. htmlspecialchars($content) .
'</textarea>
</div>
<div class="row logs-row">
<div class="log-file col-sm-6 col-xs-12">' . htmlspecialchars($fileName) . '
<div class="logs-size">' . number_format((filesize($filePath) / 1000000), 2, ",", ".") . ' MB'
. $downloadButtonHtml .
'</div>
</div>
<div class="col-sm-6 col-xs-12">'
. $buttonsHtml .
'</div>
</div>
</div>';
return $html;
}
// Load default data from JSON file
$defaultDataFile = 'logs_defaults.json';
$defaultData = file_exists($defaultDataFile) ? json_decode(file_get_contents($defaultDataFile), true) : [];
// Check if JSON data is submitted via POST
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['items'])) {
$items = json_decode($_POST['items'], true);
} else {
$items = $defaultData;
}
// Render the log areas with the retrieved or default data
$html = '';
foreach ($items as $item) {
$html .= renderLogArea($item);
}
echo $html;
exit();
?>

View File

@@ -0,0 +1,98 @@
[
{
"buttons": [
{
"labelStringCode": "Maint_PurgeLog",
"event": "logManage('app.log', 'cleanLog')"
},
{
"labelStringCode": "Maint_RestartServer",
"event": "askRestartBackend()"
}
],
"fileName": "app.log",
"filePath": "/app/front/log/app.log",
"textAreaCssClass": "logs"
},
{
"buttons": [
{
"labelStringCode": "Maint_PurgeLog",
"event": "logManage('app_front.log', 'cleanLog')"
}
],
"fileName": "app_front.log",
"filePath": "/app/front/log/app_front.log",
"textAreaCssClass": "logs logs-small"
},
{
"buttons": [
{
"labelStringCode": "Maint_PurgeLog",
"event": "logManage('app.php_errors.log', 'cleanLog')"
}
],
"fileName": "app.php_errors.log",
"filePath": "/app/front/log/app.php_errors.log",
"textAreaCssClass": "logs logs-small"
},
{
"buttons": [
{
"labelStringCode": "Maint_PurgeLog",
"event": "logManage('execution_queue.log', 'cleanLog')"
}
],
"fileName": "execution_queue.log",
"filePath": "/app/front/log/execution_queue.log",
"textAreaCssClass": "logs logs-small"
},
{
"buttons": [
],
"fileName": "nginx/error.log",
"filePath": "/var/log/nginx/error.log",
"textAreaCssClass": "logs logs-small"
},
{
"buttons": [
{
"labelStringCode": "Maint_PurgeLog",
"event": "logManage('app_front.log', 'cleanLog')"
}
],
"fileName": "app_front.log",
"filePath": "/app/front/log/app_front.log",
"textAreaCssClass": "logs logs-small"
},
{
"buttons": [
],
"fileName": "db_is_locked.log",
"filePath": "/app/front/log/db_is_locked.log",
"textAreaCssClass": "logs logs-small"
},
{
"buttons": [
{
"labelStringCode": "Maint_PurgeLog",
"event": "logManage('stdout.log', 'cleanLog')"
}
],
"fileName": "stdout.log",
"filePath": "/app/front/log/stdout.log",
"textAreaCssClass": "logs logs-small"
},
{
"buttons": [
{
"labelStringCode": "Maint_PurgeLog",
"event": "logManage('stderr.log', 'cleanLog')"
}
],
"fileName": "stderr.log",
"filePath": "/app/front/log/stderr.log",
"textAreaCssClass": "logs logs-small"
}
]

View File

@@ -463,15 +463,29 @@ function ExportCSV() {
// Import CSV of devices
//------------------------------------------------------------------------------
function ImportCSV() {
$file = '../../../config/devices.csv';
if (file_exists($file)) {
global $db;
$skipped = "";
$error = "";
global $db;
$file = '../../../config/devices.csv';
$data = "";
$skipped = "";
$error = "";
// check if content passed in query string
if(isset ($_POST['content']) && !empty ($_POST['content']))
{
// Decode the Base64 string
$data = base64_decode($_POST['content']);
} else if (file_exists($file)) { // try to get the data form the file
// Read the CSV file
$data = file_get_contents($file);
} else {
echo lang('BackDevices_DBTools_ImportCSVMissing');
}
if($data != "")
{
$lines = explode("\n", $data);
// Get the column headers from the first line of the CSV
@@ -517,8 +531,6 @@ function ImportCSV() {
// An error occurred while writing to the DB, display the last error message
echo lang('BackDevices_DBTools_ImportCSVError') . "\n" . $error . "\n" . $sql . "\n\n" . $result;
}
} else {
echo lang('BackDevices_DBTools_ImportCSVMissing');
}
}
@@ -901,18 +913,11 @@ function copyFromDevice() {
$MAC_FROM = $_REQUEST['macFrom'];
$MAC_TO = $_REQUEST['macTo'];
if ((false === filter_var($MAC_FROM , FILTER_VALIDATE_MAC) && $MAC_FROM != "Internet" && $MAC_FROM != "") ) {
throw new Exception('Invalid mac address');
}
if ((false === filter_var($MAC_TO , FILTER_VALIDATE_MAC) && $MAC_TO != "Internet" && $MAC_TO != "") ) {
throw new Exception('Invalid mac address');
}
global $db;
// clean-up temporary table
$sql = "DROP TABLE temp_devices ";
$sql = "DROP TABLE IF EXISTS temp_devices ";
$result = $db->query($sql);
// create temporary table with the source data

View File

@@ -28,10 +28,7 @@ if(array_key_exists('settings', $_REQUEST) != FALSE)
// call functions based on requested params
switch ($FUNCTION) {
case 'restartBackend':
restartBackend();
break;
case 'savesettings':
saveSettings();
@@ -228,6 +225,8 @@ function displayMessage($message, $logAlert = FALSE, $logConsole = TRUE, $logFil
}
// ----------------------------------------------------------------------------------------
// Adds an action to perform into the execution_queue.log file
function addToExecutionQueue($action)
{
@@ -247,27 +246,6 @@ function addToExecutionQueue($action)
}
// ----------------------------------------------------------------------------------------
function restartBackend()
{
$command = 'pkill -f "python /app/server" && (python /app/server > /dev/null 2>&1 &) && echo "done" 2>&1';
// Execute the command
$output = [];
$output_str = "";
$return_var = 0;
exec($command, $output, $return_var);
// Format the output
foreach ($output as $line) {
$output_str .= $line . "\n";
}
echo "Command result: $return_var, $output_str";
}
// ----------------------------------------------------------------------------------------
function cleanLog($logFile)
@@ -276,7 +254,7 @@ function cleanLog($logFile)
$path = "";
$allowedFiles = ['app.log', 'app_front.log', 'IP_changes.log', 'stdout.log', 'stderr.log', "pholus_lastrun.log", 'app.php_errors.log'];
$allowedFiles = ['app.log', 'app_front.log', 'IP_changes.log', 'stdout.log', 'stderr.log', "pholus_lastrun.log", 'app.php_errors.log', 'execution_queue.log'];
if(in_array($logFile, $allowedFiles))
{
@@ -328,7 +306,7 @@ function saveSettings()
$txt = $txt."# Generated: ".$timestamp." #\n";
$txt = $txt."# #\n";
$txt = $txt."# Config file for the LAN intruder detection app: #\n";
$txt = $txt."# https://github.com/jokob-sk/NetAlertX #\n";
$txt = $txt."# https://github.com/jokob-sk/NetAlertX #\n";
$txt = $txt."# #\n";
$txt = $txt."#-----------------AUTOGENERATED FILE-----------------#\n";
@@ -348,56 +326,57 @@ function saveSettings()
$txt .= "\n#---------------------------\n";
foreach ($decodedSettings as $setting) {
$settingGroup = $setting[0];
$settingKey = $setting[1];
$settingType = $setting[2];
$settingValue = $setting[3];
// sanity check
if($settingKey == "UI_LANG" && $settingValue == "")
{
$settingGroup = $setting[0];
$settingKey = $setting[1];
$dataType = $setting[2];
$settingValue = $setting[3];
// // Parse the settingType JSON
// $settingType = json_decode($settingTypeJson, true);
// Sanity check
if($settingKey == "UI_LANG" && $settingValue == "") {
echo "🔴 Error: important settings missing. Refresh the page with 🔃 on the top and try again.";
return;
}
}
if ($group == $settingGroup) {
if ($dataType == 'string' ) {
$val = encode_single_quotes($settingValue);
$txt .= $settingKey . "='" . $val . "'\n";
} elseif ($dataType == 'integer') {
$txt .= $settingKey . "=" . $settingValue . "\n";
} elseif ($dataType == 'json') {
$txt .= $settingKey . "=" . $settingValue . "\n";
} elseif ($dataType == 'boolean') {
$val = ($settingValue === true || $settingValue === 1 || strtolower($settingValue) === 'true') ? "True" : "False";
$txt .= $settingKey . "=" . $val . "\n";
} elseif ($dataType == 'array' ) {
$temp = '';
if(is_array($settingValue) == FALSE)
{
$settingValue = json_decode($settingValue);
}
// skipping __metadata entries (?)
if (count($setting) > 3 && is_array($settingValue) == true) {
foreach ($settingValue as $val) {
$temp .= "'" . encode_single_quotes($val) . "',";
}
if ($group == $settingGroup) {
if ($settingType == 'text' || $settingType == 'password' || $settingType == 'password.SHA256' || $settingType == 'readonly' || $settingType == 'text.select') {
$val = encode_single_quotes($settingValue);
$txt .= $settingKey . "='" . $val . "'\n";
} elseif ($settingType == 'integer' || $settingType == 'integer.select') {
$txt .= $settingKey . "=" . $settingValue . "\n";
} elseif ($settingType == 'boolean' || $settingType == 'integer.checkbox') {
$temp = substr_replace($temp, "", -1); // remove last comma ','
}
if ($settingValue === true || $settingValue === 1 || strtolower($settingValue) === 'true') {
$val = "True";
} else {
$val = "False";
}
$txt .= $settingKey . "=" . $val . "\n";
} elseif ($settingType == 'text.multiselect' || $settingType == 'subnets' || $settingType == 'list' || $settingType == 'list.select') {
$temp = '';
if(is_array($settingValue) == FALSE)
{
$settingValue = json_decode($settingValue);
}
if (count($setting) > 3 && is_array($settingValue) == true) {
foreach ($settingValue as $val) {
$temp .= "'" . encode_single_quotes($val) . "',";
}
$temp = substr_replace($temp, "", -1); // remove last comma ','
}
$temp = '['.$temp.']'; // wrap brackets
$txt .= $settingKey . "=" . $temp . "\n";
} elseif ($settingType == 'json') {
$txt .= $settingKey . "=" . $settingValue . "\n";
}
}
}
$temp = '['.$temp.']'; // wrap brackets
$txt .= $settingKey . "=" . $temp . "\n";
} else {
$txt .= $settingKey . "='⭕Not handled⭕'\n";
}
}
}
}

View File

@@ -3,7 +3,7 @@
require dirname(__FILE__).'/../templates/timezone.php';
// ----------------------------------------------------------------------------------------
// Check if the action parameter is set in the GET request
if (isset($_GET['action'])) {
// Collect GUID if provided
@@ -46,6 +46,8 @@ if (isset($_GET['action'])) {
}
}
// ----------------------------------------------------------------------------------------
// Generates a random GUID
function generate_guid() {
if (function_exists('com_create_guid') === true) {
return trim(com_create_guid(), '{}');
@@ -54,8 +56,10 @@ function generate_guid() {
mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535),
mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535),
mt_rand(0, 65535), mt_rand(0, 65535));
}
}
// ----------------------------------------------------------------------------------------
// Logs a notification in in-app notification system
function write_notification($content, $level = "interrupt") {
$NOTIFICATION_API_FILE = '/app/front/api/user_notifications.json';
@@ -87,6 +91,8 @@ function write_notification($content, $level = "interrupt") {
file_put_contents($NOTIFICATION_API_FILE, json_encode($notifications));
}
// ----------------------------------------------------------------------------------------
// Removes a notification based on GUID
function remove_notification($guid) {
$NOTIFICATION_API_FILE = '/app/front/api/user_notifications.json';
@@ -102,6 +108,8 @@ function remove_notification($guid) {
file_put_contents($NOTIFICATION_API_FILE, json_encode(array_values($filtered_notifications)));
}
// ----------------------------------------------------------------------------------------
// Deletes all notifications
function notifications_clear() {
$NOTIFICATION_API_FILE = '/app/front/api/user_notifications.json';
@@ -109,6 +117,8 @@ function notifications_clear() {
file_put_contents($NOTIFICATION_API_FILE, json_encode(array()));
}
// ----------------------------------------------------------------------------------------
// Mark a notification read based on GUID
function mark_notification_as_read($guid) {
$NOTIFICATION_API_FILE = '/app/front/api/user_notifications.json';
$max_attempts = 3;
@@ -152,10 +162,12 @@ function mark_notification_as_read($guid) {
echo "Failed to read notification file after $max_attempts attempts.";
}
// ----------------------------------------------------------------------------------------
function notifications_mark_all_read() {
mark_notification_as_read(null);
}
// ----------------------------------------------------------------------------------------
function get_unread_notifications() {
$NOTIFICATION_API_FILE = '/app/front/api/user_notifications.json';

35
front/php/templates/auth.php Executable file
View File

@@ -0,0 +1,35 @@
<?php
session_start();
$isAuthenticated = false;
// Check if the user is logged in
if (isset($_SESSION["login"]) && $_SESSION["login"] == 1) {
$isAuthenticated = true;
}
// $current_directory = __DIR__;
// echo "Current directory: " . $current_directory;
// Check if a valid cookie is present
$CookieSaveLoginName = "NetAlertX_SaveLogin";
$config_file = "../../../config/app.conf"; // depends on where this file is called from
$config_file_lines = file($config_file);
$config_file_lines = array_values(preg_grep('/^SETPWD_password.*=/', $config_file_lines));
$password_line = explode("'", $config_file_lines[0]);
$Pia_Password = $password_line[1];
if (isset($_COOKIE[$CookieSaveLoginName]) && $Pia_Password == $_COOKIE[$CookieSaveLoginName]) {
$isAuthenticated = true;
}
if ($isAuthenticated) {
echo 'Authorized 200';
http_response_code(200);
exit; // Important: Ensure script exits after successful authentication
} else {
http_response_code(401);
echo 'Unauthorized 401';
exit; // Ensure script exits after failed authentication
}
?>

View File

@@ -55,7 +55,7 @@
<!-- NetAlertX -->
<script src="js/handle_version.js"></script>
<script src="js/ui_components.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<script src="js/db_methods.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<!-- Select2 JavaScript -->
<script src="lib/AdminLTE/bower_components/select2/dist/js/select2.full.min.js" defer></script>

View File

@@ -33,6 +33,8 @@ require dirname(__FILE__).'/security.php';
<script src="js/common.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<script src="js/modal.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<script src="js/tests.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<script src="js/db_methods.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<script src="js/settings_utils.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<!-- Bootstrap 3.3.7 -->
<link rel="stylesheet" href="lib/AdminLTE/bower_components/bootstrap/dist/css/bootstrap.min.css">
@@ -339,7 +341,7 @@ if ($ENABLED_DARKMODE === True) {
</a>
<ul class="treeview-menu" style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('settings.php') ) ){ echo 'block'; } else {echo 'none';} ?>;">
<li>
<a href="settings.php#pageTitle"> <?= lang("settings_enabled");?> </a>
<a href="settings.php#settingsOverview"> <?= lang("settings_enabled");?> </a>
</li>
<li>
<a href="settings.php#core_content_header"> <?= lang("settings_core_label");?> </a>
@@ -348,13 +350,13 @@ if ($ENABLED_DARKMODE === True) {
<a href="settings.php#system_content_header"> <?= lang("settings_system_label");?> </a>
</li>
<li>
<a href="settings.php#device_scanner_content_header"> <?= lang("settings_device_scanners_label");?> </a>
<a href="settings.php#device_scanners_content_header"> <?= lang("settings_device_scanners_label");?> </a>
</li>
<li>
<a href="settings.php#other_content_header"> <?= lang("settings_other_scanners_label");?> </a>
<a href="settings.php#other_scanners_content_header"> <?= lang("settings_other_scanners_label");?> </a>
</li>
<li>
<a href="settings.php#publisher_content_header"> <?= lang("settings_publishers_label");?> </a>
<a href="settings.php#publishers_content_header"> <?= lang("settings_publishers_label");?> </a>
</li>
</ul>
@@ -370,7 +372,7 @@ if ($ENABLED_DARKMODE === True) {
</a>
<ul class="treeview-menu " style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('plugins.php', 'workflows.php' ) ) ){ echo 'block'; } else {echo 'none';} ?>;">
<li>
<div class="info-icon-nav work-in-progress"> </div>
<div class="info-icon-nav"> </div>
<a href="workflows.php"><?= lang('Navigation_Workflows');?></a>
</li>
<li>
@@ -414,7 +416,7 @@ if ($ENABLED_DARKMODE === True) {
// Generate work-in-progress icons
function workInProgress() {
if($(".work-in-progress").html().trim() == "")
if($(".work-in-progress").length > 0 && $(".work-in-progress").html().trim() == "")
{
$(".work-in-progress").append(`
<a href="https://github.com/jokob-sk/NetAlertX/issues" target="_blank">

44
front/php/templates/language/de_de.json Executable file → Normal file
View File

@@ -5,7 +5,7 @@
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"APPRISE_HOST_description": "Apprise host URL starting with <code>http://</code> or <code>https://</code>. (do not forget to include <code>/notify</code> at the end)",
"APPRISE_HOST_name": "Apprise host URL",
"APPRISE_PAYLOAD_description": "Select the payoad type sent to Apprise. For example <code>html</code> works well with emails, <code>text</code> with chat apps, such as Telegram.",
"APPRISE_PAYLOAD_description": "Select the payload type sent to Apprise. For example <code>html</code> works well with emails, <code>text</code> with chat apps, such as Telegram.",
"APPRISE_PAYLOAD_name": "Payload type",
"APPRISE_SIZE_description": "The maximum size of the apprise payload as number of characters in the passed string. If above limit, it will be truncated and a <code>(text was truncated)</code> message is appended.",
"APPRISE_SIZE_name": "Max payload size",
@@ -13,7 +13,7 @@
"APPRISE_URL_name": "Apprise notification URL",
"About_Design": "Designed for:",
"About_Exit": "Abmelden",
"About_Title": "Open Source Network Guard",
"About_Title": "Netzwerksicherheitsscanner und Benachrichtigungsframework",
"AppEvents_DateTimeCreated": "protokolliert",
"AppEvents_Extra": "Extra",
"AppEvents_GUID": "Anwendungsereignis-GUID",
@@ -93,17 +93,17 @@
"DevDetail_MainInfo_Group": "Gruppe",
"DevDetail_MainInfo_Location": "Standort",
"DevDetail_MainInfo_Name": "Name",
"DevDetail_MainInfo_Network": "Netzwerk Knoten",
"DevDetail_MainInfo_Network_Port": "Netzwerk Knoten Port",
"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_Title": "<i class=\"fa fa-network-wired\"></i> Network",
"DevDetail_MainInfo_Owner": "Eigen&shy;tümer",
"DevDetail_MainInfo_SSID": "",
"DevDetail_MainInfo_Title": "Haupt Infos",
"DevDetail_MainInfo_Title": "<i class=\"fa fa-pencil\"></i> Hauptinformation",
"DevDetail_MainInfo_Type": "Typ",
"DevDetail_MainInfo_Vendor": "Hersteller",
"DevDetail_MainInfo_mac": "MAC",
"DevDetail_Network_Node_hover": "Select the parent network device the current device is connected to to populate the Network tree.",
"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_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 mehr herauszufinden.",
@@ -129,7 +129,7 @@
"DevDetail_SessionInfo_LastSession": "Letzte Sitzung",
"DevDetail_SessionInfo_StaticIP": "Statische IP",
"DevDetail_SessionInfo_Status": "Status",
"DevDetail_SessionInfo_Title": "Sitzungsinfos",
"DevDetail_SessionInfo_Title": "<i class=\"fa fa-calendar\"></i> Sitzungsinformation",
"DevDetail_SessionTable_Additionalinfo": "Zusätzliche Info",
"DevDetail_SessionTable_Connection": "Verbindung",
"DevDetail_SessionTable_Disconnection": "Trennung",
@@ -140,13 +140,13 @@
"DevDetail_Shortcut_DownAlerts": "Down Meldungen",
"DevDetail_Shortcut_Presence": "Anwesenheit",
"DevDetail_Shortcut_Sessions": "Sitzungen",
"DevDetail_Tab_Details": "Details",
"DevDetail_Tab_Events": "Ereignisse",
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Details",
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Ereignisse",
"DevDetail_Tab_EventsTableDate": "Datum",
"DevDetail_Tab_EventsTableEvent": "Ereignistype",
"DevDetail_Tab_EventsTableIP": "IP",
"DevDetail_Tab_EventsTableInfo": "Zusätzliche Informationen",
"DevDetail_Tab_Nmap": "Nmap",
"DevDetail_Tab_Nmap": "<i class=\"fa fa-ethernet\"></i> Nmap",
"DevDetail_Tab_NmapEmpty": "An diesem Gerät wurden keine offenen Ports mit Nmap gefunden.",
"DevDetail_Tab_NmapTableExtra": "Extra",
"DevDetail_Tab_NmapTableHeader": "Ergebnisse geplanter Scans",
@@ -157,8 +157,8 @@
"DevDetail_Tab_NmapTableText": "Erstelle einen Plan über die<a href=\"/settings.php#NMAP_ACTIVE\">Einstellungen</a>",
"DevDetail_Tab_NmapTableTime": "Zeit",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins",
"DevDetail_Tab_Presence": "Anwesenheit",
"DevDetail_Tab_Sessions": "Sitzungen",
"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_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",
@@ -314,17 +314,17 @@
"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. Geräte markiert als <b>Neues Gerät</b> werden gelöscht, wenn ihre <b>Erste Sitzung</b> länger her ist als die angegebenen Stunden in dieser Einstellung. <code>0</code> deaktiviert diese Funktion. Nutzen Sie diese Einstellung, um <b>Neue Geräte</b> automatisch nach <code>X</code> Stunden zu löschen.",
"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",
"HelpFAQ_Cat_Detail": "Detailansicht",
"HelpFAQ_Cat_Detail_300_head": "Was bedeutet ",
"HelpFAQ_Cat_Detail_300_text_a": "meint ein Netzwerkgerät (welches den typ AP, Gateway, Firewall, Hypervisor, Powerline, Switch, WLAN, PLC, Router,USB LAN Adapter, USB WIFI Adapter, or Internet eingestellt hat)",
"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.",
"HelpFAQ_Cat_Detail_300_text_b": "bezeichnet die Anschlussnummer/Portnummer, an der das gerade bearbeitete Gerät mit diesem Netzwerkgerät verbunden ist. Siehe <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md\">diese Dokumentation</a> für mehr informationen.",
"HelpFAQ_Cat_Detail_301_head_a": "Wann wird nun gescannt? Bei ",
"HelpFAQ_Cat_Detail_301_head_b": " steht 1min aber der Graph zeigt 5min - Abstände an.",
"HelpFAQ_Cat_Detail_301_text": "Den zeitlichen Abstand zwischen den Scans legt der \"Cronjob\" fest, welcher standardmäßig auf 5min eingestellt ist. Die Benennung \"1min\" bezieht sich auf die zu erwartende Dauer des Scans. Abhängig vor der Netzwerkkonfiguration kann diese Zeitangabe variieren. Um den Cronjob zu bearbeiten, kannst du im Terminal/der Konsole <span class=\"text-danger help_faq_code\">crontab -e</span> eingeben und den Intervall ändern.",
"HelpFAQ_Cat_Detail_302_head_a": "Was bedeutet ",
"HelpFAQ_Cat_Detail_302_head_b": " und warum kann ich das nicht auswählen?",
"HelpFAQ_Cat_Detail_302_head_b": "und warum kann ich das nicht auswählen?",
"HelpFAQ_Cat_Detail_302_text": "Einige moderne Geräte generieren aus Datenschutzgründen zufällige MAC-Adressen, die keinem Hersteller mehr zugeordnet werden können und welche sich mit jeder neuen Verbindung ändern. NetAlertX erkennt, ob es sich um eine solche zufällige MAC-Adresse handelt und aktiviert dieses \"Feld\" automatisch. Um das Verhalten abzustellen, musst du in deinem Endgerät schauen, wie du die MAC-Adressen-Generierung deaktivierst.",
"HelpFAQ_Cat_Detail_303_head": "Was ist Nmap und wozu dient es?",
"HelpFAQ_Cat_Detail_303_text": "Nmap ist ein Netzwerkscanner mit vielfältigen Möglichkeiten.<br> Wenn ein neues Gerät in deiner Liste auftaucht, hast du die Möglichkeit über den Nmap-Scan genauere Informationen über das Gerät zu erhalten.",
@@ -384,17 +384,23 @@
"MQTT_USER_name": "MQTT user",
"MQTT_display_name": "MQTT",
"MQTT_icon": "<i class=\"fa fa-square-rss\"></i>",
"Maint_PurgeLog": "",
"Maint_RestartServer": "",
"Maint_Restart_Server_noti_text": "",
"Maintenance_Running_Version": "Installierte Version",
"Maintenance_Status": "Status",
"Maintenance_Title": "Wartungswerkzeuge",
"Maintenance_Tool_ExportCSV": "CSV Export",
"Maintenance_Tool_ExportCSV_noti": "CSV Export",
"Maintenance_Tool_ExportCSV_noti_text": "Sind Sie sich sicher, dass Sie die CSV-Datei erstellen wollen?",
"Maintenance_Tool_ExportCSV_text": "Generiere eine CSV-Datei (comma separated values) mit einer Liste aller Geräte und deren Beziehungen zwischen Netzwerkknoten und verbundenen Geräten. Dies kann auch durch das Besuchen dieser URL <code>your NetAlertX url/php/server/devices.php?action=ExportCSV</code> ausgelöst werden.",
"Maintenance_Tool_ExportCSV_text": "Generiere eine CSV-Datei (comma separated values) mit einer Liste aller Geräte und deren Beziehungen zwischen Netzwerkknoten und verbundenen Geräten. Dies kann auch durch das Besuchen der URL <code>your NetAlertX url/php/server/devices.php?action=ExportCSV</code> oder durch Aktivieren des <a href=\"settings.php#CSVBCKP_header\">CSV-Backups</a> ausgelöst werden.",
"Maintenance_Tool_ImportCSV": "CSV Import",
"Maintenance_Tool_ImportCSV_noti": "CSV Import",
"Maintenance_Tool_ImportCSV_noti_text": "Sind Sie sich sicher, dass Sie die CSV-Datei importieren wollen? Dies wird alle Geräte in der Datenbank überschreiben.",
"Maintenance_Tool_ImportCSV_noti_text": "Sind Sie sich sicher, dass Sie die CSV-Datei importieren wollen? Dies wird <b>alle Geräte in der Datenbank überschreiben</b>.",
"Maintenance_Tool_ImportCSV_text": "Machen Sie ein Backup, bevor Sie diese Funk­tion nutzen. Importiere eine CSV-Datei (comma separated values) mit einer Liste aller Geräte und deren Beziehungen zwischen Netzwerkknoten und verbundenen Geräten. Um dies zu tun platziere die <b>devices.csv</b> benannte CSV-Datei in deinen <b>/config</b> Ordner.",
"Maintenance_Tool_ImportPastedCSV": "",
"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_noti_text": "Wenn der Scan aus ist, bleibt er so lange aus bis er wieder aktiviert wird.",
@@ -730,7 +736,7 @@
"Webhooks_display_name": "Webhooks",
"Webhooks_icon": "<i class=\"fa fa-circle-nodes\"></i>",
"devices_old": "Aktualisiert...",
"general_event_description": " The event you have triggered might take a while until background processes finish. The execution ended once you see <code>finished</code> below. Check the <a href='/maintenance.php#tab_Logging'>error log</a> if you didn not get the expected result. <br/> <br/> Status: ",
"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",
"report_guid": "",
"report_guid_missing": "",
@@ -765,4 +771,4 @@
"settings_update_item_warning": "",
"test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Save your changes at first before you test your settings."
}
}

12
front/php/templates/language/en_us.json Executable file → Normal file
View File

@@ -358,6 +358,9 @@
"Login_Toggle_Alert_headline": "Password Alert!",
"Login_Toggle_Info": "Password Information",
"Login_Toggle_Info_headline": "Password Information",
"Maint_PurgeLog": "Purge log",
"Maint_RestartServer": "Restart server",
"Maint_Restart_Server_noti_text": "Are you sure you want to restart the backend server? This may casue app inconsistency. Backup your setup first. <br/> <br/> Note: This may take a few minutes.",
"Maintenance_Running_Version": "Installed version",
"Maintenance_Status": "Status",
"Maintenance_Title": "Maintenance tools",
@@ -367,8 +370,11 @@
"Maintenance_Tool_ExportCSV_text": "Generate a CSV (comma separated value) file containing the list of Devices including the Network relationships between Network Nodes and connected devices. You can also trigger this by accessing this URL <code>your NetAlertX url/php/server/devices.php?action=ExportCSV</code> or by enabling the <a href=\"settings.php#CSVBCKP_header\">CSV Backup</a> plugin.",
"Maintenance_Tool_ImportCSV": "CSV Import",
"Maintenance_Tool_ImportCSV_noti": "CSV Import",
"Maintenance_Tool_ImportCSV_noti_text": "Are you sure you want to import the CSV file? This will completely overwrite the devices in your database.",
"Maintenance_Tool_ImportCSV_noti_text": "Are you sure you want to import the CSV file? This will completely <b>overwrite</b> the devices in your database.",
"Maintenance_Tool_ImportCSV_text": "Before using this function, please make a backup. Import a CSV (comma separated value) file containing the list of Devices including the Network relationships between Network Nodes and connected devices. To do that place the CSV file named <b>devices.csv</b> into your <b>/config</b> folder.",
"Maintenance_Tool_ImportPastedCSV": "CSV Import (Paste)",
"Maintenance_Tool_ImportPastedCSV_noti_text": "Are you sure you want to import the pasted CSV? This will completely <b>overwrite</b> the devices in your database.",
"Maintenance_Tool_ImportPastedCSV_text": "Before using this function, please make a backup. Import a CSV (comma separated value) file containing the list of Devices including the Network relationships between Network Nodes and connected devices.",
"Maintenance_Tool_arpscansw": "Toggle arp-Scan (on/off)",
"Maintenance_Tool_arpscansw_noti": "Toggle arp-Scan on or off",
"Maintenance_Tool_arpscansw_noti_text": "When the scan has been switched off it remains off until it is activated again.",
@@ -649,7 +655,7 @@
"UI_REFRESH_description": "Enter number of seconds after which the UI reloads. Set to <code>0</code> to disable.",
"UI_REFRESH_name": "Auto-refresh UI",
"devices_old": "Refreshing...",
"general_event_description": "The event you have triggered might take a while until background processes finish. The execution ended once the below execution queue empties (Check the <a href='/maintenance.php#tab_Logging'>error log</a> if you encounter issues). <br/> <br/> Execution queue:",
"general_event_description": "The event you have triggered might take a while until background processes finish. The execution ended once the below execution queue empties (Check the <a href='/maintenance.php#tab_Logging'>error log</a> if you encounter issues). <br/> <br/> Execution queue:",
"general_event_title": "Executing an ad-hoc event",
"report_guid": "Notification guid:",
"report_guid_missing": "Linked notification not found. There is a small delay between recently sent notifications and them being available. Referesh your page and cache after a few seconds. It's also possible the selected notification have been deleted during maintenance as specified in the <code>DBCLNP_NOTIFI_HIST</code> setting. <br/> <br/>The latest notification is displayed instead. The missing notification has the following GUID:",
@@ -684,4 +690,4 @@
"settings_update_item_warning": "Update the value below. Be careful to follow the previous format. <b>Validation is not performed.</b>",
"test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Save your changes at first before you test your settings."
}
}

22
front/php/templates/language/es_es.json Executable file → Normal file
View File

@@ -93,10 +93,10 @@
"DevDetail_MainInfo_Name": "Nombre",
"DevDetail_MainInfo_Network": "<i class=\"fa fa-server\"></i> Nodo (MAC)",
"DevDetail_MainInfo_Network_Port": "<i class=\"fa fa-ethernet\"></i> Puerto de Red HW",
"DevDetail_MainInfo_Network_Site": "",
"DevDetail_MainInfo_Network_Site": "Lugar",
"DevDetail_MainInfo_Network_Title": "<i class=\"fa fa-network-wired\"></i> Red",
"DevDetail_MainInfo_Owner": "Propietario",
"DevDetail_MainInfo_SSID": "",
"DevDetail_MainInfo_SSID": "SSID",
"DevDetail_MainInfo_Title": "<i class=\"fa fa-pencil\"></i> Información principal",
"DevDetail_MainInfo_Type": "Tipo",
"DevDetail_MainInfo_Vendor": "Proveedor",
@@ -218,13 +218,13 @@
"Device_TableHead_MAC": "MAC aleatoria",
"Device_TableHead_MAC_full": "MAC completa",
"Device_TableHead_Name": "Nombre",
"Device_TableHead_NetworkSite": "",
"Device_TableHead_NetworkSite": "Lugar de la red",
"Device_TableHead_Owner": "Propietario",
"Device_TableHead_Parent_MAC": "Nodo principal de la MAC",
"Device_TableHead_Port": "Puerto",
"Device_TableHead_RowID": "Row ID",
"Device_TableHead_Rowid": "Row ID",
"Device_TableHead_SSID": "",
"Device_TableHead_SSID": "SSID",
"Device_TableHead_Status": "Situación",
"Device_TableHead_SyncHubNodeName": "Nodo de sincronización",
"Device_TableHead_Type": "Tipo",
@@ -280,7 +280,7 @@
"Gen_Action": "Acción",
"Gen_Add": "Añadir",
"Gen_Add_All": "Añadir todo",
"Gen_All_Devices": "",
"Gen_All_Devices": "Todo los dispositivos",
"Gen_AreYouSure": "¿Estás seguro?",
"Gen_Backup": "Ejecutar copia de seguridad",
"Gen_Cancel": "Cancelar",
@@ -382,6 +382,9 @@
"MQTT_USER_name": "Usuario de MQTT",
"MQTT_display_name": "MQTT",
"MQTT_icon": "<i class=\"fa fa-square-rss\"></i>",
"Maint_PurgeLog": "Purgar los registros",
"Maint_RestartServer": "Restablecer el servidor",
"Maint_Restart_Server_noti_text": "¿Estás seguro de que desea reiniciar el servidor backend? Esto puede causar inconsistencia en la aplicación. Primero haga una copia de seguridad de su configuración.<br/> <br/> Nota: Esto puede tardar unos minutos.",
"Maintenance_Running_Version": "Versión instalada",
"Maintenance_Status": "Situación",
"Maintenance_Title": "Herramientas de mantenimiento",
@@ -393,6 +396,9 @@
"Maintenance_Tool_ImportCSV_noti": "Importación CSV",
"Maintenance_Tool_ImportCSV_noti_text": "¿Está seguro de que quiere importar el archivo CSV? Esto sobrescribirá completamente los dispositivos de su base de datos.",
"Maintenance_Tool_ImportCSV_text": "Antes de usar esta función, haga una copia de seguridad. Importe un archivo CSV (valor separado por comas) que contiene la lista de dispositivos, incluidas las relaciones de red entre nodos de red y dispositivos conectados. Para hacer eso, coloque el archivo CSV llamado <b> devices.csv </b> en su carpeta <b>/config </b>.",
"Maintenance_Tool_ImportPastedCSV": "",
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
"Maintenance_Tool_ImportPastedCSV_text": "",
"Maintenance_Tool_arpscansw": "Activar arp-scan (on/off)",
"Maintenance_Tool_arpscansw_noti": "Activar arp-scan on or off",
"Maintenance_Tool_arpscansw_noti_text": "Cuando el escaneo se ha apagado, permanece apagado hasta que se active nuevamente.",
@@ -741,7 +747,7 @@
"settings_core_label": "Núcleo",
"settings_device_scanners": "Los escáneres de los dispositivos se utilizan para descubrir dispositivos que escriben en la tabla de base de datos de CurrentScan.",
"settings_device_scanners_icon": "fa-solid fa-magnifying-glass-plus",
"settings_device_scanners_info": "",
"settings_device_scanners_info": "Cargue aún más escáneres de dispositivos con el ajuste <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
"settings_device_scanners_label": "Escáneres de dispositivos",
"settings_enabled": "Configuración activada",
"settings_enabled_icon": "fa-solid fa-toggle-on",
@@ -756,7 +762,7 @@
"settings_other_scanners_label": "Otros escáneres",
"settings_publishers": "Puertas de enlace para las notificación habilitadas: editores, que enviarán una notificación según su configuración.",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "",
"settings_publishers_info": "Cargue más editor@s con el ajuste <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
"settings_publishers_label": "Editores",
"settings_saved": "<br/>Ajustes guardados. <br/><br/> Recargando... <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
"settings_system_icon": "fa-solid fa-gear",
@@ -764,4 +770,4 @@
"settings_update_item_warning": "Actualice el valor a continuación. Tenga cuidado de seguir el formato anterior. <b>O la validación no se realiza.</b>",
"test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Guarda tus cambios antes de probar nuevos ajustes."
}
}

View File

@@ -1,40 +1,40 @@
{
"API_CUSTOM_SQL_description": "",
"API_CUSTOM_SQL_description": "Vous pouvez specifier votre propre requête SQL qui retournera un fichier JSON et l'exposer via <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> file endpoint</a>.",
"API_CUSTOM_SQL_name": "Point de terminaison personnalisé",
"API_display_name": "API",
"API_icon": "",
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"About_Design": "Conçu pour:",
"About_Exit": "Quitter",
"About_Title": "Analyse de la sécurité du réseau et cadre de notification",
"AppEvents_DateTimeCreated": "Journalisé",
"AppEvents_Extra": "Extra",
"AppEvents_GUID": "",
"AppEvents_Helper1": "",
"AppEvents_Helper2": "",
"AppEvents_Helper3": "",
"AppEvents_Helper1": "Helper 1",
"AppEvents_Helper2": "Helper 2",
"AppEvents_Helper3": "Helper 3",
"AppEvents_ObjectForeignKey": "Clé étrangère",
"AppEvents_ObjectIndex": "Index",
"AppEvents_ObjectIsArchived": "Est archivé (au moment de l'enregistrement)",
"AppEvents_ObjectIsNew": "",
"AppEvents_ObjectIsNew": "nouveau (au moment de l'enregistrement dans le journal)",
"AppEvents_ObjectPlugin": "Greffon lié",
"AppEvents_ObjectPrimaryID": "",
"AppEvents_ObjectSecondaryID": "",
"AppEvents_ObjectStatus": "Statut (au moment de l'enregistrement)",
"AppEvents_ObjectPrimaryID": "Identité primaire",
"AppEvents_ObjectSecondaryID": "Indentité secondaire",
"AppEvents_ObjectStatus": "Status (au moment de l'enregistrement)",
"AppEvents_ObjectStatusColumn": "Colonne d'état",
"AppEvents_ObjectType": "Type d'objet",
"AppEvents_Plugin": "Greffon",
"AppEvents_Type": "Type",
"BackDevDetail_Actions_Ask_Run": "",
"BackDevDetail_Actions_Not_Registered": "",
"BackDevDetail_Actions_Title_Run": "",
"BackDevDetail_Copy_Ask": "",
"BackDevDetail_Actions_Ask_Run": "Voulez vous executer cette commande?",
"BackDevDetail_Actions_Not_Registered": "Action non enregistrée ",
"BackDevDetail_Actions_Title_Run": "Execute Action",
"BackDevDetail_Copy_Ask": "Copie les details des objets selectioné dans la liste (tout ce qui est sur cette page sura remplacé)?",
"BackDevDetail_Copy_Title": "Copier les détails",
"BackDevDetail_Tools_WOL_error": "",
"BackDevDetail_Tools_WOL_okay": "",
"BackDevices_Arpscan_disabled": "",
"BackDevices_Arpscan_enabled": "",
"BackDevices_Backup_CopError": "",
"BackDevices_Backup_Failed": "",
"BackDevDetail_Tools_WOL_error": "Cette commande N'A PAS été exécutée.",
"BackDevDetail_Tools_WOL_okay": "Commande Exécutée.",
"BackDevices_Arpscan_disabled": "Arp-Scan Suspendu",
"BackDevices_Arpscan_enabled": "Apr-Scan Activé",
"BackDevices_Backup_CopError": "La base de donnée initiale n'a pas pu être sauvegardée.",
"BackDevices_Backup_Failed": "La sauvegarde a été partiellement complétée. L'archive n'a pas pu être crée ou est vide.",
"BackDevices_Backup_okay": "",
"BackDevices_DBTools_DelDevError_a": "Erreur lors de la suppression de l'appareil",
"BackDevices_DBTools_DelDevError_b": "Erreur lors de la suppression des appareils",
@@ -358,6 +358,9 @@
"Login_Toggle_Alert_headline": "",
"Login_Toggle_Info": "",
"Login_Toggle_Info_headline": "",
"Maint_PurgeLog": "",
"Maint_RestartServer": "",
"Maint_Restart_Server_noti_text": "",
"Maintenance_Running_Version": "Version installée",
"Maintenance_Status": "État",
"Maintenance_Title": "Outils d'entretien",
@@ -369,6 +372,9 @@
"Maintenance_Tool_ImportCSV_noti": "Importation CSV",
"Maintenance_Tool_ImportCSV_noti_text": "Êtes-vous sûr de vouloir importer le fichier CSV? Cela écrasera complètement les appareils de votre base de données.",
"Maintenance_Tool_ImportCSV_text": "",
"Maintenance_Tool_ImportPastedCSV": "",
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
"Maintenance_Tool_ImportPastedCSV_text": "",
"Maintenance_Tool_arpscansw": "Basculer l'arp-Scan (activé/désactivé)",
"Maintenance_Tool_arpscansw_noti": "Activer ou désactiver l'arp-Scan",
"Maintenance_Tool_arpscansw_noti_text": "Une fois le scan désactivé, il reste désactivé jusqu'à ce qu'il soit réactivé.",

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

@@ -358,6 +358,9 @@
"Login_Toggle_Alert_headline": "Avviso password!",
"Login_Toggle_Info": "Informazioni password",
"Login_Toggle_Info_headline": "Informazioni password",
"Maint_PurgeLog": "Elimina log",
"Maint_RestartServer": "Riavvia server",
"Maint_Restart_Server_noti_text": "Sei sicuro di voler riavviare il server backend? Questo potrebbe causare incoerenze dell'app. Prima esegui il backup della tua configurazione. <br/> <br/> Nota: l'operazione potrebbe richiedere alcuni minuti.",
"Maintenance_Running_Version": "Versione installata",
"Maintenance_Status": "Stato",
"Maintenance_Title": "Strumenti di manutenzione",
@@ -369,6 +372,9 @@
"Maintenance_Tool_ImportCSV_noti": "Importa CSV",
"Maintenance_Tool_ImportCSV_noti_text": "Sei sicuro di voler importare il file CSV? Questa operazione sovrascriverà tutti i dispositivi presenti nel database.",
"Maintenance_Tool_ImportCSV_text": "Prima di utilizzare questa funzione, esegui un backup. Importa un file CSV (comma separated value) contenente la lista dei dispositivi incluse le relazioni di rete tra i nodi di rete e i dispositivi connessi. Per far ciò posiziona il file CSV denominato <b>devices.csv</b> nella cartella <b>/config</b>.",
"Maintenance_Tool_ImportPastedCSV": "",
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
"Maintenance_Tool_ImportPastedCSV_text": "",
"Maintenance_Tool_arpscansw": "Attiva/disattiva arp-Scan",
"Maintenance_Tool_arpscansw_noti": "Attiva o disattiva arp-Scan",
"Maintenance_Tool_arpscansw_noti_text": "Una volta disattivata la scansione rimane disattivata finché non viene nuovamente attivata.",
@@ -661,7 +667,7 @@
"settings_core_label": "Core",
"settings_device_scanners": "Scanner dei dispositivi utilizzati per rilevare i dispositivi che scrivono nella tabella del database CurrentScan.",
"settings_device_scanners_icon": "fa-solid fa-magnifying-glass-plus",
"settings_device_scanners_info": "",
"settings_device_scanners_info": "Carica ancora più scanner di dispositivi con l'impostazione <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
"settings_device_scanners_label": "Scanner dispositivi",
"settings_enabled": "Impostazioni abilitate",
"settings_enabled_icon": "fa-solid fa-toggle-on",
@@ -676,7 +682,7 @@
"settings_other_scanners_label": "Altri scanner",
"settings_publishers": "Gateway/editori di notifica abilitati, che invieranno una notifica in base alle tue impostazioni.",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "",
"settings_publishers_info": "Carica più editori con l'impostazione <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
"settings_publishers_label": "Editori",
"settings_saved": "<br/>Impostazioni salvate. <br/> Aggiornamento in corso... <br/> <i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
"settings_system_icon": "fa-solid fa-gear",

View File

@@ -103,7 +103,8 @@ function lang($key)
}
}
return $result;
// HTML encode the result before returning
return str_replace("'", '&#39;', $result);
}

8
front/php/templates/language/nb_no.json Executable file → Normal file
View File

@@ -358,6 +358,9 @@
"Login_Toggle_Alert_headline": "Passord Varsling!",
"Login_Toggle_Info": "Passordinformasjon",
"Login_Toggle_Info_headline": "Passordinformasjon",
"Maint_PurgeLog": "",
"Maint_RestartServer": "",
"Maint_Restart_Server_noti_text": "",
"Maintenance_Running_Version": "Installert versjon",
"Maintenance_Status": "Status",
"Maintenance_Title": "Vedlikeholdsverktøy",
@@ -369,6 +372,9 @@
"Maintenance_Tool_ImportCSV_noti": "Importer CSV",
"Maintenance_Tool_ImportCSV_noti_text": "Er du sikker på at du vil importere CSV-filen? Dette vil fullstendig overskrive enhetene i databasen din.",
"Maintenance_Tool_ImportCSV_text": "Før du bruker denne funksjonen, vennligst ta en sikkerhetskopi. Importer en CSV-fil (kommaseparert verdi) som inneholder listen over enheter, inkludert nettverksrelasjoner mellom nettverksnoder og tilkoblede enheter. For å gjøre det, plasser CSV-filen med navnet <b>devices.csv</b> i mappen <b>/config</b>.",
"Maintenance_Tool_ImportPastedCSV": "",
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
"Maintenance_Tool_ImportPastedCSV_text": "",
"Maintenance_Tool_arpscansw": "Slå arp-Scan (på/av)",
"Maintenance_Tool_arpscansw_noti": "Slå arp-Scan på eller av",
"Maintenance_Tool_arpscansw_noti_text": "Når skanningen er slått av, forblir den slått av til den aktiveres igjen.",
@@ -684,4 +690,4 @@
"settings_update_item_warning": "Oppdater verdien nedenfor. Pass på å følge forrige format. <b>Validering etterpå utføres ikke.</b>",
"test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Lagre endringene først, før du tester innstillingene dine."
}
}

30
front/php/templates/language/pl_pl.json Executable file → Normal file
View File

@@ -83,10 +83,10 @@
"DevDetail_MainInfo_Name": "Nazwa",
"DevDetail_MainInfo_Network": "<i class=\"fa fa-server\"></i> Węzeł (MAC)",
"DevDetail_MainInfo_Network_Port": "<i class=\"fa fa-ethernet\"></i> Port",
"DevDetail_MainInfo_Network_Site": "",
"DevDetail_MainInfo_Network_Site": "Lokalizacja",
"DevDetail_MainInfo_Network_Title": "<i class=\"fa fa-network-wired\"></i> Sieć",
"DevDetail_MainInfo_Owner": "Właściciel",
"DevDetail_MainInfo_SSID": "",
"DevDetail_MainInfo_SSID": "SSID",
"DevDetail_MainInfo_Title": "<i class=\"fa fa-pencil\"></i> Główne informacje",
"DevDetail_MainInfo_Type": "Typ",
"DevDetail_MainInfo_Vendor": "Dostawca",
@@ -208,29 +208,29 @@
"Device_TableHead_MAC": "Losowy MAC",
"Device_TableHead_MAC_full": "Pełen MAC",
"Device_TableHead_Name": "Nazwa",
"Device_TableHead_NetworkSite": "",
"Device_TableHead_NetworkSite": "Lokalizacja sieciowa",
"Device_TableHead_Owner": "Właściciel",
"Device_TableHead_Parent_MAC": "MAC rodzica węzła",
"Device_TableHead_Port": "Port",
"Device_TableHead_RowID": "ID wiersza",
"Device_TableHead_Rowid": "ID wiersza",
"Device_TableHead_SSID": "",
"Device_TableHead_SSID": "SSID",
"Device_TableHead_Status": "Status",
"Device_TableHead_SyncHubNodeName": "Węzeł Synchronizacji",
"Device_TableHead_Type": "Typ",
"Device_TableHead_Vendor": "Dostawca",
"Device_Table_Not_Network_Device": "Nie skonfigurowane jako urządzenie sieciowe",
"Device_Table_info": "Pokazuje_od_POCZĄTKU_do_KOŃCA_WSZYSKICH_wpisów",
"Device_Table_info": "Pokazuje_od_POCZĄTKU_do_KOŃCA_WSZYSKIE_wpisy",
"Device_Table_nav_next": "Następna",
"Device_Table_nav_prev": "Poprzednia",
"Device_Tablelenght": "Pokaż_wpisy_MENU",
"Device_Tablelenght_all": "Wszystkie",
"Device_Title": "Urządzenia",
"Donations_Others": "Reszta",
"Donations_Others": "Inne",
"Donations_Platforms": "Platforma Sponsora",
"Donations_Text": "Cześć 👋! </br> Dziękuje że kliknąłeś w to menu 😅 </br> </br> Próbuje zebrać trochę donacji by ulepszyć to oprogramowanie. Także pomaga mi to się nie wypalić bym dalej mógł wspierać to narzędzie. Każdy mały (powtarzający się lub nie) sponsoring sprawia że chce wkładać więcej pracy w tą aplikację. </br> Chciałbym skróć mój tydzień pracy i w wolnym czasie skupić się nad NetAlertX. Dostawalibyście więcej funkcjonalności i bardziej wypolerowane, posiadające mniej błędów wydania. </br> </br> Dziękuję że to przeczytałeś - Jestem wdzięczny za pomoc ❤🙏</br> </br> TL;DR: Wspierając mnie otrzymujesz: </br> </br> <ul><li> Regularne aktualizacje by zapewnić twoim danym i rodzinie bezpieczeństwo 🔄 </li><li>Mniej błędów (bugów) 🐛🔫</li><li>Więcej i lepsze funkcjonalności</li><li>Ja się nie wypale🔥🤯</li><li>Mniej wypchane na siłę wydania💨</li><li>Lepsza dokumentacja📚</li><li>Szybsza i lepsza pomoc w problemach🆘</li></ul> </br>📧Napisz E-mail do mnie na<a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> jeżeli chcesz nawiązać kontakt albo czy powinien dodać kolejną platformę z sponsoringiem.</br>",
"Donations_Text": "Cześć 👋! </br> Dziękuje że kliknąłeś w to menu 😅 </br> </br> Próbuje zebrać trochę dotacji by ulepszyć to oprogramowanie. Także pomaga mi to się nie wypalić bym dalej mógł ulepszać to narzędzie. Każdy mały (powtarzający się lub nie) sponsoring sprawia że chce wkładać więcej pracy w tą aplikację. </br> Chciałbym skrócić mój tydzień pracy i w wolnym czasie skupić się nad NetAlertX. Dostawalibyście wtedy więcej funkcjonalności i były by one ciągle udoskonalane i posiadające mniej błędów. </br> </br> Dziękuję że to przeczytałeś - Jestem wdzięczny za pomoc ❤🙏</br> </br> TL;DR: Wspierając mnie otrzymujesz: </br> </br> <ul><li> Regularne aktualizacje by zapewnić twoim danym i rodzinie bezpieczeństwo 🔄 </li><li>Mniej błędów (bugów) 🐛🔫</li><li>Nowe i lepsze funkcjonalności</li><li>Nie tracę zapału do dalszego tworzenia 🔥🤯</li><li>Mniej pośpieszne, bardziej dopracowane wydania💨</li><li>Lepsza dokumentacja📚</li><li>Szybsza i lepsza pomoc w problemach🆘</li></ul> </br>📧Napisz E-mail do mnie na<a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> jeżeli chcesz nawiązać kontakt albo czy powinien dodać kolejną platformę z sponsoringiem.</br>",
"Donations_Title": "Dotacje",
"ENABLE_PLUGINS_description": "Włącza funkcjonalność <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">pluginów</a>. Uruchomienie pluginów wymaga więcej zasobów sprzętu więcej możesz chcieć to wyłączyć dla systemu o niskich parametrach.",
"ENABLE_PLUGINS_description": "Włącza funkcjonalność <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">pluginów</a>. Uruchomienie pluginów wymaga więcej zasobów sprzętu więcej możesz chcieć to wyłączyć dla słabszych systemów.",
"ENABLE_PLUGINS_name": "Włącz Pluginy",
"Email_display_name": "Email",
"Email_icon": "<i class=\"fa fa-at\"></i>",
@@ -241,9 +241,9 @@
"Events_Periodselect_LastYear": "Ostatni Rok",
"Events_Periodselect_today": "Dzisiaj",
"Events_Searchbox": "Szukaj",
"Events_Shortcut_AllEvents": "Wszystkie Wydarzenia",
"Events_Shortcut_AllEvents": "Wszystkie Zdarzenia",
"Events_Shortcut_DownAlerts": "Alerty o rozłączeniu",
"Events_Shortcut_Events": "Wydarzenia",
"Events_Shortcut_Events": "Zdarzenia",
"Events_Shortcut_MissSessions": "Brakujące Sesje",
"Events_Shortcut_NewDevices": "Nowe Urządzenia",
"Events_Shortcut_Sessions": "Sesje",
@@ -270,7 +270,7 @@
"Gen_Action": "Akcja",
"Gen_Add": "Dodaj",
"Gen_Add_All": "Dodaj wszystko",
"Gen_All_Devices": "",
"Gen_All_Devices": "Wszystkie urządzenia",
"Gen_AreYouSure": "Jesteś pewien?",
"Gen_Backup": "Wykonaj Kopie Zapasową",
"Gen_Cancel": "Anuluj",
@@ -358,6 +358,9 @@
"Login_Toggle_Alert_headline": "Alert Hasła!",
"Login_Toggle_Info": "Informacje o haśle",
"Login_Toggle_Info_headline": "Informacje o haśle",
"Maint_PurgeLog": "Wyczyść Logi",
"Maint_RestartServer": "Zrestartuj serwer",
"Maint_Restart_Server_noti_text": "Jesteś pewien, że chcesz zrestartować serwer backend? Może spowodować to niespujności w aplikacji. Najpierw utwórz backup konfiguracji. <br/> <br/> Uwaga: Może to zająć kilkla minut.",
"Maintenance_Running_Version": "Zainstalowana wersja",
"Maintenance_Status": "Status",
"Maintenance_Title": "Narzędzia konserwacyjne",
@@ -369,6 +372,9 @@
"Maintenance_Tool_ImportCSV_noti": "Import CSV",
"Maintenance_Tool_ImportCSV_noti_text": "Jesteś pewien że chcesz zaimportować plik CSV? Nadpisze to wszystkie urządzenie w bazie danych.",
"Maintenance_Tool_ImportCSV_text": "Przed użyciem tej funkcji, wykonaj proszę kopię zapasową. Zaimportuj plik CSV (wartości oddzielone przecinkami) zawierający listę Urządzeń, w tym Relacji Sieci między sieciowymi węzłami i podłączonymi urządzeniami. By to zrobić umieść plik CSV nazwany <b>devices.csv</b> do twojego folderu <b>/config</b>.",
"Maintenance_Tool_ImportPastedCSV": "",
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
"Maintenance_Tool_ImportPastedCSV_text": "",
"Maintenance_Tool_arpscansw": "Przełącz Skan-arp (wł/wył)",
"Maintenance_Tool_arpscansw_noti": "Przełącz Skan-arp na włączony lub wyłączony",
"Maintenance_Tool_arpscansw_noti_text": "Kiedy skan zostanie przełączony na wył zostaje wyłączony do czasu ponownej aktywacji.",
@@ -684,4 +690,4 @@
"settings_update_item_warning": "Zaktualizuj poniższą wartość. Zachowaj ostrożność i postępuj zgodnie z poprzednim formatem. <b>Walidacja nie jest wykonywana.</b>",
"test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Zapisz zmiany zanim będziesz testować swoje ustawienia."
}
}

View File

@@ -358,6 +358,9 @@
"Login_Toggle_Alert_headline": "",
"Login_Toggle_Info": "",
"Login_Toggle_Info_headline": "",
"Maint_PurgeLog": "",
"Maint_RestartServer": "",
"Maint_Restart_Server_noti_text": "",
"Maintenance_Running_Version": "",
"Maintenance_Status": "",
"Maintenance_Title": "",
@@ -369,6 +372,9 @@
"Maintenance_Tool_ImportCSV_noti": "",
"Maintenance_Tool_ImportCSV_noti_text": "",
"Maintenance_Tool_ImportCSV_text": "",
"Maintenance_Tool_ImportPastedCSV": "",
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
"Maintenance_Tool_ImportPastedCSV_text": "",
"Maintenance_Tool_arpscansw": "",
"Maintenance_Tool_arpscansw_noti": "",
"Maintenance_Tool_arpscansw_noti_text": "",

View File

@@ -358,6 +358,9 @@
"Login_Toggle_Alert_headline": "Предупреждение о пароле!",
"Login_Toggle_Info": "Информация о пароле",
"Login_Toggle_Info_headline": "Информация о пароле",
"Maint_PurgeLog": "Журнал очистки",
"Maint_RestartServer": "Перезапустить сервер",
"Maint_Restart_Server_noti_text": "Вы уверены, что хотите перезапустить внутренний сервер? Это может привести к несогласованности работы приложения. Сначала создайте резервную копию настроек. <br/> <br/> Примечание: Это может занять несколько минут.",
"Maintenance_Running_Version": "Установленная версия",
"Maintenance_Status": "Статус",
"Maintenance_Title": "Инструменты обслуживания",
@@ -369,6 +372,9 @@
"Maintenance_Tool_ImportCSV_noti": "CSV Импорт",
"Maintenance_Tool_ImportCSV_noti_text": "Вы уверены, что хотите импортировать файл CSV? Это полностью перезапишет устройства в вашей базе данных.",
"Maintenance_Tool_ImportCSV_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Импортируйте файл CSV (значения, разделенные запятыми), содержащий список устройств, включая сетевые отношения между сетевыми узлами и подключенными устройствами. Для этого поместите файл CSV с именем <b>devices.csv</b> в папку <b>/config</b>.",
"Maintenance_Tool_ImportPastedCSV": "",
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
"Maintenance_Tool_ImportPastedCSV_text": "",
"Maintenance_Tool_arpscansw": "Переключить arp-скан (ВКЛ./ВЫКЛ.)",
"Maintenance_Tool_arpscansw_noti": "Включить или выключить arp-скан",
"Maintenance_Tool_arpscansw_noti_text": "Когда сканирование было выключено, оно остается выключенным до тех пор, пока не будет активировано снова.",
@@ -661,7 +667,7 @@
"settings_core_label": "Основные",
"settings_device_scanners": "Сканеры устройств, используемые для обнаружения устройств, записывающих данные в таблицу базы данных CurrentScan.",
"settings_device_scanners_icon": "fa-solid fa-magnifying-glass-plus",
"settings_device_scanners_info": "",
"settings_device_scanners_info": "Загрузите еще больше сканеров устройств с помощью параметра <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
"settings_device_scanners_label": "Сканеры устройств",
"settings_enabled": "Вкл. настройки",
"settings_enabled_icon": "fa-solid fa-toggle-on",
@@ -676,7 +682,7 @@
"settings_other_scanners_label": "Другие сканеры",
"settings_publishers": "Включенные шлюзы уведомлений - сервисы, которые будут отправлять уведомления в зависимости от ваших настроек.",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "",
"settings_publishers_info": "Загрузите больше нотификаторов с помощью настройки <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
"settings_publishers_label": "Уведомления",
"settings_saved": "<br/>Настройки сохранены. <br/> Перезагрузка... <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
"settings_system_icon": "fa-solid fa-gear",

View File

@@ -358,6 +358,9 @@
"Login_Toggle_Alert_headline": "",
"Login_Toggle_Info": "",
"Login_Toggle_Info_headline": "",
"Maint_PurgeLog": "",
"Maint_RestartServer": "",
"Maint_Restart_Server_noti_text": "",
"Maintenance_Running_Version": "",
"Maintenance_Status": "",
"Maintenance_Title": "",
@@ -369,6 +372,9 @@
"Maintenance_Tool_ImportCSV_noti": "",
"Maintenance_Tool_ImportCSV_noti_text": "",
"Maintenance_Tool_ImportCSV_text": "",
"Maintenance_Tool_ImportPastedCSV": "",
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
"Maintenance_Tool_ImportPastedCSV_text": "",
"Maintenance_Tool_arpscansw": "",
"Maintenance_Tool_arpscansw_noti": "",
"Maintenance_Tool_arpscansw_noti_text": "",

View File

@@ -358,6 +358,9 @@
"Login_Toggle_Alert_headline": "",
"Login_Toggle_Info": "",
"Login_Toggle_Info_headline": "",
"Maint_PurgeLog": "",
"Maint_RestartServer": "",
"Maint_Restart_Server_noti_text": "",
"Maintenance_Running_Version": "",
"Maintenance_Status": "",
"Maintenance_Title": "",
@@ -369,6 +372,9 @@
"Maintenance_Tool_ImportCSV_noti": "",
"Maintenance_Tool_ImportCSV_noti_text": "",
"Maintenance_Tool_ImportCSV_text": "",
"Maintenance_Tool_ImportPastedCSV": "",
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
"Maintenance_Tool_ImportPastedCSV_text": "",
"Maintenance_Tool_arpscansw": "",
"Maintenance_Tool_arpscansw_noti": "",
"Maintenance_Tool_arpscansw_noti_text": "",

View File

@@ -40,3 +40,4 @@ $timestamp = $date->format('Y-m-d_H-i-s');
// ###################################
// ## TimeZone processing end
// ###################################

View File

@@ -24,39 +24,41 @@ NetAlertX supports additional plugins to extend its functionality, each with its
Device-detecting plugins insert values into the `CurrentScan` database table. The plugins that are not required are safe to ignore, however, it makes sense to have at least some device-detecting plugins enabled, such as `ARPSCAN` or `NMAPDEV`.
| ID | Type | Description | Required | Data source | Detailed docs |
|---------------|---------|---------------------------------------------|----------|--------------------|---------------------------------------------------------------|
| `APPRISE` | ▶️ | Apprise notification proxy | | Script | [📚_publisher_apprise](/front/plugins/_publisher_apprise/) |
| `ARPSCAN` | 🔍 | ARP-scan on current network | | Script | [📚arp_scan](/front/plugins/arp_scan/) |
| `CSVBCKP` | ⚙ | CSV devices backup | | Script | [📚csv_backup](/front/plugins/csv_backup/) |
| `DBCLNP` | ⚙ | Database cleanup | Yes* | Script | [📚db_cleanup](/front/plugins/db_cleanup/) |
| `DDNS` | ⚙ | DDNS update | | Script | [📚ddns_update](/front/plugins/ddns_update/) |
| `DHCPLSS` | 🔍/📥 | Import devices from DHCP leases | | Script | [📚dhcp_leases](/front/plugins/dhcp_leases/) |
| `DHCPSRVS` | ♻ | DHCP servers | | Script | [📚dhcp_servers](/front/plugins/dhcp_servers/) |
| `INTRNT` | 🔍 | Internet IP scanner | | Script | [📚internet_ip](/front/plugins/internet_ip/) |
| `INTRSPD` | ♻ | Internet speed test | | Script | [📚internet_speedtest](/front/plugins/internet_speedtest/) |
| `MAINT` | ⚙ | Maintenance of logs, etc. | | Script | [📚maintenance](/front/plugins/maintenance/) |
| `MQTT` | ▶️ | MQTT for synching to Home Assistant | | Script | [📚_publisher_mqtt](/front/plugins/_publisher_mqtt/) |
| `NEWDEV` | | New device template | Yes | Template | [📚newdev_template](/front/plugins/newdev_template/) |
| `NMAP` | | Nmap port scanning & discovery | | Script | [📚nmap_scan](/front/plugins/nmap_scan/) |
| `NMAPDEV` | 🔍 | Nmap dev scan on current network | | Script | [📚nmap_dev_scan](/front/plugins/nmap_dev_scan/) |
| `NSLOOKUP` | | NSLookup name resolution | | Script | [📚nslookup_scan](/front/plugins/nslookup_scan/) |
| `NTFPRCS` | | Notification processing | Yes | Template | [📚notification_processing](/front/plugins/notification_processing/)|
| `NTFY` | ▶️ | NTFY notifications | | Script | [📚_publisher_ntfy](/front/plugins/_publisher_ntfy/) |
| `PHOLUS` | | Pholus name resolution | | Script | [📚pholus_scan](/front/plugins/pholus_scan/) |
| `PIHOLE` | 🔍/📥 | Pi-hole device import & sync | | SQLite DB | [📚pihole_scan](/front/plugins/pihole_scan/) |
| `PUSHSAFER` | ▶️ | Pushsafer notifications | | Script | [📚_publisher_pushsafer](/front/plugins/_publisher_pushsafer/) |
| `PUSHOVER` | ▶️ | Pushover notifications | | Script | [📚_publisher_pushover](/front/plugins/_publisher_pushover/) |
| `SETPWD` | ⚙ | Set password | Yes | Template | [📚set_password](/front/plugins/set_password/) |
| `SMTP` | ▶️ | Email notifications | | Script | [📚_publisher_email](/front/plugins/_publisher_email/) |
| `SNMPDSC` | 🔍/📥 | SNMP device import & sync | | Script | [📚snmp_discovery](/front/plugins/snmp_discovery/) |
| `SYNC` | 🔍/⚙/📥| Sync & import from other NetAlertX instances | | Script | [📚snmp_discovery](/front/plugins/snmp_discovery/) |
| `UNDIS` | 🔍/📥 | Create dummy devices | | Script | [📚undiscoverables](/front/plugins/undiscoverables/) |
| `UNFIMP` | 🔍/📥 | UniFi device import & sync | | Script | [📚unifi_import](/front/plugins/unifi_import/) |
| `VNDRPDT` | ⚙ | Vendor database update | | Script | [📚vendor_update](/front/plugins/vendor_update/) |
| `WEBHOOK` | ▶️ | Webhook notifications | | Script | [📚_publisher_webhook](/front/plugins/_publisher_webhook/) |
| `WEBMON` | | Website down monitoring | | Script | [📚website_monitor](/front/plugins/website_monitor/)
| ID | Type | Description | Features | Required | Data source | Detailed docs |
|---------------|---------|--------------------------------------------|----------|----------|--------------------|---------------------------------------------------------------|
| `APPRISE` | ▶️ | Apprise notification proxy | | | Script | [_publisher_apprise](/front/plugins/_publisher_apprise/) |
| `ARPSCAN` | 🔍 | ARP-scan on current network | | | Script | [arp_scan](/front/plugins/arp_scan/) |
| `CSVBCKP` | ⚙ | CSV devices backup | | | Script | [csv_backup](/front/plugins/csv_backup/) |
| `DBCLNP` | ⚙ | Database cleanup | | Yes* | Script | [db_cleanup](/front/plugins/db_cleanup/) |
| `DDNS` | ⚙ | DDNS update | | | Script | [ddns_update](/front/plugins/ddns_update/) |
| `DHCPLSS` | 🔍/📥 | Import devices from DHCP leases | | | Script | [dhcp_leases](/front/plugins/dhcp_leases/) |
| `DHCPSRVS` | ♻ | DHCP servers | | | Script | [dhcp_servers](/front/plugins/dhcp_servers/) |
| `INTRNT` | 🔍 | Internet IP scanner | | | Script | [internet_ip](/front/plugins/internet_ip/) |
| `INTRSPD` | ♻ | Internet speed test | | | Script | [internet_speedtest](/front/plugins/internet_speedtest/) |
| `MAINT` | ⚙ | Maintenance of logs, etc. | | | Script | [maintenance](/front/plugins/maintenance/) |
| `MQTT` | ▶️ | MQTT for synching to Home Assistant | | | Script | [_publisher_mqtt](/front/plugins/_publisher_mqtt/) |
| `NBTSCAN` | | Nbtscan (NetBIOS-based) name resolution | | | Script | [nbtscan_scan](/front/plugins/nbtscan_scan/) |
| `NEWDEV` | | New device template | | Yes | Template | [newdev_template](/front/plugins/newdev_template/) |
| `NMAP` | | Nmap port scanning & discovery | | | Script | [nmap_scan](/front/plugins/nmap_scan/) |
| `NMAPDEV` | 🔍 | Nmap dev scan on current network | | | Script | [nmap_dev_scan](/front/plugins/nmap_dev_scan/) |
| `NSLOOKUP` | | NSLookup (DNS-based) name resolution | | | Script | [nslookup_scan](/front/plugins/nslookup_scan/) |
| `NTFPRCS` | | Notification processing | | Yes | Template | [notification_processing](/front/plugins/notification_processing/)|
| `NTFY` | ▶️ | NTFY notifications | | | Script | [_publisher_ntfy](/front/plugins/_publisher_ntfy/) |
| `OMDSDN` | 📥 | OMADA TP-Link import | 📊🔄 | | Script | [omada_sdn_imp](/front/plugins/omada_sdn_imp/) |
| `PHOLUS` | | Pholus name resolution | | | Script | [pholus_scan](/front/plugins/pholus_scan/) |
| `PIHOLE` | 🔍/📥 | Pi-hole device import & sync | | | SQLite DB | [pihole_scan](/front/plugins/pihole_scan/) |
| `PUSHSAFER` | ▶️ | Pushsafer notifications | | | Script | [_publisher_pushsafer](/front/plugins/_publisher_pushsafer/) |
| `PUSHOVER` | ▶️ | Pushover notifications | | | Script | [_publisher_pushover](/front/plugins/_publisher_pushover/) |
| `SETPWD` | | Set password | | Yes | Template | [set_password](/front/plugins/set_password/) |
| `SMTP` | ▶️ | Email notifications | | | Script | [_publisher_email](/front/plugins/_publisher_email/) |
| `SNMPDSC` | 🔍/📥 | SNMP device import & sync | | | Script | [snmp_discovery](/front/plugins/snmp_discovery/) |
| `SYNC` | 🔍/⚙/📥| Sync & import from NetAlertX instances | 📊🔄 | | Script | [sync](/front/plugins/sync/) |
| `UNDIS` | 🔍/📥 | Create dummy devices | | | Script | [undiscoverables](/front/plugins/undiscoverables/) |
| `UNFIMP` | 🔍/📥 | UniFi device import & sync | | | Script | [unifi_import](/front/plugins/unifi_import/) |
| `VNDRPDT` | | Vendor database update | | | Script | [vendor_update](/front/plugins/vendor_update/) |
| `WEBHOOK` | ▶️ | Webhook notifications | | | Script | [_publisher_webhook](/front/plugins/_publisher_webhook/) |
| `WEBMON` | ♻ | Website down monitoring | | | Script | [website_monitor](/front/plugins/website_monitor/) |
> \* The database cleanup plugin (`DBCLNP`) is not _required_ but the app will become unusable after a while if not executed.
>
@@ -75,11 +77,19 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
| system | ⚙ | Providing core system functionality. | `schedule` / always on | ✖/✔ | Script / Template |
| other | ♻ | Other scanners, e.g. for name resolution | misc | ✖ | Script / Template |
## Features
| Icon | Description |
|------|---------------------------------------------------------------|
| 📊 | Auto-imports the network topology diagram |
| 🔄 | Has the option to sync some data back into the plugin source |
## ✅Enabling plugins
Plugins can be enabled via Settings, and can be disabled as needed.
1. Research which plugin you'd like to use below and then load the required plugins in Settings via the `LOADED_PLUGINS` setting.
1. Research which plugin you'd like to use and load the required plugins in Settings via the `LOADED_PLUGINS` setting.
1. Save the changes and review the Settings of the newly loaded plugins.
1. Change the `<prefix>_RUN` Setting to the recommended or custom value as per the documentation of the given setting
- If using `schedule` on a `🔍 dev scanner` plugin, make sure the schedules are the same across all `🔍 dev scanner` plugins

View File

@@ -1,9 +1,10 @@
{
"code_name": "folder_name",
"unique_prefix": "",
"plugin_type": "core|general|system|scanner|other|publisher",
"code_name": "__template",
"unique_prefix": "TMP",
"plugin_type": "device_scanner",
"execution_order" : "Layer_0",
"enabled": true,
"data_source": "script|app-db-query|template|sqlite-db-query",
"data_source": "script",
"mapped_to_table": "CurrentScan",
"data_filters": [
{
@@ -39,7 +40,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
@@ -66,7 +72,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "*/5 * * * *",
"options": [],
"localized": ["name", "description"],
@@ -85,7 +96,12 @@
},
{
"function": "text_example",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 50,
"default_value": "",
"options": [],
@@ -105,7 +121,16 @@
},
{
"function": "boolean_example",
"type": "boolean",
"type": {
"dataType": "boolean",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": false,
"options": [],
"localized": ["name", "description"],
@@ -122,9 +147,89 @@
}
]
},
{
"function": "list_example",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "input",
"elementOptions": [
{ "placeholder": "Enter value" },
{ "suffix": "_in" },
{ "cssClasses": "col-sm-10" },
{ "prefillValue": "null" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": ["_in"] },
{ "separator": "" },
{ "cssClasses": "col-xs-12" },
{ "onClick": "addList(this, false)" },
{ "getStringKey": "Gen_Add" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeAllOptions(this)" },
{ "getStringKey": "Gen_Remove_All" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeFromList(this)" },
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
},
{
"elementType": "select",
"elementOptions": [
{ "multiple": "true" },
{ "readonly": "true" },
{ "editable": "true" }
],
"transformers": []
}
]
},
"default_value": ["existing_entry_1", "existing_entry_2"],
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Setting name"
}
],
"description": [
{
"language_code": "en_us",
"string": "Description / simple setup instructions"
}
]
},
{
"function": "multiselect_example_from_setting",
"type": "text.multiselect",
"type": {
"dataType": "array",
"element": "select",
"elementOptions": ["multiple"],
"transformers": []
},
"maxLength": 50,
"default_value": [],
"options": ["{value}"],
@@ -151,7 +256,12 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"element": "input",
"elementOptions": ["readonly"],
"transformers": []
},
"default_value": "python3 /app/front/plugins/<plugin folder>/rename_me.py",
"options": [],
"localized": ["name", "description"],
@@ -170,7 +280,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 30,
"options": [],
"localized": ["name", "description"],
@@ -255,7 +374,7 @@
},
{
"column": "Watched_Value3",
"mapped_to_column": "cur_SyncHubNodeName",
"mapped_to_column": "cur_Type",
"css_classes": "col-sm-2",
"show": true,
"type": "label",
@@ -265,14 +384,14 @@
"name": [
{
"language_code": "en_us",
"string": "Sync Node"
"string": "Device Type"
}
]
},
{
"column": "Watched_Value4",
"css_classes": "col-sm-2",
"show": true,
"show": false,
"type": "label",
"default_value": "",
"options": [],
@@ -280,7 +399,7 @@
"name": [
{
"language_code": "en_us",
"string": "Device GUID"
"string": "N/A"
}
]
},
@@ -288,7 +407,7 @@
"column": "Dummy",
"mapped_to_column": "cur_ScanMethod",
"mapped_to_column_data": {
"value": "sync"
"value": "Example Plugin"
},
"css_classes": "col-sm-2",
"show": true,

View File

@@ -6,7 +6,6 @@ import sys
import json
import sqlite3
# Define the installation path and extend the system path for plugin imports
INSTALL_PATH = "/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
@@ -47,20 +46,20 @@ def main():
#"database_column_definitions": [
# {
# "column": "Object_PrimaryID", <--------- the value I save into primaryId
# "mapped_to_column": "cur_MAC", <--------- gets unserted into the CurrentScan DB table column cur_MAC
# "mapped_to_column": "cur_MAC", <--------- gets inserted into the CurrentScan DB table column cur_MAC
#
for device in device_data:
plugin_objects.add_object(
primaryId = device['some_id'],
secondaryId = device['some_id'],
watched1 = device['some_id'],
watched2 = device['some_id'],
watched3 = device['some_id'],
watched4 = device['some_id'],
primaryId = device['mac_address'],
secondaryId = device['ip_address'],
watched1 = device['hostname'],
watched2 = device['vendor'],
watched3 = device['device_type'],
watched4 = device['last_seen'],
extra = '',
foreignKey = device['some_id'])
foreignKey = device['mac_address'])
mylog('verbose', [f'[{pluginName}] New entries: "{len(new_devices)}"'])
mylog('verbose', [f'[{pluginName}] New entries: "{len(device_data)}"'])
# log result
plugin_objects.write_result_file()
@@ -75,7 +74,34 @@ def get_device_data(some_setting):
# do some processing, call exteranl APIs, and return a device_data list
# ...
#
# Sample data for testing purposes, you can adjust the processing in main() as needed
# ... before adding it to the plugin_objects.add_object(...)
device_data = [
{
'device_id': 'device1',
'mac_address': '00:11:22:33:44:55',
'ip_address': '192.168.1.2',
'hostname': 'iPhone 12',
'vendor': 'Apple Inc.',
'device_type': 'Smartphone',
'last_seen': '2024-06-27 10:00:00',
'port': '1',
'network_id': 'network1'
},
{
'device_id': 'device2',
'mac_address': '00:11:22:33:44:66',
'ip_address': '192.168.1.3',
'hostname': 'Moto G82',
'vendor': 'Motorola Inc.',
'device_type': 'Laptop',
'last_seen': '2024-06-27 10:05:00',
'port': '',
'network_id': 'network1'
}
]
# Return the data to be detected by teh main application
return device_data
if __name__ == '__main__':

82
front/plugins/__test/test.py Executable file
View File

@@ -0,0 +1,82 @@
#!/usr/bin/env python
# Just a testing library plugin for development purposes
import json
import subprocess
import argparse
import os
import pathlib
import sys
from datetime import datetime
import time
import re
import hashlib
import sqlite3
# Register NetAlertX directories
INSTALL_PATH="/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
# NetAlertX modules
import conf
from const import apiPath, confFileName
from plugin_utils import getPluginObject
from plugin_helper import Plugin_Objects
from logger import mylog, append_line_to_file
from helper import timeNowTZ, get_setting_value, bytes_to_string, sanitize_string, cleanDeviceName
from notification import Notification_obj
from database import DB, get_device_stats
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log')
# Initialize the Plugin obj output file
plugin_objects = Plugin_Objects(RESULT_FILE)
# Create an MD5 hash object
md5_hash = hashlib.md5()
pluginName = 'TESTONLY'
# globals
def main():
# START
mylog('verbose', [f'[{pluginName}] In script'])
# SPACE FOR TESTING 🔽
str = "ABC-MBP._another.localdomain."
# cleanDeviceName(str, match_IP)
# result = cleanDeviceName(str, True)
regexes = get_setting_value('NEWDEV_NAME_CLEANUP_REGEX')
print(regexes)
subnets = get_setting_value('SCAN_SUBNETS')
print(subnets)
for rgx in regexes:
mylog('trace', ["[cleanDeviceName] applying regex : " + rgx])
mylog('trace', ["[cleanDeviceName] name before regex : " + str])
str = re.sub(rgx, "", str)
mylog('trace', ["[cleanDeviceName] name after regex : " + str])
mylog('debug', ["[cleanDeviceName] output: " + str])
# SPACE FOR TESTING 🔼
# END
mylog('verbose', [f'[{pluginName}] result "{str}"'])
# -------------INIT---------------------
if __name__ == '__main__':
sys.exit(main())

View File

@@ -2,7 +2,12 @@
[Apprise](https://hub.docker.com/r/caronc/apprise) is a notification gateway/publisher that allows you to push notifications to 80+ different services.
## Notes
You need to bring your own separate Apprise instance to use this publisher gateway. I suggest this [Apprise image](https://hub.docker.com/r/caronc/apprise).
### Usage
- Go to settings and fill in relevant details.
- Use the Apprise container's URL in the `APPRISE_HOST` setting.

View File

@@ -288,7 +288,12 @@
{
"function": "RUN",
"events": ["test"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": ["disabled", "on_notification"],
"localized": ["name", "description"],
@@ -315,7 +320,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/_publisher_apprise/apprise.py",
"options": [],
"localized": ["name", "description"],
@@ -342,7 +356,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 10,
"options": [],
"localized": ["name", "description"],
@@ -373,7 +396,12 @@
},
{
"function": "HOST",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -400,7 +428,12 @@
},
{
"function": "URL",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -427,7 +460,12 @@
},
{
"function": "PAYLOAD",
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "html",
"options": ["html", "text"],
"localized": ["name", "description"],
@@ -444,7 +482,7 @@
"description": [
{
"language_code": "en_us",
"string": "Select the payoad type sent to Apprise. For example <code>html</code> works well with emails, <code>text</code> with chat apps, such as Telegram."
"string": "Select the payload type sent to Apprise. For example <code>html</code> works well with emails, <code>text</code> with chat apps, such as Telegram."
},
{
"language_code": "es_es",
@@ -454,7 +492,16 @@
},
{
"function": "SIZE",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 1024,
"options": [],
"localized": ["name", "description"],

View File

@@ -288,7 +288,12 @@
{
"function": "RUN",
"events": ["test"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": ["disabled", "on_notification"],
"localized": ["name", "description"],
@@ -315,7 +320,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/_publisher_email/email_smtp.py",
"options": [],
"localized": ["name", "description"],
@@ -342,7 +356,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 20,
"options": [],
"localized": ["name", "description"],
@@ -373,7 +396,12 @@
},
{
"function": "SERVER",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -400,7 +428,16 @@
},
{
"function": "PORT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 587,
"options": [],
"localized": ["name", "description"],
@@ -427,7 +464,16 @@
},
{
"function": "SKIP_LOGIN",
"type": "boolean",
"type": {
"dataType": "boolean",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": false,
"options": [],
"localized": ["name", "description"],
@@ -454,7 +500,12 @@
},
{
"function": "USER",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -481,7 +532,16 @@
},
{
"function": "PASS",
"type": "password",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "password" }],
"transformers": []
}
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -508,7 +568,16 @@
},
{
"function": "SKIP_TLS",
"type": "boolean",
"type": {
"dataType": "boolean",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": false,
"options": [],
"localized": ["name", "description"],
@@ -535,7 +604,16 @@
},
{
"function": "FORCE_SSL",
"type": "boolean",
"type": {
"dataType": "boolean",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": false,
"options": [],
"localized": ["name", "description"],
@@ -562,7 +640,12 @@
},
{
"function": "REPORT_TO",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "user@gmail.com",
"options": [],
"localized": ["name", "description"],
@@ -589,7 +672,12 @@
},
{
"function": "REPORT_FROM",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "NetAlertX <user@gmail.com>",
"options": [],
"localized": ["name", "description"],

View File

@@ -56,6 +56,19 @@ def main():
# Retrieve new notifications
new_notifications = notifications.getNew()
# mylog('verbose', [f'[{pluginName}] new_notifications: ', new_notifications])
# mylog('verbose', [f'[{pluginName}] SMTP_SERVER: ', get_setting_value("SMTP_SERVER")])
# mylog('verbose', [f'[{pluginName}] SMTP_PORT: ', get_setting_value("SMTP_PORT")])
# mylog('verbose', [f'[{pluginName}] SMTP_SKIP_LOGIN: ', get_setting_value("SMTP_SKIP_LOGIN")])
# mylog('verbose', [f'[{pluginName}] SMTP_USER: ', get_setting_value("SMTP_USER")])
# mylog('verbose', [f'[{pluginName}] SMTP_PASS: ', get_setting_value("SMTP_PASS")])
# mylog('verbose', [f'[{pluginName}] SMTP_SKIP_TLS: ', get_setting_value("SMTP_SKIP_TLS")])
# mylog('verbose', [f'[{pluginName}] SMTP_FORCE_SSL: ', get_setting_value("SMTP_FORCE_SSL")])
# mylog('verbose', [f'[{pluginName}] SMTP_REPORT_TO: ', get_setting_value("SMTP_REPORT_TO")])
# mylog('verbose', [f'[{pluginName}] SMTP_REPORT_FROM: ', get_setting_value("SMTP_REPORT_FROM")])
# Process the new notifications (see the Notifications DB table for structure or check the /api/table_notifications.json endpoint)
for notification in new_notifications:

View File

@@ -25,7 +25,7 @@
"description": [
{
"language_code": "en_us",
"string": "A plugin to publish a notification via the Apprise gateway."
"string": "A plugin to publish a notification via MQTT to Home Assistant."
}
],
"params": [
@@ -278,7 +278,12 @@
{
"function": "RUN",
"events": ["test"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
"disabled",
@@ -312,7 +317,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/_publisher_mqtt/mqtt.py devices={devices}",
"options": [],
"localized": ["name", "description"],
@@ -339,7 +353,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "0 2 * * 3",
"options": [],
"localized": ["name", "description"],
@@ -374,7 +393,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 20,
"options": [],
"localized": ["name", "description"],
@@ -405,7 +433,12 @@
},
{
"function": "BROKER",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -432,7 +465,16 @@
},
{
"function": "PORT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 1883,
"options": [],
"localized": ["name", "description"],
@@ -459,7 +501,12 @@
},
{
"function": "USER",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -486,7 +533,16 @@
},
{
"function": "PASSWORD",
"type": "password",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "password" }],
"transformers": []
}
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -513,7 +569,16 @@
},
{
"function": "SEND_STATS",
"type": "boolean",
"type": {
"dataType": "boolean",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": true,
"options": [],
"localized": ["name", "description"],
@@ -532,7 +597,12 @@
},
{
"function": "DEVICE_ID",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "netalertx",
"options": [],
"localized": ["name", "description"],
@@ -551,7 +621,12 @@
},
{
"function": "DEVICE_NAME",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "NetAlertX",
"options": [],
"localized": ["name", "description"],
@@ -570,7 +645,16 @@
},
{
"function": "SEND_DEVICES",
"type": "boolean",
"type": {
"dataType": "boolean",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": true,
"options": [],
"localized": ["name", "description"],
@@ -587,9 +671,38 @@
}
]
},
{
"function": "DEVICES_SQL",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "select rowid, * from Devices where dev_Name not in ({s-quote}null{s-quote}, {s-quote}(name not found){s-quote}, {s-quote}(unknown){s-quote})",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Devices SQL"
}
],
"description": [
{
"language_code": "en_us",
"string": "The SQL condition used to select which Devices are sent via MQTT. Please note that you need to use <code>{s-quote}</code> for single quotes replacement and double-quotes are not supported."
}
]
},
{
"function": "QOS",
"type": "integer.select",
"type": {
"dataType": "integer",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": 0,
"options": [0, 1, 2],
"localized": ["name", "description"],
@@ -616,7 +729,12 @@
},
{
"function": "VERSION",
"type": "integer.select",
"type": {
"dataType": "integer",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": 1,
"options": [1, 2],
"localized": ["name", "description"],
@@ -635,7 +753,16 @@
},
{
"function": "DELAY_SEC",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 2,
"options": [2, 3, 4, 5],
"localized": ["name", "description"],

View File

@@ -13,6 +13,7 @@ import paho.mqtt.client as mqtt
# from paho.mqtt import client as mqtt_client
# from paho.mqtt import CallbackAPIVersion as mqtt_CallbackAPIVersion
import hashlib
import sqlite3
# Register NetAlertX directories
@@ -27,7 +28,7 @@ from plugin_helper import Plugin_Objects
from logger import mylog, append_line_to_file
from helper import timeNowTZ, get_setting_value, bytes_to_string, sanitize_string
from notification import Notification_obj
from database import DB, get_all_devices, get_device_stats
from database import DB, get_device_stats
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
@@ -340,10 +341,10 @@ def mqtt_start(db):
# Generate device-specific MQTT messages if enabled
if get_setting_value('MQTT_SEND_DEVICES') == True:
# Specific devices
# Specific devices processing
# Get all devices
devices = get_all_devices(db)
devices = db.read(get_setting_value('MQTT_DEVICES_SQL').replace('{s-quote}',"'"))
sec_delay = len(devices) * int(get_setting_value('MQTT_DELAY_SEC'))*5

View File

@@ -242,7 +242,12 @@
{
"function": "RUN",
"events": ["test"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": ["disabled", "on_notification"],
"localized": ["name", "description"],
@@ -269,7 +274,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/_publisher_ntfy/ntfy.py",
"options": [],
"localized": ["name", "description"],
@@ -296,7 +310,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 10,
"options": [],
"localized": ["name", "description"],
@@ -327,7 +350,12 @@
},
{
"function": "HOST",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "https://ntfy.sh",
"options": [],
"localized": ["name", "description"],
@@ -354,7 +382,12 @@
},
{
"function": "TOPIC",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -381,7 +414,12 @@
},
{
"function": "USER",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -408,7 +446,16 @@
},
{
"function": "PASSWORD",
"type": "password",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "password" }],
"transformers": []
}
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -435,7 +482,12 @@
},
{
"function": "PRIORITY",
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "urgent",
"options": ["urgent", "high", "default", "low", "min"],
"localized": ["name", "description"],

View File

@@ -242,7 +242,12 @@
{
"function": "RUN",
"events": ["test"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": ["disabled", "on_notification"],
"localized": ["name", "description"],
@@ -269,7 +274,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/_publisher_pushover/pushover.py",
"options": [],
"localized": ["name", "description"],
@@ -296,7 +310,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 10,
"options": [],
"localized": ["name", "description"],
@@ -323,7 +346,12 @@
},
{
"function": "USER_KEY",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "USER_KEY",
"options": [],
"localized": ["name", "description"],
@@ -342,7 +370,12 @@
},
{
"function": "APP_TOKEN",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "APP_TOKEN",
"options": [],
"localized": ["name", "description"],
@@ -361,7 +394,12 @@
},
{
"function": "DEVICE_NAME",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "DEVICE_NAME",
"options": [],
"localized": ["name", "description"],

View File

@@ -242,7 +242,12 @@
{
"function": "RUN",
"events": ["test"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": ["disabled", "on_notification"],
"localized": ["name", "description"],
@@ -269,7 +274,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/_publisher_pushsafer/pushsafer.py",
"options": [],
"localized": ["name", "description"],
@@ -296,7 +310,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 10,
"options": [],
"localized": ["name", "description"],
@@ -327,7 +350,12 @@
},
{
"function": "TOKEN",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "ApiKey",
"options": [],
"localized": ["name", "description"],

View File

@@ -242,7 +242,12 @@
{
"function": "RUN",
"events": ["test"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": ["disabled", "on_notification"],
"localized": ["name", "description"],
@@ -269,7 +274,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/_publisher_webhook/webhook.py",
"options": [],
"localized": ["name", "description"],
@@ -296,7 +310,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 10,
"options": [],
"localized": ["name", "description"],
@@ -327,7 +350,12 @@
},
{
"function": "URL",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -354,7 +382,12 @@
},
{
"function": "PAYLOAD",
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "json",
"options": ["json", "html", "text"],
"localized": ["name", "description"],
@@ -381,7 +414,12 @@
},
{
"function": "REQUEST_METHOD",
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "GET",
"options": ["GET", "POST", "PUT"],
"localized": ["name", "description"],
@@ -408,7 +446,16 @@
},
{
"function": "SIZE",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 1024,
"options": [],
"localized": ["name", "description"],
@@ -435,7 +482,12 @@
},
{
"function": "SECRET",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],

View File

@@ -1,6 +1,7 @@
{
"code_name": "arp_scan",
"unique_prefix": "ARPSCAN",
"execution_order" : "Layer_2",
"plugin_type": "device_scanner",
"enabled": true,
"data_source": "script",
@@ -69,8 +70,13 @@
"settings": [
{
"function": "RUN",
"type": "text.select",
"default_value": "schedule",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
"disabled",
"once",
@@ -111,7 +117,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/arp_scan/script.py userSubnets={subnets}",
"options": [],
"localized": ["name", "description"],
@@ -146,7 +161,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 300,
"options": [],
"localized": ["name", "description"],
@@ -181,7 +205,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "*/5 * * * *",
"options": [],
"localized": ["name", "description"],
@@ -216,7 +245,16 @@
},
{
"function": "WATCH",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["Watched_Value1", "Watched_Value2"],
"options": [
"Watched_Value1",
@@ -256,7 +294,16 @@
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["new"],
"options": [
"new",
@@ -296,7 +343,12 @@
},
{
"function": "ARGS",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "sudo arp-scan --ignoredups --retry=6",
"options": [],
"localized": ["name", "description"],

View File

@@ -58,7 +58,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "schedule",
"options": [
"disabled",
@@ -99,7 +104,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/csv_backup/script.py overwrite={overwrite} location={location}",
"options": [],
"localized": ["name", "description"],
@@ -134,7 +148,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "0 2 * * 3",
"options": [],
"localized": ["name", "description"],
@@ -169,7 +188,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 30,
"options": [],
"localized": ["name", "description"],
@@ -204,7 +232,16 @@
},
{
"function": "overwrite",
"type": "boolean",
"type": {
"dataType": "boolean",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": false,
"options": [],
"localized": ["name", "description"],
@@ -239,7 +276,12 @@
},
{
"function": "location",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "/app/config",
"options": [],
"localized": ["name", "description"],

View File

@@ -47,7 +47,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "schedule",
"options": ["disabled", "once", "schedule", "always_after_scan"],
"localized": ["name", "description"],
@@ -74,7 +79,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/db_cleanup/script.py pluginskeephistory={pluginskeephistory} hourstokeepnewdevice={hourstokeepnewdevice} daystokeepevents={daystokeepevents} pholuskeepdays={pholuskeepdays}",
"options": [],
"localized": ["name", "description"],
@@ -109,7 +123,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "*/30 * * * *",
"options": [],
"localized": ["name", "description"],
@@ -144,7 +163,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 30,
"options": [],
"localized": ["name", "description"],
@@ -179,7 +207,16 @@
},
{
"function": "NOTIFI_HIST",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 100,
"options": [],
"localized": ["name", "description"],

View File

@@ -76,7 +76,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": ["disabled", "once", "schedule", "always_after_scan"],
"localized": ["name", "description"],
@@ -107,7 +112,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/ddns_update/script.py prev_ip={prev_ip} DDNS_UPDATE_URL={DDNS_UPDATE_URL} DDNS_USER={DDNS_USER} DDNS_PASSWORD={DDNS_PASSWORD} DDNS_DOMAIN={DDNS_DOMAIN} ",
"options": [],
"localized": ["name", "description"],
@@ -142,7 +156,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "*/5 * * * *",
"options": [],
"localized": ["name", "description"],
@@ -177,7 +196,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 30,
"options": [],
"localized": ["name", "description"],
@@ -212,7 +240,12 @@
},
{
"function": "DOMAIN",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "your_domain.freeddns.org",
"options": [],
"localized": ["name", "description"],
@@ -247,7 +280,12 @@
},
{
"function": "USER",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "dynu_user",
"options": [],
"localized": ["name", "description"],
@@ -282,7 +320,16 @@
},
{
"function": "PASSWORD",
"type": "password",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "password" }],
"transformers": []
}
]
},
"default_value": "A0000000B0000000C0000000D0000000",
"options": [],
"localized": ["name", "description"],
@@ -317,7 +364,12 @@
},
{
"function": "UPDATE_URL",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "https://api.dynu.com/nic/update?",
"options": [],
"localized": ["name", "description"],
@@ -352,7 +404,16 @@
},
{
"function": "WATCH",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["Watched_Value1"],
"options": [
"Watched_Value1",
@@ -388,7 +449,16 @@
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["new", "watched-changed"],
"options": [
"new",

View File

@@ -2,6 +2,7 @@
"code_name": "dhcp_leases",
"unique_prefix": "DHCPLSS",
"plugin_type": "device_scanner",
"execution_order" : "Layer_3",
"enabled": true,
"data_source": "script",
"data_filters": [
@@ -414,7 +415,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
"disabled",
@@ -455,7 +461,12 @@
},
{
"function": "CMD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "python3 /app/front/plugins/dhcp_leases/script.py paths={paths}",
"options": [],
"localized": ["name", "description"],
@@ -490,7 +501,63 @@
},
{
"function": "paths_to_check",
"type": "list",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "input",
"elementOptions": [
{ "placeholder": "Enter value" },
{ "suffix": "_in" },
{ "cssClasses": "col-sm-10" },
{ "prefillValue": "null" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": ["_in"] },
{ "separator": "" },
{ "cssClasses": "col-xs-12" },
{ "onClick": "addList(this, false)" },
{ "getStringKey": "Gen_Add" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeAllOptions(this)" },
{ "getStringKey": "Gen_Remove_All" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeFromList(this)" },
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
},
{
"elementType": "select",
"elementOptions": [
{ "multiple": "true" },
{ "readonly": "true" },
{ "editable": "true" }
],
"transformers": []
}
]
},
"default_value": ["/mnt/dhcp1.leases", "/mnt/dhcp2.leases"],
"options": [],
"localized": ["name", "description"],
@@ -511,21 +578,18 @@
"description": [
{
"language_code": "en_us",
"string": "Add all dhcp.leases mapped paths to watch. Enter full path within the container, e.g. <code>/mnt/dhcp2.leases</code>. You must map these files accordingly in your <code>docker-compose.yml</code> file. (If you are mapping a PiHole dhcp.leases file the path in the container must contain <code>pihole</code>, e.g.: <code>:/etc/pihole/dhcp.leases</code>)"
},
{
"language_code": "es_es",
"string": "Agregue todas las rutas asignadas de dhcp.leases para observar. Ingrese la ruta completa dentro del contenedor, p.e. <code>/mnt/dhcp2.leases</code>. Debe asignar estos archivos en consecuencia en su archivo <code>docker-compose.yml</code>. (Si está asignando un archivo PiHole dhcp.leases, la ruta en el contenedor debe contener <code>pihole</code>, por ejemplo: <code>:/etc/pihole/dhcp.leases</code>)"
},
{
"language_code": "de_de",
"string": "Alle zu überwachenden dhcp.leases-Pfade hinzufügen. Den absoluten Pfad innerhalb des Containers angeben, z.B. <code>/mnt/dchp2.leases</code>. Diese Dateien müssen korrekt in der <code>docker-compose.yml</code> gemapped werden. Wird eine PiHole dhcp.leases-Datei in den Container gemapped, so muss der Pfad im Container <code>pihole</code> inkludieren, z.B. <code>:/etc/pihole/dhcp.leases</code>"
"string": "Add all dhcp.leases mapped paths to watch. Enter full path within the container, e.g. <code>/mnt/dhcp2.leases</code>. You must map these files accordingly in your <code>docker-compose.yml</code> file. Supports pihole, dnsmasq, and generic formats. <br><br> For dnsmasq or pihole the path in the container must contain <code>pihole</code> or <code>dnsmasq</code>; e.g.: <code>:/etc/pihole/dhcp.leases</code>). See the above docs for details."
}
]
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "0 2 * * *",
"options": [],
"localized": ["name", "description"],
@@ -560,7 +624,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 5,
"options": [],
"localized": ["name", "description"],
@@ -595,7 +668,16 @@
},
{
"function": "WATCH",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["Watched_Value1", "Watched_Value4"],
"options": [
"Watched_Value1",
@@ -635,7 +717,16 @@
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["new", "watched-changed"],
"options": [
"new",

View File

@@ -2,6 +2,7 @@
"code_name": "dhcp_servers",
"unique_prefix": "DHCPSRVS",
"plugin_type": "other",
"execution_order" : "Layer_3",
"enabled": true,
"data_source": "script",
"show_ui": true,
@@ -307,7 +308,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
"disabled",
@@ -340,7 +346,12 @@
},
{
"function": "CMD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "python3 /app/front/plugins/dhcp_servers/script.py",
"options": [],
"localized": ["name", "description"],
@@ -367,7 +378,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "0 2 * * *",
"options": [],
"localized": ["name", "description"],
@@ -394,7 +410,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 10,
"options": [],
"localized": ["name", "description"],
@@ -425,7 +450,16 @@
},
{
"function": "WATCH",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["Watched_Value1"],
"options": [
"Watched_Value1",
@@ -457,7 +491,16 @@
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["new", "watched-changed"],
"options": ["new", "watched-changed", "watched-not-changed"],
"localized": ["name", "description"],

View File

@@ -153,7 +153,16 @@
"string": "Device ID Parameter"
}
],
"type": "string",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [],
"transformers": []
}
]
},
"default_value": "1",
"localized": ["name"]
},
@@ -164,7 +173,16 @@
"string": "Event Type Parameter"
}
],
"type": "string",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [],
"transformers": []
}
]
},
"default_value": "device_down",
"localized": ["name"]
},
@@ -175,7 +193,16 @@
"string": "Repetition Count Parameter"
}
],
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 3,
"localized": ["name"]
}
@@ -216,7 +243,12 @@
},
{
"function": "CMD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "UPDATE Devices SET dev_AlertDeviceDown = {KNWN_dev_AlertDeviceDown}, dev_AlertEvents = {KNWN_dev_AlertEvents} WHERE dev_MAC in ({target_macs})",
"options": [],
"localized": ["name", "description"],
@@ -235,7 +267,16 @@
},
{
"function": "dev_Name",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": "(unknown)",
"options": [],
@@ -255,7 +296,12 @@
},
{
"function": "dev_Owner",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 30,
"default_value": "House",
"override_value": {
@@ -278,7 +324,12 @@
},
{
"function": "dev_DeviceType",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 30,
"default_value": "",
"options": [],
@@ -298,7 +349,16 @@
},
{
"function": "dev_Vendor",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 250,
"default_value": "",
"options": [],
@@ -318,7 +378,16 @@
},
{
"function": "dev_Favorite",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"override_value": {
"override": false
@@ -340,7 +409,12 @@
},
{
"function": "dev_Group",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 10,
"default_value": "",
"override_value": {
@@ -363,7 +437,12 @@
},
{
"function": "dev_Comments",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -382,7 +461,16 @@
},
{
"function": "dev_FirstConnection",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
@@ -402,7 +490,16 @@
},
{
"function": "dev_LastConnection",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
@@ -422,7 +519,16 @@
},
{
"function": "dev_LastIP",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": "",
"options": [],
@@ -442,7 +548,16 @@
},
{
"function": "dev_StaticIP",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"override_value": {
"override": true
@@ -464,7 +579,16 @@
},
{
"function": "dev_ScanCycle",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"override_value": {
"override": true
@@ -486,7 +610,16 @@
},
{
"function": "dev_LogEvents",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"override_value": {
"override": false
@@ -508,7 +641,16 @@
},
{
"function": "dev_AlertEvents",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"override_value": {
"override": true
@@ -530,7 +672,16 @@
},
{
"function": "dev_AlertDeviceDown",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
@@ -549,7 +700,16 @@
},
{
"function": "dev_SkipRepeated",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
@@ -568,7 +728,16 @@
},
{
"function": "dev_LastNotification",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
@@ -588,7 +757,16 @@
},
{
"function": "dev_PresentLastScan",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"options": [],
"localized": ["name", "description"],
@@ -607,7 +785,16 @@
},
{
"function": "dev_NewDevice",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": true,
"options": [],
"localized": ["name", "description"],
@@ -626,7 +813,12 @@
},
{
"function": "dev_Location",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 250,
"default_value": "",
"options": [],
@@ -646,7 +838,16 @@
},
{
"function": "dev_Archived",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
@@ -665,7 +866,12 @@
},
{
"function": "dev_Network_Node_MAC_ADDR",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -684,7 +890,16 @@
},
{
"function": "dev_Network_Node_port",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
@@ -703,7 +918,12 @@
},
{
"function": "dev_Icon",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],

View File

@@ -2,6 +2,7 @@
"code_name": "internet_ip",
"unique_prefix": "INTRNT",
"plugin_type": "device_scanner",
"execution_order" : "Layer_3",
"enabled": true,
"mapped_to_table": "CurrentScan",
"data_filters": [
@@ -63,8 +64,13 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"default_value": "schedule",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": ["disabled", "once", "schedule", "always_after_scan"],
"localized": ["name", "description"],
"name": [
@@ -94,7 +100,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/internet_ip/script.py prev_ip={prev_ip} INTRNT_DIG_GET_IP_ARG={INTRNT_DIG_GET_IP_ARG}",
"options": [],
"localized": ["name", "description"],
@@ -129,7 +144,12 @@
},
{
"function": "DIG_GET_IP_ARG",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "-4 myip.opendns.com @resolver1.opendns.com",
"options": [],
"localized": ["name", "description"],
@@ -164,7 +184,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "*/5 * * * *",
"options": [],
"localized": ["name", "description"],
@@ -199,7 +224,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 30,
"options": [],
"localized": ["name", "description"],
@@ -234,7 +268,16 @@
},
{
"function": "RETRIES",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 3,
"options": [],
"localized": ["name", "description"],
@@ -253,7 +296,16 @@
},
{
"function": "WATCH",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["Watched_Value1"],
"options": [
"Watched_Value1",
@@ -279,7 +331,7 @@
"description": [
{
"language_code": "en_us",
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Previous IP (not recommended)</li><li><code>Watched_Value2</code> unused</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> unused </li></ul>"
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Previous IP (not recommended)</li><li><code>Watched_Value2</code> unused</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> type </li></ul>"
},
{
"language_code": "de_de",
@@ -289,7 +341,16 @@
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["new", "watched-changed"],
"options": [
"new",
@@ -426,6 +487,22 @@
}
]
},
{
"column": "Watched_Value4",
"mapped_to_column": "cur_Type",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Type"
}
]
},
{
"column": "Dummy",
"mapped_to_column": "cur_ScanMethod",

View File

@@ -71,7 +71,7 @@ def main():
watched1 = f'Previous IP: {PREV_IP}',
watched2 = cmd_output.replace('\n',''),
watched3 = retries_needed,
watched4 = '',
watched4 = 'Gateway',
extra = f'Previous IP: {PREV_IP}',
foreignKey = 'Internet')

View File

@@ -377,7 +377,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": ["disabled", "once", "schedule", "always_after_scan"],
"localized": ["name", "description"],
@@ -408,7 +413,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/internet_speedtest/script.py",
"options": [],
"localized": ["name", "description"],
@@ -443,7 +457,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "*/30 * * * *",
"options": [],
"localized": ["name", "description"],
@@ -478,7 +497,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 60,
"options": [],
"localized": ["name", "description"],
@@ -513,7 +541,16 @@
},
{
"function": "WATCH",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": [],
"options": [
"Watched_Value1",
@@ -549,7 +586,16 @@
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": [],
"options": [
"new",

View File

@@ -159,7 +159,12 @@
},
{
"function": "CMD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "UPDATE Devices SET dev_AlertDeviceDown = {KNWN_dev_AlertDeviceDown}, dev_AlertEvents = {KNWN_dev_AlertEvents} WHERE dev_MAC in ({target_macs})",
"options": [],
"localized": ["name", "description"],
@@ -178,7 +183,16 @@
},
{
"function": "dev_Name",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": "(unknown)",
"options": [],
@@ -198,7 +212,12 @@
},
{
"function": "dev_Owner",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 30,
"default_value": "House",
"override_value": {
@@ -221,7 +240,12 @@
},
{
"function": "dev_DeviceType",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 30,
"default_value": "",
"options": [],
@@ -241,7 +265,16 @@
},
{
"function": "dev_Vendor",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 250,
"default_value": "",
"options": [],
@@ -261,7 +294,16 @@
},
{
"function": "dev_Favorite",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"override_value": {
"override": false
@@ -283,7 +325,12 @@
},
{
"function": "dev_Group",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 10,
"default_value": "",
"override_value": {
@@ -306,7 +353,12 @@
},
{
"function": "dev_Comments",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -325,7 +377,16 @@
},
{
"function": "dev_FirstConnection",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
@@ -345,7 +406,16 @@
},
{
"function": "dev_LastConnection",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
@@ -365,7 +435,16 @@
},
{
"function": "dev_LastIP",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": "",
"options": [],
@@ -385,7 +464,16 @@
},
{
"function": "dev_StaticIP",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"override_value": {
"override": true
@@ -407,7 +495,16 @@
},
{
"function": "dev_ScanCycle",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"override_value": {
"override": true
@@ -429,7 +526,16 @@
},
{
"function": "dev_LogEvents",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"override_value": {
"override": false
@@ -451,7 +557,16 @@
},
{
"function": "dev_AlertEvents",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"override_value": {
"override": true
@@ -473,7 +588,16 @@
},
{
"function": "dev_AlertDeviceDown",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
@@ -492,7 +616,16 @@
},
{
"function": "dev_SkipRepeated",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
@@ -511,7 +644,16 @@
},
{
"function": "dev_LastNotification",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
@@ -531,7 +673,16 @@
},
{
"function": "dev_PresentLastScan",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"options": [],
"localized": ["name", "description"],
@@ -550,7 +701,16 @@
},
{
"function": "dev_NewDevice",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": true,
"options": [],
"localized": ["name", "description"],
@@ -569,7 +729,12 @@
},
{
"function": "dev_Location",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 250,
"default_value": "",
"options": [],
@@ -589,7 +754,16 @@
},
{
"function": "dev_Archived",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
@@ -608,7 +782,12 @@
},
{
"function": "dev_Network_Node_MAC_ADDR",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -627,7 +806,16 @@
},
{
"function": "dev_Network_Node_port",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
@@ -646,7 +834,12 @@
},
{
"function": "dev_Icon",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],

View File

@@ -29,7 +29,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "schedule",
"options": [
"disabled",
@@ -62,7 +67,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/maintenance/maintenance.py",
"options": [],
"localized": ["name", "description"],
@@ -97,7 +111,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "0 2 * * *",
"options": [],
"localized": ["name", "description"],
@@ -132,7 +151,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 30,
"options": [],
"localized": ["name", "description"],
@@ -167,7 +195,16 @@
},
{
"function": "LOG_LENGTH",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 250000,
"options": [],
"localized": ["name", "description"],

View File

@@ -0,0 +1,7 @@
## Overview
Plugin for device name discovery via the [nbtscan](https://linuxcommandlibrary.com/man/nbtscan) network utility supporting NetBIOS.
### Usage
- Check the Settings page for details.

View File

@@ -0,0 +1,338 @@
{
"code_name": "nbtscan_scan",
"unique_prefix": "NBTSCAN",
"plugin_type": "other",
"enabled": true,
"data_source": "script",
"execution_order" : "Layer_3",
"show_ui": true,
"localized": ["display_name", "description", "icon"],
"display_name": [
{
"language_code": "en_us",
"string": "NBTSCAN (Name discovery)"
}
],
"icon": [
{
"language_code": "en_us",
"string": "<i class=\"fa-solid fa-search\"></i>"
}
],
"description": [
{
"language_code": "en_us",
"string": "A plugin to discover device names via NetBIOS."
}
],
"params": [
{
"name": "ips",
"type": "sql",
"value": "SELECT dev_LastIP from DEVICES order by dev_MAC",
"timeoutMultiplier": true
}
],
"settings": [
{
"function": "RUN",
"events": ["run"],
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
"disabled",
"before_name_updates",
"on_new_device",
"once",
"schedule",
"always_after_scan"
],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "When to run"
},
{
"language_code": "es_es",
"string": "Cuándo ejecutar"
},
{
"language_code": "de_de",
"string": "Wann laufen"
}
],
"description": [
{
"language_code": "en_us",
"string": "When the plugin should be executed. If enabled this will execute the scan until there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Setting this to <code>on_new_device</code> or a daily <code>schedule</code> is recommended.<br/><br/> Depends on the <a onclick=\"toggleAllSettings()\" href=\"#SCAN_SUBNETS\"><code>SCAN_SUBNETS</code> setting</a>."
}
]
},
{
"function": "CMD",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/nbtscan_scan/nbtscan.py",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Command"
},
{
"language_code": "es_es",
"string": "Comando"
},
{
"language_code": "de_de",
"string": "Befehl"
}
],
"description": [
{
"language_code": "en_us",
"string": "Command to run. This can not be changed"
},
{
"language_code": "es_es",
"string": "Comando a ejecutar. Esto no se puede cambiar"
},
{
"language_code": "de_de",
"string": "Befehl zum Ausführen. Dies kann nicht geändert werden"
}
]
},
{
"function": "RUN_SCHD",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "*/30 * * * *",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Schedule"
},
{
"language_code": "es_es",
"string": "Schedule"
},
{
"language_code": "de_de",
"string": "Schedule"
}
],
"description": [
{
"language_code": "en_us",
"string": "Only enabled if you select <code>schedule</code> in the <a href=\"#NBTSCAN_RUN\"><code>NBTSCAN_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes."
},
{
"language_code": "es_es",
"string": "Solo está habilitado si selecciona <code>schedule</code> en la configuración <a href=\"#NBTSCAN_RUN\"><code>NBTSCAN_RUN</code></a>. Asegúrese de ingresar la programación en el formato similar a cron correcto (por ejemplo, valide en <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Por ejemplo, ingresar <code>0 4 * * *</code> ejecutará el escaneo después de las 4 a.m. en el <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</ código> que configuró arriba</a>. Se ejecutará la PRÓXIMA vez que pase el tiempo."
},
{
"language_code": "de_de",
"string": "Nur aktiviert, wenn Sie <code>schedule</code> in der <a href=\"#NBTSCAN_RUN\"><code>NBTSCAN_RUN</code>-Einstellung</a> auswählen. Stellen Sie sicher, dass Sie den Zeitplan im richtigen Cron-ähnlichen Format eingeben (z. B. validieren unter <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Wenn Sie beispielsweise <code>0 4 * * *</code> eingeben, wird der Scan nach 4 Uhr morgens in der <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</ ausgeführt. Code> den Sie oben festgelegt haben</a>. Wird das NÄCHSTE Mal ausgeführt, wenn die Zeit vergeht."
}
]
},
{
"function": "RUN_TIMEOUT",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 10,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Run timeout"
},
{
"language_code": "es_es",
"string": "Tiempo límite de ejecución"
},
{
"language_code": "de_de",
"string": "Zeitüberschreitung"
}
],
"description": [
{
"language_code": "en_us",
"string": "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted."
},
{
"language_code": "es_es",
"string": "Tiempo máximo en segundos para esperar a que finalice el script. Si se supera este tiempo, el script se cancela."
},
{
"language_code": "de_de",
"string": "Maximale Zeit in Sekunden, die auf den Abschluss des Skripts gewartet werden soll. Bei Überschreitung dieser Zeit wird das Skript abgebrochen."
}
]
}
],
"database_column_definitions": [
{
"column": "Object_PrimaryID",
"css_classes": "col-sm-2",
"show": true,
"type": "device_name_mac",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "MAC"
},
{
"language_code": "es_es",
"string": "MAC"
}
]
},
{
"column": "Object_SecondaryID",
"css_classes": "col-sm-2",
"show": true,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "IP"
},
{
"language_code": "es_es",
"string": "IP"
}
]
},
{
"column": "Watched_Value1",
"css_classes": "col-sm-2",
"show": true,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Server"
}
]
},
{
"column": "Watched_Value2",
"css_classes": "col-sm-2",
"show": true,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Name"
}
]
},
{
"column": "DateTimeCreated",
"css_classes": "col-sm-2",
"show": true,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Created"
}
]
},
{
"column": "DateTimeChanged",
"css_classes": "col-sm-2",
"show": true,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Changed"
}
]
},
{
"column": "Status",
"css_classes": "col-sm-1",
"show": true,
"type": "replace",
"default_value": "",
"options": [
{
"equals": "watched-not-changed",
"replacement": "<div style='text-align:center'><i class='fa-solid fa-square-check'></i><div></div>"
},
{
"equals": "watched-changed",
"replacement": "<div style='text-align:center'><i class='fa-solid fa-triangle-exclamation'></i></div>"
},
{
"equals": "new",
"replacement": "<div style='text-align:center'><i class='fa-solid fa-circle-plus'></i></div>"
},
{
"equals": "missing-in-last-scan",
"replacement": "<div style='text-align:center'><i class='fa-solid fa-question'></i></div>"
}
],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Status"
}
]
}
]
}

View File

@@ -0,0 +1,139 @@
#!/usr/bin/env python
import os
import pathlib
import sys
import json
import sqlite3
import subprocess
# Define the installation path and extend the system path for plugin imports
INSTALL_PATH = "/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from plugin_utils import get_plugins_configs
from logger import mylog
from const import pluginsPath, fullDbPath
from helper import timeNowTZ, get_setting_value
from notification import write_notification
from database import DB
from device import Device_obj
# Define the current path and log file paths
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')
# Initialize the Plugin obj output file
plugin_objects = Plugin_Objects(RESULT_FILE)
pluginName = 'NBTSCAN'
def main():
mylog('verbose', [f'[{pluginName}] In script'])
# timeout = get_setting_value('NBLOOKUP_RUN_TIMEOUT')
timeout = 20
# Create a database connection
db = DB() # instance of class DB
db.open()
# Initialize the Plugin obj output file
plugin_objects = Plugin_Objects(RESULT_FILE)
# Create a Device_obj instance
device_handler = Device_obj(db)
# Retrieve devices
unknown_devices = device_handler.getUnknown()
mylog('verbose', [f'[{pluginName}] Unknown devices count: {len(unknown_devices)}'])
# TEST
# execute_name_lookup('192.168.1.121', timeout)
for device in unknown_devices:
domain_name, dns_server = execute_name_lookup(device['dev_LastIP'], timeout)
if domain_name != '':
plugin_objects.add_object(
# "MAC", "IP", "Server", "Name"
primaryId = device['dev_MAC'],
secondaryId = device['dev_LastIP'],
watched1 = dns_server,
watched2 = domain_name,
watched3 = '',
watched4 = '',
extra = '',
foreignKey = device['dev_MAC'])
plugin_objects.write_result_file()
mylog('verbose', [f'[{pluginName}] Script finished'])
return 0
#===============================================================================
# Execute scan
#===============================================================================
def execute_name_lookup (ip, timeout):
"""
Execute the NBLOOKUP command on IP.
"""
args = ['nbtscan', ip]
# Execute command
output = ""
try:
# try runnning a subprocess with a forced (timeout) in case the subprocess hangs
output = subprocess.check_output (args, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(timeout), text=True)
mylog('verbose', [f'[{pluginName}] DEBUG OUTPUT : {output}'])
domain_name = ''
dns_server = ''
# Split the output into lines
lines = output.splitlines()
# Look for the first line containing a valid NetBIOS name entry
index = 0
for line in lines:
if 'Doing NBT name scan' not in line and ip in line:
# Split the line and extract the primary NetBIOS name
parts = line.split()
if parts:
domain_name = parts[1]
mylog('verbose', [f'[{pluginName}] Domain Name: {domain_name}'])
return domain_name, dns_server
except subprocess.CalledProcessError as e:
# An error occurred, handle it
# if "NXDOMAIN" in e.output:
# mylog('verbose', [f'[{pluginName}]', f"No PTR record found for IP: {ip}"])
# else:
mylog('verbose', [f'[{pluginName}]', e.output])
# Handle other errors here
# mylog('verbose', [f'[{pluginName}] ⚠ ERROR - check logs'])
except subprocess.TimeoutExpired as timeErr:
mylog('verbose', [f'[{pluginName}] TIMEOUT - the process forcefully terminated as timeout reached'])
if output == "": # check if the subprocess failed
mylog('verbose', [f'[{pluginName}] Scan: FAIL - check logs'])
else:
mylog('verbose', [f'[{pluginName}] Scan: SUCCESS'])
return '', ''
if __name__ == '__main__':
main()

View File

@@ -28,7 +28,63 @@
"settings": [
{
"function": "ignored_MACs",
"type": "list",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "input",
"elementOptions": [
{ "placeholder": "Enter value" },
{ "suffix": "_in" },
{ "cssClasses": "col-sm-10" },
{ "prefillValue": "null" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": ["_in"] },
{ "separator": "" },
{ "cssClasses": "col-xs-12" },
{ "onClick": "addList(this, false)" },
{ "getStringKey": "Gen_Add" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeAllOptions(this)" },
{ "getStringKey": "Gen_Remove_All" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeFromList(this)" },
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
},
{
"elementType": "select",
"elementOptions": [
{ "multiple": "true" },
{ "readonly": "true" },
{ "editable": "true" }
],
"transformers": []
}
]
},
"default_value": [],
"options": [],
"localized": ["name", "description"],
@@ -47,7 +103,63 @@
},
{
"function": "ignored_IPs",
"type": "list",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "input",
"elementOptions": [
{ "placeholder": "Enter value" },
{ "suffix": "_in" },
{ "cssClasses": "col-sm-10" },
{ "prefillValue": "null" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": ["_in"] },
{ "separator": "" },
{ "cssClasses": "col-xs-12" },
{ "onClick": "addList(this, false)" },
{ "getStringKey": "Gen_Add" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeAllOptions(this)" },
{ "getStringKey": "Gen_Remove_All" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeFromList(this)" },
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
},
{
"elementType": "select",
"elementOptions": [
{ "multiple": "true" },
{ "readonly": "true" },
{ "editable": "true" }
],
"transformers": []
}
]
},
"default_value": [],
"options": [],
"localized": ["name", "description"],
@@ -64,9 +176,104 @@
}
]
},
{
"function": "NAME_CLEANUP_REGEX",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "input",
"elementOptions": [
{ "placeholder": "Enter value" },
{ "suffix": "_in" },
{ "cssClasses": "col-sm-10" },
{ "prefillValue": "null" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-sm-3" },
{ "onClick": "removeAllOptions(this)" },
{ "getStringKey": "Gen_Remove_All" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-sm-3" },
{ "onClick": "removeFromList(this)" },
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": ["_in"] },
{ "separator": "" },
{ "cssClasses": "col-sm-2" },
{ "onClick": "addList(this, false)" },
{ "getStringKey": "Gen_Add" }
],
"transformers": []
},
{
"elementType": "select",
"elementOptions": [
{ "multiple": "true" },
{ "readonly": "true" },
{ "editable": "true" }
],
"transformers": ["base64"]
}
]
},
"default_value": [
"XC5fYWlycGxheQ==",
"XC5fdGNw",
"XC5sb2NhbGRvbWFpbg==",
"XC5sb2NhbA==",
"XC5fZXNwaG9tZWxpYg==",
"XC5fZ29vZ2xlY2FzdA==",
"XC5sYW4=",
"XC5ob21l",
"LVthLWZBLUYwLTldezMyfQ==",
"Iy4q"
],
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Name Cleanup REGEX"
}
],
"description": [
{
"language_code": "en_us",
"string": "All the newly discovered device names are clened up by applying the following REGEX expression in this order. All the below are replaced by a blank string."
}
]
},
{
"function": "dev_MAC",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": "",
"options": [],
@@ -86,7 +293,16 @@
},
{
"function": "dev_Name",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": "(unknown)",
"options": [],
@@ -106,7 +322,12 @@
},
{
"function": "dev_Owner",
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 30,
"default_value": "",
"options": ["{value}"],
@@ -133,7 +354,12 @@
},
{
"function": "dev_DeviceType",
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 30,
"default_value": "",
"options": ["{value}"],
@@ -165,7 +391,16 @@
},
{
"function": "dev_Vendor",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 250,
"default_value": "",
"options": [],
@@ -185,7 +420,16 @@
},
{
"function": "dev_Favorite",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
@@ -204,7 +448,12 @@
},
{
"function": "dev_Group",
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 10,
"default_value": "",
"options": ["{value}"],
@@ -231,7 +480,12 @@
},
{
"function": "dev_Comments",
"type": "string",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -250,7 +504,16 @@
},
{
"function": "dev_FirstConnection",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
@@ -270,7 +533,16 @@
},
{
"function": "dev_LastConnection",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
@@ -290,7 +562,16 @@
},
{
"function": "dev_LastIP",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": "",
"options": [],
@@ -310,7 +591,16 @@
},
{
"function": "dev_StaticIP",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
@@ -329,7 +619,16 @@
},
{
"function": "dev_ScanCycle",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"options": [],
"localized": ["name", "description"],
@@ -348,7 +647,16 @@
},
{
"function": "dev_LogEvents",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"options": [],
"localized": ["name", "description"],
@@ -367,7 +675,16 @@
},
{
"function": "dev_AlertEvents",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"options": [],
"localized": ["name", "description"],
@@ -386,7 +703,16 @@
},
{
"function": "dev_AlertDeviceDown",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
@@ -405,7 +731,12 @@
},
{
"function": "dev_SkipRepeated",
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": 0,
"options": ["{value}"],
"options_params": [
@@ -431,7 +762,16 @@
},
{
"function": "dev_LastNotification",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
@@ -451,7 +791,16 @@
},
{
"function": "dev_PresentLastScan",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"options": [],
"localized": ["name", "description"],
@@ -470,7 +819,16 @@
},
{
"function": "dev_NewDevice",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"options": [],
"localized": ["name", "description"],
@@ -489,7 +847,12 @@
},
{
"function": "dev_Location",
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 250,
"default_value": "",
"options": ["{value}"],
@@ -516,7 +879,16 @@
},
{
"function": "dev_Archived",
"type": "integer.checkbox",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
@@ -535,7 +907,12 @@
},
{
"function": "dev_Network_Node_MAC_ADDR",
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": ["{value}"],
"options_params": [
@@ -566,7 +943,16 @@
},
{
"function": "dev_Network_Node_port",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
@@ -585,7 +971,12 @@
},
{
"function": "dev_Icon",
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": ["{value}"],
"options_params": [
@@ -608,25 +999,6 @@
"string": "The icon associated with the device. Check the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/ICONS.md\" target=\"_blank\">documentation on icons</a> for more details."
}
]
},
{
"function": "LESS_NAME_CLEANUP",
"type": "integer.checkbox",
"default_value": 0,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Less Name Cleanup"
}
],
"description": [
{
"language_code": "en_us",
"string": "Check to start using the new code for cleaning device names. Removes all labels starting with underscore and removes network domain and search list."
}
]
}
],
"required": [

View File

@@ -2,6 +2,7 @@
"code_name": "nmap_dev_scan",
"unique_prefix": "NMAPDEV",
"plugin_type": "device_scanner",
"execution_order" : "Layer_3",
"enabled": true,
"data_source": "script",
"mapped_to_table": "CurrentScan",
@@ -45,7 +46,12 @@
"settings": [
{
"function": "RUN",
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
"disabled",
@@ -87,7 +93,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/nmap_dev_scan/nmap_dev.py ",
"options": [],
"localized": ["name", "description"],
@@ -122,7 +137,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 300,
"options": [],
"localized": ["name", "description"],
@@ -157,7 +181,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "*/5 * * * *",
"options": [],
"localized": ["name", "description"],
@@ -192,7 +221,16 @@
},
{
"function": "WATCH",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": [],
"options": [
"Watched_Value1",
@@ -232,7 +270,16 @@
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["new"],
"options": [
"new",
@@ -272,7 +319,12 @@
},
{
"function": "ARGS",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "sudo nmap -sn -PR -oX - ",
"options": [],
"localized": ["name", "description"],

View File

@@ -84,7 +84,7 @@ def execute_scan(subnets_list, timeout):
for interface in subnets_list:
nmap_output = execute_scan_on_interface(interface, timeout)
mylog('verbose', [f"[{pluginName}] nmap_output: ", nmap_output])
# mylog('verbose', [f"[{pluginName}] nmap_output XML: ", nmap_output])
if nmap_output: # Proceed only if nmap output is not empty
# Parse the XML output using python-nmap

View File

@@ -2,6 +2,7 @@
"code_name": "nmap_scan",
"unique_prefix": "NMAP",
"plugin_type": "other",
"execution_order" : "Layer_4",
"enabled": true,
"data_source": "script",
"data_filters": [
@@ -354,7 +355,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
"disabled",
@@ -387,7 +393,12 @@
},
{
"function": "CMD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "python3 /app/front/plugins/nmap_scan/script.py ips={ips} macs={macs} timeout={timeout} args={args}",
"options": [],
"localized": ["name", "description"],
@@ -414,7 +425,12 @@
},
{
"function": "ARGS",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "-p -10000",
"options": [],
"localized": ["name", "description"],
@@ -441,7 +457,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "0 2 * * *",
"options": [],
"localized": ["name", "description"],
@@ -468,7 +489,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 30,
"options": [],
"localized": ["name", "description"],
@@ -495,7 +525,16 @@
},
{
"function": "WATCH",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["Watched_Value1"],
"options": [
"Watched_Value1",
@@ -527,7 +566,16 @@
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["new", "watched-changed"],
"options": ["new", "watched-changed", "watched-not-changed"],
"localized": ["name", "description"],

View File

@@ -29,7 +29,16 @@
"settings": [
{
"function": "INCLUDED_SECTIONS",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["new_devices", "down_devices", "events"],
"options": [
"new_devices",
@@ -70,7 +79,16 @@
},
{
"function": "alert_down_time",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 5,
"options": [],
"localized": ["name", "description"],
@@ -89,7 +107,12 @@
},
{
"function": "new_dev_condition",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
@@ -108,7 +131,12 @@
},
{
"function": "event_condition",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],

View File

@@ -2,6 +2,7 @@
"code_name": "nslookup_scan",
"unique_prefix": "NSLOOKUP",
"plugin_type": "other",
"execution_order" : "Layer_4",
"enabled": true,
"data_source": "script",
"show_ui": true,
@@ -36,8 +37,13 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"default_value": "before_name_updates",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
"disabled",
"before_name_updates",
@@ -70,7 +76,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/nslookup_scan/nslookup.py",
"options": [],
"localized": ["name", "description"],
@@ -105,7 +120,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "*/30 * * * *",
"options": [],
"localized": ["name", "description"],
@@ -140,7 +160,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 10,
"options": [],
"localized": ["name", "description"],

View File

@@ -1,18 +1,33 @@
## Overview
PLugin functionality overview and links to external resources if relevant. Include use cases if available.
The OMADA SDN plugin aims at synchronizing data between NetAlertX and a TPLINK OMADA SND controler by leveraging a tplink omada python library.
#### features:
1. extract list of OMADA Clients from OMADA and sync them up with NetAlertX
2. extract list of OAMDA Devices (switches and access points) and sync them up with NetAlertX
> [!TIP]
> Some tip.
> some omada devices are apparently not fully compatible with the API which might lead to partial results.
### Quick setup guide
To set up the plugin correctly, make sure...
1. You SHOULD (ie: strongly recommend) set up an account in your OMADA SDN console dedicated to NetAlertX OMADA_SDN plugin.
- you should set USER TYPE = Local USer
- you should set USER ROLE = Administrator (if you use a read-only role you won't be able to sync names from NetAlerX to OMADA SDN)
- you can set Site Privileges = All Sites (or limit it to specific sites )
2. populate the variables in NetAlertX as instructed in the config plugin page.
#### Required Settings
- When to run `PREF_RUN`
-
- OMDSDN_url
- OMDSDN_sites
- OMDSDN_username
- OMDSDN_password
- OMDSDN_force_overwrite
### Usage
@@ -20,4 +35,37 @@ To set up the plugin correctly, make sure...
### Notes
- Additional notes, limitations, Author info.
#### features not implemented yet:
3. extract list of OAMDA router Devices (er605...) and sync them up with NetAlertX
(I need to setup my own er605 however due to its limitations I have no use for it, and due to limitations of opensense dhcp servers, I can't deploy it yet without breaking dhcp self registration into opnsense unbound - see below)
#### know limitations:
OMADA SDN limitation fixed by the plugin:
0. OMADA SDN can't use DNS for names and keep using MAC ref: https://community.tp-link.com/en/business/forum/topic/503782
- when you use an OMADA user Role = Administrator, the plugin will attempt to fix OMADA's shortcoming and populat the NAME field from NetAlertX (from DNS/DHCP/...)
![OMADA SDN account page](Oamadaomada_sdn_imp.png)
-
can not fix some of tplinks OMADA SDN own limitations/bugs:
1. OMADA SDN switches uplinks/downlinks is broken if the default router is not an OMADA native device
- (I try to circumvent that through a tree parsing heuristic but your mileage might vary...)
- ref: https://community.tp-link.com/en/business/forum/topic/673628
2. OMADA SDN clients are sometimes mapped to the wrong switch/port... for instance:
- client -> access_switch1/port1 -> core_switch2/port2 sometimes shows as client -> core_switch2/port2
- it is unclear if this issue is realted to (1)
3. OMADA er605 routers do not self register DHCP names with a remote unbound DNS (nor embded DNS):
- ref: https://community.tp-link.com/en/business/forum/topic/542472
- it looks like some release candidate firmware might provide this feature... I will test when opnsesne Kea self registration get fixed as well(4)and I can get it dhcp proxy to work.
4. Opnsense dhcp doesn't support relay and self-registration at the same time...
- opnsense legacy ISC dhcp server doesn't support dhcp proxies: ref: https://forum.opnsense.org/index.php?topic=34254.0
- opnsense new kea dhcp server doesn't support dns self registration (yet) ref: https://github.com/opnsense/core/pull/7362
5. incompatible devices:
- OMADA EAP245 - to be fair to tp-link, this access point works inside OMADA SDN, so it might be an issue with our omada python library but we can't extract data from it.
### Other infos
- Author : Flying Toto
- Date : 04-Jul-2024 - version 1.0

View File

@@ -2,6 +2,7 @@
"code_name": "omada_sdn_imp",
"unique_prefix": "OMDSDN",
"plugin_type": "device_scanner",
"execution_order" : "Layer_0",
"enabled": true,
"data_source": "script",
"mapped_to_table": "CurrentScan",
@@ -39,15 +40,15 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
"disabled",
"once",
"schedule",
"always_after_scan"
],
"options": ["disabled", "once", "schedule", "always_after_scan"],
"localized": ["name", "description"],
"name": [
{
@@ -72,7 +73,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "*/5 * * * *",
"options": [],
@@ -100,7 +106,12 @@
},
{
"function": "url",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 50,
"default_value": "",
"options": [],
@@ -114,33 +125,93 @@
"description": [
{
"language_code": "en_us",
"string": "Enter full URL with protocol <code>https://CHANGEME_omada.mylocaldomain</code>."
"string": "Enter full URL with protocol <code>https://CHANGEME_omada.mylocaldomain:PORT</code>."
}
]
},
{
"function": "site",
"type": "text",
"maxLength": 50,
"default_value": "",
"function": "sites",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "input",
"elementOptions": [
{ "placeholder": "Enter value" },
{ "suffix": "_in" },
{ "cssClasses": "col-sm-10" },
{ "prefillValue": "null" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": ["_in"] },
{ "separator": "" },
{ "cssClasses": "col-xs-12" },
{ "onClick": "addList(this, false)" },
{ "getStringKey": "Gen_Add" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeAllOptions(this)" },
{ "getStringKey": "Gen_Remove_All" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeFromList(this)" },
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
},
{
"elementType": "select",
"elementOptions": [
{ "multiple": "true" },
{ "readonly": "true" },
{ "editable": "true" }
],
"transformers": []
}
]
},
"default_value": [],
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "OMADA site"
"string": "OMADA sites"
}
],
"description": [
{
"language_code": "en_us",
"string": "Omada SDN site id. You can get it by..."
"string": "Omada SDN site IDs. For now, we only process the first site listed since NetAlertX's other probes won't traverse across NAT and routers. But if needed please submit an issue in github with your specific use case for consideration: <code>https://github.com/jokob-sk/NetAlertX/issues </code> "
}
]
},
{
"function": "username",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 50,
"default_value": "",
"options": [],
@@ -160,7 +231,16 @@
},
{
"function": "password",
"type": "password",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "password" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": "",
"options": [],
@@ -174,13 +254,50 @@
"description": [
{
"language_code": "en_us",
"string": "Omada SDN instance password"
"string": "Omada SDN instance password."
}
]
},
{
"function": "force_overwrite",
"type": {
"dataType": "boolean",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": false,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Force overwrite"
}
],
"description": [
{
"language_code": "en_us",
"string": "The plugin synchronizes names from NetAlertX to OMADA Clients. By default NetAlertX will only populate missing names in OMADASDN devices (i.e.: where the name is defaulting to the device MAC address); with this setting toggled, it will overwrite existing values regardless."
}
]
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/omada_sdn_imp/omada_sdn.py",
"options": [],
"localized": ["name", "description"],
@@ -215,7 +332,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 30,
"options": [],
"localized": ["name", "description"],
@@ -247,6 +373,76 @@
"string": "Maximale Zeit in Sekunden, die auf den Abschluss des Skripts gewartet werden soll. Bei Überschreitung dieser Zeit wird das Skript abgebrochen."
}
]
},
{
"default_value": [],
"description": [
{
"language_code": "en_us",
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Hostname </li><li><code>Watched_Value2</code> is Parent Node </li><li><code>Watched_Value3</code> is Port </li><li><code>Watched_Value4</code> is SSID </li></ul>"
}
],
"function": "WATCH",
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Watched"
},
{
"language_code": "es_es",
"string": "Visto"
}
],
"options": [
"Watched_Value1",
"Watched_Value2",
"Watched_Value3",
"Watched_Value4"
],
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
}
},
{
"default_value": ["new", "watched-changed"],
"description": [
{
"language_code": "en_us",
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
}
],
"function": "REPORT_ON",
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Report on"
}
],
"options": [
"new",
"watched-changed",
"watched-not-changed",
"missing-in-last-scan"
],
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
}
}
],
"database_column_definitions": [
@@ -364,7 +560,7 @@
},
{
"column": "Extra",
"mapped_to_column": "cur_NetworkSite",
"mapped_to_column": "cur_Type",
"css_classes": "col-sm-2",
"show": false,
"type": "label",

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View File

@@ -1,12 +1,33 @@
#!/usr/bin/env python
__author__ = "ffsb"
__version__ = "0.1" #initial
__version__ = "0.2" # added logic to retry omada api call once as it seems to sometimes fail for some reasons, and error handling logic...
__version__ = "0.3" # split devices API calls to allow multithreading but had to stop due to concurency issues.
__version__ = "0.6" # found issue with multithreading - my omada calls redirect stdout which gets clubbered by normal stdout... not sure how to fix for now...
# query OMADA SDN to populate NetAlertX witch omada switches, access points, clients.
# try to identify and populate their connections by switch/accesspoints and ports/SSID
# try to differentiate root bridges from accessory
#
# sample code to update unbound on opnsense - for reference...
# curl -X POST -d '{"host":{"enabled":"1","hostname":"test","domain":"testdomain.com","rr":"A","mxprio":"","mx":"","server":"10.0.1.1","description":""}}' -H "Content-Type: application/json" -k -u $OPNS_KEY:$OPNS_SECRET https://$IPFW/api/unbound/settings/AddHostOverride
#
import os
import pathlib
import sys
import json
import sqlite3
import tplink_omada_client
import importlib.util
import time
import io
import re
import concurrent.futures
#import netifaces
# Define the installation path and extend the system path for plugin imports
INSTALL_PATH = "/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
@@ -22,26 +43,168 @@ from notification import write_notification
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')
OMADA_API_RETURN_FILE = os.path.join(CUR_PATH, 'omada_api_return')
# Initialize the Plugin obj output file
plugin_objects = Plugin_Objects(RESULT_FILE)
#
# sample target output:
# 0 MAC, 1 IP, 2 Name, 3 switch/AP, 4 port/SSID, 5 TYPE
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-6F', '192.168.0.217', '1A-2B-3C-4D-5E-6F', '17', '40-AE-30-A5-A7-50, 'Switch']"
# Constants for array indices
MAC, IP, NAME, SWITCH_AP, PORT_SSID, TYPE = range(6)
# sample omada devices input format:
#
# 0.MAC 1.IP 2.type 3.status 4.name 5.model
#40-AE-30-A5-A7-50 192.168.0.11 ap CONNECTED office_Access_point EAP773(US) v1.0
#B0-95-75-46-0C-39 192.168.0.4 switch CONNECTED pantry12 T1600G-52PS v4.0
dMAC, dIP, dTYPE, dSTATUS, dNAME, dMODEL = range(6)
# sample omada clients input format:
# 0 MAC, 1 IP, 2 Name, 3 switch/AP, 4 port/SSID,
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-6F', '192.168.0.217', '1A-2B-3C-4D-5E-6F', 'myssid_name2', '(office_Access_point)']"
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-01', '192.168.0.153', 'frontyard_ESP_29E753', 'pantry12', '(48)']"
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-02', '192.168.0.1', 'bastion', 'office24', '(23)']"
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-03', '192.168.0.226', 'brick', 'myssid_name3', '(office_Access_point)']"
cMAC, cIP, cNAME, cSWITCH_AP, cPORT_SSID = range(5)
OMDLOGLEVEL = 'debug'
pluginName = 'OMDSDN'
#
# translate MAC address from standard ieee model to ietf draft
# AA-BB-CC-DD-EE-FF to aa:bb:cc:dd:ee:ff
# tplink adheres to ieee, Nax adheres to ietf
def ieee2ietf_mac_formater(inputmac):
return(inputmac.lower().replace('-',':'))
def ietf2ieee_mac_formater(inputmac):
return(inputmac.upper().replace(':','-'))
def get_mac_from_IP(target_IP):
from scapy.all import ARP, Ether, srp
try:
arp_request = ARP(pdst=target_IP)
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
packet = ether/arp_request
result = srp(packet, timeout=3, verbose=0)[0]
if result:
return result[0][1].hwsrc
else:
return None
except Exception as e:
mylog('minimal', [f'[{pluginName}] get_mac_from_IP ERROR:{e}'])
return None
#
# wrapper to call the omada python library's own wrapper
# it returns the output as a multiline python string
#
def callomada(myargs):
arguments=" ".join(myargs)
mylog('verbose', [f'[{pluginName}] callomada:{arguments}'])
from tplink_omada_client.cli import main as omada
from contextlib import redirect_stdout
omada_output = ''
retries = 2
while omada_output == '' and retries > 1:
retries = retries - 1
try:
mf = io.StringIO()
with redirect_stdout(mf):
bar = omada(myargs)
omada_output = mf.getvalue()
except Exception as e:
mylog('minimal', [f'[{pluginName}] ERROR WHILE CALLING callomada:{arguments}\n {mf}'])
omada_output= ''
return(omada_output)
#
# extract all the mac addresses from a multilines text...
# return a list of MAC as 'string'
#
def extract_mac_addresses(text):
mac_pattern = r"([0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2})"
mac_addresses = re.findall(mac_pattern, text)
return ["".join(parts) for parts in mac_addresses]
def find_default_gateway_ip ():
#import netifaces
#gw = netifaces.gateways()
#return(gw['default'][netifaces.AF_INET][0])
from scapy.all import conf, Route, sr1, IP, ICMP
default_route = conf.route.route("0.0.0.0")
return default_route[2] if default_route[2] else None
#return('192.168.0.1')
def add_uplink (uplink_mac, switch_mac, device_data_bymac, sadevices_linksbymac,port_byswitchmac_byclientmac):
#mylog(OMDLOGLEVEL, [f'[{pluginName}] trying to add uplink="{uplink_mac}" to switch="{switch_mac}"'])
#mylog(OMDLOGLEVEL, [f'[{pluginName}] before adding:"{device_data_bymac[switch_mac]}"'])
if device_data_bymac[switch_mac][SWITCH_AP] == 'null':
device_data_bymac[switch_mac][SWITCH_AP] = uplink_mac
if device_data_bymac[switch_mac][TYPE] == 'Switch' and device_data_bymac[uplink_mac][TYPE] == 'Switch':
port_to_uplink = port_byswitchmac_byclientmac[switch_mac][uplink_mac]
#find_port_of_uplink_switch(switch_mac, uplink_mac)
else:
port_to_uplink=device_data_bymac[uplink_mac][PORT_SSID]
device_data_bymac[switch_mac][PORT_SSID] = port_to_uplink
# mylog(OMDLOGLEVEL, [f'[{pluginName}] after adding:"{device_data_bymac[switch_mac]}"'])
for link in sadevices_linksbymac[switch_mac]:
if device_data_bymac[link][SWITCH_AP] == 'null' and device_data_bymac[switch_mac][TYPE] == 'Switch':
add_uplink(switch_mac, link, device_data_bymac, sadevices_linksbymac,port_byswitchmac_byclientmac)
pluginName = '<unique_prefix>'
# ----------------------------------------------
# Main initialization
def main():
mylog('verbose', [f'[{pluginName}] In script'])
start_time = time.time()
mylog('verbose', [f'[{pluginName}] starting execution'])
from database import DB
from device import Device_obj
db = DB() # instance of class DB
db.open()
# Create a Device_obj instance
device_handler = Device_obj(db)
# Retrieve configuration settings
some_setting = get_setting_value('OMDSDN_url')
# these should be self-explanatory
omada_sites = []
omada_username = get_setting_value('OMDSDN_username')
omada_password = get_setting_value('OMDSDN_password')
omada_sites = get_setting_value('OMDSDN_sites')
omada_site = omada_sites[0]
omada_url = get_setting_value('OMDSDN_url')
omada_login = callomada(['-t','myomada','target','--url',omada_url,'--user',omada_username,
'--password',omada_password,'--site',omada_site,'--set-default'])
mylog('verbose', [f'[{pluginName}] login to omada result is: {omada_login}'])
clients_list = callomada(['-t','myomada','clients'])
mylog('verbose', [f'[{pluginName}] clients found:"{clients_list.count("\n")}"\n{clients_list}'])
switches_and_aps = callomada(['-t','myomada','devices'])
mylog('verbose', [f'[{pluginName}] omada devices (switches, access points) found:"{switches_and_aps.count("\n")}" \n {switches_and_aps}'])
#some_setting = get_setting_value('OMDSDN_url')
#mylog(OMDLOGLEVEL, [f'[{pluginName}] some_setting value {some_setting}'])
mylog(OMDLOGLEVEL, [f'[{pluginName}] ffsb'])
mylog('verbose', [f'[{pluginName}] some_setting calue {some_setting}'])
# retrieve data
device_data = get_device_data(some_setting)
device_data = get_device_data(clients_list, switches_and_aps, device_handler)
# Process the data into native application tables
mylog('verbose', [f'[{pluginName}] New entries to create: "{len(device_data)}"'])
if len(device_data) > 0:
# insert devices into the lats_result.log
@@ -50,36 +213,238 @@ def main():
# {
# "column": "Object_PrimaryID", <--------- the value I save into primaryId
# "mapped_to_column": "cur_MAC", <--------- gets unserted into the CurrentScan DB table column cur_MAC
#
for device in device_data:
plugin_objects.add_object(
primaryId = device['some_id'], # MAC
secondaryId = device['some_id'], # IP
watched1 = device['some_id'], # NAME/HOSTNAME
watched2 = device['some_id'], # PARENT NETWORK NODE MAC
watched3 = device['some_id'], # PORT
watched4 = device['some_id'], # SSID
extra = device['some_id'], # SITENAME (cur_NetworkSite) or VENDOR (cur_Vendor) (PICK one and adjust config.json -> "column": "Extra")
foreignKey = device['some_id']) # usually MAC
# watched1 = 'null' ,
# figure a way to run my udpate script delayed
mylog('verbose', [f'[{pluginName}] New entries: "{len(new_devices)}"'])
for device in device_data:
mylog(OMDLOGLEVEL, [f'[{pluginName}] main parsing device: "{device}"'])
myport = device[PORT_SSID] if device[PORT_SSID].isdigit() else ''
myssid = device[PORT_SSID] if not device[PORT_SSID].isdigit() else ''
ParentNetworkNode = ieee2ietf_mac_formater(device[SWITCH_AP]) if device[SWITCH_AP] != 'Internet' else 'Internet'
mymac = ieee2ietf_mac_formater(device[MAC])
plugin_objects.add_object(
primaryId = mymac, # MAC
secondaryId = device[IP], # IP
watched1 = device[NAME], # NAME/HOSTNAME
watched2 = ParentNetworkNode, # PARENT NETWORK NODE MAC
watched3 = myport, # PORT
watched4 = myssid, # SSID
extra = device[TYPE],
#omada_site, # SITENAME (cur_NetworkSite) or VENDOR (cur_Vendor) (PICK one and adjust config.json -> "column": "Extra")
foreignKey = device[MAC].lower().replace('-',':')) # usually MAC
mylog('verbose', [f'[{pluginName}] New entries: "{mymac:<18}, {device[IP]:<16}, {device[NAME]:<63}, {ParentNetworkNode:<18}, {myport:<4}, {myssid:<32}, {device[TYPE]}"'])
mylog('verbose', [f'[{pluginName}] New entries: "{len(device_data)}"'])
# log result
plugin_objects.write_result_file()
#mylog(OMDLOGLEVEL, [f'[{pluginName}] TEST name from MAC: {device_handler.getValueWithMac('dev_Name','00:e2:59:00:a0:8e')}'])
#mylog(OMDLOGLEVEL, [f'[{pluginName}] TEST MAC from IP: {get_mac_from_IP('192.168.0.1')} also {ietf2ieee_mac_formater(get_mac_from_IP('192.168.0.1'))}'])
end_time = time.time()
mylog('verbose', [f'[{pluginName}] execution completed in {end_time - start_time:.2f} seconds'])
return 0
def get_omada_devices_details(msadevice_data):
mthisswitch = msadevice_data[dMAC]
mtype = msadevice_data[dTYPE]
mswitch_detail = ''
mswitch_dump = ''
if mtype == 'ap':
mswitch_detail = callomada(['access-point', mthisswitch])
elif mtype == 'switch':
mswitch_detail = callomada(['switch', mthisswitch])
mswitch_dump = callomada(['-t','myomada','switch','-d',mthisswitch])
else:
mswitch_detail = ''
nswitch_dump = ''
return mswitch_detail, mswitch_dump
# ----------------------------------------------
# retrieve data
def get_device_data(some_setting):
def get_device_data(omada_clients_output,switches_and_aps,device_handler):
device_data = []
# sample omada devices input format:
# 0.MAC 1.IP 2.type 3.status 4.name 5.model
#40-AE-30-A5-A7-50 192.168.0.11 ap CONNECTED office_Access_point EAP773(US) v1.0
#B0-95-75-46-0C-39 192.168.0.4 switch CONNECTED pantry12 T1600G-52PS v4.0
#
# sample target output:
# 0 MAC, 1 IP, 2 Name, 3 switch/AP, 4 port/SSID, 5 TYPE
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-6F', '192.168.0.217', '1A-2B-3C-4D-5E-6F', '17', '40-AE-30-A5-A7-50, 'Switch']"
#constants
sadevices_macbyname = {}
sadevices_macbymac = {}
sadevices_linksbymac = {}
port_byswitchmac_byclientmac = {}
device_data_bymac = {}
device_data_mac_byip = {}
omada_force_overwrite = get_setting_value('OMDSDN_force_overwrite')
switch_details = {}
switch_dumps = {}
sadevices = switches_and_aps.splitlines()
mylog(OMDLOGLEVEL, [f'[{pluginName}] switches_and_aps rows: "{len(sadevices)}"'])
for sadevice in sadevices:
sadevice_data = sadevice.split()
thisswitch = sadevice_data[dMAC]
thistype = sadevice_data[dTYPE]
switch_details[thisswitch], switch_dumps[thisswitch] = get_omada_devices_details(sadevice_data)
mylog('verbose', [f'[{pluginName}] switches details collected "{len(switch_details)}"'])
mylog('verbose', [f'[{pluginName}] dump details collected "{len(switch_details)}"'])
# Using ThreadPoolExecutor for parallel execution
for sadevice in sadevices:
sadevice_data = sadevice.split()
thisswitch = sadevice_data[dMAC]
sadevices_macbyname[sadevice_data[4]] = thisswitch
if sadevice_data[dTYPE] == 'ap':
sadevice_type = 'AP'
#sadevice_details = callomada(['access-point', thisswitch])
sadevice_details = switch_details[thisswitch]
if sadevice_details == '':
sadevice_links = [thisswitch]
else:
sadevice_links = extract_mac_addresses(sadevice_details)
sadevices_linksbymac[thisswitch] = sadevice_links[1:]
#mylog(OMDLOGLEVEL, [f'[{pluginName}]adding switch details: "{sadevice_details}"'])
#mylog(OMDLOGLEVEL, [f'[{pluginName}]links are: "{sadevice_links}"'])
#mylog(OMDLOGLEVEL, [f'[{pluginName}]linksbymac are: "{sadevices_linksbymac[thisswitch]}"'])
elif sadevice_data[dTYPE] == 'switch':
sadevice_type = 'Switch'
#sadevice_details=callomada(['switch', thisswitch])
sadevice_details = switch_details[thisswitch]
if sadevice_details == '':
sadevice_links = [thisswitch]
else:
sadevice_links=extract_mac_addresses(sadevice_details)
sadevices_linksbymac[thisswitch] = sadevice_links[1:]
# recovering the list of switches connected to sadevice switch and on which port...
#switchdump = callomada(['-t','myomada','switch','-d',thisswitch])
switchdump = switch_dumps[thisswitch]
mylog(OMDLOGLEVEL, [f'[{pluginName}] switchdump: {switchdump}'])
port_byswitchmac_byclientmac[thisswitch] = {}
for link in sadevices_linksbymac[thisswitch]:
port_pattern = r"(?:{[^}]*\"port\"\: )([0-9]+)(?=[^}]*"+re.escape(link)+r")"
myport = re.findall(port_pattern, switchdump,re.DOTALL)
#mylog(OMDLOGLEVEL, [f'[{pluginName}] switchdump: link={link} myport:{myport}'])
port_byswitchmac_byclientmac[thisswitch][link] = myport[0] if myport else ''
#mylog(OMDLOGLEVEL, [f'[{pluginName}]links are: "{sadevice_links}"'])
#mylog(OMDLOGLEVEL, [f'[{pluginName}]linksbymac are: "{sadevices_linksbymac[thisswitch]}"'])
#mylog(OMDLOGLEVEL, [f'[{pluginName}]ports of each links are: "{port_byswitchmac_byclientmac[thisswitch]}"'])
#mylog(OMDLOGLEVEL, [f'[{pluginName}]adding switch details: "{sadevice_details}"'])
else:
sadevice_type = 'null'
sadevice_details='null'
device_data_bymac[thisswitch] = [thisswitch, sadevice_data[dIP], sadevice_data[dNAME], 'null', 'null',sadevice_type]
device_data_mac_byip[sadevice_data[dIP]] = thisswitch
foo=[thisswitch, sadevice_data[1], sadevice_data[4], 'null', 'null']
mylog(OMDLOGLEVEL, [f'[{pluginName}]adding switch: "{foo}"'])
# sadevices_macbymac[thisswitch] = thisswitch
mylog(OMDLOGLEVEL, [f'[{pluginName}] switch_macbyname: "{sadevices_macbyname}"'])
mylog(OMDLOGLEVEL, [f'[{pluginName}] switches: "{device_data_bymac}"'])
# do some processing, call exteranl APIs, and return a device list
# ...
#
# sample omada clients input format:
# 0 MAC, 1 IP, 2 Name, 3 switch/AP, 4 port/SSID,
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-6F', '192.168.0.217', '1A-2B-3C-4D-5E-6F', 'myssid_name2', '(office_Access_point)']"
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-01', '192.168.0.153', 'frontyard_ESP_29E753', 'pantry12', '(48)']"
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-02', '192.168.0.1', 'bastion', 'office24', '(23)']"
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-03', '192.168.0.226', 'brick', 'myssid_name3', '(office_Access_point)']"
# sample target output:
# 0 MAC, 1 IP, 2 Name, 3 MAC of switch/AP, 4 port/SSID, 5 TYPE
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-6F', '192.168.0.217', 'brick', 'office_Access_point','myssid_name2', , 'Switch']"
return device_data
odevices = omada_clients_output.splitlines()
mylog(OMDLOGLEVEL, [f'[{pluginName}] omada_clients_outputs rows: "{len(odevices)}"'])
for odevice in odevices:
odevice_data = odevice.split()
odevice_data_reordered = [ MAC, IP, NAME, SWITCH_AP, PORT_SSID, TYPE]
odevice_data_reordered[MAC]=odevice_data[cMAC]
odevice_data_reordered[IP]=odevice_data[cIP]
real_naxname = device_handler.getValueWithMac('dev_Name',ieee2ietf_mac_formater(odevice_data[cMAC]))
#
# if the name stored in Nax for a device is empty or the MAC addres or has some parenthhesis or is the same as in omada
# don't bother updating omada's name at all.
#
naxname = real_naxname
if real_naxname != None:
if '(' in real_naxname:
# removing parenthesis and domains from the name
naxname = real_naxname.split('(')[0]
if naxname != None and '.' in naxname:
naxname = naxname.split('.')[0]
if naxname in ( None, 'null', '' ):
naxname = odevice_data[cNAME] if odevice_data[cNAME] != '' else odevice_data[cMAC]
naxname = naxname.strip()
mylog('debug', [f'[{pluginName}] TEST name from MAC: {naxname}'])
if odevice_data[cNAME] in (odevice_data[cMAC], 'null', ''):
mylog('verbose', [f'[{pluginName}] updating omada server because odevice_data is: {odevice_data[cNAME]} and naxname is: "{naxname}"'])
callomada(['set-client-name', odevice_data[cMAC], naxname])
odevice_data_reordered[NAME] = naxname
else:
if omada_force_overwrite and naxname != odevice_data[cNAME] :
mylog('verbose', [f'[{pluginName}] updating omada server because odevice_data is: "{odevice_data[cNAME]} and naxname is: "{naxname}"'])
callomada(['set-client-name', odevice_data[cMAC], naxname])
odevice_data_reordered[NAME] = naxname
mightbeport = odevice_data[cPORT_SSID].lstrip('(')
mightbeport = mightbeport.rstrip(')')
if mightbeport.isdigit():
odevice_data_reordered[SWITCH_AP] = odevice_data[cSWITCH_AP]
odevice_data_reordered[PORT_SSID] = mightbeport
else:
odevice_data_reordered[SWITCH_AP] = mightbeport
odevice_data_reordered[PORT_SSID] = odevice_data[cSWITCH_AP]
# replacing the switch name with its MAC...
try:
mightbemac = sadevices_macbyname[odevice_data_reordered[SWITCH_AP]]
odevice_data_reordered[SWITCH_AP] = mightbemac
except KeyError:
mylog(OMDLOGLEVEL, [f'[{pluginName}] could not find the mac adddress for: "{odevice_data_reordered[SWITCH_AP]}"'])
# adding the type
odevice_data_reordered[TYPE] = 'null'
device_data_bymac[odevice_data_reordered[MAC]] = odevice_data_reordered
device_data_mac_byip[odevice_data_reordered[IP]] = odevice_data_reordered[MAC]
mylog(OMDLOGLEVEL, [f'[{pluginName}] tokens: "{odevice_data}"'])
mylog(OMDLOGLEVEL, [f'[{pluginName}] tokens_reordered: "{odevice_data_reordered}"'])
# populating the uplinks nodes of the omada switches and access points manually
# since OMADA SDN makes is unreliable if the gateway is not their own tplink hardware...
# step1 let's find the the default router
#
default_router_ip = find_default_gateway_ip()
default_router_mac = ietf2ieee_mac_formater(get_mac_from_IP(default_router_ip))
device_data_bymac[default_router_mac][TYPE] = 'Firewall'
# step2 let's find the first switch and set the default router parent to internet
first_switch=device_data_bymac[default_router_mac][SWITCH_AP]
device_data_bymac[default_router_mac][SWITCH_AP] = 'Internet'
# step3 let's set the switch connected to the default gateway uplink to the default gateway and hardcode port to 1 for now:
#device_data_bymac[first_switch][SWITCH_AP]=default_router_mac
#device_data_bymac[first_switch][SWITCH_AP][PORT_SSID] = '1'
# step4, let's go recursively through switches other links to mark update their uplinks
# and pray it ends one day...
#
add_uplink(default_router_mac,first_switch, device_data_bymac,sadevices_linksbymac,port_byswitchmac_byclientmac)
return device_data_bymac.values()
if __name__ == '__main__':
main()

View File

@@ -62,8 +62,13 @@
"settings": [
{
"function": "RUN",
"type": "text.select",
"default_value": "on_new_device",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
"disabled",
"once",
@@ -96,7 +101,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/pholus_scan/script.py userSubnets={subnets} timeoutSec={timeout}",
"options": [],
"localized": ["name", "description"],
@@ -123,7 +137,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 300,
"options": [],
"localized": ["name", "description"],
@@ -150,7 +173,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "30 3 * * *",
"options": [],
"localized": ["name", "description"],
@@ -177,7 +205,16 @@
},
{
"function": "DAYS_DATA",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 30,
"options": [],
"localized": ["name", "description"],
@@ -204,7 +241,16 @@
},
{
"function": "WATCH",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["Watched_Value1", "Watched_Value2"],
"options": [
"Watched_Value1",
@@ -236,7 +282,16 @@
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["new"],
"options": [
"new",

View File

@@ -2,6 +2,7 @@
"code_name": "pihole_scan",
"unique_prefix": "PIHOLE",
"plugin_type": "device_scanner",
"execution_order" : "Layer_2",
"enabled": true,
"data_source": "sqlite-db-query",
"mapped_to_table": "CurrentScan",
@@ -60,7 +61,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
"disabled",
@@ -93,7 +99,12 @@
},
{
"function": "CMD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "SELECT n.hwaddr AS Object_PrimaryID, {s-quote}null{s-quote} AS Object_SecondaryID, datetime() AS DateTime, na.ip AS Watched_Value1, n.lastQuery AS Watched_Value2, na.name AS Watched_Value3, n.macVendor AS Watched_Value4, {s-quote}null{s-quote} AS Extra, n.hwaddr AS ForeignKey FROM EXTERNAL_PIHOLE.Network AS n LEFT JOIN EXTERNAL_PIHOLE.Network_Addresses AS na ON na.network_id = n.id WHERE n.hwaddr NOT LIKE {s-quote}ip-%{s-quote} AND n.hwaddr is not {s-quote}00:00:00:00:00:00{s-quote} AND na.ip is not null",
"options": [],
"localized": ["name", "description"],
@@ -120,7 +131,12 @@
},
{
"function": "DB_PATH",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "/etc/pihole/pihole-FTL.db",
"options": [],
"localized": ["name", "description"],
@@ -147,7 +163,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "*/30 * * * *",
"options": [],
"localized": ["name", "description"],
@@ -164,17 +185,26 @@
"description": [
{
"language_code": "en_us",
"string": "Only enabled if you select <code>schedule</code> in the <a href=\"#ARPSCAN_RUN\"><code>ARPSCAN_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>*/30 * * * *</code> will run the scan every 30 minutes. Will be run NEXT time the time passes. <br/> It's recommended to use the same schedule interval for all plugins responsible for discovering new devices."
"string": "Only enabled if you select <code>schedule</code> in the <a href=\"#PIHOLE_RUN\"><code>PIHOLE_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>*/30 * * * *</code> will run the scan every 30 minutes. Will be run NEXT time the time passes. <br/> It's recommended to use the same schedule interval for all plugins responsible for discovering new devices."
},
{
"language_code": "es_es",
"string": "Solo está habilitado si selecciona <code>schedule</code> en la configuración <a href=\"#ARPSCAN_RUN\"><code>ARPSCAN_RUN</code></a>. Asegúrese de ingresar la programación en el formato similar a cron correcto (por ejemplo, valide en <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Por ejemplo, ingresar <code>*/30 * * * *</code> ejecutará el escaneo cada 30 minutos. Se ejecutará la PRÓXIMA vez que pase el tiempo. <br/> Se recomienda utilizar el mismo intervalo de programación para todos los complementos que analizan su red."
"string": "Solo está habilitado si selecciona <code>schedule</code> en la configuración <a href=\"#PIHOLE_RUN\"><code>PIHOLE_RUN</code></a>. Asegúrese de ingresar la programación en el formato similar a cron correcto (por ejemplo, valide en <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Por ejemplo, ingresar <code>*/30 * * * *</code> ejecutará el escaneo cada 30 minutos. Se ejecutará la PRÓXIMA vez que pase el tiempo. <br/> Se recomienda utilizar el mismo intervalo de programación para todos los complementos que analizan su red."
}
]
},
{
"function": "WATCH",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["Watched_Value1", "Watched_Value2"],
"options": [
"Watched_Value1",
@@ -206,7 +236,16 @@
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["new"],
"options": [
"new",

View File

@@ -79,6 +79,22 @@ def decodeBase64(inputParamBase64):
return result
# -------------------------------------------------------------------
def normalize_mac(mac):
# Split the MAC address by colon (:) or hyphen (-) and convert each part to uppercase
parts = mac.upper().split(':')
# If the MAC address is split by hyphen instead of colon
if len(parts) == 1:
parts = mac.upper().split('-')
# Normalize each part to have exactly two hexadecimal digits
normalized_parts = [part.zfill(2) for part in parts]
# Join the parts with colon (:)
normalized_mac = ':'.join(normalized_parts)
return normalized_mac
# -------------------------------------------------------------------
class Plugin_Object:

View File

@@ -47,7 +47,16 @@
"settings": [
{
"function": "enable_password",
"type": "boolean",
"type": {
"dataType": "boolean",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": false,
"options": [],
"localized": ["name", "description"],
@@ -66,7 +75,16 @@
},
{
"function": "password",
"type": "password.SHA256",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "password" }],
"transformers": ["sha256"]
}
]
},
"maxLength": 50,
"default_value": "123456",
"options": [],

View File

@@ -1,17 +1,19 @@
## Overview
A plugin for importing devices from an SNMP enabled router or switch. Using SNMP offers an efficient way to discover IPv4 devices across one or more networks/subnets/vlans.
A plugin for importing devices from an SNMP-enabled router or switch. Using SNMP offers an efficient way to discover IPv4 devices across one or more networks/subnets/vlans.
### Usage
Specify the following settings in the Settings section of NetAlertX:
- `SNMPDSC_routers` - A list of `snmpwalk` commands to execute against IP addresses of roputers/switches with SNMP turned on. For example:
- `SNMPDSC_routers` - A list of `snmpwalk` commands to execute against IP addresses of routers/switches with SNMP turned on. For example:
- `snmpwalk -v 2c -c public -OXsq 192.168.1.1 .1.3.6.1.2.1.3.1.1.2`
- `snmpwalk -v 2c -c public -Oxsq 192.168.1.1 .1.3.6.1.2.1.3.1.1.2` (note: lower case `x`)
If unsure, please check [snmpwalk examples](https://www.comparitech.com/net-admin/snmpwalk-examples-windows-linux/).
### Setup Cisco IOS
Enable IOS SNMP service and restrict to selected (internal) IP/Subnet.
@@ -35,5 +37,24 @@ show snmp
### Notes
- Only IPv4 supported.
- The SNMP OID `.1.1.1.3.6.1.2.1.3.1.1.2` is specifically for devices IPv4 ARP table. This OID has been tested on Cisco ISRs and other L3 devices. Support may vary between other vendors / devices.
- Expected output (ingestion) in format `iso.3.6.1.2.1.3.1.1.2.3.1.192.168.1.2 "6C 6C 6C 6C 6C 6C "`.
- The SNMP OID `.1.1.1.3.6.1.2.1.3.1.1.2` is specifically for devices IPv4 ARP table. This OID has been tested on Cisco ISRs and other L3 devices. Support may vary between other vendors/devices.
- Expected output (ingestion) in formats:
- `iso.3.6.1.2.1.3.1.1.2.3.1.192.168.1.2 "6C 6C 6C 6C 6C 6C "`.
- `ipNetToMediaPhysAddress[3][192.168.1.9] 6C:6C:6C:6C:6C:b6C1`.
### Finding your OID
- Ssh into the router (in this example the IP of the router is `192.168.1.1`)
- On the router execute `snmptranslate -On -IR ipNetToMediaPhysAddress` (This is a UniFi router example, and the `object_id` is `ipNetToMediaPhysAddress`. This might vary between vendors, google your router manufacturer examples.)
```bash
jokob@SecurityGateway-USG:~$ snmptranslate -On -IR ipNetToMediaPhysAddress
.1.3.6.1.2.1.4.22.1.2
```
- Use the `snmpwalk -v 2c -OXsq -c public 192.168.1.1 .1.3.6.1.2.1.4.22.1.2` command in NetAlertX

View File

@@ -2,6 +2,7 @@
"code_name": "snmp_discovery",
"unique_prefix": "SNMPDSC",
"plugin_type": "device_scanner",
"execution_order" : "Layer_1",
"enabled": true,
"data_source": "script",
"data_filters": [
@@ -339,7 +340,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
"disabled",
@@ -372,7 +378,12 @@
},
{
"function": "CMD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "python3 /app/front/plugins/snmp_discovery/script.py routers={s-quote}{routers}{s-quote}",
"options": [],
"localized": ["name", "description"],
@@ -399,7 +410,63 @@
},
{
"function": "routers",
"type": "list",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "input",
"elementOptions": [
{ "placeholder": "Enter value" },
{ "suffix": "_in" },
{ "cssClasses": "col-sm-10" },
{ "prefillValue": "null" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": ["_in"] },
{ "separator": "" },
{ "cssClasses": "col-xs-12" },
{ "onClick": "addList(this, false)" },
{ "getStringKey": "Gen_Add" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeAllOptions(this)" },
{ "getStringKey": "Gen_Remove_All" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeFromList(this)" },
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
},
{
"elementType": "select",
"elementOptions": [
{ "multiple": "true" },
{ "readonly": "true" },
{ "editable": "true" }
],
"transformers": []
}
]
},
"default_value": [
"snmpwalk -v 2c -c public -OXsq 192.168.1.1 .1.3.6.1.2.1.3.1.1.2"
],
@@ -428,7 +495,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "0 2 * * *",
"options": [],
"localized": ["name", "description"],
@@ -455,7 +527,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 5,
"options": [],
"localized": ["name", "description"],
@@ -486,7 +567,16 @@
},
{
"function": "WATCH",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["Watched_Value1"],
"options": [
"Watched_Value1",
@@ -518,7 +608,16 @@
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["new", "watched-changed"],
"options": [
"new",

View File

@@ -11,7 +11,7 @@ import sys
INSTALL_PATH="/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64, handleEmpty
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64, handleEmpty, normalize_mac
from logger import mylog
from helper import timeNowTZ
from const import logPath, applicationPath
@@ -25,7 +25,7 @@ def main():
mylog('verbose', ['[SNMPDSC] In script '])
# init global variables
global ROUTERS
global snmpWalkCmds
parser = argparse.ArgumentParser(description='This plugin is used to discover devices via the arp table(s) of a RFC1213 compliant router or switch.')
@@ -35,18 +35,20 @@ def main():
plugin_objects = Plugin_Objects(RESULT_FILE)
if values.routers:
ROUTERS = values.routers.split('=')[1].replace('\'','')
snmpWalkCmds = values.routers.split('=')[1].replace('\'','')
if ',' in ROUTERS:
routers = ROUTERS.split(',')
if ',' in snmpWalkCmds:
commands = snmpWalkCmds.split(',')
else:
routers = [ROUTERS]
commands = [snmpWalkCmds]
for router in routers:
mylog('verbose', ['[SNMPDSC] Router snmpwalk command: ', router])
for cmd in commands:
mylog('verbose', ['[SNMPDSC] Router snmpwalk command: ', cmd])
timeoutSec = 10
snmpwalkArgs = router.split(' ')
# split the string, remove white spaces around each item, and exclude any empty strings
snmpwalkArgs = [arg.strip() for arg in cmd.split(' ') if arg.strip()]
# Execute N probes and insert in list
probes = 1 # N probes
@@ -60,11 +62,9 @@ def main():
for line in lines:
tmpSplt = line.split('"')
tmpSplt = line.split('"')
if len(tmpSplt) == 3:
ipStr = tmpSplt[0].split('.')[-4:] # Get the last 4 elements to extract the IP
macStr = tmpSplt[1].strip().split(' ') # Remove leading/trailing spaces from MAC
@@ -86,6 +86,26 @@ def main():
else:
mylog('verbose', [f'[SNMPDSC] ipStr does not seem to contain a valid IP:', ipStr])
elif line.startswith('ipNetToMediaPhysAddress'):
# Format: snmpwalk -OXsq output
parts = line.split()
if len(parts) == 2:
ipAddress = parts[0].split('[')[-1][:-1]
macAddress = normalize_mac(parts[1])
mylog('verbose', [f'[SNMPDSC] IP: {ipAddress} MAC: {macAddress}'])
plugin_objects.add_object(
primaryId = handleEmpty(macAddress),
secondaryId = handleEmpty(ipAddress.strip()),
watched1 = '(unknown)',
watched2 = handleEmpty(snmpwalkArgs[6]),
extra = handleEmpty(line),
foreignKey = handleEmpty(macAddress)
)
mylog('verbose', ['[SNMPDSC] Entries found: ', len(plugin_objects)])
plugin_objects.write_result_file()

View File

@@ -39,7 +39,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
@@ -74,7 +79,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "*/5 * * * *",
"options": [],
@@ -102,7 +112,12 @@
},
{
"function": "api_token",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 50,
"default_value": "",
"options": [],
@@ -122,7 +137,12 @@
},
{
"function": "encryption_key",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 50,
"default_value": "",
"options": [],
@@ -142,7 +162,12 @@
},
{
"function": "hub_url",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 50,
"default_value": "",
@@ -163,7 +188,12 @@
},
{
"function": "node_name",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 50,
"default_value": "",
"options": [],
@@ -183,7 +213,16 @@
},
{
"function": "devices",
"type": "boolean",
"type": {
"dataType": "boolean",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": false,
"options": [],
"localized": ["name", "description"],
@@ -202,7 +241,16 @@
},
{
"function": "plugins",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": [],
"options": ["{value}"],
@@ -229,7 +277,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/sync/sync.py",
"options": [],
"localized": ["name", "description"],
@@ -264,7 +321,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 30,
"options": [],
"localized": ["name", "description"],
@@ -376,14 +442,6 @@
{
"language_code": "en_us",
"string": "Vendor"
},
{
"language_code": "es_es",
"string": "Proveedor"
},
{
"language_code": "de_de",
"string": "Hersteller"
}
]
},

View File

@@ -28,7 +28,16 @@
"settings": [
{
"function": "shown_cards",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": [
"my_devices",
@@ -64,7 +73,16 @@
},
{
"function": "hide_empty",
"type": "boolean",
"type": {
"dataType": "boolean",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": false,
"options": [],
"localized": ["name", "description"],

View File

@@ -25,3 +25,6 @@ Allowing Un-Discoverable devices like hubs, switches or APs to be added to the n
### Known Limitations
- Un-Discoverable Devices always show as offline. That is expected as they can not be discovered by NetAlertX.
- All IPs are set to 0.0.0.0 therefore the "Random MAC" icon might show up.
Made with ❤ by [@Data-Monkey](https://github.com/Data-Monkey) 🙏

View File

@@ -60,7 +60,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": ["disabled", "once", "schedule", "always_after_scan"],
"localized": ["name", "description"],
@@ -95,7 +100,12 @@
},
{
"function": "CMD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "python3 /app/front/plugins/undiscoverables/script.py devices={devices}",
"options": [],
"localized": ["name", "description"],
@@ -130,7 +140,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 10,
"options": [],
"localized": ["name", "description"],
@@ -165,7 +184,16 @@
},
{
"function": "WATCH",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": [],
"options": [],
"localized": ["name", "description"],
@@ -200,7 +228,16 @@
},
{
"function": "REPORT_ON",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": [],
"options": [
"new",
@@ -240,7 +277,63 @@
},
{
"function": "devices_to_import",
"type": "list",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "input",
"elementOptions": [
{ "placeholder": "Enter value" },
{ "suffix": "_in" },
{ "cssClasses": "col-sm-10" },
{ "prefillValue": "null" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": ["_in"] },
{ "separator": "" },
{ "cssClasses": "col-xs-12" },
{ "onClick": "addList(this, false)" },
{ "getStringKey": "Gen_Add" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeAllOptions(this)" },
{ "getStringKey": "Gen_Remove_All" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeFromList(this)" },
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
},
{
"elementType": "select",
"elementOptions": [
{ "multiple": "true" },
{ "readonly": "true" },
{ "editable": "true" }
],
"transformers": []
}
]
},
"default_value": ["dummy_router"],
"options": [],
"localized": ["name", "description"],
@@ -275,7 +368,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "*/5 * * * *",
"options": [],
"localized": ["name", "description"],

View File

@@ -3,6 +3,7 @@
"show_ui": true,
"unique_prefix": "UNFIMP",
"plugin_type": "device_scanner",
"execution_order" : "Layer_1",
"data_source": "script",
"localized": ["display_name", "description", "icon"],
"display_name": [
@@ -483,7 +484,12 @@
"always_after_scan",
"on_new_device"
],
"type": "text.select"
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
}
},
{
"default_value": "python3 /app/front/plugins/unifi_import/script.py username={username} password={password} host={host} sites={sites} port={port} verifyssl={verifyssl} version={version} fullimport={fullimport}",
@@ -518,7 +524,12 @@
}
],
"options": [],
"type": "text"
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
}
},
{
"default_value": "",
@@ -545,7 +556,12 @@
}
],
"options": [],
"type": "text"
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
}
},
{
"default_value": "",
@@ -572,7 +588,16 @@
}
],
"options": [],
"type": "password"
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "password" }],
"transformers": []
}
]
}
},
{
"default_value": "192.168.1.1",
@@ -599,7 +624,12 @@
}
],
"options": [],
"type": "text"
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
}
},
{
"default_value": "8443",
@@ -626,7 +656,12 @@
}
],
"options": [],
"type": "text"
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
}
},
{
"default_value": "false",
@@ -653,11 +688,21 @@
}
],
"options": ["true", "false"],
"type": "text.select"
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
}
},
{
"function": "version",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "v4",
"options": [],
"localized": ["name", "description"],
@@ -707,7 +752,63 @@
}
],
"options": [],
"type": "list"
"type": {
"dataType": "array",
"elements": [
{
"elementType": "input",
"elementOptions": [
{ "placeholder": "Enter value" },
{ "suffix": "_in" },
{ "cssClasses": "col-sm-10" },
{ "prefillValue": "null" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": ["_in"] },
{ "separator": "" },
{ "cssClasses": "col-xs-12" },
{ "onClick": "addList(this, false)" },
{ "getStringKey": "Gen_Add" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeAllOptions(this)" },
{ "getStringKey": "Gen_Remove_All" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeFromList(this)" },
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
},
{
"elementType": "select",
"elementOptions": [
{ "multiple": "true" },
{ "readonly": "true" },
{ "editable": "true" }
],
"transformers": []
}
]
}
},
{
"default_value": "0 2 * * *",
@@ -734,7 +835,12 @@
}
],
"options": [],
"type": "text"
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
}
},
{
"default_value": 5,
@@ -769,7 +875,16 @@
}
],
"options": [],
"type": "integer"
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
}
},
{
"default_value": ["Watched_Value1", "Watched_Value4"],
@@ -801,7 +916,16 @@
"Watched_Value3",
"Watched_Value4"
],
"type": "text.multiselect"
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
}
},
{
"default_value": ["new", "watched-changed"],
@@ -833,7 +957,16 @@
"watched-not-changed",
"missing-in-last-scan"
],
"type": "text.multiselect"
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
}
},
{
"default_value": "disabled",
@@ -868,7 +1001,12 @@
}
],
"options": ["disabled", "once", "always"],
"type": "text.select"
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
}
}
]
}

View File

@@ -41,7 +41,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "schedule",
"options": ["disabled", "once", "schedule", "always_after_scan"],
"localized": ["name", "description"],
@@ -72,7 +77,16 @@
},
{
"function": "CMD",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/vendor_update/script.py",
"options": [],
"localized": ["name", "description"],
@@ -107,7 +121,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "0 4 * * 3",
"options": [],
"localized": ["name", "description"],
@@ -142,7 +161,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 600,
"options": [],
"localized": ["name", "description"],
@@ -177,7 +205,16 @@
},
{
"function": "WATCH",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["Watched_Value1"],
"options": [
"Watched_Value1",
@@ -213,7 +250,16 @@
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["new", "watched-changed"],
"options": [
"new",

View File

@@ -344,7 +344,12 @@
{
"function": "RUN",
"events": ["run"],
"type": "text.select",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": [
"disabled",
@@ -377,7 +382,12 @@
},
{
"function": "CMD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "python3 /app/front/plugins/website_monitor/script.py urls={urls}",
"options": [],
"localized": ["name", "description"],
@@ -404,7 +414,12 @@
},
{
"function": "RUN_SCHD",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "0 2 * * *",
"options": [],
"localized": ["name", "description"],
@@ -431,7 +446,12 @@
},
{
"function": "API_SQL",
"type": "text",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "SELECT * FROM plugin_website_monitor",
"options": [],
"localized": ["name", "description"],
@@ -458,7 +478,16 @@
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 5,
"options": [],
"localized": ["name", "description"],
@@ -489,7 +518,16 @@
},
{
"function": "WATCH",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["Watched_Value1"],
"options": [
"Watched_Value1",
@@ -521,7 +559,16 @@
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"default_value": ["new", "watched-changed"],
"options": [
"new",
@@ -553,7 +600,63 @@
},
{
"function": "urls_to_check",
"type": "list",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "input",
"elementOptions": [
{ "placeholder": "Enter value" },
{ "suffix": "_in" },
{ "cssClasses": "col-sm-10" },
{ "prefillValue": "null" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": ["_in"] },
{ "separator": "" },
{ "cssClasses": "col-xs-12" },
{ "onClick": "addList(this, false)" },
{ "getStringKey": "Gen_Add" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeAllOptions(this)" },
{ "getStringKey": "Gen_Remove_All" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-6" },
{ "onClick": "removeFromList(this)" },
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
},
{
"elementType": "select",
"elementOptions": [
{ "multiple": "true" },
{ "readonly": "true" },
{ "editable": "true" }
],
"transformers": []
}
]
},
"default_value": ["https://google.com", "https://duck.com"],
"options": [],
"localized": ["name", "description"],
@@ -580,7 +683,16 @@
},
{
"function": "SQL_internet_ip",
"type": "readonly",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet'",
"options": [],
"localized": ["name", "description"],

View File

@@ -30,7 +30,16 @@
"settings": [
{
"function": "AppEvents_hist",
"type": "integer",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 5000,
"options": [],
"localized": ["name", "description"],

Some files were not shown because too many files have changed in this diff Show More