Compare commits

...

40 Commits

Author SHA1 Message Date
Hosted Weblate
703ba5c75b Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2025-02-08 00:54:10 +01:00
Anonymous
aad74451ef Translated using Weblate (Polish)
Currently translated at 88.0% (663 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pl/
2025-02-08 00:54:08 +01:00
Anonymous
a787510963 Translated using Weblate (Portuguese (Brazil))
Currently translated at 32.9% (248 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pt_BR/
2025-02-08 00:54:07 +01:00
jokob-sk
dd2b872712 Cron Schedule validation 2025-02-08 10:53:43 +11:00
jokob-sk
2a5e419034 Better dummy newdev MAC check 2025-02-08 08:17:37 +11:00
jokob-sk
b921144dbb treeviz flatdata experiment + better invalid TZ handling
Some checks are pending
docker / docker_dev (push) Waiting to run
2025-02-08 08:01:05 +11:00
jokob-sk
4f2ddccdde Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2025-02-08 08:00:05 +11:00
jokob-sk
780b818815 treeviz flatdata experiment + better invalid TZ handling 2025-02-08 07:59:55 +11:00
jokob-sk
5779fd34c5 treeviz flatdata experiment + better invalid TZ handling 2025-02-08 07:52:13 +11:00
Safeguard
b7a6fe9112 Translated using Weblate (Russian)
Some checks are pending
docker / docker_dev (push) Waiting to run
Currently translated at 100.0% (753 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ru/
2025-02-07 00:52:35 +01:00
Максим Горпиніч
906bfd24a4 Translated using Weblate (Ukrainian)
Some checks failed
docker / docker_dev (push) Has been cancelled
Currently translated at 100.0% (753 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/uk/
2025-02-02 07:03:04 +01:00
Massimo Pissarello
8f48172940 Translated using Weblate (Italian)
Currently translated at 100.0% (753 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2025-02-02 07:03:03 +01:00
Sylvain Pichon
736304eb8a Translated using Weblate (French)
Currently translated at 100.0% (753 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2025-02-02 07:03:02 +01:00
Anonymous
5fce3c79b0 Translated using Weblate (Ukrainian)
Some checks are pending
docker / docker_dev (push) Waiting to run
Currently translated at 99.8% (752 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/uk/
2025-02-01 06:14:17 +01:00
Anonymous
81c1f65816 Translated using Weblate (Catalan)
Currently translated at 99.8% (752 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ca/
2025-02-01 06:14:17 +01:00
Anonymous
edfaadf682 Translated using Weblate (Turkish)
Currently translated at 22.0% (166 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/tr/
2025-02-01 06:14:17 +01:00
Anonymous
0a51d5fe79 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 87.9% (662 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/zh_Hans/
2025-02-01 06:14:17 +01:00
Anonymous
893063c695 Translated using Weblate (Polish)
Currently translated at 88.4% (666 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pl/
2025-02-01 06:14:17 +01:00
Anonymous
da5cf4a8f1 Translated using Weblate (Portuguese (Brazil))
Currently translated at 32.5% (245 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pt_BR/
2025-02-01 06:14:17 +01:00
Anonymous
1e5a4e96e4 Translated using Weblate (Italian)
Currently translated at 99.8% (752 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2025-02-01 06:14:16 +01:00
Anonymous
74d7a7853a Translated using Weblate (Russian)
Currently translated at 99.7% (751 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ru/
2025-02-01 06:14:16 +01:00
Anonymous
63469007ef Translated using Weblate (Norwegian Bokmål)
Currently translated at 87.6% (660 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/nb_NO/
2025-02-01 06:14:16 +01:00
Anonymous
f5b875e2df Translated using Weblate (French)
Currently translated at 99.8% (752 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2025-02-01 06:14:16 +01:00
Anonymous
d18efb2103 Translated using Weblate (Spanish)
Currently translated at 96.5% (727 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/es/
2025-02-01 06:14:15 +01:00
Anonymous
e2cdce2f39 Translated using Weblate (German)
Currently translated at 89.3% (673 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/de/
2025-02-01 06:14:15 +01:00
jokob-sk
c855d50999 docs + sorting #983
Some checks are pending
docker / docker_dev (push) Waiting to run
2025-02-01 13:07:46 +11:00
jokob-sk
9d8b147e40 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2025-01-31 07:04:19 +11:00
jokob-sk
3aa9be7019 docs #982 2025-01-31 07:04:15 +11:00
Hosted Weblate
72b3d5eb6d Merge branch 'origin/main' into Weblate.
Some checks failed
docker / docker_dev (push) Has been cancelled
2025-01-26 23:36:17 +00:00
anton garcias
83bc406ed6 Translated using Weblate (Catalan)
Currently translated at 100.0% (753 of 753 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ca/
2025-01-26 23:36:16 +00:00
jokob-sk
e6e1c79d6a docs 2025-01-27 10:35:57 +11:00
Jokob @NetAlertX
e0616f72fe Merge pull request #981 from vladaurosh/main
Update default PUID and PGID, and update documentation
2025-01-27 09:20:28 +11:00
vladaurosh
696403ac20 Update FILE_PERMISSIONS.md 2025-01-26 21:57:54 +00:00
vladaurosh
c946a5335a Update README.md 2025-01-26 18:18:04 +00:00
vladaurosh
9610810891 Set uid/gid to previous default 102/82 2025-01-26 17:33:30 +00:00
Jokob @NetAlertX
2ad7f02255 Merge pull request #980 from vladaurosh/main
Some checks are pending
docker / docker_dev (push) Waiting to run
Adding option to set user ID and GID
2025-01-26 13:40:13 +11:00
root
431543ba80 adding option to set user ID and GID 2025-01-26 01:46:38 +00:00
jokob-sk
09d2e68479 Undiscoverables - UNDIS removal #979
Some checks are pending
docker / docker_dev (push) Waiting to run
2025-01-26 10:23:21 +11:00
jokob-sk
896b8b7641 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2025-01-26 10:21:01 +11:00
jokob-sk
8d607aac96 css fixes, docs 2025-01-26 10:20:46 +11:00
75 changed files with 5648 additions and 1666 deletions

View File

@@ -5,7 +5,7 @@ ARG INSTALL_DIR=/app
ENV PYTHONUNBUFFERED=1 ENV PYTHONUNBUFFERED=1
# Install build dependencies # Install build dependencies
RUN apk add --no-cache bash python3 python3-dev gcc musl-dev libffi-dev openssl-dev git \ RUN apk add --no-cache bash shadow python3 python3-dev gcc musl-dev libffi-dev openssl-dev git \
&& python -m venv /opt/venv && python -m venv /opt/venv
# Enable venv # Enable venv
@@ -13,7 +13,6 @@ ENV PATH="/opt/venv/bin:$PATH"
COPY . ${INSTALL_DIR}/ COPY . ${INSTALL_DIR}/
RUN pip install openwrt-luci-rpc asusrouter asyncio aiohttp graphene flask 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 asusrouter asyncio aiohttp graphene flask 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 {} \;" \
@@ -28,6 +27,7 @@ FROM alpine:3.21 AS runner
ARG INSTALL_DIR=/app ARG INSTALL_DIR=/app
COPY --from=builder /opt/venv /opt/venv COPY --from=builder /opt/venv /opt/venv
COPY --from=builder /usr/sbin/usermod /usr/sbin/groupmod /usr/sbin/
# Enable venv # Enable venv
ENV PATH="/opt/venv/bin:$PATH" ENV PATH="/opt/venv/bin:$PATH"
@@ -41,7 +41,7 @@ ENV S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0
# ❗ IMPORTANT - if you modify this file modify the /install/install_dependecies.sh file as well ❗ # ❗ IMPORTANT - if you modify this file modify the /install/install_dependecies.sh file as well ❗
RUN apk update --no-cache \ RUN apk update --no-cache \
&& apk add --no-cache bash zip lsblk gettext-envsubst sudo mtr tzdata s6-overlay \ && apk add --no-cache bash libbsd zip lsblk gettext-envsubst sudo mtr tzdata s6-overlay \
&& apk add --no-cache curl arp-scan iproute2 iproute2-ss nmap nmap-scripts traceroute nbtscan avahi avahi-tools openrc dbus net-tools net-snmp-tools bind-tools awake ca-certificates \ && apk add --no-cache curl arp-scan iproute2 iproute2-ss nmap nmap-scripts traceroute nbtscan avahi avahi-tools openrc dbus net-tools net-snmp-tools bind-tools awake ca-certificates \
&& apk add --no-cache sqlite php83 php83-fpm php83-cgi php83-curl php83-sqlite3 php83-session \ && apk add --no-cache sqlite php83 php83-fpm php83-cgi php83-curl php83-sqlite3 php83-session \
&& apk add --no-cache python3 nginx \ && apk add --no-cache python3 nginx \

View File

@@ -28,6 +28,7 @@ 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 \ --mount type=tmpfs,target=/app/api \
-e PUID=200 -e PGID=300 \
-e TZ=Europe/Berlin \ -e TZ=Europe/Berlin \
-e PORT=20211 \ -e PORT=20211 \
jokobsk/netalertx:latest jokobsk/netalertx:latest
@@ -37,15 +38,18 @@ See alternative [docked-compose examples](https://github.com/jokob-sk/NetAlertX/
### Docker environment variables ### Docker environment variables
| Variable | Description | Default | | Variable | Description | Example Value |
| :------------- |:-------------| -----:| | :------------- |:------------------------| -----:|
| `PORT` |Port of the web interface | `20211` | | `PORT` |Port of the web interface | `20211` |
| `PUID` |Application User UID | `102` |
| `PGID` |Application User GID | `82` |
| `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']","GRAPHQL_PORT":"20212"}` | `N/A` | |`LOADED_PLUGINS` | Default [plugins](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md) to load. Plugins cannot be loaded with `APP_CONF_OVERRIDE`, you need to use this variable instead and then specify the plugins settings with `APP_CONF_OVERRIDE`. | `["PIHOLE","ASUSWRT"]` |
|`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` | |`APP_CONF_OVERRIDE` | JSON override for settings (except `LOADED_PLUGINS`). | `{"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","GRAPHQL_PORT":"20212"}` |
|`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. | `true` |
> 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. `LOADED_PLUGINS` and settings in `APP_CONF_OVERRIDE` can be specified via the UI as well.
### Docker paths ### Docker paths
@@ -68,7 +72,7 @@ See alternative [docked-compose examples](https://github.com/jokob-sk/NetAlertX/
- 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 - 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
### Setting up scanners #### Setting up scanners
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. 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.
@@ -77,19 +81,18 @@ If you are running PiHole you can synchronize devices directly. Check the [PiHol
> [!NOTE] > [!NOTE]
> You can bulk-import devices via the [CSV import method](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md). > 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
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. 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.
> Please note these might be outdated. Rely on official documentation first. > Please note these might be outdated. Rely on official documentation first.
### **Common issues** #### Common issues
💡 Before creating a new issue, please check if a similar issue was [already resolved](https://github.com/jokob-sk/NetAlertX/issues?q=is%3Aissue+is%3Aclosed). - Before creating a new issue, please check if a similar issue was [already resolved](https://github.com/jokob-sk/NetAlertX/issues?q=is%3Aissue+is%3Aclosed).
- 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). ## 💙 Support me
## ❤ Support me
| [![GitHub](https://i.imgur.com/emsRCPh.png)](https://github.com/sponsors/jokob-sk) | [![Buy Me A Coffee](https://i.imgur.com/pIM6YXL.png)](https://www.buymeacoffee.com/jokobsk) | [![Patreon](https://i.imgur.com/MuYsrq1.png)](https://www.patreon.com/user?u=84385063) | | [![GitHub](https://i.imgur.com/emsRCPh.png)](https://github.com/sponsors/jokob-sk) | [![Buy Me A Coffee](https://i.imgur.com/pIM6YXL.png)](https://www.buymeacoffee.com/jokobsk) | [![Patreon](https://i.imgur.com/MuYsrq1.png)](https://www.patreon.com/user?u=84385063) |
| --- | --- | --- | | --- | --- | --- |

View File

@@ -1,8 +1,36 @@
#!/usr/bin/with-contenv bash #!/usr/bin/with-contenv bash
echo "---------------------------------------------------------" echo "---------------------------------------------------------
echo "[INSTALL] Run init.sh" [INSTALL] Run init.sh
echo "---------------------------------------------------------" ---------------------------------------------------------"
DEFAULT_PUID=102
DEFAULT_GID=82
PUID=${PUID:-${DEFAULT_PUID}}
PGID=${PGID:-${DEFAULT_GID}}
echo "[INSTALL] Setting up user UID and GID"
if ! groupmod -o -g "$PGID" www-data && [ "$PGID" != "$DEFAULT_GID" ] ; then
echo "Failed to set user GID to ${PGID}, trying with default GID ${DEFAULT_GID}"
groupmod -o -g "$DEFAULT_GID" www-data
fi
if ! usermod -o -u "$PUID" nginx && [ "$PUID" != "$DEFAULT_PUID" ] ; then
echo "Failed to set user UID to ${PUID}, trying with default PUID ${DEFAULT_PUID}"
usermod -o -u "$DEFAULT_PUID" nginx
fi
echo "
---------------------------------------------------------
GID/UID
---------------------------------------------------------
User UID: $(id -u nginx)
User GID: $(getent group www-data | cut -d: -f3)
---------------------------------------------------------"
chown nginx:nginx /run/nginx/ /var/log/nginx/ /var/lib/nginx/ /var/lib/nginx/tmp/
chgrp www-data /var/www/localhost/htdocs/
export INSTALL_DIR=/app # Specify the installation directory here export INSTALL_DIR=/app # Specify the installation directory here
@@ -119,8 +147,7 @@ touch "${INSTALL_DIR}"/api/user_notifications.json
mkdir -p "${INSTALL_DIR}"/log/plugins 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}"
chown -R nginx:www-data "${INSTALL_DIR}"/api/user_notifications.json
chmod 750 "${INSTALL_DIR}"/{config,log,db} chmod 750 "${INSTALL_DIR}"/{config,log,db}
find "${INSTALL_DIR}"/{config,log,db} -type f -exec chmod 640 {} \; find "${INSTALL_DIR}"/{config,log,db} -type f -exec chmod 640 {} \;

View File

@@ -99,30 +99,3 @@ DEV_LOCATION=/path/to/local/source/code
``` ```
To run the container execute: `sudo docker-compose --env-file /path/to/.env up` 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
```

View File

@@ -5,37 +5,19 @@
> ``` > ```
> docker run -d --rm --network=host \ > docker run -d --rm --network=host \
> -e TZ=Europe/Berlin \ > -e TZ=Europe/Berlin \
> -e PUID=200 -e PGID=200 \
> -e PORT=20211 \ > -e PORT=20211 \
> jokobsk/netalertx:latest > jokobsk/netalertx:latest
> ``` > ```
NetAlertX runs on an Nginx web server. On Alpine Linux, Nginx operates as the `nginx` user (user ID 101, group ID 82 - `www-data`). Consequently, files accessed or written by the NetAlertX application are owned by `nginx:www-data`. NetAlertX runs on an Nginx web server. On Alpine Linux, Nginx operates as the `nginx` user (if PUID and GID environment variables are not specified, nginx user UID will be set to 102, and its supplementary group `www-data` ID to 82). Consequently, files accessed or written by the NetAlertX application are owned by `nginx:www-data`.
Upon starting, NetAlertX changes the ownership of files on the host system mapped to `/app/config` and `/app/db` in the container to `nginx:www-data`. This ensures that Nginx can access and write to these files. Since the user in the Docker container is mapped to a user on the host system by ID:GID, the files in `/app/config` and `/app/db` on the host system are owned by a user with the same ID and GID (ID 101 and GID 82). On different systems, this ID:GID may belong to different users (on Debian, the user with ID 82 is `uuidd`), or there may not be a user with ID 82 at all. Upon starting, NetAlertX changes nginx user UID and www-data GID to specified values (or defaults), and the ownership of files on the host system mapped to `/app/config` and `/app/db` in the container to `nginx:www-data`. This ensures that Nginx can access and write to these files. Since the user in the Docker container is mapped to a user on the host system by ID:GID, the files in `/app/config` and `/app/db` on the host system are owned by a user with the same ID and GID (defaults are ID 102 and GID 82). On different systems, this ID:GID may belong to different users, or there may not be a group with ID 82 at all.
While this generally isn't problematic, it can cause issues for host system users needing to access these files (e.g., backup scripts). If users other than root need access to these files, it is recommended to add those users to the group with GID 82. If that group doesn't exist, it should be created. Option to set specific user UID and GID can be useful for host system users needing to access these files (e.g., backup scripts).
### Permissions Table for Individual Folders ### Permissions Table for Individual Folders
| Folder | User | User ID | Group | Group ID | Permissions | Notes | | Folder | User | User ID | Group | Group ID | Permissions | Notes |
|----------------|--------|---------|-----------|----------|-------------|---------------------------------------------------------------------| |----------------|--------|---------|-----------|----------|-------------|---------------------------------------------------------------------|
| `/app/config` | nginx | 101 | www-data | 82 | rwxr-xr-x | Ensure `nginx` can read/write; other users can read if in `www-data` | | `/app/config` | nginx | PUID (default 102) | www-data | PGID (default 82) | rwxr-xr-x | Ensure `nginx` can read/write; other users can read if in `www-data` |
| `/app/db` | nginx | 101 | www-data | 82 | rwxr-xr-x | Same as above | | `/app/db` | nginx | PUID (default 102) | www-data | PGID (default 82) | rwxr-xr-x | Same as above |
### Steps to Add Users to Group
1. **Check if group exists:**
```sh
getent group www-data
```
2. **Create group if it does not exist:**
```sh
sudo groupadd -g 82 www-data
```
3. **Add user to group:**
```sh
sudo usermod -aG www-data <username>
```
Replace `<username>` with the actual username that requires access.

View File

@@ -126,7 +126,7 @@ You can show or hide the UI on the "Plugins" page and "Plugins" tab for a plugin
If the `data_source` is set to `script` the `CMD` setting (that you specify in the `settings` array section in the `config.json`) contains an executable Linux command, that usually generates a `last_result.<prefix>.log` file (not required if you don't import any data into the app). The `last_result.<prefix>.log` file needs to be saved in `/api/log/plugins`. If the `data_source` is set to `script` the `CMD` setting (that you specify in the `settings` array section in the `config.json`) contains an executable Linux command, that usually generates a `last_result.<prefix>.log` file (not required if you don't import any data into the app). The `last_result.<prefix>.log` file needs to be saved in `/api/log/plugins`.
> [!IMPORTANT] > [!IMPORTANT]
> A lot of the work is taken care of by the [`plugin_helper.py` library](/front/plugins/plugin_helper.py). You don't need to manage the `last_result.<prefix>.log` file if using the helper objects. Check other `script.py` of other plugins for details (The [Undicoverables plugins `script.py` file](/front/plugins/undiscoverables/script.py) is a good example). > A lot of the work is taken care of by the [`plugin_helper.py` library](/front/plugins/plugin_helper.py). You don't need to manage the `last_result.<prefix>.log` file if using the helper objects. Check other `script.py` of other plugins for details.
The content of the `last_result.<prefix>.log` file needs to contain the columns as defined in the "Column order and values" section above. The order of columns can't be changed. After every scan it should contain only the results from the latest scan/execution. The content of the `last_result.<prefix>.log` file needs to contain the columns as defined in the "Column order and values" section above. The order of columns can't be changed. After every scan it should contain only the results from the latest scan/execution.
@@ -578,7 +578,7 @@ Each element may also have associated events (e.g., running a scan or triggering
##### Supported settings `function` values ##### Supported settings `function` values
You can have any `"function": "my_custom_name"` custom name, however, the ones listed below have a specific functionality attached to them. If you use a custom name, then the setting is mostly used as an input parameter for the `params` section. You can have any `"function": "my_custom_name"` custom name, however, the ones listed below have a specific functionality attached to them.
| Setting | Description | | Setting | Description |
| ------- | ----------- | | ------- | ----------- |

View File

@@ -1253,12 +1253,16 @@ input[readonly] {
} }
.filter-group { .filter-group {
flex: 1 100px;
box-sizing: border-box; /* Ensure padding and borders are included in the width */ box-sizing: border-box; /* Ensure padding and borders are included in the width */
padding: 1em; padding: 1em;
padding-top: 0; padding-top: 0;
} }
.filter-dropdown
{
width:7em
}
.modal-header .close .modal-header .close
{ {
display: flex; display: flex;
@@ -1525,6 +1529,14 @@ input[readonly] {
flex-direction:column; flex-direction:column;
justify-content:center; justify-content:center;
} }
.networkHelpIcon
{
padding: 5px;
margin-left: 5px;
top: 55px;
position: absolute;
z-index:5;
}
#networkTree .netNodeText #networkTree .netNodeText
{ {
position: absolute; position: absolute;
@@ -1585,7 +1597,7 @@ input[readonly] {
.spanNetworkTree { .spanNetworkTree {
display: inline-block; display: inline-block;
width: 120px; width: 135px;
white-space: nowrap; white-space: nowrap;
overflow: hidden !important; overflow: hidden !important;
text-overflow: ellipsis; text-overflow: ellipsis;
@@ -1631,6 +1643,10 @@ input[readonly] {
{ {
display: none; display: none;
} }
.dev-detail-tab-name
{
display: none;
}
} }
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */

View File

@@ -61,12 +61,54 @@
<!-- <div class="box-transparent"> --> <!-- <div class="box-transparent"> -->
<div id="navDevice" class="nav-tabs-custom"> <div id="navDevice" class="nav-tabs-custom">
<ul class="nav nav-tabs" style="font-size:16px;"> <ul class="nav nav-tabs" style="font-size:16px;">
<li> <a id="tabDetails" href="#panDetails" data-toggle="tab"> <?= lang('DevDetail_Tab_Details');?> </a></li> <li>
<li> <a id="tabTools" href="#panTools" data-toggle="tab"> <?= lang('DevDetail_Tab_Tools');?> </a></li> <a id="tabDetails" href="#panDetails" data-toggle="tab">
<li> <a id="tabSessions" href="#panSessions" data-toggle="tab"> <?= lang('DevDetail_Tab_Sessions');?> </a></li> <i class="fa fa-info-circle"></i>
<li> <a id="tabPresence" href="#panPresence" data-toggle="tab"> <?= lang('DevDetail_Tab_Presence');?> </a></li> <span class="dev-detail-tab-name">
<li> <a id="tabEvents" href="#panEvents" data-toggle="tab"> <?= lang('DevDetail_Tab_Events');?> </a></li> <?= lang('DevDetail_Tab_Details');?>
<li> <a id="tabPlugins" href="#panPlugins" data-toggle="tab"> <?= lang('DevDetail_Tab_Plugins');?> </a></li> </span>
</a>
</li>
<li>
<a id="tabTools" href="#panTools" data-toggle="tab">
<i class="fa fa-screwdriver-wrench"></i>
<span class="dev-detail-tab-name">
<?= lang('DevDetail_Tab_Tools');?>
</span>
</a>
</li>
<li>
<a id="tabSessions" href="#panSessions" data-toggle="tab">
<i class="fa fa-list-ol"></i>
<span class="dev-detail-tab-name">
<?= lang('DevDetail_Tab_Sessions');?>
</span>
</a>
</li>
<li>
<a id="tabPresence" href="#panPresence" data-toggle="tab">
<i class="fa fa-calendar"></i>
<span class="dev-detail-tab-name">
<?= lang('DevDetail_Tab_Presence');?>
</span>
</a>
</li>
<li>
<a id="tabEvents" href="#panEvents" data-toggle="tab">
<i class="fa fa-bolt"></i>
<span class="dev-detail-tab-name">
<?= lang('DevDetail_Tab_Events');?>
</span>
</a>
</li>
<li>
<a id="tabPlugins" href="#panPlugins" data-toggle="tab">
<i class="fa fa-plug"></i>
<span class="dev-detail-tab-name">
<?= lang('DevDetail_Tab_Plugins');?>
</span>
</a>
</li>
<div class="btn-group pull-right"> <div class="btn-group pull-right">
<button type="button" class="btn btn-default" style="padding: 10px; min-width: 30px;" <button type="button" class="btn btn-default" style="padding: 10px; min-width: 30px;"

View File

@@ -348,16 +348,17 @@
const createNew = mac === 'new' ? 1 : 0; const createNew = mac === 'new' ? 1 : 0;
const devLastIP = $('#NEWDEV_devLastIP').val(); const devLastIP = $('#NEWDEV_devLastIP').val();
const newMac = $('#NEWDEV_devMac').val()
// Validate MAC and Last IP // Validate MAC and Last IP
if (mac === '' || !(isValidIPv4(devLastIP) || isValidIPv6(devLastIP))) { if (mac === '' || !isValidMac(newMac) || !( isValidIPv4(devLastIP) || isValidIPv6(devLastIP) )) {
showMessage(getString("DeviceEdit_ValidMacIp"), 5000, "modal_red"); showMessage(getString("DeviceEdit_ValidMacIp"), 5000, "modal_red");
return; return;
} }
showSpinner(); showSpinner();
// Update data to server using POST // Update data to server using POST
$.post('php/server/devices.php?action=setDeviceData', { $.post('php/server/devices.php?action=setDeviceData', {
mac: $('#NEWDEV_devMac').val(), mac: $('#NEWDEV_devMac').val(),
name: encodeURIComponent($('#NEWDEV_devName').val().replace(/'/g, "")), name: encodeURIComponent($('#NEWDEV_devName').val().replace(/'/g, "")),
@@ -403,7 +404,6 @@
// Everything loaded // Everything loaded
hideSpinner(); hideSpinner();
}); });
} }
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------

View File

@@ -40,9 +40,9 @@
<div class="row" id="DevicePresence"> <div class="row" id="DevicePresence">
<div class="col-md-12"> <div class="col-md-12">
<div class="box" id="clients"> <div class="box" id="clients">
<div class="box-header "> <div class="box-header ">
<h3 class="box-title"><?= lang('Device_Shortcut_OnlineChart');?> </h3> <h3 class="box-title col-md-12"><?= lang('Device_Shortcut_OnlineChart');?> </h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<div class="chart"> <div class="chart">
@@ -61,7 +61,7 @@
<!-- Device Filters ------------------------------------------------------- --> <!-- Device Filters ------------------------------------------------------- -->
<div class="box box-aqua hidden" id="columnFiltersWrap"> <div class="box box-aqua hidden" id="columnFiltersWrap">
<div class="box-header "> <div class="box-header ">
<h3 class="box-title"><?= lang('Devices_Filters');?> </h3> <h3 class="box-title col-md-12"><?= lang('Devices_Filters');?> </h3>
</div> </div>
<!-- Placeholder ------------------------------------------------------- --> <!-- Placeholder ------------------------------------------------------- -->
<div id="columnFilters" ></div> <div id="columnFilters" ></div>
@@ -446,7 +446,7 @@ function initFilters() {
// Server side component // Server side component
function renderFilters(customData) { function renderFilters(customData) {
console.log(JSON.stringify(customData)); // console.log(JSON.stringify(customData));
// Load filter data from the JSON file // Load filter data from the JSON file
$.ajax({ $.ajax({
@@ -455,7 +455,7 @@ function renderFilters(customData) {
type: 'POST', type: 'POST',
dataType: 'html', dataType: 'html',
success: function(response) { success: function(response) {
console.log(response); // console.log(response);
$('#columnFilters').html(response); // Replace container content with fetched HTML $('#columnFilters').html(response); // Replace container content with fetched HTML
$('#columnFilters').removeClass('hidden'); // Show the filters container $('#columnFilters').removeClass('hidden'); // Show the filters container

View File

@@ -776,6 +776,11 @@ function checkMacOrInternet(inputStr) {
} }
} }
// Alias
function isValidMac(value) {
return checkMacOrInternet(value);
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Gte MAC from query string // Gte MAC from query string
function getMac(){ function getMac(){

View File

@@ -717,6 +717,7 @@ const handleElementOptions = (setKey, elementOptions, transformers, val) => {
let customParams = ""; let customParams = "";
let customId = ""; let customId = "";
let columns = []; let columns = [];
let base64Regex = "";
elementOptions.forEach((option) => { elementOptions.forEach((option) => {
@@ -773,6 +774,9 @@ const handleElementOptions = (setKey, elementOptions, transformers, val) => {
if (option.columns) { if (option.columns) {
columns = option.columns; columns = option.columns;
} }
if (option.base64Regex) {
base64Regex = option.base64Regex;
}
}); });
if (transformers.includes("sha256")) { if (transformers.includes("sha256")) {
@@ -796,7 +800,8 @@ const handleElementOptions = (setKey, elementOptions, transformers, val) => {
onChange, onChange,
customParams, customParams,
customId, customId,
columns columns,
base64Regex
}; };
}; };
@@ -973,7 +978,8 @@ function generateFormHtml(settingsData, set, overrideValue, overrideOptions, ori
onChange, onChange,
customParams, customParams,
customId, customId,
columns columns,
base64Regex
} = handleElementOptions(setKey, elementOptions, transformers, inVal); } = handleElementOptions(setKey, elementOptions, transformers, inVal);
// Override value // Override value
@@ -1022,6 +1028,7 @@ function generateFormHtml(settingsData, set, overrideValue, overrideOptions, ori
my-customparams="${customParams}" my-customparams="${customParams}"
my-customid="${customId}" my-customid="${customId}"
my-originalSetKey="${originalSetKey}" my-originalSetKey="${originalSetKey}"
my-base64Regex="${base64Regex}"
id="${setKey}${suffix}" id="${setKey}${suffix}"
type="${inputType}" type="${inputType}"
value="${val}" value="${val}"

View File

@@ -171,7 +171,47 @@ function updateIconPreview(elem) {
tryUpdateIcon(); tryUpdateIcon();
} }
// ----------------------------------------------
// Validate the value based on regex
// ⚠ IMPORTANT: use the below to get a valid REGEX ⚠
// const regexStr = String.raw`^(?:\*|(?:[0-9]|[1-5][0-9]|[0-9]+-[0-9]+|\*/[0-9]+))\s+(?:\*|(?:[0-9]|1[0-9]|2[0-3]|[0-9]+-[0-9]+|\*/[0-9]+))\s+(?:\*|(?:[1-9]|[12][0-9]|3[01]|[0-9]+-[0-9]+|\*/[0-9]+))\s+(?:\*|(?:[1-9]|1[0-2]|[0-9]+-[0-9]+|\*/[0-9]+))\s+(?:\*|(?:[0-6]|[0-6]-[0-6]|\*/[0-9]+))$`;
// console.log(btoa(regexStr));
function validateRegex(elem) {
const iconSpan = $(elem).parent().find(".validityCheck");
const inputElem = $(elem);
const regexTmp = atob($(inputElem).attr("my-base64Regex")); // Decode base64 regex
console.log(regexTmp);
const regex = new RegExp(regexTmp); // Convert to a valid RegExp object
let attempts = 0;
function tryUpdateValidityResultIcon() {
let value = inputElem.val().trim(); // Ensure trimmed value
if (value === "") {
attempts++;
if (attempts < 10) {
setTimeout(tryUpdateValidityResultIcon, 1000); // Retry after 1 sec if empty
} else {
console.error("Input value is empty after 10 attempts");
}
return;
}
// Validate against regex
if (regex.test(value)) {
iconSpan.html("<i class='fa-regular fa-check'></i>");
} else {
iconSpan.html("<i class='fa-regular fa-xmark'></i>");
}
}
// Attach real-time validation on input change
inputElem.on("input", tryUpdateValidityResultIcon);
tryUpdateValidityResultIcon(); // Initial validation
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Nice checkboxes with iCheck // Nice checkboxes with iCheck
@@ -231,38 +271,65 @@ function copyToClipboard(buttonElement) {
// Simple Sortable Table columns // Simple Sortable Table columns
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Function to handle column sorting when a user clicks on a table header
function sortColumn(element) { function sortColumn(element) {
var th = $(element).closest('th'); var th = $(element).closest('th'); // Get the clicked table header
var table = th.closest('table'); var table = th.closest('table'); // Find the closest table
var columnIndex = th.index(); var columnIndex = th.index(); // Get the index of the column
var ascending = !th.data('asc'); var ascending = !th.data('asc'); // Toggle sorting order
sortTable(table, columnIndex, ascending); sortTable(table, columnIndex, ascending);
th.data('asc', ascending); th.data('asc', ascending); // Store sorting order
} }
// Function to sort the table based on the selected column
function sortTable(table, columnIndex, ascending) { function sortTable(table, columnIndex, ascending) {
var tbody = table.find('tbody'); var tbody = table.find('tbody'); // Get the table body
var rows = tbody.find('tr').toArray().sort(comparer(columnIndex)); var rows = tbody.find('tr').toArray().sort(comparer(columnIndex)); // Convert rows to an array and sort
if (!ascending) { if (!ascending) {
rows = rows.reverse(); rows = rows.reverse(); // Reverse order if descending
} }
for (var i = 0; i < rows.length; i++) { for (var i = 0; i < rows.length; i++) {
tbody.append(rows[i]); tbody.append(rows[i]); // Append sorted rows back to the table
} }
} }
// Function to compare values in the selected column
function comparer(index) { function comparer(index) {
return function(a, b) { return function (a, b) {
var valA = getCellValue(a, index); var valA = getCellValue(a, index);
var valB = getCellValue(b, index); var valB = getCellValue(b, index);
return $.isNumeric(valA) && $.isNumeric(valB) ? valA - valB : valA.localeCompare(valB);
// Check if both values are valid IP addresses, and sort numerically if so
if (isIPAddress(valA) && isIPAddress(valB)) {
return ipToNum(valA) - ipToNum(valB);
}
// If both values are numbers, sort numerically
if ($.isNumeric(valA) && $.isNumeric(valB)) {
return valA - valB;
}
// Otherwise, sort as text
return valA.localeCompare(valB);
}; };
} }
// Function to get the text value from a table cell
function getCellValue(row, index) { function getCellValue(row, index) {
return $(row).children('td').eq(index).text(); return $(row).children('td').eq(index).text().trim(); // Get text from the specified column and trim spaces
} }
// Function to check if a string is a valid IPv4 address
function isIPAddress(value) {
return /^\d{1,3}(\.\d{1,3}){3}$/.test(value); // Regular expression to match IPv4 format
}
// Function to convert an IP address to a numeric value for sorting
function ipToNum(ip) {
return ip.split('.').reduce((acc, octet) => (acc << 8) + parseInt(octet, 10), 0);
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// handling events // handling events
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

4178
front/lib/treeviz/bundle.js Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -136,7 +136,8 @@
onChange, onChange,
customParams, customParams,
customId, customId,
columns columns,
base64Regex
} = handleElementOptions('none', elementOptions, transformers, val = ""); } = handleElementOptions('none', elementOptions, transformers, val = "");
// render based on element type // render based on element type

View File

@@ -464,9 +464,8 @@
require 'php/templates/footer.php'; require 'php/templates/footer.php';
?> ?>
<script src="lib/treeviz/bundle.js"></script>
<script src="lib/treeviz/index.js"></script> <script src="lib/treeviz/bundle.js.map"></script>
<script src="lib/treeviz/require.js"></script>
<script defer> <script defer>
@@ -527,7 +526,6 @@
// Init global variable // Init global variable
deviceListGlobal = devicesListnew; deviceListGlobal = devicesListnew;
// create tree // create tree
initTree(getHierarchy()); initTree(getHierarchy());
@@ -538,378 +536,414 @@
<script defer> <script defer>
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Tree functionality // Tree functionality
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
var leafNodesCount = 0;
var visibleNodesCount = 0;
var parentNodesCount = 0;
var hiddenMacs = []; // hidden children
var hiddenChildren = [];
var deviceListGlobal = null;
// ---------------------------------------------------------------------------
// Recursively get children nodes and build a tree
function getChildren(node, list, path, visited = [])
{
var children = [];
// Check for infinite recursion by seeing if the node has been visited before
if (visited.includes(node.mac.toLowerCase())) {
console.error("Infinite recursion detected at node:", node.mac);
write_notification("[ERROR] ⚠ Infinite recursion detected. You probably have assigned the Internet node to another children node or to itself. Please open a new issue on GitHub and describe how you did it.", 'interrupt')
return { error: "Infinite recursion detected", node: node.mac };
}
// Add current node to visited list
visited.push(node.mac.toLowerCase());
// Loop through all items to find children of the current node
for (var i in list) {
if (list[i].parentMac.toLowerCase() == node.mac.toLowerCase() && !hiddenMacs.includes(list[i].parentMac)) {
visibleNodesCount++;
// Process children recursively, passing a copy of the visited list
children.push(getChildren(list[i], list, path + ((path == "") ? "" : '|') + list[i].parentMac, visited));
}
}
// Track leaf and parent node counts
if (children.length == 0) {
leafNodesCount++;
} else {
parentNodesCount++;
}
return {
name: node.name,
path: path,
mac: node.mac,
port: node.port,
id: node.mac,
parentMac: node.parentMac,
icon: node.icon,
type: node.type,
status: node.status,
hasChildren: children.length > 0 || hiddenMacs.includes(node.mac),
hiddenChildren: hiddenMacs.includes(node.mac),
qty: children.length,
children: children
};
}
// ---------------------------------------------------------------------------
function getHierarchy()
{
for(i in deviceListGlobal)
{
if(deviceListGlobal[i].mac == 'Internet')
{
return (getChildren(deviceListGlobal[i], deviceListGlobal, ''))
break;
}
}
}
// ---------------------------------------------------------------------------
function getFlatData() {
var result = [];
var leafNodesCount = 0; var leafNodesCount = 0;
var visibleNodesCount = 0;
var parentNodesCount = 0; var parentNodesCount = 0;
var hiddenMacs = []; // hidden children var visibleNodesCount = 0;
var hiddenChildren = [];
var deviceListGlobal = null;
for (let node of deviceListGlobal) {
let path = "";
let childrenCount = 0;
// count children of this node
for (let nodeTmp of deviceListGlobal) {
if (nodeTmp.parentMac === node.mac) {
childrenCount++;
}
}
// store parent and leaf node count
if (childrenCount === 0) {
leafNodesCount++;
} else {
parentNodesCount++;
}
// --------------------------------------------------------------------------- if (!hiddenMacs.includes(node.parentMac)) {
// Recursively get children nodes and build a tree if (!((node.parentMac == "") && node.mac != "Internet")) { // skip leaf nodes without father that are not the root
function getChildren(node, list, path, visited = []) visibleNodesCount++;
{
var children = [];
// Check for infinite recursion by seeing if the node has been visited before result.push({
if (visited.includes(node.mac.toLowerCase())) { name: node.name,
console.error("Infinite recursion detected at node:", node.mac); path: path,
write_notification("[ERROR] ⚠ Infinite recursion detected. You probably have assigned the Internet node to another children node or to itself. Please open a new issue on GitHub and describe how you did it.", 'interrupt') mac: node.mac, // Replacing "mac" with "id"
return { error: "Infinite recursion detected", node: node.mac }; parentMac: node.mac == "Internet" ? "" : node.parentMac, // Replacing "parentMac" with "father"
} port: node.port,
icon: node.icon,
// Add current node to visited list type: node.type,
visited.push(node.mac.toLowerCase()); status: node.status,
hasChildren: childrenCount > 0 || hiddenMacs.includes(node.mac),
// Loop through all items to find children of the current node hiddenChildren: hiddenMacs.includes(node.mac),
for (var i in list) { qty: childrenCount,
if (list[i].parentMac.toLowerCase() == node.mac.toLowerCase() && !hiddenMacs.includes(list[i].parentMac)) { });
visibleNodesCount++;
// Process children recursively, passing a copy of the visited list
children.push(getChildren(list[i], list, path + ((path == "") ? "" : '|') + list[i].parentMac, visited));
}
}
// Track leaf and parent node counts
if (children.length == 0) {
leafNodesCount++;
} else {
parentNodesCount++;
}
return {
name: node.name,
path: path,
mac: node.mac,
port: node.port,
id: node.mac,
parentMac: node.parentMac,
icon: node.icon,
type: node.type,
status: node.status,
hasChildren: children.length > 0 || hiddenMacs.includes(node.mac),
hiddenChildren: hiddenMacs.includes(node.mac),
qty: children.length,
children: children
};
}
// ---------------------------------------------------------------------------
function getHierarchy()
{
for(i in deviceListGlobal)
{
if(deviceListGlobal[i].mac == 'Internet')
{
return (getChildren(deviceListGlobal[i], deviceListGlobal, ''))
break;
} }
} }
} }
return result;
}
// --------------------------------------------------------------------------- //---------------------------------------------------------------------------
function toggleSubTree(parentMac, treePath) function toggleSubTree(parentMac, treePath)
{
treePath = treePath.split('|')
if(!hiddenMacs.includes(parentMac))
{ {
treePath = treePath.split('|') hiddenMacs.push(parentMac)
}
if(!hiddenMacs.includes(parentMac)) else
{ {
hiddenMacs.push(parentMac) removeItemFromArray(hiddenMacs, parentMac)
}
else
{
removeItemFromArray(hiddenMacs, parentMac)
}
// updatedTree = myHierarchy;
updatedTree = getHierarchy()
myTree.refresh(updatedTree);
// re-attach any onclick events
attachTreeEvents();
} }
// --------------------------------------------------------------------------- updatedTree = getHierarchy()
function attachTreeEvents() myTree.refresh(updatedTree);
// re-attach any onclick events
attachTreeEvents();
}
// ---------------------------------------------------------------------------
function attachTreeEvents()
{
// toggle subtree functionality
$("div[data-mytreemac]").each(function(){
$(this).attr('onclick', 'toggleSubTree("'+$(this).attr('data-mytreemac')+'","'+ $(this).attr('data-mytreepath')+'")')
});
}
// ---------------------------------------------------------------------------
// Handle network node click - select correct tab in the bottom table
function handleNodeClick(nodeData)
{
const targetTabMAC = nodeData.data.mac;
var targetTab = $(`a[data-mytabmac="${targetTabMAC}"]`);
// Simulate a click event on the target tab
targetTab.click();
}
// ---------------------------------------------------------------------------
var myTree;
var visibleTreeArea = $(window).height()-155;
var nodeWidth = 120;
var emSize;
var nodeHeight;
var sizeCoefficient = 1.4
function initTree(myHierarchy)
{
// calculate the drawing area based on teh tree width and available screen size
var treeAreaHeight = visibleTreeArea > 800 ? 800 : visibleTreeArea;
let screenWidth = $('.content-header').width();
let treeWidth = (nodeWidth + 20) * parentNodesCount;
let treeAreaWidth = screenWidth < treeWidth ? treeWidth : screenWidth;
// init the drawing area size
$("#networkTree").attr('style', `height:${treeAreaHeight}px; width:${treeAreaWidth}px`)
if(myHierarchy.type == "")
{ {
// toggle subtree functionality showModalOk(getString('Network_Configuration_Error'), getString('Network_Root_Not_Configured'))
$("div[data-mytreemac]").each(function(){
$(this).attr('onclick', 'toggleSubTree("'+$(this).attr('data-mytreemac')+'","'+ $(this).attr('data-mytreepath')+'")') return;
});
} }
// --------------------------------------------------------------------------- // calculate the font size of the leaf nodes to fit everything into the tree area
// Handle network node click - select correct tab in the bottom table leafNodesCount == 0 ? 1 : leafNodesCount;
function handleNodeClick(event) emSize = ((treeAreaHeight/(25*leafNodesCount)).toFixed(2));
{ emSize = emSize > 1 ? 1 : emSize;
// console.log(event.target.offsetParent.offsetParent)
const targetTabMAC = $(event.target.offsetParent.offsetParent).attr("data-mytreemacmain"); // nodeHeight = ((emSize*100*0.30).toFixed(0))
nodeHeight = ((emSize*100*0.30).toFixed(0))
var targetTab = $(`a[data-mytabmac="${targetTabMAC}"]`); console.log(Treeviz);
// Simulate a click event on the target tab myTree = Treeviz.create({
targetTab.click(); htmlId: "networkTree",
} renderNode: nodeData => {
// --------------------------------------------------------------------------- var fontSize = "font-size:"+emSize+"em;";
var myTree;
var visibleTreeArea = $(window).height()-155;
var nodeWidth = 160;
var emSize;
var nodeHeight;
var sizeCoefficient = 1
function initTree(myHierarchy) (!emptyArr.includes(nodeData.data.port )) ? port = nodeData.data.port : port = "";
{
console.log(myHierarchy)
// calculate the drawing area based on teh tree width and available screen size (port == "" || port == 0 || port == 'None' ) ? portBckgIcon = `<i class="fa fa-wifi"></i>` : portBckgIcon = `<i class="fa fa-ethernet"></i>`;
var treeAreaHeight = visibleTreeArea > 800 ? 800 : visibleTreeArea;
let screenWidth = $('.content-header').width();
let treeWidth = (nodeWidth + 20) * parentNodesCount;
let treeAreaWidth = screenWidth < treeWidth ? treeWidth : screenWidth;
// init the drawing area size portHtml = (port == "" || port == 0 || port == 'None' ) ? "" : port;
$("#networkTree").attr('style', `height:${treeAreaHeight}px; width:${treeAreaWidth}px`)
if(myHierarchy.type == "") // Build HTML for individual nodes in the network diagram
{ deviceIcon = (!emptyArr.includes(nodeData.data.icon )) ?
showModalOk(getString('Network_Configuration_Error'), getString('Network_Root_Not_Configured')) `<div class="netIcon">
${atob(nodeData.data.icon)}
</div>` : "";
devicePort = `<div class="netPort"
style="width:${emSize*sizeCoefficient}em;height:${emSize*sizeCoefficient}em">
${portHtml}</div>
<div class="portBckgIcon"
style="margin-left:-${emSize*sizeCoefficient}em;">
${portBckgIcon}
</div>`;
collapseExpandIcon = nodeData.data.hiddenChildren ?
"square-plus" : "square-minus";
return; // generate +/- icon if node has children nodes
} collapseExpandHtml = nodeData.data.hasChildren ?
`<div class="netCollapse"
style="font-size:${emSize*sizeCoefficient}em;top:${emSize/6}em"
data-mytreepath="${nodeData.data.path}"
data-mytreemac="${nodeData.data.mac}">
<i class="fa fa-${collapseExpandIcon} pointer"></i>
</div>` : "";
// calculate the font size of the leaf nodes to fit everything into the tree area selectedNodeMac = $(".nav-tabs-custom .active a").attr('data-mytabmac')
leafNodesCount == 0 ? 1 : leafNodesCount;
emSize = ((treeAreaHeight/(25*leafNodesCount)).toFixed(2));
emSize = emSize > 1 ? 1 : emSize;
// nodeHeight = ((emSize*100*0.30).toFixed(0)) highlightedCss = nodeData.data.mac == selectedNodeMac ?
nodeHeight = ((emSize*100*0.30).toFixed(0)) " highlightedNode" : "";
console.log(Treeviz); // css indicating online/offline status
statusCss = ` netStatus-${nodeData.data.status}`;
myTree = Treeviz.create({
htmlId: "networkTree",
renderNode: nodeData => {
var fontSize = "font-size:"+emSize+"em;";
(!emptyArr.includes(nodeData.data.port )) ? port = nodeData.data.port : port = "";
(port == "" || port == 0 || port == 'None' ) ? portBckgIcon = `<i class="fa fa-wifi"></i>` : portBckgIcon = `<i class="fa fa-ethernet"></i>`;
portHtml = (port == "" || port == 0 || port == 'None' ) ? "" : port
// Build HTML for individual nodes in the network diagram
deviceIcon = (!emptyArr.includes(nodeData.data.icon )) ?
`<div class="netIcon">
${atob(nodeData.data.icon)}
</div>` : "";
devicePort = `<div class="netPort"
style="width:${emSize*sizeCoefficient}em;height:${emSize*sizeCoefficient}em">
${portHtml}</div>
<div class="portBckgIcon"
style="margin-left:-${emSize*sizeCoefficient}em;">
${portBckgIcon}
</div>`;
collapseExpandIcon = nodeData.data.hiddenChildren ?
"square-plus" : "square-minus";
// generate +/- icon if node has children nodes
collapseExpandHtml = nodeData.data.hasChildren ?
`<div class="netCollapse"
style="font-size:${emSize*sizeCoefficient}em;top:${1/2*emSize*sizeCoefficient}em"
data-mytreepath="${nodeData.data.path}"
data-mytreemac="${nodeData.data.mac}">
<i class="fa fa-${collapseExpandIcon} pointer"></i>
</div>` : "";
selectedNodeMac = $(".nav-tabs-custom .active a").attr('data-mytabmac')
highlightedCss = nodeData.data.mac == selectedNodeMac ?
" highlightedNode" : "";
// css indicating online/offline status
statusCss = ` netStatus-${nodeData.data.status}`;
return result = `<div class="box ${nodeData.data.hasChildren ? "pointer":""} ${statusCss} ${highlightedCss}"
data-mytreemacmain="${nodeData.data.mac}"
style="height:${nodeData.settings.nodeHeight}px;${fontSize}"
>
<div class="netNodeText">
<strong>${devicePort} ${deviceIcon}
<span class="spanNetworkTree anonymizeDev" >${nodeData.data.name}</span>
</strong>
${collapseExpandHtml}
</div>
</div>`;
},
onNodeClick: nodeData => {
console.log(this)
},
mainAxisNodeSpacing: 'auto',
// mainAxisNodeSpacing: 3,
secondaryAxisNodeSpacing: 0.3,
nodeHeight: nodeHeight.toString(),
marginTop: '5',
hasZoom: true,
hasPan: true,
// marginLeft: '15',
idKey: "id",
hasFlatData: false,
linkWidth: (nodeData) => 3,
linkColor: (nodeData) => "#ffcc80",
onNodeClick: (nodeData) => handleNodeClick(nodeData),
relationnalField: "children",
});
myTree.refresh(myHierarchy);
// hide spinning icon
hideSpinner()
}
// ---------------------------------------------------------------------------
// Tabs functionality
// ---------------------------------------------------------------------------
// Register events on tab change
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
initButtons()
return result = `<div class="box ${nodeData.data.hasChildren ? "pointer":""} ${statusCss} ${highlightedCss}"
data-mytreemacmain="${nodeData.data.mac}"
style="height:${nodeData.settings.nodeHeight}px;${fontSize}"
>
<div class="netNodeText">
<strong>${devicePort} ${deviceIcon}
<span class="spanNetworkTree anonymizeDev" >${nodeData.data.name}</span>
</strong>
${collapseExpandHtml}
</div>
</div>`;
},
mainAxisNodeSpacing: 'auto',
secondaryAxisNodeSpacing: 0.3,
nodeHeight: nodeHeight.toString(),
marginTop: '5',
isHorizontal : true,
hasZoom: true,
hasPan: true,
marginLeft: '15',
idKey: "mac",
hasFlatData: false,
relationnalField: "children",
linkWidth: (nodeData) => 3,
linkColor: (nodeData) => "#ffcc80",
onNodeClick: (nodeData) => handleNodeClick(nodeData),
}); });
console.log(deviceListGlobal);
myTree.refresh(myHierarchy);
// --------------------------------------------------------------------------- // hide spinning icon
function initTab() hideSpinner()
{ }
key = "activeNetworkTab"
// default selection
selectedTab = "Internet_id"
// the #target from the url
target = getQueryString('mac')
// update cookie if target specified
if(target != "")
{
setCache(key, target.replaceAll(":","_")+'_id') // _id is added so it doesn't conflict with AdminLTE tab behavior
}
// get the tab id from the cookie (already overridden by the target)
if(!emptyArr.includes(getCache(key)))
{
selectedTab = getCache(key);
}
// Activate panel
$('.nav-tabs a[id='+ selectedTab +']').tab('show');
// When changed save new current tab
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
setCache(key, $(e.target).attr('id'))
});
}
// ---------------------------------------------------------------------------
function initDeviceNamesFromMACs()
{
$('.mac-to-name').each(function() {
var dataMacValue = $(this).attr('my-data-mac');
if(dataMacValue =="" )
{
$(this).html(getString("Network_Root"))
}
else{
$(this).html(getNameByMacAddress(dataMacValue));
}
}); // ---------------------------------------------------------------------------
// Tabs functionality
// ---------------------------------------------------------------------------
// Register events on tab change
} $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
// ---------------------------------------------------------------------------
function initButtons()
{
var currentNodeMac = $(".tab-content .active td[data-mynodemac]").attr('data-mynodemac');
// change highlighted node in the tree
selNode = $("#networkTree .highlightedNode")[0]
// console.log(selNode)
if(selNode)
{
$(selNode).attr('class', $(selNode).attr('class').replace('highlightedNode'))
}
newSelNode = $("#networkTree div[data-mytreemacmain='"+currentNodeMac+"']")[0]
$(newSelNode).attr('class', $(newSelNode).attr('class') + ' highlightedNode')
// init the Assign buttons
$('#unassignedDevices button[data-myleafmac]').each(function(){
$(this).attr('onclick', `updateLeaf("${$(this).attr('data-myleafmac')}","${currentNodeMac}")`)
});
// init Unassign buttons
$('#assignedDevices button[data-myleafmac]').each(function(){
$(this).attr('onclick', `updateLeaf("${$(this).attr('data-myleafmac')}","")`)
});
}
// ---------------------------------------------------------------------------
function updateLeaf(leafMac,nodeMac)
{
console.log(leafMac) // child
console.log(nodeMac) // parent
console.log(nodeMac != "") // parent
// prevent the assignment of the Internet root node avoiding recursion when generating the network tree topology
if(leafMac.toLowerCase().includes('internet') && nodeMac != "")
{
showMessage(getString('Network_Cant_Assign'))
}
else{
saveData('updateNetworkLeaf', leafMac, nodeMac);
setTimeout("location.reload();", 500); // refresh page
}
}
// init device names where macs are used
initDeviceNamesFromMACs();
// init selected (first) tab
initTab();
// init Assign/Unassign buttons
initButtons() initButtons()
});
// ---------------------------------------------------------------------------
function initTab()
{
key = "activeNetworkTab"
// default selection
selectedTab = "Internet_id"
// the #target from the url
target = getQueryString('mac')
// update cookie if target specified
if(target != "")
{
setCache(key, target.replaceAll(":","_")+'_id') // _id is added so it doesn't conflict with AdminLTE tab behavior
}
// get the tab id from the cookie (already overridden by the target)
if(!emptyArr.includes(getCache(key)))
{
selectedTab = getCache(key);
}
// Activate panel
$('.nav-tabs a[id='+ selectedTab +']').tab('show');
// When changed save new current tab
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
setCache(key, $(e.target).attr('id'))
});
}
// ---------------------------------------------------------------------------
function initDeviceNamesFromMACs()
{
$('.mac-to-name').each(function() {
var dataMacValue = $(this).attr('my-data-mac');
if(dataMacValue =="" )
{
$(this).html(getString("Network_Root"))
}
else{
$(this).html(getNameByMacAddress(dataMacValue));
}
});
}
// ---------------------------------------------------------------------------
function initButtons()
{
var currentNodeMac = $(".tab-content .active td[data-mynodemac]").attr('data-mynodemac');
// change highlighted node in the tree
selNode = $("#networkTree .highlightedNode")[0]
// console.log(selNode)
if(selNode)
{
$(selNode).attr('class', $(selNode).attr('class').replace('highlightedNode'))
}
newSelNode = $("#networkTree div[data-mytreemacmain='"+currentNodeMac+"']")[0]
$(newSelNode).attr('class', $(newSelNode).attr('class') + ' highlightedNode')
// init the Assign buttons
$('#unassignedDevices button[data-myleafmac]').each(function(){
$(this).attr('onclick', `updateLeaf("${$(this).attr('data-myleafmac')}","${currentNodeMac}")`)
});
// init Unassign buttons
$('#assignedDevices button[data-myleafmac]').each(function(){
$(this).attr('onclick', `updateLeaf("${$(this).attr('data-myleafmac')}","")`)
});
}
// ---------------------------------------------------------------------------
function updateLeaf(leafMac,nodeMac)
{
console.log(leafMac) // child
console.log(nodeMac) // parent
console.log(nodeMac != "") // parent
// prevent the assignment of the Internet root node avoiding recursion when generating the network tree topology
if(leafMac.toLowerCase().includes('internet') && nodeMac != "")
{
showMessage(getString('Network_Cant_Assign'))
}
else{
saveData('updateNetworkLeaf', leafMac, nodeMac);
setTimeout("location.reload();", 500); // refresh page
}
}
// init device names where macs are used
initDeviceNamesFromMACs();
// init selected (first) tab
initTab();
// init Assign/Unassign buttons
initButtons()
</script> </script>

View File

@@ -17,7 +17,7 @@ function renderFilterDropdown($headerKey, $columnName, $values) {
// Generate the dropdown HTML // Generate the dropdown HTML
return ' return '
<div class="filter-group"> <div class="filter-group input-group">
<label for="filter_' . htmlspecialchars($columnName) . '">' . lang($headerKey) . '</label> <label for="filter_' . htmlspecialchars($columnName) . '">' . lang($headerKey) . '</label>
<select id="filter_' . htmlspecialchars($columnName) . '" class="filter-dropdown" data-column="' . htmlspecialchars($columnName) . '"> <select id="filter_' . htmlspecialchars($columnName) . '" class="filter-dropdown" data-column="' . htmlspecialchars($columnName) . '">
' . $optionsHtml . ' ' . $optionsHtml . '

View File

@@ -328,6 +328,7 @@
"Gen_Upd_Fail": "", "Gen_Upd_Fail": "",
"Gen_Update": "", "Gen_Update": "",
"Gen_Update_Value": "", "Gen_Update_Value": "",
"Gen_ValidIcon": "",
"Gen_Warning": "", "Gen_Warning": "",
"Gen_Work_In_Progress": "", "Gen_Work_In_Progress": "",
"Gen_create_new_device": "", "Gen_create_new_device": "",

View File

@@ -62,7 +62,7 @@
"CLEAR_NEW_FLAG_name": "Netejar indicador de nou", "CLEAR_NEW_FLAG_name": "Netejar indicador de nou",
"CustProps_cant_remove": "No es pot eliminar, es necessita una propietat mínim.", "CustProps_cant_remove": "No es pot eliminar, es necessita una propietat mínim.",
"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 anteriors", "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",
@@ -138,8 +138,8 @@
"DevDetail_Shortcut_DownAlerts": "Aturar alertes", "DevDetail_Shortcut_DownAlerts": "Aturar alertes",
"DevDetail_Shortcut_Presence": "Presència", "DevDetail_Shortcut_Presence": "Presència",
"DevDetail_Shortcut_Sessions": "Sessions", "DevDetail_Shortcut_Sessions": "Sessions",
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Detalls", "DevDetail_Tab_Details": "Detalls",
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Esdeveniments", "DevDetail_Tab_Events": "Esdeveniments",
"DevDetail_Tab_EventsTableDate": "Data", "DevDetail_Tab_EventsTableDate": "Data",
"DevDetail_Tab_EventsTableEvent": "Tipus d'esdeveniment", "DevDetail_Tab_EventsTableEvent": "Tipus d'esdeveniment",
"DevDetail_Tab_EventsTableIP": "IP", "DevDetail_Tab_EventsTableIP": "IP",
@@ -154,10 +154,10 @@
"DevDetail_Tab_NmapTableState": "Estat", "DevDetail_Tab_NmapTableState": "Estat",
"DevDetail_Tab_NmapTableText": "Configurar un calendari a <a href=\"/settings.php#NMAP_ACTIVE\">Configuració</a>", "DevDetail_Tab_NmapTableText": "Configurar un calendari a <a href=\"/settings.php#NMAP_ACTIVE\">Configuració</a>",
"DevDetail_Tab_NmapTableTime": "Temps", "DevDetail_Tab_NmapTableTime": "Temps",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Connectors (Plugins)", "DevDetail_Tab_Plugins": "Connectors (Plugins)",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Presència", "DevDetail_Tab_Presence": "Presència",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sessions", "DevDetail_Tab_Sessions": "Sessions",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Eines", "DevDetail_Tab_Tools": "Eines",
"DevDetail_Tab_Tools_Internet_Info_Description": "L'eina d'informació d'Internet mostra informació sobre la connexió a Internet, com ara adreça IP, ciutat, país, codi d'àrea i zona horària.", "DevDetail_Tab_Tools_Internet_Info_Description": "L'eina d'informació d'Internet mostra informació sobre la connexió a Internet, com ara adreça IP, ciutat, país, codi d'àrea i zona horària.",
"DevDetail_Tab_Tools_Internet_Info_Error": "S'ha produït un error", "DevDetail_Tab_Tools_Internet_Info_Error": "S'ha produït un error",
"DevDetail_Tab_Tools_Internet_Info_Start": "Inici Informació d'Internet", "DevDetail_Tab_Tools_Internet_Info_Start": "Inici Informació d'Internet",
@@ -242,7 +242,7 @@
"Device_Tablelenght": "Veure_entrades_MENU", "Device_Tablelenght": "Veure_entrades_MENU",
"Device_Tablelenght_all": "Tot", "Device_Tablelenght_all": "Tot",
"Device_Title": "Dispositius", "Device_Title": "Dispositius",
"Devices_Filters": "", "Devices_Filters": "Filtres",
"Donations_Others": "Altres", "Donations_Others": "Altres",
"Donations_Platforms": "Plataformes patrocinadores", "Donations_Platforms": "Plataformes patrocinadores",
"Donations_Text": "Hola 👋! </br> Gràcies per fer clic en aquest element de menú 😅 </br> </br> Estic intentant recollir algunes donacions per fer un millor programari. També, m'ajudaria per cremar-me, i així recolzar aquesta aplicació més temps. Qualsevol petit (recurrent o no) patrocini em farà posar més esforç a aquesta aplicació. </br> M'agradaria escurçar la meva setmana de feina i en el temps restant enfocar-me en el NetAlertX. Així rebries més funcionalitat, una aplicació més neta i menys bugs. </br> </br> Gràcies per llegir-ho - Agraeixo qualsevol suport ❤🙏 </br> </br> TL;DR: Pel teu suport reps: </br> </br> <ul><li>Actualitzacions regulars per seguir les vostres dades i mantenir la família segura 🔄</li><li>Menys bugs 🐛🔫</li><li>Millor i més funcionalitat</li><li>Que no m'arribi el \"burn out\" 🔥🤯</li><li>Menys actualitzacions d'emergència 💨</li><li>Millors documentacions📚</li><li>Suport més ràpid i millor amb les incidències 🆘</li></ul> </br> 📧Correu electrònic <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> si vols contactar o si hauria d'afegir altres programes de patrocini. </br>", "Donations_Text": "Hola 👋! </br> Gràcies per fer clic en aquest element de menú 😅 </br> </br> Estic intentant recollir algunes donacions per fer un millor programari. També, m'ajudaria per cremar-me, i així recolzar aquesta aplicació més temps. Qualsevol petit (recurrent o no) patrocini em farà posar més esforç a aquesta aplicació. </br> M'agradaria escurçar la meva setmana de feina i en el temps restant enfocar-me en el NetAlertX. Així rebries més funcionalitat, una aplicació més neta i menys bugs. </br> </br> Gràcies per llegir-ho - Agraeixo qualsevol suport ❤🙏 </br> </br> TL;DR: Pel teu suport reps: </br> </br> <ul><li>Actualitzacions regulars per seguir les vostres dades i mantenir la família segura 🔄</li><li>Menys bugs 🐛🔫</li><li>Millor i més funcionalitat</li><li>Que no m'arribi el \"burn out\" 🔥🤯</li><li>Menys actualitzacions d'emergència 💨</li><li>Millors documentacions📚</li><li>Suport més ràpid i millor amb les incidències 🆘</li></ul> </br> 📧Correu electrònic <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> si vols contactar o si hauria d'afegir altres programes de patrocini. </br>",
@@ -328,6 +328,7 @@
"Gen_Upd_Fail": "Actualització fallida", "Gen_Upd_Fail": "Actualització fallida",
"Gen_Update": "Actualitza", "Gen_Update": "Actualitza",
"Gen_Update_Value": "Actualitzar Valor", "Gen_Update_Value": "Actualitzar Valor",
"Gen_ValidIcon": "",
"Gen_Warning": "Advertència", "Gen_Warning": "Advertència",
"Gen_Work_In_Progress": "Work in progress, un bon moment per retroalimentació a https://github.com/jokob-sk/NetAlertX/issues", "Gen_Work_In_Progress": "Work in progress, un bon moment per retroalimentació a https://github.com/jokob-sk/NetAlertX/issues",
"Gen_create_new_device": "Nou dispositiu", "Gen_create_new_device": "Nou dispositiu",
@@ -717,7 +718,7 @@
"general_event_title": "Execució d'un esdeveniment ad-hoc", "general_event_title": "Execució d'un esdeveniment ad-hoc",
"go_to_node_event_icon": "fa-square-up-right", "go_to_node_event_icon": "fa-square-up-right",
"go_to_node_event_tooltip": "Navegació a la pàgina de la Xarxa del node donat", "go_to_node_event_tooltip": "Navegació a la pàgina de la Xarxa del node donat",
"new_version_available": "", "new_version_available": "Ja està disponible una nova versió.",
"report_guid": "Notificació guid:", "report_guid": "Notificació guid:",
"report_guid_missing": "No s'ha trobat la notificació enllaçada. Hi ha un petit retard entre les notificacions enviades recentment i que estiguin disponibles. Refresqui la pàgina i la memòria cau d'aquí uns segons. També és possible que la notificació seleccionada s'hagi esborrat durant el manteniment tal com s'especifica a la configuració <code>DBCLNP_NOTIFI_HIST</code>. <br/> <br/>L'última notificació es mostra en el seu lloc. La notificació perduda té el següent GUID:", "report_guid_missing": "No s'ha trobat la notificació enllaçada. Hi ha un petit retard entre les notificacions enviades recentment i que estiguin disponibles. Refresqui la pàgina i la memòria cau d'aquí uns segons. També és possible que la notificació seleccionada s'hagi esborrat durant el manteniment tal com s'especifica a la configuració <code>DBCLNP_NOTIFI_HIST</code>. <br/> <br/>L'última notificació es mostra en el seu lloc. La notificació perduda té el següent GUID:",
"report_select_format": "Seleccioneu Format:", "report_select_format": "Seleccioneu Format:",

View File

@@ -328,6 +328,7 @@
"Gen_Upd_Fail": "", "Gen_Upd_Fail": "",
"Gen_Update": "", "Gen_Update": "",
"Gen_Update_Value": "", "Gen_Update_Value": "",
"Gen_ValidIcon": "",
"Gen_Warning": "", "Gen_Warning": "",
"Gen_Work_In_Progress": "", "Gen_Work_In_Progress": "",
"Gen_create_new_device": "", "Gen_create_new_device": "",

View File

@@ -150,8 +150,8 @@
"DevDetail_Shortcut_DownAlerts": "Down Meldungen", "DevDetail_Shortcut_DownAlerts": "Down Meldungen",
"DevDetail_Shortcut_Presence": "Anwesenheit", "DevDetail_Shortcut_Presence": "Anwesenheit",
"DevDetail_Shortcut_Sessions": "Sitzungen", "DevDetail_Shortcut_Sessions": "Sitzungen",
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Details", "DevDetail_Tab_Details": "Details",
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Ereignisse", "DevDetail_Tab_Events": "Ereignisse",
"DevDetail_Tab_EventsTableDate": "Datum", "DevDetail_Tab_EventsTableDate": "Datum",
"DevDetail_Tab_EventsTableEvent": "Ereignistype", "DevDetail_Tab_EventsTableEvent": "Ereignistype",
"DevDetail_Tab_EventsTableIP": "IP", "DevDetail_Tab_EventsTableIP": "IP",
@@ -166,10 +166,10 @@
"DevDetail_Tab_NmapTableState": "Status", "DevDetail_Tab_NmapTableState": "Status",
"DevDetail_Tab_NmapTableText": "Erstelle einen Plan über die<a href=\"/settings.php#NMAP_ACTIVE\">Einstellungen</a>", "DevDetail_Tab_NmapTableText": "Erstelle einen Plan über die<a href=\"/settings.php#NMAP_ACTIVE\">Einstellungen</a>",
"DevDetail_Tab_NmapTableTime": "Zeit", "DevDetail_Tab_NmapTableTime": "Zeit",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins", "DevDetail_Tab_Plugins": "Plugins",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Anwesenheit", "DevDetail_Tab_Presence": "Anwesenheit",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sitzungen", "DevDetail_Tab_Sessions": "Sitzungen",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Werkzeuge", "DevDetail_Tab_Tools": "Werkzeuge",
"DevDetail_Tab_Tools_Internet_Info_Description": "Das Internet-Info-Tool zeigt Informationen über die Internetverbindung an, wie z. B. IP-Adresse, Stadt, Land, Ortsvorwahl und Zeitzone.", "DevDetail_Tab_Tools_Internet_Info_Description": "Das Internet-Info-Tool zeigt Informationen über die Internetverbindung an, wie z. B. IP-Adresse, Stadt, Land, Ortsvorwahl und Zeitzone.",
"DevDetail_Tab_Tools_Internet_Info_Error": "Es ist ein Fehler aufgetreten", "DevDetail_Tab_Tools_Internet_Info_Error": "Es ist ein Fehler aufgetreten",
"DevDetail_Tab_Tools_Internet_Info_Start": "Internet-Info starten", "DevDetail_Tab_Tools_Internet_Info_Start": "Internet-Info starten",
@@ -340,6 +340,7 @@
"Gen_Upd_Fail": "Aktualisierung fehlgeschlagen", "Gen_Upd_Fail": "Aktualisierung fehlgeschlagen",
"Gen_Update": "Aktualisieren", "Gen_Update": "Aktualisieren",
"Gen_Update_Value": "Wert aktualisieren", "Gen_Update_Value": "Wert aktualisieren",
"Gen_ValidIcon": "",
"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": "Neues Gerät", "Gen_create_new_device": "Neues Gerät",

View File

@@ -48,7 +48,7 @@
"BackDevices_DBTools_ImportCSVError": "The CSV file could not be imported. Make sure the format is correct.", "BackDevices_DBTools_ImportCSVError": "The CSV file could not be imported. Make sure the format is correct.",
"BackDevices_DBTools_ImportCSVMissing": "The CSV file could not be found under <b>/config/devices.csv.</b>", "BackDevices_DBTools_ImportCSVMissing": "The CSV file could not be found under <b>/config/devices.csv.</b>",
"BackDevices_DBTools_Purge": "The oldest backups were deleted", "BackDevices_DBTools_Purge": "The oldest backups were deleted",
"BackDevices_DBTools_UpdDev": "Device updated successfully", "BackDevices_DBTools_UpdDev": "Device updated successfully. Main devices list may need some time to reload if a scan is in progress.",
"BackDevices_DBTools_UpdDevError": "Error updating device", "BackDevices_DBTools_UpdDevError": "Error updating device",
"BackDevices_DBTools_Upgrade": "Database upgraded successfully", "BackDevices_DBTools_Upgrade": "Database upgraded successfully",
"BackDevices_DBTools_UpgradeError": "Database upgrade failed", "BackDevices_DBTools_UpgradeError": "Database upgrade failed",
@@ -138,8 +138,8 @@
"DevDetail_Shortcut_DownAlerts": "Down Alerts", "DevDetail_Shortcut_DownAlerts": "Down Alerts",
"DevDetail_Shortcut_Presence": "Presence", "DevDetail_Shortcut_Presence": "Presence",
"DevDetail_Shortcut_Sessions": "Sessions", "DevDetail_Shortcut_Sessions": "Sessions",
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Details", "DevDetail_Tab_Details": "Details",
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Events", "DevDetail_Tab_Events": "Events",
"DevDetail_Tab_EventsTableDate": "Date", "DevDetail_Tab_EventsTableDate": "Date",
"DevDetail_Tab_EventsTableEvent": "Event type", "DevDetail_Tab_EventsTableEvent": "Event type",
"DevDetail_Tab_EventsTableIP": "IP", "DevDetail_Tab_EventsTableIP": "IP",
@@ -154,10 +154,10 @@
"DevDetail_Tab_NmapTableState": "State", "DevDetail_Tab_NmapTableState": "State",
"DevDetail_Tab_NmapTableText": "Set up a schedule in <a href=\"/settings.php#NMAP_ACTIVE\">Settings</a>", "DevDetail_Tab_NmapTableText": "Set up a schedule in <a href=\"/settings.php#NMAP_ACTIVE\">Settings</a>",
"DevDetail_Tab_NmapTableTime": "Time", "DevDetail_Tab_NmapTableTime": "Time",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins", "DevDetail_Tab_Plugins": "Plugins",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Presence", "DevDetail_Tab_Presence": "Presence",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sessions", "DevDetail_Tab_Sessions": "Sessions",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Tools", "DevDetail_Tab_Tools": "Tools",
"DevDetail_Tab_Tools_Internet_Info_Description": "The Internet info tool displays information about the Internet connection, such as IP address, city, country, area code and time zone.", "DevDetail_Tab_Tools_Internet_Info_Description": "The Internet info tool displays information about the Internet connection, such as IP address, city, country, area code and time zone.",
"DevDetail_Tab_Tools_Internet_Info_Error": "An error has occurred", "DevDetail_Tab_Tools_Internet_Info_Error": "An error has occurred",
"DevDetail_Tab_Tools_Internet_Info_Start": "Start Internet Info", "DevDetail_Tab_Tools_Internet_Info_Start": "Start Internet Info",
@@ -328,6 +328,7 @@
"Gen_Upd_Fail": "Update failed", "Gen_Upd_Fail": "Update failed",
"Gen_Update": "Update", "Gen_Update": "Update",
"Gen_Update_Value": "Update Value", "Gen_Update_Value": "Update Value",
"Gen_ValidIcon": "<i class=\"fa-solid fa-chevron-right \"></i>",
"Gen_Warning": "Warning", "Gen_Warning": "Warning",
"Gen_Work_In_Progress": "Work in progress, good time to feedback on https://github.com/jokob-sk/NetAlertX/issues", "Gen_Work_In_Progress": "Work in progress, good time to feedback on https://github.com/jokob-sk/NetAlertX/issues",
"Gen_create_new_device": "New device", "Gen_create_new_device": "New device",

View File

@@ -148,8 +148,8 @@
"DevDetail_Shortcut_DownAlerts": "Alerta(s) de caída(s)", "DevDetail_Shortcut_DownAlerts": "Alerta(s) de caída(s)",
"DevDetail_Shortcut_Presence": "Historial", "DevDetail_Shortcut_Presence": "Historial",
"DevDetail_Shortcut_Sessions": "Sesiones", "DevDetail_Shortcut_Sessions": "Sesiones",
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Detalles", "DevDetail_Tab_Details": "Detalles",
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Eventos", "DevDetail_Tab_Events": "Eventos",
"DevDetail_Tab_EventsTableDate": "Fecha", "DevDetail_Tab_EventsTableDate": "Fecha",
"DevDetail_Tab_EventsTableEvent": "Tipo de evento", "DevDetail_Tab_EventsTableEvent": "Tipo de evento",
"DevDetail_Tab_EventsTableIP": "IP", "DevDetail_Tab_EventsTableIP": "IP",
@@ -164,10 +164,10 @@
"DevDetail_Tab_NmapTableState": "Estado", "DevDetail_Tab_NmapTableState": "Estado",
"DevDetail_Tab_NmapTableText": "Establece la programación en los <a href=\"/settings.php#NMAP_ACTIVE\">Ajustes</a>", "DevDetail_Tab_NmapTableText": "Establece la programación en los <a href=\"/settings.php#NMAP_ACTIVE\">Ajustes</a>",
"DevDetail_Tab_NmapTableTime": "Tiempo", "DevDetail_Tab_NmapTableTime": "Tiempo",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins", "DevDetail_Tab_Plugins": "Plugins",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Historial", "DevDetail_Tab_Presence": "Historial",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sesiones", "DevDetail_Tab_Sessions": "Sesiones",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Herramientas", "DevDetail_Tab_Tools": "Herramientas",
"DevDetail_Tab_Tools_Internet_Info_Description": "La herramienta de información de internet muestra información sobre la conexión a Internet, como dirección IP, ciudad, país, código de área y zona horaria.", "DevDetail_Tab_Tools_Internet_Info_Description": "La herramienta de información de internet muestra información sobre la conexión a Internet, como dirección IP, ciudad, país, código de área y zona horaria.",
"DevDetail_Tab_Tools_Internet_Info_Error": "Se ha producido un error", "DevDetail_Tab_Tools_Internet_Info_Error": "Se ha producido un error",
"DevDetail_Tab_Tools_Internet_Info_Start": "Iniciar información de Internet", "DevDetail_Tab_Tools_Internet_Info_Start": "Iniciar información de Internet",
@@ -338,6 +338,7 @@
"Gen_Upd_Fail": "Fallo al actualizar", "Gen_Upd_Fail": "Fallo al actualizar",
"Gen_Update": "Actualizar", "Gen_Update": "Actualizar",
"Gen_Update_Value": "Actualizar valor", "Gen_Update_Value": "Actualizar valor",
"Gen_ValidIcon": "",
"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": "Nuevo dispositivo", "Gen_create_new_device": "Nuevo dispositivo",

15
front/php/templates/language/fr_fr.json Normal file → Executable file
View File

@@ -48,7 +48,7 @@
"BackDevices_DBTools_ImportCSVError": "Le fichier CSV n'a pas pu être importé. Assurez-vous que le format est correct.", "BackDevices_DBTools_ImportCSVError": "Le fichier CSV n'a pas pu être importé. Assurez-vous que le format est correct.",
"BackDevices_DBTools_ImportCSVMissing": "Le fichier CSV est introuvable sous <b>/config/devices.csv.</b>", "BackDevices_DBTools_ImportCSVMissing": "Le fichier CSV est introuvable sous <b>/config/devices.csv.</b>",
"BackDevices_DBTools_Purge": "Les sauvegardes les plus anciennes ont été supprimées", "BackDevices_DBTools_Purge": "Les sauvegardes les plus anciennes ont été supprimées",
"BackDevices_DBTools_UpdDev": "Appareil mis à jour avec succès", "BackDevices_DBTools_UpdDev": "Appareil mis à jour avec succès. La liste principale des appareils peut prendre un peu de temps à se mettre à jour si un scan est en cours.",
"BackDevices_DBTools_UpdDevError": "Erreur lors de la mise à jour de l'appareil", "BackDevices_DBTools_UpdDevError": "Erreur lors de la mise à jour de l'appareil",
"BackDevices_DBTools_Upgrade": "Base de données mise à niveau avec succès", "BackDevices_DBTools_Upgrade": "Base de données mise à niveau avec succès",
"BackDevices_DBTools_UpgradeError": "La mise à niveau de la base de données a échoué", "BackDevices_DBTools_UpgradeError": "La mise à niveau de la base de données a échoué",
@@ -138,8 +138,8 @@
"DevDetail_Shortcut_DownAlerts": "Alertes de panne", "DevDetail_Shortcut_DownAlerts": "Alertes de panne",
"DevDetail_Shortcut_Presence": "Présence", "DevDetail_Shortcut_Presence": "Présence",
"DevDetail_Shortcut_Sessions": "Sessions", "DevDetail_Shortcut_Sessions": "Sessions",
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Détails", "DevDetail_Tab_Details": "Détails",
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Événements", "DevDetail_Tab_Events": "Événements",
"DevDetail_Tab_EventsTableDate": "Date", "DevDetail_Tab_EventsTableDate": "Date",
"DevDetail_Tab_EventsTableEvent": "Type d'événement", "DevDetail_Tab_EventsTableEvent": "Type d'événement",
"DevDetail_Tab_EventsTableIP": "IP", "DevDetail_Tab_EventsTableIP": "IP",
@@ -154,10 +154,10 @@
"DevDetail_Tab_NmapTableState": "État", "DevDetail_Tab_NmapTableState": "État",
"DevDetail_Tab_NmapTableText": "Configurer une programmation dans les <a href=\"/settings.php#NMAP_ACTIVE\">Paramètres</a>", "DevDetail_Tab_NmapTableText": "Configurer une programmation dans les <a href=\"/settings.php#NMAP_ACTIVE\">Paramètres</a>",
"DevDetail_Tab_NmapTableTime": "Heure", "DevDetail_Tab_NmapTableTime": "Heure",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins", "DevDetail_Tab_Plugins": "Plugins",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Présence", "DevDetail_Tab_Presence": "Présence",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sessions", "DevDetail_Tab_Sessions": "Sessions",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Outils", "DevDetail_Tab_Tools": "Outils",
"DevDetail_Tab_Tools_Internet_Info_Description": "L'outil Infos Internet affiche les informations sur la connexion Internet, comme l'adresse IP, la ville, la région, le code région et le fuseau horaire.", "DevDetail_Tab_Tools_Internet_Info_Description": "L'outil Infos Internet affiche les informations sur la connexion Internet, comme l'adresse IP, la ville, la région, le code région et le fuseau horaire.",
"DevDetail_Tab_Tools_Internet_Info_Error": "Une erreur est survenue", "DevDetail_Tab_Tools_Internet_Info_Error": "Une erreur est survenue",
"DevDetail_Tab_Tools_Internet_Info_Start": "Lancer les informations Internet", "DevDetail_Tab_Tools_Internet_Info_Start": "Lancer les informations Internet",
@@ -328,6 +328,7 @@
"Gen_Upd_Fail": "Échec de la mise à jour", "Gen_Upd_Fail": "Échec de la mise à jour",
"Gen_Update": "Mise à jour", "Gen_Update": "Mise à jour",
"Gen_Update_Value": "Valeur à mettre à jour", "Gen_Update_Value": "Valeur à mettre à jour",
"Gen_ValidIcon": "",
"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": "Nouvel appareil", "Gen_create_new_device": "Nouvel appareil",

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

@@ -48,7 +48,7 @@
"BackDevices_DBTools_ImportCSVError": "Impossibile importare il file CSV. Assicurati che il formato del file sia corretto.", "BackDevices_DBTools_ImportCSVError": "Impossibile importare il file CSV. Assicurati che il formato del file sia corretto.",
"BackDevices_DBTools_ImportCSVMissing": "Impossibile trovare il file CSV in <b>/config/devices.csv.</b>", "BackDevices_DBTools_ImportCSVMissing": "Impossibile trovare il file CSV in <b>/config/devices.csv.</b>",
"BackDevices_DBTools_Purge": "I backup più vecchi sono stati eliminati", "BackDevices_DBTools_Purge": "I backup più vecchi sono stati eliminati",
"BackDevices_DBTools_UpdDev": "Dispositivo aggiornato correttamente", "BackDevices_DBTools_UpdDev": "Dispositivo aggiornato correttamente. L'elenco dei dispositivi principali potrebbe richiedere del tempo per ricaricarsi se è in corso una scansione.",
"BackDevices_DBTools_UpdDevError": "Errore durante l'aggiornamento del dispositivo", "BackDevices_DBTools_UpdDevError": "Errore durante l'aggiornamento del dispositivo",
"BackDevices_DBTools_Upgrade": "Database aggiornato correttamente", "BackDevices_DBTools_Upgrade": "Database aggiornato correttamente",
"BackDevices_DBTools_UpgradeError": "Aggiornamento del database non riuscito", "BackDevices_DBTools_UpgradeError": "Aggiornamento del database non riuscito",
@@ -138,8 +138,8 @@
"DevDetail_Shortcut_DownAlerts": "Avvisi disconnessione", "DevDetail_Shortcut_DownAlerts": "Avvisi disconnessione",
"DevDetail_Shortcut_Presence": "Presenza", "DevDetail_Shortcut_Presence": "Presenza",
"DevDetail_Shortcut_Sessions": "Sessioni", "DevDetail_Shortcut_Sessions": "Sessioni",
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Dettagli", "DevDetail_Tab_Details": "Dettagli",
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Eventi", "DevDetail_Tab_Events": "Eventi",
"DevDetail_Tab_EventsTableDate": "Data", "DevDetail_Tab_EventsTableDate": "Data",
"DevDetail_Tab_EventsTableEvent": "Tipo evento", "DevDetail_Tab_EventsTableEvent": "Tipo evento",
"DevDetail_Tab_EventsTableIP": "IP", "DevDetail_Tab_EventsTableIP": "IP",
@@ -154,10 +154,10 @@
"DevDetail_Tab_NmapTableState": "Stato", "DevDetail_Tab_NmapTableState": "Stato",
"DevDetail_Tab_NmapTableText": "Imposta una pianificazione nelle <a href=\"/settings.php#NMAP_ACTIVE\">Impostazioni</a>", "DevDetail_Tab_NmapTableText": "Imposta una pianificazione nelle <a href=\"/settings.php#NMAP_ACTIVE\">Impostazioni</a>",
"DevDetail_Tab_NmapTableTime": "Ora", "DevDetail_Tab_NmapTableTime": "Ora",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugin", "DevDetail_Tab_Plugins": "Plugin",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Presenza", "DevDetail_Tab_Presence": "Presenza",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sessioni", "DevDetail_Tab_Sessions": "Sessioni",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Strumenti", "DevDetail_Tab_Tools": "Strumenti",
"DevDetail_Tab_Tools_Internet_Info_Description": "Lo strumento informazioni Internet visualizza informazioni sulla connessione Internet, come indirizzo IP, città, paese, prefisso e fuso orario.", "DevDetail_Tab_Tools_Internet_Info_Description": "Lo strumento informazioni Internet visualizza informazioni sulla connessione Internet, come indirizzo IP, città, paese, prefisso e fuso orario.",
"DevDetail_Tab_Tools_Internet_Info_Error": "Si è verificato un errore", "DevDetail_Tab_Tools_Internet_Info_Error": "Si è verificato un errore",
"DevDetail_Tab_Tools_Internet_Info_Start": "Avvia info Internet", "DevDetail_Tab_Tools_Internet_Info_Start": "Avvia info Internet",
@@ -328,6 +328,7 @@
"Gen_Upd_Fail": "Aggiornamento fallito", "Gen_Upd_Fail": "Aggiornamento fallito",
"Gen_Update": "Aggiorna", "Gen_Update": "Aggiorna",
"Gen_Update_Value": "Aggiorna valore", "Gen_Update_Value": "Aggiorna valore",
"Gen_ValidIcon": "",
"Gen_Warning": "Avviso", "Gen_Warning": "Avviso",
"Gen_Work_In_Progress": "Lavori in corso, è quindi un buon momento per un feedback su https://github.com/jokob-sk/NetAlertX/issues", "Gen_Work_In_Progress": "Lavori in corso, è quindi un buon momento per un feedback su https://github.com/jokob-sk/NetAlertX/issues",
"Gen_create_new_device": "Nuovo dispositivo", "Gen_create_new_device": "Nuovo dispositivo",

View File

@@ -138,8 +138,8 @@
"DevDetail_Shortcut_DownAlerts": "Nede Varslinger", "DevDetail_Shortcut_DownAlerts": "Nede Varslinger",
"DevDetail_Shortcut_Presence": "Tilstedeværelse", "DevDetail_Shortcut_Presence": "Tilstedeværelse",
"DevDetail_Shortcut_Sessions": "Sesjoner", "DevDetail_Shortcut_Sessions": "Sesjoner",
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Detaljer", "DevDetail_Tab_Details": "Detaljer",
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Hendelser", "DevDetail_Tab_Events": "Hendelser",
"DevDetail_Tab_EventsTableDate": "Dato", "DevDetail_Tab_EventsTableDate": "Dato",
"DevDetail_Tab_EventsTableEvent": "Hendelstype", "DevDetail_Tab_EventsTableEvent": "Hendelstype",
"DevDetail_Tab_EventsTableIP": "IP", "DevDetail_Tab_EventsTableIP": "IP",
@@ -154,10 +154,10 @@
"DevDetail_Tab_NmapTableState": "Tilstand", "DevDetail_Tab_NmapTableState": "Tilstand",
"DevDetail_Tab_NmapTableText": "Konfigurer en tidsplan i <a href=\"/settings.php#NMAP_ACTIVE\">Innstillinger</a>", "DevDetail_Tab_NmapTableText": "Konfigurer en tidsplan i <a href=\"/settings.php#NMAP_ACTIVE\">Innstillinger</a>",
"DevDetail_Tab_NmapTableTime": "Tidspunkt", "DevDetail_Tab_NmapTableTime": "Tidspunkt",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins", "DevDetail_Tab_Plugins": "Plugins",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Tilstedeværelse", "DevDetail_Tab_Presence": "Tilstedeværelse",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Økter", "DevDetail_Tab_Sessions": "Økter",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Verktøy", "DevDetail_Tab_Tools": "Verktøy",
"DevDetail_Tab_Tools_Internet_Info_Description": "Internett-informasjonsverktøyet viser informasjon om Internett-tilkoblingen, for eksempel IP-adresse, by, land, retningsnummer og tidssone.", "DevDetail_Tab_Tools_Internet_Info_Description": "Internett-informasjonsverktøyet viser informasjon om Internett-tilkoblingen, for eksempel IP-adresse, by, land, retningsnummer og tidssone.",
"DevDetail_Tab_Tools_Internet_Info_Error": "En feil har oppstått", "DevDetail_Tab_Tools_Internet_Info_Error": "En feil har oppstått",
"DevDetail_Tab_Tools_Internet_Info_Start": "Start Internett-informasjonsverktøyet", "DevDetail_Tab_Tools_Internet_Info_Start": "Start Internett-informasjonsverktøyet",
@@ -328,6 +328,7 @@
"Gen_Upd_Fail": "Oppdatering feilet", "Gen_Upd_Fail": "Oppdatering feilet",
"Gen_Update": "Oppdater", "Gen_Update": "Oppdater",
"Gen_Update_Value": "Oppdater verdi", "Gen_Update_Value": "Oppdater verdi",
"Gen_ValidIcon": "",
"Gen_Warning": "Advarsel", "Gen_Warning": "Advarsel",
"Gen_Work_In_Progress": "Work in progress, gjerne kom med tilbakemeldinger på https://github.com/jokob-sk/NetAlertX/issues", "Gen_Work_In_Progress": "Work in progress, gjerne kom med tilbakemeldinger på https://github.com/jokob-sk/NetAlertX/issues",
"Gen_create_new_device": "", "Gen_create_new_device": "",

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

@@ -155,9 +155,9 @@
"DevDetail_Tab_NmapTableText": "Ustaw harmonogram w <a href=\"/settings.php#NMAP_ACTIVE\">Ustawieniach</a>", "DevDetail_Tab_NmapTableText": "Ustaw harmonogram w <a href=\"/settings.php#NMAP_ACTIVE\">Ustawieniach</a>",
"DevDetail_Tab_NmapTableTime": "Czas", "DevDetail_Tab_NmapTableTime": "Czas",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i>Pluginy", "DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i>Pluginy",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Obecność", "DevDetail_Tab_Presence": "Obecność",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sesje", "DevDetail_Tab_Sessions": "Sesje",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Narzędzia", "DevDetail_Tab_Tools": "Narzędzia",
"DevDetail_Tab_Tools_Internet_Info_Description": "Narzędzie informacji o Internecie wyświetla informację o połączeniu z Internetem, takie jak adres IP, miasto, państwo, kod pocztowy i strefa czasowa.", "DevDetail_Tab_Tools_Internet_Info_Description": "Narzędzie informacji o Internecie wyświetla informację o połączeniu z Internetem, takie jak adres IP, miasto, państwo, kod pocztowy i strefa czasowa.",
"DevDetail_Tab_Tools_Internet_Info_Error": "Wystąpił błąd", "DevDetail_Tab_Tools_Internet_Info_Error": "Wystąpił błąd",
"DevDetail_Tab_Tools_Internet_Info_Start": "Rozpocznij Informacje o Internecie", "DevDetail_Tab_Tools_Internet_Info_Start": "Rozpocznij Informacje o Internecie",
@@ -328,6 +328,7 @@
"Gen_Upd_Fail": "Aktualizacja nie powiodła się", "Gen_Upd_Fail": "Aktualizacja nie powiodła się",
"Gen_Update": "Aktualizuj", "Gen_Update": "Aktualizuj",
"Gen_Update_Value": "Aktualizuj Wartość", "Gen_Update_Value": "Aktualizuj Wartość",
"Gen_ValidIcon": "",
"Gen_Warning": "Uwaga", "Gen_Warning": "Uwaga",
"Gen_Work_In_Progress": "Praca w toku, dobry czas na feedback https://github.com/jokob-sk/NetAlertX/issues", "Gen_Work_In_Progress": "Praca w toku, dobry czas na feedback https://github.com/jokob-sk/NetAlertX/issues",
"Gen_create_new_device": "", "Gen_create_new_device": "",

11
front/php/templates/language/pt_br.json Executable file → Normal file
View File

@@ -138,8 +138,8 @@
"DevDetail_Shortcut_DownAlerts": "Alertas para baixo", "DevDetail_Shortcut_DownAlerts": "Alertas para baixo",
"DevDetail_Shortcut_Presence": "Presença", "DevDetail_Shortcut_Presence": "Presença",
"DevDetail_Shortcut_Sessions": "Sessões", "DevDetail_Shortcut_Sessions": "Sessões",
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Detalhes", "DevDetail_Tab_Details": "Detalhes",
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Eventos", "DevDetail_Tab_Events": "Eventos",
"DevDetail_Tab_EventsTableDate": "Data", "DevDetail_Tab_EventsTableDate": "Data",
"DevDetail_Tab_EventsTableEvent": "Tipo de evento", "DevDetail_Tab_EventsTableEvent": "Tipo de evento",
"DevDetail_Tab_EventsTableIP": "IP", "DevDetail_Tab_EventsTableIP": "IP",
@@ -155,9 +155,9 @@
"DevDetail_Tab_NmapTableText": "Configure uma programação em <a href=\"/settings.php#NMAP_ACTIVE\">Configurações</a>", "DevDetail_Tab_NmapTableText": "Configure uma programação em <a href=\"/settings.php#NMAP_ACTIVE\">Configurações</a>",
"DevDetail_Tab_NmapTableTime": "Tempo", "DevDetail_Tab_NmapTableTime": "Tempo",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"> </i> Plugins", "DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"> </i> Plugins",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Presença", "DevDetail_Tab_Presence": "Presença",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sessões", "DevDetail_Tab_Sessions": "Sessões",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Ferramentas", "DevDetail_Tab_Tools": "Ferramentas",
"DevDetail_Tab_Tools_Internet_Info_Description": "A ferramenta info Internet exibe informações sobre a conexão com a Internet, como endereço IP, cidade, país, código de área e fuso horário.", "DevDetail_Tab_Tools_Internet_Info_Description": "A ferramenta info Internet exibe informações sobre a conexão com a Internet, como endereço IP, cidade, país, código de área e fuso horário.",
"DevDetail_Tab_Tools_Internet_Info_Error": "Um erro ocorreu", "DevDetail_Tab_Tools_Internet_Info_Error": "Um erro ocorreu",
"DevDetail_Tab_Tools_Internet_Info_Start": "Iniciar informações da Internet", "DevDetail_Tab_Tools_Internet_Info_Start": "Iniciar informações da Internet",
@@ -328,6 +328,7 @@
"Gen_Upd_Fail": "A atualização falhou", "Gen_Upd_Fail": "A atualização falhou",
"Gen_Update": "Atualizar", "Gen_Update": "Atualizar",
"Gen_Update_Value": "Atualizar valor", "Gen_Update_Value": "Atualizar valor",
"Gen_ValidIcon": "",
"Gen_Warning": "Aviso", "Gen_Warning": "Aviso",
"Gen_Work_In_Progress": "Trabalho em andamento, um bom momento para enviar feedback em https://github.com/jokob-sk/NetAlertX/issues", "Gen_Work_In_Progress": "Trabalho em andamento, um bom momento para enviar feedback em https://github.com/jokob-sk/NetAlertX/issues",
"Gen_create_new_device": "", "Gen_create_new_device": "",

17
front/php/templates/language/ru_ru.json Normal file → Executable file
View File

@@ -48,7 +48,7 @@
"BackDevices_DBTools_ImportCSVError": "Не удалось импортировать файл CSV. Убедитесь, что формат правильный.", "BackDevices_DBTools_ImportCSVError": "Не удалось импортировать файл CSV. Убедитесь, что формат правильный.",
"BackDevices_DBTools_ImportCSVMissing": "CSV-файл не найден в<b>/config/devices.csv.</b>", "BackDevices_DBTools_ImportCSVMissing": "CSV-файл не найден в<b>/config/devices.csv.</b>",
"BackDevices_DBTools_Purge": "Самые старые резервные копии были удалены", "BackDevices_DBTools_Purge": "Самые старые резервные копии были удалены",
"BackDevices_DBTools_UpdDev": "Устройство успешно обновлено", "BackDevices_DBTools_UpdDev": "Устройство успешно обновлено. При выполнении сканирования может потребоваться некоторое время для перезагрузки основного списка устройств.",
"BackDevices_DBTools_UpdDevError": "Ошибка обновления устройства", "BackDevices_DBTools_UpdDevError": "Ошибка обновления устройства",
"BackDevices_DBTools_Upgrade": "База данных успешно обновлена", "BackDevices_DBTools_Upgrade": "База данных успешно обновлена",
"BackDevices_DBTools_UpgradeError": "Обновление базы данных не удалось", "BackDevices_DBTools_UpgradeError": "Обновление базы данных не удалось",
@@ -138,8 +138,8 @@
"DevDetail_Shortcut_DownAlerts": "Оповещения о сбое", "DevDetail_Shortcut_DownAlerts": "Оповещения о сбое",
"DevDetail_Shortcut_Presence": "Присутствие", "DevDetail_Shortcut_Presence": "Присутствие",
"DevDetail_Shortcut_Sessions": "Сеансы", "DevDetail_Shortcut_Sessions": "Сеансы",
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Детали", "DevDetail_Tab_Details": "Детали",
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> События", "DevDetail_Tab_Events": "События",
"DevDetail_Tab_EventsTableDate": "Дата", "DevDetail_Tab_EventsTableDate": "Дата",
"DevDetail_Tab_EventsTableEvent": "Тип события", "DevDetail_Tab_EventsTableEvent": "Тип события",
"DevDetail_Tab_EventsTableIP": "IP", "DevDetail_Tab_EventsTableIP": "IP",
@@ -154,10 +154,10 @@
"DevDetail_Tab_NmapTableState": "Состояние", "DevDetail_Tab_NmapTableState": "Состояние",
"DevDetail_Tab_NmapTableText": "Настройте расписание в <a href=\"/settings.php#NMAP_ACTIVE\">Настройки</a>", "DevDetail_Tab_NmapTableText": "Настройте расписание в <a href=\"/settings.php#NMAP_ACTIVE\">Настройки</a>",
"DevDetail_Tab_NmapTableTime": "Время", "DevDetail_Tab_NmapTableTime": "Время",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Плагины", "DevDetail_Tab_Plugins": "Плагины",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Присутствие", "DevDetail_Tab_Presence": "Присутствие",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Сеансы", "DevDetail_Tab_Sessions": "Сеансы",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Инструменты", "DevDetail_Tab_Tools": "Инструменты",
"DevDetail_Tab_Tools_Internet_Info_Description": "Инструмент «Информация об Интернете» отображает информацию о подключении к Интернету, такую как IP-адрес, город, страна, код города и часовой пояс.", "DevDetail_Tab_Tools_Internet_Info_Description": "Инструмент «Информация об Интернете» отображает информацию о подключении к Интернету, такую как IP-адрес, город, страна, код города и часовой пояс.",
"DevDetail_Tab_Tools_Internet_Info_Error": "Произошла ошибка", "DevDetail_Tab_Tools_Internet_Info_Error": "Произошла ошибка",
"DevDetail_Tab_Tools_Internet_Info_Start": "Показать инфо об Интернете", "DevDetail_Tab_Tools_Internet_Info_Start": "Показать инфо об Интернете",
@@ -242,7 +242,7 @@
"Device_Tablelenght": "Показать _MENU_ записей", "Device_Tablelenght": "Показать _MENU_ записей",
"Device_Tablelenght_all": "Все", "Device_Tablelenght_all": "Все",
"Device_Title": "Устройства", "Device_Title": "Устройства",
"Devices_Filters": "", "Devices_Filters": "Фильтры",
"Donations_Others": "Другие", "Donations_Others": "Другие",
"Donations_Platforms": "Спонсорские платформы", "Donations_Platforms": "Спонсорские платформы",
"Donations_Text": "Привет 👋! </br> Спасибо, что нажали на этот пункт меню 😅 </br> </br> Я пытаюсь собрать пожертвования, чтобы сделать ваше программное обеспечение лучше. Кроме того, это поможет мне не перегореть, и я смогу дольше поддерживать это приложение. Любое небольшое спонсорство (периодическое или нет) вызывает у меня желание приложить больше усилий к этому приложению. </br> Мне бы хотелось сократить свою рабочую неделю и в оставшееся время полностью сосредоточиться на NetAlertX. Вы получите больше функциональности, более усовершенствованное приложение и меньше ошибок. </br> </br> Спасибо за прочтение буду благодарен за любую поддержку❤🙏 </br> </br> TL;DR: Поддержав меня, вы получаете: </br> </br> <ul><li>Регулярные обновления для обеспечения безопасности ваших данных и семьи 🔄</li><li>Меньше ошибок 🐛🔫</li><li>Лучшую функциональность➕</li><li>Я не выгораю 🔥🤯</li><li>Меньше поспешных релизов 💨</li><li>Лучшая документация📚</li><li>Быстрее и лучше поддержка по вопросам 🆘</li></ul> </br> 📧Напишите мне на <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> если вы хотите связаться или если следует добавить другие спонсорские платформы. </br>", "Donations_Text": "Привет 👋! </br> Спасибо, что нажали на этот пункт меню 😅 </br> </br> Я пытаюсь собрать пожертвования, чтобы сделать ваше программное обеспечение лучше. Кроме того, это поможет мне не перегореть, и я смогу дольше поддерживать это приложение. Любое небольшое спонсорство (периодическое или нет) вызывает у меня желание приложить больше усилий к этому приложению. </br> Мне бы хотелось сократить свою рабочую неделю и в оставшееся время полностью сосредоточиться на NetAlertX. Вы получите больше функциональности, более усовершенствованное приложение и меньше ошибок. </br> </br> Спасибо за прочтение буду благодарен за любую поддержку❤🙏 </br> </br> TL;DR: Поддержав меня, вы получаете: </br> </br> <ul><li>Регулярные обновления для обеспечения безопасности ваших данных и семьи 🔄</li><li>Меньше ошибок 🐛🔫</li><li>Лучшую функциональность➕</li><li>Я не выгораю 🔥🤯</li><li>Меньше поспешных релизов 💨</li><li>Лучшая документация📚</li><li>Быстрее и лучше поддержка по вопросам 🆘</li></ul> </br> 📧Напишите мне на <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> если вы хотите связаться или если следует добавить другие спонсорские платформы. </br>",
@@ -328,6 +328,7 @@
"Gen_Upd_Fail": "Не удалось обновить", "Gen_Upd_Fail": "Не удалось обновить",
"Gen_Update": "Обновление", "Gen_Update": "Обновление",
"Gen_Update_Value": "Обновить значение", "Gen_Update_Value": "Обновить значение",
"Gen_ValidIcon": "",
"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": "Новое устройство",

View File

@@ -138,7 +138,7 @@
"DevDetail_Shortcut_DownAlerts": "", "DevDetail_Shortcut_DownAlerts": "",
"DevDetail_Shortcut_Presence": "", "DevDetail_Shortcut_Presence": "",
"DevDetail_Shortcut_Sessions": "Oturumlar", "DevDetail_Shortcut_Sessions": "Oturumlar",
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Detaylar", "DevDetail_Tab_Details": "Detaylar",
"DevDetail_Tab_Events": "", "DevDetail_Tab_Events": "",
"DevDetail_Tab_EventsTableDate": "Tarih", "DevDetail_Tab_EventsTableDate": "Tarih",
"DevDetail_Tab_EventsTableEvent": "", "DevDetail_Tab_EventsTableEvent": "",
@@ -156,7 +156,7 @@
"DevDetail_Tab_NmapTableTime": "Zaman", "DevDetail_Tab_NmapTableTime": "Zaman",
"DevDetail_Tab_Plugins": "", "DevDetail_Tab_Plugins": "",
"DevDetail_Tab_Presence": "", "DevDetail_Tab_Presence": "",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Oturumlar", "DevDetail_Tab_Sessions": "Oturumlar",
"DevDetail_Tab_Tools": "", "DevDetail_Tab_Tools": "",
"DevDetail_Tab_Tools_Internet_Info_Description": "", "DevDetail_Tab_Tools_Internet_Info_Description": "",
"DevDetail_Tab_Tools_Internet_Info_Error": "Bir hata oluştu", "DevDetail_Tab_Tools_Internet_Info_Error": "Bir hata oluştu",
@@ -328,6 +328,7 @@
"Gen_Upd_Fail": "", "Gen_Upd_Fail": "",
"Gen_Update": "", "Gen_Update": "",
"Gen_Update_Value": "", "Gen_Update_Value": "",
"Gen_ValidIcon": "",
"Gen_Warning": "Uyarı", "Gen_Warning": "Uyarı",
"Gen_Work_In_Progress": "", "Gen_Work_In_Progress": "",
"Gen_create_new_device": "", "Gen_create_new_device": "",

15
front/php/templates/language/uk_ua.json Normal file → Executable file
View File

@@ -48,7 +48,7 @@
"BackDevices_DBTools_ImportCSVError": "Не вдалося імпортувати файл CSV. Переконайтеся, що формат правильний.", "BackDevices_DBTools_ImportCSVError": "Не вдалося імпортувати файл CSV. Переконайтеся, що формат правильний.",
"BackDevices_DBTools_ImportCSVMissing": "Не вдалося знайти файл CSV у <b>/config/devices.csv.</b>", "BackDevices_DBTools_ImportCSVMissing": "Не вдалося знайти файл CSV у <b>/config/devices.csv.</b>",
"BackDevices_DBTools_Purge": "Найстаріші резервні копії видалено", "BackDevices_DBTools_Purge": "Найстаріші резервні копії видалено",
"BackDevices_DBTools_UpdDev": "Пристрій успішно оновлено", "BackDevices_DBTools_UpdDev": "Пристрій успішно оновлено. Перезавантаження основного списку пристроїв може знадобитися деякий час, якщо триває сканування.",
"BackDevices_DBTools_UpdDevError": "Помилка оновлення пристрою", "BackDevices_DBTools_UpdDevError": "Помилка оновлення пристрою",
"BackDevices_DBTools_Upgrade": "Базу даних успішно оновлено", "BackDevices_DBTools_Upgrade": "Базу даних успішно оновлено",
"BackDevices_DBTools_UpgradeError": "Не вдалося оновити базу даних", "BackDevices_DBTools_UpgradeError": "Не вдалося оновити базу даних",
@@ -138,8 +138,8 @@
"DevDetail_Shortcut_DownAlerts": "Сповіщення про падіння", "DevDetail_Shortcut_DownAlerts": "Сповіщення про падіння",
"DevDetail_Shortcut_Presence": "Присутність", "DevDetail_Shortcut_Presence": "Присутність",
"DevDetail_Shortcut_Sessions": "Сеанси", "DevDetail_Shortcut_Sessions": "Сеанси",
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Подробиці", "DevDetail_Tab_Details": "Подробиці",
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Події", "DevDetail_Tab_Events": "Події",
"DevDetail_Tab_EventsTableDate": "Дата", "DevDetail_Tab_EventsTableDate": "Дата",
"DevDetail_Tab_EventsTableEvent": "Тип події", "DevDetail_Tab_EventsTableEvent": "Тип події",
"DevDetail_Tab_EventsTableIP": "IP", "DevDetail_Tab_EventsTableIP": "IP",
@@ -154,10 +154,10 @@
"DevDetail_Tab_NmapTableState": "Держава", "DevDetail_Tab_NmapTableState": "Держава",
"DevDetail_Tab_NmapTableText": "Налаштуйте розклад у <a href=\"/settings.php#NMAP_ACTIVE\">Settings</a>", "DevDetail_Tab_NmapTableText": "Налаштуйте розклад у <a href=\"/settings.php#NMAP_ACTIVE\">Settings</a>",
"DevDetail_Tab_NmapTableTime": "час", "DevDetail_Tab_NmapTableTime": "час",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Плагіни", "DevDetail_Tab_Plugins": "Плагіни",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Присутність", "DevDetail_Tab_Presence": "Присутність",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Сеанси", "DevDetail_Tab_Sessions": "Сеанси",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Інструменти", "DevDetail_Tab_Tools": "Інструменти",
"DevDetail_Tab_Tools_Internet_Info_Description": "Інструмент Інтернет-інформації відображає інформацію про підключення до Інтернету, таку як IP-адреса, місто, країна, код міста та часовий пояс.", "DevDetail_Tab_Tools_Internet_Info_Description": "Інструмент Інтернет-інформації відображає інформацію про підключення до Інтернету, таку як IP-адреса, місто, країна, код міста та часовий пояс.",
"DevDetail_Tab_Tools_Internet_Info_Error": "Сталася помилка", "DevDetail_Tab_Tools_Internet_Info_Error": "Сталася помилка",
"DevDetail_Tab_Tools_Internet_Info_Start": "Запустіть Internet Info", "DevDetail_Tab_Tools_Internet_Info_Start": "Запустіть Internet Info",
@@ -328,6 +328,7 @@
"Gen_Upd_Fail": "Не вдалося оновити", "Gen_Upd_Fail": "Не вдалося оновити",
"Gen_Update": "оновлення", "Gen_Update": "оновлення",
"Gen_Update_Value": "Оновити значення", "Gen_Update_Value": "Оновити значення",
"Gen_ValidIcon": "",
"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": "новий пристрій",

View File

@@ -138,8 +138,8 @@
"DevDetail_Shortcut_DownAlerts": "下线警报", "DevDetail_Shortcut_DownAlerts": "下线警报",
"DevDetail_Shortcut_Presence": "存在", "DevDetail_Shortcut_Presence": "存在",
"DevDetail_Shortcut_Sessions": "会话", "DevDetail_Shortcut_Sessions": "会话",
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> 详细信息", "DevDetail_Tab_Details": "详细信息",
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> 事件", "DevDetail_Tab_Events": "事件",
"DevDetail_Tab_EventsTableDate": "日期", "DevDetail_Tab_EventsTableDate": "日期",
"DevDetail_Tab_EventsTableEvent": "事件类型", "DevDetail_Tab_EventsTableEvent": "事件类型",
"DevDetail_Tab_EventsTableIP": "IP", "DevDetail_Tab_EventsTableIP": "IP",
@@ -154,10 +154,10 @@
"DevDetail_Tab_NmapTableState": "状态", "DevDetail_Tab_NmapTableState": "状态",
"DevDetail_Tab_NmapTableText": "<a href=\"/settings.php#NMAP_ACTIVE\">设置</a>时间表", "DevDetail_Tab_NmapTableText": "<a href=\"/settings.php#NMAP_ACTIVE\">设置</a>时间表",
"DevDetail_Tab_NmapTableTime": "时间", "DevDetail_Tab_NmapTableTime": "时间",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> 插件", "DevDetail_Tab_Plugins": "插件",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> 存在", "DevDetail_Tab_Presence": "存在",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> 会话", "DevDetail_Tab_Sessions": "会话",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> 工具", "DevDetail_Tab_Tools": "工具",
"DevDetail_Tab_Tools_Internet_Info_Description": "互联网信息工具显示有关互联网连接的信息,例如 IP 地址、城市、国家、区号和时区。", "DevDetail_Tab_Tools_Internet_Info_Description": "互联网信息工具显示有关互联网连接的信息,例如 IP 地址、城市、国家、区号和时区。",
"DevDetail_Tab_Tools_Internet_Info_Error": "发生了错误", "DevDetail_Tab_Tools_Internet_Info_Error": "发生了错误",
"DevDetail_Tab_Tools_Internet_Info_Start": "开始互联网信息", "DevDetail_Tab_Tools_Internet_Info_Start": "开始互联网信息",
@@ -328,6 +328,7 @@
"Gen_Upd_Fail": "更新失败", "Gen_Upd_Fail": "更新失败",
"Gen_Update": "更新", "Gen_Update": "更新",
"Gen_Update_Value": "更新值", "Gen_Update_Value": "更新值",
"Gen_ValidIcon": "",
"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": "",

View File

@@ -8,6 +8,7 @@ $configFolderPath = dirname(__FILE__)."/../../../config/";
$config_file = "app.conf"; $config_file = "app.conf";
$logFolderPath = "/app/log/"; $logFolderPath = "/app/log/";
$log_file = "app_front.log"; $log_file = "app_front.log";
$default_tz = "Europe/Berlin";
$fullConfPath = $configFolderPath.$config_file; $fullConfPath = $configFolderPath.$config_file;
@@ -29,7 +30,13 @@ foreach ($config_file_lines as $line)
if($timeZone == "") if($timeZone == "")
{ {
$timeZone = "Europe/Berlin"; $timeZone = $default_tz;
}
// Validate the timezone
if (!in_array($timeZone, timezone_identifiers_list())) {
error_log("Invalid timezone '$timeZone' in config. Falling back to default: '$default_tz' ");
$timeZone = $default_tz;
} }
date_default_timezone_set($timeZone); date_default_timezone_set($timeZone);

View File

@@ -60,7 +60,6 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
| `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/) |
| `UI` | ♻ | UI specific settings | | Yes | Template | [ui_settings](/front/plugins/ui_settings/) | | `UI` | ♻ | UI specific settings | | Yes | Template | [ui_settings](/front/plugins/ui_settings/) |
| `UNDIS` | 🔍/📥 | Create dummy devices ❌ | | | Script | [undiscoverables](/front/plugins/undiscoverables/) |
| `UNFIMP` | 🔍/📥/🆎| UniFi device import & sync | 🖧 | | Script | [unifi_import](/front/plugins/unifi_import/) | | `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/) |
@@ -69,7 +68,6 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
> \* 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.
> ❌ marked for removal > ❌ 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.

View File

@@ -75,7 +75,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/5 * * * *", "default_value": "*/5 * * * *",

View File

@@ -361,7 +361,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "0 2 * * 3", "default_value": "0 2 * * 3",

View File

@@ -208,7 +208,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/5 * * * *", "default_value": "*/5 * * * *",

View File

@@ -8,6 +8,7 @@ This Plugin is using awesome [asusrouter](https://github.com/Vaskivskyi/asusrout
- Enable the `ASUSWRT` plugin - Enable the `ASUSWRT` plugin
- Head to **Settings** > **AsusWRT device import** to adjust the default values. - Head to **Settings** > **AsusWRT device import** to adjust the default values.
- If you have troubles configuring the plugin set the `LOG_LEVEL='debug'` to get a more detailed error message.
### Notes ### Notes

View File

@@ -84,9 +84,28 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{ {
"elementType": "input", "elementType": "input",
"elementOptions": [], "elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": [] "transformers": []
} }
] ]

View File

@@ -132,7 +132,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/30 * * * *", "default_value": "*/30 * * * *",

View File

@@ -5,8 +5,11 @@
"enabled": true, "enabled": true,
"data_source": "script", "data_source": "script",
"show_ui": false, "show_ui": false,
"localized": ["display_name", "description", "icon"], "localized": [
"display_name",
"description",
"icon"
],
"display_name": [ "display_name": [
{ {
"language_code": "en_us", "language_code": "en_us",
@@ -53,15 +56,20 @@
"value": "CSVBCKP_location" "value": "CSVBCKP_location"
} }
], ],
"settings": [ "settings": [
{ {
"function": "RUN", "function": "RUN",
"events": ["run"], "events": [
"run"
],
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] } {
"elementType": "select",
"elementOptions": [],
"transformers": []
}
] ]
}, },
"default_value": "schedule", "default_value": "schedule",
@@ -72,7 +80,10 @@
"always_after_scan", "always_after_scan",
"on_new_device" "on_new_device"
], ],
"localized": ["name", "description"], "localized": [
"name",
"description"
],
"name": [ "name": [
{ {
"language_code": "en_us", "language_code": "en_us",
@@ -109,14 +120,21 @@
"elements": [ "elements": [
{ {
"elementType": "input", "elementType": "input",
"elementOptions": [{ "readonly": "true" }], "elementOptions": [
{
"readonly": "true"
}
],
"transformers": [] "transformers": []
} }
] ]
}, },
"default_value": "python3 /app/front/plugins/csv_backup/script.py overwrite={overwrite} location={location}", "default_value": "python3 /app/front/plugins/csv_backup/script.py overwrite={overwrite} location={location}",
"options": [], "options": [],
"localized": ["name", "description"], "localized": [
"name",
"description"
],
"name": [ "name": [
{ {
"language_code": "en_us", "language_code": "en_us",
@@ -151,12 +169,38 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "0 2 * * 3", "default_value": "0 2 * * 3",
"options": [], "options": [],
"localized": ["name", "description"], "localized": [
"name",
"description"
],
"name": [ "name": [
{ {
"language_code": "en_us", "language_code": "en_us",
@@ -193,14 +237,21 @@
"elements": [ "elements": [
{ {
"elementType": "input", "elementType": "input",
"elementOptions": [{ "type": "number" }], "elementOptions": [
{
"type": "number"
}
],
"transformers": [] "transformers": []
} }
] ]
}, },
"default_value": 30, "default_value": 30,
"options": [], "options": [],
"localized": ["name", "description"], "localized": [
"name",
"description"
],
"name": [ "name": [
{ {
"language_code": "en_us", "language_code": "en_us",
@@ -237,14 +288,21 @@
"elements": [ "elements": [
{ {
"elementType": "input", "elementType": "input",
"elementOptions": [{ "type": "checkbox" }], "elementOptions": [
{
"type": "checkbox"
}
],
"transformers": [] "transformers": []
} }
] ]
}, },
"default_value": false, "default_value": false,
"options": [], "options": [],
"localized": ["name", "description"], "localized": [
"name",
"description"
],
"name": [ "name": [
{ {
"language_code": "en_us", "language_code": "en_us",
@@ -279,12 +337,19 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "input",
"elementOptions": [],
"transformers": []
}
] ]
}, },
"default_value": "/app/config", "default_value": "/app/config",
"options": [], "options": [],
"localized": ["name", "description"], "localized": [
"name",
"description"
],
"name": [ "name": [
{ {
"language_code": "en_us", "language_code": "en_us",
@@ -315,6 +380,5 @@
] ]
} }
], ],
"database_column_definitions": [] "database_column_definitions": []
} }

View File

@@ -109,7 +109,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/30 * * * *", "default_value": "*/30 * * * *",

View File

@@ -159,7 +159,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/5 * * * *", "default_value": "*/5 * * * *",

View File

@@ -580,7 +580,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "0 2 * * *", "default_value": "0 2 * * *",

View File

@@ -381,7 +381,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "0 2 * * *", "default_value": "0 2 * * *",

View File

@@ -87,9 +87,28 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{ {
"elementType": "input", "elementType": "input",
"elementOptions": [], "elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": [] "transformers": []
} }
] ]

View File

@@ -164,7 +164,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/5 * * * *", "default_value": "*/5 * * * *",

View File

@@ -187,7 +187,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/5 * * * *", "default_value": "*/5 * * * *",

View File

@@ -452,7 +452,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/30 * * * *", "default_value": "*/30 * * * *",

View File

@@ -87,9 +87,28 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{ {
"elementType": "input", "elementType": "input",
"elementOptions": [], "elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": [] "transformers": []
} }
] ]

View File

@@ -114,7 +114,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "0 2 * * *", "default_value": "0 2 * * *",

View File

@@ -114,7 +114,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/30 * * * *", "default_value": "*/30 * * * *",

View File

@@ -132,7 +132,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/30 * * * *", "default_value": "*/30 * * * *",

View File

@@ -184,7 +184,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/5 * * * *", "default_value": "*/5 * * * *",

View File

@@ -460,7 +460,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "0 2 * * *", "default_value": "0 2 * * *",

View File

@@ -132,7 +132,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/30 * * * *", "default_value": "*/30 * * * *",

View File

@@ -76,7 +76,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },

View File

@@ -166,7 +166,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/30 * * * *", "default_value": "*/30 * * * *",

View File

@@ -1,5 +1,6 @@
from time import strftime from time import strftime
import pytz import pytz
from pytz import timezone, all_timezones, UnknownTimeZoneError
import sys import sys
import re import re
import base64 import base64
@@ -11,7 +12,7 @@ sys.path.append(f"{INSTALL_PATH}/front/plugins")
sys.path.append(f'{INSTALL_PATH}/server') sys.path.append(f'{INSTALL_PATH}/server')
from logger import mylog, Logger from logger import mylog, Logger
from const import confFileName from const import confFileName, default_tz
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
def read_config_file(): def read_config_file():
@@ -35,6 +36,8 @@ def read_config_file():
configFile = read_config_file() configFile = read_config_file()
timeZoneSetting = configFile['TIMEZONE'] timeZoneSetting = configFile['TIMEZONE']
if timeZoneSetting not in all_timezones:
timeZoneSetting = default_tz
timeZone = pytz.timezone(timeZoneSetting) timeZone = pytz.timezone(timeZoneSetting)
# ------------------------------------------------------------------- # -------------------------------------------------------------------

View File

@@ -495,7 +495,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "0 2 * * *", "default_value": "0 2 * * *",

View File

@@ -82,7 +82,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },

View File

@@ -465,7 +465,7 @@
"description": [ "description": [
{ {
"language_code": "en_us", "language_code": "en_us",
"string": "Which column filters should be displayed in the main Devices screen." "string": "Which column filters should be displayed in the main Devices screen. Remove all to hide the Filters section."
} }
] ]
}, },

View File

@@ -1,30 +0,0 @@
## Overview
A plugin allowing for importing Un-Discoverable devices from the settings page.
The main usecase is to add dumb network gear like unmanaged hubs and switches to the network view.
There might be other usecases, please let me know.
### Usage
- Go to settings and find Un-Discoverabe Devices in the list of plugins.
- Enable the plugin by changing the RUN parameter from disabled to `once` or `always_after_scan`.
- Add the name of your device to the list. (remove the sample entry first)
- SAVE
- wait for the next scan to finish
#### Examples:
Settings:
![settings](https://github.com/Data-Monkey/Pi.Alert/assets/7224371/52883307-19a5-4602-b13a-9825461f6cc4)
resulting in these devices:
![devices](https://github.com/Data-Monkey/Pi.Alert/assets/7224371/9f7659e7-75a8-4ae9-9f5f-781bdbcbc949)
Allowing Un-Discoverable devices like hubs, switches or APs to be added to the network view.
![network](https://github.com/Data-Monkey/Pi.Alert/assets/7224371/b5ccc3b3-f5fd-4f5b-b0f0-e4e637c6da33)
### Known Limitations
- Un-Discoverable Devices always show as offline. That is expected as they can not be discovered by NetAlertX.
- All IPs are set to 0.0.0.0 therefore the "Random MAC" icon might show up.
Made with ❤ by [@Data-Monkey](https://github.com/Data-Monkey) 🙏

View File

@@ -1,573 +0,0 @@
{
"code_name": "undiscoverables",
"unique_prefix": "UNDIS",
"plugin_type": "device_scanner",
"enabled": true,
"data_source": "script",
"mapped_to_table": "CurrentScan",
"show_ui": true,
"localized": ["display_name", "description", "icon"],
"display_name": [
{
"language_code": "en_us",
"string": "Un-Discoverable Devices"
},
{
"language_code": "es_es",
"string": "Dispositivos no detectables"
},
{
"language_code": "de_de",
"string": "Nicht erkennbare Geräte"
}
],
"icon": [
{
"language_code": "en_us",
"string": "<i class=\"fa-solid fa-binoculars\"></i>"
}
],
"description": [
{
"language_code": "en_us",
"string": "This plugin is to import undiscoverable devices from a file. Only ASCII characters are supported."
}
],
"params": [
{
"name": "devices",
"type": "setting",
"value": "UNDIS_devices_to_import"
}
],
"settings": [
{
"function": "RUN",
"events": ["run"],
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": ["disabled", "once", "schedule", "always_after_scan"],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "When to run"
},
{
"language_code": "es_es",
"string": "Cuándo ejecuta"
},
{
"language_code": "de_de",
"string": "Wann ausführen"
}
],
"description": [
{
"language_code": "en_us",
"string": "When enabled, <code>once</code> is the preferred option, or set to <code>schedule</code> and align the <code>UNDIS_RUN_SCHD</code> setting with the other scanners if you want the devices to show up as ONLINE. It runs at startup and after every save of the config here.<br> Changes will only show in the devices <b> after the next scan!</b>"
},
{
"language_code": "es_es",
"string": "Cuando está habilitado, <code>once</code> es la opción preferida. Se ejecuta al inicio y después de cada guardado de la configuración aquí.<br> ¡Los cambios solo se mostrarán en los dispositivos <b> después del próximo escaneo!</b>"
},
{
"language_code": "de_de",
"string": "Wenn dieses Plugin aktiviert ist, ist <code>once</code> die bevorzugte Methode. Das Plugin wird dann bei jedem Start und nach jedem Speichern der Einstellungen ausgeführt.</br>Änderungen scheinen in den Geräten erst <b>nach dem nächsten Scan</b> auf!"
}
]
},
{
"function": "CMD",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "python3 /app/front/plugins/undiscoverables/script.py devices={devices}",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Command"
},
{
"language_code": "es_es",
"string": "Comando"
},
{
"language_code": "de_de",
"string": "Befehl"
}
],
"description": [
{
"language_code": "en_us",
"string": "Command to run. This can not be changed"
},
{
"language_code": "es_es",
"string": "Comando a ejecutar. Esto no se puede cambiar"
},
{
"language_code": "de_de",
"string": "Befehl zum Ausführen. Dies kann nicht geändert werden"
}
]
},
{
"function": "RUN_TIMEOUT",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 10,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Run timeout"
},
{
"language_code": "es_es",
"string": "Tiempo límite de ejecución"
},
{
"language_code": "de_de",
"string": "Zeitlimit"
}
],
"description": [
{
"language_code": "en_us",
"string": "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted."
},
{
"language_code": "es_es",
"string": "Tiempo máximo en segundos para esperar a que finalice el script. Si se supera este tiempo, el script se cancela."
},
{
"language_code": "de_de",
"string": "Maximale Zeit in Sekunden, die auf den Abschluss des Skripts gewartet werden soll. Bei Überschreitung dieser Zeit wird das Skript abgebrochen."
}
]
},
{
"function": "WATCH",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": [],
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Watched"
},
{
"language_code": "es_es",
"string": "Visto"
},
{
"language_code": "de_de",
"string": "Überwacht"
}
],
"description": [
{
"language_code": "en_us",
"string": "Undiscoverable Devices can not change their status, no watch is enabled."
},
{
"language_code": "es_es",
"string": "Los dispositivos no detectables no pueden cambiar su estado, ningún reloj está habilitado."
},
{
"language_code": "de_de",
"string": "Status von nicht erkennbaren Geräten können sich nicht ändern, keine Überwachung aktiviert."
}
]
},
{
"function": "REPORT_ON",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": [],
"options": [
"new",
"watched-changed",
"watched-not-changed",
"missing-in-last-scan"
],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Report on"
},
{
"language_code": "es_es",
"string": "Informar sobre"
},
{
"language_code": "de_de",
"string": "Benachrichtige wenn"
}
],
"description": [
{
"language_code": "en_us",
"string": "No notifications will be sent."
},
{
"language_code": "es_es",
"string": "No se enviarán notificaciones."
},
{
"language_code": "de_de",
"string": "Keine Benachrichtigungen werden versendet."
}
]
},
{
"function": "devices_to_import",
"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": []
}
]
},
"default_value": ["dummy_router"],
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "UnDiscoverable Devices"
},
{
"language_code": "es_es",
"string": "Dispositivo no detectable"
},
{
"language_code": "de_de",
"string": "Nicht erkennbare Geräte"
}
],
"description": [
{
"language_code": "en_us",
"string": "Devices to be added to the devices list."
},
{
"language_code": "es_es",
"string": "Dispositivos que se añadirán a la lista de dispositivos."
},
{
"language_code": "de_de",
"string": "Geräte, welche der Geräteliste hinzugefügt werden."
}
]
},
{
"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": "es_es",
"string": "Schedule"
}
],
"description": [
{
"language_code": "en_us",
"string": "Only enabled if you select <code>schedule</code> in the <a href=\"#UNDIS_RUN\"><code>UNDIS_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. <br/> It's recommended to use the same schedule interval for all plugins responsible for discovering new devices. "
},
{
"language_code": "es_es",
"string": "Solo está habilitado si selecciona <code>schedule</code> en la configuración <a href=\"#UNDIS_RUN\"><code>UNDIS_RUN</code></a>. Asegúrese de ingresar la programación en el formato similar a cron correcto (por ejemplo, valide en <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Por ejemplo, ingresar <code>0 4 * * *</code> ejecutará el escaneo después de las 4 a.m. en el <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</ código> que configuró arriba</a>. Se ejecutará la PRÓXIMA vez que pase el tiempo."
}
]
}
],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": true,
"type": "none",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Index"
}
]
},
{
"column": "Watched_Value1",
"mapped_to_column": "cur_Name",
"css_classes": "col-sm-2",
"show": true,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Device Name"
},
{
"language_code": "es_es",
"string": "Nombre del dispositivo"
},
{
"language_code": "de_de",
"string": "Gerätename"
}
]
},
{
"column": "Object_PrimaryID",
"mapped_to_column": "cur_MAC",
"css_classes": "col-sm-2",
"show": true,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "MAC address"
},
{
"language_code": "es_es",
"string": "Dirección MAC"
},
{
"language_code": "de_de",
"string": "MAC-Adresse"
}
]
},
{
"column": "Object_SecondaryID",
"mapped_to_column": "cur_IP",
"css_classes": "col-sm-2",
"show": true,
"type": "device_ip",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "IP"
},
{
"language_code": "es_es",
"string": "IP"
},
{
"language_code": "de_de",
"string": "IP"
}
]
},
{
"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": "es_es",
"string": "Creado"
},
{
"language_code": "de_de",
"string": "Erstellt"
}
]
},
{
"column": "DateTimeChanged",
"mapped_to_column": "cur_DateTime",
"css_classes": "col-sm-2",
"show": true,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Changed"
},
{
"language_code": "es_es",
"string": "Cambiado"
},
{
"language_code": "de_de",
"string": "Geändert"
}
]
},
{
"column": "Dummy",
"mapped_to_column": "cur_ScanMethod",
"mapped_to_column_data": {
"value": "UNDIS"
},
"css_classes": "col-sm-2",
"show": true,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Scan method"
},
{
"language_code": "es_es",
"string": "Método de escaneo"
},
{
"language_code": "de_de",
"string": "Scanmethode"
}
]
},
{
"column": "ForeignKey",
"css_classes": "col-sm-2",
"show": false,
"type": "device_mac",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "MAC"
},
{
"language_code": "es_es",
"string": "MAC"
},
{
"language_code": "de_de",
"string": "MAC"
}
]
}
]
}

View File

@@ -1,76 +0,0 @@
#!/usr/bin/env python
# test script by running python script.py devices=test,dummy
import os
import pathlib
import argparse
import sys
import hashlib
# Register NetAlertX directories
INSTALL_PATH="/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from 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
# Make sure the TIMEZONE for logging is correct
conf.tz = timezone(get_setting_value('TIMEZONE'))
# Make sure log level is initialized correctly
Logger(get_setting_value('LOG_LEVEL'))
pluginName = 'UNDIS'
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')
def main():
# the script expects a parameter in the format of devices=device1,device2,...
parser = argparse.ArgumentParser(description='Import devices from settings')
parser.add_argument('devices', action="store", help="list of device names separated by ','")
values = parser.parse_args()
mylog('verbose', [f'[{pluginName}] In script'])
plugin_objects = Plugin_Objects( RESULT_FILE )
if values.devices:
for fake_dev in values.devices.split('=')[1].split(','):
fake_mac = string_to_mac_hash(fake_dev)
plugin_objects.add_object(
primaryId=fake_mac, # MAC (Device Name)
secondaryId="0.0.0.0", # IP Address (always 0.0.0.0)
watched1=fake_dev, # Device Name
watched2="",
watched3="",
watched4="",
extra="",
foreignKey=fake_mac)
plugin_objects.write_result_file()
return 0
def string_to_mac_hash(input_string):
# Calculate a hash using SHA-256
sha256_hash = hashlib.sha256(input_string.encode()).hexdigest()
# Take the first 12 characters of the hash and format as a MAC address
mac_hash = ':'.join(sha256_hash[i:i+2] for i in range(0, 12, 2))
return mac_hash
#===============================================================================
# BEGIN
#===============================================================================
if __name__ == '__main__':
main()

View File

@@ -124,7 +124,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "0 4 * * 3", "default_value": "0 4 * * 3",

View File

@@ -74,7 +74,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "*/5 * * * *", "default_value": "*/5 * * * *",

View File

@@ -408,7 +408,30 @@
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] } {
"elementType": "span",
"elementOptions": [
{
"cssClasses": "input-group-addon validityCheck"
},
{
"getStringKey": "Gen_ValidIcon"
}
],
"transformers": []
},
{
"elementType": "input",
"elementOptions": [
{
"onChange": "validateRegex(this)"
},
{
"base64Regex": "Xig/OlwqfCg/OlswLTldfFsxLTVdWzAtOV18WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlswLTldfDFbMC05XXwyWzAtM118WzAtOV0rLVswLTldK3xcKi9bMC05XSspKVxzKyg/OlwqfCg/OlsxLTldfFsxMl1bMC05XXwzWzAxXXxbMC05XSstWzAtOV0rfFwqL1swLTldKykpXHMrKD86XCp8KD86WzEtOV18MVswLTJdfFswLTldKy1bMC05XSt8XCovWzAtOV0rKSlccysoPzpcKnwoPzpbMC02XXxbMC02XS1bMC02XXxcKi9bMC05XSspKSQ="
}
],
"transformers": []
}
] ]
}, },
"default_value": "0 2 * * *", "default_value": "0 2 * * *",

View File

@@ -14,7 +14,7 @@
<table align=center width=100% cellpadding=0 cellspacing=0 style="border-radius: 5px;"> <table align=center width=100% cellpadding=0 cellspacing=0 style="border-radius: 5px;">
<tr> <tr>
<td bgcolor=#3c8dbc align=center style="padding: 20px 10px 10px 10px; font-size: 20px; color:#ffffff; border-top-right-radius: 5px; border-top-left-radius: 5px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)"> <td bgcolor=#3c8dbc align=center style="padding: 20px 10px 10px 10px; font-size: 20px; color:#ffffff; border-top-right-radius: 5px; border-top-left-radius: 5px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
<img src="https://netalertx.com/NetAlertX_logo.png" alt="NetAlertX Logo" style="vertical-align: middle;" width="32" height="32" /> <img src="https://netalertx.com/NetAlertX_logo.png" alt="NetAlertX Logo" style="vertical-align: middle; margin-top:-6px" width="32" height="32" />
Net<b>Alert</b><sup>x</sup> Net<b>Alert</b><sup>x</sup>
</td> </td>
</tr> </tr>

View File

@@ -595,7 +595,8 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
onChange, onChange,
customParams, customParams,
customId, customId,
columns columns,
base64Regex
} = handleElementOptions('none', elementOptions, transformers, val = ""); } = handleElementOptions('none', elementOptions, transformers, val = "");
let value; let value;

View File

@@ -20,7 +20,7 @@ fullDbPath = applicationPath + dbPath
vendorsPath = '/usr/share/arp-scan/ieee-oui.txt' vendorsPath = '/usr/share/arp-scan/ieee-oui.txt'
vendorsPathNewest = '/usr/share/arp-scan/ieee-oui_all_filtered.txt' vendorsPathNewest = '/usr/share/arp-scan/ieee-oui_all_filtered.txt'
default_tz = 'Europe/Berlin'
#=============================================================================== #===============================================================================

View File

@@ -1,7 +1,7 @@
import os import os
import time import time
from pytz import timezone from pytz import timezone, all_timezones, UnknownTimeZoneError
from cron_converter import Cron from cron_converter import Cron
from pathlib import Path from pathlib import Path
import datetime import datetime
@@ -11,7 +11,7 @@ import re
# Register NetAlertX libraries # Register NetAlertX libraries
import conf import conf
from const import fullConfPath, applicationPath, fullConfFolder from const import fullConfPath, applicationPath, fullConfFolder, default_tz
from helper import fixPermissions, collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, setting_value_to_python_type, timeNowTZ, get_setting_value, generate_random_string from helper import fixPermissions, collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, setting_value_to_python_type, timeNowTZ, get_setting_value, generate_random_string
from app_state import updateState from app_state import updateState
from logger import mylog from logger import mylog
@@ -161,7 +161,7 @@ def importConfigs (db, all_plugins):
conf.DISCOVER_PLUGINS = ccd('DISCOVER_PLUGINS', True , c_d, 'Discover plugins', """{"dataType": "boolean","elements": [{"elementType": "input","elementOptions": [{ "type": "checkbox" }],"transformers": []}]}""", '[]', 'General') conf.DISCOVER_PLUGINS = ccd('DISCOVER_PLUGINS', True , c_d, 'Discover plugins', """{"dataType": "boolean","elements": [{"elementType": "input","elementOptions": [{ "type": "checkbox" }],"transformers": []}]}""", '[]', 'General')
conf.SCAN_SUBNETS = ccd('SCAN_SUBNETS', ['192.168.1.0/24 --interface=eth1', '192.168.1.0/24 --interface=eth0'] , c_d, 'Subnets to scan', '''{"dataType": "array","elements": [{"elementType": "input","elementOptions": [{"placeholder": "192.168.1.0/24 --interface=eth1"},{"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": []}]}''', '[]', 'General') conf.SCAN_SUBNETS = ccd('SCAN_SUBNETS', ['192.168.1.0/24 --interface=eth1', '192.168.1.0/24 --interface=eth0'] , c_d, 'Subnets to scan', '''{"dataType": "array","elements": [{"elementType": "input","elementOptions": [{"placeholder": "192.168.1.0/24 --interface=eth1"},{"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": []}]}''', '[]', 'General')
conf.LOG_LEVEL = ccd('LOG_LEVEL', 'verbose' , c_d, 'Log verboseness', '{"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}', "['none', 'minimal', 'verbose', 'debug', 'trace']", 'General') conf.LOG_LEVEL = ccd('LOG_LEVEL', 'verbose' , c_d, 'Log verboseness', '{"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}', "['none', 'minimal', 'verbose', 'debug', 'trace']", 'General')
conf.TIMEZONE = ccd('TIMEZONE', 'Europe/Berlin' , c_d, 'Time zone', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General') conf.TIMEZONE = ccd('TIMEZONE', default_tz , c_d, 'Time zone', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General')
conf.PLUGINS_KEEP_HIST = ccd('PLUGINS_KEEP_HIST', 250 , c_d, 'Keep history entries', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', '[]', 'General') conf.PLUGINS_KEEP_HIST = ccd('PLUGINS_KEEP_HIST', 250 , c_d, 'Keep history entries', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', '[]', 'General')
conf.REPORT_DASHBOARD_URL = ccd('REPORT_DASHBOARD_URL', 'http://netalertx/' , c_d, 'NetAlertX URL', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General') conf.REPORT_DASHBOARD_URL = ccd('REPORT_DASHBOARD_URL', 'http://netalertx/' , c_d, 'NetAlertX URL', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General')
conf.DAYS_TO_KEEP_EVENTS = ccd('DAYS_TO_KEEP_EVENTS', 90 , c_d, 'Delete events days', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', '[]', 'General') conf.DAYS_TO_KEEP_EVENTS = ccd('DAYS_TO_KEEP_EVENTS', 90 , c_d, 'Delete events days', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', '[]', 'General')
@@ -177,8 +177,15 @@ def importConfigs (db, all_plugins):
# UI # UI
conf.UI_LANG = ccd('UI_LANG', 'English' , c_d, 'Language Interface', '{"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}', "['English', 'German', 'Spanish', 'French', 'Norwegian', 'Russian', 'Italian (it_it)', 'Portuguese (pt_br)', 'Polish (pl_pl)', 'Chinese (zh_cn)', 'Turkish (tr_tr)', 'Czech (cs_cz)', 'Arabic (ar_ar)', 'Catalan (ca_ca)', 'Ukrainian (uk_ua)' ]", 'UI') conf.UI_LANG = ccd('UI_LANG', 'English' , c_d, 'Language Interface', '{"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}', "['English', 'German', 'Spanish', 'French', 'Norwegian', 'Russian', 'Italian (it_it)', 'Portuguese (pt_br)', 'Polish (pl_pl)', 'Chinese (zh_cn)', 'Turkish (tr_tr)', 'Czech (cs_cz)', 'Arabic (ar_ar)', 'Catalan (ca_ca)', 'Ukrainian (uk_ua)' ]", 'UI')
# Init timezone in case it changed # Init timezone in case it changed and handle invalid values
conf.tz = timezone(conf.TIMEZONE) try:
if conf.TIMEZONE not in all_timezones:
raise UnknownTimeZoneError(f"Invalid timezone: {conf.TIMEZONE}")
conf.tz = timezone(conf.TIMEZONE)
except UnknownTimeZoneError:
conf.tz = timezone(default_tz) # Init Default
conf.TIMEZONE = ccd('TIMEZONE', conf.tz , c_d, '_KEEP_', '_KEEP_', '[]', 'General')
mylog('none', [f"[Config] Invalid timezone '{conf.TIMEZONE}', defaulting to {default_tz}."])
# TODO cleanup later ---------------------------------------------------------------------------------- # TODO cleanup later ----------------------------------------------------------------------------------
# init all time values as we have timezone - all this shoudl be moved into plugin/plugin settings # init all time values as we have timezone - all this shoudl be moved into plugin/plugin settings