Compare commits
77 Commits
8f8264c6fa
...
v25.1.8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad32e76a55 | ||
|
|
190ffd3237 | ||
|
|
c8280184dc | ||
|
|
076d8bbcc2 | ||
|
|
b21d57c524 | ||
|
|
064e0cb0ff | ||
|
|
ad9d61aa16 | ||
|
|
64ff9710d1 | ||
|
|
0cc87e3cfc | ||
|
|
c40af37ca1 | ||
|
|
07a7ace5fc | ||
|
|
4a82ea87f7 | ||
|
|
db47571424 | ||
|
|
58eaa33f39 | ||
|
|
6e4d34b93a | ||
|
|
b2c445e39d | ||
|
|
90ff2efbfb | ||
|
|
b49f1ab335 | ||
|
|
3da5af1b7c | ||
|
|
90dd8e3198 | ||
|
|
c31966bdd0 | ||
|
|
f2a0018982 | ||
|
|
48ac108ca0 | ||
|
|
19441a4431 | ||
|
|
5541d6c9d2 | ||
|
|
93886cec8a | ||
|
|
8401ecda5e | ||
|
|
09aba51a33 | ||
|
|
06946e4fea | ||
|
|
f96ca3e08b | ||
|
|
4aa18691f4 | ||
|
|
bd198587cd | ||
|
|
e8a4cb1d51 | ||
|
|
75e25867e1 | ||
|
|
7dadb735c2 | ||
|
|
b444f98e2d | ||
|
|
8ca2bff456 | ||
|
|
308285f808 | ||
|
|
1a03b2ccc3 | ||
|
|
f6a6c3684c | ||
|
|
f2bf379597 | ||
|
|
802002a5f0 | ||
|
|
e6d2a1c138 | ||
|
|
729c24029f | ||
|
|
3260a67bf4 | ||
|
|
5621f13c6e | ||
|
|
aae08594bb | ||
|
|
ba83884b9f | ||
|
|
2799d3598b | ||
|
|
1ee746a625 | ||
|
|
e52601e062 | ||
|
|
2dad079979 | ||
|
|
47bdb60c85 | ||
|
|
6b9df66b02 | ||
|
|
b188afab44 | ||
|
|
5fe6ac9816 | ||
|
|
d354acbcb2 | ||
|
|
846e15d518 | ||
|
|
067467da53 | ||
|
|
8ac4112ab9 | ||
|
|
ae32b0dd42 | ||
|
|
4fef6e156b | ||
|
|
161a74dee0 | ||
|
|
fa570b9bc9 | ||
|
|
9cfbc7d140 | ||
|
|
dda440eb53 | ||
|
|
efe161494e | ||
|
|
35f1624804 | ||
|
|
74ec75f105 | ||
|
|
0f474fb884 | ||
|
|
f54ffcbbc3 | ||
|
|
21fd9866fe | ||
|
|
3732416616 | ||
|
|
29396ad6bd | ||
|
|
37ae75ed9a | ||
|
|
7cdcf95300 | ||
|
|
e26f7d42e9 |
@@ -6,9 +6,6 @@
|
|||||||
docker-compose.yml
|
docker-compose.yml
|
||||||
Dockerfile
|
Dockerfile
|
||||||
Dockerfile.debian
|
Dockerfile.debian
|
||||||
dockerfiles/LICENSE
|
|
||||||
dockerfiles/README.md
|
|
||||||
dockerfiles/README_ES.md
|
|
||||||
docs
|
docs
|
||||||
LICENSE.txt
|
LICENSE.txt
|
||||||
README.md
|
README.md
|
||||||
@@ -16,4 +13,3 @@ CONTRIBUTING
|
|||||||
FUNDING.yml
|
FUNDING.yml
|
||||||
config/.gitignore
|
config/.gitignore
|
||||||
db/.gitignore
|
db/.gitignore
|
||||||
|
|
||||||
|
|||||||
9
.gitignore
vendored
@@ -11,6 +11,7 @@ front/log/*
|
|||||||
front/api/*
|
front/api/*
|
||||||
/api/*
|
/api/*
|
||||||
**/plugins/**/*.log
|
**/plugins/**/*.log
|
||||||
|
**/plugins/cloud_services/*
|
||||||
**/%40eaDir/
|
**/%40eaDir/
|
||||||
**/@eaDir/
|
**/@eaDir/
|
||||||
|
|
||||||
@@ -24,10 +25,10 @@ __pycache__/
|
|||||||
**/pialert.db_bak
|
**/pialert.db_bak
|
||||||
.*.swp
|
.*.swp
|
||||||
|
|
||||||
front/img/account/*
|
front/img/cloud_services/*
|
||||||
**/account.php
|
**/cloud_services.php
|
||||||
**/account.js
|
**/cloud_services.js
|
||||||
front/css/account.css
|
front/css/cloud_services.css
|
||||||
|
|
||||||
docker-compose.yml.ffsb42
|
docker-compose.yml.ffsb42
|
||||||
.env.omada.ffsb42
|
.env.omada.ffsb42
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ ENV PATH="/opt/venv/bin:$PATH"
|
|||||||
COPY . ${INSTALL_DIR}/
|
COPY . ${INSTALL_DIR}/
|
||||||
|
|
||||||
|
|
||||||
RUN pip install graphene flask netifaces tplink-omada-client wakeonlan pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros git+https://github.com/foreign-sub/aiofreepybox.git \
|
RUN pip install openwrt-luci-rpc graphene flask netifaces tplink-omada-client wakeonlan pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros git+https://github.com/foreign-sub/aiofreepybox.git \
|
||||||
&& bash -c "find ${INSTALL_DIR} -type d -exec chmod 750 {} \;" \
|
&& 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 -exec chmod 640 {} \;" \
|
||||||
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"
|
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"
|
||||||
@@ -69,7 +69,7 @@ COPY --from=builder --chown=nginx:www-data ${INSTALL_DIR}/ ${INSTALL_DIR}/
|
|||||||
COPY install/crontab /etc/crontabs/root
|
COPY install/crontab /etc/crontabs/root
|
||||||
|
|
||||||
# Start all required services
|
# Start all required services
|
||||||
RUN ${INSTALL_DIR}/dockerfiles/pre-setup.sh
|
RUN ${INSTALL_DIR}/dockerfiles/start.sh
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=2 \
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=2 \
|
||||||
CMD curl -sf -o /dev/null ${LISTEN_ADDR}:${PORT}/php/server/query_json.php?file=app_state.json
|
CMD curl -sf -o /dev/null ${LISTEN_ADDR}:${PORT}/php/server/query_json.php?file=app_state.json
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ RUN phpenmod -v 8.2 sqlite3
|
|||||||
RUN apt-get install -y python3-venv
|
RUN apt-get install -y python3-venv
|
||||||
RUN python3 -m venv myenv
|
RUN python3 -m venv myenv
|
||||||
|
|
||||||
RUN /bin/bash -c "source myenv/bin/activate && update-alternatives --install /usr/bin/python python /usr/bin/python3 10 && pip3 install tplink-omada-client wakeonlan pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros "
|
RUN /bin/bash -c "source myenv/bin/activate && update-alternatives --install /usr/bin/python python /usr/bin/python3 10 && pip3 install openwrt-luci-rpc graphene flask netifaces tplink-omada-client wakeonlan pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros "
|
||||||
|
|
||||||
# Create a buildtimestamp.txt to later check if a new version was released
|
# Create a buildtimestamp.txt to later check if a new version was released
|
||||||
RUN date +%s > ${INSTALL_DIR}/front/buildtimestamp.txt
|
RUN date +%s > ${INSTALL_DIR}/front/buildtimestamp.txt
|
||||||
|
|||||||
27
README.md
@@ -1,4 +1,3 @@
|
|||||||
[](https://github.com/jokob-sk/NetAlertX)
|
|
||||||
[](https://hub.docker.com/r/jokobsk/netalertx)
|
[](https://hub.docker.com/r/jokobsk/netalertx)
|
||||||
[](https://hub.docker.com/r/jokobsk/netalertx)
|
[](https://hub.docker.com/r/jokobsk/netalertx)
|
||||||
[](https://github.com/jokob-sk/NetAlertX/releases)
|
[](https://github.com/jokob-sk/NetAlertX/releases)
|
||||||
@@ -9,23 +8,19 @@
|
|||||||
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).
|
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).
|
||||||
|
|
||||||
|
|
||||||
| 🐳 [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) |
|
| [📑 Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) | [🚀 Releases](https://github.com/jokob-sk/NetAlertX/releases) | [📚 Docs](https://github.com/jokob-sk/NetAlertX/tree/main/docs) | [🔌 Plugins](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md) | [🤖 Ask AI](https://gurubase.io/g/netalertx)
|
||||||
|----------------------|----------------------| ----------------------| ----------------------|
|
|----------------------| ----------------------| ----------------------| ----------------------| ----------------------|
|
||||||
|
|
||||||
|
|
||||||
| ![Main screen][main] | ![device_details 1][device_details] | ![Screen network][network] |
|
|
||||||
|----------------------|----------------------| ----------------------|
|
|
||||||
|
|
||||||
![network_setup][network_setup]
|
|
||||||
|
|
||||||
|
![showcase][showcase]
|
||||||
|
|
||||||
Head to [https://netalertx.com/](https://netalertx.com/) for more gifs and screenshots 📷.
|
Head to [https://netalertx.com/](https://netalertx.com/) for more gifs and screenshots 📷.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>📷 Click for more screenshots</summary>
|
<summary>📷 Click for more screenshots</summary>
|
||||||
|
|
||||||
| ![presence][presence] | ![maintenance][maintenance] | ![settings][settings] |
|
| ![Main screen][main] | ![device_details 1][device_details] | ![Screen network][network] |
|
||||||
|----------------------|----------------------|----------------------|
|
|----------------------|----------------------|----------------------|
|
||||||
|
| ![presence][presence] | ![maintenance][maintenance] | ![settings][settings] |
|
||||||
| ![sync_hub][sync_hub] | ![report1][report1] | ![device_nmap][device_nmap] |
|
| ![sync_hub][sync_hub] | ![report1][report1] | ![device_nmap][device_nmap] |
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
@@ -35,7 +30,7 @@ Head to [https://netalertx.com/](https://netalertx.com/) for more gifs and scree
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
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.
|
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 🔐_.
|
||||||
|
|
||||||
@@ -88,9 +83,7 @@ Get notified about a new release, what new functionality you can use and about b
|
|||||||
|
|
||||||
[](https://github.com/sponsors/jokob-sk)
|
[](https://github.com/sponsors/jokob-sk)
|
||||||
|
|
||||||
Thank you to all the wonderful people who are sponsoring this project.
|
Thank you to all the wonderful people who are sponsoring this project (private sponsors are hidden).
|
||||||
|
|
||||||
> preventing my burnout😅 are:
|
|
||||||
|
|
||||||
<!-- SPONSORS-LIST DO NOT MODIFY BELOW -->
|
<!-- SPONSORS-LIST DO NOT MODIFY BELOW -->
|
||||||
| All Sponsors |
|
| All Sponsors |
|
||||||
@@ -98,8 +91,6 @@ Thank you to all the wonderful people who are sponsoring this project.
|
|||||||
|
|
||||||
<!-- SPONSORS-LIST DO NOT MODIFY ABOVE -->
|
<!-- SPONSORS-LIST DO NOT MODIFY ABOVE -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Click for more ways to donate</summary>
|
<summary>Click for more ways to donate</summary>
|
||||||
|
|
||||||
@@ -119,7 +110,7 @@ Thank you to all the wonderful people who are sponsoring this project.
|
|||||||
|
|
||||||
This project would be nothing without the amazing work of the community, with special thanks to:
|
This project would be nothing without the amazing work of the community, with special thanks to:
|
||||||
|
|
||||||
> [pucherot/Pi.Alert](https://github.com/pucherot/Pi.Alert) (the original creator of PiAlert), [leiweibau](https://github.com/leiweibau/Pi.Alert): Dark mode (and much more), [Macleykun](https://github.com/Macleykun) (Help with Dockerfile clean-up) [Final-Hawk](https://github.com/Final-Hawk) (Help with NTFY, styling and other fixes), [TeroRERO](https://github.com/terorero) (Spanish translations), [Data-Monkey](https://github.com/Data-Monkey), (Split-up of the python.py file and more), [cvc90](https://github.com/cvc90) (Spanish translation and various UI work) to name a few...
|
> [pucherot/Pi.Alert](https://github.com/pucherot/Pi.Alert) (the original creator of PiAlert), [leiweibau](https://github.com/leiweibau/Pi.Alert): Dark mode (and much more), [Macleykun](https://github.com/Macleykun) (Help with Dockerfile clean-up), [vladaurosh](https://github.com/vladaurosh) for Alpine re-base help, [Final-Hawk](https://github.com/Final-Hawk) (Help with NTFY, styling and other fixes), [TeroRERO](https://github.com/terorero) (Spanish translations), [Data-Monkey](https://github.com/Data-Monkey), (Split-up of the python.py file and more), [cvc90](https://github.com/cvc90) (Spanish translation and various UI work) to name a few. Check out all the [amazing contributors](https://github.com/jokob-sk/NetAlertX/graphs/contributors).
|
||||||
|
|
||||||
|
|
||||||
## Everything else
|
## Everything else
|
||||||
@@ -148,7 +139,7 @@ Help out and suggest languages in the [online portal of Weblate](https://hosted.
|
|||||||
[maintenance]: ./docs/img/maintenance.png "Screen 4"
|
[maintenance]: ./docs/img/maintenance.png "Screen 4"
|
||||||
[network]: ./docs/img/network.png "Screen 5"
|
[network]: ./docs/img/network.png "Screen 5"
|
||||||
[settings]: ./docs/img/settings.png "Screen 6"
|
[settings]: ./docs/img/settings.png "Screen 6"
|
||||||
[network_setup]: ./docs/img/network_setup.gif "Screen 6"
|
[showcase]: ./docs/img/showcase.gif "Screen 6"
|
||||||
[help_faq]: ./docs/img/help_faq.png "Screen 7"
|
[help_faq]: ./docs/img/help_faq.png "Screen 7"
|
||||||
[sync_hub]: ./docs/img/sync_hub.png "Screen 8"
|
[sync_hub]: ./docs/img/sync_hub.png "Screen 8"
|
||||||
[notification_center]: ./docs/img/notification_center.png "Screen 8"
|
[notification_center]: ./docs/img/notification_center.png "Screen 8"
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
version: "3"
|
|
||||||
services:
|
services:
|
||||||
netalertx:
|
netalertx:
|
||||||
privileged: true
|
privileged: true
|
||||||
@@ -16,7 +15,7 @@ services:
|
|||||||
# - ${APP_DATA_LOCATION}/netalertx_dev/db:/app/db
|
# - ${APP_DATA_LOCATION}/netalertx_dev/db:/app/db
|
||||||
- ${APP_DATA_LOCATION}/netalertx/db:/app/db
|
- ${APP_DATA_LOCATION}/netalertx/db:/app/db
|
||||||
# (optional) useful for debugging if you have issues setting up the container
|
# (optional) useful for debugging if you have issues setting up the container
|
||||||
- ${DEV_LOCATION}/log:/app/log
|
- ${APP_DATA_LOCATION}/netalertx/log:/app/log
|
||||||
# (API: OPTION 1) use for performance
|
# (API: OPTION 1) use for performance
|
||||||
- type: tmpfs
|
- type: tmpfs
|
||||||
target: /app/api
|
target: /app/api
|
||||||
@@ -40,11 +39,6 @@ services:
|
|||||||
- ${DEV_LOCATION}/front/lib:/app/front/lib
|
- ${DEV_LOCATION}/front/lib:/app/front/lib
|
||||||
- ${DEV_LOCATION}/front/js:/app/front/js
|
- ${DEV_LOCATION}/front/js:/app/front/js
|
||||||
- ${DEV_LOCATION}/front/report_templates:/front/report_templates
|
- ${DEV_LOCATION}/front/report_templates:/front/report_templates
|
||||||
- ${DEV_LOCATION}/install/start.debian.sh:/app/install/start.debian.sh
|
|
||||||
- ${DEV_LOCATION}/install/user-mapping.debian.sh:/app/install/user-mapping.debian.sh
|
|
||||||
- ${DEV_LOCATION}/install/install.debian.sh:/app/install/install.debian.sh
|
|
||||||
- ${DEV_LOCATION}/install/install_dependencies.debian.sh:/app/install/install_dependencies.debian.sh
|
|
||||||
|
|
||||||
- ${DEV_LOCATION}/front/php:/app/front/php
|
- ${DEV_LOCATION}/front/php:/app/front/php
|
||||||
- ${DEV_LOCATION}/front/deviceDetails.php:/app/front/deviceDetails.php
|
- ${DEV_LOCATION}/front/deviceDetails.php:/app/front/deviceDetails.php
|
||||||
- ${DEV_LOCATION}/front/deviceDetailsEdit.php:/app/front/deviceDetailsEdit.php
|
- ${DEV_LOCATION}/front/deviceDetailsEdit.php:/app/front/deviceDetailsEdit.php
|
||||||
@@ -64,7 +58,7 @@ services:
|
|||||||
- ${DEV_LOCATION}/front/presence.php:/app/front/presence.php
|
- ${DEV_LOCATION}/front/presence.php:/app/front/presence.php
|
||||||
- ${DEV_LOCATION}/front/settings.php:/app/front/settings.php
|
- ${DEV_LOCATION}/front/settings.php:/app/front/settings.php
|
||||||
- ${DEV_LOCATION}/front/systeminfo.php:/app/front/systeminfo.php
|
- ${DEV_LOCATION}/front/systeminfo.php:/app/front/systeminfo.php
|
||||||
- ${DEV_LOCATION}/front/account.php:/app/front/account.php
|
- ${DEV_LOCATION}/front/cloud_services.php:/app/front/cloud_services.php
|
||||||
- ${DEV_LOCATION}/front/report.php:/app/front/report.php
|
- ${DEV_LOCATION}/front/report.php:/app/front/report.php
|
||||||
- ${DEV_LOCATION}/front/workflows.php:/app/front/workflows.php
|
- ${DEV_LOCATION}/front/workflows.php:/app/front/workflows.php
|
||||||
- ${DEV_LOCATION}/front/appEventsCore.php:/app/front/appEventsCore.php
|
- ${DEV_LOCATION}/front/appEventsCore.php:/app/front/appEventsCore.php
|
||||||
@@ -74,7 +68,7 @@ services:
|
|||||||
# DELETE END anyone trying to use this file: comment out / delete ABOVE lines, they are only for development purposes
|
# DELETE END anyone trying to use this file: comment out / delete ABOVE lines, they are only for development purposes
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
environment:
|
environment:
|
||||||
# - APP_CONF_OVERRIDE={"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_theme":"Dark"}
|
# - APP_CONF_OVERRIDE={"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","GRAPHQL_PORT":"20223","UI_theme":"Light"}
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
- PORT=${PORT}
|
- PORT=${PORT}
|
||||||
# ❗ DANGER ZONE BELOW - Setting ALWAYS_FRESH_INSTALL=true will delete the content of the /db & /config folders
|
# ❗ DANGER ZONE BELOW - Setting ALWAYS_FRESH_INSTALL=true will delete the content of the /db & /config folders
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
[](https://github.com/jokob-sk/NetAlertX)
|
|
||||||
[](https://hub.docker.com/r/jokobsk/netalertx)
|
[](https://hub.docker.com/r/jokobsk/netalertx)
|
||||||
[](https://hub.docker.com/r/jokobsk/netalertx)
|
[](https://hub.docker.com/r/jokobsk/netalertx)
|
||||||
[](https://github.com/jokob-sk/NetAlertX/releases)
|
[](https://github.com/jokob-sk/NetAlertX/releases)
|
||||||
@@ -7,8 +6,8 @@
|
|||||||
|
|
||||||
# NetAlertX 🖧🔍 Network 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) |
|
| [📑 Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) | [🚀 Releases](https://github.com/jokob-sk/NetAlertX/releases) | [📚 Docs](https://github.com/jokob-sk/NetAlertX/tree/main/docs) | [🔌 Plugins](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md) | [🤖 Ask AI](https://gurubase.io/g/netalertx)
|
||||||
|----------------------|----------------------| ----------------------| ----------------------|
|
|----------------------| ----------------------| ----------------------| ----------------------| ----------------------|
|
||||||
|
|
||||||
<a href="https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/docs/img/GENERAL/github_social_image.jpg" target="_blank">
|
<a href="https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/docs/img/GENERAL/github_social_image.jpg" target="_blank">
|
||||||
<img src="https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/docs/img/GENERAL/github_social_image.jpg" width="1000px" />
|
<img src="https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/docs/img/GENERAL/github_social_image.jpg" width="1000px" />
|
||||||
@@ -22,17 +21,19 @@ Head to [https://netalertx.com/](https://netalertx.com/) for more gifs and scree
|
|||||||
## 📕 Basic Usage
|
## 📕 Basic Usage
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> You will have to run the container on the `host` network.
|
> You will have to run the container on the `host` network and specify `SCAN_SUBNETS` unless you use other [plugin scanners](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md). The initial scan can take a few minutes, so please wait 5-10 minutes for the initial discovery to finish.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
docker run -d --rm --network=host \
|
docker run -d --rm --network=host \
|
||||||
-v local/path/config:/app/config \
|
-v local_path/config:/app/config \
|
||||||
-v local/path/db:/app/db \
|
-v local_path/db:/app/db \
|
||||||
|
--mount type=tmpfs,target=/app/api \
|
||||||
-e TZ=Europe/Berlin \
|
-e TZ=Europe/Berlin \
|
||||||
-e PORT=20211 \
|
-e PORT=20211 \
|
||||||
jokobsk/netalertx:latest
|
jokobsk/netalertx:latest
|
||||||
```
|
```
|
||||||
- The initial scan can take up to 15min (with 50 devices and MQTT). Subsequent ones 3 and 5 minutes so wait that long for all of the scans to run.
|
|
||||||
|
See alternative [docked-compose examples](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_COMPOSE.md).
|
||||||
|
|
||||||
### Docker environment variables
|
### Docker environment variables
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ docker run -d --rm --network=host \
|
|||||||
| `PORT` |Port of the web interface | `20211` |
|
| `PORT` |Port of the web interface | `20211` |
|
||||||
| `LISTEN_ADDR` |Set the specific IP Address for the listener address for the nginx webserver (web interface). This could be useful when using multiple subnets to hide the web interface from all untrusted networks. | `0.0.0.0` |
|
| `LISTEN_ADDR` |Set the specific IP Address for the listener address for the nginx webserver (web interface). This could be useful when using multiple subnets to hide the web interface from all untrusted networks. | `0.0.0.0` |
|
||||||
|`TZ` |Time zone to display stats correctly. Find your time zone [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) | `Europe/Berlin` |
|
|`TZ` |Time zone to display stats correctly. Find your time zone [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) | `Europe/Berlin` |
|
||||||
|`APP_CONF_OVERRIDE` | JSON override for settings, e.g. `{"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_theme":"Dark"}` (Experimental 🧪) | `N/A` |
|
|`APP_CONF_OVERRIDE` | JSON override for settings, e.g. `{"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","GRAPHQL_PORT":"20212"}` | `N/A` |
|
||||||
|`ALWAYS_FRESH_INSTALL` | If `true` will delete the content of the `/db` & `/config` folders. For testing purposes. Can be coupled with [watchtower](https://github.com/containrrr/watchtower) to have an always freshly installed `netalertx`/`netalertx-dev` image. | `N/A` |
|
|`ALWAYS_FRESH_INSTALL` | If `true` will delete the content of the `/db` & `/config` folders. For testing purposes. Can be coupled with [watchtower](https://github.com/containrrr/watchtower) to have an always freshly installed `netalertx`/`netalertx-dev` image. | `N/A` |
|
||||||
|
|
||||||
> You can override the default GraphQL port setting `GRAPHQL_PORT` (set to `20212`) by using the `APP_CONF_OVERRIDE` env variable.
|
> You can override the default GraphQL port setting `GRAPHQL_PORT` (set to `20212`) by using the `APP_CONF_OVERRIDE` env variable.
|
||||||
@@ -53,54 +54,34 @@ docker run -d --rm --network=host \
|
|||||||
|
|
||||||
| Required | Path | Description |
|
| Required | Path | Description |
|
||||||
| :------------- | :------------- | :-------------|
|
| :------------- | :------------- | :-------------|
|
||||||
| ✅ | `:/app/config` | Folder which will contain the `app.conf` & `devices.csv` ([read about devices.csv](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md)) files (see below for details). |
|
| ✅ | `:/app/config` | Folder which will contain the `app.conf` & `devices.csv` ([read about devices.csv](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md)) files |
|
||||||
| ✅ | `:/app/db` | Folder which will contain the `app.db` file |
|
| ✅ | `:/app/db` | Folder which will contain the `app.db` database file |
|
||||||
| | `:/app/log` | Logs folder useful for debugging if you have issues setting up the container |
|
| | `:/app/log` | Logs folder useful for debugging if you have issues setting up the container |
|
||||||
| | `:/etc/pihole/pihole-FTL.db` | PiHole's `pihole-FTL.db` database file. Required if you want to use PiHole DB mapping. |
|
|
||||||
| | `:/etc/pihole/dhcp.leases` | PiHole's `dhcp.leases` file. Required if you want to use PiHole `dhcp.leases` file. This has to be matched with a corresponding `DHCPLSS_paths_to_check` setting entry (the path in the container must contain `pihole`)|
|
|
||||||
| | `:/app/api` | A simple [API endpoint](https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md) containing static (but regularly updated) json and other files. |
|
| | `:/app/api` | A simple [API endpoint](https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md) containing static (but regularly updated) json and other files. |
|
||||||
| | `:/app/front/plugins/<plugin>/ignore_plugin` | Map a file `ignore_plugin` to ignore a plugin. Plugins can be soft-disabled via settings. More in the [Plugin docs](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md). |
|
| | `:/app/front/plugins/<plugin>/ignore_plugin` | Map a file `ignore_plugin` to ignore a plugin. Plugins can be soft-disabled via settings. More in the [Plugin docs](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md). |
|
||||||
| | `:/etc/resolv.conf` | Use a custom `resolv.conf` file for [better name resolution](https://github.com/jokob-sk/NetAlertX/blob/main/docs/REVERSE_DNS.md). |
|
| | `:/etc/resolv.conf` | Use a custom `resolv.conf` file for [better name resolution](https://github.com/jokob-sk/NetAlertX/blob/main/docs/REVERSE_DNS.md). |
|
||||||
|
|
||||||
> Use separate `db` and `config` directories, don't nest them.
|
> Use separate `db` and `config` directories, do not nest them.
|
||||||
|
|
||||||
### (If UI is not available) Modify the config (`app.conf`)
|
### Initial setup
|
||||||
|
|
||||||
- The preferred way is to manage the configuration via the Settings section in the UI.
|
|
||||||
- You can modify [app.conf](https://github.com/jokob-sk/NetAlertX/tree/main/config) directly, if needed.
|
|
||||||
- If unavailable, the app generates a default `app.conf` and `app.db` file on the first run.
|
- If unavailable, the app generates a default `app.conf` and `app.db` file on the first run.
|
||||||
|
- The preferred way is to manage the configuration via the Settings section in the UI, if UI is inaccessible you can modify [app.conf](https://github.com/jokob-sk/NetAlertX/tree/main/back) in the `/app/config/` folder directly
|
||||||
|
|
||||||
### ⚙ Important settings
|
### Setting up scanners
|
||||||
|
|
||||||
These are the most important settings to get at least some output in your Devices screen. Usually, only one approach is used, but you can combine these approaches.
|
You have to specify which network(s) should be scanned. This is done by entering subnets that are accessible from the host. If you use the default `ARPSCAN` plugin, you have to specify at least one valid subnet and interface in the `SCAN_SUBNETS` setting. See the documentation on [How to set up multiple SUBNETS, VLANs and what are limitations](https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md) for troubleshooting and more advanced scenarios.
|
||||||
|
|
||||||
| Scan method | Setting | Description |
|
|
||||||
| :------------- | :------------- | :-------------|
|
|
||||||
| arp-scan, nmap-scan | `SCAN_SUBNETS` | See the documentation on how [to setup SUBNETS, VLANs & limitations](https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md) |
|
|
||||||
| PiHole | `PIHOLE_RUN` | There are 2 approaches how to get PiHole devices imported. Via the PiHole import (`PIHOLE`) plugin or DHCP leases (`DHCPLSS`) plugin. The `PIHOLE` plugin requires you to map the PiHole database, as mentioned above. |
|
|
||||||
| dhcp.leases | `DHCPLSS_RUN` | You need to map `:/etc/myfiles/dhcp.leases` in the `docker-compose.yml` file if you enable this setting. This path has to be matched with a corresponding `DHCPLSS_paths_to_check` setting entry (check the [DHCPLSS plugin readme](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/dhcp_leases#overview) for details). |
|
|
||||||
|
|
||||||
|
If you are running PiHole you can synchronize devices directly. Check the [PiHole configuration guide](https://github.com/jokob-sk/NetAlertX/blob/main/docs/PIHOLE_GUIDE.md) for details.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> It's recommended to use the same schedule interval for all plugins responsible for discovering new devices.
|
> You can bulk-import devices via the [CSV import method](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md).
|
||||||
|
|
||||||
|
|
||||||
#### 🧭 Community guides
|
#### 🧭 Community guides
|
||||||
|
|
||||||
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 🙏
|
You can read or watch several [community configuration guides](https://github.com/jokob-sk/NetAlertX/blob/main/docs/COMMUNITY_GUIDES.md) in Chinese, Korean, German, or French.
|
||||||
|
|
||||||
- ▶ [Home Lab Network Monitoring - Scotti-BYTE Enterprise Consulting Services](https://www.youtube.com/watch?v=0DryhzrQSJA) (July 2024)
|
> Please note these might be outdated. Rely on official documentation first.
|
||||||
- 📄 [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)
|
|
||||||
- 📄 [防蹭网神器,网络安全助手 | 极空间部署网络扫描和通知系统『NetAlertX』](https://blog.csdn.net/qq_63499861/article/details/141105273)
|
|
||||||
- 📄 [시놀/헤놀에서 네트워크 스캐너 Pi.Alert Docker로 설치 및 사용하기](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](https://www.youtube.com/watch?v=-ouvA2UNu-A) (March 2023)
|
|
||||||
- ▶ [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.
|
|
||||||
|
|
||||||
### **Common issues**
|
### **Common issues**
|
||||||
|
|
||||||
@@ -108,134 +89,6 @@ Use the official installation guides at first and use community content as suppl
|
|||||||
|
|
||||||
⚠ Check also common issues and [debugging tips](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEBUG_TIPS.md).
|
⚠ Check also common issues and [debugging tips](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEBUG_TIPS.md).
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> You can bulk-update devices via the [CSV import method](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md).
|
|
||||||
|
|
||||||
## 📄 docker-compose.yml Examples
|
|
||||||
|
|
||||||
### Example 1
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: "3"
|
|
||||||
services:
|
|
||||||
netalertx:
|
|
||||||
container_name: netalertx
|
|
||||||
# use the below line if you want to test the latest dev image
|
|
||||||
# image: "jokobsk/netalertx-dev:latest"
|
|
||||||
image: "jokobsk/netalertx:latest"
|
|
||||||
network_mode: "host"
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- local/path/config:/app/config
|
|
||||||
- local/path/db:/app/db
|
|
||||||
# (optional) useful for debugging if you have issues setting up the container
|
|
||||||
- local/path/logs:/app/log
|
|
||||||
# (API: OPTION 1) use for performance
|
|
||||||
- type: tmpfs
|
|
||||||
target: /app/api
|
|
||||||
# (API: OPTION 2) use when debugging issues
|
|
||||||
# - local/path/api:/app/api
|
|
||||||
environment:
|
|
||||||
- TZ=Europe/Berlin
|
|
||||||
- PORT=20211
|
|
||||||
```
|
|
||||||
|
|
||||||
To run the container execute: `sudo docker-compose up -d`
|
|
||||||
|
|
||||||
### Example 2
|
|
||||||
|
|
||||||
Example by [SeimuS](https://github.com/SeimusS).
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
netalertx:
|
|
||||||
container_name: NetAlertX
|
|
||||||
hostname: NetAlertX
|
|
||||||
privileged: true
|
|
||||||
# use the below line if you want to test the latest dev image
|
|
||||||
# image: "jokobsk/netalertx-dev:latest"
|
|
||||||
image: jokobsk/netalertx:latest
|
|
||||||
environment:
|
|
||||||
- TZ=Europe/Bratislava
|
|
||||||
restart: always
|
|
||||||
volumes:
|
|
||||||
- ./netalertx/db:/app/db
|
|
||||||
- ./netalertx/config:/app/config
|
|
||||||
network_mode: host
|
|
||||||
```
|
|
||||||
|
|
||||||
To run the container execute: `sudo docker-compose up -d`
|
|
||||||
|
|
||||||
### Example 3
|
|
||||||
|
|
||||||
`docker-compose.yml`
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: "3"
|
|
||||||
services:
|
|
||||||
netalertx:
|
|
||||||
container_name: netalertx
|
|
||||||
# use the below line if you want to test the latest dev image
|
|
||||||
# image: "jokobsk/netalertx-dev:latest"
|
|
||||||
image: "jokobsk/netalertx:latest"
|
|
||||||
network_mode: "host"
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- ${APP_DATA_LOCATION}/netalertx/config:/app/config
|
|
||||||
- ${APP_DATA_LOCATION}/netalertx/db/:/app/db/
|
|
||||||
# (optional) useful for debugging if you have issues setting up the container
|
|
||||||
- ${LOGS_LOCATION}:/app/log
|
|
||||||
environment:
|
|
||||||
- TZ=${TZ}
|
|
||||||
- PORT=${PORT}
|
|
||||||
```
|
|
||||||
|
|
||||||
`.env` file
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
#GLOBAL PATH VARIABLES
|
|
||||||
|
|
||||||
APP_DATA_LOCATION=/path/to/docker_appdata
|
|
||||||
APP_CONFIG_LOCATION=/path/to/docker_config
|
|
||||||
LOGS_LOCATION=/path/to/docker_logs
|
|
||||||
|
|
||||||
#ENVIRONMENT VARIABLES
|
|
||||||
|
|
||||||
TZ=Europe/Paris
|
|
||||||
PORT=20211
|
|
||||||
|
|
||||||
#DEVELOPMENT VARIABLES
|
|
||||||
|
|
||||||
DEV_LOCATION=/path/to/local/source/code
|
|
||||||
```
|
|
||||||
|
|
||||||
To run the container execute: `sudo docker-compose --env-file /path/to/.env up`
|
|
||||||
|
|
||||||
### Example 4
|
|
||||||
|
|
||||||
Courtesy of [pbek](https://github.com/pbek). The volume `netalertx_db` is used by the db directory. The two config files are mounted directly from a local folder to their places in the config folder. You can backup the `docker-compose.yaml` folder and the docker volumes folder.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
netalertx:
|
|
||||||
# use the below line if you want to test the latest dev image
|
|
||||||
# image: "jokobsk/netalertx-dev:latest"
|
|
||||||
image: jokobsk/netalertx
|
|
||||||
ports:
|
|
||||||
- "80:20211/tcp"
|
|
||||||
environment:
|
|
||||||
- TZ=Europe/Vienna
|
|
||||||
networks:
|
|
||||||
local:
|
|
||||||
ipv4_address: 192.168.1.2
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- netalertx_db:/app/db
|
|
||||||
- ./netalertx/:/app/config/
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🏅 Recognitions
|
|
||||||
|
|
||||||
Big thanks to <a href="https://github.com/Macleykun">@Macleykun</a> & for help and tips & tricks for Dockerfile(s) and <a href="https://github.com/vladaurosh">@vladaurosh</a> for Alpine re-base help.
|
|
||||||
|
|
||||||
## ❤ Support me
|
## ❤ Support me
|
||||||
|
|
||||||
| [](https://github.com/sponsors/jokob-sk) | [](https://www.buymeacoffee.com/jokobsk) | [](https://www.patreon.com/user?u=84385063) |
|
| [](https://github.com/sponsors/jokob-sk) | [](https://www.buymeacoffee.com/jokobsk) | [](https://www.patreon.com/user?u=84385063) |
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/with-contenv bash
|
#!/usr/bin/with-contenv bash
|
||||||
|
|
||||||
echo "---------------------------------------------------------"
|
echo "---------------------------------------------------------"
|
||||||
echo "[INSTALL] Run setup.sh"
|
echo "[INSTALL] Run init.sh"
|
||||||
echo "---------------------------------------------------------"
|
echo "---------------------------------------------------------"
|
||||||
|
|
||||||
export INSTALL_DIR=/app # Specify the installation directory here
|
export INSTALL_DIR=/app # Specify the installation directory here
|
||||||
@@ -108,6 +108,8 @@ fi
|
|||||||
# Create the execution_queue.log and app_front.log files if they don't exist
|
# Create the execution_queue.log and app_front.log files if they don't exist
|
||||||
touch "${INSTALL_DIR}"/log/{app.log,execution_queue.log,app_front.log,app.php_errors.log,stderr.log,stdout.log,db_is_locked.log}
|
touch "${INSTALL_DIR}"/log/{app.log,execution_queue.log,app_front.log,app.php_errors.log,stderr.log,stdout.log,db_is_locked.log}
|
||||||
touch "${INSTALL_DIR}"/api/user_notifications.json
|
touch "${INSTALL_DIR}"/api/user_notifications.json
|
||||||
|
# Create plugins sub-directory if it doesn't exist in case a custom log folder is used
|
||||||
|
mkdir -p "${INSTALL_DIR}"/log/plugins
|
||||||
|
|
||||||
echo "[INSTALL] Fixing permissions after copied starter config & DB"
|
echo "[INSTALL] Fixing permissions after copied starter config & DB"
|
||||||
chown -R nginx:www-data "${INSTALL_DIR}"/{config,log,db,api}
|
chown -R nginx:www-data "${INSTALL_DIR}"/{config,log,db,api}
|
||||||
@@ -19,7 +19,7 @@ echo "oneshot" > /etc/s6-overlay/s6-rc.d/SetupOneshot/type
|
|||||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/php-fpm/type
|
echo "longrun" > /etc/s6-overlay/s6-rc.d/php-fpm/type
|
||||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/nginx/type
|
echo "longrun" > /etc/s6-overlay/s6-rc.d/nginx/type
|
||||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/$APP_NAME/type
|
echo "longrun" > /etc/s6-overlay/s6-rc.d/$APP_NAME/type
|
||||||
echo -e "${INSTALL_DIR}/dockerfiles/setup.sh" > /etc/s6-overlay/s6-rc.d/SetupOneshot/up
|
echo -e "${INSTALL_DIR}/dockerfiles/init.sh" > /etc/s6-overlay/s6-rc.d/SetupOneshot/up
|
||||||
echo -e "#!/bin/execlineb -P\n/usr/sbin/php-fpm83 -F" > /etc/s6-overlay/s6-rc.d/php-fpm/run
|
echo -e "#!/bin/execlineb -P\n/usr/sbin/php-fpm83 -F" > /etc/s6-overlay/s6-rc.d/php-fpm/run
|
||||||
echo -e '#!/bin/execlineb -P\nnginx -g "daemon off;"' > /etc/s6-overlay/s6-rc.d/nginx/run
|
echo -e '#!/bin/execlineb -P\nnginx -g "daemon off;"' > /etc/s6-overlay/s6-rc.d/nginx/run
|
||||||
echo -e '#!/bin/execlineb -P
|
echo -e '#!/bin/execlineb -P
|
||||||
@@ -38,6 +38,5 @@ 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/nginx/dependencies.d/php-fpm
|
||||||
touch /etc/s6-overlay/s6-rc.d/$APP_NAME/dependencies.d/nginx
|
touch /etc/s6-overlay/s6-rc.d/$APP_NAME/dependencies.d/nginx
|
||||||
|
|
||||||
|
# this removes the current file
|
||||||
|
# rm -f $0
|
||||||
rm -f $0
|
|
||||||
171
docs/API.md
@@ -1,7 +1,134 @@
|
|||||||
## API endpoints
|
# API endpoints
|
||||||
|
|
||||||
NetAlertX comes with a simple API. These API endpoints are static files, that are periodically updated based on your settings.
|
NetAlertX comes with a couple of API endpoints. All requests need to be authorized (executed in a logged in browser session) or you have to pass the value of the `API_TOKEN` settings as authorization bearer, for example:
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
curl 'http://host:GRAPHQL_PORT/graphql' \
|
||||||
|
-X POST \
|
||||||
|
-H 'Authorization: Bearer API_TOKEN' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
--data '{
|
||||||
|
"query": "query GetDevices($options: PageQueryOptionsInput) { devices(options: $options) { devices { rowid devMac devName devOwner devType devVendor devLastConnection devStatus } count } }",
|
||||||
|
"variables": {
|
||||||
|
"options": {
|
||||||
|
"page": 1,
|
||||||
|
"limit": 10,
|
||||||
|
"sort": [{ "field": "devName", "order": "asc" }],
|
||||||
|
"search": "",
|
||||||
|
"status": "connected"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Endpoint: GraphQL
|
||||||
|
|
||||||
|
Endpoint URL: `php/server/query_graphql.php`
|
||||||
|
Host: `same as front end (web ui)`
|
||||||
|
Port: `20212` or as defined by the `GRAPHQL_PORT` setting
|
||||||
|
|
||||||
|
### Example Query to Fetch Devices
|
||||||
|
|
||||||
|
First, let's define the GraphQL query to fetch devices with pagination and sorting options.
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
query GetDevices($options: PageQueryOptionsInput) {
|
||||||
|
devices(options: $options) {
|
||||||
|
devices {
|
||||||
|
rowid
|
||||||
|
devMac
|
||||||
|
devName
|
||||||
|
devOwner
|
||||||
|
devType
|
||||||
|
devVendor
|
||||||
|
devLastConnection
|
||||||
|
devStatus
|
||||||
|
}
|
||||||
|
count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `curl` Command
|
||||||
|
|
||||||
|
You can use the following `curl` command to execute the query.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl 'http://host:GRAPHQL_PORT/graphql' -X POST -H 'Authorization: Bearer API_TOKEN' -H 'Content-Type: application/json' --data '{
|
||||||
|
"query": "query GetDevices($options: PageQueryOptionsInput) { devices(options: $options) { devices { rowid devMac devName devOwner devType devVendor devLastConnection devStatus } count } }",
|
||||||
|
"variables": {
|
||||||
|
"options": {
|
||||||
|
"page": 1,
|
||||||
|
"limit": 10,
|
||||||
|
"sort": [{ "field": "devName", "order": "asc" }],
|
||||||
|
"search": "",
|
||||||
|
"status": "connected"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Explanation:
|
||||||
|
|
||||||
|
1. **GraphQL Query**:
|
||||||
|
- The `query` parameter contains the GraphQL query as a string.
|
||||||
|
- The `variables` parameter contains the input variables for the query.
|
||||||
|
|
||||||
|
2. **Query Variables**:
|
||||||
|
- `page`: Specifies the page number of results to fetch.
|
||||||
|
- `limit`: Specifies the number of results per page.
|
||||||
|
- `sort`: Specifies the sorting options, with `field` being the field to sort by and `order` being the sort order (`asc` for ascending or `desc` for descending).
|
||||||
|
- `search`: A search term to filter the devices.
|
||||||
|
- `status`: The status filter to apply (valid values are `my_devices` (determined by the `UI_MY_DEVICES` setting), `connected`, `favorites`, `new`, `down`, `archived`, `offline`).
|
||||||
|
|
||||||
|
3. **`curl` Command**:
|
||||||
|
- The `-X POST` option specifies that we are making a POST request.
|
||||||
|
- The `-H "Content-Type: application/json"` option sets the content type of the request to JSON.
|
||||||
|
- The `-d` option provides the request payload, which includes the GraphQL query and variables.
|
||||||
|
|
||||||
|
### Sample Response
|
||||||
|
|
||||||
|
The response will be in JSON format, similar to the following:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"devices": {
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"rowid": 1,
|
||||||
|
"devMac": "00:11:22:33:44:55",
|
||||||
|
"devName": "Device 1",
|
||||||
|
"devOwner": "Owner 1",
|
||||||
|
"devType": "Type 1",
|
||||||
|
"devVendor": "Vendor 1",
|
||||||
|
"devLastConnection": "2025-01-01T00:00:00Z",
|
||||||
|
"devStatus": "connected"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rowid": 2,
|
||||||
|
"devMac": "66:77:88:99:AA:BB",
|
||||||
|
"devName": "Device 2",
|
||||||
|
"devOwner": "Owner 2",
|
||||||
|
"devType": "Type 2",
|
||||||
|
"devVendor": "Vendor 2",
|
||||||
|
"devLastConnection": "2025-01-02T00:00:00Z",
|
||||||
|
"devStatus": "connected"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"count": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Endpoint: JSON files
|
||||||
|
|
||||||
|
These API endpoint are static files, that are periodically updated.
|
||||||
|
|
||||||
|
Endpoint URL: `php/server/query_json.php?file=<file name>`
|
||||||
|
Host: `same as front end (web ui)`
|
||||||
|
Port: `20211` or as defined by the $PORT docker environment variable (same as the port for the web ui)
|
||||||
|
|
||||||
### When are the endpoints updated
|
### When are the endpoints updated
|
||||||
|
|
||||||
@@ -9,7 +136,7 @@ The endpoints are updated when objects in the API endpoints are changed.
|
|||||||
|
|
||||||
### Location of the endpoints
|
### Location of the endpoints
|
||||||
|
|
||||||
In the container, these files are located under the `/app/api/` folder. You can acces sthem via the `/php/server/query_json.php?file=user_notifications.json` endpoint.
|
In the container, these files are located under the `/app/api/` folder. You can access them via the `/php/server/query_json.php?file=user_notifications.json` endpoint.
|
||||||
|
|
||||||
### Available endpoints
|
### Available endpoints
|
||||||
|
|
||||||
@@ -95,3 +222,41 @@ Example JSON of the `table_devices.json` endpoint with two Devices (database row
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## API Endpoint: /log files
|
||||||
|
|
||||||
|
To retrieve files from the `/app/log` folder.
|
||||||
|
|
||||||
|
Endpoint URL: `php/server/query_logs.php?file=<file name>`
|
||||||
|
Host: `same as front end (web ui)`
|
||||||
|
Port: `20211` or as defined by the $PORT docker environment variable (same as the port for the web ui)
|
||||||
|
|
||||||
|
| File | Description |
|
||||||
|
|--------------------------|--------------------------------------------------|
|
||||||
|
| `IP_changes.log` | Logs of IP address changes |
|
||||||
|
| `app.log` | Main application log |
|
||||||
|
| `app.php_errors`.log | PHP error log |
|
||||||
|
| `app_front.log` | Frontend application log |
|
||||||
|
| `app_nmap.log` | Logs of Nmap scan results |
|
||||||
|
| `db_is_locked.log` | Logs when the database is locked |
|
||||||
|
| `execution_queue.log` | Logs of execution queue activities |
|
||||||
|
| `plugins/` | Directory for plugin-related files (not accessible) |
|
||||||
|
| `report_output.html` | HTML report output |
|
||||||
|
| `report_output.json` | JSON format report output |
|
||||||
|
| `report_output.txt` | Text format report output |
|
||||||
|
| `stderr.log` | Logs of standard error output |
|
||||||
|
| `stdout.log` | Logs of standard output |
|
||||||
|
|
||||||
|
|
||||||
|
## API Endpoint: /config files
|
||||||
|
|
||||||
|
To retrieve files from the `/app/config` folder.
|
||||||
|
|
||||||
|
Endpoint URL: `php/server/query_config.php?file=<file name>`
|
||||||
|
Host: `same as front end (web ui)`
|
||||||
|
Port: `20211` or as defined by the $PORT docker environment variable (same as the port for the web ui)
|
||||||
|
|
||||||
|
| File | Description |
|
||||||
|
|--------------------------|--------------------------------------------------|
|
||||||
|
| `devices.csv` | Devices csv file |
|
||||||
|
| `app.conf` | Application config file |
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
# 💾 Backing things up
|
# 💾 Backing things up
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> To backup 99% of your configuration backup at least the `/config` folder. Please read the whole page (or at least "Scenario 2: Corrupted database") for details.
|
> To backup 99% of your configuration backup at least the `/app/config` folder. Please read the whole page (or at least "Scenario 2: Corrupted database") for details.
|
||||||
|
> Please also note that database definitions might change over versions. The safest way is to restore your older backups into the **same version** of the app and then gradually upgarde between releases to the latest version.
|
||||||
|
|
||||||
There are 3 artifacts that can be used to backup the application:
|
There are 3 artifacts that can be used to backup the application:
|
||||||
|
|
||||||
@@ -22,16 +23,17 @@ The core application configuration is in the `app.conf` file (See [Settings Syst
|
|||||||
- Notification settings
|
- Notification settings
|
||||||
- Scanner settings
|
- Scanner settings
|
||||||
- Scheduled maintenance settings
|
- Scheduled maintenance settings
|
||||||
- UI configuration (80%)
|
- UI configuration
|
||||||
|
|
||||||
### Core Device Data
|
### Core Device Data
|
||||||
|
|
||||||
The core device data is backed up to the `devices_<timestamp>.csv` file via the [CSV Backup `CSVBCKP` Plugin](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/csv_backup). This file contains data, such as:
|
The core device data is backed up to the `devices_<timestamp>.csv` or `devices.csv` file via the [CSV Backup `CSVBCKP` Plugin](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/csv_backup). This file contains data, such as:
|
||||||
|
|
||||||
- Device names
|
- Device names
|
||||||
- Device Icons
|
- Device icons
|
||||||
- Device Network configuration
|
- Device network configuration
|
||||||
- Device categorization
|
- Device categorization
|
||||||
|
- Device custom properties data
|
||||||
|
|
||||||
### Historical data
|
### Historical data
|
||||||
|
|
||||||
@@ -40,13 +42,13 @@ Historical data is stored in the `app.db` database (See [Database overview](http
|
|||||||
- Plugin objects
|
- Plugin objects
|
||||||
- Plugin historical entries
|
- Plugin historical entries
|
||||||
- History of Events, Notifications, Workflow Events
|
- History of Events, Notifications, Workflow Events
|
||||||
- Presence History
|
- Presence history
|
||||||
|
|
||||||
## 🧭 Backup strategies
|
## 🧭 Backup strategies
|
||||||
|
|
||||||
The safest approach to backups is to backup all of the above, by taking regular file system backups (I use [Kopia](https://github.com/kopia/kopia)).
|
The safest approach to backups is to backup all of the above, by taking regular file system backups (I use [Kopia](https://github.com/kopia/kopia)).
|
||||||
|
|
||||||
Arguably, the most time is spent setting up the device list, so if only one file is kept I'd recommend to have a latest backup of the `devices_<timestamp>.csv` file, followed by the `app.conf` file.
|
Arguably, the most time is spent setting up the device list, so if only one file is kept I'd recommend to have a latest backup of the `devices_<timestamp>.csv` or `devices.csv` file, followed by the `app.conf` file.
|
||||||
|
|
||||||
### Scenario 1: Full backup
|
### Scenario 1: Full backup
|
||||||
|
|
||||||
@@ -54,8 +56,8 @@ End-result: Full restore
|
|||||||
|
|
||||||
#### Source artifacts:
|
#### Source artifacts:
|
||||||
|
|
||||||
- `/db/app.db` (uncorrupted)
|
- `/app/db/app.db` (uncorrupted)
|
||||||
- `/config/app.conf`
|
- `/app/config/app.conf`
|
||||||
|
|
||||||
#### Recovery:
|
#### Recovery:
|
||||||
|
|
||||||
@@ -68,15 +70,15 @@ End-result: Partial restore (historical data & configurations from the Maintenan
|
|||||||
|
|
||||||
#### Source artifacts:
|
#### Source artifacts:
|
||||||
|
|
||||||
- `/config/app.conf`
|
- `/app/config/app.conf`
|
||||||
- `/config/devices_<timestamp>.csv` or `/config/devices.csv`
|
- `/app/config/devices_<timestamp>.csv` or `/app/config/devices.csv`
|
||||||
|
|
||||||
#### Recovery:
|
#### Recovery:
|
||||||
|
|
||||||
Even with a corrupted database you can recover what I would argue is 99% of the configuration.
|
Even with a corrupted database you can recover what I would argue is 99% of the configuration.
|
||||||
|
|
||||||
- map the `/config/app.conf` file as described in the [Setup documentation](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md#docker-paths).
|
- upload the `app.conf` file into the mounted `/app/config/` folder as described in the [Setup documentation](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md#docker-paths).
|
||||||
- rename the `devices_<timestamp>.csv` to `devices.csv` and place it in the `/config` folder
|
- rename the `devices_<timestamp>.csv` to `devices.csv` and place it in the `/app/config` folder
|
||||||
- Restore the `devices.csv` backup via the [Maintenance section](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md)
|
- Restore the `devices.csv` backup via the [Maintenance section](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
14
docs/COMMUNITY_GUIDES.md
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
# Community Guides
|
||||||
|
|
||||||
|
Use the official installation guides at first and use community content as supplementary material. Open an issue or PR if you'd like to add your link to the list 🙏 (Ordered by last update time)
|
||||||
|
|
||||||
|
- ▶ [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)
|
||||||
|
- 📄 [防蹭网神器,网络安全助手 | 极空间部署网络扫描和通知系统『NetAlertX』](https://blog.csdn.net/qq_63499861/article/details/141105273)
|
||||||
|
- 📄 [시놀/헤놀에서 네트워크 스캐너 Pi.Alert Docker로 설치 및 사용하기](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](https://www.youtube.com/watch?v=-ouvA2UNu-A) (March 2023)
|
||||||
|
- ▶ [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)
|
||||||
85
docs/CUSTOM_PROPERTIES.md
Executable file
@@ -0,0 +1,85 @@
|
|||||||
|
# Custom Properties for Devices
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This functionality allows you to define **custom properties** for devices, which can store and display additional information on the device listing page. By marking properties as visible, you can enhance the user interface with quick actions, notes, or external links.
|
||||||
|
|
||||||
|
### Key Features:
|
||||||
|
- **Customizable Properties**: Define specific properties for each device.
|
||||||
|
- **Visibility Control**: Choose which properties are displayed on the device listing page.
|
||||||
|
- **Interactive Elements**: Include actions like links, modals, and device management directly in the interface.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Defining Custom Properties
|
||||||
|
|
||||||
|
Custom properties are structured as a list of objects, where each property includes the following fields:
|
||||||
|
|
||||||
|
| Field | Description |
|
||||||
|
|--------------------|-----------------------------------------------------------------------------|
|
||||||
|
| `CUSTPROP_icon` | The icon (Base64-encoded HTML) displayed for the property. |
|
||||||
|
| `CUSTPROP_type` | The action type (e.g., `show_notes`, `link`, `delete_dev`). |
|
||||||
|
| `CUSTPROP_name` | A short name or title for the property. |
|
||||||
|
| `CUSTPROP_args` | Arguments for the action (e.g., URL or modal text). |
|
||||||
|
| `CUSTPROP_notes` | Additional notes or details displayed when applicable. |
|
||||||
|
| `CUSTPROP_show` | A boolean to control visibility (`true` to show on the listing page). |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Available Action Types
|
||||||
|
|
||||||
|
- **Show Notes**: Displays a modal with a title and additional notes.
|
||||||
|
- **Example**: Show firmware details or custom messages.
|
||||||
|
- **Link**: Redirects to a specified URL in the current browser tab. (**Arguments** Needs to contain the full URL.)
|
||||||
|
- **Link (New Tab)**: Opens a specified URL in a new browser tab. (**Arguments** Needs to contain the full URL.)
|
||||||
|
- **Delete Device**: Deletes the device using its MAC address.
|
||||||
|
- **Run Plugin**: Placeholder for executing custom plugins (not implemented yet).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage on the Device Listing Page
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Visible properties (`CUSTPROP_show: true`) are displayed as interactive icons in the device listing. Each icon can perform one of the following actions based on the `CUSTPROP_type`:
|
||||||
|
|
||||||
|
1. **Modals (e.g., Show Notes)**:
|
||||||
|
- Displays detailed information in a popup modal.
|
||||||
|
- Example: Firmware version details.
|
||||||
|
|
||||||
|
2. **Links**:
|
||||||
|
- Redirect to an external or internal URL.
|
||||||
|
- Example: Open a device's documentation or external site.
|
||||||
|
|
||||||
|
3. **Device Actions**:
|
||||||
|
- Manage devices with actions like delete.
|
||||||
|
- Example: Quickly remove a device from the network.
|
||||||
|
|
||||||
|
4. **Plugins**:
|
||||||
|
- Future placeholder for running custom plugin scripts.
|
||||||
|
- **Note**: Not implemented yet.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example Scenarios
|
||||||
|
|
||||||
|
1. **Device Documentation Link**:
|
||||||
|
- Add a custom property with `CUSTPROP_type` set to `link` or `link_new_tab` to allow quick navigation to the documentation.
|
||||||
|
|
||||||
|
2. **Firmware Details**:
|
||||||
|
- Use `CUSTPROP_type: show_notes` to display firmware versions or upgrade instructions in a modal.
|
||||||
|
|
||||||
|
3. **Device Removal**:
|
||||||
|
- Enable device removal functionality using `CUSTPROP_type: delete_dev`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- **Plugin Functionality**: The `run_plugin` action type is currently not implemented and will show an alert if used.
|
||||||
|
- **Custom Icons (Experimental 🧪)**: Use Base64-encoded HTML to provide custom icons for each property. You can add your icons in Setttings via the `CUSTPROP_icon` settings
|
||||||
|
- **Visibility Control**: Only properties with `CUSTPROP_show: true` will appear on the listing page.
|
||||||
|
|
||||||
|
This feature provides a flexible way to enhance device management and display with interactive elements tailored to your needs.
|
||||||
128
docs/DOCKER_COMPOSE.md
Executable file
@@ -0,0 +1,128 @@
|
|||||||
|
# `docker-compose.yaml` Examples
|
||||||
|
|
||||||
|
### Example 1
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
netalertx:
|
||||||
|
container_name: netalertx
|
||||||
|
# use the below line if you want to test the latest dev image
|
||||||
|
# image: "jokobsk/netalertx-dev:latest"
|
||||||
|
image: "jokobsk/netalertx:latest"
|
||||||
|
network_mode: "host"
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- local_path/config:/app/config
|
||||||
|
- local_path/db:/app/db
|
||||||
|
# (optional) useful for debugging if you have issues setting up the container
|
||||||
|
- local_path/logs:/app/log
|
||||||
|
# (API: OPTION 1) use for performance
|
||||||
|
- type: tmpfs
|
||||||
|
target: /app/api
|
||||||
|
# (API: OPTION 2) use when debugging issues
|
||||||
|
# - local_path/api:/app/api
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Berlin
|
||||||
|
- PORT=20211
|
||||||
|
```
|
||||||
|
|
||||||
|
To run the container execute: `sudo docker-compose up -d`
|
||||||
|
|
||||||
|
### Example 2
|
||||||
|
|
||||||
|
Example by [SeimuS](https://github.com/SeimusS).
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
netalertx:
|
||||||
|
container_name: NetAlertX
|
||||||
|
hostname: NetAlertX
|
||||||
|
privileged: true
|
||||||
|
# use the below line if you want to test the latest dev image
|
||||||
|
# image: "jokobsk/netalertx-dev:latest"
|
||||||
|
image: jokobsk/netalertx:latest
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Bratislava
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./netalertx/db:/app/db
|
||||||
|
- ./netalertx/config:/app/config
|
||||||
|
network_mode: host
|
||||||
|
```
|
||||||
|
|
||||||
|
To run the container execute: `sudo docker-compose up -d`
|
||||||
|
|
||||||
|
### Example 3
|
||||||
|
|
||||||
|
`docker-compose.yml`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
netalertx:
|
||||||
|
container_name: netalertx
|
||||||
|
# use the below line if you want to test the latest dev image
|
||||||
|
# image: "jokobsk/netalertx-dev:latest"
|
||||||
|
image: "jokobsk/netalertx:latest"
|
||||||
|
network_mode: "host"
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ${APP_DATA_LOCATION}/netalertx/config:/app/config
|
||||||
|
- ${APP_DATA_LOCATION}/netalertx/db/:/app/db/
|
||||||
|
# (optional) useful for debugging if you have issues setting up the container
|
||||||
|
- ${LOGS_LOCATION}:/app/log
|
||||||
|
# (API: OPTION 1) use for performance
|
||||||
|
- type: tmpfs
|
||||||
|
target: /app/api
|
||||||
|
# (API: OPTION 2) use when debugging issues
|
||||||
|
# - local/path/api:/app/api
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
- PORT=${PORT}
|
||||||
|
```
|
||||||
|
|
||||||
|
`.env` file
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
#GLOBAL PATH VARIABLES
|
||||||
|
|
||||||
|
APP_DATA_LOCATION=/path/to/docker_appdata
|
||||||
|
APP_CONFIG_LOCATION=/path/to/docker_config
|
||||||
|
LOGS_LOCATION=/path/to/docker_logs
|
||||||
|
|
||||||
|
#ENVIRONMENT VARIABLES
|
||||||
|
|
||||||
|
TZ=Europe/Paris
|
||||||
|
PORT=20211
|
||||||
|
|
||||||
|
#DEVELOPMENT VARIABLES
|
||||||
|
|
||||||
|
DEV_LOCATION=/path/to/local/source/code
|
||||||
|
```
|
||||||
|
|
||||||
|
To run the container execute: `sudo docker-compose --env-file /path/to/.env up`
|
||||||
|
|
||||||
|
### Example 4
|
||||||
|
|
||||||
|
Courtesy of [pbek](https://github.com/pbek). The volume `netalertx_db` is used by the db directory. The two config files are mounted directly from a local folder to their places in the config folder. You can backup the `docker-compose.yaml` folder and the docker volumes folder.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
netalertx:
|
||||||
|
# use the below line if you want to test the latest dev image
|
||||||
|
# image: "jokobsk/netalertx-dev:latest"
|
||||||
|
image: jokobsk/netalertx
|
||||||
|
ports:
|
||||||
|
- "80:20211/tcp"
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Vienna
|
||||||
|
networks:
|
||||||
|
local:
|
||||||
|
ipv4_address: 192.168.1.2
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- netalertx_db:/app/db
|
||||||
|
- ./netalertx/:/app/config/
|
||||||
|
# (API: OPTION 1) use for performance
|
||||||
|
- type: tmpfs
|
||||||
|
target: /app/api
|
||||||
|
# (API: OPTION 2) use when debugging issues
|
||||||
|
# - local/path/api:/app/api
|
||||||
|
```
|
||||||
@@ -5,7 +5,7 @@ To download and install NetAlertX on the hardware/server directly use the `curl`
|
|||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> This is an Experimental feature 🧪 and it relies on community support.
|
> This is an Experimental feature 🧪 and it relies on community support.
|
||||||
>
|
>
|
||||||
> Looking for maintainers for this installation method 🙂
|
> 🙏 Looking for maintainers for this installation method 🙂
|
||||||
>
|
>
|
||||||
> There is no guarantee that the install script or any other script will gracefully handle other installed software.
|
> There is no guarantee that the install script or any other script will gracefully handle other installed software.
|
||||||
> Data loss is a possibility, **it is recommended to install NetAlertX using the supplied Docker image**.
|
> Data loss is a possibility, **it is recommended to install NetAlertX using the supplied Docker image**.
|
||||||
@@ -36,6 +36,9 @@ Some facts about what and where something will be changed/installed by the HW in
|
|||||||
|
|
||||||
## 📥 Installation via CURL
|
## 📥 Installation via CURL
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> If the below fails try grabbing and installing one of the [previous releases](https://github.com/jokob-sk/NetAlertX/releases) and run the installation from the zip package.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -o install.debian.sh https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/install/install.debian.sh && sudo chmod +x install.debian.sh && sudo ./install.debian.sh
|
curl -o install.debian.sh https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/install/install.debian.sh && sudo chmod +x install.debian.sh && sudo ./install.debian.sh
|
||||||
```
|
```
|
||||||
|
|||||||
45
docs/PIHOLE_GUIDE.md
Executable file
@@ -0,0 +1,45 @@
|
|||||||
|
# Integration with PiHole
|
||||||
|
|
||||||
|
NetAlertX comes with 2 plugins suitable for integarting with your existing PiHole instace. One plugin is using a direct SQLite DB connection, the other leverages the DHCP.leases file generated by PiHole. You can combine both approaches and also supplement it with other [plugins](/front/plugins/README.md).
|
||||||
|
|
||||||
|
## Approach 1: `DHCPLSS` Plugin - Import devices from the PiHole DHCP leases file
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Settings
|
||||||
|
|
||||||
|
| Setting | Description | Recommended value |
|
||||||
|
| :------------- | :------------- | :-------------|
|
||||||
|
| `DHCPLSS_RUN` | When the plugin should run. | `schedule` |
|
||||||
|
| `DHCPLSS_RUN_SCHD` | If you run multiple device scanner plugins, align the schedules of all plugins to the same value. | `*/5 * * * *` |
|
||||||
|
| `DHCPLSS_paths_to_check` | You need to map the value in this setting in the `docker-compose.yml` file. The in-container path must contain `pihole` so it's parsed correctly. | `['/etc/pihole/dhcp.leases']` |
|
||||||
|
|
||||||
|
Check the [DHCPLSS plugin readme](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/dhcp_leases#overview) for details
|
||||||
|
|
||||||
|
### docker-compose changes
|
||||||
|
|
||||||
|
| Path | Description |
|
||||||
|
| :------------- | :------------- |
|
||||||
|
| `:/etc/pihole/dhcp.leases` | PiHole's `dhcp.leases` file. Required if you want to use PiHole `dhcp.leases` file. This has to be matched with a corresponding `DHCPLSS_paths_to_check` setting entry (the path in the container must contain `pihole`) |
|
||||||
|
|
||||||
|
|
||||||
|
## Approach 2: `PIHOLE` Plugin - Import devices directly from the PiHole database
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
| Setting | Description | Recommended value |
|
||||||
|
| :------------- | :------------- | :-------------|
|
||||||
|
| `PIHOLE_RUN` | When the plugin should run. | `schedule` |
|
||||||
|
| `PIHOLE_RUN_SCHD` | If you run multiple device scanner plugins, align the schedules of all plugins to the same value. | `*/5 * * * *` |
|
||||||
|
| `PIHOLE_DB_PATH` | You need to map the value in this setting in the `docker-compose.yml` file. | `/etc/pihole/pihole-FTL.db` |
|
||||||
|
|
||||||
|
Check the [PiHole plugin readme](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/pihole_scan) for details
|
||||||
|
|
||||||
|
### docker-compose changes
|
||||||
|
|
||||||
|
| Path | Description |
|
||||||
|
| :------------- | :------------- |
|
||||||
|
| `:/etc/pihole/pihole-FTL.db` | PiHole's `pihole-FTL.db` database file. |
|
||||||
|
|
||||||
|
|
||||||
|
Check out other [plugins](/front/plugins/README.md) that can help you discover more about your network or check how to scan [Remote networks](/docs/REMOTE_NETWORKS.md).
|
||||||
@@ -12,6 +12,9 @@ NetAlertX comes with a plugin system to feed events from third-party scripts int
|
|||||||
|
|
||||||
### 🎥 Watch the video:
|
### 🎥 Watch the video:
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> Read this guide [Development environment setup guide](/docs/DEV_ENV_SETUP.md) to set up your local environment for development. 👩💻
|
||||||
|
|
||||||
[](https://youtu.be/cdbxlwiWhv8)
|
[](https://youtu.be/cdbxlwiWhv8)
|
||||||
|
|
||||||
### 📸 Screenshots
|
### 📸 Screenshots
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
You need to specify the network interface and the network mask. You can also configure multiple subnets and specify VLANs (see VLAN exceptions below).
|
You need to specify the network interface and the network mask. You can also configure multiple subnets and specify VLANs (see VLAN exceptions below).
|
||||||
|
|
||||||
`ARPSCAN` can scan multiple networks if the network allows it. To scan networks directly, the subnets must be accessible from the network where NetAlertX is running. This means NetAlertX needs to have access to the interface attached to that subnet. You can verify this by running the following command in the container:
|
`ARPSCAN` can scan multiple networks if the network allows it. To scan networks directly, the subnets must be accessible from the network where NetAlertX is running. This means NetAlertX needs to have access to the interface attached to that subnet. You can verify this by running the following command in the container (replace the interface and ip mask):
|
||||||
|
|
||||||
`sudo arp-scan --interface=eth0 192.168.1.0/24`
|
`sudo arp-scan --interface=eth0 192.168.1.0/24`
|
||||||
|
|
||||||
@@ -45,18 +45,24 @@ Specify the network filter, which **significantly** speeds up the scan process.
|
|||||||
|
|
||||||
**Example value:** `--interface=eth0`
|
**Example value:** `--interface=eth0`
|
||||||
|
|
||||||
The adapter will probably be `eth0` or `eth1`. (Check `System Info` > `Network Hardware` or run `iwconfig` in the container to find your interface name(s)).
|
The adapter will probably be `eth0` or `eth1`. (Check `System Info` > `Network Hardware`, or run `iwconfig` in the container to find your interface name(s)).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> As an alternative to `iwconfig`, run `ip -o link show | awk -F': ' '!/lo|vir|docker/ {print $2}'` in your container to find your interface name(s) (e.g.: `eth0`, `eth1`).
|
> As an alternative to `iwconfig`, run `ip -o link show | awk -F': ' '!/lo|vir|docker/ {print $2}'` in your container to find your interface name(s) (e.g.: `eth0`, `eth1`):
|
||||||
|
> ```bash
|
||||||
|
> Synology-NAS:/# ip -o link show | awk -F': ' '!/lo|vir|docker/ {print $2}'
|
||||||
|
> sit0@NONE
|
||||||
|
> eth1
|
||||||
|
> eth0
|
||||||
|
> ```
|
||||||
|
|
||||||
### VLANs
|
### VLANs
|
||||||
|
|
||||||
**Example value:** `-vlan=107`
|
**Example value:** `--vlan=107`
|
||||||
|
|
||||||
- Append `-vlan=107` to the interface field (e.g.: `eth0 -vlan=107`) for multiple VLANs. More details are available in this [comment](https://github.com/jokob-sk/NetAlertX/issues/170#issuecomment-1419902988).
|
- Append `--vlan=107` to the `SCAN_SUBNETS` field (e.g.: `192.168.1.0/24 --interface=vmbr0 --vlan=107`) for multiple VLANs.
|
||||||
|
|
||||||
#### VLANs on a Hyper-V Setup
|
#### VLANs on a Hyper-V Setup
|
||||||
|
|
||||||
|
|||||||
BIN
docs/img/CUSTOM_PROPERTIES/Device_Custom_Properties.png
Executable file
|
After Width: | Height: | Size: 39 KiB |
BIN
docs/img/CUSTOM_PROPERTIES/Device_Custom_Properties_vid.gif
Executable file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
docs/img/PIHOLE_GUIDE/DHCPLSS_pihole_settings.png
Executable file
|
After Width: | Height: | Size: 99 KiB |
BIN
docs/img/PIHOLE_GUIDE/PIHOLE_settings.png
Executable file
|
After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 18 KiB |
BIN
docs/img/showcase.gif
Executable file
|
After Width: | Height: | Size: 5.1 MiB |
@@ -287,11 +287,6 @@ body
|
|||||||
margin-left: 150px;
|
margin-left: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#settingsPage
|
|
||||||
{
|
|
||||||
display: grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
.main-header .logo {
|
.main-header .logo {
|
||||||
@@ -620,7 +615,7 @@ body
|
|||||||
|
|
||||||
.modal_red
|
.modal_red
|
||||||
{
|
{
|
||||||
color: rgb(245, 245, 245);
|
color: #d41001;
|
||||||
background-color: #e2acaa;
|
background-color: #e2acaa;
|
||||||
border-color: #d41001;
|
border-color: #d41001;
|
||||||
}
|
}
|
||||||
@@ -893,6 +888,34 @@ height: 50px;
|
|||||||
} */
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Hide unusable buttons on the settings page for the NEWDEV plugin*/
|
||||||
|
#settingsPage #add_option_NEWDEV_devGroup,
|
||||||
|
#settingsPage #add_option_NEWDEV_devLocation,
|
||||||
|
#settingsPage #add_option_NEWDEV_devOwner,
|
||||||
|
#settingsPage #copy_icons_NEWDEV_devIcon,
|
||||||
|
#settingsPage #add_icon_NEWDEV_devIcon,
|
||||||
|
#settingsPage #add_option_NEWDEV_devSite,
|
||||||
|
#settingsPage #add_option_NEWDEV_devType
|
||||||
|
{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#settingsPage
|
||||||
|
{
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#settingsPage .small-box .inner .card-title {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.settingswrap
|
.settingswrap
|
||||||
{
|
{
|
||||||
margin-bottom: 100px;
|
margin-bottom: 100px;
|
||||||
@@ -1382,9 +1405,80 @@ input[readonly] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------- */
|
/* ----------------------------------------------------------------- */
|
||||||
/* MODAL popups */
|
/* Device details */
|
||||||
/* ----------------------------------------------------------------- */
|
/* ----------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.dataTables_length label .form-control, .dataTables_filter label .form-control
|
||||||
|
{
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.form-inline .input-group
|
||||||
|
{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group .actionIcon
|
||||||
|
{
|
||||||
|
height: 2.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group .actionIcon:hover
|
||||||
|
{
|
||||||
|
backdrop-filter: brightness(50%);
|
||||||
|
background-color: rgba(0, 0, 0, 0.2); /* darkens the background */
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
transition: box-shadow 0.1s ease-in-out, background-color 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.devicePropAction
|
||||||
|
{
|
||||||
|
width: 1.2em;
|
||||||
|
height: 1.2em;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.1em;
|
||||||
|
margin: 0.1em;
|
||||||
|
/* transition: font-size 0.3s;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.devicePropAction:hover
|
||||||
|
{
|
||||||
|
font-size: larger;
|
||||||
|
padding: 0em;
|
||||||
|
margin: 0em;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#panDetails .dataTables_wrapper .bottom div
|
||||||
|
{
|
||||||
|
max-width: 34%;
|
||||||
|
display: block;
|
||||||
|
float:inline-end;
|
||||||
|
height: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#panDetails .dataTables_wrapper .bottom .dataTables_info
|
||||||
|
{
|
||||||
|
float:inline-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
#panDetails .dataTables_wrapper .bottom .dataTables_length
|
||||||
|
{
|
||||||
|
padding: 0.3em;
|
||||||
|
}
|
||||||
|
/* #panDetails .dataTables_wrapper .bottom .paging_simple_numbers */
|
||||||
|
|
||||||
|
|
||||||
|
#panDetails #NEWDEV_devCustomProps_label
|
||||||
|
{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------- */
|
||||||
|
/* MODAL popups */
|
||||||
|
/* ----------------------------------------------------------------- */
|
||||||
#modal-input-textarea
|
#modal-input-textarea
|
||||||
{
|
{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -1555,6 +1649,7 @@ input[readonly] {
|
|||||||
.integrations-plugins .content
|
.integrations-plugins .content
|
||||||
{
|
{
|
||||||
display: table;
|
display: table;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.plugin-content .tab-content
|
.plugin-content .tab-content
|
||||||
@@ -1606,13 +1701,6 @@ input[readonly] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#settingsPage .small-box .inner .card-title {
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.textOverflow
|
.textOverflow
|
||||||
{
|
{
|
||||||
@@ -1719,7 +1807,8 @@ input[readonly] {
|
|||||||
|
|
||||||
table.dataTable tbody > tr.selected
|
table.dataTable tbody > tr.selected
|
||||||
{
|
{
|
||||||
color:red;
|
/* color:red; */
|
||||||
|
color: #353c42;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ html {
|
|||||||
background-color: #353c42;
|
background-color: #353c42;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
/* body {
|
||||||
background-image: url('../img/boxed-bg-dark.png') !important;
|
background-image: url('../img/boxed-bg-dark.png') !important;
|
||||||
}
|
} */
|
||||||
|
|
||||||
body, .bg-yellow, .callout.callout-warning, .alert-warning, .label-warning, .modal-warning .modal-body {
|
body, .bg-yellow, .callout.callout-warning, .alert-warning, .label-warning, .modal-warning .modal-body {
|
||||||
|
|
||||||
@@ -732,4 +732,8 @@ input[type="password"]::-webkit-caps-lock-indicator {
|
|||||||
background-color: #000 !important;
|
background-color: #000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.callout code {
|
||||||
|
background-color: #fff !important;
|
||||||
|
color:#000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,9 +19,9 @@
|
|||||||
background-color: #353c42;
|
background-color: #353c42;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
/* body {
|
||||||
background-image: url('../img/boxed-bg-dark.png') !important;
|
background-image: url('../img/boxed-bg-dark.png') !important;
|
||||||
}
|
} */
|
||||||
|
|
||||||
body, .bg-yellow, .callout.callout-warning, .alert-warning, .label-warning, .modal-warning .modal-body {
|
body, .bg-yellow, .callout.callout-warning, .alert-warning, .label-warning, .modal-warning .modal-body {
|
||||||
|
|
||||||
@@ -735,3 +735,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.callout code {
|
||||||
|
background-color: #fff !important;
|
||||||
|
color:#000 !important;
|
||||||
|
}
|
||||||
@@ -14,26 +14,21 @@
|
|||||||
<!-- Buttons -->
|
<!-- Buttons -->
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<button type="button"
|
|
||||||
class="btn btn-default pa-btn pa-btn-delete"
|
|
||||||
style="margin-left:0px;"
|
|
||||||
id="btnDeleteEvents"
|
|
||||||
onclick="askDeleteDeviceEvents()">
|
|
||||||
<?= lang('DevDetail_button_DeleteEvents');?>
|
|
||||||
</button>
|
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-default pa-btn pa-btn-delete"
|
class="btn btn-default pa-btn pa-btn-delete"
|
||||||
style="margin-left:0px;"
|
style="margin-left:0px;"
|
||||||
id="btnDelete"
|
id="btnDelete"
|
||||||
onclick="askDeleteDevice()">
|
onclick="askDeleteDevice()">
|
||||||
<?= lang('DevDetail_button_Delete');?>
|
<i class="fas fa-trash-alt"></i>
|
||||||
|
<?= lang('DevDetail_button_Delete');?>
|
||||||
</button>
|
</button>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-primary pa-btn"
|
class="btn btn-primary pa-btn"
|
||||||
style="margin-left:6px; "
|
style="margin-left:6px; "
|
||||||
id="btnSave"
|
id="btnSave"
|
||||||
onclick="setDeviceData()" >
|
onclick="setDeviceData()" >
|
||||||
<?= lang('DevDetail_button_Save');?>
|
<i class="fas fa-save"></i>
|
||||||
|
<?= lang('DevDetail_button_Save');?>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -75,7 +70,7 @@
|
|||||||
// columns to hide
|
// columns to hide
|
||||||
hiddenFields = ["NEWDEV_devScan", "NEWDEV_devPresentLastScan" ]
|
hiddenFields = ["NEWDEV_devScan", "NEWDEV_devPresentLastScan" ]
|
||||||
// columns to disable - conditional depending if a new dummy device is created
|
// columns to disable - conditional depending if a new dummy device is created
|
||||||
disabledFields = mac == "new" ? ["NEWDEV_devLastNotification", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection"] : ["NEWDEV_devLastNotification", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devMac", "NEWDEV_devLastIP" ];
|
disabledFields = mac == "new" ? ["NEWDEV_devLastNotification", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection"] : ["NEWDEV_devLastNotification", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devMac", "NEWDEV_devLastIP", "NEWDEV_devSyncHubNode" ];
|
||||||
|
|
||||||
// Grouping of fields into categories with associated documentation links
|
// Grouping of fields into categories with associated documentation links
|
||||||
const fieldGroups = {
|
const fieldGroups = {
|
||||||
@@ -83,32 +78,55 @@
|
|||||||
DevDetail_MainInfo_Title: {
|
DevDetail_MainInfo_Title: {
|
||||||
data: ["devMac", "devLastIP", "devName", "devOwner", "devType", "devVendor", "devGroup", "devIcon", "devLocation", "devComments"],
|
data: ["devMac", "devLastIP", "devName", "devOwner", "devType", "devVendor", "devGroup", "devIcon", "devLocation", "devComments"],
|
||||||
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICE_MANAGEMENT.md",
|
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICE_MANAGEMENT.md",
|
||||||
iconClass: "fa fa-pencil"
|
iconClass: "fa fa-pencil",
|
||||||
|
inputGroupClasses: "field-group col-lg-4 col-sm-6 col-xs-12",
|
||||||
|
labelClasses: "col-sm-4 col-xs-12 control-label",
|
||||||
|
inputClasses: "col-sm-8 col-xs-12 input-group"
|
||||||
},
|
},
|
||||||
// Group for session information
|
// Group for session information
|
||||||
DevDetail_SessionInfo_Title: {
|
DevDetail_SessionInfo_Title: {
|
||||||
data: ["devStatus", "devLastConnection", "devFirstConnection"],
|
data: ["devStatus", "devLastConnection", "devFirstConnection"],
|
||||||
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/SESSION_INFO.md",
|
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/SESSION_INFO.md",
|
||||||
iconClass: "fa fa-calendar"
|
iconClass: "fa fa-calendar",
|
||||||
|
inputGroupClasses: "field-group col-lg-4 col-sm-6 col-xs-12",
|
||||||
|
labelClasses: "col-sm-4 col-xs-12 control-label",
|
||||||
|
inputClasses: "col-sm-8 col-xs-12 input-group"
|
||||||
},
|
},
|
||||||
// Group for event and alert settings
|
// Group for event and alert settings
|
||||||
DevDetail_EveandAl_Title: {
|
DevDetail_EveandAl_Title: {
|
||||||
data: ["devAlertEvents", "devAlertDown", "devSkipRepeated"],
|
data: ["devAlertEvents", "devAlertDown", "devSkipRepeated"],
|
||||||
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/NOTIFICATIONS.md",
|
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/NOTIFICATIONS.md",
|
||||||
iconClass: "fa fa-bell"
|
iconClass: "fa fa-bell",
|
||||||
|
inputGroupClasses: "field-group col-lg-4 col-sm-6 col-xs-12",
|
||||||
|
labelClasses: "col-sm-4 col-xs-12 control-label",
|
||||||
|
inputClasses: "col-sm-8 col-xs-12 input-group"
|
||||||
},
|
},
|
||||||
// Group for network details
|
// Group for network details
|
||||||
DevDetail_MainInfo_Network_Title: {
|
DevDetail_MainInfo_Network_Title: {
|
||||||
data: ["devParentMAC", "devParentPort", "devSSID", "devSite"],
|
data: ["devParentMAC", "devParentPort", "devSSID", "devSite", "devSyncHubNode"],
|
||||||
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md",
|
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md",
|
||||||
iconClass: "fa fa-network-wired"
|
iconClass: "fa fa-network-wired",
|
||||||
|
inputGroupClasses: "field-group col-lg-4 col-sm-6 col-xs-12",
|
||||||
|
labelClasses: "col-sm-4 col-xs-12 control-label",
|
||||||
|
inputClasses: "col-sm-8 col-xs-12 input-group"
|
||||||
},
|
},
|
||||||
// Group for other fields like static IP, archived status, etc.
|
// Group for other fields like static IP, archived status, etc.
|
||||||
DevDetail_DisplayFields_Title: {
|
DevDetail_DisplayFields_Title: {
|
||||||
data: ["devStaticIP", "devIsNew", "devFavorite", "devIsArchived"],
|
data: ["devStaticIP", "devIsNew", "devFavorite", "devIsArchived"],
|
||||||
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICE_DISPLAY_SETTINGS.md",
|
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICE_DISPLAY_SETTINGS.md",
|
||||||
iconClass: "fa fa-list-check"
|
iconClass: "fa fa-list-check",
|
||||||
|
inputGroupClasses: "field-group col-lg-4 col-sm-6 col-xs-12",
|
||||||
|
labelClasses: "col-sm-4 col-xs-12 control-label",
|
||||||
|
inputClasses: "col-sm-8 col-xs-12 input-group"
|
||||||
|
},
|
||||||
|
// Group for Custom properties.
|
||||||
|
DevDetail_CustomProperties_Title: {
|
||||||
|
data: ["devCustomProps"],
|
||||||
|
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/CUSTOM_PROPERTIES.md",
|
||||||
|
iconClass: "fa fa-list",
|
||||||
|
inputGroupClasses: "field-group col-lg-12 col-sm-12 col-xs-12",
|
||||||
|
labelClasses: "col-sm-12 col-xs-12 control-label",
|
||||||
|
inputClasses: "col-sm-12 col-xs-12 input-group"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -126,7 +144,7 @@
|
|||||||
|
|
||||||
// Loop over each field group to generate sections for each category
|
// Loop over each field group to generate sections for each category
|
||||||
Object.entries(fieldGroups).forEach(([groupName, obj]) => {
|
Object.entries(fieldGroups).forEach(([groupName, obj]) => {
|
||||||
const groupDiv = $('<div>').addClass('field-group col-lg-4 col-sm-6 col-xs-12'); // Create a div for each group with responsive Bootstrap classes
|
const groupDiv = $('<div>').addClass(obj.inputGroupClasses); // Create a div for each group with responsive Bootstrap classes
|
||||||
|
|
||||||
// Add group title and documentation link
|
// Add group title and documentation link
|
||||||
groupDiv.append(`<h5><i class="${obj.iconClass}"></i> ${getString(groupName)}
|
groupDiv.append(`<h5><i class="${obj.iconClass}"></i> ${getString(groupName)}
|
||||||
@@ -137,7 +155,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</h5>
|
</h5>
|
||||||
<hr>
|
<hr>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
// Filter relevant settings for the current group
|
// Filter relevant settings for the current group
|
||||||
const groupSettings = settings.filter(set => obj.data.includes(set.setKey.replace('NEWDEV_', '')));
|
const groupSettings = settings.filter(set => obj.data.includes(set.setKey.replace('NEWDEV_', '')));
|
||||||
@@ -193,15 +211,15 @@
|
|||||||
|
|
||||||
// Generate the input field HTML
|
// Generate the input field HTML
|
||||||
const inputFormHtml = `<div class="form-group col-xs-12">
|
const inputFormHtml = `<div class="form-group col-xs-12">
|
||||||
<label class="col-sm-4 col-xs-12 control-label"> ${setting.setName}
|
<label id="${setting.setKey}_label" class="${obj.labelClasses}" > ${setting.setName}
|
||||||
<i my-set-key="${setting.setKey}"
|
<i my-set-key="${setting.setKey}"
|
||||||
title="${getString("Settings_Show_Description")}"
|
title="${getString("Settings_Show_Description")}"
|
||||||
class="fa fa-circle-info pointer helpIconSmallTopRight"
|
class="fa fa-circle-info pointer helpIconSmallTopRight"
|
||||||
onclick="showDescriptionPopup(this)">
|
onclick="showDescriptionPopup(this)">
|
||||||
</i>
|
</i>
|
||||||
</label>
|
</label>
|
||||||
<div class="col-sm-8 col-xs-12 input-group">
|
<div class="${obj.inputClasses}">
|
||||||
${generateFormHtml(setting, fieldData.toString())}
|
${generateFormHtml(settingsData, setting, fieldData.toString(), null, null)}
|
||||||
${inlineControl}
|
${inlineControl}
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
@@ -214,8 +232,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// wait until everything is initialized to update icon
|
// wait until everything is initialized to update icons
|
||||||
updateIconPreview();
|
updateAllIconPreviews();
|
||||||
|
|
||||||
// update readonly fields
|
// update readonly fields
|
||||||
handleReadOnly(settingsData, disabledFields);
|
handleReadOnly(settingsData, disabledFields);
|
||||||
@@ -317,64 +335,7 @@
|
|||||||
showModalOK("Info", getString($(e).attr("my-set-key") + '_description'))
|
showModalOK("Info", getString($(e).attr("my-set-key") + '_description'))
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
function askDeleteDeviceEvents () {
|
|
||||||
// Check MAC
|
|
||||||
if (mac == '') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask delete device Events
|
|
||||||
showModalWarning ('<?= lang('DevDetail_button_DeleteEvents');?>', '<?= lang('DevDetail_button_DeleteEvents_Warning');?>',
|
|
||||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteDeviceEvents');
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteDeviceEvents () {
|
|
||||||
// Check MAC
|
|
||||||
if (mac == '') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete device events
|
|
||||||
$.get('php/server/devices.php?action=deleteDeviceEvents&mac='+ mac, function(msg) {
|
|
||||||
showMessage (msg);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Deactivate controls
|
|
||||||
$('#panDetails :input').attr('disabled', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
function askDeleteDevice () {
|
|
||||||
// Check MAC
|
|
||||||
if (mac == '') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask delete device
|
|
||||||
showModalWarning ('Delete Device', 'Are you sure you want to delete this device?<br>(maybe you prefer to archive it)',
|
|
||||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteDevice');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
function deleteDevice () {
|
|
||||||
// Check MAC
|
|
||||||
if (mac == '') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete device
|
|
||||||
$.get('php/server/devices.php?action=deleteDevice&mac='+ mac, function(msg) {
|
|
||||||
showMessage (msg);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Deactivate controls
|
|
||||||
$('#panDetails :input').attr('disabled', true);
|
|
||||||
|
|
||||||
// refresh API
|
|
||||||
updateApi("devices,appevents")
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
function setDeviceData(direction = '', refreshCallback = '') {
|
function setDeviceData(direction = '', refreshCallback = '') {
|
||||||
@@ -396,51 +357,53 @@
|
|||||||
|
|
||||||
showSpinner();
|
showSpinner();
|
||||||
|
|
||||||
// update data to server
|
// Update data to server using POST
|
||||||
$.get('php/server/devices.php?action=setDeviceData&mac='+ $('#NEWDEV_devMac').val()
|
$.post('php/server/devices.php?action=setDeviceData', {
|
||||||
+ '&name=' + encodeURIComponent($('#NEWDEV_devName').val().replace(/'/g, ""))
|
mac: $('#NEWDEV_devMac').val(),
|
||||||
+ '&owner=' + encodeURIComponent($('#NEWDEV_devOwner').val().replace(/'/g, ""))
|
name: encodeURIComponent($('#NEWDEV_devName').val().replace(/'/g, "")),
|
||||||
+ '&type=' + $('#NEWDEV_devType').val()
|
owner: encodeURIComponent($('#NEWDEV_devOwner').val().replace(/'/g, "")),
|
||||||
+ '&vendor=' + encodeURIComponent($('#NEWDEV_devVendor').val().replace(/'/g, ""))
|
type: $('#NEWDEV_devType').val().replace(/'/g, ""),
|
||||||
+ '&icon=' + encodeURIComponent($('#NEWDEV_devIcon').val())
|
vendor: encodeURIComponent($('#NEWDEV_devVendor').val().replace(/'/g, "")),
|
||||||
+ '&favorite=' + ($('#NEWDEV_devFavorite')[0].checked * 1)
|
icon: encodeURIComponent($('#NEWDEV_devIcon').val()),
|
||||||
+ '&group=' + encodeURIComponent($('#NEWDEV_devGroup').val())
|
favorite: ($('#NEWDEV_devFavorite')[0].checked * 1),
|
||||||
+ '&location=' + encodeURIComponent($('#NEWDEV_devLocation').val())
|
group: encodeURIComponent($('#NEWDEV_devGroup').val().replace(/'/g, "")),
|
||||||
+ '&comments=' + encodeURIComponent(encodeSpecialChars($('#NEWDEV_devComments').val()))
|
location: encodeURIComponent($('#NEWDEV_devLocation').val().replace(/'/g, "")),
|
||||||
+ '&networknode=' + $('#NEWDEV_devParentMAC').val()
|
comments: encodeURIComponent(encodeSpecialChars($('#NEWDEV_devComments').val())),
|
||||||
+ '&networknodeport=' + $('#NEWDEV_devParentPort').val()
|
networknode: $('#NEWDEV_devParentMAC').val(),
|
||||||
+ '&ssid=' + $('#NEWDEV_devSSID').val()
|
networknodeport: $('#NEWDEV_devParentPort').val(),
|
||||||
+ '&networksite=' + $('#NEWDEV_devSite').val()
|
ssid: $('#NEWDEV_devSSID').val(),
|
||||||
+ '&staticIP=' + ($('#NEWDEV_devStaticIP')[0].checked * 1)
|
networksite: $('#NEWDEV_devSite').val(),
|
||||||
+ '&scancycle=' + "1"
|
staticIP: ($('#NEWDEV_devStaticIP')[0].checked * 1),
|
||||||
+ '&alertevents=' + ($('#NEWDEV_devAlertEvents')[0].checked * 1)
|
scancycle: "1",
|
||||||
+ '&alertdown=' + ($('#NEWDEV_devAlertDown')[0].checked * 1)
|
alertevents: ($('#NEWDEV_devAlertEvents')[0].checked * 1),
|
||||||
+ '&skiprepeated=' + $('#NEWDEV_devSkipRepeated').val().split(' ')[0]
|
alertdown: ($('#NEWDEV_devAlertDown')[0].checked * 1),
|
||||||
+ '&newdevice=' + ($('#NEWDEV_devIsNew')[0].checked * 1)
|
skiprepeated: $('#NEWDEV_devSkipRepeated').val().split(' ')[0],
|
||||||
+ '&archived=' + ($('#NEWDEV_devIsArchived')[0].checked * 1)
|
newdevice: ($('#NEWDEV_devIsNew')[0].checked * 1),
|
||||||
+ '&devFirstConnection=' + ($('#NEWDEV_devFirstConnection').val())
|
archived: ($('#NEWDEV_devIsArchived')[0].checked * 1),
|
||||||
+ '&devLastConnection=' + ($('#NEWDEV_devLastConnection').val())
|
devFirstConnection: ($('#NEWDEV_devFirstConnection').val()),
|
||||||
+ '&ip=' + ($('#NEWDEV_devLastIP').val())
|
devLastConnection: ($('#NEWDEV_devLastConnection').val()),
|
||||||
+ '&createNew=' + createNew
|
devCustomProps: btoa(JSON.stringify(collectTableData("#NEWDEV_devCustomProps_table"))),
|
||||||
, function(msg) {
|
ip: ($('#NEWDEV_devLastIP').val()),
|
||||||
|
createNew: createNew
|
||||||
showMessage (msg);
|
}, function(msg) {
|
||||||
|
showMessage(msg);
|
||||||
|
|
||||||
// Remove navigation prompt "Are you sure you want to leave..."
|
// Remove navigation prompt "Are you sure you want to leave..."
|
||||||
window.onbeforeunload = null;
|
window.onbeforeunload = null;
|
||||||
somethingChanged = false;
|
somethingChanged = false;
|
||||||
|
|
||||||
// refresh API
|
// refresh API
|
||||||
updateApi("devices,appevents")
|
updateApi("devices,appevents");
|
||||||
|
|
||||||
// Callback fuction
|
// Callback function
|
||||||
if (typeof refreshCallback == 'function') {
|
if (typeof refreshCallback == 'function') {
|
||||||
refreshCallback(direction);
|
refreshCallback(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// everything loaded
|
// Everything loaded
|
||||||
hideSpinner();
|
hideSpinner();
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -228,10 +228,6 @@ function initializeCalendar() {
|
|||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
showSpinner()
|
showSpinner()
|
||||||
} else {
|
} else {
|
||||||
// setTimeout(() => {
|
|
||||||
// updateIconPreview($('#txtIcon'))
|
|
||||||
// }, 500);
|
|
||||||
|
|
||||||
hideSpinner()
|
hideSpinner()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,48 @@
|
|||||||
|
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Delete Events -->
|
||||||
|
<h4 class=""><i class="fa-solid fa-bell"></i>
|
||||||
|
<?= lang("DevDetail_button_DeleteEvents") ?>
|
||||||
|
</h4>
|
||||||
|
<h5 class="">
|
||||||
|
<?= lang("DevDetail_button_DeleteEvents_Warning") ?>
|
||||||
|
</h5>
|
||||||
|
<br>
|
||||||
|
<div style="width:100%; text-align: center; margin-bottom: 50px;">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-default pa-btn pa-btn-delete"
|
||||||
|
style="margin-left:0px;"
|
||||||
|
id="btnDeleteEvents"
|
||||||
|
onclick="askDeleteDeviceEvents()">
|
||||||
|
<?= lang('DevDetail_button_DeleteEvents');?>
|
||||||
|
</button>
|
||||||
|
<br>
|
||||||
|
<div id="wol_output" style="margin-top: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Reset Custom Proprties -->
|
||||||
|
<h4 class=""><i class="fa-solid fa-list"></i>
|
||||||
|
<?= lang("DevDetail_CustomProperties_Title") ?>
|
||||||
|
</h4>
|
||||||
|
<h5 class="">
|
||||||
|
<?= lang("DevDetail_CustomProps_reset_info") ?>
|
||||||
|
</h5>
|
||||||
|
<br>
|
||||||
|
<div style="width:100%; text-align: center; margin-bottom: 50px;">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-default pa-btn pa-btn-delete"
|
||||||
|
style="margin-left:0px;"
|
||||||
|
id="btnDeleteEvents"
|
||||||
|
onclick="askResetDeviceProps()">
|
||||||
|
<?= lang("Gen_Reset") ?>
|
||||||
|
</button>
|
||||||
|
<br>
|
||||||
|
<div id="wol_output" style="margin-top: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- SPEEDTEST -->
|
<!-- SPEEDTEST -->
|
||||||
<?php if ($_REQUEST["mac"] == "Internet") { ?>
|
<?php if ($_REQUEST["mac"] == "Internet") { ?>
|
||||||
<h4 class=""><i class="fa-solid fa-gauge-high"></i>
|
<h4 class=""><i class="fa-solid fa-gauge-high"></i>
|
||||||
@@ -336,6 +378,56 @@
|
|||||||
return devicesList;
|
return devicesList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
function askDeleteDeviceEvents () {
|
||||||
|
// Check MAC
|
||||||
|
if (mac == '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ask delete device Events
|
||||||
|
showModalWarning ('<?= lang('DevDetail_button_DeleteEvents');?>', '<?= lang('DevDetail_button_DeleteEvents_Warning');?>',
|
||||||
|
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteDeviceEvents');
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteDeviceEvents () {
|
||||||
|
// Check MAC
|
||||||
|
if (mac == '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete device events
|
||||||
|
$.get('php/server/devices.php?action=deleteDeviceEvents&mac='+ mac, function(msg) {
|
||||||
|
showMessage (msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
function askResetDeviceProps () {
|
||||||
|
// Check MAC
|
||||||
|
if (mac == '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ask Resert Custom properties
|
||||||
|
showModalWarning ('<?= lang('Gen_Reset');?>', '<?= lang('DevDetail_CustomProps_reset_info');?>',
|
||||||
|
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'resetDeviceProps');
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetDeviceProps () {
|
||||||
|
// Check MAC
|
||||||
|
if (mac == '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
$.get('php/server/devices.php?action=resetDeviceProps&mac='+ mac, function(msg) {
|
||||||
|
showMessage (msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
function internetinfo() {
|
function internetinfo() {
|
||||||
$( "#internetinfooutput" ).empty();
|
$( "#internetinfooutput" ).empty();
|
||||||
|
|||||||
@@ -144,6 +144,10 @@ function main () {
|
|||||||
//initialize the table headers in the correct order
|
//initialize the table headers in the correct order
|
||||||
var availableColumns = getSettingOptions("UI_device_columns").split(",");
|
var availableColumns = getSettingOptions("UI_device_columns").split(",");
|
||||||
headersDefaultOrder = availableColumns.map(val => getString(val));
|
headersDefaultOrder = availableColumns.map(val => getString(val));
|
||||||
|
|
||||||
|
console.log(headersDefaultOrder);
|
||||||
|
|
||||||
|
|
||||||
var selectedColumns = JSON.parse(getSetting("UI_device_columns").replace(/'/g, '"'));
|
var selectedColumns = JSON.parse(getSetting("UI_device_columns").replace(/'/g, '"'));
|
||||||
|
|
||||||
// generate default order lists of given length
|
// generate default order lists of given length
|
||||||
@@ -181,6 +185,9 @@ function main () {
|
|||||||
// mapping the default order to the user specified one
|
// mapping the default order to the user specified one
|
||||||
function mapIndx(oldIndex)
|
function mapIndx(oldIndex)
|
||||||
{
|
{
|
||||||
|
// console.log(oldIndex);
|
||||||
|
// console.log(tableColumnOrder);
|
||||||
|
|
||||||
for(i=0;i<tableColumnOrder.length;i++)
|
for(i=0;i<tableColumnOrder.length;i++)
|
||||||
{
|
{
|
||||||
if(tableColumnOrder[i] == oldIndex)
|
if(tableColumnOrder[i] == oldIndex)
|
||||||
@@ -289,47 +296,6 @@ function renderInfoboxes(customData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Define a function to filter data based on deviceStatus
|
|
||||||
function filterDataByStatus(data, status) {
|
|
||||||
return data.filter(function(item) {
|
|
||||||
switch (status) {
|
|
||||||
case 'my_devices':
|
|
||||||
to_display = getSetting('UI_MY_DEVICES');
|
|
||||||
|
|
||||||
let result = true;
|
|
||||||
|
|
||||||
if (!to_display.includes('down') && item.devPresentLastScan === 0 && item.devAlertDown !== 0) {
|
|
||||||
result = false;
|
|
||||||
} else if (!to_display.includes('new') && item.devIsNew === 1) {
|
|
||||||
result = false;
|
|
||||||
} else if (!to_display.includes('archived') && item.devIsArchived === 1) {
|
|
||||||
result = false;
|
|
||||||
} else if (!to_display.includes('offline') && item.devPresentLastScan === 0) {
|
|
||||||
result = false;
|
|
||||||
} else if (!to_display.includes('online') && item.devPresentLastScan === 1) {
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result; // Include all items for 'my_devices' status
|
|
||||||
case 'connected':
|
|
||||||
return item.devPresentLastScan === 1;
|
|
||||||
case 'favorites':
|
|
||||||
return item.devFavorite === 1;
|
|
||||||
case 'new':
|
|
||||||
return item.devIsNew === 1;
|
|
||||||
case 'offline':
|
|
||||||
return item.devPresentLastScan === 0;
|
|
||||||
case 'down':
|
|
||||||
return (item.devPresentLastScan === 0 && item.devAlertDown !== 0);
|
|
||||||
case 'archived':
|
|
||||||
return item.devIsArchived === 1;
|
|
||||||
default:
|
|
||||||
return true; // Include all items for unknown statuses
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Map column index to column name for GraphQL query
|
// Map column index to column name for GraphQL query
|
||||||
function mapColumnIndexToFieldName(index, tableColumnVisible) {
|
function mapColumnIndexToFieldName(index, tableColumnVisible) {
|
||||||
// the order is important, don't change it!
|
// the order is important, don't change it!
|
||||||
@@ -359,7 +325,8 @@ function mapColumnIndexToFieldName(index, tableColumnVisible) {
|
|||||||
"devSSID",
|
"devSSID",
|
||||||
"devSourcePlugin",
|
"devSourcePlugin",
|
||||||
"devPresentLastScan",
|
"devPresentLastScan",
|
||||||
"devAlertDown"
|
"devAlertDown",
|
||||||
|
"devCustomProps"
|
||||||
];
|
];
|
||||||
|
|
||||||
// console.log("OrderBy: " + columnNames[tableColumnOrder[index]]);
|
// console.log("OrderBy: " + columnNames[tableColumnOrder[index]]);
|
||||||
@@ -369,6 +336,7 @@ function mapColumnIndexToFieldName(index, tableColumnVisible) {
|
|||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
|
// Initializes the main devices list datatable
|
||||||
function initializeDatatable (status) {
|
function initializeDatatable (status) {
|
||||||
|
|
||||||
if(!status)
|
if(!status)
|
||||||
@@ -469,6 +437,7 @@ function initializeDatatable (status) {
|
|||||||
devStatus
|
devStatus
|
||||||
devParentChildrenCount
|
devParentChildrenCount
|
||||||
devIpLong
|
devIpLong
|
||||||
|
devCustomProps
|
||||||
}
|
}
|
||||||
count
|
count
|
||||||
}
|
}
|
||||||
@@ -535,7 +504,8 @@ function initializeDatatable (status) {
|
|||||||
device.devSSID || "",
|
device.devSSID || "",
|
||||||
device.devSourcePlugin || "",
|
device.devSourcePlugin || "",
|
||||||
device.devPresentLastScan || "",
|
device.devPresentLastScan || "",
|
||||||
device.devAlertDown || ""
|
device.devAlertDown || "",
|
||||||
|
device.devCustomProps || ""
|
||||||
];
|
];
|
||||||
|
|
||||||
const newRow = [];
|
const newRow = [];
|
||||||
@@ -653,6 +623,17 @@ function initializeDatatable (status) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Custom Properties
|
||||||
|
{targets: [mapIndx(26)],
|
||||||
|
'createdCell': function (td, cellData, rowData, row, col) {
|
||||||
|
if (!emptyArr.includes(cellData)){
|
||||||
|
$(td).html (`<span>${renderCustomProps(cellData, rowData[mapIndx(11)])}<span>`);
|
||||||
|
} else {
|
||||||
|
$(td).html ('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Favorite
|
// Favorite
|
||||||
{targets: [mapIndx(4)],
|
{targets: [mapIndx(4)],
|
||||||
'createdCell': function (td, cellData, rowData, row, col) {
|
'createdCell': function (td, cellData, rowData, row, col) {
|
||||||
@@ -771,6 +752,11 @@ function initializeDatatable (status) {
|
|||||||
|
|
||||||
hideSpinner();
|
hideSpinner();
|
||||||
|
|
||||||
|
},
|
||||||
|
createdRow: function(row, data, dataIndex) {
|
||||||
|
// add devMac to the table row
|
||||||
|
$(row).attr('my-devMac', data[mapIndx(11)]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -782,9 +768,7 @@ function initializeDatatable (status) {
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
function handleLoadingDialog(needsReload = false)
|
function handleLoadingDialog(needsReload = false)
|
||||||
{
|
{
|
||||||
|
// console.log(`needsReload: ${needsReload}`);
|
||||||
// console.log('needsReload:');
|
|
||||||
// console.log(needsReload);
|
|
||||||
|
|
||||||
$.get('/php/server/query_logs.php?file=execution_queue.log&nocache=' + Date.now(), function(data) {
|
$.get('/php/server/query_logs.php?file=execution_queue.log&nocache=' + Date.now(), function(data) {
|
||||||
|
|
||||||
@@ -830,34 +814,93 @@ function multiEditDevices()
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Function collects shown devices from the DataTable
|
// Function collects shown devices from the DataTable
|
||||||
function getMacsOfShownDevices() {
|
function getMacsOfShownDevices() {
|
||||||
|
rows = $('#tableDevices')[0].rows;
|
||||||
rows = $('#tableDevices')[0].rows
|
macs = [];
|
||||||
macs = []
|
|
||||||
|
|
||||||
// var devicesDataTableData = $('#tableDevices').dataTable().fnGetData();
|
// var devicesDataTableData = $('#tableDevices').dataTable().fnGetData();
|
||||||
var devicesDataTableData = $('#tableDevices').DataTable().rows({ selected: false, page: 'current' }).data().toArray();
|
var devicesDataTableData = $('#tableDevices').DataTable().rows({ selected: false, page: 'current' }).data().toArray();
|
||||||
|
|
||||||
console.log(devicesDataTableData);
|
console.log(devicesDataTableData);
|
||||||
|
|
||||||
|
|
||||||
var selectedDevices = [];
|
var selectedDevices = [];
|
||||||
|
|
||||||
// first row is the heading, skip
|
// first row is the heading, skip
|
||||||
for (var i = 1; i < rows.length; i++) {
|
for (var i = 1; i < rows.length; i++) {
|
||||||
|
var rowIndex = rows[i]._DT_RowIndex;
|
||||||
|
|
||||||
// console.log(rows[i]._DT_RowIndex);
|
// Ensure the rowIndex is valid and within bounds of devicesDataTableData
|
||||||
|
if (rowIndex >= 0 && rowIndex < devicesDataTableData.length) {
|
||||||
selectedDevices.push(devicesDataTableData[rows[i]._DT_RowIndex]);
|
selectedDevices.push(devicesDataTableData[rowIndex]);
|
||||||
|
} else {
|
||||||
|
console.log(`Invalid rowIndex: ${rowIndex} at row ${i}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var j = 0; j < selectedDevices.length; j++) {
|
for (var j = 0; j < selectedDevices.length; j++) {
|
||||||
macs.push(selectedDevices[j][mapIndx(11)]); // mapIndx(11) == MAC
|
// Ensure that selectedDevices[j] is not undefined
|
||||||
|
if (selectedDevices[j]) {
|
||||||
|
macs.push(selectedDevices[j][mapIndx(11)]); // mapIndx(11) == MAC
|
||||||
|
} else {
|
||||||
|
console.log(`selectedDevices[${j}] is undefined`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return macs;
|
return macs;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Handle custom actions/properties on a device
|
||||||
|
function renderCustomProps(custProps, mac) {
|
||||||
|
// Decode and parse the custom properties
|
||||||
|
|
||||||
|
if (!isBase64(custProps)) {
|
||||||
|
|
||||||
|
console.error(`Unable to decode CustomProps for ${mac}`);
|
||||||
|
console.error(custProps);
|
||||||
|
|
||||||
|
} else{
|
||||||
|
const props = JSON.parse(atob(custProps));
|
||||||
|
let html = "";
|
||||||
|
|
||||||
|
props.forEach((propGroup, index) => {
|
||||||
|
const propMap = Object.fromEntries(
|
||||||
|
propGroup.map(prop => Object.entries(prop)[0]) // Convert array of objects to key-value pairs
|
||||||
|
);
|
||||||
|
|
||||||
|
if (propMap["CUSTPROP_show"] === true) { // Render if visible
|
||||||
|
let onClickEvent = "";
|
||||||
|
|
||||||
|
switch (propMap["CUSTPROP_type"]) {
|
||||||
|
case "show_notes":
|
||||||
|
onClickEvent = `showModalOK('${propMap["CUSTPROP_name"]}','${propMap["CUSTPROP_notes"]}')`;
|
||||||
|
break;
|
||||||
|
case "link":
|
||||||
|
onClickEvent = `window.location.href='${propMap["CUSTPROP_args"]}';`;
|
||||||
|
break;
|
||||||
|
case "link_new_tab":
|
||||||
|
onClickEvent = `openInNewTab('${propMap["CUSTPROP_args"]}')`;
|
||||||
|
break;
|
||||||
|
case "run_plugin":
|
||||||
|
onClickEvent = `alert('Not implemented')`;
|
||||||
|
break;
|
||||||
|
case "delete_dev":
|
||||||
|
onClickEvent = `askDelDevDTInline('${mac}')`;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += `<div class="pointer devicePropAction" onclick="${onClickEvent}" title="${propMap["CUSTPROP_name"]} ${propMap["CUSTPROP_args"]}"> ${atob(propMap["CUSTPROP_icon"])} </div>`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Error, check browser Console log"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Update cache with shown devices before navigating away
|
// Update cache with shown devices before navigating away
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ function cacheSettings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Get a setting value by key
|
// Get a setting options value by key
|
||||||
function getSettingOptions (key) {
|
function getSettingOptions (key) {
|
||||||
|
|
||||||
// handle initial load to make sure everything is set-up and cached
|
// handle initial load to make sure everything is set-up and cached
|
||||||
@@ -353,6 +353,30 @@ function getLangCode() {
|
|||||||
// String utilities
|
// String utilities
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ----------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Replaces double quotes within single-quoted strings, then converts all single quotes to double quotes,
|
||||||
|
* while preserving the intended structure.
|
||||||
|
*
|
||||||
|
* @param {string} inputString - The input string to process.
|
||||||
|
* @returns {string} - The processed string with transformations applied.
|
||||||
|
*/
|
||||||
|
function processQuotes(inputString) {
|
||||||
|
// Step 1: Replace double quotes within single-quoted strings
|
||||||
|
let tempString = inputString.replace(/'([^']*?)'/g, (match, p1) => {
|
||||||
|
const escapedContent = p1.replace(/"/g, '_escaped_double_quote_'); // Temporarily replace double quotes
|
||||||
|
return `'${escapedContent}'`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Step 2: Replace all single quotes with double quotes
|
||||||
|
tempString = tempString.replace(/'/g, '"');
|
||||||
|
|
||||||
|
// Step 3: Restore escaped double quotes
|
||||||
|
const processedString = tempString.replace(/_escaped_double_quote_/g, "'");
|
||||||
|
|
||||||
|
return processedString;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
function jsonSyntaxHighlight(json) {
|
function jsonSyntaxHighlight(json) {
|
||||||
if (typeof json != 'string') {
|
if (typeof json != 'string') {
|
||||||
@@ -386,6 +410,14 @@ function isValidBase64(str) {
|
|||||||
return invalidCharacters === '';
|
return invalidCharacters === '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Utility function to check if the value is already Base64
|
||||||
|
function isBase64(value) {
|
||||||
|
const base64Regex =
|
||||||
|
/^(?:[A-Za-z0-9+\/]{4})*?(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/;
|
||||||
|
return base64Regex.test(value);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
function isValidJSON(jsonString) {
|
function isValidJSON(jsonString) {
|
||||||
try {
|
try {
|
||||||
@@ -431,6 +463,8 @@ function utf8ToBase64(str) {
|
|||||||
// General utilities
|
// General utilities
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// check if JSON object
|
// check if JSON object
|
||||||
function isJsonObject(value) {
|
function isJsonObject(value) {
|
||||||
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
||||||
|
|||||||
70
front/js/device.js
Executable file
@@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
function askDeleteDevice() {
|
||||||
|
// Check MAC
|
||||||
|
if (mac == '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ask delete device
|
||||||
|
showModalWarning(
|
||||||
|
getString("DevDetail_button_Delete"),
|
||||||
|
getString("DevDetail_button_Delete_ask"),
|
||||||
|
getString('Gen_Cancel'),
|
||||||
|
getString('Gen_Delete'),
|
||||||
|
'deleteDevice');
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
function askDelDevDTInline(mac) {
|
||||||
|
// Check MAC
|
||||||
|
if (mac == '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
showModalWarning(
|
||||||
|
getString("DevDetail_button_Delete"),
|
||||||
|
getString("DevDetail_button_Delete_ask"),
|
||||||
|
getString('Gen_Cancel'),
|
||||||
|
getString('Gen_Delete'),
|
||||||
|
() => deleteDeviceByMac(mac))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
function deleteDevice() {
|
||||||
|
// Check MAC
|
||||||
|
if (mac == '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete device
|
||||||
|
$.get('php/server/devices.php?action=deleteDevice&mac=' + mac, function (msg) {
|
||||||
|
showMessage(msg);
|
||||||
|
});
|
||||||
|
|
||||||
|
// refresh API
|
||||||
|
updateApi("devices,appevents")
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
function deleteDeviceByMac(mac) {
|
||||||
|
// Check MAC
|
||||||
|
if (mac == '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// alert(mac)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// Delete device
|
||||||
|
$.get('php/server/devices.php?action=deleteDevice&mac=' + mac, function (msg) {
|
||||||
|
showMessage(msg);
|
||||||
|
});
|
||||||
|
|
||||||
|
// refresh API
|
||||||
|
updateApi("devices,appevents")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -65,7 +65,8 @@ function showModalWarning(
|
|||||||
message,
|
message,
|
||||||
btnCancel = getString("Gen_Cancel"),
|
btnCancel = getString("Gen_Cancel"),
|
||||||
btnOK = getString("Gen_Okay"),
|
btnOK = getString("Gen_Okay"),
|
||||||
callbackFunction = null
|
callbackFunction = null,
|
||||||
|
triggeredBy = null
|
||||||
) {
|
) {
|
||||||
// set captions
|
// set captions
|
||||||
$("#modal-warning-title").html(title);
|
$("#modal-warning-title").html(title);
|
||||||
@@ -77,6 +78,10 @@ function showModalWarning(
|
|||||||
modalCallbackFunction = callbackFunction;
|
modalCallbackFunction = callbackFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (triggeredBy != null) {
|
||||||
|
$('#'+prefix).attr("data-myparam-triggered-by", triggeredBy)
|
||||||
|
}
|
||||||
|
|
||||||
// Show modal
|
// Show modal
|
||||||
$("#modal-warning").modal("show");
|
$("#modal-warning").modal("show");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,14 +191,6 @@ function isSHA256(value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
// Utility function to check if the value is already Base64
|
|
||||||
function isBase64(value) {
|
|
||||||
const base64Regex =
|
|
||||||
/^(?:[A-Za-z0-9+\/]{4})*?(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/;
|
|
||||||
return base64Regex.test(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Validation
|
// Validation
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
@@ -245,6 +237,68 @@ function settingsCollectedCorrectly(settingsArray, settingsJSON_DB) {
|
|||||||
// Manipulating Editable List options
|
// Manipulating Editable List options
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// Add row to datatable
|
||||||
|
function addDataTableRow(el)
|
||||||
|
{
|
||||||
|
alert("a")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// Clone datatable row
|
||||||
|
function cloneDataTableRow(el){
|
||||||
|
|
||||||
|
console.log(el);
|
||||||
|
|
||||||
|
const id = "NEWDEV_devCustomProps_table"; // Your table ID
|
||||||
|
const table = $('#'+id).DataTable();
|
||||||
|
|
||||||
|
|
||||||
|
// Get the 'my-index' attribute from the closest tr element
|
||||||
|
const myIndex = parseInt($(el).closest("tr").attr("my-index"));
|
||||||
|
|
||||||
|
// Find the row in the table with the matching 'my-index'
|
||||||
|
const row = table.rows().nodes().to$().filter(`[my-index="${myIndex}"]`).first().get(0);
|
||||||
|
|
||||||
|
// Clone the row (including its data and controls)
|
||||||
|
let clonedRow = $(row).clone(true, true); // The true arguments copy the data and event handlers
|
||||||
|
|
||||||
|
|
||||||
|
$(clonedRow).attr("my-index",table.rows().count())
|
||||||
|
|
||||||
|
|
||||||
|
console.log(clonedRow);
|
||||||
|
|
||||||
|
|
||||||
|
// Add the cloned row to the DataTable
|
||||||
|
table.row.add(clonedRow[0]).draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// Remove current datatable row
|
||||||
|
function removeDataTableRow(el) {
|
||||||
|
console.log(el);
|
||||||
|
|
||||||
|
const id = "NEWDEV_devCustomProps_table"; // Your table ID
|
||||||
|
const table = $('#'+id).DataTable();
|
||||||
|
|
||||||
|
if(table.rows().count() > 1)
|
||||||
|
{
|
||||||
|
// Get the 'my-index' attribute from the closest tr element
|
||||||
|
const myIndex = parseInt($(el).closest("tr").attr("my-index"));
|
||||||
|
|
||||||
|
// Find the row in the table with the matching 'my-index'
|
||||||
|
const row = table.rows().nodes().to$().filter(`[my-index="${myIndex}"]`).first().get(0);
|
||||||
|
|
||||||
|
// Remove the row from the DataTable
|
||||||
|
table.row(row).remove().draw();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
showMessage (getString("CustProps_cant_remove"), 3000, "modal_red");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
// Add item to list
|
// Add item to list
|
||||||
function addList(element, clearInput = true) {
|
function addList(element, clearInput = true) {
|
||||||
@@ -551,7 +605,7 @@ function overrideToggle(element) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
// Generate options or set options based on the provided parameters
|
// Generate options or set options based on the provided parameters
|
||||||
function generateOptionsOrSetOptions(
|
function generateOptionsOrSetOptions(
|
||||||
setKey,
|
setKey,
|
||||||
@@ -559,13 +613,20 @@ function generateOptionsOrSetOptions(
|
|||||||
placeholder, // ID of the HTML element where dropdown should be rendered (will be replaced)
|
placeholder, // ID of the HTML element where dropdown should be rendered (will be replaced)
|
||||||
processDataCallback, // Callback function to generate entries based on options
|
processDataCallback, // Callback function to generate entries based on options
|
||||||
targetField, // Target field or element where selected value should be applied or updated
|
targetField, // Target field or element where selected value should be applied or updated
|
||||||
transformers = [] // Transformers to be applied to the values
|
transformers = [], // Transformers to be applied to the values
|
||||||
|
overrideOptions = null // override options if available
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// console.log(setKey);
|
// console.log(setKey);
|
||||||
|
|
||||||
|
// console.log(overrideOptions);
|
||||||
|
// console.log( getSettingOptions(setKey));
|
||||||
|
// console.log( setKey);
|
||||||
|
|
||||||
// NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
|
// NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
|
||||||
options = arrayToObject(createArray(getSettingOptions(setKey)))
|
options = arrayToObject(createArray(overrideOptions ? overrideOptions : getSettingOptions(setKey)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Call to render lists
|
// Call to render lists
|
||||||
renderList(
|
renderList(
|
||||||
@@ -655,6 +716,7 @@ const handleElementOptions = (setKey, elementOptions, transformers, val) => {
|
|||||||
let onChange = "console.log('onChange - Not implemented');";
|
let onChange = "console.log('onChange - Not implemented');";
|
||||||
let customParams = "";
|
let customParams = "";
|
||||||
let customId = "";
|
let customId = "";
|
||||||
|
let columns = [];
|
||||||
|
|
||||||
|
|
||||||
elementOptions.forEach((option) => {
|
elementOptions.forEach((option) => {
|
||||||
@@ -708,6 +770,9 @@ const handleElementOptions = (setKey, elementOptions, transformers, val) => {
|
|||||||
if (option.customId) {
|
if (option.customId) {
|
||||||
customId = option.customId;
|
customId = option.customId;
|
||||||
}
|
}
|
||||||
|
if (option.columns) {
|
||||||
|
columns = option.columns;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (transformers.includes("sha256")) {
|
if (transformers.includes("sha256")) {
|
||||||
@@ -730,7 +795,8 @@ const handleElementOptions = (setKey, elementOptions, transformers, val) => {
|
|||||||
onClick,
|
onClick,
|
||||||
onChange,
|
onChange,
|
||||||
customParams,
|
customParams,
|
||||||
customId
|
customId,
|
||||||
|
columns
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -863,7 +929,7 @@ function genListWithInputSet(options, valuesArray, targetField, transformers, pl
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// Generate the form control for setting
|
// Generate the form control for setting
|
||||||
function generateFormHtml(set, overrideValue) {
|
function generateFormHtml(settingsData, set, overrideValue, overrideOptions, originalSetKey) {
|
||||||
let inputHtml = '';
|
let inputHtml = '';
|
||||||
|
|
||||||
|
|
||||||
@@ -871,14 +937,17 @@ function generateFormHtml(set, overrideValue) {
|
|||||||
const setKey = set['setKey'];
|
const setKey = set['setKey'];
|
||||||
const setType = set['setType'];
|
const setType = set['setType'];
|
||||||
|
|
||||||
|
// if (setKey == '') {
|
||||||
|
|
||||||
// console.log(setType);
|
// console.log(setType);
|
||||||
// console.log(setKey);
|
// console.log(setKey);
|
||||||
// console.log(overrideValue);
|
// console.log(overrideValue);
|
||||||
// console.log(inVal);
|
// console.log(inVal);
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
// Parse the setType JSON string
|
// Parse the setType JSON string
|
||||||
const setTypeObject = JSON.parse(setType.replace(/'/g, '"'));
|
const setTypeObject = JSON.parse(processQuotes(setType))
|
||||||
const dataType = setTypeObject.dataType;
|
const dataType = setTypeObject.dataType;
|
||||||
const elements = setTypeObject.elements || [];
|
const elements = setTypeObject.elements || [];
|
||||||
|
|
||||||
@@ -903,14 +972,22 @@ function generateFormHtml(set, overrideValue) {
|
|||||||
onClick,
|
onClick,
|
||||||
onChange,
|
onChange,
|
||||||
customParams,
|
customParams,
|
||||||
customId
|
customId,
|
||||||
|
columns
|
||||||
} = handleElementOptions(setKey, elementOptions, transformers, inVal);
|
} = handleElementOptions(setKey, elementOptions, transformers, inVal);
|
||||||
|
|
||||||
// Override value
|
// Override value
|
||||||
const val = valRes;
|
let val = valRes;
|
||||||
|
|
||||||
// console.log(val);
|
// if (setKey == '') {
|
||||||
|
|
||||||
|
// console.log(setType);
|
||||||
|
// console.log(setKey);
|
||||||
|
// console.log(overrideValue);
|
||||||
|
// console.log(inVal);
|
||||||
|
// console.log(val);
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
// Generate HTML based on elementType
|
// Generate HTML based on elementType
|
||||||
switch (elementType) {
|
switch (elementType) {
|
||||||
@@ -921,20 +998,21 @@ function generateFormHtml(set, overrideValue) {
|
|||||||
inputHtml += `<select onChange="settingsChanged();${onChange}"
|
inputHtml += `<select onChange="settingsChanged();${onChange}"
|
||||||
my-data-type="${dataType}"
|
my-data-type="${dataType}"
|
||||||
my-editable="${editable}"
|
my-editable="${editable}"
|
||||||
class="form-control ${addCss}"
|
class="form-control ${addCss} ${cssClasses}"
|
||||||
name="${setKey}"
|
name="${setKey}"
|
||||||
id="${setKey}"
|
id="${setKey}"
|
||||||
my-customparams="${customParams}"
|
my-customparams="${customParams}"
|
||||||
my-customid="${customId}"
|
my-customid="${customId}"
|
||||||
|
my-originalSetKey="${originalSetKey}"
|
||||||
${multi}>
|
${multi}>
|
||||||
<option value="" id="${setKey + "_temp_"}"></option>
|
<option value="" id="${setKey + "_temp_"}"></option>
|
||||||
</select>`;
|
</select>`;
|
||||||
|
|
||||||
generateOptionsOrSetOptions(setKey, createArray(val), `${setKey}_temp_`, generateOptions, null, transformers);
|
generateOptionsOrSetOptions(setKey, createArray(val), `${setKey}_temp_`, generateOptions, null, transformers, overrideOptions);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'input':
|
case 'input':
|
||||||
const checked = val === 'True' || val === '1' ? 'checked' : '';
|
const checked = val === 'True' || val === 'true' || val === '1' ? 'checked' : '';
|
||||||
const inputClass = inputType === 'checkbox' ? 'checkbox' : 'form-control';
|
const inputClass = inputType === 'checkbox' ? 'checkbox' : 'form-control';
|
||||||
|
|
||||||
inputHtml += `<input
|
inputHtml += `<input
|
||||||
@@ -943,6 +1021,7 @@ function generateFormHtml(set, overrideValue) {
|
|||||||
my-data-type="${dataType}"
|
my-data-type="${dataType}"
|
||||||
my-customparams="${customParams}"
|
my-customparams="${customParams}"
|
||||||
my-customid="${customId}"
|
my-customid="${customId}"
|
||||||
|
my-originalSetKey="${originalSetKey}"
|
||||||
id="${setKey}${suffix}"
|
id="${setKey}${suffix}"
|
||||||
type="${inputType}"
|
type="${inputType}"
|
||||||
value="${val}"
|
value="${val}"
|
||||||
@@ -957,6 +1036,7 @@ function generateFormHtml(set, overrideValue) {
|
|||||||
class="btn btn-primary ${cssClasses}"
|
class="btn btn-primary ${cssClasses}"
|
||||||
my-customparams="${customParams}"
|
my-customparams="${customParams}"
|
||||||
my-customid="${customId}"
|
my-customid="${customId}"
|
||||||
|
my-originalSetKey="${originalSetKey}"
|
||||||
my-input-from="${sourceIds}"
|
my-input-from="${sourceIds}"
|
||||||
my-input-to="${setKey}"
|
my-input-to="${setKey}"
|
||||||
onclick="${onClick}">
|
onclick="${onClick}">
|
||||||
@@ -969,6 +1049,7 @@ function generateFormHtml(set, overrideValue) {
|
|||||||
class="form-control input"
|
class="form-control input"
|
||||||
my-customparams="${customParams}"
|
my-customparams="${customParams}"
|
||||||
my-customid="${customId}"
|
my-customid="${customId}"
|
||||||
|
my-originalSetKey="${originalSetKey}"
|
||||||
my-data-type="${dataType}"
|
my-data-type="${dataType}"
|
||||||
id="${setKey}"
|
id="${setKey}"
|
||||||
${readOnly}>${val}</textarea>`;
|
${readOnly}>${val}</textarea>`;
|
||||||
@@ -979,10 +1060,116 @@ function generateFormHtml(set, overrideValue) {
|
|||||||
class="${cssClasses}"
|
class="${cssClasses}"
|
||||||
my-data-type="${dataType}"
|
my-data-type="${dataType}"
|
||||||
my-customparams="${customParams}"
|
my-customparams="${customParams}"
|
||||||
my-customid="${customId}">
|
my-customid="${customId}"
|
||||||
${getString(getStringKey)}
|
my-originalSetKey="${originalSetKey}"
|
||||||
|
onclick="${onClick}">
|
||||||
|
${getString(getStringKey)}${placeholder}
|
||||||
</span>`;
|
</span>`;
|
||||||
break;
|
break;
|
||||||
|
case 'datatable':
|
||||||
|
|
||||||
|
const tableId = `${setKey}_table`;
|
||||||
|
let datatableHtml = `<table id="${tableId}" class="table table-striped">`;
|
||||||
|
|
||||||
|
// Dynamic array creation
|
||||||
|
let emptyVal = [];
|
||||||
|
|
||||||
|
let columnSettings = [];
|
||||||
|
|
||||||
|
// Generate table headers
|
||||||
|
datatableHtml += '<thead><tr>';
|
||||||
|
|
||||||
|
columns.forEach(column => {
|
||||||
|
let columnSetting = getSetObject(settingsData, column.settingKey) || {};
|
||||||
|
|
||||||
|
datatableHtml += `<th>${columnSetting.setName}</th>`;
|
||||||
|
|
||||||
|
if(column.typeOverride)
|
||||||
|
{
|
||||||
|
columnSetting["setType"] = JSON.stringify(column.typeOverride);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(column.optionsOverride)
|
||||||
|
{
|
||||||
|
if (column.optionsOverride.startsWith("setting.")) {
|
||||||
|
columnSetting["setOptions"] = getSetting(column.optionsOverride.replace("setting.",""));
|
||||||
|
} else {
|
||||||
|
columnSetting["setOptions"] = column.optionsOverride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
columnSettings.push(columnSetting)
|
||||||
|
|
||||||
|
// helper for if val is empty
|
||||||
|
emptyVal.push('');
|
||||||
|
});
|
||||||
|
datatableHtml += '</tr></thead>';
|
||||||
|
|
||||||
|
// Generate table body
|
||||||
|
datatableHtml += '<tbody>';
|
||||||
|
|
||||||
|
if(val.length > 0 && isBase64(val))
|
||||||
|
{
|
||||||
|
val = atob(val)
|
||||||
|
// console.log(val);
|
||||||
|
val = JSON.parse(val)
|
||||||
|
}else{
|
||||||
|
// init empty
|
||||||
|
val = [emptyVal]
|
||||||
|
}
|
||||||
|
|
||||||
|
let index = 0;
|
||||||
|
val.forEach(rowData => {
|
||||||
|
datatableHtml += `<tr my-index="${index}">`;
|
||||||
|
|
||||||
|
let j = 0;
|
||||||
|
columnSettings.forEach(set => {
|
||||||
|
// Extract the value for the current column based on the new structure
|
||||||
|
let columnOverrideValue = rowData[j] && Object.values(rowData[j])[0];
|
||||||
|
|
||||||
|
if(columnOverrideValue == undefined)
|
||||||
|
{
|
||||||
|
columnOverrideValue = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create unique key to prevent dropdown data duplication
|
||||||
|
const oldKey = set["setKey"];
|
||||||
|
set["setKey"] = oldKey + "_" + index;
|
||||||
|
|
||||||
|
// Generate the cell HTML using the extracted value
|
||||||
|
const cellHtml = generateFormHtml(
|
||||||
|
settingsData,
|
||||||
|
set,
|
||||||
|
columnOverrideValue.toString(),
|
||||||
|
set["setOptions"],
|
||||||
|
oldKey
|
||||||
|
);
|
||||||
|
datatableHtml += `<td> <div class="input-group"> ${cellHtml} </div></td>`;
|
||||||
|
|
||||||
|
// Restore the original key
|
||||||
|
set["setKey"] = oldKey;
|
||||||
|
|
||||||
|
j++;
|
||||||
|
});
|
||||||
|
datatableHtml += '</tr>';
|
||||||
|
index++;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
datatableHtml += '</tbody></table>';
|
||||||
|
|
||||||
|
inputHtml += datatableHtml;
|
||||||
|
|
||||||
|
// Initialize DataTable with jQuery
|
||||||
|
$(document).ready(() => {
|
||||||
|
$(`#${tableId}`).DataTable({
|
||||||
|
ordering: false, // Disables sorting on all columns
|
||||||
|
searching: false, // Disables the search box
|
||||||
|
dom: "<'top'rt><'bottom'ipl>", // Move length dropdown to the bottom
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.warn(`🟥 Unknown element type: ${elementType}`);
|
console.warn(`🟥 Unknown element type: ${elementType}`);
|
||||||
@@ -992,10 +1179,6 @@ function generateFormHtml(set, overrideValue) {
|
|||||||
// Generate event HTML if applicable
|
// Generate event HTML if applicable
|
||||||
let eventsHtml = '';
|
let eventsHtml = '';
|
||||||
|
|
||||||
// console.log(setTypeObject);
|
|
||||||
|
|
||||||
// console.log(set);
|
|
||||||
|
|
||||||
const eventsList = createArray(set['setEvents']);
|
const eventsList = createArray(set['setEvents']);
|
||||||
// inline buttons events
|
// inline buttons events
|
||||||
|
|
||||||
@@ -1019,4 +1202,68 @@ function generateFormHtml(set, overrideValue) {
|
|||||||
return inputHtml + eventsHtml;
|
return inputHtml + eventsHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// Return the setting object by setKey
|
||||||
|
function getSetObject(settingsData, setKey) {
|
||||||
|
|
||||||
|
found = false;
|
||||||
|
result = ""
|
||||||
|
|
||||||
|
settingsData.forEach(function(set) {
|
||||||
|
|
||||||
|
if (set.setKey == setKey) {
|
||||||
|
// console.log(set);
|
||||||
|
|
||||||
|
result = set;
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if(result == "")
|
||||||
|
{
|
||||||
|
console.error(settingsData);
|
||||||
|
console.error(`Setting not found: ${setKey}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------
|
||||||
|
// Collect DataTable data
|
||||||
|
function collectTableData(tableSelector) {
|
||||||
|
const table = $(tableSelector).DataTable();
|
||||||
|
|
||||||
|
let tableData = [];
|
||||||
|
|
||||||
|
table.rows().every(function () {
|
||||||
|
const rowData = [];
|
||||||
|
const cells = $(this.node()).find('td');
|
||||||
|
|
||||||
|
cells.each((index, cell) => {
|
||||||
|
const input = $(cell).find('input, select, textarea');
|
||||||
|
|
||||||
|
if (input.length) {
|
||||||
|
if (input.attr('type') === 'checkbox') {
|
||||||
|
// For checkboxes, check if they are checked
|
||||||
|
rowData[index] = { [input.attr("my-originalsetkey")] : input.prop('checked') };
|
||||||
|
} else {
|
||||||
|
// Generic sync for other inputs (text, select, textarea)
|
||||||
|
rowData[index] = { [input.attr("my-originalsetkey")] : input.val().replace(/'/g, "").replace(/"/g, "") };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Handle plain text
|
||||||
|
// rowData[index] = { [input.attr("my-originalsetkey")] : $(cell).text()};
|
||||||
|
console.log(`Nothig to collect: ${$(cell).html()}`)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tableData.push(rowData);
|
||||||
|
});
|
||||||
|
|
||||||
|
return tableData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -97,12 +97,54 @@ function generateApiToken(elem, length) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------
|
||||||
|
// Generate a random N-byte hexadecimal key
|
||||||
|
function getRandomBytes(elem, length) {
|
||||||
|
|
||||||
|
// Retrieve and parse custom parameters from the element
|
||||||
|
let params = $(elem).attr("my-customparams")?.split(',').map(param => param.trim());
|
||||||
|
if (params && params.length >= 1) {
|
||||||
|
var targetElementID = params[0]; // Get the target element's ID
|
||||||
|
}
|
||||||
|
|
||||||
|
let targetElement = $('#' + targetElementID);
|
||||||
|
|
||||||
|
// Generate random bytes
|
||||||
|
const array = new Uint8Array(length);
|
||||||
|
window.crypto.getRandomValues(array);
|
||||||
|
|
||||||
|
// Convert bytes to hexadecimal string
|
||||||
|
let hexString = Array.from(array, byte =>
|
||||||
|
byte.toString(16).padStart(2, '0')
|
||||||
|
).join('');
|
||||||
|
|
||||||
|
// Format hexadecimal string with hyphens
|
||||||
|
let formattedHex = hexString.match(/.{1,2}/g).join('-');
|
||||||
|
|
||||||
|
console.log(formattedHex);
|
||||||
|
// console.log($(`#${targetInput}`).val());
|
||||||
|
|
||||||
|
// Set the formatted key value to the input field
|
||||||
|
targetElement.val(formattedHex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------
|
||||||
|
// Updates the icon preview
|
||||||
|
function updateAllIconPreviews() {
|
||||||
|
$(".iconInputVal").each((index, el)=>{
|
||||||
|
updateIconPreview(el)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
// Updates the icon preview
|
// Updates the icon preview
|
||||||
function updateIconPreview(elem) {
|
function updateIconPreview(elem) {
|
||||||
const targetElement = $('[my-customid="NEWDEV_devIcon_preview"]');
|
|
||||||
const iconInput = $("#NEWDEV_devIcon");
|
const previewSpan = $(elem).parent().find(".iconPreview");
|
||||||
|
const iconInput = $(elem);
|
||||||
|
|
||||||
let attempts = 0;
|
let attempts = 0;
|
||||||
|
|
||||||
@@ -110,10 +152,10 @@ function updateIconPreview(elem) {
|
|||||||
let value = iconInput.val();
|
let value = iconInput.val();
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
targetElement.html(atob(value));
|
previewSpan.html(atob(value));
|
||||||
iconInput.off('change input').on('change input', function () {
|
iconInput.off('change input').on('change input', function () {
|
||||||
let newValue = $(this).val();
|
let newValue = $(elem).val();
|
||||||
targetElement.html(atob(newValue));
|
previewSpan.html(atob(newValue));
|
||||||
});
|
});
|
||||||
return; // Stop retrying if successful
|
return; // Stop retrying if successful
|
||||||
}
|
}
|
||||||
@@ -449,7 +491,7 @@ function showIconSelection() {
|
|||||||
iconDiv.addEventListener('click', () => {
|
iconDiv.addEventListener('click', () => {
|
||||||
selectElement.value = value; // Update the select element value
|
selectElement.value = value; // Update the select element value
|
||||||
$(`#${modalId}`).modal('hide'); // Hide the modal
|
$(`#${modalId}`).modal('hide'); // Hide the modal
|
||||||
updateIconPreview();
|
updateAllIconPreviews();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
48
front/lib/bcrypt/bcrypt.min.js
vendored
Executable file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
bcrypt.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
|
||||||
|
Released under the Apache License, Version 2.0
|
||||||
|
see: https://github.com/dcodeIO/bcrypt.js for details
|
||||||
|
*/
|
||||||
|
(function(u,r){"function"===typeof define&&define.amd?define([],r):"function"===typeof require&&"object"===typeof module&&module&&module.exports?module.exports=r():(u.dcodeIO=u.dcodeIO||{}).bcrypt=r()})(this,function(){function u(e){if("undefined"!==typeof module&&module&&module.exports)try{return require("crypto").randomBytes(e)}catch(d){}try{var c;(self.crypto||self.msCrypto).getRandomValues(c=new Uint32Array(e));return Array.prototype.slice.call(c)}catch(b){}if(!w)throw Error("Neither WebCryptoAPI nor a crypto module is available. Use bcrypt.setRandomFallback to set an alternative");
|
||||||
|
return w(e)}function r(e,d){for(var c=0,b=0,a=0,f=e.length;a<f;++a)e.charCodeAt(a)===d.charCodeAt(a)?++c:++b;return 0>c?!1:0===b}function H(e){var d=[],c=0;I.encodeUTF16toUTF8(function(){return c>=e.length?null:e.charCodeAt(c++)},function(b){d.push(b)});return d}function x(e,d){var c=0,b=[],a,f;if(0>=d||d>e.length)throw Error("Illegal len: "+d);for(;c<d;){a=e[c++]&255;b.push(s[a>>2&63]);a=(a&3)<<4;if(c>=d){b.push(s[a&63]);break}f=e[c++]&255;a|=f>>4&15;b.push(s[a&63]);a=(f&15)<<2;if(c>=d){b.push(s[a&
|
||||||
|
63]);break}f=e[c++]&255;a|=f>>6&3;b.push(s[a&63]);b.push(s[f&63])}return b.join("")}function B(e,d){var c=0,b=e.length,a=0,f=[],g,m,h;if(0>=d)throw Error("Illegal len: "+d);for(;c<b-1&&a<d;){h=e.charCodeAt(c++);g=h<q.length?q[h]:-1;h=e.charCodeAt(c++);m=h<q.length?q[h]:-1;if(-1==g||-1==m)break;h=g<<2>>>0;h|=(m&48)>>4;f.push(z(h));if(++a>=d||c>=b)break;h=e.charCodeAt(c++);g=h<q.length?q[h]:-1;if(-1==g)break;h=(m&15)<<4>>>0;h|=(g&60)>>2;f.push(z(h));if(++a>=d||c>=b)break;h=e.charCodeAt(c++);m=h<q.length?
|
||||||
|
q[h]:-1;h=(g&3)<<6>>>0;h|=m;f.push(z(h));++a}b=[];for(c=0;c<a;c++)b.push(f[c].charCodeAt(0));return b}function v(e,d,c,b){var a,f=e[d],g=e[d+1],f=f^c[0];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^c[1];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[2];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^c[3];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[4];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|
|
||||||
|
f>>8&255];a+=b[768|f&255];g=g^a^c[5];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[6];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^c[7];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[8];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^c[9];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[10];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^
|
||||||
|
c[11];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[12];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^c[13];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[14];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^c[15];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[16];e[d]=g^c[17];e[d+1]=f;return e}function t(e,d){for(var c=0,b=0;4>c;++c)b=b<<8|e[d]&255,d=(d+1)%e.length;
|
||||||
|
return{key:b,offp:d}}function C(e,d,c){for(var b=0,a=[0,0],f=d.length,g=c.length,m,h=0;h<f;h++)m=t(e,b),b=m.offp,d[h]^=m.key;for(h=0;h<f;h+=2)a=v(a,0,d,c),d[h]=a[0],d[h+1]=a[1];for(h=0;h<g;h+=2)a=v(a,0,d,c),c[h]=a[0],c[h+1]=a[1]}function J(e,d,c,b){for(var a=0,f=[0,0],g=c.length,m=b.length,h,l=0;l<g;l++)h=t(d,a),a=h.offp,c[l]^=h.key;for(l=a=0;l<g;l+=2)h=t(e,a),a=h.offp,f[0]^=h.key,h=t(e,a),a=h.offp,f[1]^=h.key,f=v(f,0,c,b),c[l]=f[0],c[l+1]=f[1];for(l=0;l<m;l+=2)h=t(e,a),a=h.offp,f[0]^=h.key,h=t(e,
|
||||||
|
a),a=h.offp,f[1]^=h.key,f=v(f,0,c,b),b[l]=f[0],b[l+1]=f[1]}function D(e,d,c,b,a){function f(){a&&a(n/c);if(n<c)for(var h=Date.now();n<c&&!(n+=1,C(e,l,k),C(d,l,k),100<Date.now()-h););else{for(n=0;64>n;n++)for(y=0;y<m>>1;y++)v(g,y<<1,l,k);h=[];for(n=0;n<m;n++)h.push((g[n]>>24&255)>>>0),h.push((g[n]>>16&255)>>>0),h.push((g[n]>>8&255)>>>0),h.push((g[n]&255)>>>0);if(b){b(null,h);return}return h}b&&p(f)}var g=E.slice(),m=g.length,h;if(4>c||31<c){h=Error("Illegal number of rounds (4-31): "+c);if(b){p(b.bind(this,
|
||||||
|
h));return}throw h;}if(16!==d.length){h=Error("Illegal salt length: "+d.length+" != 16");if(b){p(b.bind(this,h));return}throw h;}c=1<<c>>>0;var l,k,n=0,y;Int32Array?(l=new Int32Array(F),k=new Int32Array(G)):(l=F.slice(),k=G.slice());J(d,e,l,k);if("undefined"!==typeof b)f();else for(;;)if("undefined"!==typeof(h=f()))return h||[]}function A(e,d,c,b){function a(a){var b=[];b.push("$2");"a"<=f&&b.push(f);b.push("$");10>l&&b.push("0");b.push(l.toString());b.push("$");b.push(x(k,k.length));b.push(x(a,4*
|
||||||
|
E.length-1));return b.join("")}if("string"!==typeof e||"string"!==typeof d){b=Error("Invalid string / salt: Not a string");if(c){p(c.bind(this,b));return}throw b;}var f,g;if("$"!==d.charAt(0)||"2"!==d.charAt(1)){b=Error("Invalid salt version: "+d.substring(0,2));if(c){p(c.bind(this,b));return}throw b;}if("$"===d.charAt(2))f=String.fromCharCode(0),g=3;else{f=d.charAt(2);if("a"!==f&&"b"!==f&&"y"!==f||"$"!==d.charAt(3)){b=Error("Invalid salt revision: "+d.substring(2,4));if(c){p(c.bind(this,b));return}throw b;
|
||||||
|
}g=4}if("$"<d.charAt(g+2)){b=Error("Missing salt rounds");if(c){p(c.bind(this,b));return}throw b;}var m=10*parseInt(d.substring(g,g+1),10),h=parseInt(d.substring(g+1,g+2),10),l=m+h;d=d.substring(g+3,g+25);e=H(e+("a"<=f?"\x00":""));var k=B(d,16);if("undefined"==typeof c)return a(D(e,k,l));D(e,k,l,function(b,d){b?c(b,null):c(null,a(d))},b)}var k={},w=null;try{u(1)}catch(K){}w=null;k.setRandomFallback=function(e){w=e};k.genSaltSync=function(e,d){e=e||10;if("number"!==typeof e)throw Error("Illegal arguments: "+
|
||||||
|
typeof e+", "+typeof d);4>e?e=4:31<e&&(e=31);var c=[];c.push("$2a$");10>e&&c.push("0");c.push(e.toString());c.push("$");c.push(x(u(16),16));return c.join("")};k.genSalt=function(e,d,c){function b(a){p(function(){try{a(null,k.genSaltSync(e))}catch(b){a(b)}})}"function"===typeof d&&(c=d,d=void 0);"function"===typeof e&&(c=e,e=void 0);if("undefined"===typeof e)e=10;else if("number"!==typeof e)throw Error("illegal arguments: "+typeof e);if(c){if("function"!==typeof c)throw Error("Illegal callback: "+
|
||||||
|
typeof c);b(c)}else return new Promise(function(a,c){b(function(b,d){b?c(b):a(d)})})};k.hashSync=function(e,d){"undefined"===typeof d&&(d=10);"number"===typeof d&&(d=k.genSaltSync(d));if("string"!==typeof e||"string"!==typeof d)throw Error("Illegal arguments: "+typeof e+", "+typeof d);return A(e,d)};k.hash=function(e,d,c,b){function a(a){"string"===typeof e&&"number"===typeof d?k.genSalt(d,function(c,d){A(e,d,a,b)}):"string"===typeof e&&"string"===typeof d?A(e,d,a,b):p(a.bind(this,Error("Illegal arguments: "+
|
||||||
|
typeof e+", "+typeof d)))}if(c){if("function"!==typeof c)throw Error("Illegal callback: "+typeof c);a(c)}else return new Promise(function(b,c){a(function(a,d){a?c(a):b(d)})})};k.compareSync=function(e,d){if("string"!==typeof e||"string"!==typeof d)throw Error("Illegal arguments: "+typeof e+", "+typeof d);return 60!==d.length?!1:r(k.hashSync(e,d.substr(0,d.length-31)),d)};k.compare=function(e,d,c,b){function a(a){"string"!==typeof e||"string"!==typeof d?p(a.bind(this,Error("Illegal arguments: "+typeof e+
|
||||||
|
", "+typeof d))):60!==d.length?p(a.bind(this,null,!1)):k.hash(e,d.substr(0,29),function(b,c){b?a(b):a(null,r(c,d))},b)}if(c){if("function"!==typeof c)throw Error("Illegal callback: "+typeof c);a(c)}else return new Promise(function(b,c){a(function(a,d){a?c(a):b(d)})})};k.getRounds=function(e){if("string"!==typeof e)throw Error("Illegal arguments: "+typeof e);return parseInt(e.split("$")[2],10)};k.getSalt=function(e){if("string"!==typeof e)throw Error("Illegal arguments: "+typeof e);if(60!==e.length)throw Error("Illegal hash length: "+
|
||||||
|
e.length+" != 60");return e.substring(0,29)};var p="undefined"!==typeof process&&process&&"function"===typeof process.nextTick?"function"===typeof setImmediate?setImmediate:process.nextTick:setTimeout,s="./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split(""),q=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,54,55,56,57,58,59,60,61,62,63,-1,-1,-1,-1,-1,-1,-1,2,3,4,5,6,7,8,9,10,11,12,
|
||||||
|
13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,-1,-1,-1,-1,-1,-1,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,-1,-1,-1,-1,-1],z=String.fromCharCode,I=function(){var e={MAX_CODEPOINT:1114111,encodeUTF8:function(d,c){var b=null;"number"===typeof d&&(b=d,d=function(){return null});for(;null!==b||null!==(b=d());)128>b?c(b&127):(2048>b?c(b>>6&31|192):(65536>b?c(b>>12&15|224):(c(b>>18&7|240),c(b>>12&63|128)),c(b>>6&63|128)),c(b&63|128)),b=null},decodeUTF8:function(d,c){for(var b,
|
||||||
|
a,f,e,k=function(a){a=a.slice(0,a.indexOf(null));var b=Error(a.toString());b.name="TruncatedError";b.bytes=a;throw b;};null!==(b=d());)if(0===(b&128))c(b);else if(192===(b&224))null===(a=d())&&k([b,a]),c((b&31)<<6|a&63);else if(224===(b&240))null!==(a=d())&&null!==(f=d())||k([b,a,f]),c((b&15)<<12|(a&63)<<6|f&63);else if(240===(b&248))null!==(a=d())&&null!==(f=d())&&null!==(e=d())||k([b,a,f,e]),c((b&7)<<18|(a&63)<<12|(f&63)<<6|e&63);else throw RangeError("Illegal starting byte: "+b);},UTF16toUTF8:function(d,
|
||||||
|
c){for(var b,a=null;null!==(b=null!==a?a:d());)55296<=b&&57343>=b&&null!==(a=d())&&56320<=a&&57343>=a?(c(1024*(b-55296)+a-56320+65536),a=null):c(b);null!==a&&c(a)},UTF8toUTF16:function(d,c){var b=null;"number"===typeof d&&(b=d,d=function(){return null});for(;null!==b||null!==(b=d());)65535>=b?c(b):(b-=65536,c((b>>10)+55296),c(b%1024+56320)),b=null},encodeUTF16toUTF8:function(d,c){e.UTF16toUTF8(d,function(b){e.encodeUTF8(b,c)})},decodeUTF8toUTF16:function(d,c){e.decodeUTF8(d,function(b){e.UTF8toUTF16(b,
|
||||||
|
c)})},calculateCodePoint:function(d){return 128>d?1:2048>d?2:65536>d?3:4},calculateUTF8:function(d){for(var c,b=0;null!==(c=d());)b+=e.calculateCodePoint(c);return b},calculateUTF16asUTF8:function(d){var c=0,b=0;e.UTF16toUTF8(d,function(a){++c;b+=e.calculateCodePoint(a)});return[c,b]}};return e}();Date.now=Date.now||function(){return+new Date};var F=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,
|
||||||
|
3041331479,2450970073,2306472731],G=[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,
|
||||||
|
289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,
|
||||||
|
1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,
|
||||||
|
442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,
|
||||||
|
3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,
|
||||||
|
48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946,1266315497,3048417604,3681880366,3289982499,290971E4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,
|
||||||
|
1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,
|
||||||
|
613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,
|
||||||
|
2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,
|
||||||
|
1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,
|
||||||
|
4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055,3913112168,
|
||||||
|
2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,
|
||||||
|
499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,
|
||||||
|
3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,
|
||||||
|
309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,
|
||||||
|
1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,
|
||||||
|
2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504,976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,
|
||||||
|
2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,
|
||||||
|
3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,
|
||||||
|
3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409E3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,
|
||||||
|
3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,
|
||||||
|
1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462],E=[1332899944,1700884034,1701343084,1684370003,1668446532,
|
||||||
|
1869963892];k.encodeBase64=x;k.decodeBase64=B;return k});
|
||||||
@@ -482,8 +482,13 @@ function ImportPastedCSV()
|
|||||||
{
|
{
|
||||||
var csv = $('#modal-input-textarea').val();
|
var csv = $('#modal-input-textarea').val();
|
||||||
|
|
||||||
|
console.log(csv);
|
||||||
|
|
||||||
csvBase64 = utf8ToBase64(csv);
|
csvBase64 = utf8ToBase64(csv);
|
||||||
|
|
||||||
|
console.log(csvBase64);
|
||||||
|
|
||||||
|
|
||||||
$.post('php/server/devices.php?action=ImportCSV', { content: csvBase64 }, function(msg) {
|
$.post('php/server/devices.php?action=ImportCSV', { content: csvBase64 }, function(msg) {
|
||||||
showMessage(msg);
|
showMessage(msg);
|
||||||
write_notification(`[Maintenance] Devices imported from pasted content`, 'info');
|
write_notification(`[Maintenance] Devices imported from pasted content`, 'info');
|
||||||
|
|||||||
@@ -17,14 +17,14 @@
|
|||||||
<h3 class="box-title"><?= lang('Gen_Selected_Devices');?></h3>
|
<h3 class="box-title"><?= lang('Gen_Selected_Devices');?></h3>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="deviceSelector col-md-9 col-sm-12" style="z-index:5"></div>
|
<div class="deviceSelector col-md-11 col-sm-11" style="z-index:5"></div>
|
||||||
|
|
||||||
<div class="col-md-3">
|
<div class="col-md-1">
|
||||||
<button type="button" class="btn btn-default" onclick="markAllSelected()">
|
<button type="button" class="btn btn-default col-md-12" onclick="markAllSelected()" title="<?= lang('Gen_Add_All');?>">
|
||||||
<i class="fa-solid fa-circle-check"></i> <?= lang('Gen_Add_All');?>
|
<i class="fa-solid fa-circle-check"></i>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-default" onclick="markAllNotSelected()">
|
<button type="button" class="btn btn-default col-md-12" onclick="markAllNotSelected()" title="<?= lang('Gen_Remove_All');?>">
|
||||||
<i class="fa-solid fa-circle-xmark"></i> <?= lang('Gen_Remove_All');?>
|
<i class="fa-solid fa-circle-xmark"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
|
|
||||||
settingsData = res["data"];
|
settingsData = res["data"];
|
||||||
|
|
||||||
excludedColumns = ["NEWDEV_devMac", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devLastNotification", "NEWDEV_devLastIP", "NEWDEV_devStaticIP", "NEWDEV_devScan", "NEWDEV_devPresentLastScan" ]
|
excludedColumns = ["NEWDEV_devMac", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devLastNotification", "NEWDEV_devStaticIP", "NEWDEV_devScan", "NEWDEV_devPresentLastScan", "NEWDEV_devCustomProps" ]
|
||||||
|
|
||||||
const relevantColumns = settingsData.filter(set =>
|
const relevantColumns = settingsData.filter(set =>
|
||||||
set.setGroup === "NEWDEV" &&
|
set.setGroup === "NEWDEV" &&
|
||||||
@@ -90,21 +90,21 @@
|
|||||||
!set.setKey.includes("__metadata")
|
!set.setKey.includes("__metadata")
|
||||||
);
|
);
|
||||||
|
|
||||||
const generateSimpleForm = columns => {
|
const generateSimpleForm = multiEditColumns => {
|
||||||
const form = $('#multi-edit-form');
|
const form = $('#multi-edit-form');
|
||||||
const numColumns = 2; // Number of columns
|
const numColumns = 2; // Number of columns
|
||||||
|
|
||||||
// Calculate number of elements per column
|
// Calculate number of elements per column
|
||||||
const elementsPerColumn = Math.ceil(columns.length / numColumns);
|
const elementsPerColumn = Math.ceil(multiEditColumns.length / numColumns);
|
||||||
|
|
||||||
// Divide columns equally
|
// Divide columns equally
|
||||||
for (let i = 0; i < numColumns; i++) {
|
for (let i = 0; i < numColumns; i++) {
|
||||||
const column = $('<div>').addClass('col-md-6');
|
const column = $('<div>').addClass('col-md-6');
|
||||||
|
|
||||||
// Append form groups to the column
|
// Append form groups to the column
|
||||||
for (let j = i * elementsPerColumn; j < Math.min((i + 1) * elementsPerColumn, columns.length); j++) {
|
for (let j = i * elementsPerColumn; j < Math.min((i + 1) * elementsPerColumn, multiEditColumns.length); j++) {
|
||||||
|
|
||||||
const setTypeObject = JSON.parse(columns[j].setType.replace(/'/g, '"'));
|
const setTypeObject = JSON.parse(multiEditColumns[j].setType.replace(/'/g, '"'));
|
||||||
|
|
||||||
// get the element with the input value(s)
|
// get the element with the input value(s)
|
||||||
let elements = setTypeObject.elements.filter(element => element.elementHasInputValue === 1);
|
let elements = setTypeObject.elements.filter(element => element.elementHasInputValue === 1);
|
||||||
@@ -135,37 +135,38 @@
|
|||||||
onClick,
|
onClick,
|
||||||
onChange,
|
onChange,
|
||||||
customParams,
|
customParams,
|
||||||
customId
|
customId,
|
||||||
|
columns
|
||||||
} = handleElementOptions('none', elementOptions, transformers, val = "");
|
} = handleElementOptions('none', elementOptions, transformers, val = "");
|
||||||
|
|
||||||
// render based on element type
|
// render based on element type
|
||||||
if (elementType === 'select') {
|
if (elementType === 'select') {
|
||||||
|
|
||||||
targetLocation = columns[j].setKey + "_generateSetOptions"
|
targetLocation = multiEditColumns[j].setKey + "_generateSetOptions"
|
||||||
|
|
||||||
generateOptionsOrSetOptions(columns[j].setKey, [], targetLocation, generateOptions)
|
generateOptionsOrSetOptions(multiEditColumns[j].setKey, [], targetLocation, generateOptions, null)
|
||||||
|
|
||||||
console.log(columns[j].setKey)
|
console.log(multiEditColumns[j].setKey)
|
||||||
// Handle Icons as they need a preview
|
// Handle Icons as they need a preview
|
||||||
if(columns[j].setKey == 'NEWDEV_devIcon')
|
if(multiEditColumns[j].setKey == 'NEWDEV_devIcon')
|
||||||
{
|
{
|
||||||
input = `
|
input = `
|
||||||
<span class="input-group-addon iconPreview" my-customid="NEWDEV_devIcon_preview"></span>
|
<span class="input-group-addon iconPreview" my-customid="NEWDEV_devIcon_preview"></span>
|
||||||
<select class="form-control"
|
<select class="form-control"
|
||||||
onChange="updateIconPreview(this)"
|
onChange="updateIconPreview(this)"
|
||||||
my-customparams="NEWDEV_devIcon,NEWDEV_devIcon_preview"
|
my-customparams="NEWDEV_devIcon,NEWDEV_devIcon_preview"
|
||||||
id="${columns[j].setKey}"
|
id="${multiEditColumns[j].setKey}"
|
||||||
data-my-column="${columns[j].setKey}"
|
data-my-column="${multiEditColumns[j].setKey}"
|
||||||
data-my-targetColumns="${columns[j].setKey.replace('NEWDEV_','')}" >
|
data-my-targetColumns="${multiEditColumns[j].setKey.replace('NEWDEV_','')}" >
|
||||||
<option id="${targetLocation}"></option>
|
<option id="${targetLocation}"></option>
|
||||||
</select>`
|
</select>`
|
||||||
|
|
||||||
} else{
|
} else{
|
||||||
|
|
||||||
input = `<select class="form-control"
|
input = `<select class="form-control"
|
||||||
id="${columns[j].setKey}"
|
id="${multiEditColumns[j].setKey}"
|
||||||
data-my-column="${columns[j].setKey}"
|
data-my-column="${multiEditColumns[j].setKey}"
|
||||||
data-my-targetColumns="${columns[j].setKey.replace('NEWDEV_','')}" >
|
data-my-targetColumns="${multiEditColumns[j].setKey.replace('NEWDEV_','')}" >
|
||||||
<option id="${targetLocation}"></option>
|
<option id="${targetLocation}"></option>
|
||||||
</select>`
|
</select>`
|
||||||
}
|
}
|
||||||
@@ -178,20 +179,20 @@
|
|||||||
|
|
||||||
|
|
||||||
input = `<input class="${inputClass}"
|
input = `<input class="${inputClass}"
|
||||||
id="${columns[j].setKey}"
|
id="${multiEditColumns[j].setKey}"
|
||||||
my-customid="${columns[j].setKey}"
|
my-customid="${multiEditColumns[j].setKey}"
|
||||||
data-my-column="${columns[j].setKey}"
|
data-my-column="${multiEditColumns[j].setKey}"
|
||||||
data-my-targetColumns="${columns[j].setKey.replace('NEWDEV_','')}"
|
data-my-targetColumns="${multiEditColumns[j].setKey.replace('NEWDEV_','')}"
|
||||||
type="${inputType}">`
|
type="${inputType}">`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const inputEntry = `<div class="form-group col-sm-12" >
|
const inputEntry = `<div class="form-group col-sm-12" >
|
||||||
<label class="col-sm-3 control-label">${columns[j].setName}</label>
|
<label class="col-sm-3 control-label">${multiEditColumns[j].setName}</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group red-hover-border">
|
<div class="input-group red-hover-border">
|
||||||
${input}
|
${input}
|
||||||
<span class="input-group-addon pointer red-hover-background" onclick="massUpdateField('${columns[j].setKey}');" title="${getString('Device_MultiEdit_Tooltip')}">
|
<span class="input-group-addon pointer red-hover-background" onclick="massUpdateField('${multiEditColumns[j].setKey}');" title="${getString('Device_MultiEdit_Tooltip')}">
|
||||||
<i class="fa fa-save"></i>
|
<i class="fa fa-save"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
case 'deleteEvents30': deleteEvents30(); break;
|
case 'deleteEvents30': deleteEvents30(); break;
|
||||||
case 'deleteActHistory': deleteActHistory(); break;
|
case 'deleteActHistory': deleteActHistory(); break;
|
||||||
case 'deleteDeviceEvents': deleteDeviceEvents(); break;
|
case 'deleteDeviceEvents': deleteDeviceEvents(); break;
|
||||||
|
case 'resetDeviceProps': resetDeviceProps(); break;
|
||||||
case 'PiaBackupDBtoArchive': PiaBackupDBtoArchive(); break;
|
case 'PiaBackupDBtoArchive': PiaBackupDBtoArchive(); break;
|
||||||
case 'PiaRestoreDBfromArchive': PiaRestoreDBfromArchive(); break;
|
case 'PiaRestoreDBfromArchive': PiaRestoreDBfromArchive(); break;
|
||||||
case 'PiaPurgeDBBackups': PiaPurgeDBBackups(); break;
|
case 'PiaPurgeDBBackups': PiaPurgeDBBackups(); break;
|
||||||
@@ -105,6 +106,7 @@ function getServerDeviceData() {
|
|||||||
"devSSID" => "",
|
"devSSID" => "",
|
||||||
"devSyncHubNode" => "",
|
"devSyncHubNode" => "",
|
||||||
"devSourcePlugin" => "",
|
"devSourcePlugin" => "",
|
||||||
|
"devCustomProps" => "",
|
||||||
"devStatus" => "Unknown",
|
"devStatus" => "Unknown",
|
||||||
"devIsRandomMAC" => false,
|
"devIsRandomMAC" => false,
|
||||||
"devSessions" => 0,
|
"devSessions" => 0,
|
||||||
@@ -190,129 +192,131 @@ function setDeviceData() {
|
|||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
// Sanitize input
|
// Sanitize input
|
||||||
$mac = quotes($_REQUEST['mac']);
|
$mac = quotes($_POST['mac']);
|
||||||
$name = quotes($_REQUEST['name']);
|
$name = urldecode(quotes($_POST['name']));
|
||||||
$owner = quotes($_REQUEST['owner']);
|
$owner = urldecode(quotes($_POST['owner']));
|
||||||
$type = quotes($_REQUEST['type']);
|
$type = urldecode(quotes($_POST['type']));
|
||||||
$vendor = quotes($_REQUEST['vendor']);
|
$vendor = urldecode(quotes($_POST['vendor']));
|
||||||
$icon = quotes($_REQUEST['icon']);
|
$icon = urldecode(quotes($_POST['icon']));
|
||||||
$favorite = quotes($_REQUEST['favorite']);
|
$favorite = quotes($_POST['favorite']);
|
||||||
$group = quotes($_REQUEST['group']);
|
$group = urldecode(quotes($_POST['group']));
|
||||||
$location = quotes($_REQUEST['location']);
|
$location = urldecode(quotes($_POST['location']));
|
||||||
$comments = quotes($_REQUEST['comments']);
|
$comments = urldecode(quotes($_POST['comments']));
|
||||||
$parentMac = quotes($_REQUEST['networknode']);
|
$parentMac = quotes($_POST['networknode']);
|
||||||
$parentPort = quotes($_REQUEST['networknodeport']);
|
$parentPort = quotes($_POST['networknodeport']);
|
||||||
$ssid = quotes($_REQUEST['ssid']);
|
$ssid = urldecode(quotes($_POST['ssid']));
|
||||||
$site = quotes($_REQUEST['networksite']);
|
$site = quotes($_POST['networksite']);
|
||||||
$staticIP = quotes($_REQUEST['staticIP']);
|
$staticIP = quotes($_POST['staticIP']);
|
||||||
$scancycle = quotes($_REQUEST['scancycle']);
|
$scancycle = quotes($_POST['scancycle']);
|
||||||
$alertevents = quotes($_REQUEST['alertevents']);
|
$alertevents = quotes($_POST['alertevents']);
|
||||||
$alertdown = quotes($_REQUEST['alertdown']);
|
$alertdown = quotes($_POST['alertdown']);
|
||||||
$skiprepeated = quotes($_REQUEST['skiprepeated']);
|
$skiprepeated = quotes($_POST['skiprepeated']);
|
||||||
$newdevice = quotes($_REQUEST['newdevice']);
|
$newdevice = quotes($_POST['newdevice']);
|
||||||
$archived = quotes($_REQUEST['archived']);
|
$archived = quotes($_POST['archived']);
|
||||||
$devFirstConnection = quotes($_REQUEST['devFirstConnection']);
|
$devFirstConnection = quotes($_POST['devFirstConnection']);
|
||||||
$devLastConnection = quotes($_REQUEST['devLastConnection']);
|
$devLastConnection = quotes($_POST['devLastConnection']);
|
||||||
$ip = quotes($_REQUEST['ip']);
|
$ip = quotes($_POST['ip']);
|
||||||
$createNew = quotes($_REQUEST['createNew']);
|
$devCustomProps = quotes($_POST['devCustomProps']);
|
||||||
|
$createNew = quotes($_POST['createNew']);
|
||||||
$devNewGuid = generateGUID();
|
$devNewGuid = generateGUID();
|
||||||
|
|
||||||
// an update
|
// An update
|
||||||
if ($_REQUEST['createNew'] == 0)
|
if ($_POST['createNew'] == 0) {
|
||||||
{
|
// UPDATE SQL query
|
||||||
// UPDATE SQL query
|
$sql = "UPDATE Devices SET
|
||||||
$sql = "UPDATE Devices SET
|
devName = '$name',
|
||||||
devName = '$name',
|
devOwner = '$owner',
|
||||||
devOwner = '$owner',
|
devType = '$type',
|
||||||
devType = '$type',
|
devVendor = '$vendor',
|
||||||
devVendor = '$vendor',
|
devIcon = '$icon',
|
||||||
devIcon = '$icon',
|
devFavorite = '$favorite',
|
||||||
devFavorite = '$favorite',
|
devGroup = '$group',
|
||||||
devGroup = '$group',
|
devLocation = '$location',
|
||||||
devLocation = '$location',
|
devComments = '$comments',
|
||||||
devComments = '$comments',
|
devParentMAC = '$parentMac',
|
||||||
devParentMAC = '$parentMac',
|
devParentPort = '$parentPort',
|
||||||
devParentPort = '$parentPort',
|
devSSID = '$ssid',
|
||||||
devSSID = '$ssid',
|
devSite = '$site',
|
||||||
devSite = '$site',
|
devStaticIP = '$staticIP',
|
||||||
devStaticIP = '$staticIP',
|
devScan = '$scancycle',
|
||||||
devScan = '$scancycle',
|
devAlertEvents = '$alertevents',
|
||||||
devAlertEvents = '$alertevents',
|
devAlertDown = '$alertdown',
|
||||||
devAlertDown = '$alertdown',
|
devSkipRepeated = '$skiprepeated',
|
||||||
devSkipRepeated = '$skiprepeated',
|
devIsNew = '$newdevice',
|
||||||
devIsNew = '$newdevice',
|
devIsArchived = '$archived',
|
||||||
devIsArchived = '$archived'
|
devCustomProps = '$devCustomProps'
|
||||||
WHERE devMac = '$mac'";
|
WHERE devMac = '$mac'";
|
||||||
} else // an INSERT
|
} else { // An INSERT
|
||||||
{
|
$sql = "INSERT INTO Devices (
|
||||||
$sql = "INSERT INTO Devices (
|
devMac,
|
||||||
devMac,
|
devName,
|
||||||
devName,
|
devOwner,
|
||||||
devOwner,
|
devType,
|
||||||
devType,
|
devVendor,
|
||||||
devVendor,
|
devIcon,
|
||||||
devIcon,
|
devFavorite,
|
||||||
devFavorite,
|
devGroup,
|
||||||
devGroup,
|
devLocation,
|
||||||
devLocation,
|
devComments,
|
||||||
devComments,
|
devParentMAC,
|
||||||
devParentMAC,
|
devParentPort,
|
||||||
devParentPort,
|
devSSID,
|
||||||
devSSID,
|
devSite,
|
||||||
devSite,
|
devStaticIP,
|
||||||
devStaticIP,
|
devScan,
|
||||||
devScan,
|
devAlertEvents,
|
||||||
devAlertEvents,
|
devAlertDown,
|
||||||
devAlertDown,
|
devSkipRepeated,
|
||||||
devSkipRepeated,
|
devIsNew,
|
||||||
devIsNew,
|
devIsArchived,
|
||||||
devIsArchived,
|
devLastConnection,
|
||||||
devLastConnection,
|
devFirstConnection,
|
||||||
devFirstConnection,
|
devLastIP,
|
||||||
devLastIP,
|
devGUID,
|
||||||
devGUID
|
devCustomProps
|
||||||
) VALUES (
|
) VALUES (
|
||||||
'$mac',
|
'$mac',
|
||||||
'$name',
|
'$name',
|
||||||
'$owner',
|
'$owner',
|
||||||
'$type',
|
'$type',
|
||||||
'$vendor',
|
'$vendor',
|
||||||
'$icon',
|
'$icon',
|
||||||
'$favorite',
|
'$favorite',
|
||||||
'$group',
|
'$group',
|
||||||
'$location',
|
'$location',
|
||||||
'$comments',
|
'$comments',
|
||||||
'$parentMac',
|
'$parentMac',
|
||||||
'$parentPort',
|
'$parentPort',
|
||||||
'$ssid',
|
'$ssid',
|
||||||
'$site',
|
'$site',
|
||||||
'$staticIP',
|
'$staticIP',
|
||||||
'$scancycle',
|
'$scancycle',
|
||||||
'$alertevents',
|
'$alertevents',
|
||||||
'$alertdown',
|
'$alertdown',
|
||||||
'$skiprepeated',
|
'$skiprepeated',
|
||||||
'$newdevice',
|
'$newdevice',
|
||||||
'$archived',
|
'$archived',
|
||||||
'$devLastConnection',
|
'$devLastConnection',
|
||||||
'$devFirstConnection',
|
'$devFirstConnection',
|
||||||
'$ip',
|
'$ip',
|
||||||
'$devNewGuid'
|
'$devNewGuid',
|
||||||
)
|
'$devCustomProps'
|
||||||
";
|
)";
|
||||||
}
|
}
|
||||||
|
|
||||||
// update Data
|
// Execute the query
|
||||||
$result = $db->query($sql);
|
$result = $db->query($sql);
|
||||||
|
|
||||||
// check result
|
// Check the result
|
||||||
if ($result == TRUE) {
|
if ($result == TRUE) {
|
||||||
echo lang('BackDevices_DBTools_UpdDev');
|
echo lang('BackDevices_DBTools_UpdDev');
|
||||||
} else {
|
} else {
|
||||||
echo lang('BackDevices_DBTools_UpdDevError')."\n\n$sql \n\n". $db->lastErrorMsg();
|
echo lang('BackDevices_DBTools_UpdDevError')."\n\n$sql \n\n". $db->lastErrorMsg();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Delete Device
|
// Delete Device
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -389,6 +393,26 @@ function deleteDeviceEvents() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Delete Device Properties
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
function resetDeviceProps() {
|
||||||
|
global $db;
|
||||||
|
|
||||||
|
// sql
|
||||||
|
$sql = 'UPDATE Devices set devCustomProps = "'.getSettingValue("NEWDEV_devCustomProps").'" WHERE devMac="' . $_REQUEST['mac'] .'"';
|
||||||
|
|
||||||
|
// execute sql
|
||||||
|
$result = $db->query($sql);
|
||||||
|
|
||||||
|
// check result
|
||||||
|
if ($result == TRUE) {
|
||||||
|
echo lang('Gen_Okay');
|
||||||
|
} else {
|
||||||
|
echo lang('Gen_Error')."\n\n$sql \n\n". $db->lastErrorMsg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Delete all devices
|
// Delete all devices
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
38
front/php/server/query_config.php
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// ---- IMPORTS ----
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Check if authenticated
|
||||||
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
||||||
|
// Get init.php
|
||||||
|
require dirname(__FILE__).'/../server/init.php';
|
||||||
|
// ---- IMPORTS ----
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Handle incoming requests
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
|
// Get query string parameter ?file=settings_table.json
|
||||||
|
$file = isset($_GET['file']) ? $_GET['file'] : null;
|
||||||
|
|
||||||
|
// Check if file parameter is provided
|
||||||
|
if ($file) {
|
||||||
|
// Define the folder where files are located
|
||||||
|
$filePath = "/app/config/" . basename($file);
|
||||||
|
|
||||||
|
// Check if the file exists
|
||||||
|
if (file_exists($filePath)) {
|
||||||
|
// Send the response back to the client
|
||||||
|
header('Content-Type: text/plain');
|
||||||
|
echo file_get_contents($filePath);
|
||||||
|
} else {
|
||||||
|
// File not found response
|
||||||
|
http_response_code(404);
|
||||||
|
echo json_encode(["error" => "File not found"]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Missing file parameter response
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(["error" => "Missing 'file' parameter"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
55
front/php/server/query_replace_config.php
Executable file
@@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// ---- IMPORTS ----
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Check if authenticated
|
||||||
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
||||||
|
// Get init.php
|
||||||
|
require dirname(__FILE__).'/../server/init.php';
|
||||||
|
// ---- IMPORTS ----
|
||||||
|
|
||||||
|
global $fullConfPath;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Handle incoming requests
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
// Access the 'config' parameter from the POST request
|
||||||
|
$base64Data = $_POST['config'] ?? null;
|
||||||
|
|
||||||
|
if (!$base64Data) {
|
||||||
|
$msg = "Missing 'config' parameter.";
|
||||||
|
echo $msg;
|
||||||
|
http_response_code(400); // Bad request
|
||||||
|
die($msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode incoming base64 data
|
||||||
|
$input = base64_decode($base64Data, true);
|
||||||
|
|
||||||
|
if ($input === false) {
|
||||||
|
$msg = "Invalid base64 data.";
|
||||||
|
echo $msg;
|
||||||
|
http_response_code(400); // Bad request
|
||||||
|
die($msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backup the original file
|
||||||
|
if (file_exists($fullConfPath)) {
|
||||||
|
copy($fullConfPath, $fullConfPath . ".bak");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the new configuration
|
||||||
|
$file = fopen($fullConfPath, "w");
|
||||||
|
if (!$file) {
|
||||||
|
$msg = "Unable to open file!";
|
||||||
|
echo $msg;
|
||||||
|
http_response_code(500); // Server error
|
||||||
|
die($msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite($file, $input);
|
||||||
|
fclose($file);
|
||||||
|
|
||||||
|
echo "Configuration saved successfully.";
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -263,7 +263,7 @@ function cleanLog($logFile)
|
|||||||
|
|
||||||
$path = "";
|
$path = "";
|
||||||
|
|
||||||
$allowedFiles = ['app.log', 'app_front.log', 'IP_changes.log', 'stdout.log', 'stderr.log', 'app.php_errors.log', 'execution_queue.log'];
|
$allowedFiles = ['app.log', 'app_front.log', 'IP_changes.log', 'stdout.log', 'stderr.log', 'app.php_errors.log', 'execution_queue.log', 'db_is_locked.log'];
|
||||||
|
|
||||||
if(in_array($logFile, $allowedFiles))
|
if(in_array($logFile, $allowedFiles))
|
||||||
{
|
{
|
||||||
@@ -274,7 +274,7 @@ function cleanLog($logFile)
|
|||||||
{
|
{
|
||||||
// purge content
|
// purge content
|
||||||
$file = fopen($path, "w") or die("Unable to open file!");
|
$file = fopen($path, "w") or die("Unable to open file!");
|
||||||
fwrite($file, "[".$timestamp. "] Log file manually purged" .PHP_EOL."");
|
fwrite($file, "");
|
||||||
fclose($file);
|
fclose($file);
|
||||||
displayMessage('File <code>'.$logFile.'</code> purged.', FALSE, TRUE, TRUE, TRUE);
|
displayMessage('File <code>'.$logFile.'</code> purged.', FALSE, TRUE, TRUE, TRUE);
|
||||||
} else
|
} else
|
||||||
@@ -356,6 +356,8 @@ function saveSettings()
|
|||||||
$txt .= $setKey . "='" . $val . "'\n";
|
$txt .= $setKey . "='" . $val . "'\n";
|
||||||
} elseif ($dataType == 'integer') {
|
} elseif ($dataType == 'integer') {
|
||||||
$txt .= $setKey . "=" . $settingValue . "\n";
|
$txt .= $setKey . "=" . $settingValue . "\n";
|
||||||
|
} elseif ($dataType == 'none') {
|
||||||
|
$txt .= $setKey . "=''\n";
|
||||||
} elseif ($dataType == 'json') {
|
} elseif ($dataType == 'json') {
|
||||||
$txt .= $setKey . "=" . $settingValue . "\n";
|
$txt .= $setKey . "=" . $settingValue . "\n";
|
||||||
} elseif ($dataType == 'boolean') {
|
} elseif ($dataType == 'boolean') {
|
||||||
@@ -551,6 +553,7 @@ function decodeSpecialChars($str) {
|
|||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
|
// used in Export CSV
|
||||||
function getDevicesColumns(){
|
function getDevicesColumns(){
|
||||||
|
|
||||||
$columns = ["devMac",
|
$columns = ["devMac",
|
||||||
@@ -582,7 +585,8 @@ function getDevicesColumns(){
|
|||||||
"devSyncHubNode",
|
"devSyncHubNode",
|
||||||
"devSite",
|
"devSite",
|
||||||
"devSSID",
|
"devSSID",
|
||||||
"devSourcePlugin"
|
"devSourcePlugin",
|
||||||
|
"devCustomProps"
|
||||||
];
|
];
|
||||||
|
|
||||||
return $columns;
|
return $columns;
|
||||||
|
|||||||
@@ -28,12 +28,10 @@
|
|||||||
|
|
||||||
<!-- To the right -->
|
<!-- To the right -->
|
||||||
<div class="pull-right no-hidden-xs">
|
<div class="pull-right no-hidden-xs">
|
||||||
| <a href="https://github.com/jokob-sk/NetAlertX/tree/main/docs#documentation-overview" target="_blank">Docs <i class="fa fa-circle-question"></i></a>
|
| <a href="https://gurubase.io/g/netalertx" target="_blank" title="Ask AI"><i class="fa-regular fa-comment-dots fa-flip-horizontal"></i></a>
|
||||||
| <a href="https://github.com/jokob-sk/NetAlertX/issues"><i class="fa-solid fa-bug"></i></a>
|
| <a href="https://github.com/jokob-sk/NetAlertX/tree/main/docs#documentation-overview" target="_blank" title="Documentation"><i class="fa fa-book"></i></a>
|
||||||
| <a href="https://github.com/jokob-sk/NetAlertX/"><i class="fa-brands fa-github"></i></a>
|
| <a href="https://github.com/jokob-sk/NetAlertX/issues" target="_blank"><i class="fa-solid fa-bug" title="Report a bug"></i></a>
|
||||||
| <a href="https://discord.gg/UQnnHNYV"><i class="fa-brands fa-discord"></i></a>
|
| <a href="https://discord.com/invite/NczTUTWyRr" target="_blank"><i class="fa-brands fa-discord" title="Join Discord"></i></a>
|
||||||
| <a href="mailto:jokob@duck.com?subject=NetAlertX"><i class="fa-solid fa-envelope"></i></a>
|
|
||||||
| <a href="https://github.com/pucherot/Pi.Alert">©</a>
|
|
||||||
| <?= lang('Maintenance_built_on');?>: <?php include 'php/templates/build.php'; ?>
|
| <?= lang('Maintenance_built_on');?>: <?php include 'php/templates/build.php'; ?>
|
||||||
| Version: <?php include 'php/templates/version.php'; ?>
|
| Version: <?php include 'php/templates/version.php'; ?>
|
||||||
|
|
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
<script src="js/tests.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/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>
|
<script src="js/settings_utils.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||||
|
<script src="js/device.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -60,12 +60,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "",
|
"BackDevices_darkmode_enabled": "",
|
||||||
"CLEAR_NEW_FLAG_description": "",
|
"CLEAR_NEW_FLAG_description": "",
|
||||||
"CLEAR_NEW_FLAG_name": "",
|
"CLEAR_NEW_FLAG_name": "",
|
||||||
|
"CustProps_cant_remove": "",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "",
|
"DAYS_TO_KEEP_EVENTS_description": "",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "",
|
"DAYS_TO_KEEP_EVENTS_name": "",
|
||||||
"DISCOVER_PLUGINS_description": "",
|
"DISCOVER_PLUGINS_description": "",
|
||||||
"DISCOVER_PLUGINS_name": "",
|
"DISCOVER_PLUGINS_name": "",
|
||||||
"DevDetail_Copy_Device_Title": "",
|
"DevDetail_Copy_Device_Title": "",
|
||||||
"DevDetail_Copy_Device_Tooltip": "",
|
"DevDetail_Copy_Device_Tooltip": "",
|
||||||
|
"DevDetail_CustomProperties_Title": "",
|
||||||
|
"DevDetail_CustomProps_reset_info": "",
|
||||||
"DevDetail_DisplayFields_Title": "",
|
"DevDetail_DisplayFields_Title": "",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "",
|
"DevDetail_EveandAl_AlertAllEvents": "",
|
||||||
"DevDetail_EveandAl_AlertDown": "",
|
"DevDetail_EveandAl_AlertDown": "",
|
||||||
@@ -182,6 +185,7 @@
|
|||||||
"DevDetail_button_Delete": "",
|
"DevDetail_button_Delete": "",
|
||||||
"DevDetail_button_DeleteEvents": "",
|
"DevDetail_button_DeleteEvents": "",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "",
|
"DevDetail_button_DeleteEvents_Warning": "",
|
||||||
|
"DevDetail_button_Delete_ask": "",
|
||||||
"DevDetail_button_OverwriteIcons": "",
|
"DevDetail_button_OverwriteIcons": "",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "",
|
"DevDetail_button_OverwriteIcons_Tooltip": "",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "",
|
"DevDetail_button_OverwriteIcons_Warning": "",
|
||||||
@@ -205,6 +209,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "",
|
"Device_Shortcut_OnlineChart": "",
|
||||||
"Device_TableHead_AlertDown": "",
|
"Device_TableHead_AlertDown": "",
|
||||||
"Device_TableHead_Connected_Devices": "",
|
"Device_TableHead_Connected_Devices": "",
|
||||||
|
"Device_TableHead_CustomProps": "",
|
||||||
"Device_TableHead_Favorite": "",
|
"Device_TableHead_Favorite": "",
|
||||||
"Device_TableHead_FirstSession": "",
|
"Device_TableHead_FirstSession": "",
|
||||||
"Device_TableHead_GUID": "",
|
"Device_TableHead_GUID": "",
|
||||||
@@ -243,6 +248,8 @@
|
|||||||
"Donations_Title": "",
|
"Donations_Title": "",
|
||||||
"ENABLE_PLUGINS_description": "",
|
"ENABLE_PLUGINS_description": "",
|
||||||
"ENABLE_PLUGINS_name": "",
|
"ENABLE_PLUGINS_name": "",
|
||||||
|
"ENCRYPTION_KEY_description": "",
|
||||||
|
"ENCRYPTION_KEY_name": "",
|
||||||
"Email_display_name": "",
|
"Email_display_name": "",
|
||||||
"Email_icon": "",
|
"Email_icon": "",
|
||||||
"Events_Loading": "",
|
"Events_Loading": "",
|
||||||
@@ -305,6 +312,7 @@
|
|||||||
"Gen_ReadDocs": "",
|
"Gen_ReadDocs": "",
|
||||||
"Gen_Remove_All": "",
|
"Gen_Remove_All": "",
|
||||||
"Gen_Remove_Last": "",
|
"Gen_Remove_Last": "",
|
||||||
|
"Gen_Reset": "",
|
||||||
"Gen_Restore": "",
|
"Gen_Restore": "",
|
||||||
"Gen_Run": "",
|
"Gen_Run": "",
|
||||||
"Gen_Save": "",
|
"Gen_Save": "",
|
||||||
|
|||||||
@@ -60,12 +60,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "Mode fosc Activat",
|
"BackDevices_darkmode_enabled": "Mode fosc Activat",
|
||||||
"CLEAR_NEW_FLAG_description": "Si està habilitat (<code>0</code> està desactivat), els dispositius marcats com <b>Nou dispositiu</b> es desmarcaran si el temps límit (especificat en hores) supera <b>Primera sessió</b>.",
|
"CLEAR_NEW_FLAG_description": "Si està habilitat (<code>0</code> està desactivat), els dispositius marcats com <b>Nou dispositiu</b> es desmarcaran si el temps límit (especificat en hores) supera <b>Primera sessió</b>.",
|
||||||
"CLEAR_NEW_FLAG_name": "Netejar indicador de nou",
|
"CLEAR_NEW_FLAG_name": "Netejar indicador de nou",
|
||||||
|
"CustProps_cant_remove": "No es pot eliminar, almenys es necessita una propietat.",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "Això és una configuració de manteniment. Especifica el nombre de dies que es conservaran els esdeveniments. Els esdeveniments antics s'esborraran periòdicament. També aplica als esdeveniments dels Connectors (Plugins).",
|
"DAYS_TO_KEEP_EVENTS_description": "Això és una configuració de manteniment. Especifica el nombre de dies que es conservaran els esdeveniments. Els esdeveniments antics s'esborraran periòdicament. També aplica als esdeveniments dels Connectors (Plugins).",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "Esborrar esdeveniments més vells de",
|
"DAYS_TO_KEEP_EVENTS_name": "Esborrar esdeveniments més vells de",
|
||||||
"DISCOVER_PLUGINS_description": "Desactiva aquesta opció per accelerar la inicialització i l'estalvi de configuració. Quan està desactivat, els connectors no es descobreixen, i no podeu afegir nous connectors a la configuració <code>LOADED_PLUGINS</code>.",
|
"DISCOVER_PLUGINS_description": "Desactiva aquesta opció per accelerar la inicialització i l'estalvi de configuració. Quan està desactivat, els connectors no es descobreixen, i no podeu afegir nous connectors a la configuració <code>LOADED_PLUGINS</code>.",
|
||||||
"DISCOVER_PLUGINS_name": "Descobreix els plugins",
|
"DISCOVER_PLUGINS_name": "Descobreix els plugins",
|
||||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copiar detalls des del dispositiu",
|
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copiar detalls des del dispositiu",
|
||||||
"DevDetail_Copy_Device_Tooltip": "Copiar detalls del dispositius des de la llista desplegable. Tot el d'aquesta pàgina es sobre-escriurà",
|
"DevDetail_Copy_Device_Tooltip": "Copiar detalls del dispositius des de la llista desplegable. Tot el d'aquesta pàgina es sobre-escriurà",
|
||||||
|
"DevDetail_CustomProperties_Title": "Propietats personalitzades",
|
||||||
|
"DevDetail_CustomProps_reset_info": "Això eliminarà les seves propietats personalitzades en aquest dispositiu i restablir-les al valor predeterminat.",
|
||||||
"DevDetail_DisplayFields_Title": "Pantalla",
|
"DevDetail_DisplayFields_Title": "Pantalla",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "Alertes",
|
"DevDetail_EveandAl_AlertAllEvents": "Alertes",
|
||||||
"DevDetail_EveandAl_AlertDown": "Cancel·lar alerta",
|
"DevDetail_EveandAl_AlertDown": "Cancel·lar alerta",
|
||||||
@@ -182,6 +185,7 @@
|
|||||||
"DevDetail_button_Delete": "Eliminar dispositiu",
|
"DevDetail_button_Delete": "Eliminar dispositiu",
|
||||||
"DevDetail_button_DeleteEvents": "Eliminar Esdeveniments",
|
"DevDetail_button_DeleteEvents": "Eliminar Esdeveniments",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "Estàs segur que vols eliminar tots els esdeveniments d'aquest dispositiu?<br><br>(això esborrarà la <b>Historial d'esdeveniments</b> i la <b>Sessions</b> i pot ajudar amb les notificacions constants (persistents)",
|
"DevDetail_button_DeleteEvents_Warning": "Estàs segur que vols eliminar tots els esdeveniments d'aquest dispositiu?<br><br>(això esborrarà la <b>Historial d'esdeveniments</b> i la <b>Sessions</b> i pot ajudar amb les notificacions constants (persistents)",
|
||||||
|
"DevDetail_button_Delete_ask": "T'és segur vols eliminar aquest dispositiu? També el pots arxivar en comptes d'això.",
|
||||||
"DevDetail_button_OverwriteIcons": "Sobreescriure icones",
|
"DevDetail_button_OverwriteIcons": "Sobreescriure icones",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "Sobreescriure icones de tots els dispositius amb el mateix tipus de dispositiu",
|
"DevDetail_button_OverwriteIcons_Tooltip": "Sobreescriure icones de tots els dispositius amb el mateix tipus de dispositiu",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "Estàs segur que vols sobreescriure totes les icones de tots els dispositius amb el mateix tipus de dispositiu que el tipus de dispositiu actual?",
|
"DevDetail_button_OverwriteIcons_Warning": "Estàs segur que vols sobreescriure totes les icones de tots els dispositius amb el mateix tipus de dispositiu que el tipus de dispositiu actual?",
|
||||||
@@ -205,6 +209,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "Presència de dispositius",
|
"Device_Shortcut_OnlineChart": "Presència de dispositius",
|
||||||
"Device_TableHead_AlertDown": "Cancel·lar alerta",
|
"Device_TableHead_AlertDown": "Cancel·lar alerta",
|
||||||
"Device_TableHead_Connected_Devices": "Connexions",
|
"Device_TableHead_Connected_Devices": "Connexions",
|
||||||
|
"Device_TableHead_CustomProps": "Props / Accions",
|
||||||
"Device_TableHead_Favorite": "Favorit",
|
"Device_TableHead_Favorite": "Favorit",
|
||||||
"Device_TableHead_FirstSession": "Primera Sessió",
|
"Device_TableHead_FirstSession": "Primera Sessió",
|
||||||
"Device_TableHead_GUID": "GUID",
|
"Device_TableHead_GUID": "GUID",
|
||||||
@@ -243,6 +248,8 @@
|
|||||||
"Donations_Title": "Donacions",
|
"Donations_Title": "Donacions",
|
||||||
"ENABLE_PLUGINS_description": "Habilita la <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">connectors</a> funcionalitat. Carregar els connectors requereix més recursos de maquinari així podries voler desactivar-los en un sistema de baixos recursos.",
|
"ENABLE_PLUGINS_description": "Habilita la <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">connectors</a> funcionalitat. Carregar els connectors requereix més recursos de maquinari així podries voler desactivar-los en un sistema de baixos recursos.",
|
||||||
"ENABLE_PLUGINS_name": "Activa els connectors(Plugins)",
|
"ENABLE_PLUGINS_name": "Activa els connectors(Plugins)",
|
||||||
|
"ENCRYPTION_KEY_description": "Clau de xifrat de dades.",
|
||||||
|
"ENCRYPTION_KEY_name": "Clau d'encriptació",
|
||||||
"Email_display_name": "Correu electrònic",
|
"Email_display_name": "Correu electrònic",
|
||||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||||
"Events_Loading": "Carregant ...",
|
"Events_Loading": "Carregant ...",
|
||||||
@@ -278,7 +285,7 @@
|
|||||||
"Events_Tablelenght": "Veure_entrades_MENU",
|
"Events_Tablelenght": "Veure_entrades_MENU",
|
||||||
"Events_Tablelenght_all": "Tot",
|
"Events_Tablelenght_all": "Tot",
|
||||||
"Events_Title": "Esdeveniments",
|
"Events_Title": "Esdeveniments",
|
||||||
"GRAPHQL_PORT_description": "El número de port del servidor GraphQL.",
|
"GRAPHQL_PORT_description": "El número de port del servidor GraphQL. Comprova que el port és únic en totes les aplicacions d'aquest servidor i en totes les instàncies de NetAlertX.",
|
||||||
"GRAPHQL_PORT_name": "Port GraphQL",
|
"GRAPHQL_PORT_name": "Port GraphQL",
|
||||||
"Gen_Action": "Acció",
|
"Gen_Action": "Acció",
|
||||||
"Gen_Add": "Afegir",
|
"Gen_Add": "Afegir",
|
||||||
@@ -305,6 +312,7 @@
|
|||||||
"Gen_ReadDocs": "Llegit més dins el docs.",
|
"Gen_ReadDocs": "Llegit més dins el docs.",
|
||||||
"Gen_Remove_All": "Esborra tot",
|
"Gen_Remove_All": "Esborra tot",
|
||||||
"Gen_Remove_Last": "Esborra el darrer",
|
"Gen_Remove_Last": "Esborra el darrer",
|
||||||
|
"Gen_Reset": "Reinicialització",
|
||||||
"Gen_Restore": "Executar Restaurar",
|
"Gen_Restore": "Executar Restaurar",
|
||||||
"Gen_Run": "Executar",
|
"Gen_Run": "Executar",
|
||||||
"Gen_Save": "Guardar",
|
"Gen_Save": "Guardar",
|
||||||
@@ -481,7 +489,7 @@
|
|||||||
"Maintenance_themeselector_lable": "Selecciona una Skin",
|
"Maintenance_themeselector_lable": "Selecciona una Skin",
|
||||||
"Maintenance_themeselector_text": "El canvi té lloc a la part del servidor, per la qual cosa afecta tots els dispositius en ús.",
|
"Maintenance_themeselector_text": "El canvi té lloc a la part del servidor, per la qual cosa afecta tots els dispositius en ús.",
|
||||||
"Maintenance_version": "Actualitzacions d'aplicació",
|
"Maintenance_version": "Actualitzacions d'aplicació",
|
||||||
"NETWORK_DEVICE_TYPES_description": "Quins tipus de dispositius es poden utilitzar com a dispositius de xarxa a la vista de xarxa. El tipus de dispositiu ha de coincidir exactament amb la <code>Type</code> configuració d'un dispositiu específic als detalls del dispositiu. No elimini els tipus existents, només afegir-ne nous.",
|
"NETWORK_DEVICE_TYPES_description": "Quins tipus de dispositius es poden utilitzar com a dispositius de xarxa a la vista \"xarxa\". El tipus de dispositiu ha de coincidir exactament amb la configuració <code>Tipus</code> dels detalls de dispositiu. Afegir-ho al dispositiu fent servir el botó <code>+</code>. No elimini els tipus existents, només afegir-ne nous.",
|
||||||
"NETWORK_DEVICE_TYPES_name": "Tipus de dispositiu de xarxa",
|
"NETWORK_DEVICE_TYPES_name": "Tipus de dispositiu de xarxa",
|
||||||
"Navigation_About": "Sobre",
|
"Navigation_About": "Sobre",
|
||||||
"Navigation_Devices": "Dispositius",
|
"Navigation_Devices": "Dispositius",
|
||||||
|
|||||||
@@ -60,12 +60,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "",
|
"BackDevices_darkmode_enabled": "",
|
||||||
"CLEAR_NEW_FLAG_description": "",
|
"CLEAR_NEW_FLAG_description": "",
|
||||||
"CLEAR_NEW_FLAG_name": "",
|
"CLEAR_NEW_FLAG_name": "",
|
||||||
|
"CustProps_cant_remove": "",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "",
|
"DAYS_TO_KEEP_EVENTS_description": "",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "",
|
"DAYS_TO_KEEP_EVENTS_name": "",
|
||||||
"DISCOVER_PLUGINS_description": "",
|
"DISCOVER_PLUGINS_description": "",
|
||||||
"DISCOVER_PLUGINS_name": "",
|
"DISCOVER_PLUGINS_name": "",
|
||||||
"DevDetail_Copy_Device_Title": "",
|
"DevDetail_Copy_Device_Title": "",
|
||||||
"DevDetail_Copy_Device_Tooltip": "",
|
"DevDetail_Copy_Device_Tooltip": "",
|
||||||
|
"DevDetail_CustomProperties_Title": "",
|
||||||
|
"DevDetail_CustomProps_reset_info": "",
|
||||||
"DevDetail_DisplayFields_Title": "",
|
"DevDetail_DisplayFields_Title": "",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "",
|
"DevDetail_EveandAl_AlertAllEvents": "",
|
||||||
"DevDetail_EveandAl_AlertDown": "",
|
"DevDetail_EveandAl_AlertDown": "",
|
||||||
@@ -182,6 +185,7 @@
|
|||||||
"DevDetail_button_Delete": "",
|
"DevDetail_button_Delete": "",
|
||||||
"DevDetail_button_DeleteEvents": "",
|
"DevDetail_button_DeleteEvents": "",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "",
|
"DevDetail_button_DeleteEvents_Warning": "",
|
||||||
|
"DevDetail_button_Delete_ask": "",
|
||||||
"DevDetail_button_OverwriteIcons": "",
|
"DevDetail_button_OverwriteIcons": "",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "",
|
"DevDetail_button_OverwriteIcons_Tooltip": "",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "",
|
"DevDetail_button_OverwriteIcons_Warning": "",
|
||||||
@@ -205,6 +209,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "",
|
"Device_Shortcut_OnlineChart": "",
|
||||||
"Device_TableHead_AlertDown": "",
|
"Device_TableHead_AlertDown": "",
|
||||||
"Device_TableHead_Connected_Devices": "",
|
"Device_TableHead_Connected_Devices": "",
|
||||||
|
"Device_TableHead_CustomProps": "",
|
||||||
"Device_TableHead_Favorite": "",
|
"Device_TableHead_Favorite": "",
|
||||||
"Device_TableHead_FirstSession": "",
|
"Device_TableHead_FirstSession": "",
|
||||||
"Device_TableHead_GUID": "",
|
"Device_TableHead_GUID": "",
|
||||||
@@ -243,6 +248,8 @@
|
|||||||
"Donations_Title": "",
|
"Donations_Title": "",
|
||||||
"ENABLE_PLUGINS_description": "",
|
"ENABLE_PLUGINS_description": "",
|
||||||
"ENABLE_PLUGINS_name": "",
|
"ENABLE_PLUGINS_name": "",
|
||||||
|
"ENCRYPTION_KEY_description": "",
|
||||||
|
"ENCRYPTION_KEY_name": "",
|
||||||
"Email_display_name": "",
|
"Email_display_name": "",
|
||||||
"Email_icon": "",
|
"Email_icon": "",
|
||||||
"Events_Loading": "",
|
"Events_Loading": "",
|
||||||
@@ -305,6 +312,7 @@
|
|||||||
"Gen_ReadDocs": "",
|
"Gen_ReadDocs": "",
|
||||||
"Gen_Remove_All": "",
|
"Gen_Remove_All": "",
|
||||||
"Gen_Remove_Last": "",
|
"Gen_Remove_Last": "",
|
||||||
|
"Gen_Reset": "",
|
||||||
"Gen_Restore": "",
|
"Gen_Restore": "",
|
||||||
"Gen_Run": "",
|
"Gen_Run": "",
|
||||||
"Gen_Save": "",
|
"Gen_Save": "",
|
||||||
|
|||||||
@@ -72,12 +72,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "Dunkler Modus aktiviert",
|
"BackDevices_darkmode_enabled": "Dunkler Modus aktiviert",
|
||||||
"CLEAR_NEW_FLAG_description": "Wenn aktiviert (<code>0</code> bedeutet deaktiviert), werden Geräte, die als <b>Neues Gerät</b> gekennzeichnet sind, wieder freigegeben, wenn das Zeitlimit (in Stunden) die Zeit ihrer <b>Ersten Sitzung</b> überschreitet.",
|
"CLEAR_NEW_FLAG_description": "Wenn aktiviert (<code>0</code> bedeutet deaktiviert), werden Geräte, die als <b>Neues Gerät</b> gekennzeichnet sind, wieder freigegeben, wenn das Zeitlimit (in Stunden) die Zeit ihrer <b>Ersten Sitzung</b> überschreitet.",
|
||||||
"CLEAR_NEW_FLAG_name": "Neues Flag löschen",
|
"CLEAR_NEW_FLAG_name": "Neues Flag löschen",
|
||||||
|
"CustProps_cant_remove": "Kann nicht entfernt werden, es wird mindestens eine Eigenschaft benötigt.",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "Dies ist eine Wartungseinstellung. Spezifiziert wie viele Tage Events gespeichert bleiben. Alle älteren Events werden periodisch gelöscht. Wird auch auf die Plugins History angewendet.",
|
"DAYS_TO_KEEP_EVENTS_description": "Dies ist eine Wartungseinstellung. Spezifiziert wie viele Tage Events gespeichert bleiben. Alle älteren Events werden periodisch gelöscht. Wird auch auf die Plugins History angewendet.",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "Ereignisse löschen, die älter sind als",
|
"DAYS_TO_KEEP_EVENTS_name": "Ereignisse löschen, die älter sind als",
|
||||||
"DISCOVER_PLUGINS_description": "",
|
"DISCOVER_PLUGINS_description": "",
|
||||||
"DISCOVER_PLUGINS_name": "",
|
"DISCOVER_PLUGINS_name": "",
|
||||||
"DevDetail_Copy_Device_Title": "Details von Gerät kopieren",
|
"DevDetail_Copy_Device_Title": "Details von Gerät kopieren",
|
||||||
"DevDetail_Copy_Device_Tooltip": "Details vom Gerät aus der Dropdown-Liste kopieren. Alles auf dieser Seite wird überschrieben",
|
"DevDetail_Copy_Device_Tooltip": "Details vom Gerät aus der Dropdown-Liste kopieren. Alles auf dieser Seite wird überschrieben",
|
||||||
|
"DevDetail_CustomProperties_Title": "Benutzerdefinierte Eigenschaften",
|
||||||
|
"DevDetail_CustomProps_reset_info": "Dadurch werden Ihre benutzerdefinierten Eigenschaften auf diesem Gerät entfernt und auf den Standardwert zurückgesetzt.",
|
||||||
"DevDetail_DisplayFields_Title": "Anzeige",
|
"DevDetail_DisplayFields_Title": "Anzeige",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "Alarmereignisse",
|
"DevDetail_EveandAl_AlertAllEvents": "Alarmereignisse",
|
||||||
"DevDetail_EveandAl_AlertDown": "Melde Down",
|
"DevDetail_EveandAl_AlertDown": "Melde Down",
|
||||||
@@ -194,6 +197,7 @@
|
|||||||
"DevDetail_button_Delete": "Gerät löschen",
|
"DevDetail_button_Delete": "Gerät löschen",
|
||||||
"DevDetail_button_DeleteEvents": "Ereignisse löschen",
|
"DevDetail_button_DeleteEvents": "Ereignisse löschen",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "Sind Sie sicher, dass Sie alle Ereignisse dieses Geräts löschen möchten? (dies löscht den Ereignisverlauf und die Sitzungen und könnte bei ständigen (anhaltenden) Benachrichtigungen helfen)",
|
"DevDetail_button_DeleteEvents_Warning": "Sind Sie sicher, dass Sie alle Ereignisse dieses Geräts löschen möchten? (dies löscht den Ereignisverlauf und die Sitzungen und könnte bei ständigen (anhaltenden) Benachrichtigungen helfen)",
|
||||||
|
"DevDetail_button_Delete_ask": "Sind Sie sicher, dass Sie dieses Gerät löschen möchten? Sie können es stattdessen auch archivieren.",
|
||||||
"DevDetail_button_OverwriteIcons": "Symbole überschreiben",
|
"DevDetail_button_OverwriteIcons": "Symbole überschreiben",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "Symbole aller Geräte mit demselben Gerätetyp überschreiben",
|
"DevDetail_button_OverwriteIcons_Tooltip": "Symbole aller Geräte mit demselben Gerätetyp überschreiben",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "Bist du sicher, dass du alle Symbole aller Geräte mit dem gleichen Gerätetyp wie dem aktuellen Gerätetyp überschreiben willst?",
|
"DevDetail_button_OverwriteIcons_Warning": "Bist du sicher, dass du alle Symbole aller Geräte mit dem gleichen Gerätetyp wie dem aktuellen Gerätetyp überschreiben willst?",
|
||||||
@@ -217,6 +221,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "Gerätepräsenz im Laufe der Zeit",
|
"Device_Shortcut_OnlineChart": "Gerätepräsenz im Laufe der Zeit",
|
||||||
"Device_TableHead_AlertDown": "",
|
"Device_TableHead_AlertDown": "",
|
||||||
"Device_TableHead_Connected_Devices": "Verbindungen",
|
"Device_TableHead_Connected_Devices": "Verbindungen",
|
||||||
|
"Device_TableHead_CustomProps": "",
|
||||||
"Device_TableHead_Favorite": "Favorit",
|
"Device_TableHead_Favorite": "Favorit",
|
||||||
"Device_TableHead_FirstSession": "Erste Sitzung",
|
"Device_TableHead_FirstSession": "Erste Sitzung",
|
||||||
"Device_TableHead_GUID": "GUID",
|
"Device_TableHead_GUID": "GUID",
|
||||||
@@ -255,6 +260,8 @@
|
|||||||
"Donations_Title": "Spenden",
|
"Donations_Title": "Spenden",
|
||||||
"ENABLE_PLUGINS_description": "NOTUSED Enables the <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a> functionality. Loading plugins requires more hardware resources so you might want to disable them on low-powered system.",
|
"ENABLE_PLUGINS_description": "NOTUSED Enables the <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a> functionality. Loading plugins requires more hardware resources so you might want to disable them on low-powered system.",
|
||||||
"ENABLE_PLUGINS_name": "NOTUSED Enable Plugins",
|
"ENABLE_PLUGINS_name": "NOTUSED Enable Plugins",
|
||||||
|
"ENCRYPTION_KEY_description": "Schlüssel zur Datenverschlüsselung.",
|
||||||
|
"ENCRYPTION_KEY_name": "Verschlüsselungsschlüssel",
|
||||||
"Email_display_name": "Email",
|
"Email_display_name": "Email",
|
||||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||||
"Events_Loading": "Laden...",
|
"Events_Loading": "Laden...",
|
||||||
@@ -317,12 +324,13 @@
|
|||||||
"Gen_ReadDocs": "Mehr in der Dokumentation.",
|
"Gen_ReadDocs": "Mehr in der Dokumentation.",
|
||||||
"Gen_Remove_All": "Alle entfernen",
|
"Gen_Remove_All": "Alle entfernen",
|
||||||
"Gen_Remove_Last": "Letzte entfernen",
|
"Gen_Remove_Last": "Letzte entfernen",
|
||||||
|
"Gen_Reset": "Zurücksetzen",
|
||||||
"Gen_Restore": "Wiederherstellen",
|
"Gen_Restore": "Wiederherstellen",
|
||||||
"Gen_Run": "Ausführen",
|
"Gen_Run": "Ausführen",
|
||||||
"Gen_Save": "Speichern",
|
"Gen_Save": "Speichern",
|
||||||
"Gen_Saved": "Gespeichert",
|
"Gen_Saved": "Gespeichert",
|
||||||
"Gen_Search": "Suchen",
|
"Gen_Search": "Suchen",
|
||||||
"Gen_Select": "",
|
"Gen_Select": "Auswählen",
|
||||||
"Gen_SelectIcon": "",
|
"Gen_SelectIcon": "",
|
||||||
"Gen_SelectToPreview": "Zur Vorschau auswählen",
|
"Gen_SelectToPreview": "Zur Vorschau auswählen",
|
||||||
"Gen_Selected_Devices": "Ausgewählte Geräte:",
|
"Gen_Selected_Devices": "Ausgewählte Geräte:",
|
||||||
@@ -333,7 +341,7 @@
|
|||||||
"Gen_Update_Value": "Wert aktualisieren",
|
"Gen_Update_Value": "Wert aktualisieren",
|
||||||
"Gen_Warning": "Warnung",
|
"Gen_Warning": "Warnung",
|
||||||
"Gen_Work_In_Progress": "Keine Finalversion, feedback bitte unter: https://github.com/jokob-sk/NetAlertX/issues",
|
"Gen_Work_In_Progress": "Keine Finalversion, feedback bitte unter: https://github.com/jokob-sk/NetAlertX/issues",
|
||||||
"Gen_create_new_device": "",
|
"Gen_create_new_device": "Neues Gerät",
|
||||||
"Gen_create_new_device_info": "",
|
"Gen_create_new_device_info": "",
|
||||||
"General_display_name": "Allgemein",
|
"General_display_name": "Allgemein",
|
||||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||||
|
|||||||
@@ -60,12 +60,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "Darkmode Enabled",
|
"BackDevices_darkmode_enabled": "Darkmode Enabled",
|
||||||
"CLEAR_NEW_FLAG_description": "If enabled (<code>0</code> is disabled), devices flagged as <b>New Device</b> will be unflagged if the time limit (specified in hours) exceeds their <b>First Session</b> time.",
|
"CLEAR_NEW_FLAG_description": "If enabled (<code>0</code> is disabled), devices flagged as <b>New Device</b> will be unflagged if the time limit (specified in hours) exceeds their <b>First Session</b> time.",
|
||||||
"CLEAR_NEW_FLAG_name": "Clear new flag",
|
"CLEAR_NEW_FLAG_name": "Clear new flag",
|
||||||
|
"CustProps_cant_remove": "Can't remove, at least one property is needed.",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "This is a maintenance setting. This specifies the number of days worth of event entries that will be kept. All older events will be deleted periodically. Also applies on Plugin Events History.",
|
"DAYS_TO_KEEP_EVENTS_description": "This is a maintenance setting. This specifies the number of days worth of event entries that will be kept. All older events will be deleted periodically. Also applies on Plugin Events History.",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "Delete events older than",
|
"DAYS_TO_KEEP_EVENTS_name": "Delete events older than",
|
||||||
"DISCOVER_PLUGINS_description": "Disable this option to speed up initialization and settings saving. When disabled, plugins are not discovered, and you cannot add new plugins to the <code>LOADED_PLUGINS</code> setting.",
|
"DISCOVER_PLUGINS_description": "Disable this option to speed up initialization and settings saving. When disabled, plugins are not discovered, and you cannot add new plugins to the <code>LOADED_PLUGINS</code> setting.",
|
||||||
"DISCOVER_PLUGINS_name": "Discover plugins",
|
"DISCOVER_PLUGINS_name": "Discover plugins",
|
||||||
"DevDetail_Copy_Device_Title": "Copy details from device",
|
"DevDetail_Copy_Device_Title": "Copy details from device",
|
||||||
"DevDetail_Copy_Device_Tooltip": "Copy details from device from the dropdown list. Everything on this page will be overwritten",
|
"DevDetail_Copy_Device_Tooltip": "Copy details from device from the dropdown list. Everything on this page will be overwritten",
|
||||||
|
"DevDetail_CustomProperties_Title": "Custom Properties",
|
||||||
|
"DevDetail_CustomProps_reset_info": "This will remove your custom properties on this device and reset them to the default value.",
|
||||||
"DevDetail_DisplayFields_Title": "Display",
|
"DevDetail_DisplayFields_Title": "Display",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "Alert Events",
|
"DevDetail_EveandAl_AlertAllEvents": "Alert Events",
|
||||||
"DevDetail_EveandAl_AlertDown": "Alert Down",
|
"DevDetail_EveandAl_AlertDown": "Alert Down",
|
||||||
@@ -182,6 +185,7 @@
|
|||||||
"DevDetail_button_Delete": "Delete Device",
|
"DevDetail_button_Delete": "Delete Device",
|
||||||
"DevDetail_button_DeleteEvents": "Delete Events",
|
"DevDetail_button_DeleteEvents": "Delete Events",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "Are you sure you want to delete all Events of this device?<br><br>(this will clear the <b>Events history</b> and the <b>Sessions</b> and might help with constant (persistent) notifications)",
|
"DevDetail_button_DeleteEvents_Warning": "Are you sure you want to delete all Events of this device?<br><br>(this will clear the <b>Events history</b> and the <b>Sessions</b> and might help with constant (persistent) notifications)",
|
||||||
|
"DevDetail_button_Delete_ask": "Are you sure you want to delete this device? You may also archive it instead.",
|
||||||
"DevDetail_button_OverwriteIcons": "Overwrite Icons",
|
"DevDetail_button_OverwriteIcons": "Overwrite Icons",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "Overwrite icons of all devices with the same device type",
|
"DevDetail_button_OverwriteIcons_Tooltip": "Overwrite icons of all devices with the same device type",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "Are you sure you want to overwrite all icons of all devices with the same device type as the current device type?",
|
"DevDetail_button_OverwriteIcons_Warning": "Are you sure you want to overwrite all icons of all devices with the same device type as the current device type?",
|
||||||
@@ -205,6 +209,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "Device presence",
|
"Device_Shortcut_OnlineChart": "Device presence",
|
||||||
"Device_TableHead_AlertDown": "Alert Down",
|
"Device_TableHead_AlertDown": "Alert Down",
|
||||||
"Device_TableHead_Connected_Devices": "Connections",
|
"Device_TableHead_Connected_Devices": "Connections",
|
||||||
|
"Device_TableHead_CustomProps": "Props / Actions",
|
||||||
"Device_TableHead_Favorite": "Favorite",
|
"Device_TableHead_Favorite": "Favorite",
|
||||||
"Device_TableHead_FirstSession": "First Session",
|
"Device_TableHead_FirstSession": "First Session",
|
||||||
"Device_TableHead_GUID": "GUID",
|
"Device_TableHead_GUID": "GUID",
|
||||||
@@ -243,6 +248,8 @@
|
|||||||
"Donations_Title": "Donations",
|
"Donations_Title": "Donations",
|
||||||
"ENABLE_PLUGINS_description": "Enables the <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a> functionality. Loading plugins requires more hardware resources so you might want to disable them on low-powered system.",
|
"ENABLE_PLUGINS_description": "Enables the <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a> functionality. Loading plugins requires more hardware resources so you might want to disable them on low-powered system.",
|
||||||
"ENABLE_PLUGINS_name": "Enable Plugins",
|
"ENABLE_PLUGINS_name": "Enable Plugins",
|
||||||
|
"ENCRYPTION_KEY_description": "Data encryption key.",
|
||||||
|
"ENCRYPTION_KEY_name": "Encryption key",
|
||||||
"Email_display_name": "Email",
|
"Email_display_name": "Email",
|
||||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||||
"Events_Loading": "Loading...",
|
"Events_Loading": "Loading...",
|
||||||
@@ -278,7 +285,7 @@
|
|||||||
"Events_Tablelenght": "Show _MENU_ entries",
|
"Events_Tablelenght": "Show _MENU_ entries",
|
||||||
"Events_Tablelenght_all": "All",
|
"Events_Tablelenght_all": "All",
|
||||||
"Events_Title": "Events",
|
"Events_Title": "Events",
|
||||||
"GRAPHQL_PORT_description": "The port number of the GraphQL server.",
|
"GRAPHQL_PORT_description": "The port number of the GraphQL server. Make sure the port is unique across all your applications on this host and NetAlertX instances.",
|
||||||
"GRAPHQL_PORT_name": "GraphQL port",
|
"GRAPHQL_PORT_name": "GraphQL port",
|
||||||
"Gen_Action": "Action",
|
"Gen_Action": "Action",
|
||||||
"Gen_Add": "Add",
|
"Gen_Add": "Add",
|
||||||
@@ -305,6 +312,7 @@
|
|||||||
"Gen_ReadDocs": "Read more in the docs.",
|
"Gen_ReadDocs": "Read more in the docs.",
|
||||||
"Gen_Remove_All": "Remove all",
|
"Gen_Remove_All": "Remove all",
|
||||||
"Gen_Remove_Last": "Remove last",
|
"Gen_Remove_Last": "Remove last",
|
||||||
|
"Gen_Reset": "Reset",
|
||||||
"Gen_Restore": "Run Restore",
|
"Gen_Restore": "Run Restore",
|
||||||
"Gen_Run": "Run",
|
"Gen_Run": "Run",
|
||||||
"Gen_Save": "Save",
|
"Gen_Save": "Save",
|
||||||
@@ -481,7 +489,7 @@
|
|||||||
"Maintenance_themeselector_lable": "Select Skin",
|
"Maintenance_themeselector_lable": "Select Skin",
|
||||||
"Maintenance_themeselector_text": "The change takes place on the server side, so it affects all devices in use.",
|
"Maintenance_themeselector_text": "The change takes place on the server side, so it affects all devices in use.",
|
||||||
"Maintenance_version": "App updates",
|
"Maintenance_version": "App updates",
|
||||||
"NETWORK_DEVICE_TYPES_description": "Which device types are allowed to be used as network devices in the Network view. The device type has to match exactly the <code>Type</code> setting on a specific device in Device details. Do not remove existing types, only add new ones.",
|
"NETWORK_DEVICE_TYPES_description": "Which device types are allowed to be used as network devices in the Network view. The device type has to match exactly the <code>Type</code> setting on a specific device in Device details. Add it on teh Device via the <code>+</code> button. Do not remove existing types, only add new ones.",
|
||||||
"NETWORK_DEVICE_TYPES_name": "Network device types",
|
"NETWORK_DEVICE_TYPES_name": "Network device types",
|
||||||
"Navigation_About": "About",
|
"Navigation_About": "About",
|
||||||
"Navigation_Devices": "Devices",
|
"Navigation_Devices": "Devices",
|
||||||
|
|||||||
@@ -70,12 +70,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "Darkmode Activado",
|
"BackDevices_darkmode_enabled": "Darkmode Activado",
|
||||||
"CLEAR_NEW_FLAG_description": "Si está habilitado (<code>0</code> está desactivado), los dispositivos marcados como <b>Nuevo dispositivo</b> se desmarcarán si el límite de tiempo (especificado en horas) excede su tiempo de <b>primera sesión</b>.",
|
"CLEAR_NEW_FLAG_description": "Si está habilitado (<code>0</code> está desactivado), los dispositivos marcados como <b>Nuevo dispositivo</b> se desmarcarán si el límite de tiempo (especificado en horas) excede su tiempo de <b>primera sesión</b>.",
|
||||||
"CLEAR_NEW_FLAG_name": "Eliminar la nueva bandera",
|
"CLEAR_NEW_FLAG_name": "Eliminar la nueva bandera",
|
||||||
|
"CustProps_cant_remove": "",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "Esta es una configuración de mantenimiento. Esto especifica el número de días de entradas de eventos que se guardarán. Todos los eventos anteriores se eliminarán periódicamente.",
|
"DAYS_TO_KEEP_EVENTS_description": "Esta es una configuración de mantenimiento. Esto especifica el número de días de entradas de eventos que se guardarán. Todos los eventos anteriores se eliminarán periódicamente.",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "Eliminar eventos anteriores a",
|
"DAYS_TO_KEEP_EVENTS_name": "Eliminar eventos anteriores a",
|
||||||
"DISCOVER_PLUGINS_description": "",
|
"DISCOVER_PLUGINS_description": "Desactive esta opción para acelerar la inicialización y el ahorro de ajustes. Cuando está desactivado, los plugins no se descubren y no puede añadir nuevos plugins a la configuración <code>LOADED_PLUGINS</code>.",
|
||||||
"DISCOVER_PLUGINS_name": "",
|
"DISCOVER_PLUGINS_name": "Descubrir plugins",
|
||||||
"DevDetail_Copy_Device_Title": "Copiar detalles del dispositivo",
|
"DevDetail_Copy_Device_Title": "Copiar detalles del dispositivo",
|
||||||
"DevDetail_Copy_Device_Tooltip": "Copiar detalles del dispositivo de la lista desplegable. Todo en esta página se sobrescribirá",
|
"DevDetail_Copy_Device_Tooltip": "Copiar detalles del dispositivo de la lista desplegable. Todo en esta página se sobrescribirá",
|
||||||
|
"DevDetail_CustomProperties_Title": "",
|
||||||
|
"DevDetail_CustomProps_reset_info": "",
|
||||||
"DevDetail_DisplayFields_Title": "Mostrar",
|
"DevDetail_DisplayFields_Title": "Mostrar",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "Notificaciones de eventos",
|
"DevDetail_EveandAl_AlertAllEvents": "Notificaciones de eventos",
|
||||||
"DevDetail_EveandAl_AlertDown": "Alerta de caída",
|
"DevDetail_EveandAl_AlertDown": "Alerta de caída",
|
||||||
@@ -192,6 +195,7 @@
|
|||||||
"DevDetail_button_Delete": "Eliminar dispositivo",
|
"DevDetail_button_Delete": "Eliminar dispositivo",
|
||||||
"DevDetail_button_DeleteEvents": "Eliminar eventos",
|
"DevDetail_button_DeleteEvents": "Eliminar eventos",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "¿Desea eliminar todos los eventos de este dispositivo?<br><br>(se eliminarán el <b>Historial de eventos</b> y las <b>Sesiones</b>, y puede ayudar en el caso de notificaciones constantes)",
|
"DevDetail_button_DeleteEvents_Warning": "¿Desea eliminar todos los eventos de este dispositivo?<br><br>(se eliminarán el <b>Historial de eventos</b> y las <b>Sesiones</b>, y puede ayudar en el caso de notificaciones constantes)",
|
||||||
|
"DevDetail_button_Delete_ask": "",
|
||||||
"DevDetail_button_OverwriteIcons": "Sobreescribir iconos",
|
"DevDetail_button_OverwriteIcons": "Sobreescribir iconos",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "Sobreescribir los iconos de todos los dispositivos con el mismo tipo",
|
"DevDetail_button_OverwriteIcons_Tooltip": "Sobreescribir los iconos de todos los dispositivos con el mismo tipo",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "¿Sobreescribir todos los iconos de todos los dispositivos con el mismo tipo que el dispositivo actual?",
|
"DevDetail_button_OverwriteIcons_Warning": "¿Sobreescribir todos los iconos de todos los dispositivos con el mismo tipo que el dispositivo actual?",
|
||||||
@@ -215,6 +219,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "Presencia del dispositivo a lo largo del tiempo",
|
"Device_Shortcut_OnlineChart": "Presencia del dispositivo a lo largo del tiempo",
|
||||||
"Device_TableHead_AlertDown": "Alerta desactivada",
|
"Device_TableHead_AlertDown": "Alerta desactivada",
|
||||||
"Device_TableHead_Connected_Devices": "Conexiones",
|
"Device_TableHead_Connected_Devices": "Conexiones",
|
||||||
|
"Device_TableHead_CustomProps": "",
|
||||||
"Device_TableHead_Favorite": "Favorito",
|
"Device_TableHead_Favorite": "Favorito",
|
||||||
"Device_TableHead_FirstSession": "1ra. sesión",
|
"Device_TableHead_FirstSession": "1ra. sesión",
|
||||||
"Device_TableHead_GUID": "GUID",
|
"Device_TableHead_GUID": "GUID",
|
||||||
@@ -253,6 +258,8 @@
|
|||||||
"Donations_Title": "Donaciones",
|
"Donations_Title": "Donaciones",
|
||||||
"ENABLE_PLUGINS_description": "Habilita la funcionalidad de los <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">complementos</a>. Cargar los complementos requiere más recursos de hardware, así que quizás quieras desactivarlo en hardware poco potente.",
|
"ENABLE_PLUGINS_description": "Habilita la funcionalidad de los <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">complementos</a>. Cargar los complementos requiere más recursos de hardware, así que quizás quieras desactivarlo en hardware poco potente.",
|
||||||
"ENABLE_PLUGINS_name": "Habilitar complementos",
|
"ENABLE_PLUGINS_name": "Habilitar complementos",
|
||||||
|
"ENCRYPTION_KEY_description": "",
|
||||||
|
"ENCRYPTION_KEY_name": "",
|
||||||
"Email_display_name": "Email",
|
"Email_display_name": "Email",
|
||||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||||
"Events_Loading": "Cargando...",
|
"Events_Loading": "Cargando...",
|
||||||
@@ -315,6 +322,7 @@
|
|||||||
"Gen_ReadDocs": "Lee más en los documentos.",
|
"Gen_ReadDocs": "Lee más en los documentos.",
|
||||||
"Gen_Remove_All": "Quitar todo",
|
"Gen_Remove_All": "Quitar todo",
|
||||||
"Gen_Remove_Last": "Quitar el último",
|
"Gen_Remove_Last": "Quitar el último",
|
||||||
|
"Gen_Reset": "",
|
||||||
"Gen_Restore": "Ejecutar restauración",
|
"Gen_Restore": "Ejecutar restauración",
|
||||||
"Gen_Run": "Ejecutar",
|
"Gen_Run": "Ejecutar",
|
||||||
"Gen_Save": "Guardar",
|
"Gen_Save": "Guardar",
|
||||||
@@ -331,8 +339,8 @@
|
|||||||
"Gen_Update_Value": "Actualizar valor",
|
"Gen_Update_Value": "Actualizar valor",
|
||||||
"Gen_Warning": "Advertencia",
|
"Gen_Warning": "Advertencia",
|
||||||
"Gen_Work_In_Progress": "Trabajo en curso, un buen momento para hacer comentarios en https://github.com/jokob-sk/NetAlertX/issues",
|
"Gen_Work_In_Progress": "Trabajo en curso, un buen momento para hacer comentarios en https://github.com/jokob-sk/NetAlertX/issues",
|
||||||
"Gen_create_new_device": "Crear un dispositivo ficticio",
|
"Gen_create_new_device": "Nuevo dispositivo",
|
||||||
"Gen_create_new_device_info": "",
|
"Gen_create_new_device_info": "Los dispositivos se suelen descubrir utilizando <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a>. Sin embargo, en algunos casos, es posible que necesite agregar dispositivos manualmente. Para explorar escenarios específicos, consulte la documentación <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/REMOTE_NETWORKS.md\">Redes remotas</a>.",
|
||||||
"General_display_name": "General",
|
"General_display_name": "General",
|
||||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||||
"HRS_TO_KEEP_NEWDEV_description": "Se trata de una configuración de mantenimiento <b>BORRAR dispositivos</b>. Si está activado (<code>0</code> está desactivado), los dispositivos marcados como <b>Nuevo dispositivo</b> se eliminarán si su fecha de <b>primera sesión</b> es anterior a las horas especificadas en este ajuste. Use este ajuste si desea eliminar automáticamente <b>Nuevos dispositivos</b> después de <code>X</code> horas.",
|
"HRS_TO_KEEP_NEWDEV_description": "Se trata de una configuración de mantenimiento <b>BORRAR dispositivos</b>. Si está activado (<code>0</code> está desactivado), los dispositivos marcados como <b>Nuevo dispositivo</b> se eliminarán si su fecha de <b>primera sesión</b> es anterior a las horas especificadas en este ajuste. Use este ajuste si desea eliminar automáticamente <b>Nuevos dispositivos</b> después de <code>X</code> horas.",
|
||||||
|
|||||||
@@ -60,12 +60,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "Mode sombre activé",
|
"BackDevices_darkmode_enabled": "Mode sombre activé",
|
||||||
"CLEAR_NEW_FLAG_description": "Si activé (<code>0</code> est désactivé), les appareils marqués comme <b>Nouvel appareil</b> seront démarqués si la limite de temps (spécifiée en heures) dépasse la durée de <b>Première Session</b>.",
|
"CLEAR_NEW_FLAG_description": "Si activé (<code>0</code> est désactivé), les appareils marqués comme <b>Nouvel appareil</b> seront démarqués si la limite de temps (spécifiée en heures) dépasse la durée de <b>Première Session</b>.",
|
||||||
"CLEAR_NEW_FLAG_name": "Supprime le nouveau drapeau",
|
"CLEAR_NEW_FLAG_name": "Supprime le nouveau drapeau",
|
||||||
|
"CustProps_cant_remove": "Suppression impossible, au moins une donnée est requise.",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "Il s'agit d'un paramètre de maintenance. Il indique le nombre de jours pendant lesquels les entrées d'événements seront conservées. Tous les événements plus anciens seront supprimés périodiquement. S'applique également à l'historique des événements du plugin.",
|
"DAYS_TO_KEEP_EVENTS_description": "Il s'agit d'un paramètre de maintenance. Il indique le nombre de jours pendant lesquels les entrées d'événements seront conservées. Tous les événements plus anciens seront supprimés périodiquement. S'applique également à l'historique des événements du plugin.",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "Supprimer les événements plus anciens que",
|
"DAYS_TO_KEEP_EVENTS_name": "Supprimer les événements plus anciens que",
|
||||||
"DISCOVER_PLUGINS_description": "",
|
"DISCOVER_PLUGINS_description": "Désactivez cette option pour accélérer le démarrage et l'enregistrement de paramètres. Quand elle est désactivée, les plugins ne sont pas découverts, et vous ne pouvez près ajouter de nouveaux plugins au paramètre <code>LOADED_PLUGINS</code>.",
|
||||||
"DISCOVER_PLUGINS_name": "",
|
"DISCOVER_PLUGINS_name": "Découvrir des plugins",
|
||||||
"DevDetail_Copy_Device_Title": "Copier les détails de l'appareil",
|
"DevDetail_Copy_Device_Title": "Copier les détails de l'appareil",
|
||||||
"DevDetail_Copy_Device_Tooltip": "Copier les détails de l'appareil dans la liste déroulante. Tout ce qui se trouve sur cette page sera remplacé",
|
"DevDetail_Copy_Device_Tooltip": "Copier les détails de l'appareil dans la liste déroulante. Tout ce qui se trouve sur cette page sera remplacé",
|
||||||
|
"DevDetail_CustomProperties_Title": "Champs personnalisés",
|
||||||
|
"DevDetail_CustomProps_reset_info": "Cela va supprimer vos champs personnalisés de cet appareil et les remettre à leur valeur par défaut.",
|
||||||
"DevDetail_DisplayFields_Title": "Afficher",
|
"DevDetail_DisplayFields_Title": "Afficher",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "Alerter les événements",
|
"DevDetail_EveandAl_AlertAllEvents": "Alerter les événements",
|
||||||
"DevDetail_EveandAl_AlertDown": "Alerte de panne",
|
"DevDetail_EveandAl_AlertDown": "Alerte de panne",
|
||||||
@@ -182,6 +185,7 @@
|
|||||||
"DevDetail_button_Delete": "Supprimer l'appareil",
|
"DevDetail_button_Delete": "Supprimer l'appareil",
|
||||||
"DevDetail_button_DeleteEvents": "Supprimer les événements",
|
"DevDetail_button_DeleteEvents": "Supprimer les événements",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "Êtes-vous sûr de vouloir supprimer tous les Événements de cet appareil ?<br><br>(cela supprimera l'<b>Historique des événements</b> et les <b>Sessions</b> et peur aider pour les notifications persistantes)",
|
"DevDetail_button_DeleteEvents_Warning": "Êtes-vous sûr de vouloir supprimer tous les Événements de cet appareil ?<br><br>(cela supprimera l'<b>Historique des événements</b> et les <b>Sessions</b> et peur aider pour les notifications persistantes)",
|
||||||
|
"DevDetail_button_Delete_ask": "Êtes-vous sûr de vouloir supprimer cet appareil ? Vous pouvez vouloir l'archiver plutôt.",
|
||||||
"DevDetail_button_OverwriteIcons": "Remplacer les icônes",
|
"DevDetail_button_OverwriteIcons": "Remplacer les icônes",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "Remplacer les icônes de tous les appareils de ce type",
|
"DevDetail_button_OverwriteIcons_Tooltip": "Remplacer les icônes de tous les appareils de ce type",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "Êtes-vous sûr de vouloir remplacer toutes les icônes de tous les appareils du même type que l'appareil actuel ?",
|
"DevDetail_button_OverwriteIcons_Warning": "Êtes-vous sûr de vouloir remplacer toutes les icônes de tous les appareils du même type que l'appareil actuel ?",
|
||||||
@@ -205,6 +209,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "Présence de l'appareil",
|
"Device_Shortcut_OnlineChart": "Présence de l'appareil",
|
||||||
"Device_TableHead_AlertDown": "Alerter si En panne",
|
"Device_TableHead_AlertDown": "Alerter si En panne",
|
||||||
"Device_TableHead_Connected_Devices": "Connexions",
|
"Device_TableHead_Connected_Devices": "Connexions",
|
||||||
|
"Device_TableHead_CustomProps": "Champs / Actions",
|
||||||
"Device_TableHead_Favorite": "Favori",
|
"Device_TableHead_Favorite": "Favori",
|
||||||
"Device_TableHead_FirstSession": "Première session",
|
"Device_TableHead_FirstSession": "Première session",
|
||||||
"Device_TableHead_GUID": "GUID",
|
"Device_TableHead_GUID": "GUID",
|
||||||
@@ -243,6 +248,8 @@
|
|||||||
"Donations_Title": "Dons",
|
"Donations_Title": "Dons",
|
||||||
"ENABLE_PLUGINS_description": "Active les fonctionnalités des <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">Plugins</a>. Charger des plugins nécessite plus de ressources, il est recommandé de les désactiver sur des systèmes de faible puissance.",
|
"ENABLE_PLUGINS_description": "Active les fonctionnalités des <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">Plugins</a>. Charger des plugins nécessite plus de ressources, il est recommandé de les désactiver sur des systèmes de faible puissance.",
|
||||||
"ENABLE_PLUGINS_name": "Activer les Plugins",
|
"ENABLE_PLUGINS_name": "Activer les Plugins",
|
||||||
|
"ENCRYPTION_KEY_description": "",
|
||||||
|
"ENCRYPTION_KEY_name": "",
|
||||||
"Email_display_name": "Messagerie",
|
"Email_display_name": "Messagerie",
|
||||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||||
"Events_Loading": "Chargement …",
|
"Events_Loading": "Chargement …",
|
||||||
@@ -305,6 +312,7 @@
|
|||||||
"Gen_ReadDocs": "Plus d'infos dans la documentation.",
|
"Gen_ReadDocs": "Plus d'infos dans la documentation.",
|
||||||
"Gen_Remove_All": "Enlever tous",
|
"Gen_Remove_All": "Enlever tous",
|
||||||
"Gen_Remove_Last": "Enlever le dernier",
|
"Gen_Remove_Last": "Enlever le dernier",
|
||||||
|
"Gen_Reset": "Réinitialiser",
|
||||||
"Gen_Restore": "Lancer une restauration",
|
"Gen_Restore": "Lancer une restauration",
|
||||||
"Gen_Run": "Lancer",
|
"Gen_Run": "Lancer",
|
||||||
"Gen_Save": "Enregistrer",
|
"Gen_Save": "Enregistrer",
|
||||||
@@ -321,8 +329,8 @@
|
|||||||
"Gen_Update_Value": "Valeur à mettre à jour",
|
"Gen_Update_Value": "Valeur à mettre à jour",
|
||||||
"Gen_Warning": "Avertissement",
|
"Gen_Warning": "Avertissement",
|
||||||
"Gen_Work_In_Progress": "Travaux en cours, c'est le bon moment pour faire un retour via la liste d'anomalies sur Github https://github.com/jokob-sk/NetAlertX/issues",
|
"Gen_Work_In_Progress": "Travaux en cours, c'est le bon moment pour faire un retour via la liste d'anomalies sur Github https://github.com/jokob-sk/NetAlertX/issues",
|
||||||
"Gen_create_new_device": "Créer un appareil fictif",
|
"Gen_create_new_device": "Nouvel appareil",
|
||||||
"Gen_create_new_device_info": "",
|
"Gen_create_new_device_info": "Les appareils sont souvent découverts à l'aide d'un <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugin</a>. Cependant, dans certains cas, vous pouvez ajouter manuellement les appareils. Pour explorer des scénarios spécifiques, consulter la <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/REMOTE_NETWORKS.md\">documentation des réseaux distants</a>.",
|
||||||
"General_display_name": "Général",
|
"General_display_name": "Général",
|
||||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||||
"HRS_TO_KEEP_NEWDEV_description": "Paramètre de maintenance. S'il est activé (<code>0</code> s'il est désactivé), les appareils marqués comme <b>Nouvel appareil</b> seront supprimés si leur durée depuis la <b>première session</b> est plus ancienne que le nombre d'heures paramétré. Utilisez ce paramétrage si vous voulez supprimer automatiquement les <b>Nouveaux appareils</b> après <code>X</code> heures.",
|
"HRS_TO_KEEP_NEWDEV_description": "Paramètre de maintenance. S'il est activé (<code>0</code> s'il est désactivé), les appareils marqués comme <b>Nouvel appareil</b> seront supprimés si leur durée depuis la <b>première session</b> est plus ancienne que le nombre d'heures paramétré. Utilisez ce paramétrage si vous voulez supprimer automatiquement les <b>Nouveaux appareils</b> après <code>X</code> heures.",
|
||||||
|
|||||||
@@ -60,12 +60,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "Modalità scura abilitata",
|
"BackDevices_darkmode_enabled": "Modalità scura abilitata",
|
||||||
"CLEAR_NEW_FLAG_description": "Se abilitato (<code>0</code> è disabilitato), i dispositivi contrassegnati come <b>Nuovo dispositivo</b> verranno deselezionati se il limite di tempo (specificato in ore) supera il tempo della <b>Prima sessione</b>.",
|
"CLEAR_NEW_FLAG_description": "Se abilitato (<code>0</code> è disabilitato), i dispositivi contrassegnati come <b>Nuovo dispositivo</b> verranno deselezionati se il limite di tempo (specificato in ore) supera il tempo della <b>Prima sessione</b>.",
|
||||||
"CLEAR_NEW_FLAG_name": "Cancella nuova bandiera",
|
"CLEAR_NEW_FLAG_name": "Cancella nuova bandiera",
|
||||||
|
"CustProps_cant_remove": "Impossibile rimuovere, è necessaria almeno una proprietà.",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "Questa è un'impostazione di manutenzione. Specifica il numero di giorni delle voci degli eventi che verranno conservati. Tutti gli eventi più vecchi verranno eliminati periodicamente. Si applica anche alla cronologia degli eventi del plugin (Plugin Events History).",
|
"DAYS_TO_KEEP_EVENTS_description": "Questa è un'impostazione di manutenzione. Specifica il numero di giorni delle voci degli eventi che verranno conservati. Tutti gli eventi più vecchi verranno eliminati periodicamente. Si applica anche alla cronologia degli eventi del plugin (Plugin Events History).",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "Elimina eventi più vecchi di",
|
"DAYS_TO_KEEP_EVENTS_name": "Elimina eventi più vecchi di",
|
||||||
"DISCOVER_PLUGINS_description": "Disattiva questa opzione per velocizzare l'inizializzazione e il salvataggio delle impostazioni. Quando è disattivata, i plugin non vengono scoperti e non puoi aggiungere nuovi plugin all'impostazione <code>LOADED_PLUGINS</code>.",
|
"DISCOVER_PLUGINS_description": "Disattiva questa opzione per velocizzare l'inizializzazione e il salvataggio delle impostazioni. Quando è disattivata, i plugin non vengono scoperti e non puoi aggiungere nuovi plugin all'impostazione <code>LOADED_PLUGINS</code>.",
|
||||||
"DISCOVER_PLUGINS_name": "Scopri i plugin",
|
"DISCOVER_PLUGINS_name": "Scopri i plugin",
|
||||||
"DevDetail_Copy_Device_Title": "Copia dettagli dal dispositivo",
|
"DevDetail_Copy_Device_Title": "Copia dettagli dal dispositivo",
|
||||||
"DevDetail_Copy_Device_Tooltip": "Copia i dettagli dal dispositivo dall'elenco a discesa. Tutto in questa pagina verrà sovrascritto",
|
"DevDetail_Copy_Device_Tooltip": "Copia i dettagli dal dispositivo dall'elenco a discesa. Tutto in questa pagina verrà sovrascritto",
|
||||||
|
"DevDetail_CustomProperties_Title": "Proprietà personalizzate",
|
||||||
|
"DevDetail_CustomProps_reset_info": "Questa operazione rimuoverà le proprietà personalizzate su questo dispositivo e le ripristinerà al valore predefinito.",
|
||||||
"DevDetail_DisplayFields_Title": "Visualizza",
|
"DevDetail_DisplayFields_Title": "Visualizza",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "Notifica eventi",
|
"DevDetail_EveandAl_AlertAllEvents": "Notifica eventi",
|
||||||
"DevDetail_EveandAl_AlertDown": "Avviso disconnessione",
|
"DevDetail_EveandAl_AlertDown": "Avviso disconnessione",
|
||||||
@@ -182,6 +185,7 @@
|
|||||||
"DevDetail_button_Delete": "Elimina dispositivo",
|
"DevDetail_button_Delete": "Elimina dispositivo",
|
||||||
"DevDetail_button_DeleteEvents": "Elimina eventi",
|
"DevDetail_button_DeleteEvents": "Elimina eventi",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "Sei sicuro di voler eliminare tutti gli eventi di questo dispositivo?<br><br>(questa azione cancellerà la <b>Cronologia eventi</b> e le <b>Sessioni</b> e potrebbe aiutare con costanti (persistenti ) notifiche)",
|
"DevDetail_button_DeleteEvents_Warning": "Sei sicuro di voler eliminare tutti gli eventi di questo dispositivo?<br><br>(questa azione cancellerà la <b>Cronologia eventi</b> e le <b>Sessioni</b> e potrebbe aiutare con costanti (persistenti ) notifiche)",
|
||||||
|
"DevDetail_button_Delete_ask": "Vuoi davvero eliminare questo dispositivo? Puoi anche archiviarlo.",
|
||||||
"DevDetail_button_OverwriteIcons": "Sovrascrivi icone",
|
"DevDetail_button_OverwriteIcons": "Sovrascrivi icone",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "Sovrascrivi le icone di tutti i dispositivi con lo stesso tipo di dispositivo",
|
"DevDetail_button_OverwriteIcons_Tooltip": "Sovrascrivi le icone di tutti i dispositivi con lo stesso tipo di dispositivo",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "Sei sicuro di voler sovrascrivere tutte le icone di tutti i dispositivi con lo stesso tipo di dispositivo come l'attuale tipo di dispositivo?",
|
"DevDetail_button_OverwriteIcons_Warning": "Sei sicuro di voler sovrascrivere tutte le icone di tutti i dispositivi con lo stesso tipo di dispositivo come l'attuale tipo di dispositivo?",
|
||||||
@@ -205,6 +209,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "Presenza dispositivo",
|
"Device_Shortcut_OnlineChart": "Presenza dispositivo",
|
||||||
"Device_TableHead_AlertDown": "Avviso disconnessione",
|
"Device_TableHead_AlertDown": "Avviso disconnessione",
|
||||||
"Device_TableHead_Connected_Devices": "Connessioni",
|
"Device_TableHead_Connected_Devices": "Connessioni",
|
||||||
|
"Device_TableHead_CustomProps": "Proprietà/Azioni",
|
||||||
"Device_TableHead_Favorite": "Preferito",
|
"Device_TableHead_Favorite": "Preferito",
|
||||||
"Device_TableHead_FirstSession": "Prima sessione",
|
"Device_TableHead_FirstSession": "Prima sessione",
|
||||||
"Device_TableHead_GUID": "GUID",
|
"Device_TableHead_GUID": "GUID",
|
||||||
@@ -243,6 +248,8 @@
|
|||||||
"Donations_Title": "Donazioni",
|
"Donations_Title": "Donazioni",
|
||||||
"ENABLE_PLUGINS_description": "Abilita la funzionalità <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugin</a>. Utilizzare i plugin richiede più risorse hardware, potresti voler disabilitare questa opzione sui dispositivi meno performanti.",
|
"ENABLE_PLUGINS_description": "Abilita la funzionalità <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugin</a>. Utilizzare i plugin richiede più risorse hardware, potresti voler disabilitare questa opzione sui dispositivi meno performanti.",
|
||||||
"ENABLE_PLUGINS_name": "Abilita plugin",
|
"ENABLE_PLUGINS_name": "Abilita plugin",
|
||||||
|
"ENCRYPTION_KEY_description": "Chiave di crittografia dei dati.",
|
||||||
|
"ENCRYPTION_KEY_name": "Chiave di crittografia",
|
||||||
"Email_display_name": "E-mail",
|
"Email_display_name": "E-mail",
|
||||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||||
"Events_Loading": "Caricamento...",
|
"Events_Loading": "Caricamento...",
|
||||||
@@ -278,7 +285,7 @@
|
|||||||
"Events_Tablelenght": "Mostra _MENU_ elementi",
|
"Events_Tablelenght": "Mostra _MENU_ elementi",
|
||||||
"Events_Tablelenght_all": "Tutti",
|
"Events_Tablelenght_all": "Tutti",
|
||||||
"Events_Title": "Eventi",
|
"Events_Title": "Eventi",
|
||||||
"GRAPHQL_PORT_description": "Il numero di porta del server GraphQL.",
|
"GRAPHQL_PORT_description": "Il numero di porta del server GraphQL. Assicurati che la porta sia univoca in tutte le tue applicazioni su questo host e nelle istanze di NetAlertX.",
|
||||||
"GRAPHQL_PORT_name": "Porta GraphQL",
|
"GRAPHQL_PORT_name": "Porta GraphQL",
|
||||||
"Gen_Action": "Azione",
|
"Gen_Action": "Azione",
|
||||||
"Gen_Add": "Aggiungi",
|
"Gen_Add": "Aggiungi",
|
||||||
@@ -305,6 +312,7 @@
|
|||||||
"Gen_ReadDocs": "Maggiori informazioni nella documentazione.",
|
"Gen_ReadDocs": "Maggiori informazioni nella documentazione.",
|
||||||
"Gen_Remove_All": "Rimuovi tutti",
|
"Gen_Remove_All": "Rimuovi tutti",
|
||||||
"Gen_Remove_Last": "Rimuovi ultimo",
|
"Gen_Remove_Last": "Rimuovi ultimo",
|
||||||
|
"Gen_Reset": "Reimposta",
|
||||||
"Gen_Restore": "Esegui ripristino",
|
"Gen_Restore": "Esegui ripristino",
|
||||||
"Gen_Run": "Esegui",
|
"Gen_Run": "Esegui",
|
||||||
"Gen_Save": "Salva",
|
"Gen_Save": "Salva",
|
||||||
@@ -481,7 +489,7 @@
|
|||||||
"Maintenance_themeselector_lable": "Seleziona skin",
|
"Maintenance_themeselector_lable": "Seleziona skin",
|
||||||
"Maintenance_themeselector_text": "Questa modifica avviene lato server, quindi influenza tutti i dispositivi in uso.",
|
"Maintenance_themeselector_text": "Questa modifica avviene lato server, quindi influenza tutti i dispositivi in uso.",
|
||||||
"Maintenance_version": "Aggiornamenti app",
|
"Maintenance_version": "Aggiornamenti app",
|
||||||
"NETWORK_DEVICE_TYPES_description": "Quali tipi di dispositivi possono essere utilizzati come dispositivi di rete nella visualizzazione di rete. Il tipo di dispositivo deve corrispondere esattamente all'impostazione <code>Tipo</code> su un dispositivo specifico in dettagli dispositivo. Non rimuovere i tipi esistenti, aggiungine solo di nuovi.",
|
"NETWORK_DEVICE_TYPES_description": "Quali tipi di dispositivo possono essere utilizzati come dispositivi di rete nella vista Rete. Il tipo di dispositivo deve corrispondere esattamente all'impostazione <code>Tipo</code> su un dispositivo specifico nei Dettagli dispositivo. Aggiungilo sul Dispositivo tramite il pulsante <code>+</code>. Non rimuovere i tipi esistenti, aggiungine solo di nuovi.",
|
||||||
"NETWORK_DEVICE_TYPES_name": "Tipi di dispositivi di rete",
|
"NETWORK_DEVICE_TYPES_name": "Tipi di dispositivi di rete",
|
||||||
"Navigation_About": "Informazioni su",
|
"Navigation_About": "Informazioni su",
|
||||||
"Navigation_Devices": "Dispositivi",
|
"Navigation_Devices": "Dispositivi",
|
||||||
|
|||||||
@@ -60,12 +60,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "Mørk modus Aktivert",
|
"BackDevices_darkmode_enabled": "Mørk modus Aktivert",
|
||||||
"CLEAR_NEW_FLAG_description": "",
|
"CLEAR_NEW_FLAG_description": "",
|
||||||
"CLEAR_NEW_FLAG_name": "",
|
"CLEAR_NEW_FLAG_name": "",
|
||||||
|
"CustProps_cant_remove": "",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "Dette er en vedlikeholdsinnstilling. Dette spesifiserer antall dager verdt med hendelsesoppføringer som vil beholdes. Alle eldre hendelser vil bli slettet med jevne mellomrom. Gjelder også for plugin-hendelseshistorikk.",
|
"DAYS_TO_KEEP_EVENTS_description": "Dette er en vedlikeholdsinnstilling. Dette spesifiserer antall dager verdt med hendelsesoppføringer som vil beholdes. Alle eldre hendelser vil bli slettet med jevne mellomrom. Gjelder også for plugin-hendelseshistorikk.",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "Slett hendelser eldre enn",
|
"DAYS_TO_KEEP_EVENTS_name": "Slett hendelser eldre enn",
|
||||||
"DISCOVER_PLUGINS_description": "",
|
"DISCOVER_PLUGINS_description": "",
|
||||||
"DISCOVER_PLUGINS_name": "",
|
"DISCOVER_PLUGINS_name": "",
|
||||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Kopier detaljer fra enhet",
|
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Kopier detaljer fra enhet",
|
||||||
"DevDetail_Copy_Device_Tooltip": "Kopier detaljer fra enheten via nedtrekks menyen. Alt på denne siden vil bli overskrevet",
|
"DevDetail_Copy_Device_Tooltip": "Kopier detaljer fra enheten via nedtrekks menyen. Alt på denne siden vil bli overskrevet",
|
||||||
|
"DevDetail_CustomProperties_Title": "",
|
||||||
|
"DevDetail_CustomProps_reset_info": "",
|
||||||
"DevDetail_DisplayFields_Title": "",
|
"DevDetail_DisplayFields_Title": "",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "Varsel Alle Hendelser",
|
"DevDetail_EveandAl_AlertAllEvents": "Varsel Alle Hendelser",
|
||||||
"DevDetail_EveandAl_AlertDown": "Varsel Nede",
|
"DevDetail_EveandAl_AlertDown": "Varsel Nede",
|
||||||
@@ -182,6 +185,7 @@
|
|||||||
"DevDetail_button_Delete": "Slett Enhet",
|
"DevDetail_button_Delete": "Slett Enhet",
|
||||||
"DevDetail_button_DeleteEvents": "Slett Hendelser",
|
"DevDetail_button_DeleteEvents": "Slett Hendelser",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "Er du sikker på at du vil slette alle hendelser på denne enheten?<br><br>(dette vil tømme <b>hendelsesloggen</b> og <b>øktene</b> og kan hjelpe med konstante (vedvarende) varslinger)",
|
"DevDetail_button_DeleteEvents_Warning": "Er du sikker på at du vil slette alle hendelser på denne enheten?<br><br>(dette vil tømme <b>hendelsesloggen</b> og <b>øktene</b> og kan hjelpe med konstante (vedvarende) varslinger)",
|
||||||
|
"DevDetail_button_Delete_ask": "",
|
||||||
"DevDetail_button_OverwriteIcons": "Overskriv ikoner",
|
"DevDetail_button_OverwriteIcons": "Overskriv ikoner",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "Overskriv ikoner på alle enheter med samme enhetstype",
|
"DevDetail_button_OverwriteIcons_Tooltip": "Overskriv ikoner på alle enheter med samme enhetstype",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "Er du sikker på at du vil overskrive alle ikonene på alle enheter med samme enhetstype som gjeldende enhetstype?",
|
"DevDetail_button_OverwriteIcons_Warning": "Er du sikker på at du vil overskrive alle ikonene på alle enheter med samme enhetstype som gjeldende enhetstype?",
|
||||||
@@ -205,6 +209,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "Enhetens tilstedeværelse",
|
"Device_Shortcut_OnlineChart": "Enhetens tilstedeværelse",
|
||||||
"Device_TableHead_AlertDown": "",
|
"Device_TableHead_AlertDown": "",
|
||||||
"Device_TableHead_Connected_Devices": "Tilkoblinger",
|
"Device_TableHead_Connected_Devices": "Tilkoblinger",
|
||||||
|
"Device_TableHead_CustomProps": "",
|
||||||
"Device_TableHead_Favorite": "Favoritt",
|
"Device_TableHead_Favorite": "Favoritt",
|
||||||
"Device_TableHead_FirstSession": "Første Økt",
|
"Device_TableHead_FirstSession": "Første Økt",
|
||||||
"Device_TableHead_GUID": "GUID",
|
"Device_TableHead_GUID": "GUID",
|
||||||
@@ -243,6 +248,8 @@
|
|||||||
"Donations_Title": "Donasjoner",
|
"Donations_Title": "Donasjoner",
|
||||||
"ENABLE_PLUGINS_description": "Aktiverer <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a> funksjonaliten. Å laste inn plugins krever mer maskinvareressurser, så det kan være lurt å deaktivere dem på et system med lav strøm.",
|
"ENABLE_PLUGINS_description": "Aktiverer <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a> funksjonaliten. Å laste inn plugins krever mer maskinvareressurser, så det kan være lurt å deaktivere dem på et system med lav strøm.",
|
||||||
"ENABLE_PLUGINS_name": "Aktiver Plugins",
|
"ENABLE_PLUGINS_name": "Aktiver Plugins",
|
||||||
|
"ENCRYPTION_KEY_description": "",
|
||||||
|
"ENCRYPTION_KEY_name": "",
|
||||||
"Email_display_name": "E-post",
|
"Email_display_name": "E-post",
|
||||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||||
"Events_Loading": "Laster...",
|
"Events_Loading": "Laster...",
|
||||||
@@ -305,6 +312,7 @@
|
|||||||
"Gen_ReadDocs": "Les mer i dokumentasjonen.",
|
"Gen_ReadDocs": "Les mer i dokumentasjonen.",
|
||||||
"Gen_Remove_All": "Fjern alle",
|
"Gen_Remove_All": "Fjern alle",
|
||||||
"Gen_Remove_Last": "Fjern sist",
|
"Gen_Remove_Last": "Fjern sist",
|
||||||
|
"Gen_Reset": "",
|
||||||
"Gen_Restore": "Kjør Gjenopprett",
|
"Gen_Restore": "Kjør Gjenopprett",
|
||||||
"Gen_Run": "Kjør",
|
"Gen_Run": "Kjør",
|
||||||
"Gen_Save": "Lagre",
|
"Gen_Save": "Lagre",
|
||||||
|
|||||||
@@ -60,12 +60,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "Tryb ciemny Włączony",
|
"BackDevices_darkmode_enabled": "Tryb ciemny Włączony",
|
||||||
"CLEAR_NEW_FLAG_description": "",
|
"CLEAR_NEW_FLAG_description": "",
|
||||||
"CLEAR_NEW_FLAG_name": "",
|
"CLEAR_NEW_FLAG_name": "",
|
||||||
|
"CustProps_cant_remove": "",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "To jest ustawienie konserwacji. Określa ile dni mają być utrzymywane wpisy wydarzeń. Wszystkie starsze wpisy wydarzeń zostaną usunięte okresowo. Dotyczy także Historii Wydarzeń Pluginów.",
|
"DAYS_TO_KEEP_EVENTS_description": "To jest ustawienie konserwacji. Określa ile dni mają być utrzymywane wpisy wydarzeń. Wszystkie starsze wpisy wydarzeń zostaną usunięte okresowo. Dotyczy także Historii Wydarzeń Pluginów.",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "Usuń wydarzenia starsze niż",
|
"DAYS_TO_KEEP_EVENTS_name": "Usuń wydarzenia starsze niż",
|
||||||
"DISCOVER_PLUGINS_description": "",
|
"DISCOVER_PLUGINS_description": "",
|
||||||
"DISCOVER_PLUGINS_name": "",
|
"DISCOVER_PLUGINS_name": "",
|
||||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i>Kopiuj opis z urządzenia",
|
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i>Kopiuj opis z urządzenia",
|
||||||
"DevDetail_Copy_Device_Tooltip": "Kopiuj opis z urządzenia z listy rozwijanej. Wszystko na tej stronie zostanie nadpisane",
|
"DevDetail_Copy_Device_Tooltip": "Kopiuj opis z urządzenia z listy rozwijanej. Wszystko na tej stronie zostanie nadpisane",
|
||||||
|
"DevDetail_CustomProperties_Title": "",
|
||||||
|
"DevDetail_CustomProps_reset_info": "",
|
||||||
"DevDetail_DisplayFields_Title": "",
|
"DevDetail_DisplayFields_Title": "",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "Powiadamiaj o wszystkich wydarzeniach",
|
"DevDetail_EveandAl_AlertAllEvents": "Powiadamiaj o wszystkich wydarzeniach",
|
||||||
"DevDetail_EveandAl_AlertDown": "Wyłącz powiadomienia",
|
"DevDetail_EveandAl_AlertDown": "Wyłącz powiadomienia",
|
||||||
@@ -182,6 +185,7 @@
|
|||||||
"DevDetail_button_Delete": "Usuń Urządzenie",
|
"DevDetail_button_Delete": "Usuń Urządzenie",
|
||||||
"DevDetail_button_DeleteEvents": "Usuń Wydarzenia",
|
"DevDetail_button_DeleteEvents": "Usuń Wydarzenia",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "Jesteś pewien, że chcesz usunąć wszystkie Wydarzenia tego urządzenia?<br><br>(wyczyści to <b>Historię Wydarzeń</b> i <b>Sesje</b> i może pomóc ze stałymi powiadomieniami)",
|
"DevDetail_button_DeleteEvents_Warning": "Jesteś pewien, że chcesz usunąć wszystkie Wydarzenia tego urządzenia?<br><br>(wyczyści to <b>Historię Wydarzeń</b> i <b>Sesje</b> i może pomóc ze stałymi powiadomieniami)",
|
||||||
|
"DevDetail_button_Delete_ask": "",
|
||||||
"DevDetail_button_OverwriteIcons": "Nadpisz Ikony",
|
"DevDetail_button_OverwriteIcons": "Nadpisz Ikony",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "Nadpisz ikony dla urządzeń o tym samym typie",
|
"DevDetail_button_OverwriteIcons_Tooltip": "Nadpisz ikony dla urządzeń o tym samym typie",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "Czy na pewno chcesz nadpisać wszystkie ikony dla urządzeń o tym samym typie co to urządzenie?",
|
"DevDetail_button_OverwriteIcons_Warning": "Czy na pewno chcesz nadpisać wszystkie ikony dla urządzeń o tym samym typie co to urządzenie?",
|
||||||
@@ -205,6 +209,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "Obecność urządzenia",
|
"Device_Shortcut_OnlineChart": "Obecność urządzenia",
|
||||||
"Device_TableHead_AlertDown": "",
|
"Device_TableHead_AlertDown": "",
|
||||||
"Device_TableHead_Connected_Devices": "Połączenia",
|
"Device_TableHead_Connected_Devices": "Połączenia",
|
||||||
|
"Device_TableHead_CustomProps": "",
|
||||||
"Device_TableHead_Favorite": "Ulubione",
|
"Device_TableHead_Favorite": "Ulubione",
|
||||||
"Device_TableHead_FirstSession": "Pierwsza Sesja",
|
"Device_TableHead_FirstSession": "Pierwsza Sesja",
|
||||||
"Device_TableHead_GUID": "GUID",
|
"Device_TableHead_GUID": "GUID",
|
||||||
@@ -243,6 +248,8 @@
|
|||||||
"Donations_Title": "Dotacje",
|
"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 słabszych systemów.",
|
"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",
|
"ENABLE_PLUGINS_name": "Włącz Pluginy",
|
||||||
|
"ENCRYPTION_KEY_description": "",
|
||||||
|
"ENCRYPTION_KEY_name": "",
|
||||||
"Email_display_name": "Email",
|
"Email_display_name": "Email",
|
||||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||||
"Events_Loading": "Wczytywanie...",
|
"Events_Loading": "Wczytywanie...",
|
||||||
@@ -305,6 +312,7 @@
|
|||||||
"Gen_ReadDocs": "Przeczytaj więcej w dokumentacji.",
|
"Gen_ReadDocs": "Przeczytaj więcej w dokumentacji.",
|
||||||
"Gen_Remove_All": "Usuń wszystko",
|
"Gen_Remove_All": "Usuń wszystko",
|
||||||
"Gen_Remove_Last": "Usuń ostatnie",
|
"Gen_Remove_Last": "Usuń ostatnie",
|
||||||
|
"Gen_Reset": "",
|
||||||
"Gen_Restore": "Wykonaj Przywracanie",
|
"Gen_Restore": "Wykonaj Przywracanie",
|
||||||
"Gen_Run": "Wykonaj",
|
"Gen_Run": "Wykonaj",
|
||||||
"Gen_Save": "Zapisz",
|
"Gen_Save": "Zapisz",
|
||||||
|
|||||||
@@ -60,12 +60,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "Modo Noturno Habilitado",
|
"BackDevices_darkmode_enabled": "Modo Noturno Habilitado",
|
||||||
"CLEAR_NEW_FLAG_description": "Se habilitado (<code>0</code> está desativado), dispositivos marcados como<b>Novo Dispositivo</b> serão desmarcados se o limite (especificado em horas) exceder o tempo da <b>Primeira Sessão </b>.",
|
"CLEAR_NEW_FLAG_description": "Se habilitado (<code>0</code> está desativado), dispositivos marcados como<b>Novo Dispositivo</b> serão desmarcados se o limite (especificado em horas) exceder o tempo da <b>Primeira Sessão </b>.",
|
||||||
"CLEAR_NEW_FLAG_name": "",
|
"CLEAR_NEW_FLAG_name": "",
|
||||||
|
"CustProps_cant_remove": "",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "Esta é uma definição de manutenção. Especifica o número de dias de entradas de eventos que serão mantidas. Todos os eventos mais antigos serão eliminados periodicamente. Também se aplica ao Histórico de eventos do plug-in.",
|
"DAYS_TO_KEEP_EVENTS_description": "Esta é uma definição de manutenção. Especifica o número de dias de entradas de eventos que serão mantidas. Todos os eventos mais antigos serão eliminados periodicamente. Também se aplica ao Histórico de eventos do plug-in.",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "Excluir eventos mais antigos que",
|
"DAYS_TO_KEEP_EVENTS_name": "Excluir eventos mais antigos que",
|
||||||
"DISCOVER_PLUGINS_description": "",
|
"DISCOVER_PLUGINS_description": "",
|
||||||
"DISCOVER_PLUGINS_name": "",
|
"DISCOVER_PLUGINS_name": "",
|
||||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copiar detalhes do dispositivo",
|
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copiar detalhes do dispositivo",
|
||||||
"DevDetail_Copy_Device_Tooltip": "Copiar detalhes do dispositivo a partir da lista pendente. Tudo o que se encontra nesta página será substituído",
|
"DevDetail_Copy_Device_Tooltip": "Copiar detalhes do dispositivo a partir da lista pendente. Tudo o que se encontra nesta página será substituído",
|
||||||
|
"DevDetail_CustomProperties_Title": "",
|
||||||
|
"DevDetail_CustomProps_reset_info": "",
|
||||||
"DevDetail_DisplayFields_Title": "",
|
"DevDetail_DisplayFields_Title": "",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "Alerte Todos os Eventos",
|
"DevDetail_EveandAl_AlertAllEvents": "Alerte Todos os Eventos",
|
||||||
"DevDetail_EveandAl_AlertDown": "Alerta Desligado",
|
"DevDetail_EveandAl_AlertDown": "Alerta Desligado",
|
||||||
@@ -182,6 +185,7 @@
|
|||||||
"DevDetail_button_Delete": "Excluir dispositivo",
|
"DevDetail_button_Delete": "Excluir dispositivo",
|
||||||
"DevDetail_button_DeleteEvents": "Excluir eventos",
|
"DevDetail_button_DeleteEvents": "Excluir eventos",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "Tem certeza de que deseja excluir todos os eventos deste dispositivo?<br><br>(isso limpará o <b>Histórico de eventos</b> e as <b>sessões</b> e poderá ajudar com constantes (persistentes) notificações)",
|
"DevDetail_button_DeleteEvents_Warning": "Tem certeza de que deseja excluir todos os eventos deste dispositivo?<br><br>(isso limpará o <b>Histórico de eventos</b> e as <b>sessões</b> e poderá ajudar com constantes (persistentes) notificações)",
|
||||||
|
"DevDetail_button_Delete_ask": "",
|
||||||
"DevDetail_button_OverwriteIcons": "Substituir ícones",
|
"DevDetail_button_OverwriteIcons": "Substituir ícones",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "Substituir ícones de todos os dispositivos pelo mesmo tipo de dispositivo",
|
"DevDetail_button_OverwriteIcons_Tooltip": "Substituir ícones de todos os dispositivos pelo mesmo tipo de dispositivo",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "Tem certeza de que deseja substituir todos os ícones de todos os dispositivos pelo mesmo tipo de dispositivo do tipo de dispositivo atual?",
|
"DevDetail_button_OverwriteIcons_Warning": "Tem certeza de que deseja substituir todos os ícones de todos os dispositivos pelo mesmo tipo de dispositivo do tipo de dispositivo atual?",
|
||||||
@@ -205,6 +209,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "Presença do dispositivo",
|
"Device_Shortcut_OnlineChart": "Presença do dispositivo",
|
||||||
"Device_TableHead_AlertDown": "",
|
"Device_TableHead_AlertDown": "",
|
||||||
"Device_TableHead_Connected_Devices": "Conexões",
|
"Device_TableHead_Connected_Devices": "Conexões",
|
||||||
|
"Device_TableHead_CustomProps": "",
|
||||||
"Device_TableHead_Favorite": "Favorito",
|
"Device_TableHead_Favorite": "Favorito",
|
||||||
"Device_TableHead_FirstSession": "Primeira sessão",
|
"Device_TableHead_FirstSession": "Primeira sessão",
|
||||||
"Device_TableHead_GUID": "GUID",
|
"Device_TableHead_GUID": "GUID",
|
||||||
@@ -243,6 +248,8 @@
|
|||||||
"Donations_Title": "Doações",
|
"Donations_Title": "Doações",
|
||||||
"ENABLE_PLUGINS_description": "Ativa a funcionalidade de <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a>. Carregar plug-ins requer mais recursos de hardware, então você pode querer desativá-los em sistemas de baixa potência.",
|
"ENABLE_PLUGINS_description": "Ativa a funcionalidade de <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a>. Carregar plug-ins requer mais recursos de hardware, então você pode querer desativá-los em sistemas de baixa potência.",
|
||||||
"ENABLE_PLUGINS_name": "Habilitar plug-ins",
|
"ENABLE_PLUGINS_name": "Habilitar plug-ins",
|
||||||
|
"ENCRYPTION_KEY_description": "",
|
||||||
|
"ENCRYPTION_KEY_name": "",
|
||||||
"Email_display_name": "Email",
|
"Email_display_name": "Email",
|
||||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||||
"Events_Loading": "Carregando...",
|
"Events_Loading": "Carregando...",
|
||||||
@@ -305,6 +312,7 @@
|
|||||||
"Gen_ReadDocs": "Leia mais em documentos.",
|
"Gen_ReadDocs": "Leia mais em documentos.",
|
||||||
"Gen_Remove_All": "Remover tudo",
|
"Gen_Remove_All": "Remover tudo",
|
||||||
"Gen_Remove_Last": "Remover o último",
|
"Gen_Remove_Last": "Remover o último",
|
||||||
|
"Gen_Reset": "",
|
||||||
"Gen_Restore": "Executar restauração",
|
"Gen_Restore": "Executar restauração",
|
||||||
"Gen_Run": "Executar",
|
"Gen_Run": "Executar",
|
||||||
"Gen_Save": "Salvar",
|
"Gen_Save": "Salvar",
|
||||||
|
|||||||
@@ -60,12 +60,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "Темный режим включен",
|
"BackDevices_darkmode_enabled": "Темный режим включен",
|
||||||
"CLEAR_NEW_FLAG_description": "Если этот параметр включен (<code>0</code> отключен), устройства, помеченные как <b>Новое устройство</b>, станут неотмеченными, если лимит времени, указанный в часах, превышает время их <b>первой сессии</b>.",
|
"CLEAR_NEW_FLAG_description": "Если этот параметр включен (<code>0</code> отключен), устройства, помеченные как <b>Новое устройство</b>, станут неотмеченными, если лимит времени, указанный в часах, превышает время их <b>первой сессии</b>.",
|
||||||
"CLEAR_NEW_FLAG_name": "Удалить новый флаг",
|
"CLEAR_NEW_FLAG_name": "Удалить новый флаг",
|
||||||
|
"CustProps_cant_remove": "Невозможно удалить, необходимо хотя бы одно свойство.",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "Это настройка обслуживания. Здесь указывается количество дней, в течение которых будут храниться записи о событиях. Все старые события будут периодически удаляться. Также применимо к истории событий плагина.",
|
"DAYS_TO_KEEP_EVENTS_description": "Это настройка обслуживания. Здесь указывается количество дней, в течение которых будут храниться записи о событиях. Все старые события будут периодически удаляться. Также применимо к истории событий плагина.",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "Удалить события старше",
|
"DAYS_TO_KEEP_EVENTS_name": "Удалить события старше",
|
||||||
"DISCOVER_PLUGINS_description": "",
|
"DISCOVER_PLUGINS_description": "Отключите эту опцию, чтобы ускорить инициализацию и сохранение настроек. При отключении этой опции плагины не обнаруживаются, и вы не можете добавлять новые плагины в параметр <code>LOADED_PLUGINS</code>.",
|
||||||
"DISCOVER_PLUGINS_name": "",
|
"DISCOVER_PLUGINS_name": "Обзор плагинов",
|
||||||
"DevDetail_Copy_Device_Title": "Скопировать данные с устройства",
|
"DevDetail_Copy_Device_Title": "Скопировать данные с устройства",
|
||||||
"DevDetail_Copy_Device_Tooltip": "Скопируйте данные с устройства из раскрывающегося списка. Все на этой странице будет перезаписано",
|
"DevDetail_Copy_Device_Tooltip": "Скопируйте данные с устройства из раскрывающегося списка. Все на этой странице будет перезаписано",
|
||||||
|
"DevDetail_CustomProperties_Title": "Пользовательские свойства",
|
||||||
|
"DevDetail_CustomProps_reset_info": "Это удалит ваши пользовательские свойства на этом устройстве и вернет их к значению по умолчанию.",
|
||||||
"DevDetail_DisplayFields_Title": "Дисплей",
|
"DevDetail_DisplayFields_Title": "Дисплей",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "Оповещения о событиях",
|
"DevDetail_EveandAl_AlertAllEvents": "Оповещения о событиях",
|
||||||
"DevDetail_EveandAl_AlertDown": "Оповещение о доступности",
|
"DevDetail_EveandAl_AlertDown": "Оповещение о доступности",
|
||||||
@@ -182,6 +185,7 @@
|
|||||||
"DevDetail_button_Delete": "Удалить устройство",
|
"DevDetail_button_Delete": "Удалить устройство",
|
||||||
"DevDetail_button_DeleteEvents": "Удалить события",
|
"DevDetail_button_DeleteEvents": "Удалить события",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "Вы уверены, что хотите удалить все события на этом устройстве?<br><br>(это очистит <b>Историю событий</b> и <b>Сеансы</b> и может помочь с постоянными (настойчивыми) уведомлениями)",
|
"DevDetail_button_DeleteEvents_Warning": "Вы уверены, что хотите удалить все события на этом устройстве?<br><br>(это очистит <b>Историю событий</b> и <b>Сеансы</b> и может помочь с постоянными (настойчивыми) уведомлениями)",
|
||||||
|
"DevDetail_button_Delete_ask": "Вы уверены, что хотите удалить это устройство? Вместо этого вы можете заархивировать его.",
|
||||||
"DevDetail_button_OverwriteIcons": "Перезаписать значки",
|
"DevDetail_button_OverwriteIcons": "Перезаписать значки",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "Перезаписать значки всех устройств одного типа",
|
"DevDetail_button_OverwriteIcons_Tooltip": "Перезаписать значки всех устройств одного типа",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "Вы уверены, что хотите перезаписать все значки всех устройств с тем же типом устройства, что и текущий тип устройства?",
|
"DevDetail_button_OverwriteIcons_Warning": "Вы уверены, что хотите перезаписать все значки всех устройств с тем же типом устройства, что и текущий тип устройства?",
|
||||||
@@ -205,6 +209,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "Присутствие устройств",
|
"Device_Shortcut_OnlineChart": "Присутствие устройств",
|
||||||
"Device_TableHead_AlertDown": "Оповещение о сост. ВЫКЛ",
|
"Device_TableHead_AlertDown": "Оповещение о сост. ВЫКЛ",
|
||||||
"Device_TableHead_Connected_Devices": "Соединения",
|
"Device_TableHead_Connected_Devices": "Соединения",
|
||||||
|
"Device_TableHead_CustomProps": "Свойства / Действия",
|
||||||
"Device_TableHead_Favorite": "Избранное",
|
"Device_TableHead_Favorite": "Избранное",
|
||||||
"Device_TableHead_FirstSession": "Первый сеанс",
|
"Device_TableHead_FirstSession": "Первый сеанс",
|
||||||
"Device_TableHead_GUID": "GUID",
|
"Device_TableHead_GUID": "GUID",
|
||||||
@@ -243,6 +248,8 @@
|
|||||||
"Donations_Title": "Пожертвования",
|
"Donations_Title": "Пожертвования",
|
||||||
"ENABLE_PLUGINS_description": "Включает функциональность <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">плагинов.</a> Загрузка плагинов требует больше аппаратных ресурсов, поэтому вы можете отключить их в маломощной системе.",
|
"ENABLE_PLUGINS_description": "Включает функциональность <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">плагинов.</a> Загрузка плагинов требует больше аппаратных ресурсов, поэтому вы можете отключить их в маломощной системе.",
|
||||||
"ENABLE_PLUGINS_name": "Разрешить плагины",
|
"ENABLE_PLUGINS_name": "Разрешить плагины",
|
||||||
|
"ENCRYPTION_KEY_description": "",
|
||||||
|
"ENCRYPTION_KEY_name": "",
|
||||||
"Email_display_name": "Эл. почта",
|
"Email_display_name": "Эл. почта",
|
||||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||||
"Events_Loading": "Загрузка...",
|
"Events_Loading": "Загрузка...",
|
||||||
@@ -305,13 +312,14 @@
|
|||||||
"Gen_ReadDocs": "Подробнее читайте в документации.",
|
"Gen_ReadDocs": "Подробнее читайте в документации.",
|
||||||
"Gen_Remove_All": "Удалить все",
|
"Gen_Remove_All": "Удалить все",
|
||||||
"Gen_Remove_Last": "Удалить последний",
|
"Gen_Remove_Last": "Удалить последний",
|
||||||
|
"Gen_Reset": "Сбросить",
|
||||||
"Gen_Restore": "Запустить восстановление",
|
"Gen_Restore": "Запустить восстановление",
|
||||||
"Gen_Run": "Запустить",
|
"Gen_Run": "Запустить",
|
||||||
"Gen_Save": "Сохранить",
|
"Gen_Save": "Сохранить",
|
||||||
"Gen_Saved": "Сохранено",
|
"Gen_Saved": "Сохранено",
|
||||||
"Gen_Search": "Поиск",
|
"Gen_Search": "Поиск",
|
||||||
"Gen_Select": "Выбрать",
|
"Gen_Select": "Выбрать",
|
||||||
"Gen_SelectIcon": "",
|
"Gen_SelectIcon": "<i class=\"fa-solid fa-chevron-down fa-fade\"></i>",
|
||||||
"Gen_SelectToPreview": "Выберите для предварительного просмотра",
|
"Gen_SelectToPreview": "Выберите для предварительного просмотра",
|
||||||
"Gen_Selected_Devices": "Выбранные устройства:",
|
"Gen_Selected_Devices": "Выбранные устройства:",
|
||||||
"Gen_Switch": "Переключить",
|
"Gen_Switch": "Переключить",
|
||||||
@@ -321,8 +329,8 @@
|
|||||||
"Gen_Update_Value": "Обновить значение",
|
"Gen_Update_Value": "Обновить значение",
|
||||||
"Gen_Warning": "Предупреждение",
|
"Gen_Warning": "Предупреждение",
|
||||||
"Gen_Work_In_Progress": "Работа продолжается, самое время оставить отзыв на https://github.com/jokob-sk/NetAlertX/issues",
|
"Gen_Work_In_Progress": "Работа продолжается, самое время оставить отзыв на https://github.com/jokob-sk/NetAlertX/issues",
|
||||||
"Gen_create_new_device": "Создать фиктивное устройство",
|
"Gen_create_new_device": "Новое устройство",
|
||||||
"Gen_create_new_device_info": "",
|
"Gen_create_new_device_info": "Устройства обычно обнаруживаются с помощью <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">плагинов</a>. Однако в некоторых случаях вам может потребоваться добавить устройства вручную. Для изучения конкретных сценариев ознакомьтесь с документацией <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/REMOTE_NETWORKS.md\">Remote Networks</a>.",
|
||||||
"General_display_name": "Главное",
|
"General_display_name": "Главное",
|
||||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||||
"HRS_TO_KEEP_NEWDEV_description": "Это настройка обслуживания <b>УДАЛЕНИЕ устройств</b>. Если этот параметр включен (<code>0</code> отключен), устройства, помеченные как <b>Новое устройство</b>, будут удалены, если время их <b>Первого сеанса</b> было старше указанных в этой настройке часов. Используйте этот параметр, если вы хотите автоматически удалять <b>Новые устройства</b> через <code>X</code> часов.",
|
"HRS_TO_KEEP_NEWDEV_description": "Это настройка обслуживания <b>УДАЛЕНИЕ устройств</b>. Если этот параметр включен (<code>0</code> отключен), устройства, помеченные как <b>Новое устройство</b>, будут удалены, если время их <b>Первого сеанса</b> было старше указанных в этой настройке часов. Используйте этот параметр, если вы хотите автоматически удалять <b>Новые устройства</b> через <code>X</code> часов.",
|
||||||
|
|||||||
@@ -60,12 +60,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "",
|
"BackDevices_darkmode_enabled": "",
|
||||||
"CLEAR_NEW_FLAG_description": "",
|
"CLEAR_NEW_FLAG_description": "",
|
||||||
"CLEAR_NEW_FLAG_name": "",
|
"CLEAR_NEW_FLAG_name": "",
|
||||||
|
"CustProps_cant_remove": "",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "",
|
"DAYS_TO_KEEP_EVENTS_description": "",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "",
|
"DAYS_TO_KEEP_EVENTS_name": "",
|
||||||
"DISCOVER_PLUGINS_description": "",
|
"DISCOVER_PLUGINS_description": "",
|
||||||
"DISCOVER_PLUGINS_name": "",
|
"DISCOVER_PLUGINS_name": "",
|
||||||
"DevDetail_Copy_Device_Title": "",
|
"DevDetail_Copy_Device_Title": "",
|
||||||
"DevDetail_Copy_Device_Tooltip": "",
|
"DevDetail_Copy_Device_Tooltip": "",
|
||||||
|
"DevDetail_CustomProperties_Title": "",
|
||||||
|
"DevDetail_CustomProps_reset_info": "",
|
||||||
"DevDetail_DisplayFields_Title": "",
|
"DevDetail_DisplayFields_Title": "",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "",
|
"DevDetail_EveandAl_AlertAllEvents": "",
|
||||||
"DevDetail_EveandAl_AlertDown": "",
|
"DevDetail_EveandAl_AlertDown": "",
|
||||||
@@ -182,6 +185,7 @@
|
|||||||
"DevDetail_button_Delete": "Cihazı Sil",
|
"DevDetail_button_Delete": "Cihazı Sil",
|
||||||
"DevDetail_button_DeleteEvents": "",
|
"DevDetail_button_DeleteEvents": "",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "",
|
"DevDetail_button_DeleteEvents_Warning": "",
|
||||||
|
"DevDetail_button_Delete_ask": "",
|
||||||
"DevDetail_button_OverwriteIcons": "",
|
"DevDetail_button_OverwriteIcons": "",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "",
|
"DevDetail_button_OverwriteIcons_Tooltip": "",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "",
|
"DevDetail_button_OverwriteIcons_Warning": "",
|
||||||
@@ -205,6 +209,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "",
|
"Device_Shortcut_OnlineChart": "",
|
||||||
"Device_TableHead_AlertDown": "",
|
"Device_TableHead_AlertDown": "",
|
||||||
"Device_TableHead_Connected_Devices": "Bağlantılar",
|
"Device_TableHead_Connected_Devices": "Bağlantılar",
|
||||||
|
"Device_TableHead_CustomProps": "",
|
||||||
"Device_TableHead_Favorite": "",
|
"Device_TableHead_Favorite": "",
|
||||||
"Device_TableHead_FirstSession": "İlk Oturum",
|
"Device_TableHead_FirstSession": "İlk Oturum",
|
||||||
"Device_TableHead_GUID": "",
|
"Device_TableHead_GUID": "",
|
||||||
@@ -243,6 +248,8 @@
|
|||||||
"Donations_Title": "",
|
"Donations_Title": "",
|
||||||
"ENABLE_PLUGINS_description": "",
|
"ENABLE_PLUGINS_description": "",
|
||||||
"ENABLE_PLUGINS_name": "",
|
"ENABLE_PLUGINS_name": "",
|
||||||
|
"ENCRYPTION_KEY_description": "",
|
||||||
|
"ENCRYPTION_KEY_name": "",
|
||||||
"Email_display_name": "Eposta",
|
"Email_display_name": "Eposta",
|
||||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||||
"Events_Loading": "Yükleniyor...",
|
"Events_Loading": "Yükleniyor...",
|
||||||
@@ -305,6 +312,7 @@
|
|||||||
"Gen_ReadDocs": "",
|
"Gen_ReadDocs": "",
|
||||||
"Gen_Remove_All": "Tümünü kaldır",
|
"Gen_Remove_All": "Tümünü kaldır",
|
||||||
"Gen_Remove_Last": "",
|
"Gen_Remove_Last": "",
|
||||||
|
"Gen_Reset": "",
|
||||||
"Gen_Restore": "",
|
"Gen_Restore": "",
|
||||||
"Gen_Run": "Çalıştır",
|
"Gen_Run": "Çalıştır",
|
||||||
"Gen_Save": "Kaydet",
|
"Gen_Save": "Kaydet",
|
||||||
|
|||||||
@@ -60,12 +60,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "Темний режим увімкнено",
|
"BackDevices_darkmode_enabled": "Темний режим увімкнено",
|
||||||
"CLEAR_NEW_FLAG_description": "Якщо ввімкнено (<code>0</code> вимкнено), пристрої, позначені як <b>Новий пристрій</b>, не будуть позначені, якщо ліміт часу (вказаний у годинах) перевищує їхній <b>Перший сеанс</b> час.",
|
"CLEAR_NEW_FLAG_description": "Якщо ввімкнено (<code>0</code> вимкнено), пристрої, позначені як <b>Новий пристрій</b>, не будуть позначені, якщо ліміт часу (вказаний у годинах) перевищує їхній <b>Перший сеанс</b> час.",
|
||||||
"CLEAR_NEW_FLAG_name": "Очистити новий прапор",
|
"CLEAR_NEW_FLAG_name": "Очистити новий прапор",
|
||||||
|
"CustProps_cant_remove": "Неможливо видалити, потрібна принаймні одна властивість.",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "Це налаштування обслуговування. Це визначає кількість днів записів про події, які зберігатимуться. Усі старіші події періодично видалятимуться. Також застосовується до історії подій плагінів.",
|
"DAYS_TO_KEEP_EVENTS_description": "Це налаштування обслуговування. Це визначає кількість днів записів про події, які зберігатимуться. Усі старіші події періодично видалятимуться. Також застосовується до історії подій плагінів.",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "Видалити події, старші за",
|
"DAYS_TO_KEEP_EVENTS_name": "Видалити події, старші за",
|
||||||
"DISCOVER_PLUGINS_description": "Вимкніть цю опцію, щоб прискорити ініціалізацію та збереження налаштувань. Якщо вимкнено, плагіни не виявляються, і ви не можете додавати нові плагіни до параметра <code>LOADED_PLUGINS</code>.",
|
"DISCOVER_PLUGINS_description": "Вимкніть цю опцію, щоб прискорити ініціалізацію та збереження налаштувань. Якщо вимкнено, плагіни не виявляються, і ви не можете додавати нові плагіни до параметра <code>LOADED_PLUGINS</code>.",
|
||||||
"DISCOVER_PLUGINS_name": "Відкрийте для себе плагіни",
|
"DISCOVER_PLUGINS_name": "Відкрийте для себе плагіни",
|
||||||
"DevDetail_Copy_Device_Title": "Скопіюйте деталі з пристрою",
|
"DevDetail_Copy_Device_Title": "Скопіюйте деталі з пристрою",
|
||||||
"DevDetail_Copy_Device_Tooltip": "Скопіюйте деталі пристрою зі спадного списку. Усе на цій сторінці буде перезаписано",
|
"DevDetail_Copy_Device_Tooltip": "Скопіюйте деталі пристрою зі спадного списку. Усе на цій сторінці буде перезаписано",
|
||||||
|
"DevDetail_CustomProperties_Title": "Спеціальні властивості",
|
||||||
|
"DevDetail_CustomProps_reset_info": "Це призведе до видалення настроюваних властивостей на цьому пристрої та скидання їх до значень за замовчуванням.",
|
||||||
"DevDetail_DisplayFields_Title": "Дисплей",
|
"DevDetail_DisplayFields_Title": "Дисплей",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "Повідомлення про події",
|
"DevDetail_EveandAl_AlertAllEvents": "Повідомлення про події",
|
||||||
"DevDetail_EveandAl_AlertDown": "Сповіщення вниз",
|
"DevDetail_EveandAl_AlertDown": "Сповіщення вниз",
|
||||||
@@ -182,6 +185,7 @@
|
|||||||
"DevDetail_button_Delete": "Видалити пристрій",
|
"DevDetail_button_Delete": "Видалити пристрій",
|
||||||
"DevDetail_button_DeleteEvents": "Видалити події",
|
"DevDetail_button_DeleteEvents": "Видалити події",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "Ви впевнені, що бажаєте видалити всі події цього пристрою?<br><br>(це очистить <b>історію подій</b> і <b>сеанси</b> та може допомогти з постійними (постійними) ) сповіщення)",
|
"DevDetail_button_DeleteEvents_Warning": "Ви впевнені, що бажаєте видалити всі події цього пристрою?<br><br>(це очистить <b>історію подій</b> і <b>сеанси</b> та може допомогти з постійними (постійними) ) сповіщення)",
|
||||||
|
"DevDetail_button_Delete_ask": "Ви впевнені, що хочете видалити цей пристрій? Натомість ви також можете заархівувати його.",
|
||||||
"DevDetail_button_OverwriteIcons": "Перезаписати значки",
|
"DevDetail_button_OverwriteIcons": "Перезаписати значки",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "Перезаписати піктограми всіх пристроїв одним типом пристрою",
|
"DevDetail_button_OverwriteIcons_Tooltip": "Перезаписати піктограми всіх пристроїв одним типом пристрою",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "Ви впевнені, що бажаєте перезаписати всі піктограми всіх пристроїв тим самим типом пристрою, що й поточний тип пристрою?",
|
"DevDetail_button_OverwriteIcons_Warning": "Ви впевнені, що бажаєте перезаписати всі піктограми всіх пристроїв тим самим типом пристрою, що й поточний тип пристрою?",
|
||||||
@@ -205,6 +209,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "Наявність пристрою",
|
"Device_Shortcut_OnlineChart": "Наявність пристрою",
|
||||||
"Device_TableHead_AlertDown": "Сповіщення вниз",
|
"Device_TableHead_AlertDown": "Сповіщення вниз",
|
||||||
"Device_TableHead_Connected_Devices": "Зв'язки",
|
"Device_TableHead_Connected_Devices": "Зв'язки",
|
||||||
|
"Device_TableHead_CustomProps": "Реквізит / дії",
|
||||||
"Device_TableHead_Favorite": "улюблений",
|
"Device_TableHead_Favorite": "улюблений",
|
||||||
"Device_TableHead_FirstSession": "Перша сесія",
|
"Device_TableHead_FirstSession": "Перша сесія",
|
||||||
"Device_TableHead_GUID": "GUID",
|
"Device_TableHead_GUID": "GUID",
|
||||||
@@ -243,6 +248,8 @@
|
|||||||
"Donations_Title": "Пожертви",
|
"Donations_Title": "Пожертви",
|
||||||
"ENABLE_PLUGINS_description": "Вмикає функції <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">плагінів</a>. Завантаження плагінів вимагає більше апаратних ресурсів, тому ви можете вимкнути їх у системі з низьким енергоспоживанням.",
|
"ENABLE_PLUGINS_description": "Вмикає функції <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">плагінів</a>. Завантаження плагінів вимагає більше апаратних ресурсів, тому ви можете вимкнути їх у системі з низьким енергоспоживанням.",
|
||||||
"ENABLE_PLUGINS_name": "Увімкнути плагіни",
|
"ENABLE_PLUGINS_name": "Увімкнути плагіни",
|
||||||
|
"ENCRYPTION_KEY_description": "",
|
||||||
|
"ENCRYPTION_KEY_name": "",
|
||||||
"Email_display_name": "Електронна пошта",
|
"Email_display_name": "Електронна пошта",
|
||||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||||
"Events_Loading": "Завантаження...",
|
"Events_Loading": "Завантаження...",
|
||||||
@@ -305,6 +312,7 @@
|
|||||||
"Gen_ReadDocs": "Детальніше читайте в документах.",
|
"Gen_ReadDocs": "Детальніше читайте в документах.",
|
||||||
"Gen_Remove_All": "Видалити Все",
|
"Gen_Remove_All": "Видалити Все",
|
||||||
"Gen_Remove_Last": "Видаліть останнім",
|
"Gen_Remove_Last": "Видаліть останнім",
|
||||||
|
"Gen_Reset": "Скинути",
|
||||||
"Gen_Restore": "Запустіть Restore",
|
"Gen_Restore": "Запустіть Restore",
|
||||||
"Gen_Run": "бігти",
|
"Gen_Run": "бігти",
|
||||||
"Gen_Save": "зберегти",
|
"Gen_Save": "зберегти",
|
||||||
|
|||||||
@@ -60,12 +60,15 @@
|
|||||||
"BackDevices_darkmode_enabled": "已启用暗黑模式",
|
"BackDevices_darkmode_enabled": "已启用暗黑模式",
|
||||||
"CLEAR_NEW_FLAG_description": "",
|
"CLEAR_NEW_FLAG_description": "",
|
||||||
"CLEAR_NEW_FLAG_name": "",
|
"CLEAR_NEW_FLAG_name": "",
|
||||||
|
"CustProps_cant_remove": "",
|
||||||
"DAYS_TO_KEEP_EVENTS_description": "这是维护设置。它指定将保留的事件条目的天数。所有较旧的事件将被定期删除。也适用于插件事件历史记录。",
|
"DAYS_TO_KEEP_EVENTS_description": "这是维护设置。它指定将保留的事件条目的天数。所有较旧的事件将被定期删除。也适用于插件事件历史记录。",
|
||||||
"DAYS_TO_KEEP_EVENTS_name": "删除早于",
|
"DAYS_TO_KEEP_EVENTS_name": "删除早于",
|
||||||
"DISCOVER_PLUGINS_description": "",
|
"DISCOVER_PLUGINS_description": "",
|
||||||
"DISCOVER_PLUGINS_name": "",
|
"DISCOVER_PLUGINS_name": "",
|
||||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> 从设备复制详细信息",
|
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> 从设备复制详细信息",
|
||||||
"DevDetail_Copy_Device_Tooltip": "从下拉列表中复制设备的详细信息。此页面上的所有内容都将被覆盖",
|
"DevDetail_Copy_Device_Tooltip": "从下拉列表中复制设备的详细信息。此页面上的所有内容都将被覆盖",
|
||||||
|
"DevDetail_CustomProperties_Title": "",
|
||||||
|
"DevDetail_CustomProps_reset_info": "",
|
||||||
"DevDetail_DisplayFields_Title": "",
|
"DevDetail_DisplayFields_Title": "",
|
||||||
"DevDetail_EveandAl_AlertAllEvents": "提醒所有事件",
|
"DevDetail_EveandAl_AlertAllEvents": "提醒所有事件",
|
||||||
"DevDetail_EveandAl_AlertDown": "警报关闭",
|
"DevDetail_EveandAl_AlertDown": "警报关闭",
|
||||||
@@ -182,6 +185,7 @@
|
|||||||
"DevDetail_button_Delete": "删除设备",
|
"DevDetail_button_Delete": "删除设备",
|
||||||
"DevDetail_button_DeleteEvents": "删除事件",
|
"DevDetail_button_DeleteEvents": "删除事件",
|
||||||
"DevDetail_button_DeleteEvents_Warning": "您确定要删除此设备的所有事件吗?<br><br>(这将清除<b>事件历史记录</b>和<b>会话</b>,并且可能有助于持续(持久)通知)",
|
"DevDetail_button_DeleteEvents_Warning": "您确定要删除此设备的所有事件吗?<br><br>(这将清除<b>事件历史记录</b>和<b>会话</b>,并且可能有助于持续(持久)通知)",
|
||||||
|
"DevDetail_button_Delete_ask": "",
|
||||||
"DevDetail_button_OverwriteIcons": "覆盖图标",
|
"DevDetail_button_OverwriteIcons": "覆盖图标",
|
||||||
"DevDetail_button_OverwriteIcons_Tooltip": "覆盖具有相同设备类型的所有设备的图标",
|
"DevDetail_button_OverwriteIcons_Tooltip": "覆盖具有相同设备类型的所有设备的图标",
|
||||||
"DevDetail_button_OverwriteIcons_Warning": "您确定要覆盖与当前设备类型相同的所有设备的所有图标吗?",
|
"DevDetail_button_OverwriteIcons_Warning": "您确定要覆盖与当前设备类型相同的所有设备的所有图标吗?",
|
||||||
@@ -205,6 +209,7 @@
|
|||||||
"Device_Shortcut_OnlineChart": "设备统计",
|
"Device_Shortcut_OnlineChart": "设备统计",
|
||||||
"Device_TableHead_AlertDown": "",
|
"Device_TableHead_AlertDown": "",
|
||||||
"Device_TableHead_Connected_Devices": "链接",
|
"Device_TableHead_Connected_Devices": "链接",
|
||||||
|
"Device_TableHead_CustomProps": "",
|
||||||
"Device_TableHead_Favorite": "收藏",
|
"Device_TableHead_Favorite": "收藏",
|
||||||
"Device_TableHead_FirstSession": "加入",
|
"Device_TableHead_FirstSession": "加入",
|
||||||
"Device_TableHead_GUID": "GUID",
|
"Device_TableHead_GUID": "GUID",
|
||||||
@@ -243,6 +248,8 @@
|
|||||||
"Donations_Title": "捐款",
|
"Donations_Title": "捐款",
|
||||||
"ENABLE_PLUGINS_description": "启用<a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">插件</a>功能。加载插件需要更多硬件资源,因此您可能需要在低功耗系统上禁用它们。",
|
"ENABLE_PLUGINS_description": "启用<a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">插件</a>功能。加载插件需要更多硬件资源,因此您可能需要在低功耗系统上禁用它们。",
|
||||||
"ENABLE_PLUGINS_name": "启用插件",
|
"ENABLE_PLUGINS_name": "启用插件",
|
||||||
|
"ENCRYPTION_KEY_description": "",
|
||||||
|
"ENCRYPTION_KEY_name": "",
|
||||||
"Email_display_name": "Email",
|
"Email_display_name": "Email",
|
||||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||||
"Events_Loading": "加载中...",
|
"Events_Loading": "加载中...",
|
||||||
@@ -305,6 +312,7 @@
|
|||||||
"Gen_ReadDocs": "在文档中阅读更多内容。",
|
"Gen_ReadDocs": "在文档中阅读更多内容。",
|
||||||
"Gen_Remove_All": "全部删除",
|
"Gen_Remove_All": "全部删除",
|
||||||
"Gen_Remove_Last": "删除最后一个",
|
"Gen_Remove_Last": "删除最后一个",
|
||||||
|
"Gen_Reset": "",
|
||||||
"Gen_Restore": "运行恢复",
|
"Gen_Restore": "运行恢复",
|
||||||
"Gen_Run": "运行",
|
"Gen_Run": "运行",
|
||||||
"Gen_Save": "保存",
|
"Gen_Save": "保存",
|
||||||
|
|||||||
@@ -24,49 +24,52 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
|
|||||||
|
|
||||||
|
|
||||||
| ID | Type | Description | Features | Required | Data source | Detailed docs |
|
| ID | Type | Description | Features | Required | Data source | Detailed docs |
|
||||||
|---------------|---------|--------------------------------------------|----------|----------|--------------------|---------------------------------------------------------------|
|
|---------------|---------|--------------------------------------------|----------|----------|--------------|---------------------------------------------------------------------|
|
||||||
| `APPRISE` | ▶️ | Apprise notification proxy | | | Script | [_publisher_apprise](/front/plugins/_publisher_apprise/) |
|
| `APPRISE` | ▶️ | Apprise notification proxy | | | Script | [_publisher_apprise](/front/plugins/_publisher_apprise/) |
|
||||||
| `ARPSCAN` | 🔍 | ARP-scan on current network | | | Script | [arp_scan](/front/plugins/arp_scan/) |
|
| `ARPSCAN` | 🔍 | ARP-scan on current network | | | Script | [arp_scan](/front/plugins/arp_scan/) |
|
||||||
| `AVAHISCAN` | 🆎 | Avahi (mDNS-based) name resolution | | | Script | [avahi_scan](/front/plugins/avahi_scan/) |
|
| `AVAHISCAN` | 🆎 | Avahi (mDNS-based) name resolution | | | Script | [avahi_scan](/front/plugins/avahi_scan/) |
|
||||||
| `CSVBCKP` | ⚙ | CSV devices backup | | | Script | [csv_backup](/front/plugins/csv_backup/) |
|
| `CSVBCKP` | ⚙ | CSV devices backup | | | Script | [csv_backup](/front/plugins/csv_backup/) |
|
||||||
|
| `CUSTPROP` | ⚙ | Managing custom device properties values | | Yes | Template | [custom_props](/front/plugins/custom_props/) |
|
||||||
| `DBCLNP` | ⚙ | Database cleanup | | Yes* | Script | [db_cleanup](/front/plugins/db_cleanup/) |
|
| `DBCLNP` | ⚙ | Database cleanup | | Yes* | Script | [db_cleanup](/front/plugins/db_cleanup/) |
|
||||||
| `DDNS` | ⚙ | DDNS update | | | Script | [ddns_update](/front/plugins/ddns_update/) |
|
| `DDNS` | ⚙ | DDNS update | | | Script | [ddns_update](/front/plugins/ddns_update/) |
|
||||||
| `DHCPLSS` | 🔍/📥/🆎| Import devices from DHCP leases | | | Script | [dhcp_leases](/front/plugins/dhcp_leases/) |
|
| `DHCPLSS` | 🔍/📥/🆎| Import devices from DHCP leases | | | Script | [dhcp_leases](/front/plugins/dhcp_leases/) |
|
||||||
| `DHCPSRVS` | ♻ | DHCP servers | | | Script | [dhcp_servers](/front/plugins/dhcp_servers/) |
|
| `DHCPSRVS` | ♻ | DHCP servers | | | Script | [dhcp_servers](/front/plugins/dhcp_servers/) |
|
||||||
| `FREEBOX` | 🔍/♻/🆎 | Pull data and names from Freebox/Iliadbox | | | Script | [freebox](/front/plugins/freebox/) |
|
| `FREEBOX` | 🔍/♻/🆎| Pull data and names from Freebox/Iliadbox | | | Script | [freebox](/front/plugins/freebox/) |
|
||||||
| `ICMP` | 🔍 | ICMP (ping) status checker | | | Script | [icmp_scan](/front/plugins/icmp_scan/) |
|
| `ICMP` | 🔍 | ICMP (ping) status checker | | | Script | [icmp_scan](/front/plugins/icmp_scan/) |
|
||||||
| `INTRNT` | 🔍 | Internet IP scanner | | | Script | [internet_ip](/front/plugins/internet_ip/) |
|
| `INTRNT` | 🔍 | Internet IP scanner | | | Script | [internet_ip](/front/plugins/internet_ip/) |
|
||||||
| `INTRSPD` | ♻ | Internet speed test | | | Script | [internet_speedtest](/front/plugins/internet_speedtest/) |
|
| `INTRSPD` | ♻ | Internet speed test | | | Script | [internet_speedtest](/front/plugins/internet_speedtest/) |
|
||||||
| `IPNEIGH` | 🔍 | Scan ARP (IPv4) and NDP (IPv6) tables | | | Script | [ipneigh](/front/plugins/ipneigh/) |
|
| `IPNEIGH` | 🔍 | Scan ARP (IPv4) and NDP (IPv6) tables | | | Script | [ipneigh](/front/plugins/ipneigh/) |
|
||||||
|
| `LUCIRPC` | 🔍 | Import connected devices from OpenWRT | | | Script | [luci_import](/front/plugins/luci_import/) |
|
||||||
| `MAINT` | ⚙ | Maintenance of logs, etc. | | | Script | [maintenance](/front/plugins/maintenance/) |
|
| `MAINT` | ⚙ | Maintenance of logs, etc. | | | Script | [maintenance](/front/plugins/maintenance/) |
|
||||||
| `MQTT` | ▶️ | MQTT for synching to Home Assistant | | | Script | [_publisher_mqtt](/front/plugins/_publisher_mqtt/) |
|
| `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/) |
|
| `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/) |
|
| `NEWDEV` | ⚙ | New device template | | Yes | Template | [newdev_template](/front/plugins/newdev_template/) |
|
||||||
| `NMAP` | ♻ | Nmap port scanning & discovery | | | Script | [nmap_scan](/front/plugins/nmap_scan/) |
|
| `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/) |
|
| `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/) |
|
| `NSLOOKUP` | 🆎 | NSLookup (DNS-based) name resolution | | | Script | [nslookup_scan](/front/plugins/nslookup_scan/) |
|
||||||
| `NTFPRCS` | ⚙ | Notification processing | | Yes | Template | [notification_processing](/front/plugins/notification_processing/)|
|
| `NTFPRCS` | ⚙ | Notification processing | | Yes | Template | [notification_processing](/front/plugins/notification_processing/)|
|
||||||
| `NTFY` | ▶️ | NTFY notifications | | | Script | [_publisher_ntfy](/front/plugins/_publisher_ntfy/) |
|
| `NTFY` | ▶️ | NTFY notifications | | | Script | [_publisher_ntfy](/front/plugins/_publisher_ntfy/) |
|
||||||
| `OMDSDN` | 📥/🆎 | OMADA TP-Link import | 🖧 🔄 | | Script | [omada_sdn_imp](/front/plugins/omada_sdn_imp/) |
|
| `OMDSDN` | 📥/🆎 | OMADA TP-Link import | 🖧 🔄 | | Script | [omada_sdn_imp](/front/plugins/omada_sdn_imp/) |
|
||||||
| `PIHOLE` | 🔍/🆎/📥| Pi-hole device import & sync | | | SQLite DB | [pihole_scan](/front/plugins/pihole_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/) |
|
| `PUSHSAFER` | ▶️ | Pushsafer notifications | | | Script | [_publisher_pushsafer](/front/plugins/_publisher_pushsafer/) |
|
||||||
| `PUSHOVER` | ▶️ | Pushover notifications | | | Script | [_publisher_pushover](/front/plugins/_publisher_pushover/) |
|
| `PUSHOVER` | ▶️ | Pushover notifications | | | Script | [_publisher_pushover](/front/plugins/_publisher_pushover/) |
|
||||||
| `SETPWD` | ⚙ | Set password | | Yes | Template | [set_password](/front/plugins/set_password/) |
|
| `SETPWD` | ⚙ | Set password | | Yes | Template | [set_password](/front/plugins/set_password/) |
|
||||||
| `SMTP` | ▶️ | Email notifications | | | Script | [_publisher_email](/front/plugins/_publisher_email/) |
|
| `SMTP` | ▶️ | Email notifications | | | Script | [_publisher_email](/front/plugins/_publisher_email/) |
|
||||||
| `SNMPDSC` | 🔍/📥 | SNMP device import & sync | | | Script | [snmp_discovery](/front/plugins/snmp_discovery/) |
|
| `SNMPDSC` | 🔍/📥 | SNMP device import & sync | | | Script | [snmp_discovery](/front/plugins/snmp_discovery/) |
|
||||||
| `SYNC` | 🔍/⚙/📥| Sync & import from NetAlertX instances | 🖧 🔄 | Yes | Script | [sync](/front/plugins/sync/) |
|
| `SYNC` | 🔍/⚙/📥| Sync & import from NetAlertX instances | 🖧 🔄 | Yes | Script | [sync](/front/plugins/sync/) |
|
||||||
| `TELEGRAM` | ▶️ | Telegram notifications | | | Script | [_publisher_telegram](/front/plugins/_publisher_telegram/) |
|
| `TELEGRAM` | ▶️ | Telegram notifications | | | Script | [_publisher_telegram](/front/plugins/_publisher_telegram/) |
|
||||||
| `UNDIS` | 🔍/📥 | Create dummy devices | | | Script | [undiscoverables](/front/plugins/undiscoverables/) |
|
| `UI` | ♻ | UI specific settings | | Yes | Template | [ui_settings](/front/plugins/ui_settings/) |
|
||||||
| `UNFIMP` | 🔍/📥/🆎| UniFi device import & sync | 🖧 | | Script | [unifi_import](/front/plugins/unifi_import/) |
|
| `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/) |
|
| `VNDRPDT` | ⚙ | Vendor database update | | | Script | [vendor_update](/front/plugins/vendor_update/) |
|
||||||
| `WEBHOOK` | ▶️ | Webhook notifications | | | Script | [_publisher_webhook](/front/plugins/_publisher_webhook/) |
|
| `WEBHOOK` | ▶️ | Webhook notifications | | | Script | [_publisher_webhook](/front/plugins/_publisher_webhook/) |
|
||||||
| `WEBMON` | ♻ | Website down monitoring | | | Script | [website_monitor](/front/plugins/website_monitor/) |
|
| `WEBMON` | ♻ | Website down monitoring | | | Script | [website_monitor](/front/plugins/website_monitor/) |
|
||||||
|
| `WOL` | ♻ | Automatic wake-on-lan | | | Script | [wake_on_lan](/front/plugins/wake_on_lan/) |
|
||||||
|
|
||||||
|
|
||||||
> \* The database cleanup plugin (`DBCLNP`) is not _required_ but the app will become unusable after a while if not executed.
|
> \* The database cleanup plugin (`DBCLNP`) is not _required_ but the app will become unusable after a while if not executed.
|
||||||
>
|
|
||||||
> \** The Undiscoverables plugin (`UNDIS`) inserts only user-specified dummy devices.
|
> \** The Undiscoverables plugin (`UNDIS`) inserts only user-specified dummy devices.
|
||||||
|
> ❌ marked for removal
|
||||||
> ⌚It's recommended to use the same schedule interval for all plugins responsible for discovering new devices.
|
> ⌚It's recommended to use the same schedule interval for all plugins responsible for discovering new devices.
|
||||||
|
|
||||||
## Plugin types
|
## Plugin types
|
||||||
@@ -79,7 +82,7 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
|
|||||||
| name discovery | 🆎 | Discovers names of devices via various protocols. | `before_name_updates`, `schedule` | ✖ | Script |
|
| name discovery | 🆎 | Discovers names of devices via various protocols. | `before_name_updates`, `schedule` | ✖ | Script |
|
||||||
| importer | 📥 | Importing devices from another service. | `schedule` | ✖ | Script / SQLite DB |
|
| importer | 📥 | Importing devices from another service. | `schedule` | ✖ | Script / SQLite DB |
|
||||||
| system | ⚙ | Providing core system functionality. | `schedule` / always on | ✖/✔ | Script / Template |
|
| system | ⚙ | Providing core system functionality. | `schedule` / always on | ✖/✔ | Script / Template |
|
||||||
| other | ♻ | Other scanners, e.g. for name resolution | misc | ✖ | Script / Template |
|
| other | ♻ | Other plugins | misc | ✖ | Script / Template |
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -93,7 +96,7 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
|
|||||||
|
|
||||||
Plugins can be enabled via Settings, and can be disabled as needed.
|
Plugins can be enabled via Settings, and can be disabled as needed.
|
||||||
|
|
||||||
1. Research which plugin you'd like to use and load the required plugins in Settings via the `LOADED_PLUGINS` setting.
|
1. Research which plugin you'd like to use, enable `DISCOVER_PLUGINS` 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. 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
|
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
|
- If using `schedule` on a `🔍 dev scanner` plugin, make sure the schedules are the same across all `🔍 dev scanner` plugins
|
||||||
|
|||||||
8
front/plugins/custom_props/README.md
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
## Overview
|
||||||
|
|
||||||
|
Settings related to the custom properties functionality on a device. A user guide can be found here: [Custom Properties](/docs/CUSTOM_PROPERTIES.md)
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
- Head to **Settings** > **Custom Properties** to adjust the default values.
|
||||||
|
|
||||||
370
front/plugins/custom_props/config.json
Executable file
@@ -0,0 +1,370 @@
|
|||||||
|
{
|
||||||
|
"code_name": "custom_props",
|
||||||
|
"unique_prefix": "CUSTPROP",
|
||||||
|
"plugin_type": "core",
|
||||||
|
"enabled": true,
|
||||||
|
"data_source": "template",
|
||||||
|
"show_ui": false,
|
||||||
|
"localized": ["display_name", "description", "icon"],
|
||||||
|
"display_name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Custom properties"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Settings related to the custom properties functionality on a device."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"icon": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "<i class=\"fa fa-list\"></i>"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": [],
|
||||||
|
"settings": [
|
||||||
|
{
|
||||||
|
"function": "icon",
|
||||||
|
"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": "select",
|
||||||
|
"elementHasInputValue": 1,
|
||||||
|
"elementOptions": [
|
||||||
|
{ "multiple": "true" },
|
||||||
|
{ "readonly": "true" },
|
||||||
|
{ "editable": "true" }
|
||||||
|
],
|
||||||
|
"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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"maxLength": 50,
|
||||||
|
"default_value": [
|
||||||
|
"PGkgY2xhc3M9ImZhcyBmYS10cmFzaC1hbHQiPjwvaT4=",
|
||||||
|
"PGkgY2xhc3M9ImZhcyBmYS1leHRlcm5hbC1saW5rLWFsdCI+PC9pPg==",
|
||||||
|
"PGkgY2xhc3M9ImZhcyBmYS1hcnJvdy1yaWdodCI+PC9pPg==",
|
||||||
|
"PGkgY2xhc3M9ImZhcyBmYS1zZWFyY2giPjwvaT4=",
|
||||||
|
"PGkgY2xhc3M9ImZhcyBmYS1jb2dzIj48L2k+",
|
||||||
|
"PGkgY2xhc3M9ImZhcyBmYS1leWUiPjwvaT4=",
|
||||||
|
"PGkgY2xhc3M9ImZhcyBmYS1kYXRhYmFzZSI+PC9pPg=="
|
||||||
|
],
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name","description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Icon"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "List of icons that can be used on a custom property."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "type",
|
||||||
|
"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": "select",
|
||||||
|
"elementHasInputValue": 1,
|
||||||
|
"elementOptions": [
|
||||||
|
{ "multiple": "true" },
|
||||||
|
{ "readonly": "true" },
|
||||||
|
{ "editable": "true" }
|
||||||
|
],
|
||||||
|
"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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"maxLength": 50,
|
||||||
|
"default_value": [
|
||||||
|
"none",
|
||||||
|
"data",
|
||||||
|
"link",
|
||||||
|
"link_new_tab",
|
||||||
|
"show_notes",
|
||||||
|
"delete_dev",
|
||||||
|
"run_plugin"
|
||||||
|
],
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name","description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Type"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "List of property types. The default ones have specific functionality associated with it."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "args",
|
||||||
|
"type": {
|
||||||
|
"dataType": "string",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"elementType": "input",
|
||||||
|
"elementOptions": [],
|
||||||
|
"transformers": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"maxLength": 50,
|
||||||
|
"default_value": "",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name","description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Arguments"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Arguments for the property type."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "name",
|
||||||
|
"type": {
|
||||||
|
"dataType": "string",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"elementType": "input",
|
||||||
|
"elementOptions": [],
|
||||||
|
"transformers": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"maxLength": 50,
|
||||||
|
"default_value": "",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name","description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Name"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Name of the property displayed on hover."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "notes",
|
||||||
|
"type": {
|
||||||
|
"dataType": "string",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"elementType": "input",
|
||||||
|
"elementOptions": [],
|
||||||
|
"transformers": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"maxLength": 50,
|
||||||
|
"default_value": "",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name","description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Notes"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Additional notes."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "show",
|
||||||
|
"type": {
|
||||||
|
"dataType": "boolean",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"elementType": "input",
|
||||||
|
"elementOptions": [{ "type": "checkbox" }],
|
||||||
|
"transformers": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_value": true,
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name", "description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Show"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Show in device list."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "actions",
|
||||||
|
"type": {
|
||||||
|
"dataType": "none",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"elementType": "span",
|
||||||
|
"elementOptions": [
|
||||||
|
{
|
||||||
|
"cssClasses": "input-group-addon pointer actionIcon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"placeholder": "<i class=\"far fa-trash-alt\"></i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"onClick": "removeDataTableRow(this)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"transformers": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elementType": "span",
|
||||||
|
"elementOptions": [
|
||||||
|
{
|
||||||
|
"cssClasses": "input-group-addon pointer actionIcon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"placeholder": "<i class=\"far fa-clone\"></i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"onClick": "cloneDataTableRow(this)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"transformers": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"maxLength": 50,
|
||||||
|
"default_value": [
|
||||||
|
],
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name","description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Action"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Actions on the property."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -148,18 +148,24 @@ def main():
|
|||||||
foreignKey=freebox["mac"],
|
foreignKey=freebox["mac"],
|
||||||
)
|
)
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
for ip in [ip for ip in host["l3connectivities"] if ip["reachable"]]:
|
# Check if 'l3connectivities' exists and is a list
|
||||||
mac: str = host["l2ident"]["id"]
|
if "l3connectivities" in host and isinstance(host["l3connectivities"], list):
|
||||||
plugin_objects.add_object(
|
for ip in [ip for ip in host["l3connectivities"] if ip.get("reachable")]:
|
||||||
primaryId=mac,
|
mac: str = host.get("l2ident", {}).get("id", "(unknown)")
|
||||||
secondaryId=ip["addr"],
|
if mac != '(unknown)':
|
||||||
watched1=host["primary_name"],
|
plugin_objects.add_object(
|
||||||
watched2=host["vendor_name"] if host["vendor_name"] else "(unknown)",
|
primaryId=mac,
|
||||||
watched3=map_device_type(host["host_type"]),
|
secondaryId=ip.get("addr", "0.0.0.0"),
|
||||||
watched4=datetime.fromtimestamp(ip["last_time_reachable"]),
|
watched1=host.get("primary_name", "(unknown)"),
|
||||||
extra="",
|
watched2=host.get("vendor_name", "(unknown)"),
|
||||||
foreignKey=mac,
|
watched3=map_device_type(host.get("host_type", "")),
|
||||||
)
|
watched4=datetime.fromtimestamp(ip.get("last_time_reachable", 0)),
|
||||||
|
extra="",
|
||||||
|
foreignKey=mac,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Optional: Log or handle hosts without 'l3connectivities'
|
||||||
|
mylog("verbose", [f"[{pluginName}] Host missing 'l3connectivities': {host}"])
|
||||||
|
|
||||||
# commit result
|
# commit result
|
||||||
plugin_objects.write_result_file()
|
plugin_objects.write_result_file()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"execution_order" : "Layer_4",
|
"execution_order" : "Layer_4",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"data_source": "script",
|
"data_source": "script",
|
||||||
|
"mapped_to_table": "CurrentScan",
|
||||||
"show_ui": true,
|
"show_ui": true,
|
||||||
"data_filters": [
|
"data_filters": [
|
||||||
{
|
{
|
||||||
@@ -130,6 +131,34 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"function": "IN_REGEX",
|
||||||
|
"type": {
|
||||||
|
"dataType": "string",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"elementType": "input",
|
||||||
|
"elementOptions": [],
|
||||||
|
"transformers": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_value": ".*",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name", "description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Inclusion REGEX"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "REGEX to specify which IPs are included in the scan. Examples: <code>192.168.1.*|10.0.0.1|172.16.5.*</code> (specific IPs or ranges). Use <code>.*</code> to include all IPs."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"function": "RUN_SCHD",
|
"function": "RUN_SCHD",
|
||||||
"type": {
|
"type": {
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ def main():
|
|||||||
|
|
||||||
timeout = get_setting_value('ICMP_RUN_TIMEOUT')
|
timeout = get_setting_value('ICMP_RUN_TIMEOUT')
|
||||||
args = get_setting_value('ICMP_ARGS')
|
args = get_setting_value('ICMP_ARGS')
|
||||||
|
in_regex = get_setting_value('ICMP_IN_REGEX')
|
||||||
|
|
||||||
# Create a database connection
|
# Create a database connection
|
||||||
db = DB() # instance of class DB
|
db = DB() # instance of class DB
|
||||||
@@ -62,9 +63,19 @@ def main():
|
|||||||
# Retrieve devices
|
# Retrieve devices
|
||||||
all_devices = device_handler.getAll()
|
all_devices = device_handler.getAll()
|
||||||
|
|
||||||
mylog('verbose', [f'[{pluginName}] Devices to PING: {len(all_devices)}'])
|
# Compile the regex for efficiency if it will be used multiple times
|
||||||
|
regex_pattern = re.compile(in_regex)
|
||||||
|
|
||||||
for device in all_devices:
|
# Filter devices based on the regex match
|
||||||
|
filtered_devices = [
|
||||||
|
device for device in all_devices
|
||||||
|
if regex_pattern.match(device['devLastIP'])
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
mylog('verbose', [f'[{pluginName}] Devices to PING: {len(filtered_devices)}'])
|
||||||
|
|
||||||
|
for device in filtered_devices:
|
||||||
is_online, output = execute_scan(device['devLastIP'], timeout, args)
|
is_online, output = execute_scan(device['devLastIP'], timeout, args)
|
||||||
|
|
||||||
mylog('verbose', [f'[{pluginName}] ip: "{device['devLastIP']}" is_online: "{is_online}"'])
|
mylog('verbose', [f'[{pluginName}] ip: "{device['devLastIP']}" is_online: "{is_online}"'])
|
||||||
|
|||||||
9
front/plugins/luci_import/README.md
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
## Overview
|
||||||
|
|
||||||
|
The plugin is used to import connected devices from OpenWRT
|
||||||
|
|
||||||
|
### Other info
|
||||||
|
|
||||||
|
- Author : [vaga9938](https://github.com/vaga9938)
|
||||||
|
- Date : 28-Dec-2024 - version 1.0
|
||||||
|
|
||||||
545
front/plugins/luci_import/config.json
Executable file
@@ -0,0 +1,545 @@
|
|||||||
|
{
|
||||||
|
"code_name": "luci_import",
|
||||||
|
"show_ui": true,
|
||||||
|
"unique_prefix": "LUCIRPC",
|
||||||
|
"plugin_type": "device_scanner",
|
||||||
|
"execution_order" : "Layer_1",
|
||||||
|
"enabled": true,
|
||||||
|
"data_source": "script",
|
||||||
|
"mapped_to_table": "CurrentScan",
|
||||||
|
"data_filters": [
|
||||||
|
{
|
||||||
|
"compare_column": "Object_PrimaryID",
|
||||||
|
"compare_operator": "==",
|
||||||
|
"compare_field_id": "txtMacFilter",
|
||||||
|
"compare_js_template": "'{value}'.toString()",
|
||||||
|
"compare_use_quotes": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"localized": ["display_name", "description", "icon"],
|
||||||
|
"display_name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Luci rpc import (Device import)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Luci rpc импорт (Device import)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "The plugin is used to import connected devices from OpenWRT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Плагин используется для импорта подключённых устройств из OpenWRT"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"icon": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "<i class=\"fa fa-search\"></i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "<i class=\"fa fa-search\"></i>"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": [
|
||||||
|
],
|
||||||
|
"settings": [
|
||||||
|
{
|
||||||
|
"function": "RUN",
|
||||||
|
"events": ["run"],
|
||||||
|
"type": {
|
||||||
|
"dataType": "string",
|
||||||
|
"elements": [
|
||||||
|
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_value": "disabled",
|
||||||
|
"options": [
|
||||||
|
"disabled",
|
||||||
|
"once",
|
||||||
|
"schedule"
|
||||||
|
],
|
||||||
|
"localized": ["name", "description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "When to run"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "When the plugin should run. Good options are <code>schedule</code>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Когда должен запуститься плагин. Хорошими вариантами являются <code>schedule</code>"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "RUN_SCHD",
|
||||||
|
"type": {
|
||||||
|
"dataType": "string",
|
||||||
|
"elements": [
|
||||||
|
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_value": "*/5 * * * *",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name", "description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Schedule"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Schedule"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Only enabled if you select <code>schedule</code> in the <a href=\"#SYNC_RUN\"><code>SYNC_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": "ru_ru",
|
||||||
|
"string": "Доступно только в том случае, если вы выбрали <code>schedule</code> в <a href=\"#SYNC_RUN\"><code>SYNC_RUN</code> setting</a>. Убедитесь, что вы вводите расписание в правильном формате, похожем на cron (например, проверьте на <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Например, если вы введете <code>0 4 * * *</code>, то сканирование будет запускаться после 4 часов утра в <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> который вы установили выше</a>. Сканирование будет запускаться СЛЕДУЮЩИЙ РАЗ, когда пройдет это время."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "CMD",
|
||||||
|
"type": {
|
||||||
|
"dataType": "string",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"elementType": "input",
|
||||||
|
"elementOptions": [{ "readonly": "true" }],
|
||||||
|
"transformers": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_value": "python3 /app/front/plugins/luci_import/script.py",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name", "description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Command"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Command to run. This can not be changed"
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Команда для запуска. Это невозможно изменить"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "RUN_TIMEOUT",
|
||||||
|
"type": {
|
||||||
|
"dataType": "integer",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"elementType": "input",
|
||||||
|
"elementOptions": [{ "type": "number" }],
|
||||||
|
"transformers": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_value": 30,
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name", "description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Run timeout"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Время ожидания выполнения"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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": "ru_ru",
|
||||||
|
"string": "Максимальное время в секундах, в течение которого нужно ждать завершения работы скрипта. Если это время превышено, скрипт прерывается."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "host",
|
||||||
|
"type": {
|
||||||
|
"dataType": "string",
|
||||||
|
"elements": [
|
||||||
|
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_value": "192.168.1.1",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name", "description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Router ip"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Ip адрес роутера"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Router ip(do not include <code>http://</code> or <code>https://</code>)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Ip адрес роутера(без <code>http://</code> и <code>https://</code>)."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "user",
|
||||||
|
"type": {
|
||||||
|
"dataType": "string",
|
||||||
|
"elements": [
|
||||||
|
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_value": "root",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name", "description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Router user"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Имя пользователя для подлючения к роутеру"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "User name used to login into your router."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Имя пользователя для подлючения к роутеру."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "password",
|
||||||
|
"type": {
|
||||||
|
"dataType": "string",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"elementType": "input",
|
||||||
|
"elementOptions": [{ "type": "password" }],
|
||||||
|
"transformers": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name", "description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Router password"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Пароль роутера"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Password used to login into your router."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Пароль для подлючения к роутеру."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "ssl",
|
||||||
|
"type": {
|
||||||
|
"dataType": "boolean",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"elementType": "input",
|
||||||
|
"elementOptions": [{ "type": "checkbox" }],
|
||||||
|
"transformers": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_value": false,
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name", "description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Router SSL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Роутер SSL."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "If your router enforces SSL connections."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Если роутер поддерживает SSL подключение."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function": "verify_ssl",
|
||||||
|
"type": {
|
||||||
|
"dataType": "boolean",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"elementType": "input",
|
||||||
|
"elementOptions": [{ "type": "checkbox" }],
|
||||||
|
"transformers": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_value": true,
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name", "description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Verify SSL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Проверка SSL"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "If SSL/TLS verification for HTTPS resources needs to be turned off (for self-signed certs, etc.)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Если необходимо отключить проверку SSL/TLS для ресурсов HTTPS (для самоподписанных сертификатов и т. д.)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"database_column_definitions": [
|
||||||
|
{
|
||||||
|
"column": "Index",
|
||||||
|
"css_classes": "col-sm-2",
|
||||||
|
"show": true,
|
||||||
|
"type": "none",
|
||||||
|
"default_value": "",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Index"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Индекс"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": "Object_PrimaryID",
|
||||||
|
"mapped_to_column": "cur_MAC",
|
||||||
|
"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": "ru_ru",
|
||||||
|
"string": "MAC"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": "Object_SecondaryID",
|
||||||
|
"mapped_to_column": "cur_IP",
|
||||||
|
"css_classes": "col-sm-2",
|
||||||
|
"show": true,
|
||||||
|
"type": "label",
|
||||||
|
"default_value": "",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "IP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"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": "Ip host"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Ip хоста"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": "Watched_Value2",
|
||||||
|
"mapped_to_column": "cur_NAME",
|
||||||
|
"css_classes": "col-sm-2",
|
||||||
|
"show": true,
|
||||||
|
"type": "label",
|
||||||
|
"default_value": "",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Имя"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": "Dummy",
|
||||||
|
"mapped_to_column": "cur_ScanMethod",
|
||||||
|
"mapped_to_column_data": {
|
||||||
|
"value": "LUCIRPC"
|
||||||
|
},
|
||||||
|
"css_classes": "col-sm-2",
|
||||||
|
"show": true,
|
||||||
|
"type": "label",
|
||||||
|
"default_value": "",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Scan method"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Метод сканирования"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": "DateTimeCreated",
|
||||||
|
"css_classes": "col-sm-2",
|
||||||
|
"show": true,
|
||||||
|
"type": "label",
|
||||||
|
"default_value": "",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Created"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Создано"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": "DateTimeChanged",
|
||||||
|
"css_classes": "col-sm-2",
|
||||||
|
"show": true,
|
||||||
|
"type": "label",
|
||||||
|
"default_value": "",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Changed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Изменено"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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>"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"localized": ["name"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Status"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "ru_ru",
|
||||||
|
"string": "Статус"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
74
front/plugins/luci_import/script.py
Executable file
@@ -0,0 +1,74 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
INSTALL_PATH="/app"
|
||||||
|
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||||
|
pluginName = 'LUCIRPC'
|
||||||
|
|
||||||
|
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
||||||
|
from logger import mylog, Logger, append_line_to_file
|
||||||
|
from helper import timeNowTZ, get_setting_value
|
||||||
|
from const import logPath, applicationPath
|
||||||
|
import conf
|
||||||
|
from pytz import timezone
|
||||||
|
|
||||||
|
try:
|
||||||
|
from openwrt_luci_rpc import OpenWrtRpc
|
||||||
|
except:
|
||||||
|
mylog('error', [f'[{pluginName}] Failed import openwrt_luci_rpc'])
|
||||||
|
exit()
|
||||||
|
|
||||||
|
conf.tz = timezone(get_setting_value('TIMEZONE'))
|
||||||
|
|
||||||
|
Logger(get_setting_value('LOG_LEVEL'))
|
||||||
|
|
||||||
|
LOG_PATH = logPath + '/plugins'
|
||||||
|
LOG_FILE = os.path.join(LOG_PATH, f'script.{pluginName}.log')
|
||||||
|
RESULT_FILE = os.path.join(LOG_PATH, f'last_result.{pluginName}.log')
|
||||||
|
|
||||||
|
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
mylog('verbose', [f'[{pluginName}] start script.'])
|
||||||
|
|
||||||
|
device_data = get_device_data()
|
||||||
|
|
||||||
|
for entry in device_data:
|
||||||
|
mylog('verbose', [f'[{pluginName}] found: ', str(entry.mac).lower()])
|
||||||
|
plugin_objects.add_object(
|
||||||
|
primaryId = str(entry.mac).lower(),
|
||||||
|
secondaryId = entry.ip,
|
||||||
|
watched1 = entry.host,
|
||||||
|
watched2 = str(entry.hostname),
|
||||||
|
watched3 = "",
|
||||||
|
watched4 = "",
|
||||||
|
extra = pluginName,
|
||||||
|
foreignKey = str(entry.mac).lower())
|
||||||
|
|
||||||
|
plugin_objects.write_result_file()
|
||||||
|
|
||||||
|
mylog('verbose', [f'[{pluginName}] Script finished'])
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def get_device_data():
|
||||||
|
router = OpenWrtRpc(
|
||||||
|
get_setting_value("LUCIRPC_host"),
|
||||||
|
get_setting_value("LUCIRPC_user"),
|
||||||
|
get_setting_value("LUCIRPC_password"),
|
||||||
|
get_setting_value("LUCIRPC_ssl"),
|
||||||
|
get_setting_value("LUCIRPC_verify_ssl")
|
||||||
|
)
|
||||||
|
|
||||||
|
if router.is_logged_in():
|
||||||
|
mylog('verbose', [f'[{pluginName}] login successfully.'])
|
||||||
|
else:
|
||||||
|
mylog('error', [f'[{pluginName}] login fail.'])
|
||||||
|
|
||||||
|
device_data = router.get_all_connected_devices(only_reachable=True)
|
||||||
|
return device_data
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"code_name": "mikrotik_scan",
|
"code_name": "mikrotik_scan",
|
||||||
"unique_prefix": "MTSCAN",
|
"unique_prefix": "MTSCAN",
|
||||||
"plugin_type": "device_scanner",
|
"plugin_type": "device_scanner",
|
||||||
"execution_order" : "Layer_4",
|
"execution_order" : "Layer_1",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"data_source": "script",
|
"data_source": "script",
|
||||||
"mapped_to_table": "CurrentScan",
|
"mapped_to_table": "CurrentScan",
|
||||||
@@ -27,12 +27,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"params": [
|
"params": [
|
||||||
{
|
|
||||||
"name": "ips",
|
|
||||||
"type": "sql",
|
|
||||||
"value": "SELECT devLastIP from DEVICES order by devMac",
|
|
||||||
"timeoutMultiplier": true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "mt_host",
|
"name": "mt_host",
|
||||||
"type": "setting",
|
"type": "setting",
|
||||||
|
|||||||
@@ -1,27 +1,16 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pathlib
|
|
||||||
import argparse
|
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
import hashlib
|
|
||||||
import csv
|
|
||||||
import sqlite3
|
|
||||||
import re
|
|
||||||
from io import StringIO
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
# Register NetAlertX directories
|
# Register NetAlertX directories
|
||||||
INSTALL_PATH="/app"
|
INSTALL_PATH="/app"
|
||||||
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||||
|
|
||||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
from plugin_helper import Plugin_Objects
|
||||||
from logger import mylog, Logger, append_line_to_file
|
from logger import mylog, Logger
|
||||||
from helper import timeNowTZ, get_setting_value
|
from helper import get_setting_value
|
||||||
from const import logPath, applicationPath, fullDbPath
|
from const import logPath
|
||||||
from database import DB
|
|
||||||
from device import Device_obj
|
|
||||||
import conf
|
import conf
|
||||||
from pytz import timezone
|
from pytz import timezone
|
||||||
from librouteros import connect
|
from librouteros import connect
|
||||||
@@ -81,6 +70,7 @@ def get_entries(plugin_objects: Plugin_Objects) -> Plugin_Objects:
|
|||||||
comment = lease.get('comment')
|
comment = lease.get('comment')
|
||||||
last_seen = lease.get('last-seen')
|
last_seen = lease.get('last-seen')
|
||||||
status = lease.get('status')
|
status = lease.get('status')
|
||||||
|
device_name = comment or host_name or "(unknown)"
|
||||||
|
|
||||||
mylog('verbose', [f"ID: {lease_id}, Address: {address}, MAC Address: {mac_address}, Host Name: {host_name}, Comment: {comment}, Last Seen: {last_seen}, Status: {status}"])
|
mylog('verbose', [f"ID: {lease_id}, Address: {address}, MAC Address: {mac_address}, Host Name: {host_name}, Comment: {comment}, Last Seen: {last_seen}, Status: {status}"])
|
||||||
|
|
||||||
@@ -89,9 +79,9 @@ def get_entries(plugin_objects: Plugin_Objects) -> Plugin_Objects:
|
|||||||
primaryId = mac_address,
|
primaryId = mac_address,
|
||||||
secondaryId = address,
|
secondaryId = address,
|
||||||
watched1 = address,
|
watched1 = address,
|
||||||
watched2 = host_name,
|
watched2 = device_name,
|
||||||
watched3 = last_seen,
|
watched3 = host_name,
|
||||||
watched4 = '',
|
watched4 = last_seen,
|
||||||
extra = '',
|
extra = '',
|
||||||
helpVal1 = comment,
|
helpVal1 = comment,
|
||||||
foreignKey = mac_address)
|
foreignKey = mac_address)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"code_name": "notification_processing",
|
"code_name": "notification_processing",
|
||||||
"unique_prefix": "NTFPRCS",
|
"unique_prefix": "NTFPRCS",
|
||||||
"plugin_type": "system",
|
"plugin_type": "core",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"data_source": "script",
|
"data_source": "script",
|
||||||
"show_ui": false,
|
"show_ui": false,
|
||||||
|
|||||||
@@ -5,11 +5,15 @@ The synchronization plugin is designed to synchronize data across multiple insta
|
|||||||
1. **💻 Devices**: Sends an encrypted `table_devices.json` file to synchronize the entire Devices database table.
|
1. **💻 Devices**: Sends an encrypted `table_devices.json` file to synchronize the entire Devices database table.
|
||||||
2. **🔌 Plugin Data**: Sends encrypted `last_result.log` files for individual plugins.
|
2. **🔌 Plugin Data**: Sends encrypted `last_result.log` files for individual plugins.
|
||||||
|
|
||||||
> **Note:** `[n]` indicates a setting specified for the node instance, and `[n,h]` indicates a setting used on both the node and the hub instances.
|
|
||||||
|
> [!TIP]
|
||||||
|
> This plugin is usually used if you need to monitor inaccessible networks (WAN, VLAN etc.). Read the [Remote networks documentation](/docs/REMOTE_NETWORKS.md) for more details about these scenarios.
|
||||||
|
|
||||||
### Synchronization Modes
|
### Synchronization Modes
|
||||||
|
|
||||||
The plugin operates in three different modes based on the configuration settings:
|
The plugin operates in three different modes based on the configuration settings.
|
||||||
|
|
||||||
|
> **Note:** `[n]` indicates a setting specified for the node instance, and `[n,h]` indicates a setting used on both the node and the hub instances.
|
||||||
|
|
||||||
1. **Mode 1: PUSH (NODE)** - Sends data from the node to the hub.
|
1. **Mode 1: PUSH (NODE)** - Sends data from the node to the hub.
|
||||||
- This mode is activated if `SYNC_hub_url` is set and either `SYNC_devices` or `SYNC_plugins` is enabled.
|
- This mode is activated if `SYNC_hub_url` is set and either `SYNC_devices` or `SYNC_plugins` is enabled.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"code_name": "sync",
|
"code_name": "sync",
|
||||||
"unique_prefix": "SYNC",
|
"unique_prefix": "SYNC",
|
||||||
"plugin_type": "system",
|
"plugin_type": "core",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"data_source": "script",
|
"data_source": "script",
|
||||||
"mapped_to_table": "CurrentScan",
|
"mapped_to_table": "CurrentScan",
|
||||||
|
|||||||
@@ -125,8 +125,6 @@ def main():
|
|||||||
# Mode 2: PULL/GET (HUB)
|
# Mode 2: PULL/GET (HUB)
|
||||||
|
|
||||||
# PULLING DEVICES
|
# PULLING DEVICES
|
||||||
|
|
||||||
file_dir = os.path.join(pluginsPath, 'sync')
|
|
||||||
file_prefix = 'last_result'
|
file_prefix = 'last_result'
|
||||||
|
|
||||||
# pull data from nodes if specified
|
# pull data from nodes if specified
|
||||||
@@ -145,7 +143,7 @@ def main():
|
|||||||
log_file_name = f'{file_prefix}.{node_name}.log'
|
log_file_name = f'{file_prefix}.{node_name}.log'
|
||||||
|
|
||||||
# Write decoded data to log file
|
# Write decoded data to log file
|
||||||
with open(os.path.join(file_dir, log_file_name), 'wb') as log_file:
|
with open(os.path.join(LOG_PATH, log_file_name), 'wb') as log_file:
|
||||||
log_file.write(decoded_data)
|
log_file.write(decoded_data)
|
||||||
|
|
||||||
message = f'[{pluginName}] Device data from node "{node_name}" written to {log_file_name}'
|
message = f'[{pluginName}] Device data from node "{node_name}" written to {log_file_name}'
|
||||||
@@ -157,7 +155,7 @@ def main():
|
|||||||
# Create the file path
|
# Create the file path
|
||||||
|
|
||||||
# Get all "last_result" files from the sync folder, decode, rename them, and get the list of files
|
# Get all "last_result" files from the sync folder, decode, rename them, and get the list of files
|
||||||
files_to_process = decode_and_rename_files(file_dir, file_prefix)
|
files_to_process = decode_and_rename_files(LOG_PATH, file_prefix)
|
||||||
|
|
||||||
if len(files_to_process) > 0:
|
if len(files_to_process) > 0:
|
||||||
|
|
||||||
@@ -181,11 +179,11 @@ def main():
|
|||||||
|
|
||||||
# Store e.g. Node_1 from last_result.encoded.Node_1.1.log
|
# Store e.g. Node_1 from last_result.encoded.Node_1.1.log
|
||||||
tmp_SyncHubNodeName = ''
|
tmp_SyncHubNodeName = ''
|
||||||
if len(file_name.split('.')) > 3:
|
if len(file_name.split('.')) > 2:
|
||||||
tmp_SyncHubNodeName = file_name.split('.')[2]
|
tmp_SyncHubNodeName = file_name.split('.')[1]
|
||||||
|
|
||||||
|
|
||||||
file_path = f"{INSTALL_PATH}/front/plugins/sync/{file_name}"
|
file_path = f"{LOG_PATH}/{file_name}"
|
||||||
|
|
||||||
with open(file_path, 'r') as f:
|
with open(file_path, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
@@ -197,7 +195,7 @@ def main():
|
|||||||
|
|
||||||
# Rename the file to "processed_" + current name
|
# Rename the file to "processed_" + current name
|
||||||
new_file_name = f"processed_{file_name}"
|
new_file_name = f"processed_{file_name}"
|
||||||
new_file_path = os.path.join(file_dir, new_file_name)
|
new_file_path = os.path.join(LOG_PATH, new_file_name)
|
||||||
|
|
||||||
# Overwrite if the new file already exists
|
# Overwrite if the new file already exists
|
||||||
if os.path.exists(new_file_path):
|
if os.path.exists(new_file_path):
|
||||||
|
|||||||
@@ -347,7 +347,8 @@
|
|||||||
"Device_TableHead_LastIP",
|
"Device_TableHead_LastIP",
|
||||||
"Device_TableHead_Status",
|
"Device_TableHead_Status",
|
||||||
"Device_TableHead_MAC_full",
|
"Device_TableHead_MAC_full",
|
||||||
"Device_TableHead_SourcePlugin"
|
"Device_TableHead_SourcePlugin",
|
||||||
|
"Device_TableHead_CustomProps"
|
||||||
],
|
],
|
||||||
"options": [
|
"options": [
|
||||||
"Device_TableHead_Name",
|
"Device_TableHead_Name",
|
||||||
@@ -375,7 +376,8 @@
|
|||||||
"Device_TableHead_SSID",
|
"Device_TableHead_SSID",
|
||||||
"Device_TableHead_SourcePlugin",
|
"Device_TableHead_SourcePlugin",
|
||||||
"Device_TableHead_PresentLastScan",
|
"Device_TableHead_PresentLastScan",
|
||||||
"Device_TableHead_AlertDown"
|
"Device_TableHead_AlertDown",
|
||||||
|
"Device_TableHead_CustomProps"
|
||||||
],
|
],
|
||||||
"localized": ["name", "description"],
|
"localized": ["name", "description"],
|
||||||
"name": [
|
"name": [
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ def get_unifi_val(obj, key, default='null'):
|
|||||||
if result not in ['','None', None, 'null']:
|
if result not in ['','None', None, 'null']:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
mylog('debug', [f'[{pluginName}] Value not found for key "{key}" in obj "{json.dumps(obj)}"'])
|
mylog('trace', [f'[{pluginName}] Value not found for key "{key}" in obj "{json.dumps(obj)}"'])
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"function": "devices_to_wake",
|
"function": "devices_to_wake",
|
||||||
"events": ["run"],
|
"events": [],
|
||||||
"type": {
|
"type": {
|
||||||
"dataType": "string",
|
"dataType": "string",
|
||||||
"elements": [
|
"elements": [
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
|
|
||||||
|
|
||||||
<script src="lib/crypto/crypto-js.min.js"></script>
|
<script src="lib/crypto/crypto-js.min.js"></script>
|
||||||
|
<script src="lib/bcrypt/bcrypt.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<div id="settingsPage" class="content-wrapper">
|
<div id="settingsPage" class="content-wrapper">
|
||||||
@@ -224,8 +225,15 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
|
|
||||||
pluginsData = res["data"];
|
pluginsData = res["data"];
|
||||||
|
|
||||||
// Sort settingsData alphabetically based on the "setGroup" property
|
// Sort settingsData alphabetically, ensuring "General" is always first
|
||||||
settingsData.sort((a, b) => {
|
settingsData.sort((a, b) => {
|
||||||
|
if (a["setGroup"] === "General") {
|
||||||
|
return -1; // Place "General" first
|
||||||
|
}
|
||||||
|
if (b["setGroup"] === "General") {
|
||||||
|
return 1; // Place "General" first
|
||||||
|
}
|
||||||
|
// For other values, sort alphabetically
|
||||||
if (a["setGroup"] < b["setGroup"]) {
|
if (a["setGroup"] < b["setGroup"]) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -501,7 +509,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
}
|
}
|
||||||
|
|
||||||
// INPUT
|
// INPUT
|
||||||
inputFormHtml = generateFormHtml(set, valIn);
|
inputFormHtml = generateFormHtml(settingsData, set, valIn, null, null);
|
||||||
|
|
||||||
// construct final HTML for the setting
|
// construct final HTML for the setting
|
||||||
setHtml += inputFormHtml + overrideHtml + `
|
setHtml += inputFormHtml + overrideHtml + `
|
||||||
@@ -565,14 +573,13 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
setType = set["setType"]
|
setType = set["setType"]
|
||||||
setCodeName = set["setKey"]
|
setCodeName = set["setKey"]
|
||||||
|
|
||||||
console.log(prefix);
|
// console.log(prefix);
|
||||||
|
|
||||||
const setTypeObject = JSON.parse(setType.replace(/'/g, '"'));
|
const setTypeObject = JSON.parse(processQuotes(setType))
|
||||||
// console.log(setTypeObject);
|
// console.log(setTypeObject);
|
||||||
|
|
||||||
const dataType = setTypeObject.dataType;
|
const dataType = setTypeObject.dataType;
|
||||||
|
|
||||||
|
|
||||||
// get the element with the input value(s)
|
// get the element with the input value(s)
|
||||||
let elements = setTypeObject.elements.filter(element => element.elementHasInputValue === 1);
|
let elements = setTypeObject.elements.filter(element => element.elementHasInputValue === 1);
|
||||||
|
|
||||||
@@ -602,12 +609,18 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
onClick,
|
onClick,
|
||||||
onChange,
|
onChange,
|
||||||
customParams,
|
customParams,
|
||||||
customId
|
customId,
|
||||||
|
columns
|
||||||
} = handleElementOptions('none', elementOptions, transformers, val = "");
|
} = handleElementOptions('none', elementOptions, transformers, val = "");
|
||||||
|
|
||||||
let value;
|
let value;
|
||||||
|
|
||||||
if (dataType === "string" ||
|
if (dataType === "string" && elementWithInputValue.elementType === "datatable" ) {
|
||||||
|
|
||||||
|
value = collectTableData(`#${setCodeName}_table`)
|
||||||
|
settingsArray.push([prefix, setCodeName, dataType, btoa(JSON.stringify(value))]);
|
||||||
|
|
||||||
|
} else if (dataType === "string" ||
|
||||||
(dataType === "integer" && (inputType === "number" || inputType === "text"))) {
|
(dataType === "integer" && (inputType === "number" || inputType === "text"))) {
|
||||||
|
|
||||||
value = $('#' + setCodeName).val();
|
value = $('#' + setCodeName).val();
|
||||||
@@ -651,6 +664,12 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
|
|
||||||
settingsArray.push([prefix, setCodeName, dataType, value]);
|
settingsArray.push([prefix, setCodeName, dataType, value]);
|
||||||
|
|
||||||
|
|
||||||
|
} else if (dataType === "none") {
|
||||||
|
// no value to save
|
||||||
|
value = ""
|
||||||
|
settingsArray.push([prefix, setCodeName, dataType, value]);
|
||||||
|
|
||||||
} else if (dataType === "json") {
|
} else if (dataType === "json") {
|
||||||
|
|
||||||
value = $('#' + setCodeName).val();
|
value = $('#' + setCodeName).val();
|
||||||
@@ -675,7 +694,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
|
|
||||||
console.log(settingsArray);
|
console.log(settingsArray);
|
||||||
console.log( JSON.stringify(settingsArray));
|
console.log( JSON.stringify(settingsArray));
|
||||||
// return;
|
// return; // 🐛 🔺
|
||||||
// trigger a save settings event in the backend
|
// trigger a save settings event in the backend
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -699,7 +718,8 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
clearCache()
|
clearCache()
|
||||||
} else{
|
} else{
|
||||||
// something went wrong
|
// something went wrong
|
||||||
write_notification("[Important] DO NOT REFERSH the page. Open the browser DEV console (F12). Please take a screenshot of it. Submit it (with the nginx and php error logs) as a new issue here: https://github.com/jokob-sk/NetAlertX/issues", 'interrupt')
|
write_notification("[Important] Please take a screenshot of the Console tab in the browser (F12) and next error. Submit it (with the nginx and php error logs) as a new issue here: https://github.com/jokob-sk/NetAlertX/issues", 'interrupt')
|
||||||
|
write_notification(data, 'interrupt')
|
||||||
|
|
||||||
console.log("🔽");
|
console.log("🔽");
|
||||||
console.log(settingsArray);
|
console.log(settingsArray);
|
||||||
@@ -736,11 +756,13 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
// check if config file has been updated
|
// check if config file has been updated
|
||||||
$.get('/php/server/query_json.php', { file: 'app_state.json', nocache: Date.now() }, function(appState) {
|
$.get('/php/server/query_json.php', { file: 'app_state.json', nocache: Date.now() }, function(appState) {
|
||||||
|
|
||||||
|
console.log("Settings: Got app_state.json");
|
||||||
|
|
||||||
fileModificationTime = <?php echo filemtime($confPath)*1000;?>;
|
fileModificationTime = <?php echo filemtime($confPath)*1000;?>;
|
||||||
|
|
||||||
// console.log(appState["settingsImported"]*1000)
|
// console.log(appState["settingsImported"]*1000)
|
||||||
importedMiliseconds = parseInt((appState["settingsImported"]*1000));
|
importedMiliseconds = parseInt((appState["settingsImported"]*1000));
|
||||||
humanReadable = (new Date(importedMiliseconds)).toLocaleString("en-UK", { timeZone: "<?php echo $timeZone?>" });
|
|
||||||
|
|
||||||
// check if displayed settings are outdated
|
// check if displayed settings are outdated
|
||||||
if(appState["showSpinner"] || fileModificationTime > importedMiliseconds)
|
if(appState["showSpinner"] || fileModificationTime > importedMiliseconds)
|
||||||
@@ -754,6 +776,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
checkInitialization();
|
checkInitialization();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
humanReadable = (new Date(importedMiliseconds)).toLocaleString("en-UK", { timeZone: "<?php echo $timeZone?>" });
|
||||||
document.getElementById('lastImportedTime').innerHTML = humanReadable;
|
document.getElementById('lastImportedTime').innerHTML = humanReadable;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -30,5 +30,5 @@ source myenv/bin/activate
|
|||||||
update-alternatives --install /usr/bin/python python /usr/bin/python3 10
|
update-alternatives --install /usr/bin/python python /usr/bin/python3 10
|
||||||
|
|
||||||
# install packages thru pip3
|
# install packages thru pip3
|
||||||
pip3 install graphene flask netifaces tplink-omada-client wakeonlan pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros git+https://github.com/foreign-sub/aiofreepybox.git
|
pip3 install openwrt-luci-rpc graphene flask netifaces tplink-omada-client wakeonlan pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros git+https://github.com/foreign-sub/aiofreepybox.git
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ fi
|
|||||||
# Run setup scripts
|
# Run setup scripts
|
||||||
echo "[INSTALL] Run setup scripts"
|
echo "[INSTALL] Run setup scripts"
|
||||||
|
|
||||||
"${INSTALL_PATH}/install/user-mapping.debian.sh"
|
|
||||||
"${INSTALL_PATH}/install/install_dependencies.debian.sh" # if modifying this file transfer the changes into the root Dockerfile.debian as well!
|
"${INSTALL_PATH}/install/install_dependencies.debian.sh" # if modifying this file transfer the changes into the root Dockerfile.debian as well!
|
||||||
|
|
||||||
echo "[INSTALL] Setup NGINX"
|
echo "[INSTALL] Setup NGINX"
|
||||||
@@ -101,6 +100,8 @@ fi
|
|||||||
# Create the execution_queue.log file if it doesn't exist
|
# Create the execution_queue.log file if it doesn't exist
|
||||||
touch "${INSTALL_DIR}"/log/{app.log,execution_queue.log,app_front.log,app.php_errors.log,stderr.log,stdout.log,db_is_locked.log}
|
touch "${INSTALL_DIR}"/log/{app.log,execution_queue.log,app_front.log,app.php_errors.log,stderr.log,stdout.log,db_is_locked.log}
|
||||||
touch "${INSTALL_DIR}"/api/user_notifications.json
|
touch "${INSTALL_DIR}"/api/user_notifications.json
|
||||||
|
# Create plugins sub-directory if it doesn't exist in case a custom log folder is used
|
||||||
|
mkdir -p "${INSTALL_DIR}"/log/plugins
|
||||||
|
|
||||||
# Fixing file permissions
|
# Fixing file permissions
|
||||||
echo "[INSTALL] Fixing file permissions"
|
echo "[INSTALL] Fixing file permissions"
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
echo "---------------------------------------------------------"
|
|
||||||
echo "[INSTALL] Run user-mapping.debian.sh"
|
|
||||||
echo "---------------------------------------------------------"
|
|
||||||
|
|
||||||
if [ -z "${USER}" ]; then
|
|
||||||
echo "We need USER to be set!"; exit 100
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if both not set we do not need to do anything
|
|
||||||
if [ -z "${HOST_USER_ID}" ] && [ -z "${HOST_USER_GID}" ]; then
|
|
||||||
echo "Nothing to do here." ; exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# reset user_id to either new id or if empty old (still one of above
|
|
||||||
# might not be set)
|
|
||||||
USER_ID=${HOST_USER_ID:=$USER_ID}
|
|
||||||
USER_GID=${HOST_USER_GID:=$USER_GID}
|
|
||||||
|
|
||||||
LINE=$(grep -F "${USER}" /etc/passwd)
|
|
||||||
# replace all ':' with a space and create array
|
|
||||||
array=( "${LINE//:/ }" )
|
|
||||||
|
|
||||||
# home is 5th element
|
|
||||||
USER_HOME=${array[4]}
|
|
||||||
|
|
||||||
# print debug output
|
|
||||||
echo USER_ID" ": "${USER_ID}";
|
|
||||||
echo USER_GID : "${USER_GID}";
|
|
||||||
echo USER_HOME: "${USER_HOME}";
|
|
||||||
echo TZ" ": "${TZ}";
|
|
||||||
|
|
||||||
sed -i -e "s/^${USER}:\([^:]*\):[0-9]*:[0-9]*/${USER}:\1:${USER_ID}:${USER_GID}/" /etc/passwd
|
|
||||||
sed -i -e "s/^${USER}:\([^:]*\):[0-9]*/${USER}:\1:${USER_GID}/" /etc/group
|
|
||||||
|
|
||||||
chown -R "${USER_ID}:${USER_GID} ${USER_HOME}"
|
|
||||||
|
|
||||||
exec su - "${USER}"
|
|
||||||
@@ -59,6 +59,7 @@ sql_devices_all = """
|
|||||||
IFNULL(devSSID, '') AS devSSID,
|
IFNULL(devSSID, '') AS devSSID,
|
||||||
IFNULL(devSyncHubNode, '') AS devSyncHubNode,
|
IFNULL(devSyncHubNode, '') AS devSyncHubNode,
|
||||||
IFNULL(devSourcePlugin, '') AS devSourcePlugin,
|
IFNULL(devSourcePlugin, '') AS devSourcePlugin,
|
||||||
|
IFNULL(devCustomProps, '') AS devCustomProps,
|
||||||
CASE
|
CASE
|
||||||
WHEN devIsNew = 1 THEN 'New'
|
WHEN devIsNew = 1 THEN 'New'
|
||||||
WHEN devPresentLastScan = 1 THEN 'On-line'
|
WHEN devPresentLastScan = 1 THEN 'On-line'
|
||||||
@@ -87,7 +88,7 @@ sql_devices_tiles = """
|
|||||||
FROM Devices
|
FROM Devices
|
||||||
WHERE
|
WHERE
|
||||||
(instr((SELECT setValue FROM Statuses), 'online') > 0 AND devPresentLastScan = 1) OR
|
(instr((SELECT setValue FROM Statuses), 'online') > 0 AND devPresentLastScan = 1) OR
|
||||||
(instr((SELECT setValue FROM Statuses), 'offline') > 0 AND devPresentLastScan = 0) OR
|
(instr((SELECT setValue FROM Statuses), 'offline') > 0 AND devPresentLastScan = 0 AND devIsArchived = 0) OR
|
||||||
(instr((SELECT setValue FROM Statuses), 'down') > 0 AND devPresentLastScan = 0 AND devAlertDown = 1) OR
|
(instr((SELECT setValue FROM Statuses), 'down') > 0 AND devPresentLastScan = 0 AND devAlertDown = 1) OR
|
||||||
(instr((SELECT setValue FROM Statuses), 'new') > 0 AND devIsNew = 1) OR
|
(instr((SELECT setValue FROM Statuses), 'new') > 0 AND devIsNew = 1) OR
|
||||||
(instr((SELECT setValue FROM Statuses), 'archived') > 0 AND devIsArchived = 1)
|
(instr((SELECT setValue FROM Statuses), 'archived') > 0 AND devIsArchived = 1)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
from Crypto.Util.Padding import pad, unpad
|
from Crypto.Util.Padding import pad, unpad
|
||||||
import base64
|
import base64
|
||||||
|
import os
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
|
|
||||||
@@ -42,3 +43,17 @@ def decrypt_data(data, encryption_key):
|
|||||||
cipher = AES.new(key, AES.MODE_CBC, iv)
|
cipher = AES.new(key, AES.MODE_CBC, iv)
|
||||||
pt = unpad(cipher.decrypt(ct), AES.block_size)
|
pt = unpad(cipher.decrypt(ct), AES.block_size)
|
||||||
return pt.decode('utf-8')
|
return pt.decode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
def get_random_bytes(length):
|
||||||
|
# Generate random bytes
|
||||||
|
random_bytes = os.urandom(length)
|
||||||
|
|
||||||
|
# Convert bytes to hexadecimal string
|
||||||
|
hex_string = random_bytes.hex()
|
||||||
|
|
||||||
|
# Format hexadecimal string with hyphens
|
||||||
|
formatted_hex = '-'.join(hex_string[i:i+2] for i in range(0, len(hex_string), 2))
|
||||||
|
|
||||||
|
return formatted_hex
|
||||||
@@ -476,6 +476,20 @@ class DB():
|
|||||||
self.sql.execute(""" DROP VIEW IF EXISTS Sessions_Devices;""")
|
self.sql.execute(""" DROP VIEW IF EXISTS Sessions_Devices;""")
|
||||||
self.sql.execute("""CREATE VIEW Sessions_Devices AS SELECT * FROM Sessions LEFT JOIN "Devices" ON ses_MAC = devMac;""")
|
self.sql.execute("""CREATE VIEW Sessions_Devices AS SELECT * FROM Sessions LEFT JOIN "Devices" ON ses_MAC = devMac;""")
|
||||||
|
|
||||||
|
|
||||||
|
# add fields if missing
|
||||||
|
|
||||||
|
# devCustomProps column
|
||||||
|
devCustomProps_missing = self.sql.execute ("""
|
||||||
|
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='devCustomProps'
|
||||||
|
""").fetchone()[0] == 0
|
||||||
|
|
||||||
|
if devCustomProps_missing :
|
||||||
|
mylog('verbose', ["[upgradeDB] Adding devCustomProps to the Devices table"])
|
||||||
|
self.sql.execute("""
|
||||||
|
ALTER TABLE "Devices" ADD "devCustomProps" TEXT
|
||||||
|
""")
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# Settings table setup
|
# Settings table setup
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -226,7 +226,8 @@ def create_new_devices (db):
|
|||||||
devGroup,
|
devGroup,
|
||||||
devComments,
|
devComments,
|
||||||
devLogEvents,
|
devLogEvents,
|
||||||
devLocation"""
|
devLocation,
|
||||||
|
devCustomProps"""
|
||||||
|
|
||||||
newDevDefaults = f"""{get_setting_value('NEWDEV_devAlertEvents')},
|
newDevDefaults = f"""{get_setting_value('NEWDEV_devAlertEvents')},
|
||||||
{get_setting_value('NEWDEV_devAlertDown')},
|
{get_setting_value('NEWDEV_devAlertDown')},
|
||||||
@@ -240,7 +241,9 @@ def create_new_devices (db):
|
|||||||
'{sanitize_SQL_input(get_setting_value('NEWDEV_devGroup'))}',
|
'{sanitize_SQL_input(get_setting_value('NEWDEV_devGroup'))}',
|
||||||
'{sanitize_SQL_input(get_setting_value('NEWDEV_devComments'))}',
|
'{sanitize_SQL_input(get_setting_value('NEWDEV_devComments'))}',
|
||||||
{get_setting_value('NEWDEV_devLogEvents')},
|
{get_setting_value('NEWDEV_devLogEvents')},
|
||||||
'{sanitize_SQL_input(get_setting_value('NEWDEV_devLocation'))}'"""
|
'{sanitize_SQL_input(get_setting_value('NEWDEV_devLocation'))}',
|
||||||
|
'{sanitize_SQL_input(get_setting_value('NEWDEV_devCustomProps'))}'
|
||||||
|
"""
|
||||||
|
|
||||||
# Fetch data from CurrentScan skipping ignored devices by IP and MAC
|
# Fetch data from CurrentScan skipping ignored devices by IP and MAC
|
||||||
query = f"""SELECT cur_MAC, cur_Name, cur_Vendor, cur_ScanMethod, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type
|
query = f"""SELECT cur_MAC, cur_Name, cur_Vendor, cur_ScanMethod, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ class Device(ObjectType):
|
|||||||
devSSID = String()
|
devSSID = String()
|
||||||
devSyncHubNode = String()
|
devSyncHubNode = String()
|
||||||
devSourcePlugin = String()
|
devSourcePlugin = String()
|
||||||
|
devCustomProps = String()
|
||||||
devStatus = String()
|
devStatus = String()
|
||||||
devIsRandomMac = Int()
|
devIsRandomMac = Int()
|
||||||
devParentChildrenCount = Int()
|
devParentChildrenCount = Int()
|
||||||
@@ -116,7 +117,7 @@ class Query(ObjectType):
|
|||||||
device["devIpLong"] = format_ip_long(device.get("devLastIP", ""))
|
device["devIpLong"] = format_ip_long(device.get("devLastIP", ""))
|
||||||
|
|
||||||
|
|
||||||
mylog('none', f'[graphql_schema] devices_data: {devices_data}')
|
mylog('verbose', f'[graphql_schema] devices_data: {devices_data}')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -126,14 +127,14 @@ class Query(ObjectType):
|
|||||||
# Define status-specific filtering
|
# Define status-specific filtering
|
||||||
if options.status:
|
if options.status:
|
||||||
status = options.status
|
status = options.status
|
||||||
mylog('none', f'[graphql_schema] Applying status filter: {status}')
|
mylog('verbose', f'[graphql_schema] Applying status filter: {status}')
|
||||||
|
|
||||||
# Example filtering based on the "status"
|
# Example filtering based on the "status"
|
||||||
if status == "my_devices":
|
if status == "my_devices":
|
||||||
# Include devices matching criteria in UI_MY_DEVICES
|
# Include devices matching criteria in UI_MY_DEVICES
|
||||||
allowed_statuses = get_setting_value("UI_MY_DEVICES")
|
allowed_statuses = get_setting_value("UI_MY_DEVICES")
|
||||||
|
|
||||||
mylog('none', f'[graphql_schema] allowed_statuses: {allowed_statuses}')
|
mylog('verbose', f'[graphql_schema] allowed_statuses: {allowed_statuses}')
|
||||||
|
|
||||||
devices_data = [
|
devices_data = [
|
||||||
device for device in devices_data
|
device for device in devices_data
|
||||||
@@ -141,7 +142,8 @@ class Query(ObjectType):
|
|||||||
(device["devPresentLastScan"] == 1 and 'online' in allowed_statuses) or
|
(device["devPresentLastScan"] == 1 and 'online' in allowed_statuses) or
|
||||||
(device["devIsNew"] == 1 and 'new' in allowed_statuses) or
|
(device["devIsNew"] == 1 and 'new' in allowed_statuses) or
|
||||||
(device["devPresentLastScan"] == 0 and device["devAlertDown"] and 'down' in allowed_statuses) or
|
(device["devPresentLastScan"] == 0 and device["devAlertDown"] and 'down' in allowed_statuses) or
|
||||||
(device["devPresentLastScan"] == 0 and 'offline' in allowed_statuses)
|
(device["devPresentLastScan"] == 0 and 'offline' in allowed_statuses) and device["devIsArchived"] == 0 or
|
||||||
|
(device["devIsArchived"] == 1 and 'archived' in allowed_statuses)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
elif status == "connected":
|
elif status == "connected":
|
||||||
@@ -217,9 +219,9 @@ class Query(ObjectType):
|
|||||||
return SettingResult(settings=[], count=0)
|
return SettingResult(settings=[], count=0)
|
||||||
|
|
||||||
|
|
||||||
mylog('none', f'[graphql_schema] settings_data: {settings_data}')
|
mylog('verbose', f'[graphql_schema] settings_data: {settings_data}')
|
||||||
|
|
||||||
# # Convert to Setting objects
|
# Convert to Setting objects
|
||||||
settings = [Setting(**setting) for setting in settings_data]
|
settings = [Setting(**setting) for setting in settings_data]
|
||||||
|
|
||||||
return SettingResult(settings=settings, count=len(settings))
|
return SettingResult(settings=settings, count=len(settings))
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ def graphql_endpoint():
|
|||||||
api_token_value = get_setting_value("API_TOKEN")
|
api_token_value = get_setting_value("API_TOKEN")
|
||||||
|
|
||||||
if incoming_header_token != f"Bearer {api_token_value}":
|
if incoming_header_token != f"Bearer {api_token_value}":
|
||||||
mylog('verbose', [f'[graphql_server] Unauthorized access attempt'])
|
msg = '[graphql_server] Unauthorized access attempt - make sure your GRAPHQL_PORT and API_TOKEN settings are correct.'
|
||||||
return jsonify({"error": "Unauthorized"}), 401
|
mylog('verbose', [msg])
|
||||||
|
return jsonify({"error": msg}), 401
|
||||||
|
|
||||||
# Retrieve and log request data
|
# Retrieve and log request data
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ def setting_value_to_python_type(set_type, set_value):
|
|||||||
transformers = element_with_input_value.get('transformers', [])
|
transformers = element_with_input_value.get('transformers', [])
|
||||||
|
|
||||||
# Convert value based on dataType and elementType
|
# Convert value based on dataType and elementType
|
||||||
if dataType == 'string' and elementType in ['input', 'select', 'textarea']:
|
if dataType == 'string' and elementType in ['input', 'select', 'textarea', 'datatable']:
|
||||||
value = reverseTransformers(str(set_value), transformers)
|
value = reverseTransformers(str(set_value), transformers)
|
||||||
|
|
||||||
elif dataType == 'integer' and (elementType == 'input' or elementType == 'select'):
|
elif dataType == 'integer' and (elementType == 'input' or elementType == 'select'):
|
||||||
@@ -825,7 +825,7 @@ def extract_ip_addresses(text):
|
|||||||
ip_addresses = re.findall(ip_pattern, text)
|
ip_addresses = re.findall(ip_pattern, text)
|
||||||
return ip_addresses
|
return ip_addresses
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
def generate_random_string(length):
|
def generate_random_string(length):
|
||||||
characters = string.ascii_letters + string.digits
|
characters = string.ascii_letters + string.digits
|
||||||
return ''.join(random.choice(characters) for _ in range(length))
|
return ''.join(random.choice(characters) for _ in range(length))
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ from scheduler import schedule_class
|
|||||||
from plugin import print_plugin_info, run_plugin_scripts
|
from plugin import print_plugin_info, run_plugin_scripts
|
||||||
from plugin_utils import get_plugins_configs, get_set_value_for_init
|
from plugin_utils import get_plugins_configs, get_set_value_for_init
|
||||||
from notification import write_notification
|
from notification import write_notification
|
||||||
|
from crypto_utils import get_random_bytes
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# Initialise user defined values
|
# Initialise user defined values
|
||||||
@@ -202,7 +203,8 @@ def importConfigs (db, all_plugins):
|
|||||||
# Plugins START
|
# Plugins START
|
||||||
# -----------------
|
# -----------------
|
||||||
|
|
||||||
necessary_plugins = ['UI', 'DBCLNP', 'INTRNT','MAINT','NEWDEV', 'SETPWD', 'SYNC', 'VNDRPDT', 'WORKFLOWS']
|
# necessary_plugins = ['UI', 'CUSTPROP', 'CLOUD' ,'DBCLNP', 'INTRNT','MAINT','NEWDEV', 'SETPWD', 'SYNC', 'VNDRPDT', 'WORKFLOWS']
|
||||||
|
necessary_plugins = ['UI', 'CUSTPROP', 'DBCLNP', 'INTRNT','MAINT','NEWDEV', 'SETPWD', 'SYNC', 'VNDRPDT', 'WORKFLOWS']
|
||||||
# make sure necessary plugins are loaded
|
# make sure necessary plugins are loaded
|
||||||
conf.LOADED_PLUGINS += [plugin for plugin in necessary_plugins if plugin not in conf.LOADED_PLUGINS]
|
conf.LOADED_PLUGINS += [plugin for plugin in necessary_plugins if plugin not in conf.LOADED_PLUGINS]
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ def test_updateSubnets():
|
|||||||
assert len(result) == 2
|
assert len(result) == 2
|
||||||
|
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
# Function to insert 10,000 random device entries
|
# Function to insert N random device entries
|
||||||
def insert_devices(db_path, num_entries=1):
|
def insert_devices(db_path, num_entries=1):
|
||||||
conn = sqlite3.connect(db_path)
|
conn = sqlite3.connect(db_path)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
@@ -85,9 +85,10 @@ def insert_devices(db_path, num_entries=1):
|
|||||||
devSite,
|
devSite,
|
||||||
devSSID,
|
devSSID,
|
||||||
devSyncHubNode,
|
devSyncHubNode,
|
||||||
devSourcePlugin
|
devSourcePlugin,
|
||||||
|
devCustomProps
|
||||||
)
|
)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# List of device types, vendors, groups, locations
|
# List of device types, vendors, groups, locations
|
||||||
@@ -128,6 +129,7 @@ def insert_devices(db_path, num_entries=1):
|
|||||||
dev_ssid = "" # Left as NULL
|
dev_ssid = "" # Left as NULL
|
||||||
dev_sync_hub_node = "" # Left as NULL
|
dev_sync_hub_node = "" # Left as NULL
|
||||||
dev_source_plugin = "" # Left as NULL
|
dev_source_plugin = "" # Left as NULL
|
||||||
|
dev_devCustomProps = "" # Left as NULL
|
||||||
|
|
||||||
# Execute the insert query
|
# Execute the insert query
|
||||||
cursor.execute(insert_query, (
|
cursor.execute(insert_query, (
|
||||||
@@ -160,7 +162,8 @@ def insert_devices(db_path, num_entries=1):
|
|||||||
dev_site,
|
dev_site,
|
||||||
dev_ssid,
|
dev_ssid,
|
||||||
dev_sync_hub_node,
|
dev_sync_hub_node,
|
||||||
dev_source_plugin
|
dev_source_plugin,
|
||||||
|
dev_devCustomProps
|
||||||
))
|
))
|
||||||
|
|
||||||
# Commit after every 1000 rows to improve performance
|
# Commit after every 1000 rows to improve performance
|
||||||
|
|||||||