Compare commits
217 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
703ba5c75b | ||
|
|
aad74451ef | ||
|
|
a787510963 | ||
|
|
dd2b872712 | ||
|
|
2a5e419034 | ||
|
|
b921144dbb | ||
|
|
4f2ddccdde | ||
|
|
780b818815 | ||
|
|
5779fd34c5 | ||
|
|
b7a6fe9112 | ||
|
|
906bfd24a4 | ||
|
|
8f48172940 | ||
|
|
736304eb8a | ||
|
|
5fce3c79b0 | ||
|
|
81c1f65816 | ||
|
|
edfaadf682 | ||
|
|
0a51d5fe79 | ||
|
|
893063c695 | ||
|
|
da5cf4a8f1 | ||
|
|
1e5a4e96e4 | ||
|
|
74d7a7853a | ||
|
|
63469007ef | ||
|
|
f5b875e2df | ||
|
|
d18efb2103 | ||
|
|
e2cdce2f39 | ||
|
|
c855d50999 | ||
|
|
9d8b147e40 | ||
|
|
3aa9be7019 | ||
|
|
72b3d5eb6d | ||
|
|
83bc406ed6 | ||
|
|
e6e1c79d6a | ||
|
|
e0616f72fe | ||
|
|
696403ac20 | ||
|
|
c946a5335a | ||
|
|
9610810891 | ||
|
|
2ad7f02255 | ||
|
|
431543ba80 | ||
|
|
09d2e68479 | ||
|
|
896b8b7641 | ||
|
|
8d607aac96 | ||
|
|
c95a371ad9 | ||
|
|
4b3ff048dc | ||
|
|
3267762280 | ||
|
|
885a470585 | ||
|
|
d0f4faca51 | ||
|
|
4443c69d31 | ||
|
|
890e533969 | ||
|
|
d7b9bb447f | ||
|
|
c63f424c7d | ||
|
|
dd1580e536 | ||
|
|
630e4f6327 | ||
|
|
cb8af32553 | ||
|
|
d469a9ded4 | ||
|
|
c8a40920b4 | ||
|
|
b0cd9acb79 | ||
|
|
6129f31a24 | ||
|
|
3eb8f39b5c | ||
|
|
5b1002620b | ||
|
|
e50d757f57 | ||
|
|
5110a3c2f3 | ||
|
|
abf7be5958 | ||
|
|
82708bd5df | ||
|
|
b5dce3f6aa | ||
|
|
5562ae7add | ||
|
|
4363e083d5 | ||
|
|
e766b19d8c | ||
|
|
b18ee70b8a | ||
|
|
f70bb40ef4 | ||
|
|
844a408ff4 | ||
|
|
a21cc0db85 | ||
|
|
a5427f795b | ||
|
|
6b390b66de | ||
|
|
af1e9b921b | ||
|
|
9503cc6397 | ||
|
|
a16c2dfed6 | ||
|
|
b4fc05d1e8 | ||
|
|
adb99e5f1a | ||
|
|
fbce3e18c2 | ||
|
|
0fcda5ff0a | ||
|
|
a5c6510654 | ||
|
|
6d44ed1bba | ||
|
|
314372a0f2 | ||
|
|
5a84cb5cc2 | ||
|
|
12cc71552c | ||
|
|
6752b7fc40 | ||
|
|
f371515258 | ||
|
|
f1d73f6ad4 | ||
|
|
9fee846436 | ||
|
|
b4ebd640e5 | ||
|
|
e94953b9af | ||
|
|
6718d054dc | ||
|
|
88e4dbf12e | ||
|
|
9f1db5ca1a | ||
|
|
5e7bb207c8 | ||
|
|
6ad90610ea | ||
|
|
c8ff0d79d1 | ||
|
|
61cf87f0d6 | ||
|
|
75bbc8bcf3 | ||
|
|
5582c0bf5e | ||
|
|
8278a92b11 | ||
|
|
d5ac00a307 | ||
|
|
2b02596b17 | ||
|
|
2a736f3c19 | ||
|
|
0b5c0b198a | ||
|
|
2d0a461724 | ||
|
|
74c6faccc7 | ||
|
|
89a154e224 | ||
|
|
8b84e4b325 | ||
|
|
e55002a9b0 | ||
|
|
b4e741568b | ||
|
|
711e0012cb | ||
|
|
ea2e8459b5 | ||
|
|
16d06e8a74 | ||
|
|
9625c36d12 | ||
|
|
f47858d773 | ||
|
|
ac2ce85f33 | ||
|
|
e887a11755 | ||
|
|
73f432c786 | ||
|
|
9c95a79e07 | ||
|
|
f0bbd37812 | ||
|
|
7b0777b805 | ||
|
|
b8dce59138 | ||
|
|
f1d79074ec | ||
|
|
4156bc1669 | ||
|
|
00c4dd86c6 | ||
|
|
979ce8fd75 | ||
|
|
ede926beee | ||
|
|
e1f91ddf17 | ||
|
|
e9539962c9 | ||
|
|
87d18a9067 | ||
|
|
2302cd9a31 | ||
|
|
babe0eab53 | ||
|
|
7c878690ef | ||
|
|
b29dcbfa98 | ||
|
|
8d9c48166b | ||
|
|
540f8e850b | ||
|
|
8316d8e741 | ||
|
|
ad32e76a55 | ||
|
|
190ffd3237 | ||
|
|
c8280184dc | ||
|
|
076d8bbcc2 | ||
|
|
b21d57c524 | ||
|
|
064e0cb0ff | ||
|
|
ad9d61aa16 | ||
|
|
64ff9710d1 | ||
|
|
0cc87e3cfc | ||
|
|
c40af37ca1 | ||
|
|
07a7ace5fc | ||
|
|
4a82ea87f7 | ||
|
|
db47571424 | ||
|
|
58eaa33f39 | ||
|
|
6e4d34b93a | ||
|
|
b2c445e39d | ||
|
|
90ff2efbfb | ||
|
|
b49f1ab335 | ||
|
|
3da5af1b7c | ||
|
|
90dd8e3198 | ||
|
|
c31966bdd0 | ||
|
|
f2a0018982 | ||
|
|
48ac108ca0 | ||
|
|
19441a4431 | ||
|
|
5541d6c9d2 | ||
|
|
93886cec8a | ||
|
|
8401ecda5e | ||
|
|
09aba51a33 | ||
|
|
06946e4fea | ||
|
|
f96ca3e08b | ||
|
|
4aa18691f4 | ||
|
|
bd198587cd | ||
|
|
e8a4cb1d51 | ||
|
|
75e25867e1 | ||
|
|
7dadb735c2 | ||
|
|
b444f98e2d | ||
|
|
8ca2bff456 | ||
|
|
308285f808 | ||
|
|
1a03b2ccc3 | ||
|
|
f6a6c3684c | ||
|
|
f2bf379597 | ||
|
|
802002a5f0 | ||
|
|
e6d2a1c138 | ||
|
|
729c24029f | ||
|
|
3260a67bf4 | ||
|
|
5621f13c6e | ||
|
|
aae08594bb | ||
|
|
ba83884b9f | ||
|
|
2799d3598b | ||
|
|
1ee746a625 | ||
|
|
e52601e062 | ||
|
|
2dad079979 | ||
|
|
47bdb60c85 | ||
|
|
6b9df66b02 | ||
|
|
b188afab44 | ||
|
|
5fe6ac9816 | ||
|
|
d354acbcb2 | ||
|
|
846e15d518 | ||
|
|
067467da53 | ||
|
|
8ac4112ab9 | ||
|
|
ae32b0dd42 | ||
|
|
4fef6e156b | ||
|
|
161a74dee0 | ||
|
|
fa570b9bc9 | ||
|
|
9cfbc7d140 | ||
|
|
dda440eb53 | ||
|
|
efe161494e | ||
|
|
35f1624804 | ||
|
|
74ec75f105 | ||
|
|
0f474fb884 | ||
|
|
f54ffcbbc3 | ||
|
|
21fd9866fe | ||
|
|
3732416616 | ||
|
|
29396ad6bd | ||
|
|
37ae75ed9a | ||
|
|
7cdcf95300 | ||
|
|
e26f7d42e9 | ||
|
|
8f8264c6fa | ||
|
|
a4c34140bf | ||
|
|
466aa62a02 |
@@ -6,14 +6,10 @@
|
||||
docker-compose.yml
|
||||
Dockerfile
|
||||
Dockerfile.debian
|
||||
dockerfiles/LICENSE
|
||||
dockerfiles/README.md
|
||||
dockerfiles/README_ES.md
|
||||
docs
|
||||
LICENSE.txt
|
||||
README.md
|
||||
CONTRIBUTING
|
||||
FUNDING.yml
|
||||
config/.gitignore
|
||||
db/.gitignore
|
||||
|
||||
db/.gitignore
|
||||
7
.github/ISSUE_TEMPLATE/i-have-an-issue.yml
vendored
@@ -60,10 +60,11 @@ body:
|
||||
required: false
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: What branch are you running?
|
||||
label: What installation are you running?
|
||||
options:
|
||||
- Production
|
||||
- Dev
|
||||
- Production (netalertx)
|
||||
- Dev (netalertx-dev)
|
||||
- Home Assistant (addon)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
|
||||
32
.github/workflows/social_post_on_release.yml
vendored
Executable file
@@ -0,0 +1,32 @@
|
||||
name: 📧 Twitter and Discord Posts
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
post-release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Wait for 15 minutes
|
||||
run: sleep 900 # 15 minutes delay
|
||||
|
||||
# Post to Twitter
|
||||
- name: Post to Twitter
|
||||
uses: twitter-together/action@v3
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
|
||||
TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
|
||||
TWITTER_API_KEY: ${{ secrets.TWITTER_API_KEY }}
|
||||
TWITTER_API_SECRET_KEY: ${{ secrets.TWITTER_API_SECRET_KEY }}
|
||||
with:
|
||||
tweet: |
|
||||
🎉 New release: **${{ github.event.release.name }}** is live! 🚀
|
||||
Check it out here: ${{ github.event.release.html_url }}
|
||||
|
||||
# Post to Discord
|
||||
- name: Post to Discord
|
||||
run: |
|
||||
curl -X POST -H "Content-Type: application/json" \
|
||||
-d '{"content": "🎉 New release: **${{ github.event.release.name }}** is live! 🚀\nCheck it out here: ${{ github.event.release.html_url }}"}' \
|
||||
${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
29
.github/workflows/update_sponsors_table.yml
vendored
@@ -1,29 +0,0 @@
|
||||
name: 🤖Automation - Update Sponsors Table
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '50 11 * * *' # Set your preferred schedule (UTC)
|
||||
|
||||
jobs:
|
||||
update-table:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.8
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r update_sponsors_requirements.txt # If you have any Python dependencies
|
||||
|
||||
- name: Update Sponsors Table
|
||||
run: |
|
||||
python update_sponsors.py
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
9
.gitignore
vendored
@@ -11,6 +11,7 @@ front/log/*
|
||||
front/api/*
|
||||
/api/*
|
||||
**/plugins/**/*.log
|
||||
**/plugins/cloud_services/*
|
||||
**/%40eaDir/
|
||||
**/@eaDir/
|
||||
|
||||
@@ -24,10 +25,10 @@ __pycache__/
|
||||
**/pialert.db_bak
|
||||
.*.swp
|
||||
|
||||
front/img/account/*
|
||||
**/account.php
|
||||
**/account.js
|
||||
front/css/account.css
|
||||
front/img/cloud_services/*
|
||||
**/cloud_services.php
|
||||
**/cloud_services.js
|
||||
front/css/cloud_services.css
|
||||
|
||||
docker-compose.yml.ffsb42
|
||||
.env.omada.ffsb42
|
||||
|
||||
34
Dockerfile
@@ -1,11 +1,11 @@
|
||||
FROM alpine:3.20 AS builder
|
||||
FROM alpine:3.21 AS builder
|
||||
|
||||
ARG INSTALL_DIR=/app
|
||||
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
# 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
|
||||
|
||||
# Enable venv
|
||||
@@ -13,34 +13,21 @@ ENV PATH="/opt/venv/bin:$PATH"
|
||||
|
||||
COPY . ${INSTALL_DIR}/
|
||||
|
||||
|
||||
RUN pip install graphene flask netifaces tplink-omada-client 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 f -exec chmod 640 {} \;" \
|
||||
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"
|
||||
|
||||
# Append Iliadbox certificate to aiofreepybox
|
||||
RUN printf "\n-----BEGIN CERTIFICATE-----\n\
|
||||
MIICOjCCAcCgAwIBAgIUI0Tu7zsrBJACQIZgLMJobtbdNn4wCgYIKoZIzj0EAwIw\n\
|
||||
TDELMAkGA1UEBhMCSVQxDjAMBgNVBAgMBUl0YWx5MQ4wDAYDVQQKDAVJbGlhZDEd\n\
|
||||
MBsGA1UEAwwUSWxpYWRib3ggRUNDIFJvb3QgQ0EwHhcNMjAxMTI3MDkzODEzWhcN\n\
|
||||
NDAxMTIyMDkzODEzWjBMMQswCQYDVQQGEwJJVDEOMAwGA1UECAwFSXRhbHkxDjAM\n\
|
||||
BgNVBAoMBUlsaWFkMR0wGwYDVQQDDBRJbGlhZGJveCBFQ0MgUm9vdCBDQTB2MBAG\n\
|
||||
ByqGSM49AgEGBSuBBAAiA2IABMryJyb2loHNAioY8IztN5MI3UgbVHVP/vZwcnre\n\
|
||||
ZvJOyDvE4HJgIti5qmfswlnMzpNbwf/MkT+7HAU8jJoTorRm1wtAnQ9cWD3Ebv79\n\
|
||||
RPwtjjy3Bza3SgdVxmd6fWPUKaNjMGEwHQYDVR0OBBYEFDUij/4lpoJ+kOXRyrcM\n\
|
||||
jf2RPzOqMB8GA1UdIwQYMBaAFDUij/4lpoJ+kOXRyrcMjf2RPzOqMA8GA1UdEwEB\n\
|
||||
/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQC6eUV1\n\
|
||||
pFh4UpJOTc1JToztN4ttnQR6rIzxMZ6mNCe+nhjkohWp24pr7BpUYSbEizYCMAQ6\n\
|
||||
LCiBKV2j7QQGy7N1aBmdur17ZepYzR1YV0eI+Kd978aZggsmhjXENQYVTmm/XA==\n\
|
||||
-----END CERTIFICATE-----\n" >> /opt/venv/lib/python3.12/site-packages/aiofreepybox/freebox_certificates.pem
|
||||
RUN cat ${INSTALL_DIR}/install/freebox_certificate.pem >> /opt/venv/lib/python3.12/site-packages/aiofreepybox/freebox_certificates.pem
|
||||
|
||||
# second stage
|
||||
FROM alpine:3.20 AS runner
|
||||
FROM alpine:3.21 AS runner
|
||||
|
||||
ARG INSTALL_DIR=/app
|
||||
|
||||
COPY --from=builder /opt/venv /opt/venv
|
||||
COPY --from=builder /usr/sbin/usermod /usr/sbin/groupmod /usr/sbin/
|
||||
|
||||
# Enable venv
|
||||
ENV PATH="/opt/venv/bin:$PATH"
|
||||
@@ -54,11 +41,10 @@ ENV S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0
|
||||
# ❗ IMPORTANT - if you modify this file modify the /install/install_dependecies.sh file as well ❗
|
||||
|
||||
RUN apk update --no-cache \
|
||||
&& apk add --no-cache bash zip lsblk gettext-envsubst sudo mtr tzdata s6-overlay \
|
||||
&& apk add --no-cache curl arp-scan iproute2 iproute2-ss nmap nmap-scripts traceroute nbtscan avahi avahi-tools openrc dbus net-tools net-snmp-tools bind-tools awake ca-certificates \
|
||||
&& 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 sqlite php83 php83-fpm php83-cgi php83-curl php83-sqlite3 php83-session \
|
||||
&& apk add --no-cache python3 nginx \
|
||||
&& apk add --no-cache dcron \
|
||||
&& ln -s /usr/bin/awake /usr/bin/wakeonlan \
|
||||
&& bash -c "install -d -m 750 -o nginx -g www-data ${INSTALL_DIR} ${INSTALL_DIR}" \
|
||||
&& rm -f /etc/nginx/http.d/default.conf
|
||||
@@ -66,10 +52,10 @@ RUN apk update --no-cache \
|
||||
COPY --from=builder --chown=nginx:www-data ${INSTALL_DIR}/ ${INSTALL_DIR}/
|
||||
|
||||
# Add crontab file
|
||||
COPY install/crontab /etc/crontabs/root
|
||||
COPY --chmod=600 --chown=root:root install/crontab /etc/crontabs/root
|
||||
|
||||
# Start all required services
|
||||
RUN ${INSTALL_DIR}/dockerfiles/pre-setup.sh
|
||||
RUN ${INSTALL_DIR}/dockerfiles/start.sh
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=2 \
|
||||
CMD curl -sf -o /dev/null ${LISTEN_ADDR}:${PORT}/php/server/query_json.php?file=app_state.json
|
||||
|
||||
@@ -43,7 +43,7 @@ RUN phpenmod -v 8.2 sqlite3
|
||||
RUN apt-get install -y python3-venv
|
||||
RUN python3 -m venv myenv
|
||||
|
||||
RUN /bin/bash -c "source myenv/bin/activate && update-alternatives --install /usr/bin/python python /usr/bin/python3 10 && pip3 install tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros "
|
||||
RUN /bin/bash -c "source myenv/bin/activate && update-alternatives --install /usr/bin/python python /usr/bin/python3 10 && pip3 install openwrt-luci-rpc 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 "
|
||||
|
||||
# Create a buildtimestamp.txt to later check if a new version was released
|
||||
RUN date +%s > ${INSTALL_DIR}/front/buildtimestamp.txt
|
||||
|
||||
122
README.md
@@ -1,104 +1,80 @@
|
||||
[](https://github.com/jokob-sk/NetAlertX)
|
||||
[](https://hub.docker.com/r/jokobsk/netalertx)
|
||||
[](https://hub.docker.com/r/jokobsk/netalertx)
|
||||
[](https://github.com/jokob-sk/NetAlertX/releases)
|
||||
[](https://discord.gg/NczTUTWyRr)
|
||||
[](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Falexbelgium%2Fhassio-addons)
|
||||
|
||||
# 🖧🔍 Network scanner & notification framework
|
||||
# NetAlertX - Network, presence scanner and alert framework
|
||||
|
||||
Get visibility of what's going on on your WIFI/LAN network. Schedule scans for devices, port changes and get alerts if unknown devices or changes are found. Write your own [Plugins](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) with auto-generated UI and in-build notification system. Build out and easily maintain your network source of truth (NSoT).
|
||||
Get visibility of what's going on on your WIFI/LAN network and enable presence detection of important devices. Schedule scans for devices, port changes and get alerts if unknown devices or changes are found. Write your own [Plugins](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) with auto-generated UI and in-build notification system. Build out and easily maintain your network source of truth (NSoT).
|
||||
|
||||
|
||||
| 🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/netalertx) | 📑 [Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) |🆕 [Release notes](https://github.com/jokob-sk/NetAlertX/releases) | 📚 [All Docs](https://github.com/jokob-sk/NetAlertX/tree/main/docs) |
|
||||
|----------------------|----------------------| ----------------------| ----------------------|
|
||||
| [📑 Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) | [🚀 Releases](https://github.com/jokob-sk/NetAlertX/releases) | [📚 Docs](https://github.com/jokob-sk/NetAlertX/tree/main/docs) | [🔌 Plugins](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md) | [🤖 Ask AI](https://gurubase.io/g/netalertx)
|
||||
|----------------------| ----------------------| ----------------------| ----------------------| ----------------------|
|
||||
|
||||
|
||||
| ![Main screen][main] | ![device_details 1][device_details] | ![Screen network][network] |
|
||||
|----------------------|----------------------| ----------------------|
|
||||
|
||||
![network_setup][network_setup]
|
||||
|
||||
|
||||
Head to [https://netalertx.com/](https://netalertx.com/) for more gifs and screenshots 📷.
|
||||
![showcase][showcase]
|
||||
|
||||
<details>
|
||||
<summary>📷 Click for more screenshots</summary>
|
||||
|
||||
| ![presence][presence] | ![maintenance][maintenance] | ![settings][settings] |
|
||||
| ![Main screen][main] | ![device_details 1][device_details] | ![Screen network][network] |
|
||||
|----------------------|----------------------|----------------------|
|
||||
| ![presence][presence] | ![maintenance][maintenance] | ![settings][settings] |
|
||||
| ![sync_hub][sync_hub] | ![report1][report1] | ![device_nmap][device_nmap] |
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>❓ Why use Net<b>Alert</b><sup>x</sup>?</summary>
|
||||
|
||||
<hr>
|
||||
|
||||
Most of us don't know what's going on on our home network, but we want our family and data to be safe. _Command-line tools_ are great, but the output can be _hard to understand_ and action if you are not a network specialist.
|
||||
|
||||
Net<b>Alert</b><sup>x</sup> gives you peace of mind. _Visualize and immediately report 📬_ what is going on in your network - this is the first step to enhance your _network security 🔐_.
|
||||
|
||||
Net<b>Alert</b><sup>x</sup> combines several network and other scanning tools 🔍 with notifications 📧 into one user-friendly package 📦.
|
||||
|
||||
Set up a _kill switch ☠_ for your network via a smart plug with the available [Home Assistant](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HOME_ASSISTANT.md) integration. Implement custom automations with the [CSV device Exports 📤](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/csv_backup), [Webhooks](https://github.com/jokob-sk/NetAlertX/blob/main/docs/WEBHOOK_N8N.md), or [API endpoints](https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md) features.
|
||||
|
||||
Extend the app if you want to create your own scanner [Plugin](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) and handle the results and notifications in Net<b>Alert</b><sup>x</sup>.
|
||||
|
||||
Looking forward to your contributions if you decide to share your work with the community ❤.
|
||||
Head to [https://netalertx.com/](https://netalertx.com/) for even more gifs and screenshots 📷.
|
||||
|
||||
</details>
|
||||
|
||||
## Scan Methods, Notifications, Integration, Extension system
|
||||
## 📦 Features
|
||||
|
||||
| Features | Details |
|
||||
|-------------|-------------|
|
||||
| 🔍 | The app scans your network for, **New devices**, **New connections** (re-connections), **Disconnections**, **"Always Connected" devices down**, Devices **IP changes** and **Internet IP address changes**. Discovery & scan methods include: **arp-scan**, **Pi-hole - DB import**, **Pi-hole - DHCP leases import**, **Generic DHCP leases import**. **UNIFI controller import**, **SNMP-enabled router import**. Check the [Plugins](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) docs for more info on individual scans. |
|
||||
|📧 | Send notifications to more than 80+ services, including Telegram via [Apprise](https://hub.docker.com/r/caronc/apprise), or use [Pushsafer](https://www.pushsafer.com/), [Pushover](https://www.pushover.net/), or [NTFY](https://ntfy.sh/). |
|
||||
|🧩 | Feed your data and device changes into [Home Assistant](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HOME_ASSISTANT.md), read [API endpoints](https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md), or use [Webhooks](https://github.com/jokob-sk/NetAlertX/blob/main/docs/WEBHOOK_N8N.md) to setup custom automation flows. |
|
||||
|➕ | Build your own scanners with the [Plugin system](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) |
|
||||
### Scanners
|
||||
|
||||
The app scans your network for **New devices**, **New connections** (re-connections), **Disconnections**, **"Always Connected" devices down**, Devices **IP changes** and **Internet IP address changes**. Discovery & scan methods include: **arp-scan**, **Pi-hole - DB import**, **Pi-hole - DHCP leases import**, **Generic DHCP leases import**, **UNIFI controller import**, **SNMP-enabled router import**. Check the [Plugins](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) docs for a full lits of avaliable plugins.
|
||||
|
||||
### Notification gateways
|
||||
|
||||
Send notifications to more than 80+ services, including Telegram via [Apprise](https://hub.docker.com/r/caronc/apprise), or use native [Pushsafer](https://www.pushsafer.com/), [Pushover](https://www.pushover.net/), or [NTFY](https://ntfy.sh/) publishers.
|
||||
|
||||
### Integrations and Plugins
|
||||
|
||||
Feed your data and device changes into [Home Assistant](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HOME_ASSISTANT.md), read [API endpoints](https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md), or use [Webhooks](https://github.com/jokob-sk/NetAlertX/blob/main/docs/WEBHOOK_N8N.md) to setup custom automation flows. You can also
|
||||
build your own scanners with the [Plugin system](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) in as little as [15 minutes](https://www.youtube.com/watch?v=cdbxlwiWhv8).
|
||||
|
||||
|
||||
## Installation & Documentation
|
||||
## 📚 Documentation
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
|
||||
Supported browsers: Chrome, Firefox
|
||||
|
||||
| Docs | Link |
|
||||
|-------------|-------------|
|
||||
| 📥🐳 | [Docker instructions](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md)
|
||||
| 📥🗄️ | [HW install (experimental 🧪)](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HW_INSTALL.md) |
|
||||
| 📥🟧 | [Unraid App](https://unraid.net/community/apps) |
|
||||
| 📚 | [All Documentation](https://github.com/jokob-sk/NetAlertX/blob/main/docs/README.md) (App Usage and Configuration) |
|
||||
|
||||
> Other Alternatives
|
||||
>
|
||||
> - Check out [leiweibau's on HW installed fork](https://github.com/leiweibau/Pi.Alert/) (maintained)
|
||||
> - [WatchYourLAN](https://github.com/aceberg/WatchYourLAN) - Lightweight network IP scanner with web GUI (Open source)
|
||||
> - [Fing](https://www.fing.com/) - Network scanner app for your Internet security (Commercial, Phone App, Proprietary hardware)
|
||||
> - [NetBox](https://netboxlabs.com/) - Network management software (Commercial)
|
||||
- [[Installation] Docker](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md)
|
||||
- [[Installation] Home Assistant](https://github.com/alexbelgium/hassio-addons/tree/master/netalertx)
|
||||
- [[Installation] Bare metal](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HW_INSTALL.md)
|
||||
- [[Installation] Unraid App](https://unraid.net/community/apps)
|
||||
- [[Setup] Usage and Configuration](https://github.com/jokob-sk/NetAlertX/blob/main/docs/README.md)
|
||||
- [[Development] API docs](https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md)
|
||||
- [[Development] Custom Plugins](https://github.com/jokob-sk/NetAlertX/blob/main/docs/PLUGINS_DEV.md)
|
||||
|
||||
## 🔔 Get notified what's new
|
||||
|
||||
## 📃 Everything else
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
|
||||
### 📧 Get notified what's new
|
||||
|
||||
Get notified about a new release, what new functionality you can use and about breaking changes.
|
||||
|
||||
![Follow and star][follow_star]
|
||||
|
||||
### ⭐ Sponsors
|
||||
### 🔀 Other Alternative Apps
|
||||
|
||||
[](https://github.com/sponsors/jokob-sk)
|
||||
|
||||
Thank you to all the wonderful people who are sponsoring this project.
|
||||
|
||||
> preventing my burnout😅 are:
|
||||
|
||||
<!-- SPONSORS-LIST DO NOT MODIFY BELOW -->
|
||||
| All Sponsors |
|
||||
|---|
|
||||
|
||||
<!-- SPONSORS-LIST DO NOT MODIFY ABOVE -->
|
||||
- [PiAlert by leiweibau](https://github.com/leiweibau/Pi.Alert/) (maintained, bare-metal install)
|
||||
- [WatchYourLAN](https://github.com/aceberg/WatchYourLAN) - Lightweight network IP scanner with web GUI (Open source)
|
||||
- [Fing](https://www.fing.com/) - Network scanner app for your Internet security (Commercial, Phone App, Proprietary hardware)
|
||||
- [NetBox](https://netboxlabs.com/) - Network management software (Commercial)
|
||||
|
||||
### 💙 Donations
|
||||
|
||||
Thank you to everyone who appreciates this tool and donates.
|
||||
|
||||
<details>
|
||||
<summary>Click for more ways to donate</summary>
|
||||
@@ -115,26 +91,20 @@ Thank you to all the wonderful people who are sponsoring this project.
|
||||
|
||||
</details>
|
||||
|
||||
### 🙏Contributors
|
||||
### 🏗 Contributors
|
||||
|
||||
This project would be nothing without the amazing work of the community, with special thanks to:
|
||||
|
||||
> [pucherot/Pi.Alert](https://github.com/pucherot/Pi.Alert) (the original creator of PiAlert), [leiweibau](https://github.com/leiweibau/Pi.Alert): Dark mode (and much more), [Macleykun](https://github.com/Macleykun) (Help with Dockerfile clean-up) [Final-Hawk](https://github.com/Final-Hawk) (Help with NTFY, styling and other fixes), [TeroRERO](https://github.com/terorero) (Spanish translations), [Data-Monkey](https://github.com/Data-Monkey), (Split-up of the python.py file and more), [cvc90](https://github.com/cvc90) (Spanish translation and various UI work) to name a few...
|
||||
|
||||
|
||||
## Everything else
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
> [pucherot/Pi.Alert](https://github.com/pucherot/Pi.Alert) (the original creator of PiAlert), [leiweibau](https://github.com/leiweibau/Pi.Alert): Dark mode (and much more), [Macleykun](https://github.com/Macleykun) (Help with Dockerfile clean-up), [vladaurosh](https://github.com/vladaurosh) for Alpine re-base help, [Final-Hawk](https://github.com/Final-Hawk) (Help with NTFY, styling and other fixes), [TeroRERO](https://github.com/terorero) (Spanish translations), [Data-Monkey](https://github.com/Data-Monkey), (Split-up of the python.py file and more), [cvc90](https://github.com/cvc90) (Spanish translation and various UI work) to name a few. Check out all the [amazing contributors](https://github.com/jokob-sk/NetAlertX/graphs/contributors).
|
||||
|
||||
### 🌍 Translations
|
||||
|
||||
Proudly using [Weblate](https://hosted.weblate.org/projects/pialert/).
|
||||
Proudly using [Weblate](https://hosted.weblate.org/projects/pialert/). Help out and suggest languages in the [online portal of Weblate](https://hosted.weblate.org/projects/pialert/core/).
|
||||
|
||||
<a href="https://hosted.weblate.org/engage/pialert/">
|
||||
<img src="https://hosted.weblate.org/widget/pialert/core/multi-auto.svg" alt="Translation status" />
|
||||
</a>
|
||||
|
||||
Help out and suggest languages in the [online portal of Weblate](https://hosted.weblate.org/projects/pialert/core/).
|
||||
|
||||
### License
|
||||
> GPL 3.0 | [Read more here](LICENSE.txt) | Source of the [animated GIF (Loading Animation)](https://commons.wikimedia.org/wiki/File:Loading_Animation.gif) | Source of the [selfhosted Fonts](https://github.com/adobe-fonts/source-sans)
|
||||
|
||||
@@ -148,7 +118,7 @@ Help out and suggest languages in the [online portal of Weblate](https://hosted.
|
||||
[maintenance]: ./docs/img/maintenance.png "Screen 4"
|
||||
[network]: ./docs/img/network.png "Screen 5"
|
||||
[settings]: ./docs/img/settings.png "Screen 6"
|
||||
[network_setup]: ./docs/img/network_setup.gif "Screen 6"
|
||||
[showcase]: ./docs/img/showcase.gif "Screen 6"
|
||||
[help_faq]: ./docs/img/help_faq.png "Screen 7"
|
||||
[sync_hub]: ./docs/img/sync_hub.png "Screen 8"
|
||||
[notification_center]: ./docs/img/notification_center.png "Screen 8"
|
||||
|
||||
@@ -5,8 +5,9 @@ LOG_FILE="${INSTALL_DIR}/log/execution_queue.log"
|
||||
|
||||
# Check if there are any entries with cron_restart_backend
|
||||
if grep -q "cron_restart_backend" "$LOG_FILE"; then
|
||||
# Kill all python processes and restart the server
|
||||
pkill -f "python " && (python ${INSTALL_DIR}/server > /dev/null 2>&1 &) && echo 'done'
|
||||
# Restart python application using s6
|
||||
s6-svc -r /var/run/s6-rc/servicedirs/netalertx
|
||||
echo 'done'
|
||||
|
||||
# Remove all lines containing cron_restart_backend from the log file
|
||||
sed -i '/cron_restart_backend/d' "$LOG_FILE"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
version: "3"
|
||||
services:
|
||||
netalertx:
|
||||
privileged: true
|
||||
@@ -16,7 +15,7 @@ services:
|
||||
# - ${APP_DATA_LOCATION}/netalertx_dev/db:/app/db
|
||||
- ${APP_DATA_LOCATION}/netalertx/db:/app/db
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
- ${DEV_LOCATION}/log:/app/log
|
||||
- ${APP_DATA_LOCATION}/netalertx/log:/app/log
|
||||
# (API: OPTION 1) use for performance
|
||||
- type: tmpfs
|
||||
target: /app/api
|
||||
@@ -39,12 +38,6 @@ services:
|
||||
- ${DEV_LOCATION}/back/update_vendors.sh:/app/back/update_vendors.sh
|
||||
- ${DEV_LOCATION}/front/lib:/app/front/lib
|
||||
- ${DEV_LOCATION}/front/js:/app/front/js
|
||||
- ${DEV_LOCATION}/front/report_templates:/front/report_templates
|
||||
- ${DEV_LOCATION}/install/start.debian.sh:/app/install/start.debian.sh
|
||||
- ${DEV_LOCATION}/install/user-mapping.debian.sh:/app/install/user-mapping.debian.sh
|
||||
- ${DEV_LOCATION}/install/install.debian.sh:/app/install/install.debian.sh
|
||||
- ${DEV_LOCATION}/install/install_dependencies.debian.sh:/app/install/install_dependencies.debian.sh
|
||||
|
||||
- ${DEV_LOCATION}/front/php:/app/front/php
|
||||
- ${DEV_LOCATION}/front/deviceDetails.php:/app/front/deviceDetails.php
|
||||
- ${DEV_LOCATION}/front/deviceDetailsEdit.php:/app/front/deviceDetailsEdit.php
|
||||
@@ -64,19 +57,19 @@ services:
|
||||
- ${DEV_LOCATION}/front/presence.php:/app/front/presence.php
|
||||
- ${DEV_LOCATION}/front/settings.php:/app/front/settings.php
|
||||
- ${DEV_LOCATION}/front/systeminfo.php:/app/front/systeminfo.php
|
||||
- ${DEV_LOCATION}/front/account.php:/app/front/account.php
|
||||
- ${DEV_LOCATION}/front/cloud_services.php:/app/front/cloud_services.php
|
||||
- ${DEV_LOCATION}/front/report.php:/app/front/report.php
|
||||
- ${DEV_LOCATION}/front/workflows.php:/app/front/workflows.php
|
||||
- ${DEV_LOCATION}/front/appEventsCore.php:/app/front/appEventsCore.php
|
||||
- ${DEV_LOCATION}/front/multiEditCore.php:/app/front/multiEditCore.php
|
||||
- ${DEV_LOCATION}/front/donations.php:/app/front/donations.php
|
||||
- ${DEV_LOCATION}/front/plugins:/app/front/plugins
|
||||
# DELETE END anyone trying to use this file: comment out / delete ABOVE lines, they are only for development purposes
|
||||
# ---------------------------------------------------------------------------
|
||||
environment:
|
||||
# - APP_CONF_OVERRIDE={"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_theme":"Dark"}
|
||||
environment:
|
||||
# - APP_CONF_OVERRIDE={"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","GRAPHQL_PORT":"20223","UI_theme":"Light"}
|
||||
- TZ=${TZ}
|
||||
- PORT=${PORT}
|
||||
# ❗ DANGER ZONE BELOW - Setting ALWAYS_FRESH_INSTALL=true will delete the content of the /db & /config folders
|
||||
- ALWAYS_FRESH_INSTALL=${ALWAYS_FRESH_INSTALL}
|
||||
# - LOADED_PLUGINS=["DHCPLSS","PIHOLE","ASUSWRT","FREEBOX"]
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
[](https://github.com/jokob-sk/NetAlertX)
|
||||
[](https://hub.docker.com/r/jokobsk/netalertx)
|
||||
[](https://hub.docker.com/r/jokobsk/netalertx)
|
||||
[](https://github.com/jokob-sk/NetAlertX/releases)
|
||||
[](https://discord.gg/NczTUTWyRr)
|
||||
[](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Falexbelgium%2Fhassio-addons)
|
||||
|
||||
# NetAlertX - Network scanner & notification framework
|
||||
|
||||
# NetAlertX 🖧🔍 Network scanner & notification framework
|
||||
|
||||
| 🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/netalertx) | 📑 [Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) |🆕 [Release notes](https://github.com/jokob-sk/NetAlertX/releases) | 📚 [All Docs](https://github.com/jokob-sk/NetAlertX/tree/main/docs) |
|
||||
|----------------------|----------------------| ----------------------| ----------------------|
|
||||
| [📑 Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) | [🚀 Releases](https://github.com/jokob-sk/NetAlertX/releases) | [📚 Docs](https://github.com/jokob-sk/NetAlertX/tree/main/docs) | [🔌 Plugins](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md) | [🤖 Ask AI](https://gurubase.io/g/netalertx)
|
||||
|----------------------| ----------------------| ----------------------| ----------------------| ----------------------|
|
||||
|
||||
<a href="https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/docs/img/GENERAL/github_social_image.jpg" target="_blank">
|
||||
<img src="https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/docs/img/GENERAL/github_social_image.jpg" width="1000px" />
|
||||
@@ -22,29 +21,35 @@ Head to [https://netalertx.com/](https://netalertx.com/) for more gifs and scree
|
||||
## 📕 Basic Usage
|
||||
|
||||
> [!WARNING]
|
||||
> You will have to run the container on the `host` network.
|
||||
> You will have to run the container on the `host` network and specify `SCAN_SUBNETS` unless you use other [plugin scanners](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md). The initial scan can take a few minutes, so please wait 5-10 minutes for the initial discovery to finish.
|
||||
|
||||
```yaml
|
||||
docker run -d --rm --network=host \
|
||||
-v local/path/config:/app/config \
|
||||
-v local/path/db:/app/db \
|
||||
-v local_path/config:/app/config \
|
||||
-v local_path/db:/app/db \
|
||||
--mount type=tmpfs,target=/app/api \
|
||||
-e PUID=200 -e PGID=300 \
|
||||
-e TZ=Europe/Berlin \
|
||||
-e PORT=20211 \
|
||||
jokobsk/netalertx:latest
|
||||
```
|
||||
- The initial scan can take up to 15min (with 50 devices and MQTT). Subsequent ones 3 and 5 minutes so wait that long for all of the scans to run.
|
||||
|
||||
See alternative [docked-compose examples](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_COMPOSE.md).
|
||||
|
||||
### Docker environment variables
|
||||
|
||||
| Variable | Description | Default |
|
||||
| :------------- |:-------------| -----:|
|
||||
| Variable | Description | Example Value |
|
||||
| :------------- |:------------------------| -----:|
|
||||
| `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` |
|
||||
|`TZ` |Time zone to display stats correctly. Find your time zone [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) | `Europe/Berlin` |
|
||||
|`APP_CONF_OVERRIDE` | JSON override for settings, e.g. `{"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_theme":"Dark"}` (Experimental 🧪) | `N/A` |
|
||||
|`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` |
|
||||
|`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"]` |
|
||||
|`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
|
||||
|
||||
@@ -53,190 +58,41 @@ docker run -d --rm --network=host \
|
||||
|
||||
| Required | Path | Description |
|
||||
| :------------- | :------------- | :-------------|
|
||||
| ✅ | `:/app/config` | Folder which will contain the `app.conf` & `devices.csv` ([read about devices.csv](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md)) files (see below for details). |
|
||||
| ✅ | `:/app/db` | Folder which will contain the `app.db` file |
|
||||
| ✅ | `:/app/config` | Folder which will contain the `app.conf` & `devices.csv` ([read about devices.csv](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md)) files |
|
||||
| ✅ | `:/app/db` | Folder which will contain the `app.db` database file |
|
||||
| | `:/app/log` | Logs folder useful for debugging if you have issues setting up the container |
|
||||
| | `:/etc/pihole/pihole-FTL.db` | PiHole's `pihole-FTL.db` database file. Required if you want to use PiHole DB mapping. |
|
||||
| | `:/etc/pihole/dhcp.leases` | PiHole's `dhcp.leases` file. Required if you want to use PiHole `dhcp.leases` file. This has to be matched with a corresponding `DHCPLSS_paths_to_check` setting entry (the path in the container must contain `pihole`)|
|
||||
| | `:/app/api` | A simple [API endpoint](https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md) containing static (but regularly updated) json and other files. |
|
||||
| | `:/app/front/plugins/<plugin>/ignore_plugin` | Map a file `ignore_plugin` to ignore a plugin. Plugins can be soft-disabled via settings. More in the [Plugin docs](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md). |
|
||||
| | `:/etc/resolv.conf` | Use a custom `resolv.conf` file for [better name resolution](https://github.com/jokob-sk/NetAlertX/blob/main/docs/REVERSE_DNS.md). |
|
||||
|
||||
> Use separate `db` and `config` directories, don't nest them.
|
||||
> Use separate `db` and `config` directories, do not nest them.
|
||||
|
||||
### (If UI is not available) Modify the config (`app.conf`)
|
||||
### Initial setup
|
||||
|
||||
- The preferred way is to manage the configuration via the Settings section in the UI.
|
||||
- You can modify [app.conf](https://github.com/jokob-sk/NetAlertX/tree/main/config) directly, if needed.
|
||||
- If unavailable, the app generates a default `app.conf` and `app.db` file on the first run.
|
||||
- The preferred way is to manage the configuration via the Settings section in the UI, if UI is inaccessible you can modify [app.conf](https://github.com/jokob-sk/NetAlertX/tree/main/back) in the `/app/config/` folder directly
|
||||
|
||||
### ⚙ Important settings
|
||||
#### Setting up scanners
|
||||
|
||||
These are the most important settings to get at least some output in your Devices screen. Usually, only one approach is used, but you can combine these approaches.
|
||||
|
||||
| Scan method | Setting | Description |
|
||||
| :------------- | :------------- | :-------------|
|
||||
| arp-scan, nmap-scan | `SCAN_SUBNETS` | See the documentation on how [to setup SUBNETS, VLANs & limitations](https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md) |
|
||||
| PiHole | `PIHOLE_RUN` | There are 2 approaches how to get PiHole devices imported. Via the PiHole import (`PIHOLE`) plugin or DHCP leases (`DHCPLSS`) plugin. The `PIHOLE` plugin requires you to map the PiHole database, as mentioned above. |
|
||||
| dhcp.leases | `DHCPLSS_RUN` | You need to map `:/etc/myfiles/dhcp.leases` in the `docker-compose.yml` file if you enable this setting. This path has to be matched with a corresponding `DHCPLSS_paths_to_check` setting entry (check the [DHCPLSS plugin readme](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/dhcp_leases#overview) for details). |
|
||||
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.
|
||||
|
||||
If you are running PiHole you can synchronize devices directly. Check the [PiHole configuration guide](https://github.com/jokob-sk/NetAlertX/blob/main/docs/PIHOLE_GUIDE.md) for details.
|
||||
|
||||
> [!NOTE]
|
||||
> It's recommended to use the same schedule interval for all plugins responsible for discovering new devices.
|
||||
> You can bulk-import devices via the [CSV import method](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md).
|
||||
|
||||
#### Community guides
|
||||
|
||||
#### 🧭 Community guides
|
||||
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.
|
||||
|
||||
Use the official installation guides at first and use community content as supplementary material. Open an issue if you'd like to add your link to the list 🙏
|
||||
|
||||
- ▶ [Home Lab Network Monitoring - Scotti-BYTE Enterprise Consulting Services](https://www.youtube.com/watch?v=0DryhzrQSJA) (July 2024)
|
||||
- 📄 [How to Install NetAlertX on Your Synology NAS - Marius hosting](https://mariushosting.com/how-to-install-pi-alert-on-your-synology-nas/) (Updated frequently)
|
||||
- 📄 [Using the PiAlert Network Security Scanner on a Raspberry Pi - PiMyLifeUp](https://pimylifeup.com/raspberry-pi-pialert/)
|
||||
- ▶ [How to Setup Pi.Alert on Your Synology NAS - Digital Aloha](https://www.youtube.com/watch?v=M4YhpuRFaUg)
|
||||
- 📄 [防蹭网神器,网络安全助手 | 极空间部署网络扫描和通知系统『NetAlertX』](https://blog.csdn.net/qq_63499861/article/details/141105273)
|
||||
- 📄 [시놀/헤놀에서 네트워크 스캐너 Pi.Alert Docker로 설치 및 사용하기](https://blog.dalso.org/article/%EC%8B%9C%EB%86%80-%ED%97%A4%EB%86%80%EC%97%90%EC%84%9C-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%8A%A4%EC%BA%90%EB%84%88-pi-alert-docker%EB%A1%9C-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9) (July 2023)
|
||||
- 📄 [网络入侵探测器Pi.Alert (Chinese)](https://codeantenna.com/a/VgUvIAjZ7J) (May 2023)
|
||||
- ▶ [Pi.Alert auf Synology & Docker by - Jürgen Barth](https://www.youtube.com/watch?v=-ouvA2UNu-A) (March 2023)
|
||||
- ▶ [Top Docker Container for Home Server Security - VirtualizationHowto](https://www.youtube.com/watch?v=tY-w-enLF6Q) (March 2023)
|
||||
- ▶ [Pi.Alert or WatchYourLAN can alert you to unknown devices appearing on your WiFi or LAN network - Danie van der Merwe](https://www.youtube.com/watch?v=v6an9QG2xF0) (November 2022)
|
||||
|
||||
> Ordered by last update time.
|
||||
> 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).
|
||||
|
||||
> [!NOTE]
|
||||
> You can bulk-update devices via the [CSV import method](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md).
|
||||
|
||||
## 📄 docker-compose.yml Examples
|
||||
|
||||
### Example 1
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
netalertx:
|
||||
container_name: netalertx
|
||||
# use the below line if you want to test the latest dev image
|
||||
# image: "jokobsk/netalertx-dev:latest"
|
||||
image: "jokobsk/netalertx:latest"
|
||||
network_mode: "host"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- local/path/config:/app/config
|
||||
- local/path/db:/app/db
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
- local/path/logs:/app/log
|
||||
# (API: OPTION 1) use for performance
|
||||
- type: tmpfs
|
||||
target: /app/api
|
||||
# (API: OPTION 2) use when debugging issues
|
||||
# - local/path/api:/app/api
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
```
|
||||
|
||||
To run the container execute: `sudo docker-compose up -d`
|
||||
|
||||
### Example 2
|
||||
|
||||
Example by [SeimuS](https://github.com/SeimusS).
|
||||
|
||||
```yaml
|
||||
netalertx:
|
||||
container_name: NetAlertX
|
||||
hostname: NetAlertX
|
||||
privileged: true
|
||||
# use the below line if you want to test the latest dev image
|
||||
# image: "jokobsk/netalertx-dev:latest"
|
||||
image: jokobsk/netalertx:latest
|
||||
environment:
|
||||
- TZ=Europe/Bratislava
|
||||
restart: always
|
||||
volumes:
|
||||
- ./netalertx/db:/app/db
|
||||
- ./netalertx/config:/app/config
|
||||
network_mode: host
|
||||
```
|
||||
|
||||
To run the container execute: `sudo docker-compose up -d`
|
||||
|
||||
### Example 3
|
||||
|
||||
`docker-compose.yml`
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
netalertx:
|
||||
container_name: netalertx
|
||||
# use the below line if you want to test the latest dev image
|
||||
# image: "jokobsk/netalertx-dev:latest"
|
||||
image: "jokobsk/netalertx:latest"
|
||||
network_mode: "host"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ${APP_DATA_LOCATION}/netalertx/config:/app/config
|
||||
- ${APP_DATA_LOCATION}/netalertx/db/:/app/db/
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
- ${LOGS_LOCATION}:/app/log
|
||||
environment:
|
||||
- TZ=${TZ}
|
||||
- PORT=${PORT}
|
||||
```
|
||||
|
||||
`.env` file
|
||||
|
||||
```yaml
|
||||
#GLOBAL PATH VARIABLES
|
||||
|
||||
APP_DATA_LOCATION=/path/to/docker_appdata
|
||||
APP_CONFIG_LOCATION=/path/to/docker_config
|
||||
LOGS_LOCATION=/path/to/docker_logs
|
||||
|
||||
#ENVIRONMENT VARIABLES
|
||||
|
||||
TZ=Europe/Paris
|
||||
PORT=20211
|
||||
|
||||
#DEVELOPMENT VARIABLES
|
||||
|
||||
DEV_LOCATION=/path/to/local/source/code
|
||||
```
|
||||
|
||||
To run the container execute: `sudo docker-compose --env-file /path/to/.env up`
|
||||
|
||||
### Example 4
|
||||
|
||||
Courtesy of [pbek](https://github.com/pbek). The volume `netalertx_db` is used by the db directory. The two config files are mounted directly from a local folder to their places in the config folder. You can backup the `docker-compose.yaml` folder and the docker volumes folder.
|
||||
|
||||
```yaml
|
||||
netalertx:
|
||||
# use the below line if you want to test the latest dev image
|
||||
# image: "jokobsk/netalertx-dev:latest"
|
||||
image: jokobsk/netalertx
|
||||
ports:
|
||||
- "80:20211/tcp"
|
||||
environment:
|
||||
- TZ=Europe/Vienna
|
||||
networks:
|
||||
local:
|
||||
ipv4_address: 192.168.1.2
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- netalertx_db:/app/db
|
||||
- ./netalertx/:/app/config/
|
||||
```
|
||||
|
||||
## 🏅 Recognitions
|
||||
|
||||
Big thanks to <a href="https://github.com/Macleykun">@Macleykun</a> & for help and tips & tricks for Dockerfile(s) and <a href="https://github.com/vladaurosh">@vladaurosh</a> for Alpine re-base help.
|
||||
|
||||
## ❤ Support me
|
||||
## 💙 Support me
|
||||
|
||||
| [](https://github.com/sponsors/jokob-sk) | [](https://www.buymeacoffee.com/jokobsk) | [](https://www.patreon.com/user?u=84385063) |
|
||||
| --- | --- | --- |
|
||||
@@ -244,4 +100,4 @@ Big thanks to <a href="https://github.com/Macleykun">@Macleykun</a> & for help a
|
||||
- Bitcoin: `1N8tupjeCK12qRVU2XrV17WvKK7LCawyZM`
|
||||
- Ethereum: `0x6e2749Cb42F4411bc98501406BdcD82244e3f9C7`
|
||||
|
||||
> 📧 Email me at [jokob@duck.com](mailto:jokob@duck.com?subject=NetAlertX) if you want to get in touch or if I should add other sponsorship platforms.
|
||||
> 📧 Email me at [netalertx@gmail.com](mailto:netalertx@gmail.com?subject=NetAlertX Donations) if you want to get in touch or if I should add other sponsorship platforms.
|
||||
|
||||
@@ -1,8 +1,36 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
echo "---------------------------------------------------------"
|
||||
echo "[INSTALL] Run setup.sh"
|
||||
echo "---------------------------------------------------------"
|
||||
echo "---------------------------------------------------------
|
||||
[INSTALL] Run init.sh
|
||||
---------------------------------------------------------"
|
||||
|
||||
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
|
||||
|
||||
@@ -55,7 +83,7 @@ else
|
||||
echo "Config file saved to ${INSTALL_DIR}/config/app_conf_override.json"
|
||||
fi
|
||||
|
||||
# 🔻 FOR BACKWARD COMPATIBILITY - REMOVE AFTER 12/12/2024
|
||||
# 🔻 FOR BACKWARD COMPATIBILITY - REMOVE AFTER 12/12/2025
|
||||
|
||||
# Check if pialert.db exists, then create a symbolic link to app.db
|
||||
if [ -f "${INSTALL_DIR_OLD}/db/${OLD_APP_NAME}.db" ]; then
|
||||
@@ -66,7 +94,7 @@ fi
|
||||
if [ -f "${INSTALL_DIR_OLD}/config/${OLD_APP_NAME}.conf" ]; then
|
||||
ln -s "${INSTALL_DIR_OLD}/config/${OLD_APP_NAME}.conf" "${INSTALL_DIR}/config/${CONF_FILE}"
|
||||
fi
|
||||
# 🔺 FOR BACKWARD COMPATIBILITY - REMOVE AFTER 12/12/2024
|
||||
# 🔺 FOR BACKWARD COMPATIBILITY - REMOVE AFTER 12/12/2025
|
||||
|
||||
# Copy starter .db and .conf if they don't exist
|
||||
cp -na "${INSTALL_DIR}/back/${CONF_FILE}" "${INSTALL_DIR}/config/${CONF_FILE}"
|
||||
@@ -83,6 +111,13 @@ if [ -n "${TZ}" ]; then
|
||||
echo $TZ > /etc/timezone
|
||||
fi
|
||||
|
||||
# if custom variables not set we do not need to do anything
|
||||
if [ -n "${LOADED_PLUGINS}" ]; then
|
||||
FILECONF="${INSTALL_DIR}/config/${CONF_FILE}"
|
||||
echo "[INSTALL] Setup custom LOADED_PLUGINS variable"
|
||||
sed -i "\#^LOADED_PLUGINS=#c\LOADED_PLUGINS=${LOADED_PLUGINS}" "${FILECONF}"
|
||||
fi
|
||||
|
||||
echo "[INSTALL] Setup NGINX"
|
||||
echo "Setting webserver to address ($LISTEN_ADDR) and port ($PORT)"
|
||||
envsubst '$INSTALL_DIR $LISTEN_ADDR $PORT' < "${INSTALL_DIR}/install/netalertx.template.conf" > "${NGINX_CONFIG_FILE}"
|
||||
@@ -108,10 +143,11 @@ fi
|
||||
# Create the execution_queue.log and app_front.log files if they don't exist
|
||||
touch "${INSTALL_DIR}"/log/{app.log,execution_queue.log,app_front.log,app.php_errors.log,stderr.log,stdout.log,db_is_locked.log}
|
||||
touch "${INSTALL_DIR}"/api/user_notifications.json
|
||||
# Create plugins sub-directory if it doesn't exist in case a custom log folder is used
|
||||
mkdir -p "${INSTALL_DIR}"/log/plugins
|
||||
|
||||
echo "[INSTALL] Fixing permissions after copied starter config & DB"
|
||||
chown -R nginx:www-data "${INSTALL_DIR}"/{config,log,db,api}
|
||||
chown -R nginx:www-data "${INSTALL_DIR}"/api/user_notifications.json
|
||||
chown -R nginx:www-data "${INSTALL_DIR}"
|
||||
|
||||
chmod 750 "${INSTALL_DIR}"/{config,log,db}
|
||||
find "${INSTALL_DIR}"/{config,log,db} -type f -exec chmod 640 {} \;
|
||||
@@ -123,10 +159,6 @@ if [ ! -f "${INSTALL_DIR}/front/buildtimestamp.txt" ]; then
|
||||
chown nginx:www-data "${INSTALL_DIR}/front/buildtimestamp.txt"
|
||||
fi
|
||||
|
||||
# Start crond service in the background
|
||||
echo "[INSTALL] Starting crond service..."
|
||||
crond -f -d 8 > /dev/null 2>&1 &
|
||||
|
||||
echo -e "
|
||||
[ENV] PATH is ${PATH}
|
||||
[ENV] PORT is ${PORT}
|
||||
@@ -13,13 +13,21 @@ sed -i "/^user/c\user = nginx" /etc/php83/php-fpm.d/www.conf
|
||||
sed -i "/^group/c\group = www-data" /etc/php83/php-fpm.d/www.conf
|
||||
|
||||
# s6 overlay setup
|
||||
mkdir -p /etc/s6-overlay/s6-rc.d/{SetupOneshot,php-fpm/dependencies.d,nginx/dependencies.d}
|
||||
mkdir -p /etc/s6-overlay/s6-rc.d/{SetupOneshot,php-fpm/dependencies.d,nginx/dependencies.d,$APP_NAME/dependencies.d}
|
||||
mkdir -p /etc/s6-overlay/s6-rc.d/{SetupOneshot,crond/dependencies.d,php-fpm/dependencies.d,nginx/dependencies.d,$APP_NAME/dependencies.d}
|
||||
echo "oneshot" > /etc/s6-overlay/s6-rc.d/SetupOneshot/type
|
||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/crond/type
|
||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/php-fpm/type
|
||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/nginx/type
|
||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/$APP_NAME/type
|
||||
echo -e "${INSTALL_DIR}/dockerfiles/setup.sh" > /etc/s6-overlay/s6-rc.d/SetupOneshot/up
|
||||
echo -e "${INSTALL_DIR}/dockerfiles/init.sh" > /etc/s6-overlay/s6-rc.d/SetupOneshot/up
|
||||
echo -e '#!/bin/execlineb -P
|
||||
|
||||
if { echo
|
||||
"
|
||||
[INSTALL] Starting crond service...
|
||||
|
||||
" }' > /etc/s6-overlay/s6-rc.d/crond/run
|
||||
echo -e "/usr/sbin/crond -f" >> /etc/s6-overlay/s6-rc.d/crond/run
|
||||
echo -e "#!/bin/execlineb -P\n/usr/sbin/php-fpm83 -F" > /etc/s6-overlay/s6-rc.d/php-fpm/run
|
||||
echo -e '#!/bin/execlineb -P\nnginx -g "daemon off;"' > /etc/s6-overlay/s6-rc.d/nginx/run
|
||||
echo -e '#!/bin/execlineb -P
|
||||
@@ -33,11 +41,9 @@ echo -e '#!/bin/execlineb -P
|
||||
|
||||
" }' > /etc/s6-overlay/s6-rc.d/$APP_NAME/run
|
||||
echo -e "python ${INSTALL_DIR}/server" >> /etc/s6-overlay/s6-rc.d/$APP_NAME/run
|
||||
touch /etc/s6-overlay/s6-rc.d/user/contents.d/{SetupOneshot,php-fpm,nginx} /etc/s6-overlay/s6-rc.d/{php-fpm,nginx}/dependencies.d/SetupOneshot
|
||||
touch /etc/s6-overlay/s6-rc.d/user/contents.d/{SetupOneshot,php-fpm,nginx,$APP_NAME} /etc/s6-overlay/s6-rc.d/{php-fpm,nginx,$APP_NAME}/dependencies.d/SetupOneshot
|
||||
touch /etc/s6-overlay/s6-rc.d/user/contents.d/{SetupOneshot,crond,php-fpm,nginx,$APP_NAME} /etc/s6-overlay/s6-rc.d/{crond,php-fpm,nginx,$APP_NAME}/dependencies.d/SetupOneshot
|
||||
touch /etc/s6-overlay/s6-rc.d/nginx/dependencies.d/php-fpm
|
||||
touch /etc/s6-overlay/s6-rc.d/$APP_NAME/dependencies.d/nginx
|
||||
|
||||
|
||||
|
||||
# this removes the current file
|
||||
rm -f $0
|
||||
176
docs/API.md
@@ -1,7 +1,134 @@
|
||||
## API endpoints
|
||||
# API endpoints
|
||||
|
||||
NetAlertX comes with a simple API. These API endpoints are static files, that are periodically updated based on your settings.
|
||||
NetAlertX comes with a couple of API endpoints. All requests need to be authorized (executed in a logged in browser session) or you have to pass the value of the `API_TOKEN` settings as authorization bearer, for example:
|
||||
|
||||
```graphql
|
||||
curl 'http://host:GRAPHQL_PORT/graphql' \
|
||||
-X POST \
|
||||
-H 'Authorization: Bearer API_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"query": "query GetDevices($options: PageQueryOptionsInput) { devices(options: $options) { devices { rowid devMac devName devOwner devType devVendor devLastConnection devStatus } count } }",
|
||||
"variables": {
|
||||
"options": {
|
||||
"page": 1,
|
||||
"limit": 10,
|
||||
"sort": [{ "field": "devName", "order": "asc" }],
|
||||
"search": "",
|
||||
"status": "connected"
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## API Endpoint: GraphQL
|
||||
|
||||
Endpoint URL: `php/server/query_graphql.php`
|
||||
Host: `same as front end (web ui)`
|
||||
Port: `20212` or as defined by the `GRAPHQL_PORT` setting
|
||||
|
||||
### Example Query to Fetch Devices
|
||||
|
||||
First, let's define the GraphQL query to fetch devices with pagination and sorting options.
|
||||
|
||||
```graphql
|
||||
query GetDevices($options: PageQueryOptionsInput) {
|
||||
devices(options: $options) {
|
||||
devices {
|
||||
rowid
|
||||
devMac
|
||||
devName
|
||||
devOwner
|
||||
devType
|
||||
devVendor
|
||||
devLastConnection
|
||||
devStatus
|
||||
}
|
||||
count
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `curl` Command
|
||||
|
||||
You can use the following `curl` command to execute the query.
|
||||
|
||||
```sh
|
||||
curl 'http://host:GRAPHQL_PORT/graphql' -X POST -H 'Authorization: Bearer API_TOKEN' -H 'Content-Type: application/json' --data '{
|
||||
"query": "query GetDevices($options: PageQueryOptionsInput) { devices(options: $options) { devices { rowid devMac devName devOwner devType devVendor devLastConnection devStatus } count } }",
|
||||
"variables": {
|
||||
"options": {
|
||||
"page": 1,
|
||||
"limit": 10,
|
||||
"sort": [{ "field": "devName", "order": "asc" }],
|
||||
"search": "",
|
||||
"status": "connected"
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Explanation:
|
||||
|
||||
1. **GraphQL Query**:
|
||||
- The `query` parameter contains the GraphQL query as a string.
|
||||
- The `variables` parameter contains the input variables for the query.
|
||||
|
||||
2. **Query Variables**:
|
||||
- `page`: Specifies the page number of results to fetch.
|
||||
- `limit`: Specifies the number of results per page.
|
||||
- `sort`: Specifies the sorting options, with `field` being the field to sort by and `order` being the sort order (`asc` for ascending or `desc` for descending).
|
||||
- `search`: A search term to filter the devices.
|
||||
- `status`: The status filter to apply (valid values are `my_devices` (determined by the `UI_MY_DEVICES` setting), `connected`, `favorites`, `new`, `down`, `archived`, `offline`).
|
||||
|
||||
3. **`curl` Command**:
|
||||
- The `-X POST` option specifies that we are making a POST request.
|
||||
- The `-H "Content-Type: application/json"` option sets the content type of the request to JSON.
|
||||
- The `-d` option provides the request payload, which includes the GraphQL query and variables.
|
||||
|
||||
### Sample Response
|
||||
|
||||
The response will be in JSON format, similar to the following:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"devices": {
|
||||
"devices": [
|
||||
{
|
||||
"rowid": 1,
|
||||
"devMac": "00:11:22:33:44:55",
|
||||
"devName": "Device 1",
|
||||
"devOwner": "Owner 1",
|
||||
"devType": "Type 1",
|
||||
"devVendor": "Vendor 1",
|
||||
"devLastConnection": "2025-01-01T00:00:00Z",
|
||||
"devStatus": "connected"
|
||||
},
|
||||
{
|
||||
"rowid": 2,
|
||||
"devMac": "66:77:88:99:AA:BB",
|
||||
"devName": "Device 2",
|
||||
"devOwner": "Owner 2",
|
||||
"devType": "Type 2",
|
||||
"devVendor": "Vendor 2",
|
||||
"devLastConnection": "2025-01-02T00:00:00Z",
|
||||
"devStatus": "connected"
|
||||
}
|
||||
],
|
||||
"count": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Endpoint: JSON files
|
||||
|
||||
This API endpoint retrieves static files, that are periodically updated.
|
||||
|
||||
Endpoint URL: `php/server/query_json.php?file=<file name>`
|
||||
Host: `same as front end (web ui)`
|
||||
Port: `20211` or as defined by the $PORT docker environment variable (same as the port for the web ui)
|
||||
|
||||
### When are the endpoints updated
|
||||
|
||||
@@ -9,7 +136,7 @@ The endpoints are updated when objects in the API endpoints are changed.
|
||||
|
||||
### Location of the endpoints
|
||||
|
||||
In the container, these files are located under the `/app/api/` folder. You can acces sthem via the `/php/server/query_json.php?file=user_notifications.json` endpoint.
|
||||
In the container, these files are located under the `/app/api/` folder. You can access them via the `/php/server/query_json.php?file=user_notifications.json` endpoint.
|
||||
|
||||
### Available endpoints
|
||||
|
||||
@@ -17,10 +144,8 @@ You can access the following files:
|
||||
|
||||
| File name | Description |
|
||||
|----------------------|----------------------|
|
||||
| `notification_text.txt` | The plain text version of the last notification. |
|
||||
| `notification_text.html` | The full HTML of the last email notification. |
|
||||
| `notification_json_final.json` | The json version of the last notification (e.g. used for webhooks - [sample JSON](https://github.com/jokob-sk/NetAlertX/blob/main/front/report_templates/webhook_json_sample.json)). |
|
||||
| `table_devices.json` | The current (at the time of the last update as mentioned above on this page) state of all of the available Devices detected by the app. |
|
||||
| `table_devices.json` | All of the available Devices detected by the app. |
|
||||
| `table_plugins_events.json` | The list of the unprocessed (pending) notification events (plugins_events DB table). |
|
||||
| `table_plugins_history.json` | The list of notification events history. |
|
||||
| `table_plugins_objects.json` | The content of the plugins_objects table. Find more info on the [Plugin system here](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins)|
|
||||
@@ -29,7 +154,6 @@ You can access the following files:
|
||||
| `table_settings.json` | The content of the settings table. |
|
||||
| `app_state.json` | Contains the current application state. |
|
||||
|
||||
Current/latest state of the aforementioned files depends on your settings.
|
||||
|
||||
### JSON Data format
|
||||
|
||||
@@ -95,3 +219,41 @@ Example JSON of the `table_devices.json` endpoint with two Devices (database row
|
||||
|
||||
```
|
||||
|
||||
## API Endpoint: /log files
|
||||
|
||||
This API endpoint retrieves files from the `/app/log` folder.
|
||||
|
||||
Endpoint URL: `php/server/query_logs.php?file=<file name>`
|
||||
Host: `same as front end (web ui)`
|
||||
Port: `20211` or as defined by the $PORT docker environment variable (same as the port for the web ui)
|
||||
|
||||
| File | Description |
|
||||
|--------------------------|---------------------------------------------------------------|
|
||||
| `IP_changes.log` | Logs of IP address changes |
|
||||
| `app.log` | Main application log |
|
||||
| `app.php_errors.log` | PHP error log |
|
||||
| `app_front.log` | Frontend application log |
|
||||
| `app_nmap.log` | Logs of Nmap scan results |
|
||||
| `db_is_locked.log` | Logs when the database is locked |
|
||||
| `execution_queue.log` | Logs of execution queue activities |
|
||||
| `plugins/` | Directory for temporary plugin-related files (not accessible) |
|
||||
| `report_output.html` | HTML report output |
|
||||
| `report_output.json` | JSON format report output |
|
||||
| `report_output.txt` | Text format report output |
|
||||
| `stderr.log` | Logs of standard error output |
|
||||
| `stdout.log` | Logs of standard output |
|
||||
|
||||
|
||||
## API Endpoint: /config files
|
||||
|
||||
To retrieve files from the `/app/config` folder.
|
||||
|
||||
Endpoint URL: `php/server/query_config.php?file=<file name>`
|
||||
Host: `same as front end (web ui)`
|
||||
Port: `20211` or as defined by the $PORT docker environment variable (same as the port for the web ui)
|
||||
|
||||
| File | Description |
|
||||
|--------------------------|--------------------------------------------------|
|
||||
| `devices.csv` | Devices csv file |
|
||||
| `app.conf` | Application config file |
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# 💾 Backing things up
|
||||
|
||||
> [!NOTE]
|
||||
> To backup 99% of your configuration backup at least the `/config` folder. Please read the whole page (or at least "Scenario 2: Corrupted database") for details.
|
||||
> To backup 99% of your configuration backup at least the `/app/config` folder. Please read the whole page (or at least "Scenario 2: Corrupted database") for details.
|
||||
> Please also note that database definitions might change over versions. The safest way is to restore your older backups into the **same version** of the app and then gradually upgarde between releases to the latest version.
|
||||
|
||||
There are 3 artifacts that can be used to backup the application:
|
||||
|
||||
@@ -22,16 +23,17 @@ The core application configuration is in the `app.conf` file (See [Settings Syst
|
||||
- Notification settings
|
||||
- Scanner settings
|
||||
- Scheduled maintenance settings
|
||||
- UI configuration (80%)
|
||||
- UI configuration
|
||||
|
||||
### Core Device Data
|
||||
|
||||
The core device data is backed up to the `devices_<timestamp>.csv` file via the [CSV Backup `CSVBCKP` Plugin](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/csv_backup). This file contains data, such as:
|
||||
The core device data is backed up to the `devices_<timestamp>.csv` or `devices.csv` file via the [CSV Backup `CSVBCKP` Plugin](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/csv_backup). This file contains data, such as:
|
||||
|
||||
- Device names
|
||||
- Device Icons
|
||||
- Device Network configuration
|
||||
- Device icons
|
||||
- Device network configuration
|
||||
- Device categorization
|
||||
- Device custom properties data
|
||||
|
||||
### Historical data
|
||||
|
||||
@@ -40,13 +42,15 @@ Historical data is stored in the `app.db` database (See [Database overview](http
|
||||
- Plugin objects
|
||||
- Plugin historical entries
|
||||
- History of Events, Notifications, Workflow Events
|
||||
- Presence History
|
||||
- Presence history
|
||||
|
||||
## 🧭 Backup strategies
|
||||
|
||||
The safest approach to backups is to backup all of the above, by taking regular file system backups (I use [Kopia](https://github.com/kopia/kopia)).
|
||||
|
||||
Arguably, the most time is spent setting up the device list, so if only one file is kept I'd recommend to have a latest backup of the `devices_<timestamp>.csv` file, followed by the `app.conf` file.
|
||||
Arguably, the most time is spent setting up the device list, so if only one file is kept I'd recommend to have a latest backup of the `devices_<timestamp>.csv` or `devices.csv` file, followed by the `app.conf` file. You can also download `app.conf` and `devices.csv` file in the Maintenance section:
|
||||
|
||||

|
||||
|
||||
### Scenario 1: Full backup
|
||||
|
||||
@@ -54,8 +58,8 @@ End-result: Full restore
|
||||
|
||||
#### Source artifacts:
|
||||
|
||||
- `/db/app.db` (uncorrupted)
|
||||
- `/config/app.conf`
|
||||
- `/app/db/app.db` (uncorrupted)
|
||||
- `/app/config/app.conf`
|
||||
|
||||
#### Recovery:
|
||||
|
||||
@@ -68,15 +72,15 @@ End-result: Partial restore (historical data & configurations from the Maintenan
|
||||
|
||||
#### Source artifacts:
|
||||
|
||||
- `/config/app.conf`
|
||||
- `/config/devices_<timestamp>.csv` or `/config/devices.csv`
|
||||
- `/app/config/app.conf`
|
||||
- `/app/config/devices_<timestamp>.csv` or `/app/config/devices.csv`
|
||||
|
||||
#### Recovery:
|
||||
|
||||
Even with a corrupted database you can recover what I would argue is 99% of the configuration.
|
||||
|
||||
- map the `/config/app.conf` file as described in the [Setup documentation](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md#docker-paths).
|
||||
- rename the `devices_<timestamp>.csv` to `devices.csv` and place it in the `/config` folder
|
||||
- upload the `app.conf` file into the mounted `/app/config/` folder as described in the [Setup documentation](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md#docker-paths).
|
||||
- rename the `devices_<timestamp>.csv` to `devices.csv` and place it in the `/app/config` folder
|
||||
- Restore the `devices.csv` backup via the [Maintenance section](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md)
|
||||
|
||||
|
||||
|
||||
14
docs/COMMUNITY_GUIDES.md
Executable file
@@ -0,0 +1,14 @@
|
||||
# Community Guides
|
||||
|
||||
Use the official installation guides at first and use community content as supplementary material. Open an issue or PR if you'd like to add your link to the list 🙏 (Ordered by last update time)
|
||||
|
||||
- ▶ [Home Lab Network Monitoring - Scotti-BYTE Enterprise Consulting Services](https://www.youtube.com/watch?v=0DryhzrQSJA) (July 2024)
|
||||
- 📄 [How to Install NetAlertX on Your Synology NAS - Marius hosting](https://mariushosting.com/how-to-install-pi-alert-on-your-synology-nas/) (Updated frequently)
|
||||
- 📄 [Using the PiAlert Network Security Scanner on a Raspberry Pi - PiMyLifeUp](https://pimylifeup.com/raspberry-pi-pialert/)
|
||||
- ▶ [How to Setup Pi.Alert on Your Synology NAS - Digital Aloha](https://www.youtube.com/watch?v=M4YhpuRFaUg)
|
||||
- 📄 [防蹭网神器,网络安全助手 | 极空间部署网络扫描和通知系统『NetAlertX』](https://blog.csdn.net/qq_63499861/article/details/141105273)
|
||||
- 📄 [시놀/헤놀에서 네트워크 스캐너 Pi.Alert Docker로 설치 및 사용하기](https://blog.dalso.org/article/%EC%8B%9C%EB%86%80-%ED%97%A4%EB%86%80%EC%97%90%EC%84%9C-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%8A%A4%EC%BA%90%EB%84%88-pi-alert-docker%EB%A1%9C-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9) (July 2023)
|
||||
- 📄 [网络入侵探测器Pi.Alert (Chinese)](https://codeantenna.com/a/VgUvIAjZ7J) (May 2023)
|
||||
- ▶ [Pi.Alert auf Synology & Docker by - Jürgen Barth](https://www.youtube.com/watch?v=-ouvA2UNu-A) (March 2023)
|
||||
- ▶ [Top Docker Container for Home Server Security - VirtualizationHowto](https://www.youtube.com/watch?v=tY-w-enLF6Q) (March 2023)
|
||||
- ▶ [Pi.Alert or WatchYourLAN can alert you to unknown devices appearing on your WiFi or LAN network - Danie van der Merwe](https://www.youtube.com/watch?v=v6an9QG2xF0) (November 2022)
|
||||
85
docs/CUSTOM_PROPERTIES.md
Executable file
@@ -0,0 +1,85 @@
|
||||
# Custom Properties for Devices
|
||||
|
||||

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

|
||||
|
||||
Visible properties (`CUSTPROP_show: true`) are displayed as interactive icons in the device listing. Each icon can perform one of the following actions based on the `CUSTPROP_type`:
|
||||
|
||||
1. **Modals (e.g., Show Notes)**:
|
||||
- Displays detailed information in a popup modal.
|
||||
- Example: Firmware version details.
|
||||
|
||||
2. **Links**:
|
||||
- Redirect to an external or internal URL.
|
||||
- Example: Open a device's documentation or external site.
|
||||
|
||||
3. **Device Actions**:
|
||||
- Manage devices with actions like delete.
|
||||
- Example: Quickly remove a device from the network.
|
||||
|
||||
4. **Plugins**:
|
||||
- Future placeholder for running custom plugin scripts.
|
||||
- **Note**: Not implemented yet.
|
||||
|
||||
---
|
||||
|
||||
## Example Scenarios
|
||||
|
||||
1. **Device Documentation Link**:
|
||||
- Add a custom property with `CUSTPROP_type` set to `link` or `link_new_tab` to allow quick navigation to the documentation.
|
||||
|
||||
2. **Firmware Details**:
|
||||
- Use `CUSTPROP_type: show_notes` to display firmware versions or upgrade instructions in a modal.
|
||||
|
||||
3. **Device Removal**:
|
||||
- Enable device removal functionality using `CUSTPROP_type: delete_dev`.
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- **Plugin Functionality**: The `run_plugin` action type is currently not implemented and will show an alert if used.
|
||||
- **Custom Icons (Experimental 🧪)**: Use Base64-encoded HTML to provide custom icons for each property. You can add your icons in Setttings via the `CUSTPROP_icon` settings
|
||||
- **Visibility Control**: Only properties with `CUSTPROP_show: true` will appear on the listing page.
|
||||
|
||||
This feature provides a flexible way to enhance device management and display with interactive elements tailored to your needs.
|
||||
@@ -74,7 +74,7 @@ Sometimes specific log sections are needed to debug issues. The Devices and Curr
|
||||
|
||||
### unable to resolve host
|
||||
|
||||
* Check that your `SCAN_SUBNETS` variable is using the correct mask and `--interface` as outlined in the instructions above.
|
||||
* Check that your `SCAN_SUBNETS` variable is using the correct mask and `--interface`. See teh [subnets docs for details](/docs/SUBNETS.md).
|
||||
|
||||
### Invalid JSON
|
||||
|
||||
@@ -95,4 +95,4 @@ The link above will probably break in time too. Go to https://packages.debian.or
|
||||
|
||||
### Only Router and own device show up
|
||||
|
||||
Make sure that the subnet and interface in SCAN_SUBNETS are the correct ones. If your device/NAS has multiple ethernet ports, you probably need to change eth0 to something else!
|
||||
Make sure that the subnet and interface in `SCAN_SUBNETS` are correct. If your device/NAS has multiple ethernet ports, you probably need to change `eth0` to something else.
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
The Main Info section is where most of the device identifiable information is stored and edited. Some of the information is autodetected via various plugins. Initial values for most of the fields can be specified in the `NEWDEV` plugin.
|
||||
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> You can multi-edit devices by selecting them in the main Devices view, from the Mainetence section, or via the CSV Export functionality under Maintenance. More info can be found in the [Devices Bulk-editing docs](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md).
|
||||
@@ -10,12 +9,11 @@ The Main Info section is where most of the device identifiable information is st
|
||||
|
||||

|
||||
|
||||
|
||||
## Main Info
|
||||
|
||||
- **MAC**: MAC addres of the device. Not editable, unless creating a new dummy device.
|
||||
- **Last IP**: IP addres of the device. Not editable, unless creating a new dummy device.
|
||||
- **Name**: Friendly device name. Autodetected via various 🆎 Name discovery [plugins](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md).
|
||||
- **Name**: Friendly device name. Autodetected via various 🆎 Name discovery [plugins](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md). The app attaches `(IP match)` if the name is discovered via an IP match and not MAC match which could mean the name could be incorrect as IPs might change.
|
||||
- **Icon**: Partially autodetected. Select an existing or [add a custom icon](https://github.com/jokob-sk/NetAlertX/blob/main/docs/ICONS.md). You can also auto-apply the same icon on all devices of the same type.
|
||||
- **Owner**: Device owner (The list is self-populated with existing owners and you can add custom values).
|
||||
- **Type**: Select a device type from the dropdown list (`Smartphone`, `Tablet`,
|
||||
|
||||
101
docs/DOCKER_COMPOSE.md
Executable file
@@ -0,0 +1,101 @@
|
||||
# `docker-compose.yaml` Examples
|
||||
|
||||
### Example 1
|
||||
|
||||
```yaml
|
||||
services:
|
||||
netalertx:
|
||||
container_name: netalertx
|
||||
# use the below line if you want to test the latest dev image
|
||||
# image: "jokobsk/netalertx-dev:latest"
|
||||
image: "jokobsk/netalertx:latest"
|
||||
network_mode: "host"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- local_path/config:/app/config
|
||||
- local_path/db:/app/db
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
- local_path/logs:/app/log
|
||||
# (API: OPTION 1) use for performance
|
||||
- type: tmpfs
|
||||
target: /app/api
|
||||
# (API: OPTION 2) use when debugging issues
|
||||
# - local_path/api:/app/api
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
```
|
||||
|
||||
To run the container execute: `sudo docker-compose up -d`
|
||||
|
||||
### Example 2
|
||||
|
||||
Example by [SeimuS](https://github.com/SeimusS).
|
||||
|
||||
```yaml
|
||||
netalertx:
|
||||
container_name: NetAlertX
|
||||
hostname: NetAlertX
|
||||
privileged: true
|
||||
# use the below line if you want to test the latest dev image
|
||||
# image: "jokobsk/netalertx-dev:latest"
|
||||
image: jokobsk/netalertx:latest
|
||||
environment:
|
||||
- TZ=Europe/Bratislava
|
||||
restart: always
|
||||
volumes:
|
||||
- ./netalertx/db:/app/db
|
||||
- ./netalertx/config:/app/config
|
||||
network_mode: host
|
||||
```
|
||||
|
||||
To run the container execute: `sudo docker-compose up -d`
|
||||
|
||||
### Example 3
|
||||
|
||||
`docker-compose.yml`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
netalertx:
|
||||
container_name: netalertx
|
||||
# use the below line if you want to test the latest dev image
|
||||
# image: "jokobsk/netalertx-dev:latest"
|
||||
image: "jokobsk/netalertx:latest"
|
||||
network_mode: "host"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ${APP_DATA_LOCATION}/netalertx/config:/app/config
|
||||
- ${APP_DATA_LOCATION}/netalertx/db/:/app/db/
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
- ${LOGS_LOCATION}:/app/log
|
||||
# (API: OPTION 1) use for performance
|
||||
- type: tmpfs
|
||||
target: /app/api
|
||||
# (API: OPTION 2) use when debugging issues
|
||||
# - local/path/api:/app/api
|
||||
environment:
|
||||
- TZ=${TZ}
|
||||
- PORT=${PORT}
|
||||
```
|
||||
|
||||
`.env` file
|
||||
|
||||
```yaml
|
||||
#GLOBAL PATH VARIABLES
|
||||
|
||||
APP_DATA_LOCATION=/path/to/docker_appdata
|
||||
APP_CONFIG_LOCATION=/path/to/docker_config
|
||||
LOGS_LOCATION=/path/to/docker_logs
|
||||
|
||||
#ENVIRONMENT VARIABLES
|
||||
|
||||
TZ=Europe/Paris
|
||||
PORT=20211
|
||||
|
||||
#DEVELOPMENT VARIABLES
|
||||
|
||||
DEV_LOCATION=/path/to/local/source/code
|
||||
```
|
||||
|
||||
To run the container execute: `sudo docker-compose --env-file /path/to/.env up`
|
||||
@@ -5,37 +5,19 @@
|
||||
> ```
|
||||
> docker run -d --rm --network=host \
|
||||
> -e TZ=Europe/Berlin \
|
||||
> -e PUID=200 -e PGID=200 \
|
||||
> -e PORT=20211 \
|
||||
> 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
|
||||
|
||||
| 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/db` | nginx | 101 | www-data | 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.
|
||||
| `/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 | PUID (default 102) | www-data | PGID (default 82) | rwxr-xr-x | Same as above |
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
NetAlertX comes with MQTT support, allowing you to show all detected devices as devices in Home Assistant. It also supplies a collection of stats, such as number of online devices.
|
||||
|
||||
> [!TIP]
|
||||
> You can install NetAlertX also as a Home Assistant addon [](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Falexbelgium%2Fhassio-addons) via the [alexbelgium/hassio-addons](https://github.com/alexbelgium/hassio-addons/).
|
||||
|
||||
## ⚠ Note
|
||||
|
||||
- Please note that discovery takes about ~10s per device.
|
||||
|
||||
@@ -5,7 +5,7 @@ To download and install NetAlertX on the hardware/server directly use the `curl`
|
||||
> [!NOTE]
|
||||
> This is an Experimental feature 🧪 and it relies on community support.
|
||||
>
|
||||
> Looking for maintainers for this installation method 🙂
|
||||
> 🙏 Looking for maintainers for this installation method 🙂
|
||||
>
|
||||
> There is no guarantee that the install script or any other script will gracefully handle other installed software.
|
||||
> Data loss is a possibility, **it is recommended to install NetAlertX using the supplied Docker image**.
|
||||
@@ -36,6 +36,9 @@ Some facts about what and where something will be changed/installed by the HW in
|
||||
|
||||
## 📥 Installation via CURL
|
||||
|
||||
> [!TIP]
|
||||
> If the below fails try grabbing and installing one of the [previous releases](https://github.com/jokob-sk/NetAlertX/releases) and run the installation from the zip package.
|
||||
|
||||
```bash
|
||||
curl -o install.debian.sh https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/install/install.debian.sh && sudo chmod +x install.debian.sh && sudo ./install.debian.sh
|
||||
```
|
||||
|
||||
@@ -38,7 +38,7 @@ Copying the HTML code from [Font Awesome](https://fontawesome.com/search?o=r&m=f
|
||||
> [!NOTE]
|
||||
> If you want to mass-apply an icon to all devices of the same device type (Field: Type), you can click the mass-copy button (next to the "+" button). A confirmation prompt is displayed. If you proceed, icons of all devices set to the same device type as the current device, will be overwritten with the current device's icon.
|
||||
|
||||
- The blue dropdown contains all icons already used in the app for device icons. You need to navigate away or refresh the page once you add a new icon.
|
||||
- The dropdown contains all icons already used in the app for device icons. You might need to navigate away or refresh the page once you add a new icon.
|
||||
|
||||
## 🌟 Pro Font Awesome icons
|
||||
|
||||
|
||||
45
docs/PIHOLE_GUIDE.md
Executable file
@@ -0,0 +1,45 @@
|
||||
# Integration with PiHole
|
||||
|
||||
NetAlertX comes with 2 plugins suitable for integarting with your existing PiHole instace. One plugin is using a direct SQLite DB connection, the other leverages the DHCP.leases file generated by PiHole. You can combine both approaches and also supplement it with other [plugins](/front/plugins/README.md).
|
||||
|
||||
## Approach 1: `DHCPLSS` Plugin - Import devices from the PiHole DHCP leases file
|
||||
|
||||

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

|
||||
|
||||
| Setting | Description | Recommended value |
|
||||
| :------------- | :------------- | :-------------|
|
||||
| `PIHOLE_RUN` | When the plugin should run. | `schedule` |
|
||||
| `PIHOLE_RUN_SCHD` | If you run multiple device scanner plugins, align the schedules of all plugins to the same value. | `*/5 * * * *` |
|
||||
| `PIHOLE_DB_PATH` | You need to map the value in this setting in the `docker-compose.yml` file. | `/etc/pihole/pihole-FTL.db` |
|
||||
|
||||
Check the [PiHole plugin readme](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/pihole_scan) for details
|
||||
|
||||
### docker-compose changes
|
||||
|
||||
| Path | Description |
|
||||
| :------------- | :------------- |
|
||||
| `:/etc/pihole/pihole-FTL.db` | PiHole's `pihole-FTL.db` database file. |
|
||||
|
||||
|
||||
Check out other [plugins](/front/plugins/README.md) that can help you discover more about your network or check how to scan [Remote networks](/docs/REMOTE_NETWORKS.md).
|
||||
@@ -12,6 +12,9 @@ NetAlertX comes with a plugin system to feed events from third-party scripts int
|
||||
|
||||
### 🎥 Watch the video:
|
||||
|
||||
> [!TIP]
|
||||
> Read this guide [Development environment setup guide](/docs/DEV_ENV_SETUP.md) to set up your local environment for development. 👩💻
|
||||
|
||||
[](https://youtu.be/cdbxlwiWhv8)
|
||||
|
||||
### 📸 Screenshots
|
||||
@@ -123,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`.
|
||||
|
||||
> [!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.
|
||||
|
||||
@@ -575,7 +578,7 @@ Each element may also have associated events (e.g., running a scan or triggering
|
||||
|
||||
##### 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 |
|
||||
| ------- | ----------- |
|
||||
@@ -657,7 +660,7 @@ The UI will adjust how columns are displayed in the UI based on the resolvers de
|
||||
| Type Definitions | |
|
||||
| `device_mac` | The value is considered to be a MAC address, and a link pointing to the device with the given MAC address is generated. |
|
||||
| `device_ip` | The value is considered to be an IP address. A link pointing to the device with the given IP is generated. The IP is checked against the last detected IP address and translated into a MAC address, which is then used for the link itself. |
|
||||
| `device_name_mac` | The value is considered to be a MAC address, and a link pointing to the device with the given IP is generated. The link label is resolved as the target device name. |
|
||||
| `device_name_mac` | The value is considered to be a MAC address, and a link pointing to the device with the given MAC is generated. The link label is resolved as the target device name. |
|
||||
| `url` | The value is considered to be a URL, so a link is generated. |
|
||||
| `textbox_save` | Generates an editable and saveable text box that saves values in the database. Primarily intended for the `UserData` database column in the `Plugins_Objects` table. |
|
||||
| `url_http_https` | Generates two links with the `https` and `http` prefix as lock icons. |
|
||||
|
||||
@@ -44,6 +44,6 @@ To create truly dummy devices, you can use a loopback IP address (e.g., `0.0.0.0
|
||||
|
||||
## NMAP and Fake MAC Addresses
|
||||
|
||||
Scanning remote networks with NMAP is possible (vai the `NMAPDEV` plugin), but since it cannot retrieve the MAC address, you need to enable the `NMAPDEV_FAKE_MAC` setting. This will generate a fake MAC address based on the IP address, allowing you to track devices. However, this can lead to inconsistencies, especially if the IP address changes or a previously logged device is rediscovered. If this setting is disabled, only the IP address will be discovered, and devices with missing MAC addresses will be skipped.
|
||||
Scanning remote networks with NMAP is possible (via the `NMAPDEV` plugin), but since it cannot retrieve the MAC address, you need to enable the `NMAPDEV_FAKE_MAC` setting. This will generate a fake MAC address based on the IP address, allowing you to track devices. However, this can lead to inconsistencies, especially if the IP address changes or a previously logged device is rediscovered. If this setting is disabled, only the IP address will be discovered, and devices with missing MAC addresses will be skipped.
|
||||
|
||||
Check the [NMAPDEV plugin](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/nmap_dev_scan) for details
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
You need to specify the network interface and the network mask. You can also configure multiple subnets and specify VLANs (see VLAN exceptions below).
|
||||
|
||||
`ARPSCAN` can scan multiple networks if the network allows it. To scan networks directly, the subnets must be accessible from the network where NetAlertX is running. This means NetAlertX needs to have access to the interface attached to that subnet. You can verify this by running the following command in the container:
|
||||
`ARPSCAN` can scan multiple networks if the network allows it. To scan networks directly, the subnets must be accessible from the network where NetAlertX is running. This means NetAlertX needs to have access to the interface attached to that subnet. You can verify this by running the following command in the container (replace the interface and ip mask):
|
||||
|
||||
`sudo arp-scan --interface=eth0 192.168.1.0/24`
|
||||
|
||||
@@ -22,7 +22,7 @@ If direct scans are not possible (Wi-Fi Extenders, VPNs and inaccessible network
|
||||
|
||||
* **Examples for one and two subnets:**
|
||||
* One subnet: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0']`
|
||||
* Two subnets: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0','192.168.1.0/24 --interface=eth1 -vlan=107']`
|
||||
* Two subnets: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0','192.168.1.0/24 --interface=eth1 --vlan=107']`
|
||||
|
||||
If you get timeout messages, decrease the network mask (e.g.: from `/16` to `/24`) or increase the `TIMEOUT` setting (e.g.: `ARPSCAN_RUN_TIMEOUT` to `300` (5-minute timeout)) for the plugin and the interval between scans (e.g.: `ARPSCAN_RUN_SCHD` to `*/10 * * * *` (scans every 10 minutes)).
|
||||
|
||||
@@ -45,18 +45,24 @@ Specify the network filter, which **significantly** speeds up the scan process.
|
||||
|
||||
**Example value:** `--interface=eth0`
|
||||
|
||||
The adapter will probably be `eth0` or `eth1`. (Check `System Info` > `Network Hardware` or run `iwconfig` in the container to find your interface name(s)).
|
||||
The adapter will probably be `eth0` or `eth1`. (Check `System Info` > `Network Hardware`, or run `iwconfig` in the container to find your interface name(s)).
|
||||
|
||||

|
||||
|
||||
> [!TIP]
|
||||
> As an alternative to `iwconfig`, run `ip -o link show | awk -F': ' '!/lo|vir|docker/ {print $2}'` in your container to find your interface name(s) (e.g.: `eth0`, `eth1`).
|
||||
> As an alternative to `iwconfig`, run `ip -o link show | awk -F': ' '!/lo|vir|docker/ {print $2}'` in your container to find your interface name(s) (e.g.: `eth0`, `eth1`):
|
||||
> ```bash
|
||||
> Synology-NAS:/# ip -o link show | awk -F': ' '!/lo|vir|docker/ {print $2}'
|
||||
> sit0@NONE
|
||||
> eth1
|
||||
> eth0
|
||||
> ```
|
||||
|
||||
### VLANs
|
||||
|
||||
**Example value:** `-vlan=107`
|
||||
**Example value:** `--vlan=107`
|
||||
|
||||
- Append `-vlan=107` to the interface field (e.g.: `eth0 -vlan=107`) for multiple VLANs. More details are available in this [comment](https://github.com/jokob-sk/NetAlertX/issues/170#issuecomment-1419902988).
|
||||
- Append `--vlan=107` to the `SCAN_SUBNETS` field (e.g.: `192.168.1.0/24 --interface=vmbr0 --vlan=107`) for multiple VLANs.
|
||||
|
||||
#### VLANs on a Hyper-V Setup
|
||||
|
||||
@@ -83,7 +89,6 @@ By default, Hyper-V only allows untagged packets through to the VM interface, bl
|
||||
2. Within the VM, set up sub-interfaces for each VLAN to enable scanning. On Ubuntu 22.04, Netplan can be used. In /etc/netplan/00-installer-config.yaml, add VLAN definitions:
|
||||
|
||||
```yaml
|
||||
|
||||
network:
|
||||
ethernets:
|
||||
eth0:
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
# Pi.Alert Version History
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
|
||||
| Version | Description |
|
||||
| ------- | --------------------------------------------------------------- |
|
||||
| v3.00 | Major set of New features & Enhancements |
|
||||
| v2.70 | New features & Usability improvements in the web prontal |
|
||||
| v2.61 | Bug fixing |
|
||||
| v2.60 | Improved the compability of installation process (Ubuntu) |
|
||||
| v2.56 | Bug fixing |
|
||||
| v2.55 | Bug fixing |
|
||||
| v2.52 | Bug fixing |
|
||||
| v2.51 | Bug fixing |
|
||||
| v2.50 | First public release |
|
||||
|
||||
|
||||
# 🆕 2022+ [Newest Release notes](https://github.com/jokob-sk/NetAlertX/issues/138)
|
||||
|
||||
## Pi.Alert v3.02
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
**PENDING UPDATE DOC**
|
||||
- Fixed: UNIQUE constraint failed with Local MAC #114
|
||||
|
||||
|
||||
## Pi.Alert v3.01
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
**PENDING UPDATE DOC**
|
||||
- Fixed: Problem with local MAC & IP (raspberry) #106
|
||||
|
||||
|
||||
## Pi.Alert v3.00
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
**PENDING UPDATE DOC**
|
||||
- `arp-scan` config options: interface, several subnets. #101 #15
|
||||
- Next/previos button while editing devices #66 #37
|
||||
- Internet presence/sessions monitoring #63
|
||||
- Logical delete / archive / hide Device #93
|
||||
- Flag to mark device with random MAC's #87
|
||||
- New Device Types predefined in combobox #92
|
||||
- Ask before leave the page with unsaved changes #104
|
||||
- Option to don't mark devices as new during installation #94
|
||||
- Uninstall script #62
|
||||
- Fixed: Error updating name of devices w/o IP #97
|
||||
- Fixed: Deleted devices reappear #84
|
||||
- Fixed: Device running Pi.Alert must be marked as "on-line" #76
|
||||
- Fixed: Incorrect calculation of presence hours #102
|
||||
- Fixed: Problem redirect to homepage clicking in logo #103
|
||||
|
||||
|
||||
## Pi.Alert v2.70
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
- Added Client names resolution #43
|
||||
- Added Check to mark devices as "known" #16
|
||||
- Remember "Show XXX entries" dropdown value #16 #26
|
||||
- Remember "sorting" in devices #16
|
||||
- Remember "Device panel " in device detail #16
|
||||
- Added "All" option to "Show x Entries" option #16
|
||||
- Added optional Location field (Door, Basement, etc.) to devices #16
|
||||
- "Device updated successfully" message now is not modal #16
|
||||
- Now is possible to delete Devices #16
|
||||
- Added Device Type Singleboard Computer (SBC) #16
|
||||
- Allowed to use " in device name #42
|
||||
|
||||
|
||||
## Pi.Alert v2.60
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
- `pialert.conf` moved from `back` to `config` folder
|
||||
- `pialert.conf` splitted in two files: `pialert.conf` and `version.conf`
|
||||
- Added compatibility with Python 3 (default version installed with Ubuntu)
|
||||
- Added compatibility in the Installation guide with Ubuntu server
|
||||
- Eliminated some unnecessary packages from the installation
|
||||
|
||||
|
||||
|
||||
### License
|
||||
GPL 3.0
|
||||
[Read more here](../LICENSE.txt)
|
||||
|
||||
### Contact
|
||||
Always use the Issue tracker for the correct fork, for example:
|
||||
|
||||
[jokob-sk/NetAlertX](https://github.com/jokob-sk/NetAlertX/issues). Please also follow the guidelines on:
|
||||
|
||||
- ➕ [Pull Request guidelines](https://github.com/jokob-sk/NetAlertX/tree/main/docs#-pull-requests-prs)
|
||||
- 🙏 [Feature request guidelines](https://github.com/jokob-sk/NetAlertX/tree/main/docs#-feature-requests)
|
||||
- 🐛 [Issue guidelines](https://github.com/jokob-sk/NetAlertX/tree/main/docs#-submitting-an-issue-or-bug)
|
||||
|
||||
BIN
docs/img/BACKUPS/Maintenance_Backup_Restore.png
Executable file
|
After Width: | Height: | Size: 88 KiB |
BIN
docs/img/CUSTOM_PROPERTIES/Device_Custom_Properties.png
Executable file
|
After Width: | Height: | Size: 39 KiB |
BIN
docs/img/CUSTOM_PROPERTIES/Device_Custom_Properties_vid.gif
Executable file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
docs/img/PIHOLE_GUIDE/DHCPLSS_pihole_settings.png
Executable file
|
After Width: | Height: | Size: 99 KiB |
BIN
docs/img/PIHOLE_GUIDE/PIHOLE_settings.png
Executable file
|
After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 18 KiB |
BIN
docs/img/showcase.gif
Executable file
|
After Width: | Height: | Size: 5.1 MiB |
10
front/.well-known/gpc.json
Executable file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"gpc": true,
|
||||
"compliance": [
|
||||
{
|
||||
"regulation": "GDPR",
|
||||
"status": "not applicable"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -287,11 +287,6 @@ body
|
||||
margin-left: 150px;
|
||||
}
|
||||
|
||||
#settingsPage
|
||||
{
|
||||
display: grid;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.main-header .logo {
|
||||
@@ -620,7 +615,7 @@ body
|
||||
|
||||
.modal_red
|
||||
{
|
||||
color: rgb(245, 245, 245);
|
||||
color: #d41001;
|
||||
background-color: #e2acaa;
|
||||
border-color: #d41001;
|
||||
}
|
||||
@@ -893,6 +888,34 @@ height: 50px;
|
||||
} */
|
||||
}
|
||||
|
||||
/* Hide unusable buttons on the settings page for the NEWDEV plugin*/
|
||||
#settingsPage #add_option_NEWDEV_devGroup,
|
||||
#settingsPage #add_option_NEWDEV_devLocation,
|
||||
#settingsPage #add_option_NEWDEV_devOwner,
|
||||
#settingsPage #copy_icons_NEWDEV_devIcon,
|
||||
#settingsPage #add_icon_NEWDEV_devIcon,
|
||||
#settingsPage #add_option_NEWDEV_devSite,
|
||||
#settingsPage #add_option_NEWDEV_devType
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#settingsPage
|
||||
{
|
||||
display: grid;
|
||||
}
|
||||
|
||||
|
||||
#settingsPage .small-box .inner .card-title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
.settingswrap
|
||||
{
|
||||
margin-bottom: 100px;
|
||||
@@ -926,16 +949,6 @@ height: 50px;
|
||||
top:0px;
|
||||
}
|
||||
|
||||
.overview-section
|
||||
{
|
||||
/* border-top: solid;
|
||||
border-width: medium;
|
||||
border-width: medium;
|
||||
border-width: 1px;
|
||||
border-radius: 15px;
|
||||
margin-bottom: 3px; */
|
||||
|
||||
}
|
||||
|
||||
.settings-group i{
|
||||
font-size: 16px;
|
||||
@@ -1232,6 +1245,24 @@ input[readonly] {
|
||||
/* Devices page */
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
|
||||
#columnFilters {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px; /* Add spacing between items */
|
||||
}
|
||||
|
||||
.filter-group {
|
||||
box-sizing: border-box; /* Ensure padding and borders are included in the width */
|
||||
padding: 1em;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.filter-dropdown
|
||||
{
|
||||
width:7em
|
||||
}
|
||||
|
||||
.modal-header .close
|
||||
{
|
||||
display: flex;
|
||||
@@ -1287,6 +1318,11 @@ input[readonly] {
|
||||
min-width: 40px;
|
||||
}
|
||||
|
||||
.iconPreview svg{
|
||||
min-width: 20px;
|
||||
max-width: 20px;
|
||||
}
|
||||
|
||||
|
||||
.dummyDevice
|
||||
{
|
||||
@@ -1313,8 +1349,8 @@ input[readonly] {
|
||||
top: -6px;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
left: 0px;
|
||||
font-size: large;
|
||||
left: 4px;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.drag
|
||||
@@ -1379,12 +1415,90 @@ input[readonly] {
|
||||
{
|
||||
display: none;
|
||||
padding-top: 2em;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* Device details */
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
.dataTables_length label .form-control, .dataTables_filter label .form-control
|
||||
{
|
||||
float: none;
|
||||
}
|
||||
|
||||
|
||||
.form-inline .input-group
|
||||
{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.input-group .actionIcon
|
||||
{
|
||||
height: 2.4em;
|
||||
}
|
||||
|
||||
.input-group .actionIcon:hover
|
||||
{
|
||||
backdrop-filter: brightness(50%);
|
||||
background-color: rgba(0, 0, 0, 0.2); /* darkens the background */
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
transition: box-shadow 0.1s ease-in-out, background-color 0.1s ease-in-out;
|
||||
}
|
||||
|
||||
.devicePropAction
|
||||
{
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
display: inline-block;
|
||||
padding: 0.1em;
|
||||
margin: 0.1em;
|
||||
/* transition: font-size 0.3s;*/
|
||||
}
|
||||
|
||||
.devicePropAction:hover
|
||||
{
|
||||
font-size: larger;
|
||||
padding: 0em;
|
||||
margin: 0em;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#panDetails .dataTables_wrapper .bottom div
|
||||
{
|
||||
max-width: 34%;
|
||||
display: block;
|
||||
float:inline-end;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
#panDetails .dataTables_wrapper .bottom .dataTables_info
|
||||
{
|
||||
float:inline-start;
|
||||
}
|
||||
|
||||
#panDetails .dataTables_wrapper .bottom .dataTables_length
|
||||
{
|
||||
padding: 0.3em;
|
||||
}
|
||||
/* #panDetails .dataTables_wrapper .bottom .paging_simple_numbers */
|
||||
|
||||
#panDetails #NEWDEV_devIcon
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#panDetails #NEWDEV_devCustomProps_label
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* MODAL popups */
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
#modal-input-textarea
|
||||
{
|
||||
width: 100%;
|
||||
@@ -1415,6 +1529,14 @@ input[readonly] {
|
||||
flex-direction:column;
|
||||
justify-content:center;
|
||||
}
|
||||
.networkHelpIcon
|
||||
{
|
||||
padding: 5px;
|
||||
margin-left: 5px;
|
||||
top: 55px;
|
||||
position: absolute;
|
||||
z-index:5;
|
||||
}
|
||||
#networkTree .netNodeText
|
||||
{
|
||||
position: absolute;
|
||||
@@ -1475,7 +1597,7 @@ input[readonly] {
|
||||
|
||||
.spanNetworkTree {
|
||||
display: inline-block;
|
||||
width: 120px;
|
||||
width: 135px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden !important;
|
||||
text-overflow: ellipsis;
|
||||
@@ -1521,6 +1643,24 @@ input[readonly] {
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
.dev-detail-tab-name
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* EVENTS page */
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
.eventsPeriodSelectWrap{
|
||||
display: inline;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.eventsPage #tableEventsTitle
|
||||
{
|
||||
float: left ;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
@@ -1528,6 +1668,7 @@ input[readonly] {
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
|
||||
|
||||
.plugin-filters
|
||||
{
|
||||
margin: 7px;
|
||||
@@ -1555,6 +1696,7 @@ input[readonly] {
|
||||
.integrations-plugins .content
|
||||
{
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.plugin-content .tab-content
|
||||
@@ -1606,13 +1748,6 @@ input[readonly] {
|
||||
}
|
||||
}
|
||||
|
||||
#settingsPage .small-box .inner .card-title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
.textOverflow
|
||||
{
|
||||
@@ -1710,16 +1845,14 @@ input[readonly] {
|
||||
----------------------------------------------------------------------------- */
|
||||
#multiEditPlc
|
||||
{
|
||||
position: fixed;
|
||||
bottom: 50px;
|
||||
right: 0px;
|
||||
z-index: 10;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
table.dataTable tbody > tr.selected
|
||||
{
|
||||
color:red;
|
||||
/* color:red; */
|
||||
color: #353c42;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
||||
@@ -17,9 +17,9 @@ html {
|
||||
background-color: #353c42;
|
||||
}
|
||||
|
||||
body {
|
||||
/* body {
|
||||
background-image: url('../img/boxed-bg-dark.png') !important;
|
||||
}
|
||||
} */
|
||||
|
||||
body, .bg-yellow, .callout.callout-warning, .alert-warning, .label-warning, .modal-warning .modal-body {
|
||||
|
||||
@@ -732,4 +732,12 @@ input[type="password"]::-webkit-caps-lock-indicator {
|
||||
background-color: #000 !important;
|
||||
}
|
||||
|
||||
.callout code {
|
||||
background-color: #fff !important;
|
||||
color:#000 !important;
|
||||
}
|
||||
|
||||
.thresholdFormControl
|
||||
{
|
||||
color:#000;
|
||||
}
|
||||
@@ -19,9 +19,9 @@
|
||||
background-color: #353c42;
|
||||
}
|
||||
|
||||
body {
|
||||
/* body {
|
||||
background-image: url('../img/boxed-bg-dark.png') !important;
|
||||
}
|
||||
} */
|
||||
|
||||
body, .bg-yellow, .callout.callout-warning, .alert-warning, .label-warning, .modal-warning .modal-body {
|
||||
|
||||
@@ -735,3 +735,13 @@
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.callout code {
|
||||
background-color: #fff !important;
|
||||
color:#000 !important;
|
||||
}
|
||||
|
||||
.thresholdFormControl
|
||||
{
|
||||
color:#000;
|
||||
}
|
||||
@@ -61,12 +61,54 @@
|
||||
<!-- <div class="box-transparent"> -->
|
||||
<div id="navDevice" class="nav-tabs-custom">
|
||||
<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> <a id="tabTools" href="#panTools" data-toggle="tab"> <?= lang('DevDetail_Tab_Tools');?> </a></li>
|
||||
<li> <a id="tabSessions" href="#panSessions" data-toggle="tab"> <?= lang('DevDetail_Tab_Sessions');?> </a></li>
|
||||
<li> <a id="tabPresence" href="#panPresence" data-toggle="tab"> <?= lang('DevDetail_Tab_Presence');?> </a></li>
|
||||
<li> <a id="tabEvents" href="#panEvents" data-toggle="tab"> <?= lang('DevDetail_Tab_Events');?> </a></li>
|
||||
<li> <a id="tabPlugins" href="#panPlugins" data-toggle="tab"> <?= lang('DevDetail_Tab_Plugins');?> </a></li>
|
||||
<li>
|
||||
<a id="tabDetails" href="#panDetails" data-toggle="tab">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
<span class="dev-detail-tab-name">
|
||||
<?= lang('DevDetail_Tab_Details');?>
|
||||
</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">
|
||||
<button type="button" class="btn btn-default" style="padding: 10px; min-width: 30px;"
|
||||
|
||||
@@ -14,26 +14,21 @@
|
||||
<!-- Buttons -->
|
||||
<div class="col-xs-12">
|
||||
<div class="pull-right">
|
||||
<button type="button"
|
||||
class="btn btn-default pa-btn pa-btn-delete"
|
||||
style="margin-left:0px;"
|
||||
id="btnDeleteEvents"
|
||||
onclick="askDeleteDeviceEvents()">
|
||||
<?= lang('DevDetail_button_DeleteEvents');?>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn btn-default pa-btn pa-btn-delete"
|
||||
style="margin-left:0px;"
|
||||
id="btnDelete"
|
||||
onclick="askDeleteDevice()">
|
||||
<?= lang('DevDetail_button_Delete');?>
|
||||
<i class="fas fa-trash-alt"></i>
|
||||
<?= lang('DevDetail_button_Delete');?>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn btn-primary pa-btn"
|
||||
style="margin-left:6px; "
|
||||
id="btnSave"
|
||||
onclick="setDeviceData()" >
|
||||
<?= lang('DevDetail_button_Save');?>
|
||||
<i class="fas fa-save"></i>
|
||||
<?= lang('DevDetail_button_Save');?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -75,7 +70,7 @@
|
||||
// columns to hide
|
||||
hiddenFields = ["NEWDEV_devScan", "NEWDEV_devPresentLastScan" ]
|
||||
// columns to disable - conditional depending if a new dummy device is created
|
||||
disabledFields = mac == "new" ? ["NEWDEV_devLastNotification", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection"] : ["NEWDEV_devLastNotification", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devMac", "NEWDEV_devLastIP" ];
|
||||
disabledFields = mac == "new" ? ["NEWDEV_devLastNotification", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection"] : ["NEWDEV_devLastNotification", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devMac", "NEWDEV_devLastIP", "NEWDEV_devSyncHubNode" ];
|
||||
|
||||
// Grouping of fields into categories with associated documentation links
|
||||
const fieldGroups = {
|
||||
@@ -83,32 +78,55 @@
|
||||
DevDetail_MainInfo_Title: {
|
||||
data: ["devMac", "devLastIP", "devName", "devOwner", "devType", "devVendor", "devGroup", "devIcon", "devLocation", "devComments"],
|
||||
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICE_MANAGEMENT.md",
|
||||
iconClass: "fa fa-pencil"
|
||||
iconClass: "fa fa-pencil",
|
||||
inputGroupClasses: "field-group main-group col-lg-4 col-sm-6 col-xs-12",
|
||||
labelClasses: "col-sm-4 col-xs-12 control-label",
|
||||
inputClasses: "col-sm-8 col-xs-12 input-group"
|
||||
},
|
||||
// Group for session information
|
||||
DevDetail_SessionInfo_Title: {
|
||||
data: ["devStatus", "devLastConnection", "devFirstConnection"],
|
||||
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/SESSION_INFO.md",
|
||||
iconClass: "fa fa-calendar"
|
||||
iconClass: "fa fa-calendar",
|
||||
inputGroupClasses: "field-group session-group col-lg-4 col-sm-6 col-xs-12",
|
||||
labelClasses: "col-sm-4 col-xs-12 control-label",
|
||||
inputClasses: "col-sm-8 col-xs-12 input-group"
|
||||
},
|
||||
// Group for event and alert settings
|
||||
DevDetail_EveandAl_Title: {
|
||||
data: ["devAlertEvents", "devAlertDown", "devSkipRepeated"],
|
||||
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/NOTIFICATIONS.md",
|
||||
iconClass: "fa fa-bell"
|
||||
iconClass: "fa fa-bell",
|
||||
inputGroupClasses: "field-group alert-group col-lg-4 col-sm-6 col-xs-12",
|
||||
labelClasses: "col-sm-4 col-xs-12 control-label",
|
||||
inputClasses: "col-sm-8 col-xs-12 input-group"
|
||||
},
|
||||
// Group for network details
|
||||
DevDetail_MainInfo_Network_Title: {
|
||||
data: ["devParentMAC", "devParentPort", "devSSID", "devSite"],
|
||||
data: ["devParentMAC", "devParentPort", "devSSID", "devSite", "devSyncHubNode"],
|
||||
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md",
|
||||
iconClass: "fa fa-network-wired"
|
||||
iconClass: "fa fa-network-wired",
|
||||
inputGroupClasses: "field-group network-group col-lg-4 col-sm-6 col-xs-12",
|
||||
labelClasses: "col-sm-4 col-xs-12 control-label",
|
||||
inputClasses: "col-sm-8 col-xs-12 input-group"
|
||||
},
|
||||
// Group for other fields like static IP, archived status, etc.
|
||||
DevDetail_DisplayFields_Title: {
|
||||
data: ["devStaticIP", "devIsNew", "devFavorite", "devIsArchived"],
|
||||
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICE_DISPLAY_SETTINGS.md",
|
||||
iconClass: "fa fa-list-check"
|
||||
|
||||
iconClass: "fa fa-list-check",
|
||||
inputGroupClasses: "field-group display-group col-lg-4 col-sm-6 col-xs-12",
|
||||
labelClasses: "col-sm-4 col-xs-12 control-label",
|
||||
inputClasses: "col-sm-8 col-xs-12 input-group"
|
||||
},
|
||||
// Group for Custom properties.
|
||||
DevDetail_CustomProperties_Title: {
|
||||
data: ["devCustomProps"],
|
||||
docs: "https://github.com/jokob-sk/NetAlertX/blob/main/docs/CUSTOM_PROPERTIES.md",
|
||||
iconClass: "fa fa-list",
|
||||
inputGroupClasses: "field-group cutprop-group col-lg-12 col-sm-12 col-xs-12",
|
||||
labelClasses: "col-sm-12 col-xs-12 control-label",
|
||||
inputClasses: "col-sm-12 col-xs-12 input-group"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -126,7 +144,7 @@
|
||||
|
||||
// Loop over each field group to generate sections for each category
|
||||
Object.entries(fieldGroups).forEach(([groupName, obj]) => {
|
||||
const groupDiv = $('<div>').addClass('field-group col-lg-4 col-sm-6 col-xs-12'); // Create a div for each group with responsive Bootstrap classes
|
||||
const groupDiv = $('<div>').addClass(obj.inputGroupClasses); // Create a div for each group with responsive Bootstrap classes
|
||||
|
||||
// Add group title and documentation link
|
||||
groupDiv.append(`<h5><i class="${obj.iconClass}"></i> ${getString(groupName)}
|
||||
@@ -137,7 +155,7 @@
|
||||
</span>
|
||||
</h5>
|
||||
<hr>
|
||||
`);
|
||||
`);
|
||||
|
||||
// Filter relevant settings for the current group
|
||||
const groupSettings = settings.filter(set => obj.data.includes(set.setKey.replace('NEWDEV_', '')));
|
||||
@@ -193,15 +211,15 @@
|
||||
|
||||
// Generate the input field HTML
|
||||
const inputFormHtml = `<div class="form-group col-xs-12">
|
||||
<label class="col-sm-4 col-xs-12 control-label"> ${setting.setName}
|
||||
<label id="${setting.setKey}_label" class="${obj.labelClasses}" > ${setting.setName}
|
||||
<i my-set-key="${setting.setKey}"
|
||||
title="${getString("Settings_Show_Description")}"
|
||||
class="fa fa-circle-info pointer helpIconSmallTopRight"
|
||||
onclick="showDescriptionPopup(this)">
|
||||
</i>
|
||||
</label>
|
||||
<div class="col-sm-8 col-xs-12 input-group">
|
||||
${generateFormHtml(setting, fieldData.toString())}
|
||||
<div class="${obj.inputClasses}">
|
||||
${generateFormHtml(settingsData, setting, fieldData.toString(), null, null)}
|
||||
${inlineControl}
|
||||
</div>
|
||||
</div>`;
|
||||
@@ -214,8 +232,8 @@
|
||||
});
|
||||
|
||||
|
||||
// wait until everything is initialized to update icon
|
||||
updateIconPreview();
|
||||
// wait until everything is initialized to update icons
|
||||
updateAllIconPreviews();
|
||||
|
||||
// update readonly fields
|
||||
handleReadOnly(settingsData, disabledFields);
|
||||
@@ -317,64 +335,7 @@
|
||||
showModalOK("Info", getString($(e).attr("my-set-key") + '_description'))
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function askDeleteDeviceEvents () {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ask delete device Events
|
||||
showModalWarning ('<?= lang('DevDetail_button_DeleteEvents');?>', '<?= lang('DevDetail_button_DeleteEvents_Warning');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteDeviceEvents');
|
||||
}
|
||||
|
||||
function deleteDeviceEvents () {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete device events
|
||||
$.get('php/server/devices.php?action=deleteDeviceEvents&mac='+ mac, function(msg) {
|
||||
showMessage (msg);
|
||||
});
|
||||
|
||||
// Deactivate controls
|
||||
$('#panDetails :input').attr('disabled', true);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function askDeleteDevice () {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ask delete device
|
||||
showModalWarning ('Delete Device', 'Are you sure you want to delete this device?<br>(maybe you prefer to archive it)',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteDevice');
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function deleteDevice () {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete device
|
||||
$.get('php/server/devices.php?action=deleteDevice&mac='+ mac, function(msg) {
|
||||
showMessage (msg);
|
||||
});
|
||||
|
||||
// Deactivate controls
|
||||
$('#panDetails :input').attr('disabled', true);
|
||||
|
||||
// refresh API
|
||||
updateApi("devices,appevents")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function setDeviceData(direction = '', refreshCallback = '') {
|
||||
@@ -387,59 +348,61 @@
|
||||
const createNew = mac === 'new' ? 1 : 0;
|
||||
|
||||
const devLastIP = $('#NEWDEV_devLastIP').val();
|
||||
const newMac = $('#NEWDEV_devMac').val()
|
||||
|
||||
// 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");
|
||||
return;
|
||||
}
|
||||
|
||||
showSpinner();
|
||||
|
||||
// update data to server
|
||||
$.get('php/server/devices.php?action=setDeviceData&mac='+ $('#NEWDEV_devMac').val()
|
||||
+ '&name=' + encodeURIComponent($('#NEWDEV_devName').val().replace(/'/g, ""))
|
||||
+ '&owner=' + encodeURIComponent($('#NEWDEV_devOwner').val().replace(/'/g, ""))
|
||||
+ '&type=' + $('#NEWDEV_devType').val()
|
||||
+ '&vendor=' + encodeURIComponent($('#NEWDEV_devVendor').val().replace(/'/g, ""))
|
||||
+ '&icon=' + encodeURIComponent($('#NEWDEV_devIcon').val())
|
||||
+ '&favorite=' + ($('#NEWDEV_devFavorite')[0].checked * 1)
|
||||
+ '&group=' + encodeURIComponent($('#NEWDEV_devGroup').val())
|
||||
+ '&location=' + encodeURIComponent($('#NEWDEV_devLocation').val())
|
||||
+ '&comments=' + encodeURIComponent(encodeSpecialChars($('#NEWDEV_devComments').val()))
|
||||
+ '&networknode=' + $('#NEWDEV_devParentMAC').val()
|
||||
+ '&networknodeport=' + $('#NEWDEV_devParentPort').val()
|
||||
+ '&ssid=' + $('#NEWDEV_devSSID').val()
|
||||
+ '&networksite=' + $('#NEWDEV_devSite').val()
|
||||
+ '&staticIP=' + ($('#NEWDEV_devStaticIP')[0].checked * 1)
|
||||
+ '&scancycle=' + "1"
|
||||
+ '&alertevents=' + ($('#NEWDEV_devAlertEvents')[0].checked * 1)
|
||||
+ '&alertdown=' + ($('#NEWDEV_devAlertDown')[0].checked * 1)
|
||||
+ '&skiprepeated=' + $('#NEWDEV_devSkipRepeated').val().split(' ')[0]
|
||||
+ '&newdevice=' + ($('#NEWDEV_devIsNew')[0].checked * 1)
|
||||
+ '&archived=' + ($('#NEWDEV_devIsArchived')[0].checked * 1)
|
||||
+ '&devFirstConnection=' + ($('#NEWDEV_devFirstConnection').val())
|
||||
+ '&devLastConnection=' + ($('#NEWDEV_devLastConnection').val())
|
||||
+ '&ip=' + ($('#NEWDEV_devLastIP').val())
|
||||
+ '&createNew=' + createNew
|
||||
, function(msg) {
|
||||
|
||||
showMessage (msg);
|
||||
// Update data to server using POST
|
||||
$.post('php/server/devices.php?action=setDeviceData', {
|
||||
mac: $('#NEWDEV_devMac').val(),
|
||||
name: encodeURIComponent($('#NEWDEV_devName').val().replace(/'/g, "")),
|
||||
owner: encodeURIComponent($('#NEWDEV_devOwner').val().replace(/'/g, "")),
|
||||
type: $('#NEWDEV_devType').val().replace(/'/g, ""),
|
||||
vendor: encodeURIComponent($('#NEWDEV_devVendor').val().replace(/'/g, "")),
|
||||
icon: encodeURIComponent($('#NEWDEV_devIcon').val()),
|
||||
favorite: ($('#NEWDEV_devFavorite')[0].checked * 1),
|
||||
group: encodeURIComponent($('#NEWDEV_devGroup').val().replace(/'/g, "")),
|
||||
location: encodeURIComponent($('#NEWDEV_devLocation').val().replace(/'/g, "")),
|
||||
comments: encodeURIComponent(encodeSpecialChars($('#NEWDEV_devComments').val())),
|
||||
networknode: $('#NEWDEV_devParentMAC').val(),
|
||||
networknodeport: $('#NEWDEV_devParentPort').val(),
|
||||
ssid: $('#NEWDEV_devSSID').val(),
|
||||
networksite: $('#NEWDEV_devSite').val(),
|
||||
staticIP: ($('#NEWDEV_devStaticIP')[0].checked * 1),
|
||||
scancycle: "1",
|
||||
alertevents: ($('#NEWDEV_devAlertEvents')[0].checked * 1),
|
||||
alertdown: ($('#NEWDEV_devAlertDown')[0].checked * 1),
|
||||
skiprepeated: $('#NEWDEV_devSkipRepeated').val().split(' ')[0],
|
||||
newdevice: ($('#NEWDEV_devIsNew')[0].checked * 1),
|
||||
archived: ($('#NEWDEV_devIsArchived')[0].checked * 1),
|
||||
devFirstConnection: ($('#NEWDEV_devFirstConnection').val()),
|
||||
devLastConnection: ($('#NEWDEV_devLastConnection').val()),
|
||||
devCustomProps: btoa(JSON.stringify(collectTableData("#NEWDEV_devCustomProps_table"))),
|
||||
ip: ($('#NEWDEV_devLastIP').val()),
|
||||
createNew: createNew
|
||||
}, function(msg) {
|
||||
showMessage(msg);
|
||||
|
||||
// Remove navigation prompt "Are you sure you want to leave..."
|
||||
window.onbeforeunload = null;
|
||||
somethingChanged = false;
|
||||
somethingChanged = false;
|
||||
|
||||
// refresh API
|
||||
updateApi("devices,appevents")
|
||||
updateApi("devices,appevents");
|
||||
|
||||
// Callback fuction
|
||||
// Callback function
|
||||
if (typeof refreshCallback == 'function') {
|
||||
refreshCallback(direction);
|
||||
refreshCallback(direction);
|
||||
}
|
||||
|
||||
// everything loaded
|
||||
hideSpinner();
|
||||
// Everything loaded
|
||||
hideSpinner();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -227,11 +227,7 @@ function initializeCalendar() {
|
||||
loading: function( isLoading, view ) {
|
||||
if (isLoading) {
|
||||
showSpinner()
|
||||
} else {
|
||||
// setTimeout(() => {
|
||||
// updateIconPreview($('#txtIcon'))
|
||||
// }, 500);
|
||||
|
||||
} else {
|
||||
hideSpinner()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,48 @@
|
||||
|
||||
<?php } ?>
|
||||
|
||||
|
||||
<!-- Delete Events -->
|
||||
<h4 class=""><i class="fa-solid fa-bell"></i>
|
||||
<?= lang("DevDetail_button_DeleteEvents") ?>
|
||||
</h4>
|
||||
<h5 class="">
|
||||
<?= lang("DevDetail_button_DeleteEvents_Warning") ?>
|
||||
</h5>
|
||||
<br>
|
||||
<div style="width:100%; text-align: center; margin-bottom: 50px;">
|
||||
<button type="button"
|
||||
class="btn btn-default pa-btn pa-btn-delete"
|
||||
style="margin-left:0px;"
|
||||
id="btnDeleteEvents"
|
||||
onclick="askDeleteDeviceEvents()">
|
||||
<?= lang('DevDetail_button_DeleteEvents');?>
|
||||
</button>
|
||||
<br>
|
||||
<div id="wol_output" style="margin-top: 10px;"></div>
|
||||
</div>
|
||||
|
||||
<!-- Reset Custom Proprties -->
|
||||
<h4 class=""><i class="fa-solid fa-list"></i>
|
||||
<?= lang("DevDetail_CustomProperties_Title") ?>
|
||||
</h4>
|
||||
<h5 class="">
|
||||
<?= lang("DevDetail_CustomProps_reset_info") ?>
|
||||
</h5>
|
||||
<br>
|
||||
<div style="width:100%; text-align: center; margin-bottom: 50px;">
|
||||
<button type="button"
|
||||
class="btn btn-default pa-btn pa-btn-delete"
|
||||
style="margin-left:0px;"
|
||||
id="btnDeleteEvents"
|
||||
onclick="askResetDeviceProps()">
|
||||
<?= lang("Gen_Reset") ?>
|
||||
</button>
|
||||
<br>
|
||||
<div id="wol_output" style="margin-top: 10px;"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- SPEEDTEST -->
|
||||
<?php if ($_REQUEST["mac"] == "Internet") { ?>
|
||||
<h4 class=""><i class="fa-solid fa-gauge-high"></i>
|
||||
@@ -336,6 +378,56 @@
|
||||
return devicesList;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function askDeleteDeviceEvents () {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ask delete device Events
|
||||
showModalWarning ('<?= lang('DevDetail_button_DeleteEvents');?>', '<?= lang('DevDetail_button_DeleteEvents_Warning');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteDeviceEvents');
|
||||
}
|
||||
|
||||
function deleteDeviceEvents () {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete device events
|
||||
$.get('php/server/devices.php?action=deleteDeviceEvents&mac='+ mac, function(msg) {
|
||||
showMessage (msg);
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function askResetDeviceProps () {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ask Resert Custom properties
|
||||
showModalWarning ('<?= lang('Gen_Reset');?>', '<?= lang('DevDetail_CustomProps_reset_info');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'resetDeviceProps');
|
||||
}
|
||||
|
||||
function resetDeviceProps () {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute
|
||||
$.get('php/server/devices.php?action=resetDeviceProps&mac='+ mac, function(msg) {
|
||||
showMessage (msg);
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
function internetinfo() {
|
||||
$( "#internetinfooutput" ).empty();
|
||||
|
||||
@@ -28,30 +28,21 @@
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<h1 id="pageTitle">
|
||||
<i class="fa fa-laptop"></i>
|
||||
<?= lang('Device_Title');?>
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
<!-- Main content ---------------------------------------------------------- -->
|
||||
<section class="content">
|
||||
|
||||
<!-- Tile toggle cards ------------------------------------------------------- -->
|
||||
<div class="row" id="TileCards">
|
||||
<div class="row " id="TileCards">
|
||||
<!-- Placeholder ------------------------------------------------------- -->
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Device presence / Activity Chart ------------------------------------------------------- -->
|
||||
|
||||
<div class="row" id="DevicePresence">
|
||||
<div class="col-md-12">
|
||||
<div class="box" id="clients">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><?= lang('Device_Shortcut_OnlineChart');?> </h3>
|
||||
<div class="box" id="clients">
|
||||
<div class="box-header ">
|
||||
<h3 class="box-title col-md-12"><?= lang('Device_Shortcut_OnlineChart');?> </h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="chart">
|
||||
@@ -67,6 +58,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Device Filters ------------------------------------------------------- -->
|
||||
<div class="box box-aqua hidden" id="columnFiltersWrap">
|
||||
<div class="box-header ">
|
||||
<h3 class="box-title col-md-12"><?= lang('Devices_Filters');?> </h3>
|
||||
</div>
|
||||
<!-- Placeholder ------------------------------------------------------- -->
|
||||
<div id="columnFilters" ></div>
|
||||
</div>
|
||||
|
||||
<!-- datatable ------------------------------------------------------------- -->
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
@@ -78,6 +78,9 @@
|
||||
<h3 id="tableDevicesTitle" class="box-title text-gray "></h3>
|
||||
</div>
|
||||
<div class="dummyDevice col-md-3 ">
|
||||
<span id="multiEditPlc">
|
||||
<!-- multi edit button placeholder -->
|
||||
</span>
|
||||
<span>
|
||||
<a href="deviceDetails.php?mac=new"><i title="<?= lang('Gen_create_new_device');?>" class="fa fa-square-plus"></i> <?= lang('Gen_create_new_device');?></a>
|
||||
</span>
|
||||
@@ -106,7 +109,7 @@
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
</section>
|
||||
<!-- /.content -->
|
||||
<div id="multiEditPlc" class="col-md-2"></div>
|
||||
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
|
||||
@@ -120,8 +123,8 @@
|
||||
<!-- page script ----------------------------------------------------------- -->
|
||||
<script>
|
||||
var deviceStatus = 'all';
|
||||
var tableRows = getCookie ("nax_parTableRows") == "" ? 10 : getCookie ("nax_parTableRows") ;
|
||||
var tableOrder = getCookie ("nax_parTableOrder") == "" ? [[3,'desc'], [0,'asc']] : JSON.parse(getCookie ("nax_parTableOrder")) ;
|
||||
var tableRows = getCache ("nax_parTableRows") == "" ? 10 : getCache ("nax_parTableRows") ;
|
||||
var tableOrder = getCache ("nax_parTableOrder") == "" ? [[3,'desc'], [0,'asc']] : JSON.parse(getCache ("nax_parTableOrder")) ;
|
||||
|
||||
var tableColumnHide = [];
|
||||
var tableColumnOrder = [];
|
||||
@@ -138,12 +141,18 @@ function main () {
|
||||
|
||||
showSpinner();
|
||||
|
||||
initFilters();
|
||||
|
||||
// render tiles
|
||||
getDevicesTotals();
|
||||
|
||||
//initialize the table headers in the correct order
|
||||
var availableColumns = getSettingOptions("UI_device_columns").split(",");
|
||||
headersDefaultOrder = availableColumns.map(val => getString(val));
|
||||
|
||||
console.log(headersDefaultOrder);
|
||||
|
||||
|
||||
var selectedColumns = JSON.parse(getSetting("UI_device_columns").replace(/'/g, '"'));
|
||||
|
||||
// generate default order lists of given length
|
||||
@@ -181,6 +190,9 @@ function main () {
|
||||
// mapping the default order to the user specified one
|
||||
function mapIndx(oldIndex)
|
||||
{
|
||||
// console.log(oldIndex);
|
||||
// console.log(tableColumnOrder);
|
||||
|
||||
for(i=0;i<tableColumnOrder.length;i++)
|
||||
{
|
||||
if(tableColumnOrder[i] == oldIndex)
|
||||
@@ -194,35 +206,61 @@ function mapIndx(oldIndex)
|
||||
// Query total numbers of Devices by status
|
||||
//------------------------------------------------------------------------------
|
||||
function getDevicesTotals() {
|
||||
maxDelay = 180; //cap at 180 seconds
|
||||
|
||||
// Fetch data via AJAX
|
||||
$.ajax({
|
||||
url: '/php/server/query_json.php',
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
data: {
|
||||
file: 'table_devices_tiles.json', // Pass the file parameter
|
||||
nocache: Date.now() // Prevent caching with a timestamp
|
||||
},
|
||||
success: function(response) {
|
||||
if (response && response.data) {
|
||||
resultJSON = response.data[0]; // Assuming the structure {"data": [ ... ]}
|
||||
|
||||
// Save the result to cache
|
||||
setCache("getDevicesTotals", JSON.stringify(resultJSON));
|
||||
let maxRetries = Math.ceil(Math.log2(maxDelay)); // Calculate maximum retries to cap at maxDelay seconds
|
||||
let attempt = 0;
|
||||
let calledUpdateAPI = false;
|
||||
|
||||
// Process the fetched data
|
||||
processDeviceTotals(resultJSON);
|
||||
} else {
|
||||
console.error("Invalid response format from API");
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Failed to fetch devices data:", error);
|
||||
}
|
||||
});
|
||||
function fetchDataWithBackoff() {
|
||||
// Calculate the delay (2^attempt seconds, capped at maxDelay seconds)
|
||||
const delay = Math.min(2 ** attempt, maxDelay) * 1000;
|
||||
|
||||
|
||||
// Attempt to fetch data
|
||||
$.ajax({
|
||||
url: '/php/server/query_json.php',
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
data: {
|
||||
file: 'table_devices_tiles.json', // Pass the file parameter
|
||||
nocache: Date.now() // Prevent caching with a timestamp
|
||||
},
|
||||
success: function(response) {
|
||||
if (response && response.data) {
|
||||
const resultJSON = response.data[0]; // Assuming the structure {"data": [ ... ]}
|
||||
|
||||
// Save the result to cache
|
||||
setCache("getDevicesTotals", JSON.stringify(resultJSON));
|
||||
|
||||
// Process the fetched data
|
||||
processDeviceTotals(resultJSON);
|
||||
} else {
|
||||
console.error("Invalid response format from API");
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Failed to fetch devices data (Attempt " + (attempt + 1) + "):", error);
|
||||
|
||||
// try updating the API once
|
||||
if(calledUpdateAPI == false)
|
||||
{
|
||||
calledUpdateAPI = true;
|
||||
updateApi("devices_tiles");
|
||||
}
|
||||
|
||||
// Retry logic
|
||||
if (attempt < maxRetries) {
|
||||
attempt++;
|
||||
setTimeout(fetchDataWithBackoff, delay);
|
||||
} else {
|
||||
console.error("Maximum retries reached. Unable to fetch devices data.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Start the first fetch attempt
|
||||
fetchDataWithBackoff();
|
||||
}
|
||||
|
||||
function processDeviceTotals(devicesData) {
|
||||
@@ -274,6 +312,8 @@ function processDeviceTotals(devicesData) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Render the info boxes/tiles on top
|
||||
function renderInfoboxes(customData) {
|
||||
if(customData.length > 0)
|
||||
{
|
||||
$.ajax({
|
||||
url: 'php/components/tile_cards.php', // PHP script URL
|
||||
type: 'POST', // Use POST method to send data
|
||||
@@ -287,49 +327,187 @@ function renderInfoboxes(customData) {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Define a function to filter data based on deviceStatus
|
||||
function filterDataByStatus(data, status) {
|
||||
return data.filter(function(item) {
|
||||
switch (status) {
|
||||
case 'my_devices':
|
||||
to_display = getSetting('UI_MY_DEVICES');
|
||||
|
||||
let result = true;
|
||||
//Render filters if specified
|
||||
let columnFilters = [];
|
||||
|
||||
if (!to_display.includes('down') && item.devPresentLastScan === 0 && item.devAlertDown !== 0) {
|
||||
result = false;
|
||||
} else if (!to_display.includes('new') && item.devIsNew === 1) {
|
||||
result = false;
|
||||
} else if (!to_display.includes('archived') && item.devIsArchived === 1) {
|
||||
result = false;
|
||||
} else if (!to_display.includes('offline') && item.devPresentLastScan === 0) {
|
||||
result = false;
|
||||
} else if (!to_display.includes('online') && item.devPresentLastScan === 1) {
|
||||
result = false;
|
||||
}
|
||||
function initFilters() {
|
||||
// Attempt to fetch data
|
||||
$.ajax({
|
||||
url: '/php/server/query_json.php',
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
data: {
|
||||
file: 'table_devices_filters.json', // Pass the file parameter
|
||||
nocache: Date.now() // Prevent caching with a timestamp
|
||||
},
|
||||
success: function(response) {
|
||||
if (response && response.data) {
|
||||
|
||||
let resultJSON = response.data;
|
||||
|
||||
return result; // Include all items for 'my_devices' status
|
||||
case 'connected':
|
||||
return item.devPresentLastScan === 1;
|
||||
case 'favorites':
|
||||
return item.devFavorite === 1;
|
||||
case 'new':
|
||||
return item.devIsNew === 1;
|
||||
case 'offline':
|
||||
return item.devPresentLastScan === 0;
|
||||
case 'down':
|
||||
return (item.devPresentLastScan === 0 && item.devAlertDown !== 0);
|
||||
case 'archived':
|
||||
return item.devIsArchived === 1;
|
||||
default:
|
||||
return true; // Include all items for unknown statuses
|
||||
// Save the result to cache
|
||||
setCache("devicesFilters", JSON.stringify(resultJSON));
|
||||
|
||||
// Get the displayed filters from settings
|
||||
const displayedFilters = createArray(getSetting("UI_columns_filters"));
|
||||
|
||||
// Clear any existing filters in the DOM
|
||||
$('#columnFilters').empty();
|
||||
|
||||
console.log(displayedFilters);
|
||||
|
||||
// Ensure displayedFilters is an array and not empty
|
||||
if (Array.isArray(displayedFilters) && displayedFilters.length > 0) {
|
||||
$('#columnFiltersWrap').removeClass("hidden");
|
||||
|
||||
displayedFilters.forEach(columnHeaderStringKey => {
|
||||
// Get the column name using the mapping function
|
||||
const columnName = getColumnNameFromLangString(columnHeaderStringKey);
|
||||
|
||||
// Ensure columnName is valid before proceeding
|
||||
if (columnName) {
|
||||
// Add the filter to the columnFilters array as [columnName, columnHeaderStringKey]
|
||||
columnFilters.push([columnName, columnHeaderStringKey]);
|
||||
} else {
|
||||
console.warn(`Invalid column header string key: ${columnHeaderStringKey}`);
|
||||
}
|
||||
});
|
||||
|
||||
// Filter resultJSON to include only entries with columnName in columnFilters
|
||||
resultJSON = resultJSON.filter(entry =>
|
||||
columnFilters.some(filter => filter[0] === entry.columnName)
|
||||
);
|
||||
|
||||
// Expand resultJSON to include the columnHeaderStringKey
|
||||
resultJSON.forEach(entry => {
|
||||
// Find the matching columnHeaderStringKey from columnFilters
|
||||
const matchingFilter = columnFilters.find(filter => filter[0] === entry.columnName);
|
||||
|
||||
// Add the columnHeaderStringKey to the entry
|
||||
if (matchingFilter) {
|
||||
entry['columnHeaderStringKey'] = matchingFilter[1];
|
||||
}
|
||||
});
|
||||
|
||||
console.log(resultJSON);
|
||||
|
||||
// Transforming the data
|
||||
const transformed = {
|
||||
filters: []
|
||||
};
|
||||
|
||||
// Group data by columnName
|
||||
resultJSON.forEach(entry => {
|
||||
const existingFilter = transformed.filters.find(filter => filter.column === entry.columnName);
|
||||
|
||||
if (existingFilter) {
|
||||
// Add the unique columnValue to options if not already present
|
||||
if (!existingFilter.options.includes(entry.columnValue)) {
|
||||
existingFilter.options.push(entry.columnValue);
|
||||
}
|
||||
} else {
|
||||
// Create a new filter entry
|
||||
transformed.filters.push({
|
||||
column: entry.columnName,
|
||||
headerKey: entry.columnHeaderStringKey,
|
||||
options: [entry.columnValue]
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Sort options alphabetically for better readability
|
||||
transformed.filters.forEach(filter => {
|
||||
filter.options.sort();
|
||||
});
|
||||
|
||||
// Output the result
|
||||
transformedJson = transformed
|
||||
|
||||
// Process the fetched data
|
||||
renderFilters(transformedJson);
|
||||
} else {
|
||||
console.log("No filters to display.");
|
||||
}
|
||||
} else {
|
||||
console.error("Invalid response format from API");
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Failed to fetch devices data 'table_devices_filters.json':", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------
|
||||
// Server side component
|
||||
function renderFilters(customData) {
|
||||
|
||||
// console.log(JSON.stringify(customData));
|
||||
|
||||
// Load filter data from the JSON file
|
||||
$.ajax({
|
||||
url: 'php/components/devices_filters.php', // PHP script URL
|
||||
data: { filterObject: JSON.stringify(customData) }, // Send customData as JSON
|
||||
type: 'POST',
|
||||
dataType: 'html',
|
||||
success: function(response) {
|
||||
// console.log(response);
|
||||
|
||||
$('#columnFilters').html(response); // Replace container content with fetched HTML
|
||||
$('#columnFilters').removeClass('hidden'); // Show the filters container
|
||||
|
||||
// Trigger the draw after select change
|
||||
$('.filter-dropdown').on('change', function() {
|
||||
// Collect filters
|
||||
const columnFilters = collectFilters();
|
||||
|
||||
// Update DataTable with the new filters or search value (if applicable)
|
||||
$('#tableDevices').DataTable().draw();
|
||||
|
||||
// Optionally, apply column filters (if using filters for individual columns)
|
||||
const table = $('#tableDevices').DataTable();
|
||||
table.columnFilters = columnFilters; // Apply your column filters logic
|
||||
table.draw();
|
||||
});
|
||||
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('Error fetching filters:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// -------------------------------------------
|
||||
// Function to collect filters
|
||||
function collectFilters() {
|
||||
const columnFilters = [];
|
||||
|
||||
// Loop through each filter group
|
||||
document.querySelectorAll('.filter-group').forEach(filterGroup => {
|
||||
const dropdown = filterGroup.querySelector('.filter-dropdown');
|
||||
|
||||
if (dropdown) {
|
||||
const filterColumn = dropdown.getAttribute('data-column');
|
||||
const filterValue = dropdown.value;
|
||||
|
||||
if (filterValue && filterColumn) {
|
||||
columnFilters.push({
|
||||
filterColumn: filterColumn,
|
||||
filterValue: filterValue
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return columnFilters;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Map column index to column name for GraphQL query
|
||||
function mapColumnIndexToFieldName(index, tableColumnVisible) {
|
||||
// the order is important, don't change it!
|
||||
@@ -359,7 +537,8 @@ function mapColumnIndexToFieldName(index, tableColumnVisible) {
|
||||
"devSSID",
|
||||
"devSourcePlugin",
|
||||
"devPresentLastScan",
|
||||
"devAlertDown"
|
||||
"devAlertDown",
|
||||
"devCustomProps"
|
||||
];
|
||||
|
||||
// console.log("OrderBy: " + columnNames[tableColumnOrder[index]]);
|
||||
@@ -369,6 +548,7 @@ function mapColumnIndexToFieldName(index, tableColumnVisible) {
|
||||
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Initializes the main devices list datatable
|
||||
function initializeDatatable (status) {
|
||||
|
||||
if(!status)
|
||||
@@ -419,8 +599,6 @@ function initializeDatatable (status) {
|
||||
}
|
||||
|
||||
// todo: dynamically filter based on status
|
||||
|
||||
|
||||
var table = $('#tableDevices').DataTable({
|
||||
"serverSide": true,
|
||||
"processing": true,
|
||||
@@ -469,6 +647,7 @@ function initializeDatatable (status) {
|
||||
devStatus
|
||||
devParentChildrenCount
|
||||
devIpLong
|
||||
devCustomProps
|
||||
}
|
||||
count
|
||||
}
|
||||
@@ -476,7 +655,13 @@ function initializeDatatable (status) {
|
||||
`;
|
||||
|
||||
console.log(d);
|
||||
|
||||
|
||||
// Handle empty filters
|
||||
let columnFilters = collectFilters();
|
||||
if (columnFilters.length === 0) {
|
||||
columnFilters = [];
|
||||
}
|
||||
|
||||
|
||||
// Prepare query variables for pagination, sorting, and search
|
||||
let query = {
|
||||
@@ -491,7 +676,8 @@ function initializeDatatable (status) {
|
||||
"order": d.order[0].dir.toUpperCase() // Sort direction (ASC/DESC)
|
||||
}] : [], // Default to an empty array if no sorting is defined
|
||||
"search": d.search.value, // Search query
|
||||
"status": deviceStatus
|
||||
"status": deviceStatus,
|
||||
"filters" : columnFilters
|
||||
}
|
||||
|
||||
}
|
||||
@@ -535,7 +721,8 @@ function initializeDatatable (status) {
|
||||
device.devSSID || "",
|
||||
device.devSourcePlugin || "",
|
||||
device.devPresentLastScan || "",
|
||||
device.devAlertDown || ""
|
||||
device.devAlertDown || "",
|
||||
device.devCustomProps || ""
|
||||
];
|
||||
|
||||
const newRow = [];
|
||||
@@ -652,6 +839,17 @@ function initializeDatatable (status) {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Custom Properties
|
||||
{targets: [mapIndx(26)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
if (!emptyArr.includes(cellData)){
|
||||
$(td).html (`<span>${renderCustomProps(cellData, rowData[mapIndx(11)])}<span>`);
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Favorite
|
||||
{targets: [mapIndx(4)],
|
||||
@@ -730,18 +928,18 @@ function initializeDatatable (status) {
|
||||
|
||||
// Save cookie Rows displayed, and Parameters rows & order
|
||||
$('#tableDevices').on( 'length.dt', function ( e, settings, len ) {
|
||||
setCookie ("nax_parTableRows", len, 129600); // save for 90 days
|
||||
setCache ("nax_parTableRows", len, 129600); // save for 90 days
|
||||
} );
|
||||
|
||||
$('#tableDevices').on( 'order.dt', function () {
|
||||
setCookie ("nax_parTableOrder", JSON.stringify (table.order()), 129600); // save for 90 days
|
||||
setCache ("nax_parTableOrder", JSON.stringify (table.order()), 129600); // save for 90 days
|
||||
} );
|
||||
|
||||
// add multi-edit button
|
||||
$('#multiEditPlc').append(
|
||||
`<button type="submit" id="multiEdit" class="btn btn-primary" style="display:none" onclick="multiEditDevices();">
|
||||
<i class="fa fa-pencil pointer" ></i> ${getString("Device_MultiEdit")}
|
||||
</button>`)
|
||||
`<span type="submit" id="multiEdit" class="pointer " style="display:none" onclick="multiEditDevices();">
|
||||
<a href="#"><i class="fa fa-pencil " ></i> ${getString("Device_MultiEdit")} </a>
|
||||
</span>`)
|
||||
|
||||
// Event listener for row selection in DataTable
|
||||
$('#tableDevices').on('click', 'tr', function (e) {
|
||||
@@ -771,6 +969,11 @@ function initializeDatatable (status) {
|
||||
|
||||
hideSpinner();
|
||||
|
||||
},
|
||||
createdRow: function(row, data, dataIndex) {
|
||||
// add devMac to the table row
|
||||
$(row).attr('my-devMac', data[mapIndx(11)]);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
@@ -782,9 +985,7 @@ function initializeDatatable (status) {
|
||||
// -----------------------------------------------------------------------------
|
||||
function handleLoadingDialog(needsReload = false)
|
||||
{
|
||||
|
||||
// console.log('needsReload:');
|
||||
// console.log(needsReload);
|
||||
// console.log(`needsReload: ${needsReload}`);
|
||||
|
||||
$.get('/php/server/query_logs.php?file=execution_queue.log&nocache=' + Date.now(), function(data) {
|
||||
|
||||
@@ -823,41 +1024,100 @@ function multiEditDevices()
|
||||
}
|
||||
|
||||
// redirect to the Maintenance section
|
||||
window.location.href = window.location.origin + '/maintenance.php#tab_multiEdit?macs=' + macs.slice(0, -1);
|
||||
window.location.href = './maintenance.php#tab_multiEdit?macs=' + macs.slice(0, -1);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Function collects shown devices from the DataTable
|
||||
function getMacsOfShownDevices() {
|
||||
|
||||
rows = $('#tableDevices')[0].rows
|
||||
macs = []
|
||||
rows = $('#tableDevices')[0].rows;
|
||||
macs = [];
|
||||
|
||||
// var devicesDataTableData = $('#tableDevices').dataTable().fnGetData();
|
||||
var devicesDataTableData = $('#tableDevices').DataTable().rows({ selected: false, page: 'current' }).data().toArray();
|
||||
|
||||
console.log(devicesDataTableData);
|
||||
|
||||
|
||||
var selectedDevices = [];
|
||||
|
||||
// first row is the heading, skip
|
||||
for (var i = 1; i < rows.length; i++) {
|
||||
|
||||
// console.log(rows[i]._DT_RowIndex);
|
||||
var rowIndex = rows[i]._DT_RowIndex;
|
||||
|
||||
selectedDevices.push(devicesDataTableData[rows[i]._DT_RowIndex]);
|
||||
}
|
||||
// Ensure the rowIndex is valid and within bounds of devicesDataTableData
|
||||
if (rowIndex >= 0 && rowIndex < devicesDataTableData.length) {
|
||||
selectedDevices.push(devicesDataTableData[rowIndex]);
|
||||
} else {
|
||||
console.log(`Invalid rowIndex: ${rowIndex} at row ${i}`);
|
||||
}
|
||||
}
|
||||
|
||||
for (var j = 0; j < selectedDevices.length; j++) {
|
||||
macs.push(selectedDevices[j][mapIndx(11)]); // mapIndx(11) == MAC
|
||||
// Ensure that selectedDevices[j] is not undefined
|
||||
if (selectedDevices[j]) {
|
||||
macs.push(selectedDevices[j][mapIndx(11)]); // mapIndx(11) == MAC
|
||||
} else {
|
||||
console.log(`selectedDevices[${j}] is undefined`);
|
||||
}
|
||||
}
|
||||
|
||||
return macs;
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Handle custom actions/properties on a device
|
||||
function renderCustomProps(custProps, mac) {
|
||||
// Decode and parse the custom properties
|
||||
|
||||
if (!isBase64(custProps)) {
|
||||
|
||||
console.error(`Unable to decode CustomProps for ${mac}`);
|
||||
console.error(custProps);
|
||||
|
||||
} else{
|
||||
const props = JSON.parse(atob(custProps));
|
||||
let html = "";
|
||||
|
||||
props.forEach((propGroup, index) => {
|
||||
const propMap = Object.fromEntries(
|
||||
propGroup.map(prop => Object.entries(prop)[0]) // Convert array of objects to key-value pairs
|
||||
);
|
||||
|
||||
if (propMap["CUSTPROP_show"] === true) { // Render if visible
|
||||
let onClickEvent = "";
|
||||
|
||||
switch (propMap["CUSTPROP_type"]) {
|
||||
case "show_notes":
|
||||
onClickEvent = `showModalOK('${propMap["CUSTPROP_name"]}','${propMap["CUSTPROP_notes"]}')`;
|
||||
break;
|
||||
case "link":
|
||||
onClickEvent = `window.location.href='${propMap["CUSTPROP_args"]}';`;
|
||||
break;
|
||||
case "link_new_tab":
|
||||
onClickEvent = `openInNewTab('${propMap["CUSTPROP_args"]}')`;
|
||||
break;
|
||||
case "run_plugin":
|
||||
onClickEvent = `alert('Not implemented')`;
|
||||
break;
|
||||
case "delete_dev":
|
||||
onClickEvent = `askDelDevDTInline('${mac}')`;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
html += `<div class="pointer devicePropAction" onclick="${onClickEvent}" title="${propMap["CUSTPROP_name"]} ${propMap["CUSTPROP_args"]}"> ${atob(propMap["CUSTPROP_icon"])} </div>`;
|
||||
}
|
||||
});
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
return "Error, check browser Console log"
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Update cache with shown devices before navigating away
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
<?php
|
||||
require 'php/templates/header.php';
|
||||
?>
|
||||
|
||||
<div id="donationsPage" class="content-wrapper">
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<h1 id="pageTitle">
|
||||
<i class="fa fa-heart"></i>
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
<!-- Main content ---------------------------------------------------------- -->
|
||||
<section class="content donations">
|
||||
<div id="donationsText" class="box box-solid"></div>
|
||||
<div class="content-header">
|
||||
<h3 class="box-title " id="donationsPlatforms"></h3>
|
||||
</div>
|
||||
<div class="box box-solid">
|
||||
<div class="box-body">
|
||||
<div class="col-sm-2">
|
||||
<a target="_blank" href="https://github.com/sponsors/jokob-sk">
|
||||
<img alt="Sponsor Me on GitHub" src="https://i.imgur.com/X6p5ACK.png" width="150px">
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<a target="_blank" href="https://www.buymeacoffee.com/jokobsk">
|
||||
<img alt="Buy Me A Coffee" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" width="117px" height="30px">
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<a target="_blank" href="https://www.patreon.com/user?u=84385063">
|
||||
<img alt="Support me on patreon" src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/82/Patreon_logo_with_wordmark.svg/512px-Patreon_logo_with_wordmark.svg.png" width="117px">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-header">
|
||||
<h3 class="box-title " id="donationsOthers"></h3>
|
||||
</div>
|
||||
<div class="box box-solid">
|
||||
<div class="box-body">
|
||||
<div class="col-sm-12">
|
||||
<ul>
|
||||
<li>Bitcoin: <code>1N8tupjeCK12qRVU2XrV17WvKK7LCawyZM</code></li>
|
||||
<li>Ethereum: <code>0x6e2749Cb42F4411bc98501406BdcD82244e3f9C7</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
</section>
|
||||
|
||||
</div> <!-- End of class="content-wrapper" -->
|
||||
|
||||
<script>
|
||||
function init()
|
||||
{
|
||||
$("#donationsText").html(getString("Donations_Text"))
|
||||
$("#pageTitle").append(getString("Donations_Title"))
|
||||
$("#donationsPlatforms").append(getString("Donations_Platforms"))
|
||||
$("#donationsOthers").append(getString("Donations_Others"))
|
||||
}
|
||||
|
||||
init();
|
||||
</script>
|
||||
|
||||
<?php
|
||||
require 'php/templates/footer.php';
|
||||
?>
|
||||
@@ -1,17 +1,3 @@
|
||||
<!--
|
||||
#---------------------------------------------------------------------------------#
|
||||
# NetAlertX #
|
||||
# Open Source Network Guard / WIFI & LAN intrusion detector #
|
||||
# #
|
||||
# events.php - Front module. Events page #
|
||||
#---------------------------------------------------------------------------------#
|
||||
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3 #
|
||||
# jokob-sk 2022 jokob.sk@gmail.com GNU GPLv3 #
|
||||
# leiweibau 2022 https://github.com/leiweibau GNU GPLv3 #
|
||||
# cvc90 2023 https://github.com/cvc90 GNU GPLv3 #
|
||||
#---------------------------------------------------------------------------------#
|
||||
-->
|
||||
|
||||
<?php
|
||||
require 'php/templates/header.php';
|
||||
?>
|
||||
@@ -19,26 +5,7 @@
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<h1 id="pageTitle">
|
||||
<i class="fa fa-bolt"></i>
|
||||
<?= lang('Events_Title');?>
|
||||
</h1>
|
||||
|
||||
<!-- period selector -->
|
||||
<span class="breadcrumb" style="top: 0px;">
|
||||
<select class="form-control" id="period" onchange="javascript: periodChanged();">
|
||||
<option value="1 day"><?= lang('Events_Periodselect_today');?></option>
|
||||
<option value="7 days"><?= lang('Events_Periodselect_LastWeek');?></option>
|
||||
<option value="1 month" selected><?= lang('Events_Periodselect_LastMonth');?></option>
|
||||
<option value="1 year"><?= lang('Events_Periodselect_LastYear');?></option>
|
||||
<option value="100 years"><?= lang('Events_Periodselect_All');?></option>
|
||||
</select>
|
||||
</span>
|
||||
</section>
|
||||
<div class="content-wrapper eventsPage">
|
||||
|
||||
<!-- Main content ---------------------------------------------------------- -->
|
||||
<section class="content">
|
||||
@@ -123,15 +90,31 @@
|
||||
<!-- datatable ------------------------------------------------------------- -->
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
|
||||
<div id="tableEventsBox" class="box">
|
||||
|
||||
<!-- box-header -->
|
||||
<div class="box-header">
|
||||
<h3 id="tableEventsTitle" class="box-title text-gray">Events</h3>
|
||||
<div class="box-header col-xs-12">
|
||||
<h3 id="tableEventsTitle" class="box-title text-gray col-xs-10">Events</h3>
|
||||
<div class="eventsPeriodSelectWrap col-xs-2">
|
||||
<select class="form-control" id="period" onchange="javascript: periodChanged();">
|
||||
<option value="1 day"><?= lang('Events_Periodselect_today');?></option>
|
||||
<option value="7 days"><?= lang('Events_Periodselect_LastWeek');?></option>
|
||||
<option value="1 month" selected><?= lang('Events_Periodselect_LastMonth');?></option>
|
||||
<option value="1 year"><?= lang('Events_Periodselect_LastYear');?></option>
|
||||
<option value="100 years"><?= lang('Events_Periodselect_All');?></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- table -->
|
||||
<div class="box-body table-responsive">
|
||||
|
||||
|
||||
|
||||
<table id="tableEvents" class="table table-bordered table-hover table-striped ">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
<?php
|
||||
require 'php/templates/header.php';
|
||||
require 'php/templates/notification.php';
|
||||
?>
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<?php require 'php/templates/notification.php'; ?>
|
||||
<h1 id="pageTitle">
|
||||
<i class="fa fa-question"></i>
|
||||
<?= lang('HelpFAQ_Title');?>
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
<!-- Main content ---------------------------------------------------------- -->
|
||||
<section class="content">
|
||||
<h4>
|
||||
|
||||
@@ -115,9 +115,9 @@ function cacheSettings()
|
||||
return new Promise((resolve, reject) => {
|
||||
if(!getCache('completedCalls').includes('cacheSettings'))
|
||||
{
|
||||
$.get('/php/server/query_json.php', { file: 'table_settings.json', nocache: Date.now() }, function(resSet) {
|
||||
$.get('php/server/query_json.php', { file: 'table_settings.json', nocache: Date.now() }, function(resSet) {
|
||||
|
||||
$.get('/php/server/query_json.php', { file: 'plugins.json', nocache: Date.now() }, function(resPlug) {
|
||||
$.get('php/server/query_json.php', { file: 'plugins.json', nocache: Date.now() }, function(resPlug) {
|
||||
|
||||
pluginsData = resPlug["data"];
|
||||
settingsData = resSet["data"];
|
||||
@@ -171,7 +171,7 @@ function cacheSettings()
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Get a setting value by key
|
||||
// Get a setting options value by key
|
||||
function getSettingOptions (key) {
|
||||
|
||||
// handle initial load to make sure everything is set-up and cached
|
||||
@@ -225,7 +225,7 @@ function cacheStrings() {
|
||||
});
|
||||
|
||||
// Fetch strings and translations from plugins
|
||||
$.get('/php/server/query_json.php', { file: 'table_plugins_language_strings.json', nocache: Date.now() })
|
||||
$.get('php/server/query_json.php', { file: 'table_plugins_language_strings.json', nocache: Date.now() })
|
||||
.done((pluginRes) => {
|
||||
const data = pluginRes["data"];
|
||||
|
||||
@@ -353,6 +353,30 @@ function getLangCode() {
|
||||
// String utilities
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// ----------------------------------------------------
|
||||
/**
|
||||
* Replaces double quotes within single-quoted strings, then converts all single quotes to double quotes,
|
||||
* while preserving the intended structure.
|
||||
*
|
||||
* @param {string} inputString - The input string to process.
|
||||
* @returns {string} - The processed string with transformations applied.
|
||||
*/
|
||||
function processQuotes(inputString) {
|
||||
// Step 1: Replace double quotes within single-quoted strings
|
||||
let tempString = inputString.replace(/'([^']*?)'/g, (match, p1) => {
|
||||
const escapedContent = p1.replace(/"/g, '_escaped_double_quote_'); // Temporarily replace double quotes
|
||||
return `'${escapedContent}'`;
|
||||
});
|
||||
|
||||
// Step 2: Replace all single quotes with double quotes
|
||||
tempString = tempString.replace(/'/g, '"');
|
||||
|
||||
// Step 3: Restore escaped double quotes
|
||||
const processedString = tempString.replace(/_escaped_double_quote_/g, "'");
|
||||
|
||||
return processedString;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
function jsonSyntaxHighlight(json) {
|
||||
if (typeof json != 'string') {
|
||||
@@ -386,6 +410,14 @@ function isValidBase64(str) {
|
||||
return invalidCharacters === '';
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Utility function to check if the value is already Base64
|
||||
function isBase64(value) {
|
||||
const base64Regex =
|
||||
/^(?:[A-Za-z0-9+\/]{4})*?(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/;
|
||||
return base64Regex.test(value);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
function isValidJSON(jsonString) {
|
||||
try {
|
||||
@@ -705,7 +737,7 @@ function forceLoadUrl(relativeUrl) {
|
||||
// -----------------------------------------------------------------------------
|
||||
function navigateToDeviceWithIp (ip) {
|
||||
|
||||
$.get('/php/server/query_json.php', { file: 'table_devices.json', nocache: Date.now() }, function(res) {
|
||||
$.get('php/server/query_json.php', { file: 'table_devices.json', nocache: Date.now() }, function(res) {
|
||||
|
||||
devices = res["data"];
|
||||
|
||||
@@ -717,7 +749,7 @@ function navigateToDeviceWithIp (ip) {
|
||||
{
|
||||
mac = obj.devMac;
|
||||
|
||||
window.open(window.location.origin +'/deviceDetails.php?mac=' + mac , "_blank");
|
||||
window.open('./deviceDetails.php?mac=' + mac , "_blank");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -744,6 +776,11 @@ function checkMacOrInternet(inputStr) {
|
||||
}
|
||||
}
|
||||
|
||||
// Alias
|
||||
function isValidMac(value) {
|
||||
return checkMacOrInternet(value);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Gte MAC from query string
|
||||
function getMac(){
|
||||
@@ -927,7 +964,7 @@ function cacheDevices()
|
||||
|
||||
// if(!getCache('completedCalls').includes('cacheDevices'))
|
||||
// {
|
||||
$.get('/php/server/query_json.php', { file: 'table_devices.json', nocache: Date.now() }, function(data) {
|
||||
$.get('php/server/query_json.php', { file: 'table_devices.json', nocache: Date.now() }, function(data) {
|
||||
|
||||
// console.log(data)
|
||||
|
||||
@@ -1293,7 +1330,7 @@ function clearCache() {
|
||||
// -----------------------------------------------------------------------------
|
||||
// Function to check if cache needs to be refreshed because of setting changes
|
||||
function checkSettingChanges() {
|
||||
$.get('/php/server/query_json.php', { file: 'app_state.json', nocache: Date.now() }, function(appState) {
|
||||
$.get('php/server/query_json.php', { file: 'app_state.json', nocache: Date.now() }, function(appState) {
|
||||
const importedMilliseconds = parseInt(appState["settingsImported"] * 1000);
|
||||
const lastReloaded = parseInt(sessionStorage.getItem(sessionStorageKey + '_time'));
|
||||
|
||||
@@ -1348,7 +1385,7 @@ async function waitForGraphQLServer() {
|
||||
// Returns 1 if running, 0 otherwise
|
||||
async function isGraphQLServerRunning() {
|
||||
try {
|
||||
const response = await $.get('/php/server/query_json.php', { file: 'app_state.json', nocache: Date.now()});
|
||||
const response = await $.get('php/server/query_json.php', { file: 'app_state.json', nocache: Date.now()});
|
||||
console.log("graphQLServerStarted: " + response["graphQLServerStarted"]);
|
||||
setCache("graphQLServerStarted", response["graphQLServerStarted"]);
|
||||
return response["graphQLServerStarted"];
|
||||
|
||||
@@ -32,7 +32,7 @@ function renderList(
|
||||
// remove first item containing the SQL query
|
||||
options.shift();
|
||||
|
||||
const apiUrl = `php/server/dbHelper.php?action=read&rawSql=${encodeURIComponent(sqlQuery)}`;
|
||||
const apiUrl = `php/server/dbHelper.php?action=read&rawSql=${btoa(encodeURIComponent(sqlQuery))}`;
|
||||
|
||||
$.get(apiUrl, function (sqlOptionsData) {
|
||||
|
||||
|
||||
70
front/js/device.js
Executable file
@@ -0,0 +1,70 @@
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function askDeleteDevice() {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ask delete device
|
||||
showModalWarning(
|
||||
getString("DevDetail_button_Delete"),
|
||||
getString("DevDetail_button_Delete_ask"),
|
||||
getString('Gen_Cancel'),
|
||||
getString('Gen_Delete'),
|
||||
'deleteDevice');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function askDelDevDTInline(mac) {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
showModalWarning(
|
||||
getString("DevDetail_button_Delete"),
|
||||
getString("DevDetail_button_Delete_ask"),
|
||||
getString('Gen_Cancel'),
|
||||
getString('Gen_Delete'),
|
||||
() => deleteDeviceByMac(mac))
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function deleteDevice() {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete device
|
||||
$.get('php/server/devices.php?action=deleteDevice&mac=' + mac, function (msg) {
|
||||
showMessage(msg);
|
||||
});
|
||||
|
||||
// refresh API
|
||||
updateApi("devices,appevents")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function deleteDeviceByMac(mac) {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// alert(mac)
|
||||
// return;
|
||||
|
||||
// Delete device
|
||||
$.get('php/server/devices.php?action=deleteDevice&mac=' + mac, function (msg) {
|
||||
showMessage(msg);
|
||||
});
|
||||
|
||||
// refresh API
|
||||
updateApi("devices,appevents")
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,8 @@ function showModalWarning(
|
||||
message,
|
||||
btnCancel = getString("Gen_Cancel"),
|
||||
btnOK = getString("Gen_Okay"),
|
||||
callbackFunction = null
|
||||
callbackFunction = null,
|
||||
triggeredBy = null
|
||||
) {
|
||||
// set captions
|
||||
$("#modal-warning-title").html(title);
|
||||
@@ -77,6 +78,10 @@ function showModalWarning(
|
||||
modalCallbackFunction = callbackFunction;
|
||||
}
|
||||
|
||||
if (triggeredBy != null) {
|
||||
$('#'+prefix).attr("data-myparam-triggered-by", triggeredBy)
|
||||
}
|
||||
|
||||
// Show modal
|
||||
$("#modal-warning").modal("show");
|
||||
}
|
||||
|
||||
@@ -191,14 +191,6 @@ function isSHA256(value) {
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Utility function to check if the value is already Base64
|
||||
function isBase64(value) {
|
||||
const base64Regex =
|
||||
/^(?:[A-Za-z0-9+\/]{4})*?(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/;
|
||||
return base64Regex.test(value);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Validation
|
||||
// -------------------------------------------------------------------
|
||||
@@ -245,6 +237,68 @@ function settingsCollectedCorrectly(settingsArray, settingsJSON_DB) {
|
||||
// Manipulating Editable List options
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Add row to datatable
|
||||
function addDataTableRow(el)
|
||||
{
|
||||
alert("a")
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Clone datatable row
|
||||
function cloneDataTableRow(el){
|
||||
|
||||
console.log(el);
|
||||
|
||||
const id = "NEWDEV_devCustomProps_table"; // Your table ID
|
||||
const table = $('#'+id).DataTable();
|
||||
|
||||
|
||||
// Get the 'my-index' attribute from the closest tr element
|
||||
const myIndex = parseInt($(el).closest("tr").attr("my-index"));
|
||||
|
||||
// Find the row in the table with the matching 'my-index'
|
||||
const row = table.rows().nodes().to$().filter(`[my-index="${myIndex}"]`).first().get(0);
|
||||
|
||||
// Clone the row (including its data and controls)
|
||||
let clonedRow = $(row).clone(true, true); // The true arguments copy the data and event handlers
|
||||
|
||||
|
||||
$(clonedRow).attr("my-index",table.rows().count())
|
||||
|
||||
|
||||
console.log(clonedRow);
|
||||
|
||||
|
||||
// Add the cloned row to the DataTable
|
||||
table.row.add(clonedRow[0]).draw();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Remove current datatable row
|
||||
function removeDataTableRow(el) {
|
||||
console.log(el);
|
||||
|
||||
const id = "NEWDEV_devCustomProps_table"; // Your table ID
|
||||
const table = $('#'+id).DataTable();
|
||||
|
||||
if(table.rows().count() > 1)
|
||||
{
|
||||
// Get the 'my-index' attribute from the closest tr element
|
||||
const myIndex = parseInt($(el).closest("tr").attr("my-index"));
|
||||
|
||||
// Find the row in the table with the matching 'my-index'
|
||||
const row = table.rows().nodes().to$().filter(`[my-index="${myIndex}"]`).first().get(0);
|
||||
|
||||
// Remove the row from the DataTable
|
||||
table.row(row).remove().draw();
|
||||
}
|
||||
else
|
||||
{
|
||||
showMessage (getString("CustProps_cant_remove"), 3000, "modal_red");
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Add item to list
|
||||
function addList(element, clearInput = true) {
|
||||
@@ -551,7 +605,7 @@ function overrideToggle(element) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Generate options or set options based on the provided parameters
|
||||
function generateOptionsOrSetOptions(
|
||||
setKey,
|
||||
@@ -559,14 +613,21 @@ function generateOptionsOrSetOptions(
|
||||
placeholder, // ID of the HTML element where dropdown should be rendered (will be replaced)
|
||||
processDataCallback, // Callback function to generate entries based on options
|
||||
targetField, // Target field or element where selected value should be applied or updated
|
||||
transformers = [] // Transformers to be applied to the values
|
||||
transformers = [], // Transformers to be applied to the values
|
||||
overrideOptions = null // override options if available
|
||||
) {
|
||||
|
||||
// console.log(setKey);
|
||||
|
||||
// NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
|
||||
options = arrayToObject(createArray(getSettingOptions(setKey)))
|
||||
// console.log(overrideOptions);
|
||||
// console.log( getSettingOptions(setKey));
|
||||
// console.log( setKey);
|
||||
|
||||
// NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
|
||||
options = arrayToObject(createArray(overrideOptions ? overrideOptions : getSettingOptions(setKey)))
|
||||
|
||||
|
||||
|
||||
// Call to render lists
|
||||
renderList(
|
||||
options,
|
||||
@@ -655,6 +716,8 @@ const handleElementOptions = (setKey, elementOptions, transformers, val) => {
|
||||
let onChange = "console.log('onChange - Not implemented');";
|
||||
let customParams = "";
|
||||
let customId = "";
|
||||
let columns = [];
|
||||
let base64Regex = "";
|
||||
|
||||
|
||||
elementOptions.forEach((option) => {
|
||||
@@ -708,6 +771,12 @@ const handleElementOptions = (setKey, elementOptions, transformers, val) => {
|
||||
if (option.customId) {
|
||||
customId = option.customId;
|
||||
}
|
||||
if (option.columns) {
|
||||
columns = option.columns;
|
||||
}
|
||||
if (option.base64Regex) {
|
||||
base64Regex = option.base64Regex;
|
||||
}
|
||||
});
|
||||
|
||||
if (transformers.includes("sha256")) {
|
||||
@@ -730,7 +799,9 @@ const handleElementOptions = (setKey, elementOptions, transformers, val) => {
|
||||
onClick,
|
||||
onChange,
|
||||
customParams,
|
||||
customId
|
||||
customId,
|
||||
columns,
|
||||
base64Regex
|
||||
};
|
||||
};
|
||||
|
||||
@@ -863,7 +934,7 @@ function genListWithInputSet(options, valuesArray, targetField, transformers, pl
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Generate the form control for setting
|
||||
function generateFormHtml(set, overrideValue) {
|
||||
function generateFormHtml(settingsData, set, overrideValue, overrideOptions, originalSetKey) {
|
||||
let inputHtml = '';
|
||||
|
||||
|
||||
@@ -871,14 +942,17 @@ function generateFormHtml(set, overrideValue) {
|
||||
const setKey = set['setKey'];
|
||||
const setType = set['setType'];
|
||||
|
||||
// if (setKey == '') {
|
||||
|
||||
// console.log(setType);
|
||||
// console.log(setKey);
|
||||
// console.log(overrideValue);
|
||||
// console.log(inVal);
|
||||
|
||||
// console.log(inVal);
|
||||
|
||||
// }
|
||||
|
||||
// Parse the setType JSON string
|
||||
const setTypeObject = JSON.parse(setType.replace(/'/g, '"'));
|
||||
const setTypeObject = JSON.parse(processQuotes(setType))
|
||||
const dataType = setTypeObject.dataType;
|
||||
const elements = setTypeObject.elements || [];
|
||||
|
||||
@@ -903,14 +977,23 @@ function generateFormHtml(set, overrideValue) {
|
||||
onClick,
|
||||
onChange,
|
||||
customParams,
|
||||
customId
|
||||
customId,
|
||||
columns,
|
||||
base64Regex
|
||||
} = handleElementOptions(setKey, elementOptions, transformers, inVal);
|
||||
|
||||
// Override value
|
||||
const val = valRes;
|
||||
let val = valRes;
|
||||
|
||||
// console.log(val);
|
||||
// if (setKey == '') {
|
||||
|
||||
// console.log(setType);
|
||||
// console.log(setKey);
|
||||
// console.log(overrideValue);
|
||||
// console.log(inVal);
|
||||
// console.log(val);
|
||||
|
||||
// }
|
||||
|
||||
// Generate HTML based on elementType
|
||||
switch (elementType) {
|
||||
@@ -921,20 +1004,21 @@ function generateFormHtml(set, overrideValue) {
|
||||
inputHtml += `<select onChange="settingsChanged();${onChange}"
|
||||
my-data-type="${dataType}"
|
||||
my-editable="${editable}"
|
||||
class="form-control ${addCss}"
|
||||
class="form-control ${addCss} ${cssClasses}"
|
||||
name="${setKey}"
|
||||
id="${setKey}"
|
||||
my-customparams="${customParams}"
|
||||
my-customid="${customId}"
|
||||
my-originalSetKey="${originalSetKey}"
|
||||
${multi}>
|
||||
<option value="" id="${setKey + "_temp_"}"></option>
|
||||
</select>`;
|
||||
|
||||
generateOptionsOrSetOptions(setKey, createArray(val), `${setKey}_temp_`, generateOptions, null, transformers);
|
||||
generateOptionsOrSetOptions(setKey, createArray(val), `${setKey}_temp_`, generateOptions, null, transformers, overrideOptions);
|
||||
break;
|
||||
|
||||
case 'input':
|
||||
const checked = val === 'True' || val === '1' ? 'checked' : '';
|
||||
const checked = val === 'True' || val === 'true' || val === '1' ? 'checked' : '';
|
||||
const inputClass = inputType === 'checkbox' ? 'checkbox' : 'form-control';
|
||||
|
||||
inputHtml += `<input
|
||||
@@ -943,6 +1027,8 @@ function generateFormHtml(set, overrideValue) {
|
||||
my-data-type="${dataType}"
|
||||
my-customparams="${customParams}"
|
||||
my-customid="${customId}"
|
||||
my-originalSetKey="${originalSetKey}"
|
||||
my-base64Regex="${base64Regex}"
|
||||
id="${setKey}${suffix}"
|
||||
type="${inputType}"
|
||||
value="${val}"
|
||||
@@ -957,6 +1043,7 @@ function generateFormHtml(set, overrideValue) {
|
||||
class="btn btn-primary ${cssClasses}"
|
||||
my-customparams="${customParams}"
|
||||
my-customid="${customId}"
|
||||
my-originalSetKey="${originalSetKey}"
|
||||
my-input-from="${sourceIds}"
|
||||
my-input-to="${setKey}"
|
||||
onclick="${onClick}">
|
||||
@@ -969,6 +1056,7 @@ function generateFormHtml(set, overrideValue) {
|
||||
class="form-control input"
|
||||
my-customparams="${customParams}"
|
||||
my-customid="${customId}"
|
||||
my-originalSetKey="${originalSetKey}"
|
||||
my-data-type="${dataType}"
|
||||
id="${setKey}"
|
||||
${readOnly}>${val}</textarea>`;
|
||||
@@ -979,10 +1067,116 @@ function generateFormHtml(set, overrideValue) {
|
||||
class="${cssClasses}"
|
||||
my-data-type="${dataType}"
|
||||
my-customparams="${customParams}"
|
||||
my-customid="${customId}">
|
||||
${getString(getStringKey)}
|
||||
my-customid="${customId}"
|
||||
my-originalSetKey="${originalSetKey}"
|
||||
onclick="${onClick}">
|
||||
${getString(getStringKey)}${placeholder}
|
||||
</span>`;
|
||||
break;
|
||||
case 'datatable':
|
||||
|
||||
const tableId = `${setKey}_table`;
|
||||
let datatableHtml = `<table id="${tableId}" class="table table-striped">`;
|
||||
|
||||
// Dynamic array creation
|
||||
let emptyVal = [];
|
||||
|
||||
let columnSettings = [];
|
||||
|
||||
// Generate table headers
|
||||
datatableHtml += '<thead><tr>';
|
||||
|
||||
columns.forEach(column => {
|
||||
let columnSetting = getSetObject(settingsData, column.settingKey) || {};
|
||||
|
||||
datatableHtml += `<th>${columnSetting.setName}</th>`;
|
||||
|
||||
if(column.typeOverride)
|
||||
{
|
||||
columnSetting["setType"] = JSON.stringify(column.typeOverride);
|
||||
}
|
||||
|
||||
if(column.optionsOverride)
|
||||
{
|
||||
if (column.optionsOverride.startsWith("setting.")) {
|
||||
columnSetting["setOptions"] = getSetting(column.optionsOverride.replace("setting.",""));
|
||||
} else {
|
||||
columnSetting["setOptions"] = column.optionsOverride;
|
||||
}
|
||||
}
|
||||
|
||||
columnSettings.push(columnSetting)
|
||||
|
||||
// helper for if val is empty
|
||||
emptyVal.push('');
|
||||
});
|
||||
datatableHtml += '</tr></thead>';
|
||||
|
||||
// Generate table body
|
||||
datatableHtml += '<tbody>';
|
||||
|
||||
if(val.length > 0 && isBase64(val))
|
||||
{
|
||||
val = atob(val)
|
||||
// console.log(val);
|
||||
val = JSON.parse(val)
|
||||
}else{
|
||||
// init empty
|
||||
val = [emptyVal]
|
||||
}
|
||||
|
||||
let index = 0;
|
||||
val.forEach(rowData => {
|
||||
datatableHtml += `<tr my-index="${index}">`;
|
||||
|
||||
let j = 0;
|
||||
columnSettings.forEach(set => {
|
||||
// Extract the value for the current column based on the new structure
|
||||
let columnOverrideValue = rowData[j] && Object.values(rowData[j])[0];
|
||||
|
||||
if(columnOverrideValue == undefined)
|
||||
{
|
||||
columnOverrideValue = ""
|
||||
}
|
||||
|
||||
// Create unique key to prevent dropdown data duplication
|
||||
const oldKey = set["setKey"];
|
||||
set["setKey"] = oldKey + "_" + index;
|
||||
|
||||
// Generate the cell HTML using the extracted value
|
||||
const cellHtml = generateFormHtml(
|
||||
settingsData,
|
||||
set,
|
||||
columnOverrideValue.toString(),
|
||||
set["setOptions"],
|
||||
oldKey
|
||||
);
|
||||
datatableHtml += `<td> <div class="input-group"> ${cellHtml} </div></td>`;
|
||||
|
||||
// Restore the original key
|
||||
set["setKey"] = oldKey;
|
||||
|
||||
j++;
|
||||
});
|
||||
datatableHtml += '</tr>';
|
||||
index++;
|
||||
});
|
||||
|
||||
|
||||
datatableHtml += '</tbody></table>';
|
||||
|
||||
inputHtml += datatableHtml;
|
||||
|
||||
// Initialize DataTable with jQuery
|
||||
$(document).ready(() => {
|
||||
$(`#${tableId}`).DataTable({
|
||||
ordering: false, // Disables sorting on all columns
|
||||
searching: false, // Disables the search box
|
||||
dom: "<'top'rt><'bottom'ipl>", // Move length dropdown to the bottom
|
||||
});
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn(`🟥 Unknown element type: ${elementType}`);
|
||||
@@ -991,10 +1185,6 @@ function generateFormHtml(set, overrideValue) {
|
||||
|
||||
// Generate event HTML if applicable
|
||||
let eventsHtml = '';
|
||||
|
||||
// console.log(setTypeObject);
|
||||
|
||||
// console.log(set);
|
||||
|
||||
const eventsList = createArray(set['setEvents']);
|
||||
// inline buttons events
|
||||
@@ -1019,4 +1209,68 @@ function generateFormHtml(set, overrideValue) {
|
||||
return inputHtml + eventsHtml;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Return the setting object by setKey
|
||||
function getSetObject(settingsData, setKey) {
|
||||
|
||||
found = false;
|
||||
result = ""
|
||||
|
||||
settingsData.forEach(function(set) {
|
||||
|
||||
if (set.setKey == setKey) {
|
||||
// console.log(set);
|
||||
|
||||
result = set;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if(result == "")
|
||||
{
|
||||
console.error(settingsData);
|
||||
console.error(`Setting not found: ${setKey}`);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
// Collect DataTable data
|
||||
function collectTableData(tableSelector) {
|
||||
const table = $(tableSelector).DataTable();
|
||||
|
||||
let tableData = [];
|
||||
|
||||
table.rows().every(function () {
|
||||
const rowData = [];
|
||||
const cells = $(this.node()).find('td');
|
||||
|
||||
cells.each((index, cell) => {
|
||||
const input = $(cell).find('input, select, textarea');
|
||||
|
||||
if (input.length) {
|
||||
if (input.attr('type') === 'checkbox') {
|
||||
// For checkboxes, check if they are checked
|
||||
rowData[index] = { [input.attr("my-originalsetkey")] : input.prop('checked') };
|
||||
} else {
|
||||
// Generic sync for other inputs (text, select, textarea)
|
||||
rowData[index] = { [input.attr("my-originalsetkey")] : input.val().replace(/'/g, "").replace(/"/g, "") };
|
||||
}
|
||||
} else {
|
||||
// Handle plain text
|
||||
// rowData[index] = { [input.attr("my-originalsetkey")] : $(cell).text()};
|
||||
console.log(`Nothig to collect: ${$(cell).html()}`)
|
||||
}
|
||||
});
|
||||
|
||||
tableData.push(rowData);
|
||||
});
|
||||
|
||||
return tableData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -97,12 +97,54 @@ function generateApiToken(elem, length) {
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------
|
||||
// Generate a random N-byte hexadecimal key
|
||||
function getRandomBytes(elem, length) {
|
||||
|
||||
// Retrieve and parse custom parameters from the element
|
||||
let params = $(elem).attr("my-customparams")?.split(',').map(param => param.trim());
|
||||
if (params && params.length >= 1) {
|
||||
var targetElementID = params[0]; // Get the target element's ID
|
||||
}
|
||||
|
||||
let targetElement = $('#' + targetElementID);
|
||||
|
||||
// Generate random bytes
|
||||
const array = new Uint8Array(length);
|
||||
window.crypto.getRandomValues(array);
|
||||
|
||||
// Convert bytes to hexadecimal string
|
||||
let hexString = Array.from(array, byte =>
|
||||
byte.toString(16).padStart(2, '0')
|
||||
).join('');
|
||||
|
||||
// Format hexadecimal string with hyphens
|
||||
let formattedHex = hexString.match(/.{1,2}/g).join('-');
|
||||
|
||||
console.log(formattedHex);
|
||||
// console.log($(`#${targetInput}`).val());
|
||||
|
||||
// Set the formatted key value to the input field
|
||||
targetElement.val(formattedHex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------
|
||||
// Updates the icon preview
|
||||
function updateAllIconPreviews() {
|
||||
$(".iconInputVal").each((index, el)=>{
|
||||
updateIconPreview(el)
|
||||
})
|
||||
}
|
||||
|
||||
// ----------------------------------------------
|
||||
// Updates the icon preview
|
||||
function updateIconPreview(elem) {
|
||||
const targetElement = $('[my-customid="NEWDEV_devIcon_preview"]');
|
||||
const iconInput = $("#NEWDEV_devIcon");
|
||||
|
||||
const previewSpan = $(elem).parent().find(".iconPreview");
|
||||
const iconInput = $(elem);
|
||||
|
||||
let attempts = 0;
|
||||
|
||||
@@ -110,10 +152,10 @@ function updateIconPreview(elem) {
|
||||
let value = iconInput.val();
|
||||
|
||||
if (value) {
|
||||
targetElement.html(atob(value));
|
||||
previewSpan.html(atob(value));
|
||||
iconInput.off('change input').on('change input', function () {
|
||||
let newValue = $(this).val();
|
||||
targetElement.html(atob(newValue));
|
||||
let newValue = $(elem).val();
|
||||
previewSpan.html(atob(newValue));
|
||||
});
|
||||
return; // Stop retrying if successful
|
||||
}
|
||||
@@ -129,7 +171,47 @@ function updateIconPreview(elem) {
|
||||
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
|
||||
@@ -189,38 +271,65 @@ function copyToClipboard(buttonElement) {
|
||||
// Simple Sortable Table columns
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Function to handle column sorting when a user clicks on a table header
|
||||
function sortColumn(element) {
|
||||
var th = $(element).closest('th');
|
||||
var table = th.closest('table');
|
||||
var columnIndex = th.index();
|
||||
var ascending = !th.data('asc');
|
||||
var th = $(element).closest('th'); // Get the clicked table header
|
||||
var table = th.closest('table'); // Find the closest table
|
||||
var columnIndex = th.index(); // Get the index of the column
|
||||
var ascending = !th.data('asc'); // Toggle sorting order
|
||||
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) {
|
||||
var tbody = table.find('tbody');
|
||||
var rows = tbody.find('tr').toArray().sort(comparer(columnIndex));
|
||||
var tbody = table.find('tbody'); // Get the table body
|
||||
var rows = tbody.find('tr').toArray().sort(comparer(columnIndex)); // Convert rows to an array and sort
|
||||
if (!ascending) {
|
||||
rows = rows.reverse();
|
||||
rows = rows.reverse(); // Reverse order if descending
|
||||
}
|
||||
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) {
|
||||
return function(a, b) {
|
||||
return function (a, b) {
|
||||
var valA = getCellValue(a, 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) {
|
||||
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
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -449,7 +558,7 @@ function showIconSelection() {
|
||||
iconDiv.addEventListener('click', () => {
|
||||
selectElement.value = value; // Update the select element value
|
||||
$(`#${modalId}`).modal('hide'); // Hide the modal
|
||||
updateIconPreview();
|
||||
updateAllIconPreviews();
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -466,8 +575,52 @@ function showIconSelection() {
|
||||
|
||||
}
|
||||
|
||||
// "Device_TableHead_Owner",
|
||||
// "Device_TableHead_Type",
|
||||
// "Device_TableHead_Group",
|
||||
// "Device_TableHead_Status",
|
||||
// "Device_TableHead_Location",
|
||||
// "Device_TableHead_Vendor",
|
||||
// "Device_TableHead_SyncHubNodeName",
|
||||
// "Device_TableHead_NetworkSite",
|
||||
// "Device_TableHead_SSID",
|
||||
// "Device_TableHead_SourcePlugin"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Get teh correct db column code name based on table header title string
|
||||
function getColumnNameFromLangString(headStringKey) {
|
||||
columnNameMap = {
|
||||
"Device_TableHead_Name": "devName",
|
||||
"Device_TableHead_Owner": "devOwner",
|
||||
"Device_TableHead_Type": "devType",
|
||||
"Device_TableHead_Icon": "devIcon",
|
||||
"Device_TableHead_Favorite": "devFavorite",
|
||||
"Device_TableHead_Group": "devGroup",
|
||||
"Device_TableHead_FirstSession": "devFirstConnection",
|
||||
"Device_TableHead_LastSession": "devLastConnection",
|
||||
"Device_TableHead_LastIP": "devLastIP",
|
||||
"Device_TableHead_MAC": "devMac",
|
||||
"Device_TableHead_Status": "devStatus",
|
||||
"Device_TableHead_MAC_full": "devMac",
|
||||
"Device_TableHead_LastIPOrder": "devIpLong",
|
||||
"Device_TableHead_Rowid": "rowid",
|
||||
"Device_TableHead_Parent_MAC": "devParentMAC",
|
||||
"Device_TableHead_Connected_Devices": "devParentChildrenCount",
|
||||
"Device_TableHead_Location": "devLocation",
|
||||
"Device_TableHead_Vendor": "devVendor",
|
||||
"Device_TableHead_Port": "devParentPort",
|
||||
"Device_TableHead_GUID": "devGUID",
|
||||
"Device_TableHead_SyncHubNodeName": "devSyncHubNode",
|
||||
"Device_TableHead_NetworkSite": "devSite",
|
||||
"Device_TableHead_SSID": "devSSID",
|
||||
"Device_TableHead_SourcePlugin": "devSourcePlugin",
|
||||
"Device_TableHead_PresentLastScan": "devPresentLastScan",
|
||||
"Device_TableHead_AlertDown": "devAlertDown",
|
||||
"Device_TableHead_CustomProps": "devCustomProps"
|
||||
};
|
||||
|
||||
return columnNameMap[headStringKey] || "";
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
48
front/lib/bcrypt/bcrypt.min.js
vendored
Executable file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
bcrypt.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
|
||||
Released under the Apache License, Version 2.0
|
||||
see: https://github.com/dcodeIO/bcrypt.js for details
|
||||
*/
|
||||
(function(u,r){"function"===typeof define&&define.amd?define([],r):"function"===typeof require&&"object"===typeof module&&module&&module.exports?module.exports=r():(u.dcodeIO=u.dcodeIO||{}).bcrypt=r()})(this,function(){function u(e){if("undefined"!==typeof module&&module&&module.exports)try{return require("crypto").randomBytes(e)}catch(d){}try{var c;(self.crypto||self.msCrypto).getRandomValues(c=new Uint32Array(e));return Array.prototype.slice.call(c)}catch(b){}if(!w)throw Error("Neither WebCryptoAPI nor a crypto module is available. Use bcrypt.setRandomFallback to set an alternative");
|
||||
return w(e)}function r(e,d){for(var c=0,b=0,a=0,f=e.length;a<f;++a)e.charCodeAt(a)===d.charCodeAt(a)?++c:++b;return 0>c?!1:0===b}function H(e){var d=[],c=0;I.encodeUTF16toUTF8(function(){return c>=e.length?null:e.charCodeAt(c++)},function(b){d.push(b)});return d}function x(e,d){var c=0,b=[],a,f;if(0>=d||d>e.length)throw Error("Illegal len: "+d);for(;c<d;){a=e[c++]&255;b.push(s[a>>2&63]);a=(a&3)<<4;if(c>=d){b.push(s[a&63]);break}f=e[c++]&255;a|=f>>4&15;b.push(s[a&63]);a=(f&15)<<2;if(c>=d){b.push(s[a&
|
||||
63]);break}f=e[c++]&255;a|=f>>6&3;b.push(s[a&63]);b.push(s[f&63])}return b.join("")}function B(e,d){var c=0,b=e.length,a=0,f=[],g,m,h;if(0>=d)throw Error("Illegal len: "+d);for(;c<b-1&&a<d;){h=e.charCodeAt(c++);g=h<q.length?q[h]:-1;h=e.charCodeAt(c++);m=h<q.length?q[h]:-1;if(-1==g||-1==m)break;h=g<<2>>>0;h|=(m&48)>>4;f.push(z(h));if(++a>=d||c>=b)break;h=e.charCodeAt(c++);g=h<q.length?q[h]:-1;if(-1==g)break;h=(m&15)<<4>>>0;h|=(g&60)>>2;f.push(z(h));if(++a>=d||c>=b)break;h=e.charCodeAt(c++);m=h<q.length?
|
||||
q[h]:-1;h=(g&3)<<6>>>0;h|=m;f.push(z(h));++a}b=[];for(c=0;c<a;c++)b.push(f[c].charCodeAt(0));return b}function v(e,d,c,b){var a,f=e[d],g=e[d+1],f=f^c[0];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^c[1];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[2];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^c[3];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[4];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|
|
||||
f>>8&255];a+=b[768|f&255];g=g^a^c[5];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[6];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^c[7];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[8];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^c[9];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[10];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^
|
||||
c[11];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[12];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^c[13];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[14];a=b[f>>>24];a+=b[256|f>>16&255];a^=b[512|f>>8&255];a+=b[768|f&255];g=g^a^c[15];a=b[g>>>24];a+=b[256|g>>16&255];a^=b[512|g>>8&255];a+=b[768|g&255];f=f^a^c[16];e[d]=g^c[17];e[d+1]=f;return e}function t(e,d){for(var c=0,b=0;4>c;++c)b=b<<8|e[d]&255,d=(d+1)%e.length;
|
||||
return{key:b,offp:d}}function C(e,d,c){for(var b=0,a=[0,0],f=d.length,g=c.length,m,h=0;h<f;h++)m=t(e,b),b=m.offp,d[h]^=m.key;for(h=0;h<f;h+=2)a=v(a,0,d,c),d[h]=a[0],d[h+1]=a[1];for(h=0;h<g;h+=2)a=v(a,0,d,c),c[h]=a[0],c[h+1]=a[1]}function J(e,d,c,b){for(var a=0,f=[0,0],g=c.length,m=b.length,h,l=0;l<g;l++)h=t(d,a),a=h.offp,c[l]^=h.key;for(l=a=0;l<g;l+=2)h=t(e,a),a=h.offp,f[0]^=h.key,h=t(e,a),a=h.offp,f[1]^=h.key,f=v(f,0,c,b),c[l]=f[0],c[l+1]=f[1];for(l=0;l<m;l+=2)h=t(e,a),a=h.offp,f[0]^=h.key,h=t(e,
|
||||
a),a=h.offp,f[1]^=h.key,f=v(f,0,c,b),b[l]=f[0],b[l+1]=f[1]}function D(e,d,c,b,a){function f(){a&&a(n/c);if(n<c)for(var h=Date.now();n<c&&!(n+=1,C(e,l,k),C(d,l,k),100<Date.now()-h););else{for(n=0;64>n;n++)for(y=0;y<m>>1;y++)v(g,y<<1,l,k);h=[];for(n=0;n<m;n++)h.push((g[n]>>24&255)>>>0),h.push((g[n]>>16&255)>>>0),h.push((g[n]>>8&255)>>>0),h.push((g[n]&255)>>>0);if(b){b(null,h);return}return h}b&&p(f)}var g=E.slice(),m=g.length,h;if(4>c||31<c){h=Error("Illegal number of rounds (4-31): "+c);if(b){p(b.bind(this,
|
||||
h));return}throw h;}if(16!==d.length){h=Error("Illegal salt length: "+d.length+" != 16");if(b){p(b.bind(this,h));return}throw h;}c=1<<c>>>0;var l,k,n=0,y;Int32Array?(l=new Int32Array(F),k=new Int32Array(G)):(l=F.slice(),k=G.slice());J(d,e,l,k);if("undefined"!==typeof b)f();else for(;;)if("undefined"!==typeof(h=f()))return h||[]}function A(e,d,c,b){function a(a){var b=[];b.push("$2");"a"<=f&&b.push(f);b.push("$");10>l&&b.push("0");b.push(l.toString());b.push("$");b.push(x(k,k.length));b.push(x(a,4*
|
||||
E.length-1));return b.join("")}if("string"!==typeof e||"string"!==typeof d){b=Error("Invalid string / salt: Not a string");if(c){p(c.bind(this,b));return}throw b;}var f,g;if("$"!==d.charAt(0)||"2"!==d.charAt(1)){b=Error("Invalid salt version: "+d.substring(0,2));if(c){p(c.bind(this,b));return}throw b;}if("$"===d.charAt(2))f=String.fromCharCode(0),g=3;else{f=d.charAt(2);if("a"!==f&&"b"!==f&&"y"!==f||"$"!==d.charAt(3)){b=Error("Invalid salt revision: "+d.substring(2,4));if(c){p(c.bind(this,b));return}throw b;
|
||||
}g=4}if("$"<d.charAt(g+2)){b=Error("Missing salt rounds");if(c){p(c.bind(this,b));return}throw b;}var m=10*parseInt(d.substring(g,g+1),10),h=parseInt(d.substring(g+1,g+2),10),l=m+h;d=d.substring(g+3,g+25);e=H(e+("a"<=f?"\x00":""));var k=B(d,16);if("undefined"==typeof c)return a(D(e,k,l));D(e,k,l,function(b,d){b?c(b,null):c(null,a(d))},b)}var k={},w=null;try{u(1)}catch(K){}w=null;k.setRandomFallback=function(e){w=e};k.genSaltSync=function(e,d){e=e||10;if("number"!==typeof e)throw Error("Illegal arguments: "+
|
||||
typeof e+", "+typeof d);4>e?e=4:31<e&&(e=31);var c=[];c.push("$2a$");10>e&&c.push("0");c.push(e.toString());c.push("$");c.push(x(u(16),16));return c.join("")};k.genSalt=function(e,d,c){function b(a){p(function(){try{a(null,k.genSaltSync(e))}catch(b){a(b)}})}"function"===typeof d&&(c=d,d=void 0);"function"===typeof e&&(c=e,e=void 0);if("undefined"===typeof e)e=10;else if("number"!==typeof e)throw Error("illegal arguments: "+typeof e);if(c){if("function"!==typeof c)throw Error("Illegal callback: "+
|
||||
typeof c);b(c)}else return new Promise(function(a,c){b(function(b,d){b?c(b):a(d)})})};k.hashSync=function(e,d){"undefined"===typeof d&&(d=10);"number"===typeof d&&(d=k.genSaltSync(d));if("string"!==typeof e||"string"!==typeof d)throw Error("Illegal arguments: "+typeof e+", "+typeof d);return A(e,d)};k.hash=function(e,d,c,b){function a(a){"string"===typeof e&&"number"===typeof d?k.genSalt(d,function(c,d){A(e,d,a,b)}):"string"===typeof e&&"string"===typeof d?A(e,d,a,b):p(a.bind(this,Error("Illegal arguments: "+
|
||||
typeof e+", "+typeof d)))}if(c){if("function"!==typeof c)throw Error("Illegal callback: "+typeof c);a(c)}else return new Promise(function(b,c){a(function(a,d){a?c(a):b(d)})})};k.compareSync=function(e,d){if("string"!==typeof e||"string"!==typeof d)throw Error("Illegal arguments: "+typeof e+", "+typeof d);return 60!==d.length?!1:r(k.hashSync(e,d.substr(0,d.length-31)),d)};k.compare=function(e,d,c,b){function a(a){"string"!==typeof e||"string"!==typeof d?p(a.bind(this,Error("Illegal arguments: "+typeof e+
|
||||
", "+typeof d))):60!==d.length?p(a.bind(this,null,!1)):k.hash(e,d.substr(0,29),function(b,c){b?a(b):a(null,r(c,d))},b)}if(c){if("function"!==typeof c)throw Error("Illegal callback: "+typeof c);a(c)}else return new Promise(function(b,c){a(function(a,d){a?c(a):b(d)})})};k.getRounds=function(e){if("string"!==typeof e)throw Error("Illegal arguments: "+typeof e);return parseInt(e.split("$")[2],10)};k.getSalt=function(e){if("string"!==typeof e)throw Error("Illegal arguments: "+typeof e);if(60!==e.length)throw Error("Illegal hash length: "+
|
||||
e.length+" != 60");return e.substring(0,29)};var p="undefined"!==typeof process&&process&&"function"===typeof process.nextTick?"function"===typeof setImmediate?setImmediate:process.nextTick:setTimeout,s="./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split(""),q=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,54,55,56,57,58,59,60,61,62,63,-1,-1,-1,-1,-1,-1,-1,2,3,4,5,6,7,8,9,10,11,12,
|
||||
13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,-1,-1,-1,-1,-1,-1,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,-1,-1,-1,-1,-1],z=String.fromCharCode,I=function(){var e={MAX_CODEPOINT:1114111,encodeUTF8:function(d,c){var b=null;"number"===typeof d&&(b=d,d=function(){return null});for(;null!==b||null!==(b=d());)128>b?c(b&127):(2048>b?c(b>>6&31|192):(65536>b?c(b>>12&15|224):(c(b>>18&7|240),c(b>>12&63|128)),c(b>>6&63|128)),c(b&63|128)),b=null},decodeUTF8:function(d,c){for(var b,
|
||||
a,f,e,k=function(a){a=a.slice(0,a.indexOf(null));var b=Error(a.toString());b.name="TruncatedError";b.bytes=a;throw b;};null!==(b=d());)if(0===(b&128))c(b);else if(192===(b&224))null===(a=d())&&k([b,a]),c((b&31)<<6|a&63);else if(224===(b&240))null!==(a=d())&&null!==(f=d())||k([b,a,f]),c((b&15)<<12|(a&63)<<6|f&63);else if(240===(b&248))null!==(a=d())&&null!==(f=d())&&null!==(e=d())||k([b,a,f,e]),c((b&7)<<18|(a&63)<<12|(f&63)<<6|e&63);else throw RangeError("Illegal starting byte: "+b);},UTF16toUTF8:function(d,
|
||||
c){for(var b,a=null;null!==(b=null!==a?a:d());)55296<=b&&57343>=b&&null!==(a=d())&&56320<=a&&57343>=a?(c(1024*(b-55296)+a-56320+65536),a=null):c(b);null!==a&&c(a)},UTF8toUTF16:function(d,c){var b=null;"number"===typeof d&&(b=d,d=function(){return null});for(;null!==b||null!==(b=d());)65535>=b?c(b):(b-=65536,c((b>>10)+55296),c(b%1024+56320)),b=null},encodeUTF16toUTF8:function(d,c){e.UTF16toUTF8(d,function(b){e.encodeUTF8(b,c)})},decodeUTF8toUTF16:function(d,c){e.decodeUTF8(d,function(b){e.UTF8toUTF16(b,
|
||||
c)})},calculateCodePoint:function(d){return 128>d?1:2048>d?2:65536>d?3:4},calculateUTF8:function(d){for(var c,b=0;null!==(c=d());)b+=e.calculateCodePoint(c);return b},calculateUTF16asUTF8:function(d){var c=0,b=0;e.UTF16toUTF8(d,function(a){++c;b+=e.calculateCodePoint(a)});return[c,b]}};return e}();Date.now=Date.now||function(){return+new Date};var F=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,
|
||||
3041331479,2450970073,2306472731],G=[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,
|
||||
289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,
|
||||
1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,
|
||||
442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,
|
||||
3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,
|
||||
48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946,1266315497,3048417604,3681880366,3289982499,290971E4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,
|
||||
1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,
|
||||
613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,
|
||||
2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,
|
||||
1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,
|
||||
4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055,3913112168,
|
||||
2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,
|
||||
499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,
|
||||
3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,
|
||||
309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,
|
||||
1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,
|
||||
2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504,976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,
|
||||
2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,
|
||||
3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,
|
||||
3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409E3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,
|
||||
3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,
|
||||
1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462],E=[1332899944,1700884034,1701343084,1684370003,1668446532,
|
||||
1869963892];k.encodeBase64=x;k.decodeBase64=B;return k});
|
||||
4178
front/lib/treeviz/bundle.js
Executable file
1
front/lib/treeviz/bundle.js.map
Executable file
@@ -1,47 +1,16 @@
|
||||
<?php
|
||||
#---------------------------------------------------------------------------------#
|
||||
# NetAlertX #
|
||||
# Open Source Network Guard / WIFI & LAN intrusion detector #
|
||||
# #
|
||||
# maintenance.php - Front module. Server side. Maintenance #
|
||||
#---------------------------------------------------------------------------------#
|
||||
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3 #
|
||||
# jokob-sk 2022 jokob.sk@gmail.com GNU GPLv3 #
|
||||
# leiweibau 2022 https://github.com/leiweibau GNU GPLv3 #
|
||||
# cvc90 2023 https://github.com/cvc90 GNU GPLv3 #
|
||||
#---------------------------------------------------------------------------------#
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
?>
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
require 'php/templates/header.php';
|
||||
require 'php/templates/notification.php';
|
||||
?>
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
|
||||
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
<div class="content-wrapper" id="maintenancePage">
|
||||
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<?php require 'php/templates/notification.php'; ?>
|
||||
<h1 id="pageTitle">
|
||||
<i class="fa fa-wrench"></i>
|
||||
<?= lang('Maintenance_Title');?>
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
<!-- Main content ---------------------------------------------------------- -->
|
||||
<section class="content">
|
||||
<!-- Main content ---------------------------------------------------------- -->
|
||||
<section class="content">
|
||||
|
||||
|
||||
<?php
|
||||
<?php
|
||||
|
||||
// Size and last mod of DB ------------------------------------------------------
|
||||
|
||||
@@ -91,10 +60,11 @@ $db->close();
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_info_table_cell" style="min-width: 140px"><?= lang('Maintenance_version');?>
|
||||
<a href="https://github.com/jokob-sk/NetAlertX/blob/main/docs/VERSIONS.md" target="_blank"> <span><i class="fa fa-circle-question"></i></a><span>
|
||||
|
||||
</div>
|
||||
<div class="db_info_table_cell">
|
||||
<div class="version" id="version" data-build-time="<?php echo file_get_contents( "buildtimestamp.txt");?>"><?php echo '<span id="new-version-text" class="myhidden">' .lang('Maintenance_new_version').'</span>'.'<span id="current-version-text" class="myhidden">' .lang('Maintenance_current_version').'</span>';?></div>
|
||||
<div class="version" id="version" data-build-time="<?php echo file_get_contents( "buildtimestamp.txt");?>">
|
||||
<?php echo '<span id="new-version-text" class="myhidden"><i class="fa-solid fa-rocket fa-beat"></i> ' .lang('Maintenance_new_version').'</span>'.'<span id="current-version-text" class="myhidden">' .lang('Maintenance_current_version').'</span>';?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
@@ -209,26 +179,38 @@ $db->close();
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" id="tab_BackupRestore">
|
||||
<div class="db_info_table">
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnExportCSV" onclick="ExportCSV()"><?= lang('Maintenance_Tool_ExportCSV');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ExportCSV_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportCSV" onclick="askImportCSV()"><?= lang('Maintenance_Tool_ImportCSV');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ImportCSV_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportPastedCSV" onclick="askImportPastedCSV()"><?= lang('Maintenance_Tool_ImportPastedCSV');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ImportPastedCSV_text');?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="db_info_table">
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnExportCSV" onclick="ExportCSV()"><?= lang('Maintenance_Tool_ExportCSV');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ExportCSV_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportCSV" onclick="askImportCSV()"><?= lang('Maintenance_Tool_ImportCSV');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ImportCSV_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportPastedCSV" onclick="askImportPastedCSV()"><?= lang('Maintenance_Tool_ImportPastedCSV');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ImportPastedCSV_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnDownloadConfig" onclick="DownloadConfig()"><?= lang('Maintenance_Tool_DownloadConfig');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_DownloadConfig_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportPastedConfig" onclick="askImportPastedConfig()"><?= lang('Maintenance_Tool_ImportPastedConfig');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ImportPastedConfig_text');?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ---------------------------Logging-------------------------------------------- -->
|
||||
<div class="tab-pane" id="tab_Logging">
|
||||
@@ -445,6 +427,44 @@ function restartBackend() {
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Import pasted Config ASK
|
||||
function askImportPastedConfig() {
|
||||
|
||||
// Add new icon as base64 string
|
||||
showModalInput ('<i class="fa fa-square-plus pointer"></i> <?= lang('Maintenance_Tool_ImportConfig_noti');?>', '<?= lang('Maintenance_Tool_ImportPastedConfig_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', 'UploadConfig');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Upload Settings Config
|
||||
function UploadConfig()
|
||||
{
|
||||
// alert("aaa")
|
||||
|
||||
appConf = $('#modal-input-textarea').val()
|
||||
// encode for import
|
||||
appConfBase64 = btoa(appConf)
|
||||
|
||||
// import
|
||||
$.post('php/server/query_replace_config.php', { config: appConfBase64 }, function(msg) {
|
||||
console.log(msg);
|
||||
// showMessage(msg);
|
||||
write_notification(`[Maintenance] Settings imported from backup: ${msg}`, 'interrupt');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Download Settings Config
|
||||
function DownloadConfig()
|
||||
{
|
||||
// Execute
|
||||
openInNewTab("php/server/query_config.php?file=app.conf&download=true")
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Export CSV
|
||||
function ExportCSV()
|
||||
@@ -482,8 +502,13 @@ function ImportPastedCSV()
|
||||
{
|
||||
var csv = $('#modal-input-textarea').val();
|
||||
|
||||
console.log(csv);
|
||||
|
||||
csvBase64 = utf8ToBase64(csv);
|
||||
|
||||
console.log(csvBase64);
|
||||
|
||||
|
||||
$.post('php/server/devices.php?action=ImportCSV', { content: csvBase64 }, function(msg) {
|
||||
showMessage(msg);
|
||||
write_notification(`[Maintenance] Devices imported from pasted content`, 'info');
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
<h3 class="box-title"><?= lang('Gen_Selected_Devices');?></h3>
|
||||
|
||||
</div>
|
||||
<div class="deviceSelector col-md-9 col-sm-12" style="z-index:5"></div>
|
||||
<div class="deviceSelector col-md-11 col-sm-11" style="z-index:5"></div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<button type="button" class="btn btn-default" onclick="markAllSelected()">
|
||||
<i class="fa-solid fa-circle-check"></i> <?= lang('Gen_Add_All');?>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-default col-md-12" onclick="markAllSelected()" title="<?= lang('Gen_Add_All');?>">
|
||||
<i class="fa-solid fa-circle-check"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default" onclick="markAllNotSelected()">
|
||||
<i class="fa-solid fa-circle-xmark"></i> <?= lang('Gen_Remove_All');?>
|
||||
<button type="button" class="btn btn-default col-md-12" onclick="markAllNotSelected()" title="<?= lang('Gen_Remove_All');?>">
|
||||
<i class="fa-solid fa-circle-xmark"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
settingsData = res["data"];
|
||||
|
||||
excludedColumns = ["NEWDEV_devMac", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devLastNotification", "NEWDEV_devLastIP", "NEWDEV_devStaticIP", "NEWDEV_devScan", "NEWDEV_devPresentLastScan" ]
|
||||
excludedColumns = ["NEWDEV_devMac", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devLastNotification", "NEWDEV_devScan", "NEWDEV_devPresentLastScan", "NEWDEV_devCustomProps" ]
|
||||
|
||||
const relevantColumns = settingsData.filter(set =>
|
||||
set.setGroup === "NEWDEV" &&
|
||||
@@ -90,21 +90,21 @@
|
||||
!set.setKey.includes("__metadata")
|
||||
);
|
||||
|
||||
const generateSimpleForm = columns => {
|
||||
const generateSimpleForm = multiEditColumns => {
|
||||
const form = $('#multi-edit-form');
|
||||
const numColumns = 2; // Number of columns
|
||||
|
||||
// Calculate number of elements per column
|
||||
const elementsPerColumn = Math.ceil(columns.length / numColumns);
|
||||
const elementsPerColumn = Math.ceil(multiEditColumns.length / numColumns);
|
||||
|
||||
// Divide columns equally
|
||||
for (let i = 0; i < numColumns; i++) {
|
||||
const column = $('<div>').addClass('col-md-6');
|
||||
|
||||
// Append form groups to the column
|
||||
for (let j = i * elementsPerColumn; j < Math.min((i + 1) * elementsPerColumn, columns.length); j++) {
|
||||
for (let j = i * elementsPerColumn; j < Math.min((i + 1) * elementsPerColumn, multiEditColumns.length); j++) {
|
||||
|
||||
const setTypeObject = JSON.parse(columns[j].setType.replace(/'/g, '"'));
|
||||
const setTypeObject = JSON.parse(multiEditColumns[j].setType.replace(/'/g, '"'));
|
||||
|
||||
// get the element with the input value(s)
|
||||
let elements = setTypeObject.elements.filter(element => element.elementHasInputValue === 1);
|
||||
@@ -135,37 +135,39 @@
|
||||
onClick,
|
||||
onChange,
|
||||
customParams,
|
||||
customId
|
||||
customId,
|
||||
columns,
|
||||
base64Regex
|
||||
} = handleElementOptions('none', elementOptions, transformers, val = "");
|
||||
|
||||
// render based on element type
|
||||
if (elementType === 'select') {
|
||||
|
||||
targetLocation = columns[j].setKey + "_generateSetOptions"
|
||||
targetLocation = multiEditColumns[j].setKey + "_generateSetOptions"
|
||||
|
||||
generateOptionsOrSetOptions(columns[j].setKey, [], targetLocation, generateOptions)
|
||||
generateOptionsOrSetOptions(multiEditColumns[j].setKey, [], targetLocation, generateOptions, null)
|
||||
|
||||
console.log(columns[j].setKey)
|
||||
console.log(multiEditColumns[j].setKey)
|
||||
// Handle Icons as they need a preview
|
||||
if(columns[j].setKey == 'NEWDEV_devIcon')
|
||||
if(multiEditColumns[j].setKey == 'NEWDEV_devIcon')
|
||||
{
|
||||
input = `
|
||||
<span class="input-group-addon iconPreview" my-customid="NEWDEV_devIcon_preview"></span>
|
||||
<select class="form-control"
|
||||
onChange="updateIconPreview(this)"
|
||||
my-customparams="NEWDEV_devIcon,NEWDEV_devIcon_preview"
|
||||
id="${columns[j].setKey}"
|
||||
data-my-column="${columns[j].setKey}"
|
||||
data-my-targetColumns="${columns[j].setKey.replace('NEWDEV_','')}" >
|
||||
id="${multiEditColumns[j].setKey}"
|
||||
data-my-column="${multiEditColumns[j].setKey}"
|
||||
data-my-targetColumns="${multiEditColumns[j].setKey.replace('NEWDEV_','')}" >
|
||||
<option id="${targetLocation}"></option>
|
||||
</select>`
|
||||
|
||||
} else{
|
||||
|
||||
input = `<select class="form-control"
|
||||
id="${columns[j].setKey}"
|
||||
data-my-column="${columns[j].setKey}"
|
||||
data-my-targetColumns="${columns[j].setKey.replace('NEWDEV_','')}" >
|
||||
id="${multiEditColumns[j].setKey}"
|
||||
data-my-column="${multiEditColumns[j].setKey}"
|
||||
data-my-targetColumns="${multiEditColumns[j].setKey.replace('NEWDEV_','')}" >
|
||||
<option id="${targetLocation}"></option>
|
||||
</select>`
|
||||
}
|
||||
@@ -178,20 +180,20 @@
|
||||
|
||||
|
||||
input = `<input class="${inputClass}"
|
||||
id="${columns[j].setKey}"
|
||||
my-customid="${columns[j].setKey}"
|
||||
data-my-column="${columns[j].setKey}"
|
||||
data-my-targetColumns="${columns[j].setKey.replace('NEWDEV_','')}"
|
||||
id="${multiEditColumns[j].setKey}"
|
||||
my-customid="${multiEditColumns[j].setKey}"
|
||||
data-my-column="${multiEditColumns[j].setKey}"
|
||||
data-my-targetColumns="${multiEditColumns[j].setKey.replace('NEWDEV_','')}"
|
||||
type="${inputType}">`
|
||||
}
|
||||
|
||||
|
||||
const inputEntry = `<div class="form-group col-sm-12" >
|
||||
<label class="col-sm-3 control-label">${columns[j].setName}</label>
|
||||
<label class="col-sm-3 control-label">${multiEditColumns[j].setName}</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group red-hover-border">
|
||||
${input}
|
||||
<span class="input-group-addon pointer red-hover-background" onclick="massUpdateField('${columns[j].setKey}');" title="${getString('Device_MultiEdit_Tooltip')}">
|
||||
<span class="input-group-addon pointer red-hover-background" onclick="massUpdateField('${multiEditColumns[j].setKey}');" title="${getString('Device_MultiEdit_Tooltip')}">
|
||||
<i class="fa fa-save"></i>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
require 'php/templates/header.php';
|
||||
require 'php/templates/notification.php';
|
||||
|
||||
// online / offline badges HTML snippets
|
||||
define('badge_online', '<div class="badge bg-green text-white" style="width: 60px;">Online</div>');
|
||||
@@ -11,21 +12,17 @@
|
||||
|
||||
?>
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<script>
|
||||
// show spinning icon
|
||||
showSpinner()
|
||||
</script>
|
||||
|
||||
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<?php require 'php/templates/notification.php'; ?>
|
||||
<h1 id="pageTitle">
|
||||
<i class="fa fa-network-wired"></i> <?= lang('Network_Title');?>
|
||||
<span class="helpIconSmallTopRight"> <a target="_blank" href="https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md"><i class="fa fa-circle-question"></i></a><span>
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
<span class="networkHelpIcon"> <a target="_blank" href="https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md"><i class="fa fa-circle-question"></i></a></span>
|
||||
|
||||
<div id="networkTree" class="drag"></div>
|
||||
|
||||
@@ -467,9 +464,8 @@
|
||||
require 'php/templates/footer.php';
|
||||
?>
|
||||
|
||||
|
||||
<script src="lib/treeviz/index.js"></script>
|
||||
<script src="lib/treeviz/require.js"></script>
|
||||
<script src="lib/treeviz/bundle.js"></script>
|
||||
<script src="lib/treeviz/bundle.js.map"></script>
|
||||
|
||||
|
||||
<script defer>
|
||||
@@ -484,6 +480,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
orderTopologyBy = createArray(getSetting("UI_TOPOLOGY_ORDER"))
|
||||
|
||||
devicesListnew = rawData["data"].map(item => {
|
||||
return {
|
||||
"name": item[0],
|
||||
@@ -497,20 +495,36 @@
|
||||
"port": item[18]
|
||||
};
|
||||
}).sort((a, b) => {
|
||||
// First sort by name alphabetically
|
||||
const nameCompare = a.name.localeCompare(b.name);
|
||||
if (nameCompare !== 0) {
|
||||
// Helper to safely parse port into an integer; invalid ports become Infinity for sorting
|
||||
const parsePort = (port) => {
|
||||
const parsed = parseInt(port, 10);
|
||||
return isNaN(parsed) ? Infinity : parsed;
|
||||
};
|
||||
|
||||
switch (orderTopologyBy[0]) {
|
||||
case "Name":
|
||||
// First sort by name alphabetically
|
||||
const nameCompare = a.name.localeCompare(b.name);
|
||||
if (nameCompare !== 0) {
|
||||
return nameCompare;
|
||||
}
|
||||
// If names are the same, sort by port numerically
|
||||
return a.port - b.port;
|
||||
}
|
||||
// If names are the same, sort by port numerically
|
||||
return parsePort(a.port) - parsePort(b.port);
|
||||
|
||||
case "Port":
|
||||
// Sort by port numerically
|
||||
return parsePort(a.port) - parsePort(b.port);
|
||||
|
||||
default:
|
||||
// Default: Sort by rowid (as a fallback)
|
||||
return a.rowid - b.rowid;
|
||||
}
|
||||
});
|
||||
|
||||
setCache('devicesListNew', JSON.stringify(devicesListnew));
|
||||
|
||||
// Init global variable
|
||||
deviceListGlobal = devicesListnew;
|
||||
|
||||
|
||||
// create tree
|
||||
initTree(getHierarchy());
|
||||
@@ -522,381 +536,414 @@
|
||||
|
||||
|
||||
<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 visibleNodesCount = 0;
|
||||
var parentNodesCount = 0;
|
||||
var hiddenMacs = []; // hidden children
|
||||
var hiddenChildren = [];
|
||||
var deviceListGlobal = null;
|
||||
var visibleNodesCount = 0;
|
||||
|
||||
for (let node of deviceListGlobal) {
|
||||
let path = "";
|
||||
let childrenCount = 0;
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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;
|
||||
}
|
||||
// count children of this node
|
||||
for (let nodeTmp of deviceListGlobal) {
|
||||
if (nodeTmp.parentMac === node.mac) {
|
||||
childrenCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
function toggleSubTree(parentMac, treePath)
|
||||
{
|
||||
treePath = treePath.split('|')
|
||||
|
||||
if(!hiddenMacs.includes(parentMac))
|
||||
{
|
||||
hiddenMacs.push(parentMac)
|
||||
}
|
||||
else
|
||||
{
|
||||
removeItemFromArray(hiddenMacs, parentMac)
|
||||
}
|
||||
|
||||
// updatedTree = myHierarchy;
|
||||
updatedTree = getHierarchy()
|
||||
|
||||
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(event)
|
||||
{
|
||||
// console.log(event.target.offsetParent.offsetParent)
|
||||
|
||||
const targetTabMAC = $(event.target.offsetParent.offsetParent).attr("data-mytreemacmain");
|
||||
|
||||
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 = 160;
|
||||
var emSize;
|
||||
var nodeHeight;
|
||||
var sizeCoefficient = 1
|
||||
|
||||
function initTree(myHierarchy)
|
||||
{
|
||||
console.log(myHierarchy)
|
||||
|
||||
// calculate the drawing area based on teh tree width and available screen size
|
||||
var treeAreaHeight = visibleTreeArea > 800 ? 800 : visibleTreeArea;
|
||||
let screenWidth = $('.content-header').width();
|
||||
let treeWidth = (nodeWidth + 20) * parentNodesCount;
|
||||
let treeAreaWidth = screenWidth < treeWidth ? treeWidth : screenWidth;
|
||||
|
||||
// init the drawing area size
|
||||
$("#networkTree").attr('style', `height:${treeAreaHeight}px; width:${treeAreaWidth}px`)
|
||||
|
||||
if(myHierarchy.type == "")
|
||||
{
|
||||
showModalOk(getString('Network_Configuration_Error'), getString('Network_Root_Not_Configured'))
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate the font size of the leaf nodes to fit everything into the tree area
|
||||
leafNodesCount == 0 ? 1 : leafNodesCount;
|
||||
emSize = ((treeAreaHeight/(25*leafNodesCount)).toFixed(2));
|
||||
emSize = emSize > 1 ? 1 : emSize;
|
||||
|
||||
// nodeHeight = ((emSize*100*0.30).toFixed(0))
|
||||
nodeHeight = ((emSize*100*0.30).toFixed(0))
|
||||
|
||||
console.log(Treeviz);
|
||||
|
||||
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()
|
||||
|
||||
});
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
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));
|
||||
}
|
||||
|
||||
// store parent and leaf node count
|
||||
if (childrenCount === 0) {
|
||||
leafNodesCount++;
|
||||
} else {
|
||||
parentNodesCount++;
|
||||
}
|
||||
|
||||
if (!hiddenMacs.includes(node.parentMac)) {
|
||||
if (!((node.parentMac == "") && node.mac != "Internet")) { // skip leaf nodes without father that are not the root
|
||||
visibleNodesCount++;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
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'))
|
||||
result.push({
|
||||
name: node.name,
|
||||
path: path,
|
||||
mac: node.mac, // Replacing "mac" with "id"
|
||||
parentMac: node.mac == "Internet" ? "" : node.parentMac, // Replacing "parentMac" with "father"
|
||||
port: node.port,
|
||||
icon: node.icon,
|
||||
type: node.type,
|
||||
status: node.status,
|
||||
hasChildren: childrenCount > 0 || hiddenMacs.includes(node.mac),
|
||||
hiddenChildren: hiddenMacs.includes(node.mac),
|
||||
qty: childrenCount,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
return result;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
function toggleSubTree(parentMac, treePath)
|
||||
{
|
||||
treePath = treePath.split('|')
|
||||
|
||||
if(!hiddenMacs.includes(parentMac))
|
||||
{
|
||||
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
|
||||
}
|
||||
hiddenMacs.push(parentMac)
|
||||
}
|
||||
else
|
||||
{
|
||||
removeItemFromArray(hiddenMacs, parentMac)
|
||||
}
|
||||
|
||||
// show spinning icon
|
||||
showSpinner()
|
||||
updatedTree = getHierarchy()
|
||||
myTree.refresh(updatedTree);
|
||||
|
||||
// init device names where macs are used
|
||||
initDeviceNamesFromMACs();
|
||||
// re-attach any onclick events
|
||||
attachTreeEvents();
|
||||
}
|
||||
|
||||
// init selected (first) tab
|
||||
initTab();
|
||||
// ---------------------------------------------------------------------------
|
||||
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 == "")
|
||||
{
|
||||
showModalOk(getString('Network_Configuration_Error'), getString('Network_Root_Not_Configured'))
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate the font size of the leaf nodes to fit everything into the tree area
|
||||
leafNodesCount == 0 ? 1 : leafNodesCount;
|
||||
emSize = ((treeAreaHeight/(25*leafNodesCount)).toFixed(2));
|
||||
emSize = emSize > 1 ? 1 : emSize;
|
||||
|
||||
// nodeHeight = ((emSize*100*0.30).toFixed(0))
|
||||
nodeHeight = ((emSize*100*0.30).toFixed(0))
|
||||
|
||||
console.log(Treeviz);
|
||||
|
||||
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:${emSize/6}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>`;
|
||||
},
|
||||
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
|
||||
hideSpinner()
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tabs functionality
|
||||
// ---------------------------------------------------------------------------
|
||||
// Register events on tab change
|
||||
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
|
||||
// init Assign/Unassign buttons
|
||||
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>
|
||||
|
||||
|
||||
|
||||
52
front/php/components/devices_filters.php
Executable file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Check if authenticated
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/server/db.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/language/lang.php';
|
||||
|
||||
// Function to render a filter dropdown
|
||||
function renderFilterDropdown($headerKey, $columnName, $values) {
|
||||
// Generate dropdown options
|
||||
$optionsHtml = '<option value="" selected>All</option>'; // Default "All" option
|
||||
foreach ($values as $value) {
|
||||
$escapedValue = htmlspecialchars($value);
|
||||
$optionsHtml .= '<option value="' . $escapedValue . '">' . $escapedValue . '</option>';
|
||||
}
|
||||
|
||||
// Generate the dropdown HTML
|
||||
return '
|
||||
<div class="filter-group input-group">
|
||||
<label for="filter_' . htmlspecialchars($columnName) . '">' . lang($headerKey) . '</label>
|
||||
<select id="filter_' . htmlspecialchars($columnName) . '" class="filter-dropdown" data-column="' . htmlspecialchars($columnName) . '">
|
||||
' . $optionsHtml . '
|
||||
</select>
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Get filterObject from POST data
|
||||
$filterObject = isset($_POST['filterObject']) ? json_decode($_POST['filterObject'], true) : [];
|
||||
|
||||
// Validate filterObject structure
|
||||
if (!isset($filterObject['filters']) || !is_array($filterObject['filters'])) {
|
||||
echo '<p class="error">Invalid filter data provided.</p>';
|
||||
exit();
|
||||
}
|
||||
|
||||
// Generate HTML for each filter in the filterObject
|
||||
$html = '';
|
||||
foreach ($filterObject['filters'] as $filter) {
|
||||
if (isset($filter['column'], $filter['headerKey'], $filter['options'])) {
|
||||
$html .= renderFilterDropdown($filter['headerKey'], $filter['column'], $filter['options']);
|
||||
} else {
|
||||
// Skip invalid entries
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Output the generated HTML
|
||||
echo $html;
|
||||
exit();
|
||||
|
||||
?>
|
||||
@@ -10,8 +10,12 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// DB File Path
|
||||
$DBFILE = dirname(__FILE__).'/../../../db/app.db';
|
||||
$DBFILE_LOCKED_FILE = dirname(__FILE__).'/../../../log/db_is_locked.log';
|
||||
// $DBFILE = dirname(__FILE__).'/../../../db/app.db';
|
||||
// $DBFILE_LOCKED_FILE = dirname(__FILE__).'/../../../log/db_is_locked.log';
|
||||
$scriptDir = realpath(dirname(__FILE__)); // Resolves symlinks to the actual physical path
|
||||
$DBFILE = $scriptDir . '/../../../db/app.db';
|
||||
$DBFILE_LOCKED_FILE = $scriptDir . '/../../../log/db_is_locked.log';
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// check if authenticated
|
||||
@@ -32,6 +36,14 @@ function SQLite3_connect($trytoreconnect = true, $retryCount = 0) {
|
||||
global $db_locked;
|
||||
$db_locked = false;
|
||||
|
||||
if (!file_exists($DBFILE)) {
|
||||
die("Database file not found: $DBFILE");
|
||||
}
|
||||
if (!file_exists(dirname($DBFILE_LOCKED_FILE))) {
|
||||
die("Log directory not found: " . dirname($DBFILE_LOCKED_FILE));
|
||||
}
|
||||
|
||||
|
||||
// Write unlock status to the locked file
|
||||
file_put_contents($DBFILE_LOCKED_FILE, '0');
|
||||
|
||||
@@ -70,7 +82,7 @@ class CustomDatabaseWrapper {
|
||||
private $maxRetries;
|
||||
private $retryDelay;
|
||||
|
||||
public function __construct($filename, $flags = SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $maxRetries = 10, $retryDelay = 1000, $encryptionKey = null) {
|
||||
public function __construct($filename, $flags = SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $maxRetries = 3, $retryDelay = 1000, $encryptionKey = null) {
|
||||
$this->sqlite = new SQLite3($filename, $flags, $encryptionKey);
|
||||
$this->maxRetries = $maxRetries;
|
||||
$this->retryDelay = $retryDelay;
|
||||
@@ -116,7 +128,7 @@ class CustomDatabaseWrapper {
|
||||
file_put_contents($DBFILE_LOCKED_FILE, '0');
|
||||
|
||||
$message = 'Error executing query (attempts: ' . $attempts . '), query: ' . $query;
|
||||
write_notification($message);
|
||||
// write_notification($message);
|
||||
error_log("Query failed after {$this->maxRetries} attempts: " . $this->sqlite->lastErrorMsg());
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
||||
}
|
||||
|
||||
if (isset ($_REQUEST['rawSql'])) {
|
||||
$rawSql = $_REQUEST['rawSql'];
|
||||
$rawSql = urldecode(base64_decode($_REQUEST['rawSql']));
|
||||
}
|
||||
|
||||
if (isset ($_REQUEST['dbtable'])) {
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
case 'deleteEvents30': deleteEvents30(); break;
|
||||
case 'deleteActHistory': deleteActHistory(); break;
|
||||
case 'deleteDeviceEvents': deleteDeviceEvents(); break;
|
||||
case 'resetDeviceProps': resetDeviceProps(); break;
|
||||
case 'PiaBackupDBtoArchive': PiaBackupDBtoArchive(); break;
|
||||
case 'PiaRestoreDBfromArchive': PiaRestoreDBfromArchive(); break;
|
||||
case 'PiaPurgeDBBackups': PiaPurgeDBBackups(); break;
|
||||
@@ -105,6 +106,7 @@ function getServerDeviceData() {
|
||||
"devSSID" => "",
|
||||
"devSyncHubNode" => "",
|
||||
"devSourcePlugin" => "",
|
||||
"devCustomProps" => "",
|
||||
"devStatus" => "Unknown",
|
||||
"devIsRandomMAC" => false,
|
||||
"devSessions" => 0,
|
||||
@@ -190,129 +192,133 @@ function setDeviceData() {
|
||||
global $db;
|
||||
|
||||
// Sanitize input
|
||||
$mac = quotes($_REQUEST['mac']);
|
||||
$name = quotes($_REQUEST['name']);
|
||||
$owner = quotes($_REQUEST['owner']);
|
||||
$type = quotes($_REQUEST['type']);
|
||||
$vendor = quotes($_REQUEST['vendor']);
|
||||
$icon = quotes($_REQUEST['icon']);
|
||||
$favorite = quotes($_REQUEST['favorite']);
|
||||
$group = quotes($_REQUEST['group']);
|
||||
$location = quotes($_REQUEST['location']);
|
||||
$comments = quotes($_REQUEST['comments']);
|
||||
$parentMac = quotes($_REQUEST['networknode']);
|
||||
$parentPort = quotes($_REQUEST['networknodeport']);
|
||||
$ssid = quotes($_REQUEST['ssid']);
|
||||
$site = quotes($_REQUEST['networksite']);
|
||||
$staticIP = quotes($_REQUEST['staticIP']);
|
||||
$scancycle = quotes($_REQUEST['scancycle']);
|
||||
$alertevents = quotes($_REQUEST['alertevents']);
|
||||
$alertdown = quotes($_REQUEST['alertdown']);
|
||||
$skiprepeated = quotes($_REQUEST['skiprepeated']);
|
||||
$newdevice = quotes($_REQUEST['newdevice']);
|
||||
$archived = quotes($_REQUEST['archived']);
|
||||
$devFirstConnection = quotes($_REQUEST['devFirstConnection']);
|
||||
$devLastConnection = quotes($_REQUEST['devLastConnection']);
|
||||
$ip = quotes($_REQUEST['ip']);
|
||||
$createNew = quotes($_REQUEST['createNew']);
|
||||
$mac = quotes($_POST['mac']);
|
||||
$name = urldecode(quotes($_POST['name']));
|
||||
$owner = urldecode(quotes($_POST['owner']));
|
||||
$type = urldecode(quotes($_POST['type']));
|
||||
$vendor = urldecode(quotes($_POST['vendor']));
|
||||
$icon = urldecode(quotes($_POST['icon']));
|
||||
$favorite = quotes($_POST['favorite']);
|
||||
$group = urldecode(quotes($_POST['group']));
|
||||
$location = urldecode(quotes($_POST['location']));
|
||||
$comments = urldecode(quotes($_POST['comments']));
|
||||
$parentMac = quotes($_POST['networknode']);
|
||||
$parentPort = quotes($_POST['networknodeport']);
|
||||
$ssid = urldecode(quotes($_POST['ssid']));
|
||||
$site = quotes($_POST['networksite']);
|
||||
$staticIP = quotes($_POST['staticIP']);
|
||||
$scancycle = quotes($_POST['scancycle']);
|
||||
$alertevents = quotes($_POST['alertevents']);
|
||||
$alertdown = quotes($_POST['alertdown']);
|
||||
$skiprepeated = quotes($_POST['skiprepeated']);
|
||||
$newdevice = quotes($_POST['newdevice']);
|
||||
$archived = quotes($_POST['archived']);
|
||||
$devFirstConnection = quotes($_POST['devFirstConnection']);
|
||||
$devLastConnection = quotes($_POST['devLastConnection']);
|
||||
$ip = quotes($_POST['ip']);
|
||||
$devCustomProps = quotes($_POST['devCustomProps']);
|
||||
$createNew = quotes($_POST['createNew']);
|
||||
$devNewGuid = generateGUID();
|
||||
|
||||
// an update
|
||||
if ($_REQUEST['createNew'] == 0)
|
||||
{
|
||||
// UPDATE SQL query
|
||||
$sql = "UPDATE Devices SET
|
||||
devName = '$name',
|
||||
devOwner = '$owner',
|
||||
devType = '$type',
|
||||
devVendor = '$vendor',
|
||||
devIcon = '$icon',
|
||||
devFavorite = '$favorite',
|
||||
devGroup = '$group',
|
||||
devLocation = '$location',
|
||||
devComments = '$comments',
|
||||
devParentMAC = '$parentMac',
|
||||
devParentPort = '$parentPort',
|
||||
devSSID = '$ssid',
|
||||
devSite = '$site',
|
||||
devStaticIP = '$staticIP',
|
||||
devScan = '$scancycle',
|
||||
devAlertEvents = '$alertevents',
|
||||
devAlertDown = '$alertdown',
|
||||
devSkipRepeated = '$skiprepeated',
|
||||
devIsNew = '$newdevice',
|
||||
devIsArchived = '$archived'
|
||||
WHERE devMac = '$mac'";
|
||||
} else // an INSERT
|
||||
{
|
||||
$sql = "INSERT INTO Devices (
|
||||
devMac,
|
||||
devName,
|
||||
devOwner,
|
||||
devType,
|
||||
devVendor,
|
||||
devIcon,
|
||||
devFavorite,
|
||||
devGroup,
|
||||
devLocation,
|
||||
devComments,
|
||||
devParentMAC,
|
||||
devParentPort,
|
||||
devSSID,
|
||||
devSite,
|
||||
devStaticIP,
|
||||
devScan,
|
||||
devAlertEvents,
|
||||
devAlertDown,
|
||||
devSkipRepeated,
|
||||
devIsNew,
|
||||
devIsArchived,
|
||||
devLastConnection,
|
||||
devFirstConnection,
|
||||
devLastIP,
|
||||
devGUID
|
||||
) VALUES (
|
||||
'$mac',
|
||||
'$name',
|
||||
'$owner',
|
||||
'$type',
|
||||
'$vendor',
|
||||
'$icon',
|
||||
'$favorite',
|
||||
'$group',
|
||||
'$location',
|
||||
'$comments',
|
||||
'$parentMac',
|
||||
'$parentPort',
|
||||
'$ssid',
|
||||
'$site',
|
||||
'$staticIP',
|
||||
'$scancycle',
|
||||
'$alertevents',
|
||||
'$alertdown',
|
||||
'$skiprepeated',
|
||||
'$newdevice',
|
||||
'$archived',
|
||||
'$devLastConnection',
|
||||
'$devFirstConnection',
|
||||
'$ip',
|
||||
'$devNewGuid'
|
||||
)
|
||||
";
|
||||
// An update
|
||||
if ($_POST['createNew'] == 0) {
|
||||
// UPDATE SQL query
|
||||
$sql = "UPDATE Devices SET
|
||||
devName = '$name',
|
||||
devOwner = '$owner',
|
||||
devType = '$type',
|
||||
devVendor = '$vendor',
|
||||
devIcon = '$icon',
|
||||
devFavorite = '$favorite',
|
||||
devGroup = '$group',
|
||||
devLocation = '$location',
|
||||
devComments = '$comments',
|
||||
devParentMAC = '$parentMac',
|
||||
devParentPort = '$parentPort',
|
||||
devSSID = '$ssid',
|
||||
devSite = '$site',
|
||||
devStaticIP = '$staticIP',
|
||||
devScan = '$scancycle',
|
||||
devAlertEvents = '$alertevents',
|
||||
devAlertDown = '$alertdown',
|
||||
devSkipRepeated = '$skiprepeated',
|
||||
devIsNew = '$newdevice',
|
||||
devIsArchived = '$archived',
|
||||
devCustomProps = '$devCustomProps'
|
||||
WHERE devMac = '$mac'";
|
||||
} else { // An INSERT
|
||||
$sql = "INSERT INTO Devices (
|
||||
devMac,
|
||||
devName,
|
||||
devOwner,
|
||||
devType,
|
||||
devVendor,
|
||||
devIcon,
|
||||
devFavorite,
|
||||
devGroup,
|
||||
devLocation,
|
||||
devComments,
|
||||
devParentMAC,
|
||||
devParentPort,
|
||||
devSSID,
|
||||
devSite,
|
||||
devStaticIP,
|
||||
devScan,
|
||||
devAlertEvents,
|
||||
devAlertDown,
|
||||
devSkipRepeated,
|
||||
devIsNew,
|
||||
devIsArchived,
|
||||
devLastConnection,
|
||||
devFirstConnection,
|
||||
devLastIP,
|
||||
devGUID,
|
||||
devCustomProps,
|
||||
devSourcePlugin
|
||||
) VALUES (
|
||||
'$mac',
|
||||
'$name',
|
||||
'$owner',
|
||||
'$type',
|
||||
'$vendor',
|
||||
'$icon',
|
||||
'$favorite',
|
||||
'$group',
|
||||
'$location',
|
||||
'$comments',
|
||||
'$parentMac',
|
||||
'$parentPort',
|
||||
'$ssid',
|
||||
'$site',
|
||||
'$staticIP',
|
||||
'$scancycle',
|
||||
'$alertevents',
|
||||
'$alertdown',
|
||||
'$skiprepeated',
|
||||
'$newdevice',
|
||||
'$archived',
|
||||
'$devLastConnection',
|
||||
'$devFirstConnection',
|
||||
'$ip',
|
||||
'$devNewGuid',
|
||||
'$devCustomProps',
|
||||
'DUMMY'
|
||||
)";
|
||||
}
|
||||
|
||||
// update Data
|
||||
// Execute the query
|
||||
$result = $db->query($sql);
|
||||
|
||||
// check result
|
||||
// Check the result
|
||||
if ($result == TRUE) {
|
||||
echo lang('BackDevices_DBTools_UpdDev');
|
||||
echo lang('BackDevices_DBTools_UpdDev');
|
||||
} else {
|
||||
echo lang('BackDevices_DBTools_UpdDevError')."\n\n$sql \n\n". $db->lastErrorMsg();
|
||||
echo lang('BackDevices_DBTools_UpdDevError')."\n\n$sql \n\n". $db->lastErrorMsg();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Delete Device
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -389,6 +395,26 @@ function deleteDeviceEvents() {
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Delete Device Properties
|
||||
//------------------------------------------------------------------------------
|
||||
function resetDeviceProps() {
|
||||
global $db;
|
||||
|
||||
// sql
|
||||
$sql = 'UPDATE Devices set devCustomProps = "'.getSettingValue("NEWDEV_devCustomProps").'" WHERE devMac="' . $_REQUEST['mac'] .'"';
|
||||
|
||||
// execute sql
|
||||
$result = $db->query($sql);
|
||||
|
||||
// check result
|
||||
if ($result == TRUE) {
|
||||
echo lang('Gen_Okay');
|
||||
} else {
|
||||
echo lang('Gen_Error')."\n\n$sql \n\n". $db->lastErrorMsg();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Delete all devices
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
53
front/php/server/query_config.php
Executable file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
// ---- IMPORTS ----
|
||||
//------------------------------------------------------------------------------
|
||||
// Check if authenticated
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
||||
// Get init.php
|
||||
require dirname(__FILE__).'/../server/init.php';
|
||||
// ---- IMPORTS ----
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Handle incoming requests
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
// Get query string parameters ?file=settings_table.json&download=true
|
||||
$file = isset($_GET['file']) ? $_GET['file'] : null;
|
||||
$download = isset($_GET['download']) ? $_GET['download'] === 'true' : false;
|
||||
|
||||
// Check if file parameter is provided
|
||||
if ($file) {
|
||||
// Define the folder where files are located
|
||||
$filePath = "/app/config/" . basename($file);
|
||||
|
||||
// Check if the file exists
|
||||
if (file_exists($filePath)) {
|
||||
// Handle download behavior
|
||||
if ($download) {
|
||||
// Force file download
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . filesize($filePath));
|
||||
readfile($filePath);
|
||||
exit;
|
||||
} else {
|
||||
// Display file content
|
||||
header('Content-Type: text/plain');
|
||||
echo file_get_contents($filePath);
|
||||
}
|
||||
} else {
|
||||
// File not found response
|
||||
http_response_code(404);
|
||||
echo json_encode(["error" => "File not found"]);
|
||||
}
|
||||
} else {
|
||||
// Missing file parameter response
|
||||
http_response_code(400);
|
||||
echo json_encode(["error" => "Missing 'file' parameter"]);
|
||||
}
|
||||
}
|
||||
?>
|
||||
55
front/php/server/query_replace_config.php
Executable file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
// ---- IMPORTS ----
|
||||
//------------------------------------------------------------------------------
|
||||
// Check if authenticated
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
||||
// Get init.php
|
||||
require dirname(__FILE__).'/../server/init.php';
|
||||
// ---- IMPORTS ----
|
||||
|
||||
global $fullConfPath;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Handle incoming requests
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// Access the 'config' parameter from the POST request
|
||||
$base64Data = $_POST['config'] ?? null;
|
||||
|
||||
if (!$base64Data) {
|
||||
$msg = "Missing 'config' parameter.";
|
||||
echo $msg;
|
||||
http_response_code(400); // Bad request
|
||||
die($msg);
|
||||
}
|
||||
|
||||
// Decode incoming base64 data
|
||||
$input = base64_decode($base64Data, true);
|
||||
|
||||
if ($input === false) {
|
||||
$msg = "Invalid base64 data.";
|
||||
echo $msg;
|
||||
http_response_code(400); // Bad request
|
||||
die($msg);
|
||||
}
|
||||
|
||||
// Backup the original file
|
||||
if (file_exists($fullConfPath)) {
|
||||
copy($fullConfPath, $fullConfPath . ".bak");
|
||||
}
|
||||
|
||||
// Write the new configuration
|
||||
$file = fopen($fullConfPath, "w");
|
||||
if (!$file) {
|
||||
$msg = "Unable to open file!";
|
||||
echo $msg;
|
||||
http_response_code(500); // Server error
|
||||
die($msg);
|
||||
}
|
||||
|
||||
fwrite($file, $input);
|
||||
fclose($file);
|
||||
|
||||
echo "Configuration saved successfully.";
|
||||
}
|
||||
?>
|
||||
@@ -263,7 +263,7 @@ function cleanLog($logFile)
|
||||
|
||||
$path = "";
|
||||
|
||||
$allowedFiles = ['app.log', 'app_front.log', 'IP_changes.log', 'stdout.log', 'stderr.log', 'app.php_errors.log', 'execution_queue.log'];
|
||||
$allowedFiles = ['app.log', 'app_front.log', 'IP_changes.log', 'stdout.log', 'stderr.log', 'app.php_errors.log', 'execution_queue.log', 'db_is_locked.log'];
|
||||
|
||||
if(in_array($logFile, $allowedFiles))
|
||||
{
|
||||
@@ -274,7 +274,7 @@ function cleanLog($logFile)
|
||||
{
|
||||
// purge content
|
||||
$file = fopen($path, "w") or die("Unable to open file!");
|
||||
fwrite($file, "[".$timestamp. "] Log file manually purged" .PHP_EOL."");
|
||||
fwrite($file, "");
|
||||
fclose($file);
|
||||
displayMessage('File <code>'.$logFile.'</code> purged.', FALSE, TRUE, TRUE, TRUE);
|
||||
} else
|
||||
@@ -356,6 +356,8 @@ function saveSettings()
|
||||
$txt .= $setKey . "='" . $val . "'\n";
|
||||
} elseif ($dataType == 'integer') {
|
||||
$txt .= $setKey . "=" . $settingValue . "\n";
|
||||
} elseif ($dataType == 'none') {
|
||||
$txt .= $setKey . "=''\n";
|
||||
} elseif ($dataType == 'json') {
|
||||
$txt .= $setKey . "=" . $settingValue . "\n";
|
||||
} elseif ($dataType == 'boolean') {
|
||||
@@ -551,6 +553,7 @@ function decodeSpecialChars($str) {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// used in Export CSV
|
||||
function getDevicesColumns(){
|
||||
|
||||
$columns = ["devMac",
|
||||
@@ -582,7 +585,8 @@ function getDevicesColumns(){
|
||||
"devSyncHubNode",
|
||||
"devSite",
|
||||
"devSSID",
|
||||
"devSourcePlugin"
|
||||
"devSourcePlugin",
|
||||
"devCustomProps"
|
||||
];
|
||||
|
||||
return $columns;
|
||||
|
||||
@@ -28,12 +28,10 @@
|
||||
|
||||
<!-- To the right -->
|
||||
<div class="pull-right no-hidden-xs">
|
||||
| <a href="https://github.com/jokob-sk/NetAlertX/tree/main/docs#documentation-overview" target="_blank">Docs <i class="fa fa-circle-question"></i></a>
|
||||
| <a href="https://github.com/jokob-sk/NetAlertX/issues"><i class="fa-solid fa-bug"></i></a>
|
||||
| <a href="https://github.com/jokob-sk/NetAlertX/"><i class="fa-brands fa-github"></i></a>
|
||||
| <a href="https://discord.gg/UQnnHNYV"><i class="fa-brands fa-discord"></i></a>
|
||||
| <a href="mailto:jokob@duck.com?subject=NetAlertX"><i class="fa-solid fa-envelope"></i></a>
|
||||
| <a href="https://github.com/pucherot/Pi.Alert">©</a>
|
||||
| <a href="https://gurubase.io/g/netalertx" class="pointer" target="_blank" title="Ask AI"><i class="fa-regular fa-comment-dots fa-flip-horizontal"></i></a>
|
||||
| <a href="https://github.com/jokob-sk/NetAlertX/tree/main/docs#documentation-overview" class="pointer" target="_blank" title="Documentation"><i class="fa fa-book"></i></a>
|
||||
| <a href="https://github.com/jokob-sk/NetAlertX/issues" class="pointer" target="_blank"><i class="fa-solid fa-bug" title="Report a bug"></i></a>
|
||||
| <a href="https://discord.com/invite/NczTUTWyRr" class="pointer" target="_blank"><i class="fa-brands fa-discord" title="Join Discord"></i></a>
|
||||
| <?= lang('Maintenance_built_on');?>: <?php include 'php/templates/build.php'; ?>
|
||||
| Version: <?php include 'php/templates/version.php'; ?>
|
||||
|
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
<script src="js/tests.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||
<script src="js/db_methods.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||
<script src="js/settings_utils.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||
<script src="js/device.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||
|
||||
|
||||
|
||||
@@ -69,9 +70,6 @@
|
||||
<!-- Theme style -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/dist/css/AdminLTE.min.css">
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- AdminLTE Skins. We have chosen the skin-blue for this starter
|
||||
page. However, you can choose any other skin. Make sure you
|
||||
apply the skin class to the body tag so the changes take effect. -->
|
||||
@@ -106,6 +104,8 @@
|
||||
<!-- Servertime to the right of the hostname -->
|
||||
<script>
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Updates the backend application state/status in the header
|
||||
function updateState(){
|
||||
$.get('/php/server/query_json.php', { file: 'app_state.json', nocache: Date.now() }, function(appState) {
|
||||
|
||||
@@ -116,19 +116,46 @@
|
||||
})
|
||||
}
|
||||
|
||||
function show_pia_servertime() {
|
||||
// -------------------------------------------------------------
|
||||
// updates the date and time in the header
|
||||
function update_servertime() {
|
||||
// Get the current date and time in the specified time zone
|
||||
let timeZone = "<?php echo $timeZone ?>";
|
||||
let now = new Date();
|
||||
|
||||
// datetime in timeZone in the "en-UK" locale
|
||||
let time = new Date().toLocaleString("en-UK", { timeZone: "<?php echo $timeZone?>" });
|
||||
// Convert to the specified time zone
|
||||
let formatter = new Intl.DateTimeFormat("en-UK", {
|
||||
timeZone: timeZone,
|
||||
day: "2-digit",
|
||||
month: "short",
|
||||
year: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
hour12: false, // Use 24-hour format
|
||||
});
|
||||
let parts = formatter.formatToParts(now);
|
||||
|
||||
if (document.getElementById) {
|
||||
document.getElementById("PIA_Servertime_place").innerHTML = '('+time+')';
|
||||
}
|
||||
|
||||
setTimeout("show_pia_servertime()", 1000);
|
||||
// Extract date components
|
||||
let day = parts.find(p => p.type === "day").value;
|
||||
let month = parts.find(p => p.type === "month").value;
|
||||
let year = parts.find(p => p.type === "year").value;
|
||||
|
||||
// Extract time components
|
||||
let hour = parts.find(p => p.type === "hour").value;
|
||||
let minute = parts.find(p => p.type === "minute").value;
|
||||
let second = parts.find(p => p.type === "second").value;
|
||||
|
||||
// Construct the date and time in DD-MMM-YYYY HH:MM:SS format
|
||||
let formattedDateTime = `${day}-${month}-${year} ${hour}:${minute}:${second}`;
|
||||
|
||||
if (document.getElementById) {
|
||||
document.getElementById("PIA_Servertime_place").innerHTML = '(' + formattedDateTime + ')';
|
||||
}
|
||||
|
||||
setTimeout(update_servertime, 1000); // Call recursively every second
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
@@ -136,7 +163,7 @@
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<!-- Layout Boxed Yellow -->
|
||||
|
||||
<body class="hold-transition fixed <?php echo $pia_skin_selected;?> sidebar-mini" onLoad="show_pia_servertime();" >
|
||||
<body class="hold-transition fixed <?php echo $pia_skin_selected;?> sidebar-mini" onLoad="update_servertime();" >
|
||||
<!-- Site wrapper -->
|
||||
<div class="wrapper">
|
||||
|
||||
@@ -144,8 +171,6 @@
|
||||
<!-- Main Header -->
|
||||
<header class="main-header">
|
||||
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<!-- Logo -->
|
||||
<a href="devices.php" class="logo">
|
||||
@@ -184,13 +209,13 @@
|
||||
</li>
|
||||
<!-- Clear cache & Reload -->
|
||||
<li>
|
||||
<a id="reload-button" href='#' role="button" span class='fa fa-repeat' onclick='clearCache()'></a>
|
||||
<a id="reload-button" href='#' role="button" span onclick='clearCache()' class='fa-solid fa-rotate'></a>
|
||||
</li>
|
||||
<!-- Full Screen -->
|
||||
<li>
|
||||
<a id="fullscreen-button" href='#' role="button" span class='fa fa-arrows-alt' onclick='toggleFullscreen()'></a>
|
||||
</li>
|
||||
<!-- Full Screen -->
|
||||
<!-- Notifications -->
|
||||
<li>
|
||||
<a id="notifications-button" href='userNotifications.php' role="button" span class='fa-solid fa-bell'></a>
|
||||
<span id="unread-notifications-bell-count" title="" class="badge bg-red unread-notifications-bell" >0</span>
|
||||
@@ -331,7 +356,10 @@
|
||||
<!-- Maintenance menu item -->
|
||||
<li class=" treeview <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('maintenance.php') ) ){ echo 'active menu-open'; } ?>">
|
||||
<a href="#" onclick="openUrl(['./maintenance.php'])">
|
||||
<div class="info-icon-nav myhidden" id="version" data-build-time="<?php echo file_get_contents( "buildtimestamp.txt");?>">🆕</div>
|
||||
<!-- NEW version available -->
|
||||
<div class="info-icon-nav myhidden" id="version" title="<?= lang('new_version_available');?>" data-build-time="<?php echo file_get_contents( "buildtimestamp.txt");?>">
|
||||
<i class="fa-solid fa-rocket fa-beat"></i>
|
||||
</div>
|
||||
<i class="fa fa-fw fa-wrench"></i> <span><?= lang('Navigation_Maintenance');?></span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
@@ -405,17 +433,14 @@
|
||||
</li>
|
||||
|
||||
<!-- About menu item -->
|
||||
<li class=" treeview <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('donations.php', 'help_faq.php', 'systeminfo.php' ) ) ){ echo 'active menu-open'; } ?>">
|
||||
<li class=" treeview <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('help_faq.php', 'systeminfo.php' ) ) ){ echo 'active menu-open'; } ?>">
|
||||
<a href="#">
|
||||
<i class="fa fa-fw fa-info"></i> <span><?= lang('Navigation_About');?></span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu " style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('donations.php', 'help_faq.php', 'systeminfo.php' ) ) ){ echo 'block'; } else {echo 'none';} ?>;">
|
||||
<li>
|
||||
<a href="donations.php"> <?= lang("Navigation_Donations");?> </a>
|
||||
</li>
|
||||
<ul class="treeview-menu " style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('help_faq.php', 'systeminfo.php' ) ) ){ echo 'block'; } else {echo 'none';} ?>;">
|
||||
<li>
|
||||
<a href="help_faq.php"> <?= lang("Navigation_HelpFAQ");?> </a>
|
||||
</li>
|
||||
@@ -467,7 +492,7 @@ function workInProgress() {
|
||||
//--------------------------------------------------------------
|
||||
|
||||
// Update server time in the header
|
||||
show_pia_servertime()
|
||||
update_servertime()
|
||||
|
||||
// Update server state in the header
|
||||
updateState()
|
||||
|
||||
@@ -60,12 +60,15 @@
|
||||
"BackDevices_darkmode_enabled": "",
|
||||
"CLEAR_NEW_FLAG_description": "",
|
||||
"CLEAR_NEW_FLAG_name": "",
|
||||
"CustProps_cant_remove": "",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "",
|
||||
"DISCOVER_PLUGINS_description": "",
|
||||
"DISCOVER_PLUGINS_name": "",
|
||||
"DevDetail_Copy_Device_Title": "",
|
||||
"DevDetail_Copy_Device_Tooltip": "",
|
||||
"DevDetail_CustomProperties_Title": "",
|
||||
"DevDetail_CustomProps_reset_info": "",
|
||||
"DevDetail_DisplayFields_Title": "",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "",
|
||||
"DevDetail_EveandAl_AlertDown": "",
|
||||
@@ -182,6 +185,7 @@
|
||||
"DevDetail_button_Delete": "",
|
||||
"DevDetail_button_DeleteEvents": "",
|
||||
"DevDetail_button_DeleteEvents_Warning": "",
|
||||
"DevDetail_button_Delete_ask": "",
|
||||
"DevDetail_button_OverwriteIcons": "",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "",
|
||||
@@ -205,6 +209,7 @@
|
||||
"Device_Shortcut_OnlineChart": "",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "",
|
||||
"Device_TableHead_CustomProps": "",
|
||||
"Device_TableHead_Favorite": "",
|
||||
"Device_TableHead_FirstSession": "",
|
||||
"Device_TableHead_GUID": "",
|
||||
@@ -237,12 +242,15 @@
|
||||
"Device_Tablelenght": "",
|
||||
"Device_Tablelenght_all": "",
|
||||
"Device_Title": "",
|
||||
"Devices_Filters": "",
|
||||
"Donations_Others": "",
|
||||
"Donations_Platforms": "",
|
||||
"Donations_Text": "",
|
||||
"Donations_Title": "",
|
||||
"ENABLE_PLUGINS_description": "",
|
||||
"ENABLE_PLUGINS_name": "",
|
||||
"ENCRYPTION_KEY_description": "",
|
||||
"ENCRYPTION_KEY_name": "",
|
||||
"Email_display_name": "",
|
||||
"Email_icon": "",
|
||||
"Events_Loading": "",
|
||||
@@ -305,6 +313,7 @@
|
||||
"Gen_ReadDocs": "",
|
||||
"Gen_Remove_All": "",
|
||||
"Gen_Remove_Last": "",
|
||||
"Gen_Reset": "",
|
||||
"Gen_Restore": "",
|
||||
"Gen_Run": "",
|
||||
"Gen_Save": "",
|
||||
@@ -319,6 +328,7 @@
|
||||
"Gen_Upd_Fail": "",
|
||||
"Gen_Update": "",
|
||||
"Gen_Update_Value": "",
|
||||
"Gen_ValidIcon": "",
|
||||
"Gen_Warning": "",
|
||||
"Gen_Work_In_Progress": "",
|
||||
"Gen_create_new_device": "",
|
||||
@@ -390,6 +400,8 @@
|
||||
"Maintenance_Running_Version": "",
|
||||
"Maintenance_Status": "",
|
||||
"Maintenance_Title": "",
|
||||
"Maintenance_Tool_DownloadConfig": "",
|
||||
"Maintenance_Tool_DownloadConfig_text": "",
|
||||
"Maintenance_Tool_ExportCSV": "",
|
||||
"Maintenance_Tool_ExportCSV_noti": "",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "",
|
||||
@@ -398,9 +410,13 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportCSV_text": "",
|
||||
"Maintenance_Tool_ImportConfig_noti": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "",
|
||||
"Maintenance_Tool_arpscansw": "",
|
||||
"Maintenance_Tool_arpscansw_noti": "",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "",
|
||||
@@ -702,6 +718,7 @@
|
||||
"general_event_title": "",
|
||||
"go_to_node_event_icon": "",
|
||||
"go_to_node_event_tooltip": "",
|
||||
"new_version_available": "",
|
||||
"report_guid": "",
|
||||
"report_guid_missing": "",
|
||||
"report_select_format": "",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Pots especificar una consulta SQL personalitzada que generarà un fitxer JSON i el mostrarà mitjançant <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> file endpoint</a>.",
|
||||
"API_CUSTOM_SQL_name": "Punt final personalitzat",
|
||||
"API_TOKEN_description": "Token API per assegurar les comunicacions, pots generar-ne una o introduir una clau. S'enviarà a la capçalera de pa petició. Es fa servir al plugin <code>SYNC</code> , del servidor GraphQL.",
|
||||
"API_TOKEN_description": "Token API per assegurar les comunicacions, pots generar-ne un o introduir un valor clau. S'enviarà a la capçalera de la petició <code>SYNC</code> plugin, servidor GraphQL i altres endpoints API. Pots fer servir els endpoints API per crear integracions personalitzades tal com es descriu a <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md\" target=\"_blank\">la documentació API</a>.",
|
||||
"API_TOKEN_name": "Token API",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
@@ -60,12 +60,15 @@
|
||||
"BackDevices_darkmode_enabled": "Mode fosc Activat",
|
||||
"CLEAR_NEW_FLAG_description": "Si està habilitat (<code>0</code> està desactivat), els dispositius marcats com <b>Nou dispositiu</b> es desmarcaran si el temps límit (especificat en hores) supera <b>Primera sessió</b>.",
|
||||
"CLEAR_NEW_FLAG_name": "Netejar indicador de nou",
|
||||
"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_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_name": "Descobreix els plugins",
|
||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copiar detalls des del dispositiu",
|
||||
"DevDetail_Copy_Device_Tooltip": "Copiar detalls del dispositius des de la llista desplegable. Tot el d'aquesta pàgina es sobre-escriurà",
|
||||
"DevDetail_CustomProperties_Title": "Propietats personalitzades",
|
||||
"DevDetail_CustomProps_reset_info": "Això eliminarà les seves propietats personalitzades en aquest dispositiu i restablirà el valor predeterminat.",
|
||||
"DevDetail_DisplayFields_Title": "Pantalla",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Alertes",
|
||||
"DevDetail_EveandAl_AlertDown": "Cancel·lar alerta",
|
||||
@@ -74,7 +77,7 @@
|
||||
"DevDetail_EveandAl_NewDevice_Tooltip": "Es mostrarà el nou estat del dispositiu i s'inclourà a les llistes quan el filtre New Devices estigui actiu. No afecta les notificacions.",
|
||||
"DevDetail_EveandAl_RandomMAC": "MAC aleatori",
|
||||
"DevDetail_EveandAl_ScanCycle": "Dispositiu d'escaneig",
|
||||
"DevDetail_EveandAl_ScanCycle_a": "Dispositiu d'escaneig",
|
||||
"DevDetail_EveandAl_ScanCycle_a": "Escanejar Dispositiu",
|
||||
"DevDetail_EveandAl_ScanCycle_z": "No Escanejar Dispositiu",
|
||||
"DevDetail_EveandAl_Skip": "Omet notificacions repetides per",
|
||||
"DevDetail_EveandAl_Title": "Configuració de Successos i Alertes",
|
||||
@@ -135,8 +138,8 @@
|
||||
"DevDetail_Shortcut_DownAlerts": "Aturar alertes",
|
||||
"DevDetail_Shortcut_Presence": "Presència",
|
||||
"DevDetail_Shortcut_Sessions": "Sessions",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Detalls",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Esdeveniments",
|
||||
"DevDetail_Tab_Details": "Detalls",
|
||||
"DevDetail_Tab_Events": "Esdeveniments",
|
||||
"DevDetail_Tab_EventsTableDate": "Data",
|
||||
"DevDetail_Tab_EventsTableEvent": "Tipus d'esdeveniment",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
@@ -151,10 +154,10 @@
|
||||
"DevDetail_Tab_NmapTableState": "Estat",
|
||||
"DevDetail_Tab_NmapTableText": "Configurar un calendari a <a href=\"/settings.php#NMAP_ACTIVE\">Configuració</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "Temps",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Connectors (Plugins)",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Presència",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sessions",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Eines",
|
||||
"DevDetail_Tab_Plugins": "Connectors (Plugins)",
|
||||
"DevDetail_Tab_Presence": "Presència",
|
||||
"DevDetail_Tab_Sessions": "Sessions",
|
||||
"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_Error": "S'ha produït un error",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Inici Informació d'Internet",
|
||||
@@ -180,8 +183,9 @@
|
||||
"DevDetail_button_AddIcon_Help": "Enganxeu en una etiqueta html SVG o en una icona etiqueta html Font Awesome. Llegir el <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/ICONS.md\" target=\"_blank\">Icons docs</a> per a més detalls.",
|
||||
"DevDetail_button_AddIcon_Tooltip": "Afegir una nova Icona a aquest dispositiu que encara no està disponible al desplegable.",
|
||||
"DevDetail_button_Delete": "Eliminar dispositiu",
|
||||
"DevDetail_button_DeleteEvents": "Eliminar Esdeveniments",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Estàs segur que vols eliminar tots els esdeveniments d'aquest dispositiu?<br><br>(això esborrarà la <b>Historial d'esdeveniments</b> i la <b>Sessions</b> i pot ajudar amb les notificacions constants (persistents)",
|
||||
"DevDetail_button_DeleteEvents": "Esborrar Esdeveniments",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Estàs segur que vols eliminar tots els esdeveniments d'aquest dispositiu?<br><br>(això esborrarà <b>l'Historial d'esdeveniments</b> i les <b>Sessions</b> i pot ajudar amb les notificacions persistents",
|
||||
"DevDetail_button_Delete_ask": "Segur que vols eliminar aquest dispositiu?. En comptes d'això el pots arxivar.",
|
||||
"DevDetail_button_OverwriteIcons": "Sobreescriure icones",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Sobreescriure icones de tots els dispositius amb el mateix tipus de dispositiu",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Estàs segur que vols sobreescriure totes les icones de tots els dispositius amb el mateix tipus de dispositiu que el tipus de dispositiu actual?",
|
||||
@@ -202,9 +206,10 @@
|
||||
"Device_Shortcut_DownOnly": "Aturat",
|
||||
"Device_Shortcut_Favorites": "Favorits",
|
||||
"Device_Shortcut_NewDevices": "Nous dispositius",
|
||||
"Device_Shortcut_OnlineChart": "Presència de dispositius",
|
||||
"Device_Shortcut_OnlineChart": "Dispositius detectats",
|
||||
"Device_TableHead_AlertDown": "Cancel·lar alerta",
|
||||
"Device_TableHead_Connected_Devices": "Connexions",
|
||||
"Device_TableHead_CustomProps": "Props / Accions",
|
||||
"Device_TableHead_Favorite": "Favorit",
|
||||
"Device_TableHead_FirstSession": "Primera Sessió",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
@@ -237,12 +242,15 @@
|
||||
"Device_Tablelenght": "Veure_entrades_MENU",
|
||||
"Device_Tablelenght_all": "Tot",
|
||||
"Device_Title": "Dispositius",
|
||||
"Devices_Filters": "Filtres",
|
||||
"Donations_Others": "Altres",
|
||||
"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_Title": "Donacions",
|
||||
"ENABLE_PLUGINS_description": "Habilita la <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">connectors</a> funcionalitat. Carregar els connectors requereix més recursos de maquinari així podries voler desactivar-los en un sistema de baixos recursos.",
|
||||
"ENABLE_PLUGINS_name": "Activa els connectors(Plugins)",
|
||||
"ENCRYPTION_KEY_description": "Clau de xifrat de dades.",
|
||||
"ENCRYPTION_KEY_name": "Clau d'encriptació",
|
||||
"Email_display_name": "Correu electrònic",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Carregant ...",
|
||||
@@ -278,7 +286,7 @@
|
||||
"Events_Tablelenght": "Veure_entrades_MENU",
|
||||
"Events_Tablelenght_all": "Tot",
|
||||
"Events_Title": "Esdeveniments",
|
||||
"GRAPHQL_PORT_description": "El número de port del servidor GraphQL.",
|
||||
"GRAPHQL_PORT_description": "El número de port del servidor GraphQL. Comprova que el port és únic en totes les aplicacions d'aquest servidor i en totes les instàncies de NetAlertX.",
|
||||
"GRAPHQL_PORT_name": "Port GraphQL",
|
||||
"Gen_Action": "Acció",
|
||||
"Gen_Add": "Afegir",
|
||||
@@ -301,10 +309,11 @@
|
||||
"Gen_Offline": "Fora de línia",
|
||||
"Gen_Okay": "Ok",
|
||||
"Gen_Online": "En línia",
|
||||
"Gen_Purge": "Elimina",
|
||||
"Gen_Purge": "Neteja",
|
||||
"Gen_ReadDocs": "Llegit més dins el docs.",
|
||||
"Gen_Remove_All": "Esborra tot",
|
||||
"Gen_Remove_Last": "Esborra el darrer",
|
||||
"Gen_Reset": "Reinicialització",
|
||||
"Gen_Restore": "Executar Restaurar",
|
||||
"Gen_Run": "Executar",
|
||||
"Gen_Save": "Guardar",
|
||||
@@ -319,6 +328,7 @@
|
||||
"Gen_Upd_Fail": "Actualització fallida",
|
||||
"Gen_Update": "Actualitza",
|
||||
"Gen_Update_Value": "Actualitzar Valor",
|
||||
"Gen_ValidIcon": "",
|
||||
"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_create_new_device": "Nou dispositiu",
|
||||
@@ -365,9 +375,9 @@
|
||||
"HelpFAQ_Cat_Presence_401_head": "Un dispositiu és mostrat tan present tot i que és Fora de línia \"\".",
|
||||
"HelpFAQ_Cat_Presence_401_text": "Si això passa, tens la possibilitat d'esborrar els esdeveniments del dispositiu en qüestió (veure detalls). Una altra possibilitat seria canviar el dispositiu i esperar fins a NetAlert X reconeix el dispositiu com a \"en línia\" amb la següent exploració i, a continuació, simplement torneu a desactivar el dispositiu. NetAlert X ha de tenir en compte l'estat del dispositiu a la base de dades amb la següent exploració.",
|
||||
"HelpFAQ_Title": "Ajuda / FAQ",
|
||||
"LOADED_PLUGINS_description": "Quins Connectors(Plugins) carregar. Afegir connectors podria alentir l'aplicació. Llegir més sobre quins connectors necessiten estar habilitats, tipus, o opcions d'escanejar dins del <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme\">documents de connectors</a>. Els connectors descarregats perdran els vostres paràmetres. Només <code>desactivats</code> es poden eliminar els connectors.",
|
||||
"LOADED_PLUGINS_description": "Quins Plugins carregar. Afegir plugins podria alentir l'aplicació. Llegir més sobre quins connectors necessiten estar habilitats, els tipus, o les opcions d'escaneig dins del <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme\">documents de connectors</a>. Els connectors descarregats perdran els vostres paràmetres. Només <code>desactivats</code> es poden eliminar els connectors.",
|
||||
"LOADED_PLUGINS_name": "Connectors carregats",
|
||||
"LOG_LEVEL_description": "Aquest paràmetre permetrà un registre més verbal. Útil per a la depuració d'esdeveniments escrivint a la base de dades.",
|
||||
"LOG_LEVEL_description": "Aquest paràmetre permetrà un registre més detallat. Útil per a la depuració d'esdeveniments d'escriptura a la base de dades.",
|
||||
"LOG_LEVEL_name": "Imprimeix el registre addicional",
|
||||
"Loading": "Carregant ...",
|
||||
"Login_Box": "Introduïu la vostra contrasenya",
|
||||
@@ -376,7 +386,7 @@
|
||||
"Login_Psw-box": "Contrasenya",
|
||||
"Login_Psw_alert": "Alerta de contrasenya!",
|
||||
"Login_Psw_folder": "a la carpeta config.",
|
||||
"Login_Psw_new": "new_password",
|
||||
"Login_Psw_new": "contrasenya_nova",
|
||||
"Login_Psw_run": "Per canviar la contrasenya executar:",
|
||||
"Login_Remember": "Recorda",
|
||||
"Login_Remember_small": "(vàlid per 7 dies)",
|
||||
@@ -390,17 +400,23 @@
|
||||
"Maintenance_Running_Version": "Versió instal·lada",
|
||||
"Maintenance_Status": "Estat",
|
||||
"Maintenance_Title": "Eines de manteniment",
|
||||
"Maintenance_Tool_ExportCSV": "CSV Exportació",
|
||||
"Maintenance_Tool_DownloadConfig": "Exportació de paràmetres",
|
||||
"Maintenance_Tool_DownloadConfig_text": "Descarregueu una còpia de seguretat completa de la vostra configuració de configuració emmagatzemada al fitxer <code>app.conf</code>.",
|
||||
"Maintenance_Tool_ExportCSV": "CSV Exportació de dispositius",
|
||||
"Maintenance_Tool_ExportCSV_noti": "CSV Exportació",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Estàs segur que vols generar un fitxer CSV?",
|
||||
"Maintenance_Tool_ExportCSV_text": "Genera un fitxer CSV (comma separated value) que conté la llista dels dispositius incloent les relacions de Xarxa entre Nodes i dispositius connectats. També pots disparar-ho accedint a la URL <code>el vostre NetAlertX url/php/server/devices.php?acció=ExportCSV</code> o activant el connector <a href=\"settings.php#CSVBCKP_header\">CSV Còpia de seguretat</a>.",
|
||||
"Maintenance_Tool_ImportCSV": "CSV Importació",
|
||||
"Maintenance_Tool_ExportCSV_text": "Genera un fitxer CSV (comma separated value) que conté la llista dels dispositius incloent les relacions de Xarxa entre Nodes i dispositius connectats. També pots disparar-ho accedint a la URL <code>el_vostre_NetAlertX_ url/php/server/devices.php?acció=ExportCSV</code> o activant el connector <a href=\"settings.php#CSVBCKP_header\">CSV Còpia de seguretat</a>.",
|
||||
"Maintenance_Tool_ImportCSV": "CSV Importació de dispositius",
|
||||
"Maintenance_Tool_ImportCSV_noti": "CSV Importació",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Estàs segur que vols importar el fitxer CSV? Això <b> sobreescriurà</b> completament els dispositius de la seva base de dades.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Abans d'utilitzar aquesta funció, fes una còpia de seguretat, si us plau. Importa un CSV (comma separated value) el fitxer que conté la llista dels dispositius que inclouen les relacions de Xarxa entre Nodes i dispositius connectats. Per fer-ho col·loca el CSV el fitxer anomenat <b>devices.csv</b> a la vostra <b>/config</b> carpeta.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Importació CSV (Paste)",
|
||||
"Maintenance_Tool_ImportConfig_noti": "Importació de la configuració (app.conf)",
|
||||
"Maintenance_Tool_ImportPastedCSV": "CSV Importació de dispositius (Paste)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "Estàs segur que vols importar el CSV copiat? Això <b> sobreescriurà</b> completament els dispositius de la base de dades.",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "Abans d'utilitzar aquesta funció, feu una còpia de seguretat. Importar un fitxer CSV (comma separated value) que contingui la llista de dispositius, incloent les relacions de xarxa entre els nodes i els dispositius connectats.",
|
||||
"Maintenance_Tool_ImportPastedConfig": "Importació de la configuració (paste)",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "Estàs segur que vols importar la configuració config enganxada? Això <b> sobreescriurà</b> completament el fitxer <code>app.conf</code>.",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "Importa el fitxer <code>app.conf</code> que conté tota l'aplicació Configuració. És possible que vulgueu descarregar el fitxer actual <code>app.conf</code> primer amb el <b>Settings Export</b>.",
|
||||
"Maintenance_Tool_arpscansw": "Conmuta arp-Scan (on/off)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Conmuta arp-Scan on or off",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Quan l'escàner ha estat canviat a off es queda off fins que és activat de bell nou.",
|
||||
@@ -420,25 +436,25 @@
|
||||
"Maintenance_Tool_del_ActHistory_text": "El gràfic d’activitat de la xarxa es reinicialitzarà. No afecta als esdeveniments.",
|
||||
"Maintenance_Tool_del_alldev": "Eliminar tots els dispositius",
|
||||
"Maintenance_Tool_del_alldev_noti": "Eliminar dispositius",
|
||||
"Maintenance_Tool_del_alldev_noti_text": "Estàs segur que vols eliminar tots els dispositius?",
|
||||
"Maintenance_Tool_del_alldev_noti_text": "Segur que vols eliminar tots els dispositius?",
|
||||
"Maintenance_Tool_del_alldev_text": "Abans d'utilitzar aquesta funció, feu una còpia de seguretat. La supressió no es pot desfer. Tots els dispositius s'eliminaran de la base de dades.",
|
||||
"Maintenance_Tool_del_allevents": "Suprimeix esdeveniments (Elimina presència)",
|
||||
"Maintenance_Tool_del_allevents30": "Suprimeix tots els esdeveniments més vells que 30 dies",
|
||||
"Maintenance_Tool_del_allevents": "Elimina deteccions (presència)",
|
||||
"Maintenance_Tool_del_allevents30": "Suprimeix tots els esdeveniments anteriors a 30 dies",
|
||||
"Maintenance_Tool_del_allevents30_noti": "Eliminar Esdeveniments",
|
||||
"Maintenance_Tool_del_allevents30_noti_text": "T'és segur vols eliminar tot els successos més vells que 30 dies? Això elimina la Presencia de tots els Dispositius.",
|
||||
"Maintenance_Tool_del_allevents30_text": "Abans d'utilitzar aquesta funció, feu una còpia de seguretat. La supressió no es pot desfer. S'eliminaran tots els esdeveniments mes vells de 30 dies a la base de dades. També es restablirà la presència de tots els dispositius. Això pot portar a sessions no vàlides. Això significa que els dispositius es mostren com a \"present\" encara que estiguin fora de línia. Una anàlisi mentre el dispositiu en qüestió està en línia resol el problema.",
|
||||
"Maintenance_Tool_del_allevents30_noti_text": "T'és segur vols eliminar tot els successos més vells que 30 dies? Això elimina tots els dispositius presents.",
|
||||
"Maintenance_Tool_del_allevents30_text": "Abans d'utilitzar aquesta funció, feu una còpia de seguretat. La supressió no es pot desfer. S'eliminaran tots els esdeveniments mes vells de 30 dies a la base de dades. També es restablirà la detecció de presència de tots els dispositius. Això pot portar a sessions no vàlides. Això significa que els dispositius es mostren com a \"presents/detectats\" encara que estiguin fora de línia. Una anàlisi mentre el dispositiu en qüestió està en línia resol el problema.",
|
||||
"Maintenance_Tool_del_allevents_noti": "Eliminar Esdeveniments",
|
||||
"Maintenance_Tool_del_allevents_noti_text": "Estàs segur que vols eliminar tots els esdeveniments? Això reinicialització Presència de tots els dispositius.",
|
||||
"Maintenance_Tool_del_allevents_text": "Abans d'utilitzar aquesta funció, feu una còpia de seguretat. La supressió no es pot desfer. Tots els esdeveniments de la base de dades seran esborrats. Es restablirà dada de presència de tots els dispositius. Les sessions seran invalidades. Això significa que els dispositius es poden mostrar com a \"present\" encara que estiguin fora de línia. Una anàlisi mentre el dispositiu en qüestió està en línia resol el problema.",
|
||||
"Maintenance_Tool_del_allevents_noti_text": "Estàs segur que vols eliminar tots els esdeveniments? Això reinicialitza la detecció de presència de tots els dispositius.",
|
||||
"Maintenance_Tool_del_allevents_text": "Abans d'utilitzar aquesta funció, feu una còpia de seguretat. La supressió no es pot desfer. Tots els esdeveniments de la base de dades s'esborraran. Es restablirà dada de detecció de tots els dispositius. S'invalidaran les sessions. Això significa que els dispositius es poden mostrar com a \"present\" encara que estiguin fora de línia. Una anàlisi mentre el dispositiu en qüestió està en línia resol el problema.",
|
||||
"Maintenance_Tool_del_empty_macs": "Eliminar dispositius amb MAC buits",
|
||||
"Maintenance_Tool_del_empty_macs_noti": "Elimina Dispositius",
|
||||
"Maintenance_Tool_del_empty_macs_noti_text": "Estàs segur que vols eliminar tots els dispositius amb adreces MAC buides?<br>(potser prefereix arxivar-lo)",
|
||||
"Maintenance_Tool_del_empty_macs_text": "Abans d'utilitzar aquesta funció, feu una còpia de seguretat. La supressió no es pot desfer. Tots els dispositius sense MAC s'eliminaran de la base de dades.",
|
||||
"Maintenance_Tool_del_selecteddev": "Suprimeix els dispositius seleccionats",
|
||||
"Maintenance_Tool_del_selecteddev_text": "Abans d'utilitzar aquesta funció, feu una còpia de seguretat. La supressió no es pot desfer. Els dispositius seleccionats s'eliminaran de la base de dades.",
|
||||
"Maintenance_Tool_del_unknowndev": "Suprimeix dispositius (desconeguts)",
|
||||
"Maintenance_Tool_del_unknowndev_noti": "Suprimeix dispositius (desconeguts)",
|
||||
"Maintenance_Tool_del_unknowndev_noti_text": "Estàs segur que vols eliminar tots els dispositius (no coneguts) i amb nom (no trobat)?",
|
||||
"Maintenance_Tool_del_unknowndev": "Elimina dispositius desconeguts",
|
||||
"Maintenance_Tool_del_unknowndev_noti": "Elimina dispositius desconeguts",
|
||||
"Maintenance_Tool_del_unknowndev_noti_text": "Estàs segur que vols eliminar tots els dispositius (no coneguts) o amb nom (no trobat)?",
|
||||
"Maintenance_Tool_del_unknowndev_text": "Abans d'utilitzar aquesta funció, feu una còpia de seguretat. La supressió no es pot desfer. Tots els dispositius anomenats (no coneguts) s'eliminaran de la base de dades.",
|
||||
"Maintenance_Tool_displayed_columns_text": "Canvieu la visibilitat i l'ordre de les columnes a la pàgina <a href=\"devices.php\"><b> <i class=\"fa fa-laptop\"></i> Dispositius</b></a>.",
|
||||
"Maintenance_Tool_drag_me": "Arrossega'm a reorder columnes.",
|
||||
@@ -475,13 +491,13 @@
|
||||
"Maintenance_lang_selector_empty": "Tria idioma",
|
||||
"Maintenance_lang_selector_lable": "Selecció d'idioma",
|
||||
"Maintenance_lang_selector_text": "El canvi té lloc en el cantó del client, així que afecta només el navegador actual.",
|
||||
"Maintenance_new_version": "🆕 Hi ha una nova versió. Comprova <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">release notes</a>.",
|
||||
"Maintenance_new_version": "Hi ha una nova versió. Comprova <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">release notes</a>.",
|
||||
"Maintenance_themeselector_apply": "Aplica",
|
||||
"Maintenance_themeselector_empty": "Tria una Skin",
|
||||
"Maintenance_themeselector_lable": "Selecciona una Skin",
|
||||
"Maintenance_themeselector_text": "El canvi té lloc a la part del servidor, per la qual cosa afecta tots els dispositius en ús.",
|
||||
"Maintenance_version": "Actualitzacions d'aplicació",
|
||||
"NETWORK_DEVICE_TYPES_description": "Quins tipus de dispositius es poden utilitzar com a dispositius de xarxa a la vista de xarxa. El tipus de dispositiu ha de coincidir exactament amb la <code>Type</code> configuració d'un dispositiu específic als detalls del dispositiu. No elimini els tipus existents, només afegir-ne nous.",
|
||||
"NETWORK_DEVICE_TYPES_description": "Quins tipus de dispositius es poden utilitzar com a dispositius de xarxa a la vista \"xarxa\". El tipus de dispositiu ha de coincidir exactament amb la configuració <code>Tipus</code> dels detalls de dispositiu. Afegir-ho al dispositiu fent servir el botó <code>+</code>. No elimini els tipus existents, només afegir-ne nous.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Tipus de dispositiu de xarxa",
|
||||
"Navigation_About": "Sobre",
|
||||
"Navigation_Devices": "Dispositius",
|
||||
@@ -550,7 +566,7 @@
|
||||
"PIALERT_WEB_PROTECTION_name": "Activa l'accés",
|
||||
"PLUGINS_KEEP_HIST_description": "Quantes entrades de Plugins s'han de mantenir a la història (per Plugin, no per dispositiu).",
|
||||
"PLUGINS_KEEP_HIST_name": "Història dels Plugins",
|
||||
"Plugins_DeleteAll": "Elimina tot (els filtres són ignorats)",
|
||||
"Plugins_DeleteAll": "Elimina tot (s'ignoraran els filtres)",
|
||||
"Plugins_Filters_Mac": "Filtre de MAC",
|
||||
"Plugins_History": "Historial d'Esdeveniments",
|
||||
"Plugins_Obj_DeleteListed": "Suprimeix els objectes mostrats",
|
||||
@@ -579,7 +595,7 @@
|
||||
"Presence_Shortcut_DownAlerts": "Aturar alertes",
|
||||
"Presence_Shortcut_Favorites": "Favorits",
|
||||
"Presence_Shortcut_NewDevices": "Nous dispositius",
|
||||
"Presence_Title": "Presència per dispositiu",
|
||||
"Presence_Title": "Detecció de dispositius",
|
||||
"REPORT_DASHBOARD_URL_description": "Aquesta URL s'utilitza com a base per generar enllaços en informes HTML (per exemple: correus electrònics). Introduïu la URL completa començant per <code>http://</code> incloent el número de port (sense barra inicial <code>/</code>).",
|
||||
"REPORT_DASHBOARD_URL_name": "URL NetAlertX",
|
||||
"REPORT_ERROR": "Si us plau, introdueix dins de la caixa de text els caràcters que veu a la imatge de sota. Això és requerit per evitar enviaments automàtics",
|
||||
@@ -686,7 +702,7 @@
|
||||
"UI_NOT_RANDOM_MAC_description": "Prefixos MAC que no s'han de marcar com a dispositius aleatoris. Introduïu per exemple <code> 52</code> per excloure els dispositius començant per <code> 52:xx:xx:xx:xx:xx</code> de ser marcats com a dispositius amb una adreça MAC aleatòria.",
|
||||
"UI_NOT_RANDOM_MAC_name": "No marqueu com a aleatori",
|
||||
"UI_PRESENCE_description": "Seleccioneu quins estats s'han de mostrar al gràfic <b> Presència de dispositius</b> a la pàgina <a href=\"/devices.php\" target=\"_blank\">Dispositius</a>.",
|
||||
"UI_PRESENCE_name": "Mostra al mapa de presència",
|
||||
"UI_PRESENCE_name": "Mostra al mapa de detecció",
|
||||
"UI_REFRESH_description": "Introduïu el nombre de segons després del qual es recarrega la interfície d'usuari. Configura a <code>0</code> per desactivar.",
|
||||
"UI_REFRESH_name": "Auto-refresc UI",
|
||||
"VERSION_description": "Versió o valor timestamp per comprovar si l'aplicació va ser actualitzada.",
|
||||
@@ -702,6 +718,7 @@
|
||||
"general_event_title": "Execució d'un esdeveniment ad-hoc",
|
||||
"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",
|
||||
"new_version_available": "Ja està disponible una nova versió.",
|
||||
"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_select_format": "Seleccioneu Format:",
|
||||
|
||||
@@ -60,12 +60,15 @@
|
||||
"BackDevices_darkmode_enabled": "",
|
||||
"CLEAR_NEW_FLAG_description": "",
|
||||
"CLEAR_NEW_FLAG_name": "",
|
||||
"CustProps_cant_remove": "",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "",
|
||||
"DISCOVER_PLUGINS_description": "",
|
||||
"DISCOVER_PLUGINS_name": "",
|
||||
"DevDetail_Copy_Device_Title": "",
|
||||
"DevDetail_Copy_Device_Tooltip": "",
|
||||
"DevDetail_CustomProperties_Title": "",
|
||||
"DevDetail_CustomProps_reset_info": "",
|
||||
"DevDetail_DisplayFields_Title": "",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "",
|
||||
"DevDetail_EveandAl_AlertDown": "",
|
||||
@@ -182,6 +185,7 @@
|
||||
"DevDetail_button_Delete": "",
|
||||
"DevDetail_button_DeleteEvents": "",
|
||||
"DevDetail_button_DeleteEvents_Warning": "",
|
||||
"DevDetail_button_Delete_ask": "",
|
||||
"DevDetail_button_OverwriteIcons": "",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "",
|
||||
@@ -205,6 +209,7 @@
|
||||
"Device_Shortcut_OnlineChart": "",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "",
|
||||
"Device_TableHead_CustomProps": "",
|
||||
"Device_TableHead_Favorite": "",
|
||||
"Device_TableHead_FirstSession": "",
|
||||
"Device_TableHead_GUID": "",
|
||||
@@ -237,12 +242,15 @@
|
||||
"Device_Tablelenght": "",
|
||||
"Device_Tablelenght_all": "",
|
||||
"Device_Title": "",
|
||||
"Devices_Filters": "",
|
||||
"Donations_Others": "",
|
||||
"Donations_Platforms": "",
|
||||
"Donations_Text": "",
|
||||
"Donations_Title": "",
|
||||
"ENABLE_PLUGINS_description": "",
|
||||
"ENABLE_PLUGINS_name": "",
|
||||
"ENCRYPTION_KEY_description": "",
|
||||
"ENCRYPTION_KEY_name": "",
|
||||
"Email_display_name": "",
|
||||
"Email_icon": "",
|
||||
"Events_Loading": "",
|
||||
@@ -305,6 +313,7 @@
|
||||
"Gen_ReadDocs": "",
|
||||
"Gen_Remove_All": "",
|
||||
"Gen_Remove_Last": "",
|
||||
"Gen_Reset": "",
|
||||
"Gen_Restore": "",
|
||||
"Gen_Run": "",
|
||||
"Gen_Save": "",
|
||||
@@ -319,6 +328,7 @@
|
||||
"Gen_Upd_Fail": "",
|
||||
"Gen_Update": "",
|
||||
"Gen_Update_Value": "",
|
||||
"Gen_ValidIcon": "",
|
||||
"Gen_Warning": "",
|
||||
"Gen_Work_In_Progress": "",
|
||||
"Gen_create_new_device": "",
|
||||
@@ -390,6 +400,8 @@
|
||||
"Maintenance_Running_Version": "",
|
||||
"Maintenance_Status": "",
|
||||
"Maintenance_Title": "",
|
||||
"Maintenance_Tool_DownloadConfig": "",
|
||||
"Maintenance_Tool_DownloadConfig_text": "",
|
||||
"Maintenance_Tool_ExportCSV": "",
|
||||
"Maintenance_Tool_ExportCSV_noti": "",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "",
|
||||
@@ -398,9 +410,13 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportCSV_text": "",
|
||||
"Maintenance_Tool_ImportConfig_noti": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "",
|
||||
"Maintenance_Tool_arpscansw": "",
|
||||
"Maintenance_Tool_arpscansw_noti": "",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "",
|
||||
@@ -702,6 +718,7 @@
|
||||
"general_event_title": "",
|
||||
"go_to_node_event_icon": "",
|
||||
"go_to_node_event_tooltip": "",
|
||||
"new_version_available": "",
|
||||
"report_guid": "",
|
||||
"report_guid_missing": "",
|
||||
"report_select_format": "",
|
||||
|
||||
@@ -72,12 +72,15 @@
|
||||
"BackDevices_darkmode_enabled": "Dunkler Modus aktiviert",
|
||||
"CLEAR_NEW_FLAG_description": "Wenn aktiviert (<code>0</code> bedeutet deaktiviert), werden Geräte, die als <b>Neues Gerät</b> gekennzeichnet sind, wieder freigegeben, wenn das Zeitlimit (in Stunden) die Zeit ihrer <b>Ersten Sitzung</b> überschreitet.",
|
||||
"CLEAR_NEW_FLAG_name": "Neues Flag löschen",
|
||||
"CustProps_cant_remove": "Kann nicht entfernt werden, es wird mindestens eine Eigenschaft benötigt.",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "Dies ist eine Wartungseinstellung. Spezifiziert wie viele Tage Events gespeichert bleiben. Alle älteren Events werden periodisch gelöscht. Wird auch auf die Plugins History angewendet.",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Ereignisse löschen, die älter sind als",
|
||||
"DISCOVER_PLUGINS_description": "",
|
||||
"DISCOVER_PLUGINS_name": "",
|
||||
"DevDetail_Copy_Device_Title": "Details von Gerät kopieren",
|
||||
"DevDetail_Copy_Device_Tooltip": "Details vom Gerät aus der Dropdown-Liste kopieren. Alles auf dieser Seite wird überschrieben",
|
||||
"DevDetail_CustomProperties_Title": "Benutzerdefinierte Eigenschaften",
|
||||
"DevDetail_CustomProps_reset_info": "Dadurch werden Ihre benutzerdefinierten Eigenschaften auf diesem Gerät entfernt und auf den Standardwert zurückgesetzt.",
|
||||
"DevDetail_DisplayFields_Title": "Anzeige",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Alarmereignisse",
|
||||
"DevDetail_EveandAl_AlertDown": "Melde Down",
|
||||
@@ -147,8 +150,8 @@
|
||||
"DevDetail_Shortcut_DownAlerts": "Down Meldungen",
|
||||
"DevDetail_Shortcut_Presence": "Anwesenheit",
|
||||
"DevDetail_Shortcut_Sessions": "Sitzungen",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Details",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Ereignisse",
|
||||
"DevDetail_Tab_Details": "Details",
|
||||
"DevDetail_Tab_Events": "Ereignisse",
|
||||
"DevDetail_Tab_EventsTableDate": "Datum",
|
||||
"DevDetail_Tab_EventsTableEvent": "Ereignistype",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
@@ -163,10 +166,10 @@
|
||||
"DevDetail_Tab_NmapTableState": "Status",
|
||||
"DevDetail_Tab_NmapTableText": "Erstelle einen Plan über die<a href=\"/settings.php#NMAP_ACTIVE\">Einstellungen</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "Zeit",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Anwesenheit",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sitzungen",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Werkzeuge",
|
||||
"DevDetail_Tab_Plugins": "Plugins",
|
||||
"DevDetail_Tab_Presence": "Anwesenheit",
|
||||
"DevDetail_Tab_Sessions": "Sitzungen",
|
||||
"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_Error": "Es ist ein Fehler aufgetreten",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Internet-Info starten",
|
||||
@@ -194,6 +197,7 @@
|
||||
"DevDetail_button_Delete": "Gerät löschen",
|
||||
"DevDetail_button_DeleteEvents": "Ereignisse löschen",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Sind Sie sicher, dass Sie alle Ereignisse dieses Geräts löschen möchten? (dies löscht den Ereignisverlauf und die Sitzungen und könnte bei ständigen (anhaltenden) Benachrichtigungen helfen)",
|
||||
"DevDetail_button_Delete_ask": "Sind Sie sicher, dass Sie dieses Gerät löschen möchten? Sie können es stattdessen auch archivieren.",
|
||||
"DevDetail_button_OverwriteIcons": "Symbole überschreiben",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Symbole aller Geräte mit demselben Gerätetyp überschreiben",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Bist du sicher, dass du alle Symbole aller Geräte mit dem gleichen Gerätetyp wie dem aktuellen Gerätetyp überschreiben willst?",
|
||||
@@ -217,6 +221,7 @@
|
||||
"Device_Shortcut_OnlineChart": "Gerätepräsenz im Laufe der Zeit",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "Verbindungen",
|
||||
"Device_TableHead_CustomProps": "",
|
||||
"Device_TableHead_Favorite": "Favorit",
|
||||
"Device_TableHead_FirstSession": "Erste Sitzung",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
@@ -249,12 +254,15 @@
|
||||
"Device_Tablelenght": "Zeige _MENU_ Einträge",
|
||||
"Device_Tablelenght_all": "Alle",
|
||||
"Device_Title": "Geräte",
|
||||
"Devices_Filters": "",
|
||||
"Donations_Others": "Andere",
|
||||
"Donations_Platforms": "Sponsor-Platformen",
|
||||
"Donations_Text": "Hey 👋! </br> Thanks for clicking on this menu item 😅 </br> </br> I'm trying to collect some donations to make you better software. Also, it would help me not to get burned out. Me burning out might mean end of support for this app. Any small (recurring or not) sponsorship makes me want ot put more effort into this app. I don't want to lock features (new plugins) behind paywalls 🔐. </br> Currently, I'm waking up 2h before work so I contribute to the app a bit. If I had some recurring income I could shorten my workweek and in the remaining time fully focus on NetAlertX. You'd get more functionality, a more polished app and less bugs. </br> </br> Thanks for reading - I'm super grateful for any support ❤🙏 </br> </br> TL;DR: By supporting me you get: </br> </br> <ul><li>Regular updates to keep your data and family safe 🔄</li><li>Less bugs 🐛🔫</li><li>Better and more functionality➕</li><li>I don't get burned out 🔥🤯</li><li>Less rushed releases 💨</li><li>Better docs📚</li><li>Quicker and better support with issues 🆘</li><li>Less grumpy me 😄</li></ul> </br> 📧Email me to <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> if you want to get in touch or if I should add other sponsorship platforms. </br>",
|
||||
"Donations_Title": "Spenden",
|
||||
"ENABLE_PLUGINS_description": "NOTUSED Enables the <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a> functionality. Loading plugins requires more hardware resources so you might want to disable them on low-powered system.",
|
||||
"ENABLE_PLUGINS_name": "NOTUSED Enable Plugins",
|
||||
"ENCRYPTION_KEY_description": "Schlüssel zur Datenverschlüsselung.",
|
||||
"ENCRYPTION_KEY_name": "Verschlüsselungsschlüssel",
|
||||
"Email_display_name": "Email",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Laden...",
|
||||
@@ -317,12 +325,13 @@
|
||||
"Gen_ReadDocs": "Mehr in der Dokumentation.",
|
||||
"Gen_Remove_All": "Alle entfernen",
|
||||
"Gen_Remove_Last": "Letzte entfernen",
|
||||
"Gen_Reset": "Zurücksetzen",
|
||||
"Gen_Restore": "Wiederherstellen",
|
||||
"Gen_Run": "Ausführen",
|
||||
"Gen_Save": "Speichern",
|
||||
"Gen_Saved": "Gespeichert",
|
||||
"Gen_Search": "Suchen",
|
||||
"Gen_Select": "",
|
||||
"Gen_Select": "Auswählen",
|
||||
"Gen_SelectIcon": "",
|
||||
"Gen_SelectToPreview": "Zur Vorschau auswählen",
|
||||
"Gen_Selected_Devices": "Ausgewählte Geräte:",
|
||||
@@ -331,9 +340,10 @@
|
||||
"Gen_Upd_Fail": "Aktualisierung fehlgeschlagen",
|
||||
"Gen_Update": "Aktualisieren",
|
||||
"Gen_Update_Value": "Wert aktualisieren",
|
||||
"Gen_ValidIcon": "",
|
||||
"Gen_Warning": "Warnung",
|
||||
"Gen_Work_In_Progress": "Keine Finalversion, feedback bitte unter: https://github.com/jokob-sk/NetAlertX/issues",
|
||||
"Gen_create_new_device": "",
|
||||
"Gen_create_new_device": "Neues Gerät",
|
||||
"Gen_create_new_device_info": "",
|
||||
"General_display_name": "Allgemein",
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
@@ -416,6 +426,8 @@
|
||||
"Maintenance_Running_Version": "Installierte Version",
|
||||
"Maintenance_Status": "Status",
|
||||
"Maintenance_Title": "Wartungswerkzeuge",
|
||||
"Maintenance_Tool_DownloadConfig": "",
|
||||
"Maintenance_Tool_DownloadConfig_text": "",
|
||||
"Maintenance_Tool_ExportCSV": "CSV Export",
|
||||
"Maintenance_Tool_ExportCSV_noti": "CSV Export",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Sind Sie sich sicher, dass Sie die CSV-Datei erstellen wollen?",
|
||||
@@ -424,9 +436,13 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "CSV Import",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Sind Sie sich sicher, dass Sie die CSV-Datei importieren wollen? Dies wird <b>alle Geräte in der Datenbank überschreiben</b>.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Machen Sie ein Backup, bevor Sie diese Funktion nutzen. Importiere eine CSV-Datei (comma separated values) mit einer Liste aller Geräte und deren Beziehungen zwischen Netzwerkknoten und verbundenen Geräten. Um dies zu tun platziere die <b>devices.csv</b> benannte CSV-Datei in deinen <b>/config</b> Ordner.",
|
||||
"Maintenance_Tool_ImportConfig_noti": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "CSV-Import (Einfügen)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "",
|
||||
"Maintenance_Tool_arpscansw": "ARP-Scan umschalten (ein/aus)",
|
||||
"Maintenance_Tool_arpscansw_noti": "ARP-Scan ein- oder ausschalten",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Wenn der Scan aus ist, bleibt er so lange aus bis er wieder aktiviert wird.",
|
||||
@@ -501,7 +517,7 @@
|
||||
"Maintenance_lang_selector_empty": "Sprache wählen",
|
||||
"Maintenance_lang_selector_lable": "Sprachauswahl",
|
||||
"Maintenance_lang_selector_text": "Die Änderung findet serverseitig statt, betrifft also alle verwendeten Geräte.",
|
||||
"Maintenance_new_version": "🆕 Eine neue Version ist vefügbar. Sieh dir die <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">Versionshinweise</a> an.",
|
||||
"Maintenance_new_version": "Eine neue Version ist vefügbar. Sieh dir die <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">Versionshinweise</a> an.",
|
||||
"Maintenance_themeselector_apply": "Übernehmen",
|
||||
"Maintenance_themeselector_empty": "Skin wählen",
|
||||
"Maintenance_themeselector_lable": "Skin Auswahl",
|
||||
@@ -783,6 +799,7 @@
|
||||
"general_event_title": "",
|
||||
"go_to_node_event_icon": "",
|
||||
"go_to_node_event_tooltip": "",
|
||||
"new_version_available": "",
|
||||
"report_guid": "",
|
||||
"report_guid_missing": "",
|
||||
"report_select_format": "Format auswählen:",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "You can specify a custom SQL query which will generate a JSON file and then expose it via the <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> file endpoint</a>.",
|
||||
"API_CUSTOM_SQL_name": "Custom endpoint",
|
||||
"API_TOKEN_description": "API token to secure communication, you can generate one or enter any value. It's sent in the request header. Used in the <code>SYNC</code> plugin, GraphQL server.",
|
||||
"API_TOKEN_description": "API token for secure communication. Generate one or enter any value. It's sent in the request header and used in the <code>SYNC</code> plugin, GraphQL server and other API endpoints. You can use the API endpoints to create custom integrations as descibed in the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md\" target=\"_blank\">API documentation</a>.",
|
||||
"API_TOKEN_name": "API token",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
@@ -48,7 +48,7 @@
|
||||
"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_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_Upgrade": "Database upgraded successfully",
|
||||
"BackDevices_DBTools_UpgradeError": "Database upgrade failed",
|
||||
@@ -60,12 +60,15 @@
|
||||
"BackDevices_darkmode_enabled": "Darkmode Enabled",
|
||||
"CLEAR_NEW_FLAG_description": "If enabled (<code>0</code> is disabled), devices flagged as <b>New Device</b> will be unflagged if the time limit (specified in hours) exceeds their <b>First Session</b> time.",
|
||||
"CLEAR_NEW_FLAG_name": "Clear new flag",
|
||||
"CustProps_cant_remove": "Can't remove, at least one property is needed.",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "This is a maintenance setting. This specifies the number of days worth of event entries that will be kept. All older events will be deleted periodically. Also applies on Plugin Events History.",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Delete events older than",
|
||||
"DISCOVER_PLUGINS_description": "Disable this option to speed up initialization and settings saving. When disabled, plugins are not discovered, and you cannot add new plugins to the <code>LOADED_PLUGINS</code> setting.",
|
||||
"DISCOVER_PLUGINS_name": "Discover plugins",
|
||||
"DevDetail_Copy_Device_Title": "Copy details from device",
|
||||
"DevDetail_Copy_Device_Tooltip": "Copy details from device from the dropdown list. Everything on this page will be overwritten",
|
||||
"DevDetail_CustomProperties_Title": "Custom Properties",
|
||||
"DevDetail_CustomProps_reset_info": "This will remove your custom properties on this device and reset them to the default value.",
|
||||
"DevDetail_DisplayFields_Title": "Display",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Alert Events",
|
||||
"DevDetail_EveandAl_AlertDown": "Alert Down",
|
||||
@@ -135,8 +138,8 @@
|
||||
"DevDetail_Shortcut_DownAlerts": "Down Alerts",
|
||||
"DevDetail_Shortcut_Presence": "Presence",
|
||||
"DevDetail_Shortcut_Sessions": "Sessions",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Details",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Events",
|
||||
"DevDetail_Tab_Details": "Details",
|
||||
"DevDetail_Tab_Events": "Events",
|
||||
"DevDetail_Tab_EventsTableDate": "Date",
|
||||
"DevDetail_Tab_EventsTableEvent": "Event type",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
@@ -151,10 +154,10 @@
|
||||
"DevDetail_Tab_NmapTableState": "State",
|
||||
"DevDetail_Tab_NmapTableText": "Set up a schedule in <a href=\"/settings.php#NMAP_ACTIVE\">Settings</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "Time",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Presence",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sessions",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Tools",
|
||||
"DevDetail_Tab_Plugins": "Plugins",
|
||||
"DevDetail_Tab_Presence": "Presence",
|
||||
"DevDetail_Tab_Sessions": "Sessions",
|
||||
"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_Error": "An error has occurred",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Start Internet Info",
|
||||
@@ -182,6 +185,7 @@
|
||||
"DevDetail_button_Delete": "Delete Device",
|
||||
"DevDetail_button_DeleteEvents": "Delete Events",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Are you sure you want to delete all Events of this device?<br><br>(this will clear the <b>Events history</b> and the <b>Sessions</b> and might help with constant (persistent) notifications)",
|
||||
"DevDetail_button_Delete_ask": "Are you sure you want to delete this device? You may also archive it instead.",
|
||||
"DevDetail_button_OverwriteIcons": "Overwrite Icons",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Overwrite icons of all devices with the same device type",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Are you sure you want to overwrite all icons of all devices with the same device type as the current device type?",
|
||||
@@ -205,6 +209,7 @@
|
||||
"Device_Shortcut_OnlineChart": "Device presence",
|
||||
"Device_TableHead_AlertDown": "Alert Down",
|
||||
"Device_TableHead_Connected_Devices": "Connections",
|
||||
"Device_TableHead_CustomProps": "Props / Actions",
|
||||
"Device_TableHead_Favorite": "Favorite",
|
||||
"Device_TableHead_FirstSession": "First Session",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
@@ -237,12 +242,15 @@
|
||||
"Device_Tablelenght": "Show _MENU_ entries",
|
||||
"Device_Tablelenght_all": "All",
|
||||
"Device_Title": "Devices",
|
||||
"Devices_Filters": "Filters",
|
||||
"Donations_Others": "Others",
|
||||
"Donations_Platforms": "Sponsor platforms",
|
||||
"Donations_Text": "Hey 👋! </br> Thanks for clicking on this menu item 😅 </br> </br> I'm trying to collect some donations to make you better software. Also, it would help me not to get burned out, so I can support this app longer. Any small (recurring or not) sponsorship makes me want to put more effort into this app. </br> I'd love to shorten my work week and in the remaining time fully focus on NetAlertX. You'd get more functionality, a more polished app and less bugs. </br> </br> Thanks for reading - I'm grateful for any support ❤🙏 </br> </br> TL;DR: By supporting me you get: </br> </br> <ul><li>Regular updates to keep your data and family safe 🔄</li><li>Less bugs 🐛🔫</li><li>Better and more functionality➕</li><li>I don't get burned out 🔥🤯</li><li>Less rushed releases 💨</li><li>Better docs📚</li><li>Quicker and better support with issues 🆘</li></ul> </br> 📧Email me to <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> if you want to get in touch or if I should add other sponsorship platforms. </br>",
|
||||
"Donations_Title": "Donations",
|
||||
"ENABLE_PLUGINS_description": "Enables the <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a> functionality. Loading plugins requires more hardware resources so you might want to disable them on low-powered system.",
|
||||
"ENABLE_PLUGINS_name": "Enable Plugins",
|
||||
"ENCRYPTION_KEY_description": "Data encryption key.",
|
||||
"ENCRYPTION_KEY_name": "Encryption key",
|
||||
"Email_display_name": "Email",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Loading...",
|
||||
@@ -278,7 +286,7 @@
|
||||
"Events_Tablelenght": "Show _MENU_ entries",
|
||||
"Events_Tablelenght_all": "All",
|
||||
"Events_Title": "Events",
|
||||
"GRAPHQL_PORT_description": "The port number of the GraphQL server.",
|
||||
"GRAPHQL_PORT_description": "The port number of the GraphQL server. Make sure the port is unique across all your applications on this host and NetAlertX instances.",
|
||||
"GRAPHQL_PORT_name": "GraphQL port",
|
||||
"Gen_Action": "Action",
|
||||
"Gen_Add": "Add",
|
||||
@@ -305,6 +313,7 @@
|
||||
"Gen_ReadDocs": "Read more in the docs.",
|
||||
"Gen_Remove_All": "Remove all",
|
||||
"Gen_Remove_Last": "Remove last",
|
||||
"Gen_Reset": "Reset",
|
||||
"Gen_Restore": "Run Restore",
|
||||
"Gen_Run": "Run",
|
||||
"Gen_Save": "Save",
|
||||
@@ -319,6 +328,7 @@
|
||||
"Gen_Upd_Fail": "Update failed",
|
||||
"Gen_Update": "Update",
|
||||
"Gen_Update_Value": "Update Value",
|
||||
"Gen_ValidIcon": "<i class=\"fa-solid fa-chevron-right \"></i>",
|
||||
"Gen_Warning": "Warning",
|
||||
"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",
|
||||
@@ -390,17 +400,23 @@
|
||||
"Maintenance_Running_Version": "Installed version",
|
||||
"Maintenance_Status": "Status",
|
||||
"Maintenance_Title": "Maintenance tools",
|
||||
"Maintenance_Tool_ExportCSV": "CSV Export",
|
||||
"Maintenance_Tool_ExportCSV_noti": "CSV Export",
|
||||
"Maintenance_Tool_DownloadConfig": "Settings Export",
|
||||
"Maintenance_Tool_DownloadConfig_text": "Download a full backup of your Settings configuration stored in the <code>app.conf</code> file.",
|
||||
"Maintenance_Tool_ExportCSV": "Devices Export (csv)",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Devices Export (csv)",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Are you sure you want to generate a CSV file?",
|
||||
"Maintenance_Tool_ExportCSV_text": "Generate a CSV (comma separated value) file containing the list of Devices including the Network relationships between Network Nodes and connected devices. You can also trigger this by accessing this URL <code>your NetAlertX url/php/server/devices.php?action=ExportCSV</code> or by enabling the <a href=\"settings.php#CSVBCKP_header\">CSV Backup</a> plugin.",
|
||||
"Maintenance_Tool_ImportCSV": "CSV Import",
|
||||
"Maintenance_Tool_ImportCSV_noti": "CSV Import",
|
||||
"Maintenance_Tool_ExportCSV_text": "Generate a CSV (comma separated value) file containing the list of Devices including the Network relationships between Network Nodes and connected devices. You can also trigger this by accessing this URL <code>your_NetAlertX_url/php/server/devices.php?action=ExportCSV</code> or by enabling the <a href=\"settings.php#CSVBCKP_header\">CSV Backup</a> plugin.",
|
||||
"Maintenance_Tool_ImportCSV": "Devices Import (csv)",
|
||||
"Maintenance_Tool_ImportCSV_noti": "Devices Import (csv)",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Are you sure you want to import the CSV file? This will completely <b>overwrite</b> the devices in your database.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Before using this function, please make a backup. Import a CSV (comma separated value) file containing the list of Devices including the Network relationships between Network Nodes and connected devices. To do that place the CSV file named <b>devices.csv</b> into your <b>/config</b> folder.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "CSV Import (Paste)",
|
||||
"Maintenance_Tool_ImportConfig_noti": "Settings Import (app.conf)",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Devices Import (csv) (paste)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "Are you sure you want to import the pasted CSV? This will completely <b>overwrite</b> the devices in your database.",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "Before using this function, please make a backup. Import a CSV (comma separated value) file containing the list of Devices including the Network relationships between Network Nodes and connected devices.",
|
||||
"Maintenance_Tool_ImportPastedConfig": "Settings Import (paste)",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "Are you sure you want to import the pasted config settings? This will completely <b>overwrite</b> the <code>app.conf</code> file.",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "Imports the <code>app.conf</code> file containing all the application Settings. You might want to download the current <code>app.conf</code> file first with the <b>Settings Export</b>.",
|
||||
"Maintenance_Tool_arpscansw": "Toggle arp-Scan (on/off)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Toggle arp-Scan on or off",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "When the scan has been switched off it remains off until it is activated again.",
|
||||
@@ -475,13 +491,13 @@
|
||||
"Maintenance_lang_selector_empty": "Choose Language",
|
||||
"Maintenance_lang_selector_lable": "Select Language",
|
||||
"Maintenance_lang_selector_text": "The change takes place on the client side, so it affects only the current browser.",
|
||||
"Maintenance_new_version": "🆕 A new version is available. Check out the <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">release notes</a>.",
|
||||
"Maintenance_new_version": "A new version is available. Check out the <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">release notes</a>.",
|
||||
"Maintenance_themeselector_apply": "Apply",
|
||||
"Maintenance_themeselector_empty": "Choose a Skin",
|
||||
"Maintenance_themeselector_lable": "Select Skin",
|
||||
"Maintenance_themeselector_text": "The change takes place on the server side, so it affects all devices in use.",
|
||||
"Maintenance_version": "App updates",
|
||||
"NETWORK_DEVICE_TYPES_description": "Which device types are allowed to be used as network devices in the Network view. The device type has to match exactly the <code>Type</code> setting on a specific device in Device details. Do not remove existing types, only add new ones.",
|
||||
"NETWORK_DEVICE_TYPES_description": "Which device types are allowed to be used as network devices in the Network view. The device type has to match exactly the <code>Type</code> setting on a specific device in Device details. Add it on the Device via the <code>+</code> button. Do not remove existing types, only add new ones.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Network device types",
|
||||
"Navigation_About": "About",
|
||||
"Navigation_Devices": "Devices",
|
||||
@@ -702,6 +718,7 @@
|
||||
"general_event_title": "Executing an ad-hoc event",
|
||||
"go_to_node_event_icon": "fa-square-up-right",
|
||||
"go_to_node_event_tooltip": "Navigate to the Network page of the given node",
|
||||
"new_version_available": "A new version is available.",
|
||||
"report_guid": "Notification guid:",
|
||||
"report_guid_missing": "Linked notification not found. There is a small delay between recently sent notifications and them being available. Referesh your page and cache after a few seconds. It's also possible the selected notification have been deleted during maintenance as specified in the <code>DBCLNP_NOTIFI_HIST</code> setting. <br/> <br/>The latest notification is displayed instead. The missing notification has the following GUID:",
|
||||
"report_select_format": "Select Format:",
|
||||
|
||||
@@ -70,12 +70,15 @@
|
||||
"BackDevices_darkmode_enabled": "Darkmode Activado",
|
||||
"CLEAR_NEW_FLAG_description": "Si está habilitado (<code>0</code> está desactivado), los dispositivos marcados como <b>Nuevo dispositivo</b> se desmarcarán si el límite de tiempo (especificado en horas) excede su tiempo de <b>primera sesión</b>.",
|
||||
"CLEAR_NEW_FLAG_name": "Eliminar la nueva bandera",
|
||||
"CustProps_cant_remove": "",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "Esta es una configuración de mantenimiento. Esto especifica el número de días de entradas de eventos que se guardarán. Todos los eventos anteriores se eliminarán periódicamente.",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Eliminar eventos anteriores a",
|
||||
"DISCOVER_PLUGINS_description": "",
|
||||
"DISCOVER_PLUGINS_name": "",
|
||||
"DISCOVER_PLUGINS_description": "Desactive esta opción para acelerar la inicialización y el ahorro de ajustes. Cuando está desactivado, los plugins no se descubren y no puede añadir nuevos plugins a la configuración <code>LOADED_PLUGINS</code>.",
|
||||
"DISCOVER_PLUGINS_name": "Descubrir plugins",
|
||||
"DevDetail_Copy_Device_Title": "Copiar detalles del dispositivo",
|
||||
"DevDetail_Copy_Device_Tooltip": "Copiar detalles del dispositivo de la lista desplegable. Todo en esta página se sobrescribirá",
|
||||
"DevDetail_CustomProperties_Title": "",
|
||||
"DevDetail_CustomProps_reset_info": "",
|
||||
"DevDetail_DisplayFields_Title": "Mostrar",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Notificaciones de eventos",
|
||||
"DevDetail_EveandAl_AlertDown": "Alerta de caída",
|
||||
@@ -145,8 +148,8 @@
|
||||
"DevDetail_Shortcut_DownAlerts": "Alerta(s) de caída(s)",
|
||||
"DevDetail_Shortcut_Presence": "Historial",
|
||||
"DevDetail_Shortcut_Sessions": "Sesiones",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Detalles",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Eventos",
|
||||
"DevDetail_Tab_Details": "Detalles",
|
||||
"DevDetail_Tab_Events": "Eventos",
|
||||
"DevDetail_Tab_EventsTableDate": "Fecha",
|
||||
"DevDetail_Tab_EventsTableEvent": "Tipo de evento",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
@@ -161,10 +164,10 @@
|
||||
"DevDetail_Tab_NmapTableState": "Estado",
|
||||
"DevDetail_Tab_NmapTableText": "Establece la programación en los <a href=\"/settings.php#NMAP_ACTIVE\">Ajustes</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "Tiempo",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Historial",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sesiones",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Herramientas",
|
||||
"DevDetail_Tab_Plugins": "Plugins",
|
||||
"DevDetail_Tab_Presence": "Historial",
|
||||
"DevDetail_Tab_Sessions": "Sesiones",
|
||||
"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_Error": "Se ha producido un error",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Iniciar información de Internet",
|
||||
@@ -192,6 +195,7 @@
|
||||
"DevDetail_button_Delete": "Eliminar dispositivo",
|
||||
"DevDetail_button_DeleteEvents": "Eliminar eventos",
|
||||
"DevDetail_button_DeleteEvents_Warning": "¿Desea eliminar todos los eventos de este dispositivo?<br><br>(se eliminarán el <b>Historial de eventos</b> y las <b>Sesiones</b>, y puede ayudar en el caso de notificaciones constantes)",
|
||||
"DevDetail_button_Delete_ask": "",
|
||||
"DevDetail_button_OverwriteIcons": "Sobreescribir iconos",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Sobreescribir los iconos de todos los dispositivos con el mismo tipo",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "¿Sobreescribir todos los iconos de todos los dispositivos con el mismo tipo que el dispositivo actual?",
|
||||
@@ -215,6 +219,7 @@
|
||||
"Device_Shortcut_OnlineChart": "Presencia del dispositivo a lo largo del tiempo",
|
||||
"Device_TableHead_AlertDown": "Alerta desactivada",
|
||||
"Device_TableHead_Connected_Devices": "Conexiones",
|
||||
"Device_TableHead_CustomProps": "",
|
||||
"Device_TableHead_Favorite": "Favorito",
|
||||
"Device_TableHead_FirstSession": "1ra. sesión",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
@@ -247,12 +252,15 @@
|
||||
"Device_Tablelenght": "Mostrar _MENU_ entradas",
|
||||
"Device_Tablelenght_all": "Todos",
|
||||
"Device_Title": "Dispositivos",
|
||||
"Devices_Filters": "",
|
||||
"Donations_Others": "Otros",
|
||||
"Donations_Platforms": "Plataforma de patrocinadores",
|
||||
"Donations_Text": "¡Hola! 👋 </br> Gracias por hacer clic en este elemento 😅 del menú </br> </br>, estoy tratando de recolectar algunas donaciones para mejorar el software. Además, me ayudaría a no quemarse, por lo que puedo apoyar esta aplicación por más tiempo. Cualquier pequeño patrocinio (recurrente o no) me hace querer esforzarme más en esta aplicación. </br> Me encantaría acortar mi semana de trabajo y en el tiempo que me queda centrarme por completo en NetAlertX. Obtendrías más funcionalidad, una aplicación más pulida y menos errores. </br> </br> Gracias por leer, agradezco cualquier apoyo ❤🙏 </br> </br> TL; DR: Al apoyarme, obtienes: </br> </br> <ul><li>Actualizaciones periódicas para mantener tus datos y tu familia seguros 🔄</li><li>Menos errores 🐛🔫</li><li>Mejor y más funcionalidad➕</li><li>No me quemo 🔥🤯</li><li>Lanzamientos 💨menos apresurados</li> <li>Mejores documentos📚</li><li>Soporte más rápido y mejor con problemas 🆘</li></ul> </br> 📧Envíame un correo electrónico a <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> si quieres ponerte en contacto o si debo añadir otras plataformas de patrocinio. </br>",
|
||||
"Donations_Title": "Donaciones",
|
||||
"ENABLE_PLUGINS_description": "Habilita la funcionalidad de los <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">complementos</a>. Cargar los complementos requiere más recursos de hardware, así que quizás quieras desactivarlo en hardware poco potente.",
|
||||
"ENABLE_PLUGINS_name": "Habilitar complementos",
|
||||
"ENCRYPTION_KEY_description": "",
|
||||
"ENCRYPTION_KEY_name": "",
|
||||
"Email_display_name": "Email",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Cargando...",
|
||||
@@ -315,6 +323,7 @@
|
||||
"Gen_ReadDocs": "Lee más en los documentos.",
|
||||
"Gen_Remove_All": "Quitar todo",
|
||||
"Gen_Remove_Last": "Quitar el último",
|
||||
"Gen_Reset": "",
|
||||
"Gen_Restore": "Ejecutar restauración",
|
||||
"Gen_Run": "Ejecutar",
|
||||
"Gen_Save": "Guardar",
|
||||
@@ -329,10 +338,11 @@
|
||||
"Gen_Upd_Fail": "Fallo al actualizar",
|
||||
"Gen_Update": "Actualizar",
|
||||
"Gen_Update_Value": "Actualizar valor",
|
||||
"Gen_ValidIcon": "",
|
||||
"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_create_new_device": "Crear un dispositivo ficticio",
|
||||
"Gen_create_new_device_info": "",
|
||||
"Gen_create_new_device": "Nuevo dispositivo",
|
||||
"Gen_create_new_device_info": "Los dispositivos se suelen descubrir utilizando <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a>. Sin embargo, en algunos casos, es posible que necesite agregar dispositivos manualmente. Para explorar escenarios específicos, consulte la documentación <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/REMOTE_NETWORKS.md\">Redes remotas</a>.",
|
||||
"General_display_name": "General",
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "Se trata de una configuración de mantenimiento <b>BORRAR dispositivos</b>. Si está activado (<code>0</code> está desactivado), los dispositivos marcados como <b>Nuevo dispositivo</b> se eliminarán si su fecha de <b>primera sesión</b> es anterior a las horas especificadas en este ajuste. Use este ajuste si desea eliminar automáticamente <b>Nuevos dispositivos</b> después de <code>X</code> horas.",
|
||||
@@ -414,6 +424,8 @@
|
||||
"Maintenance_Running_Version": "Versión instalada",
|
||||
"Maintenance_Status": "Situación",
|
||||
"Maintenance_Title": "Herramientas de mantenimiento",
|
||||
"Maintenance_Tool_DownloadConfig": "",
|
||||
"Maintenance_Tool_DownloadConfig_text": "",
|
||||
"Maintenance_Tool_ExportCSV": "Exportación CSV",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Exportación CSV",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "¿Está seguro de que quiere generar un archivo CSV?",
|
||||
@@ -422,9 +434,13 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "Importación CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "¿Estás seguro de que quieres importar el archivo CSV? Esto <b>sobrescribirá</b> completamente los dispositivos en su base de datos.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Antes de usar esta función, haga una copia de seguridad. Importe un archivo CSV (valor separado por comas) que contiene la lista de dispositivos, incluidas las relaciones de red entre nodos de red y dispositivos conectados. Para hacer eso, coloque el archivo CSV llamado <b> devices.csv </b> en su carpeta <b>/config </b>.",
|
||||
"Maintenance_Tool_ImportConfig_noti": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Importar CSV (Pegar)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "¿Seguro que desea importar el CSV pegado? Esto <b>sobrescribirá</b> completamente los dispositivos en su base de datos.",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "Antes de usar esta función, por favor haga una copia de seguridad. Importar un archivo CSV (valor separado por comas) que contiene la lista de Dispositivos incluyendo las relaciones de red entre los Nodos de red y los dispositivos conectados.",
|
||||
"Maintenance_Tool_ImportPastedConfig": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "",
|
||||
"Maintenance_Tool_arpscansw": "Activar arp-scan (on/off)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Activar arp-scan on or off",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Cuando el escaneo se ha apagado, permanece apagado hasta que se active nuevamente.",
|
||||
@@ -499,7 +515,7 @@
|
||||
"Maintenance_lang_selector_empty": "Elija un idioma",
|
||||
"Maintenance_lang_selector_lable": "Seleccione su idioma",
|
||||
"Maintenance_lang_selector_text": "El cambio se produce en el lado del cliente, por lo que sólo afecta al navegador actual.",
|
||||
"Maintenance_new_version": "🆕 Una nueva versión está disponible. Comprueba las <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">notas de lanzamiento</a>.",
|
||||
"Maintenance_new_version": "Una nueva versión está disponible. Comprueba las <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">notas de lanzamiento</a>.",
|
||||
"Maintenance_themeselector_apply": "Aplicar",
|
||||
"Maintenance_themeselector_empty": "Elige un tema",
|
||||
"Maintenance_themeselector_lable": "Seleccionar tema",
|
||||
@@ -781,6 +797,7 @@
|
||||
"general_event_title": "Ejecutar un evento ad-hoc",
|
||||
"go_to_node_event_icon": "fa-square-up-right",
|
||||
"go_to_node_event_tooltip": "Vaya a la página de Red del nodo indicado",
|
||||
"new_version_available": "",
|
||||
"report_guid": "Guía de las notificaciones:",
|
||||
"report_guid_missing": "No se ha encontrado la notificación vinculada. Hay un pequeño retraso entre las notificaciones enviadas recientemente y su disponibilidad. Actualiza tu página y la caché después de unos segundos. También es posible que la notificación seleccionada se haya eliminado durante el mantenimiento, tal y como se especifica en la configuración <code>de DBCLNP_NOTIFI_HIST</code>. <br/> <br/>En su lugar, se muestra la notificación más reciente. La notificación que falta tiene el siguiente GUID:",
|
||||
"report_select_format": "Selecciona el formato:",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Vous pouvez spécifier votre propre requête SQL qui retournera un fichier JSON et l'exposer via <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> le point de terminaison de fichier</a>.",
|
||||
"API_CUSTOM_SQL_name": "Point de terminaison personnalisé",
|
||||
"API_TOKEN_description": "Vous pouvez renseigner ou générer un jeton API pour sécuriser les échanges. Il est transmis dans le header de la requête. C'est utilisé dans le plugin <code>SYNC</code> du serveur GraphQL.",
|
||||
"API_TOKEN_description": "Vous pouvez renseigner ou générer un jeton API pour sécuriser les échanges. Il est transmis dans le header de la requête, et utilisé dans le plugin <code>SYNC</code>, le serveur GraphQL et d'autres usages API. Vous pouvez utiliser les points de terminaison API pour créer des intégrations spécifiques, comme décrit dans la <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md\" target=\"_blank\">documentation de l'API</a>.",
|
||||
"API_TOKEN_name": "Jeton d'API",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
@@ -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_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_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_Upgrade": "Base de données mise à niveau avec succès",
|
||||
"BackDevices_DBTools_UpgradeError": "La mise à niveau de la base de données a échoué",
|
||||
@@ -60,12 +60,15 @@
|
||||
"BackDevices_darkmode_enabled": "Mode sombre activé",
|
||||
"CLEAR_NEW_FLAG_description": "Si activé (<code>0</code> est désactivé), les appareils marqués comme <b>Nouvel appareil</b> seront démarqués si la limite de temps (spécifiée en heures) dépasse la durée de <b>Première Session</b>.",
|
||||
"CLEAR_NEW_FLAG_name": "Supprime le nouveau drapeau",
|
||||
"CustProps_cant_remove": "Suppression impossible, au moins une donnée est requise.",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "Il s'agit d'un paramètre de maintenance. Il indique le nombre de jours pendant lesquels les entrées d'événements seront conservées. Tous les événements plus anciens seront supprimés périodiquement. S'applique également à l'historique des événements du plugin.",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Supprimer les événements plus anciens que",
|
||||
"DISCOVER_PLUGINS_description": "",
|
||||
"DISCOVER_PLUGINS_name": "",
|
||||
"DISCOVER_PLUGINS_description": "Désactivez cette option pour accélérer le démarrage et l'enregistrement de paramètres. Quand elle est désactivée, les plugins ne sont pas découverts, et vous ne pouvez près ajouter de nouveaux plugins au paramètre <code>LOADED_PLUGINS</code>.",
|
||||
"DISCOVER_PLUGINS_name": "Découvrir des plugins",
|
||||
"DevDetail_Copy_Device_Title": "Copier les détails de l'appareil",
|
||||
"DevDetail_Copy_Device_Tooltip": "Copier les détails de l'appareil dans la liste déroulante. Tout ce qui se trouve sur cette page sera remplacé",
|
||||
"DevDetail_CustomProperties_Title": "Champs personnalisés",
|
||||
"DevDetail_CustomProps_reset_info": "Cela va supprimer vos champs personnalisés de cet appareil et les remettre à leur valeur par défaut.",
|
||||
"DevDetail_DisplayFields_Title": "Afficher",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Alerter les événements",
|
||||
"DevDetail_EveandAl_AlertDown": "Alerte de panne",
|
||||
@@ -135,8 +138,8 @@
|
||||
"DevDetail_Shortcut_DownAlerts": "Alertes de panne",
|
||||
"DevDetail_Shortcut_Presence": "Présence",
|
||||
"DevDetail_Shortcut_Sessions": "Sessions",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Détails",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Événements",
|
||||
"DevDetail_Tab_Details": "Détails",
|
||||
"DevDetail_Tab_Events": "Événements",
|
||||
"DevDetail_Tab_EventsTableDate": "Date",
|
||||
"DevDetail_Tab_EventsTableEvent": "Type d'événement",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
@@ -151,10 +154,10 @@
|
||||
"DevDetail_Tab_NmapTableState": "État",
|
||||
"DevDetail_Tab_NmapTableText": "Configurer une programmation dans les <a href=\"/settings.php#NMAP_ACTIVE\">Paramètres</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "Heure",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Présence",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sessions",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Outils",
|
||||
"DevDetail_Tab_Plugins": "Plugins",
|
||||
"DevDetail_Tab_Presence": "Présence",
|
||||
"DevDetail_Tab_Sessions": "Sessions",
|
||||
"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_Error": "Une erreur est survenue",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Lancer les informations Internet",
|
||||
@@ -182,6 +185,7 @@
|
||||
"DevDetail_button_Delete": "Supprimer l'appareil",
|
||||
"DevDetail_button_DeleteEvents": "Supprimer les événements",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Êtes-vous sûr de vouloir supprimer tous les Événements de cet appareil ?<br><br>(cela supprimera l'<b>Historique des événements</b> et les <b>Sessions</b> et peur aider pour les notifications persistantes)",
|
||||
"DevDetail_button_Delete_ask": "Êtes-vous sûr de vouloir supprimer cet appareil ? Vous pouvez vouloir l'archiver plutôt.",
|
||||
"DevDetail_button_OverwriteIcons": "Remplacer les icônes",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Remplacer les icônes de tous les appareils de ce type",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Êtes-vous sûr de vouloir remplacer toutes les icônes de tous les appareils du même type que l'appareil actuel ?",
|
||||
@@ -205,6 +209,7 @@
|
||||
"Device_Shortcut_OnlineChart": "Présence de l'appareil",
|
||||
"Device_TableHead_AlertDown": "Alerter si En panne",
|
||||
"Device_TableHead_Connected_Devices": "Connexions",
|
||||
"Device_TableHead_CustomProps": "Champs / Actions",
|
||||
"Device_TableHead_Favorite": "Favori",
|
||||
"Device_TableHead_FirstSession": "Première session",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
@@ -237,12 +242,15 @@
|
||||
"Device_Tablelenght": "Afficher les entrées _MENU_",
|
||||
"Device_Tablelenght_all": "Tous",
|
||||
"Device_Title": "Appareils",
|
||||
"Devices_Filters": "Filtres",
|
||||
"Donations_Others": "Autres",
|
||||
"Donations_Platforms": "Plateformes de sponsoring",
|
||||
"Donations_Text": "Coucou 👋 ! </br> Merci d'avoir cliqué ici 😅 </br> </br> J'essaie de récolter des donations pour vous faire un meilleur produit. En plus, ça m'aide à éviter le burn-out pour développer cette application plus longtemps. Toute subvention (régulière ou non) me donne envie de poursuivre le développement de cette application.</br> J'aimerais réduire mon activité principale pour me concentrer plus longuement à NetAlertX. Vous auriez plus de fonctionnalités, une application mieux finie et avec moins de bugs.</br> </br> Merci de votre lecture - je vous suis reconnaissant pour votre soutien ❤🙏 </br> </br> Version courte : en me soutenant, vous aurez : </br> </br> <ul><li>Des mises à jour régulières pour protéger vos données personnelles et familiales 🔄</li><li>Moins de bugs 🐛🔫</li><li>Des fonctionnalités plus riches et plus nombreuses ➕</li><li>Je ne me retrouve pas en burn-out 🔥🤯</li><li>Des versions moins à la va-vite 💨</li><li>une meilleure documentation <20></li><li>Un support meilleur et plus réactif en cas de problème 🆘</li></ul> </br> 📧Envoyez-moi un courriel à <a href='mailto :jokob@duck.com ?subject=NetAlertX'>jokob@duck.com</a> si vous voulez me contacter ou du je peux ajouter une autre plateforme de soutien. </br>",
|
||||
"Donations_Title": "Dons",
|
||||
"ENABLE_PLUGINS_description": "Active les fonctionnalités des <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">Plugins</a>. Charger des plugins nécessite plus de ressources, il est recommandé de les désactiver sur des systèmes de faible puissance.",
|
||||
"ENABLE_PLUGINS_name": "Activer les Plugins",
|
||||
"ENCRYPTION_KEY_description": "Clé de chiffrement des données.",
|
||||
"ENCRYPTION_KEY_name": "Clé de chiffrement",
|
||||
"Email_display_name": "Messagerie",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Chargement …",
|
||||
@@ -278,7 +286,7 @@
|
||||
"Events_Tablelenght": "Afficher _MENU_ entrées",
|
||||
"Events_Tablelenght_all": "Tous",
|
||||
"Events_Title": "Évènements",
|
||||
"GRAPHQL_PORT_description": "Le numéro de port du serveur GraphQL.",
|
||||
"GRAPHQL_PORT_description": "Le numéro de port du serveur GraphQL. Assurez vous sue le port est unique a l'échelle de toutes les applications sur cet hôte et vos instances NetAlertX.",
|
||||
"GRAPHQL_PORT_name": "Port GraphQL",
|
||||
"Gen_Action": "Action",
|
||||
"Gen_Add": "Ajouter",
|
||||
@@ -305,6 +313,7 @@
|
||||
"Gen_ReadDocs": "Plus d'infos dans la documentation.",
|
||||
"Gen_Remove_All": "Enlever tous",
|
||||
"Gen_Remove_Last": "Enlever le dernier",
|
||||
"Gen_Reset": "Réinitialiser",
|
||||
"Gen_Restore": "Lancer une restauration",
|
||||
"Gen_Run": "Lancer",
|
||||
"Gen_Save": "Enregistrer",
|
||||
@@ -319,10 +328,11 @@
|
||||
"Gen_Upd_Fail": "Échec de la mise à jour",
|
||||
"Gen_Update": "Mise à jour",
|
||||
"Gen_Update_Value": "Valeur à mettre à jour",
|
||||
"Gen_ValidIcon": "",
|
||||
"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_create_new_device": "Créer un appareil fictif",
|
||||
"Gen_create_new_device_info": "",
|
||||
"Gen_create_new_device": "Nouvel appareil",
|
||||
"Gen_create_new_device_info": "Les appareils sont souvent découverts à l'aide d'un <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugin</a>. Cependant, dans certains cas, vous pouvez ajouter manuellement les appareils. Pour explorer des scénarios spécifiques, consulter la <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/REMOTE_NETWORKS.md\">documentation des réseaux distants</a>.",
|
||||
"General_display_name": "Général",
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "Paramètre de maintenance. S'il est activé (<code>0</code> s'il est désactivé), les appareils marqués comme <b>Nouvel appareil</b> seront supprimés si leur durée depuis la <b>première session</b> est plus ancienne que le nombre d'heures paramétré. Utilisez ce paramétrage si vous voulez supprimer automatiquement les <b>Nouveaux appareils</b> après <code>X</code> heures.",
|
||||
@@ -390,17 +400,23 @@
|
||||
"Maintenance_Running_Version": "Version installée",
|
||||
"Maintenance_Status": "État",
|
||||
"Maintenance_Title": "Outils de maintenance",
|
||||
"Maintenance_Tool_ExportCSV": "Export en CSV",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Export en CSV",
|
||||
"Maintenance_Tool_DownloadConfig": "Export des paramètres",
|
||||
"Maintenance_Tool_DownloadConfig_text": "Télécharger une sauvegarde complète de vos paramètres stockés dans le fichier <code>app.conf</code>.",
|
||||
"Maintenance_Tool_ExportCSV": "Export des appareils (csv)",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Export des appareils (csv)",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Êtes-vous sûr de vouloir générer un fichier CSV ?",
|
||||
"Maintenance_Tool_ExportCSV_text": "Génère un fichier CSV (valeurs séparées par des virgules), contenant la liste des appareils, dont les liens entre nœuds Réseaux et les appareils connectés. Vous pouvez aussi lancer cet export depuis l'URL <code>votre URL de NetAlertX/php/server/devices.php?action=ExportCSV</code> ou en activant le plugin <a href=\"settings.php#CSVBCKP_header\">CSV Backup</a>.",
|
||||
"Maintenance_Tool_ImportCSV": "Import CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti": "Import CSV",
|
||||
"Maintenance_Tool_ExportCSV_text": "Génère un fichier CSV (valeurs séparées par des virgules), contenant la liste des appareils, dont les liens entre nœuds Réseaux et les appareils connectés. Vous pouvez aussi lancer cet export depuis l'URL <code>votre_URL_de_NetAlertX/php/server/devices.php?action=ExportCSV</code> ou en activant le plugin <a href=\"settings.php#CSVBCKP_header\">CSV Backup</a>.",
|
||||
"Maintenance_Tool_ImportCSV": "Import des appareils (csv)",
|
||||
"Maintenance_Tool_ImportCSV_noti": "Import des appareils (csv)",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Êtes-vous sûr de vouloir importer le fichier CSV ? Cela <b>écrasera</b> complètement les appareils de votre base de données.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Avant d'utiliser cette fonctionnalité, il est recommandé de faire une sauvegarde. La fonctionnalité importe un fichier CSV (valeurs séparées par des virgules) contenant la liste des appareils, dont les liens réseau entre les nœuds du réseau et ces appareils. Pour cela, placer un fichier CSV nommé <b>devices.csv</b> dans votre répertoire <b>/config</b>.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Import CSV (coller)",
|
||||
"Maintenance_Tool_ImportConfig_noti": "Import des appareils (app.conf)",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Import des appareils (csv) (coller)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "Êtes-vous sûr de vouloir importer les CSV copié ? Cela va complètement <b>remplacer</b> les appareils de votre base de données.",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "Avant d'utiliser cette fonctionnalité, il est recommandé de faire une sauvegarde. Importe un fichier CSV (valeurs séparées par des virgules) contenant la liste des appareils, dont les liens réseaux entre les nœuds du réseau et les appareils connectés.",
|
||||
"Maintenance_Tool_ImportPastedConfig": "Import des paramètres (coller)",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "Êtes-vous sûr de vouloir importer les paramètres de configuration copiés ? Cela va complètement <b>remplacer</b> le fichier <code>app.conf</code>.",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "Importe le fichier <code>app.conf</code>, qui contient tous les paramètres de l'application. Vous devriez commencer par télécharger le fichier actuel<code>app.conf</code> avec la fonctionnalité <b>Export des paramètres</b>.",
|
||||
"Maintenance_Tool_arpscansw": "Basculer l'arp-Scan (activé/désactivé)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Activer ou désactiver l'arp-Scan",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Une fois le scan désactivé, il reste désactivé jusqu'à ce qu'il soit réactivé.",
|
||||
@@ -475,13 +491,13 @@
|
||||
"Maintenance_lang_selector_empty": "Choix de la langue",
|
||||
"Maintenance_lang_selector_lable": "Sélectionner une langue",
|
||||
"Maintenance_lang_selector_text": "Le changement est effectué côté client, cela ne concerne donc que le navigateur actuel.",
|
||||
"Maintenance_new_version": "🆕 Une nouvelle version est disponible. Consulter les <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">notes de version</a>.",
|
||||
"Maintenance_new_version": "Une nouvelle version est disponible. Consulter les <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">notes de version</a>.",
|
||||
"Maintenance_themeselector_apply": "Appliquer",
|
||||
"Maintenance_themeselector_empty": "Choisir un thème",
|
||||
"Maintenance_themeselector_lable": "Sélectionner un thème",
|
||||
"Maintenance_themeselector_text": "Le changement s'effectue côté serveur, il s'applique donc à tous les appareils connectés à l'interface graphique.",
|
||||
"Maintenance_version": "Mises à jour de l'application",
|
||||
"NETWORK_DEVICE_TYPES_description": "Les types d'appareils autorisés à verre utilisés comme appareils réseau dans la vue Réseau. Le type d'appareils doit être identique au paramètre <code>Type</code> d'un appareil dans le détail des appareils. Ne pas supprimer de valeurs, seulement en ajouter de nouvelles.",
|
||||
"NETWORK_DEVICE_TYPES_description": "Les types d'appareils autorisés à être utilisés comme appareils réseau dans la vue Réseau. Le type d'appareils doit être identique au paramètre <code>Type</code> d'un appareil dans le détail des appareils. Ajouter le sur l'appareil grâce au bouton <code>+</code>. Ne pas supprimer de valeurs, seulement en ajouter de nouvelles.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Type d'appareil réseau",
|
||||
"Navigation_About": "À propos",
|
||||
"Navigation_Devices": "Appareils",
|
||||
@@ -702,6 +718,7 @@
|
||||
"general_event_title": "Lancement d'un événement sur mesure",
|
||||
"go_to_node_event_icon": "fa-square-up-right",
|
||||
"go_to_node_event_tooltip": "Aller vers la page Réseau du nœud concerné",
|
||||
"new_version_available": "Une nouvelle version est disponible.",
|
||||
"report_guid": "GUID de la notification :",
|
||||
"report_guid_missing": "La notification associée n'a pas été trouvée. Un petit délai existe entre l'envoi d'une notification et sa disponibilité réelle pour affichage. Rafraichissez la page et votre cache après quelques secondes. Il est aussi possible que la notification sélectionnée ait été supprimée durant une opération de maintenance, comme renseigné dans le paramètre <code>DBCLNP_NOTIFI_HIST</code>. <br/> <br/> La dernière notification est affichée à sa place. La notification manquante dispose du GUID suivant :",
|
||||
"report_select_format": "Sélectionner un format :",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Puoi specificare una query SQL personalizzata che genererà un file JSON e quindi lo esporrà tramite l'<a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code>endpoint del file</a>.",
|
||||
"API_CUSTOM_SQL_name": "Endpoint personalizzato",
|
||||
"API_TOKEN_description": "Token API per proteggere la comunicazione, puoi generarne uno o inserire qualsiasi valore. Viene inviato nell'intestazione della richiesta. Usato nel plugin <code>SYNC</code>, server GraphQL.",
|
||||
"API_TOKEN_description": "Token API per comunicazioni sicure. Generane uno o inserisci un valore qualsiasi. Viene inviato nell'intestazione della richiesta e utilizzato nel plugin <code>SYNC</code>, nel server GraphQL e in altri endpoint API. Puoi utilizzare gli endpoint API per creare integrazioni personalizzate come descritto nella <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md\" target=\"_blank\">documentazione API</a>.",
|
||||
"API_TOKEN_name": "Token API",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
@@ -48,7 +48,7 @@
|
||||
"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_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_Upgrade": "Database aggiornato correttamente",
|
||||
"BackDevices_DBTools_UpgradeError": "Aggiornamento del database non riuscito",
|
||||
@@ -60,12 +60,15 @@
|
||||
"BackDevices_darkmode_enabled": "Modalità scura abilitata",
|
||||
"CLEAR_NEW_FLAG_description": "Se abilitato (<code>0</code> è disabilitato), i dispositivi contrassegnati come <b>Nuovo dispositivo</b> verranno deselezionati se il limite di tempo (specificato in ore) supera il tempo della <b>Prima sessione</b>.",
|
||||
"CLEAR_NEW_FLAG_name": "Cancella nuova bandiera",
|
||||
"CustProps_cant_remove": "Impossibile rimuovere, è necessaria almeno una proprietà.",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "Questa è un'impostazione di manutenzione. Specifica il numero di giorni delle voci degli eventi che verranno conservati. Tutti gli eventi più vecchi verranno eliminati periodicamente. Si applica anche alla cronologia degli eventi del plugin (Plugin Events History).",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Elimina eventi più vecchi di",
|
||||
"DISCOVER_PLUGINS_description": "Disattiva questa opzione per velocizzare l'inizializzazione e il salvataggio delle impostazioni. Quando è disattivata, i plugin non vengono scoperti e non puoi aggiungere nuovi plugin all'impostazione <code>LOADED_PLUGINS</code>.",
|
||||
"DISCOVER_PLUGINS_name": "Scopri i plugin",
|
||||
"DevDetail_Copy_Device_Title": "Copia dettagli dal dispositivo",
|
||||
"DevDetail_Copy_Device_Tooltip": "Copia i dettagli dal dispositivo dall'elenco a discesa. Tutto in questa pagina verrà sovrascritto",
|
||||
"DevDetail_CustomProperties_Title": "Proprietà personalizzate",
|
||||
"DevDetail_CustomProps_reset_info": "Questa operazione rimuoverà le proprietà personalizzate su questo dispositivo e le ripristinerà al valore predefinito.",
|
||||
"DevDetail_DisplayFields_Title": "Visualizza",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Notifica eventi",
|
||||
"DevDetail_EveandAl_AlertDown": "Avviso disconnessione",
|
||||
@@ -135,8 +138,8 @@
|
||||
"DevDetail_Shortcut_DownAlerts": "Avvisi disconnessione",
|
||||
"DevDetail_Shortcut_Presence": "Presenza",
|
||||
"DevDetail_Shortcut_Sessions": "Sessioni",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Dettagli",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Eventi",
|
||||
"DevDetail_Tab_Details": "Dettagli",
|
||||
"DevDetail_Tab_Events": "Eventi",
|
||||
"DevDetail_Tab_EventsTableDate": "Data",
|
||||
"DevDetail_Tab_EventsTableEvent": "Tipo evento",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
@@ -151,10 +154,10 @@
|
||||
"DevDetail_Tab_NmapTableState": "Stato",
|
||||
"DevDetail_Tab_NmapTableText": "Imposta una pianificazione nelle <a href=\"/settings.php#NMAP_ACTIVE\">Impostazioni</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "Ora",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugin",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Presenza",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sessioni",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Strumenti",
|
||||
"DevDetail_Tab_Plugins": "Plugin",
|
||||
"DevDetail_Tab_Presence": "Presenza",
|
||||
"DevDetail_Tab_Sessions": "Sessioni",
|
||||
"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_Error": "Si è verificato un errore",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Avvia info Internet",
|
||||
@@ -182,6 +185,7 @@
|
||||
"DevDetail_button_Delete": "Elimina dispositivo",
|
||||
"DevDetail_button_DeleteEvents": "Elimina eventi",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Sei sicuro di voler eliminare tutti gli eventi di questo dispositivo?<br><br>(questa azione cancellerà la <b>Cronologia eventi</b> e le <b>Sessioni</b> e potrebbe aiutare con costanti (persistenti ) notifiche)",
|
||||
"DevDetail_button_Delete_ask": "Vuoi davvero eliminare questo dispositivo? Puoi anche archiviarlo.",
|
||||
"DevDetail_button_OverwriteIcons": "Sovrascrivi icone",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Sovrascrivi le icone di tutti i dispositivi con lo stesso tipo di dispositivo",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Sei sicuro di voler sovrascrivere tutte le icone di tutti i dispositivi con lo stesso tipo di dispositivo come l'attuale tipo di dispositivo?",
|
||||
@@ -205,6 +209,7 @@
|
||||
"Device_Shortcut_OnlineChart": "Presenza dispositivo",
|
||||
"Device_TableHead_AlertDown": "Avviso disconnessione",
|
||||
"Device_TableHead_Connected_Devices": "Connessioni",
|
||||
"Device_TableHead_CustomProps": "Proprietà/Azioni",
|
||||
"Device_TableHead_Favorite": "Preferito",
|
||||
"Device_TableHead_FirstSession": "Prima sessione",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
@@ -237,12 +242,15 @@
|
||||
"Device_Tablelenght": "Mostra _MENU_ elementi",
|
||||
"Device_Tablelenght_all": "Tutti",
|
||||
"Device_Title": "Dispositivi",
|
||||
"Devices_Filters": "Filtri",
|
||||
"Donations_Others": "Altri",
|
||||
"Donations_Platforms": "Piattaforme sponsor",
|
||||
"Donations_Text": "Hey 👋! </br> Grazie per aver cliccato su questa voce di menu 😅 </br> </br> Sto cercando di ricevere donazioni per poter fornire un software migliore. Inoltre potrebbe aiutarmi a non andare in burnout, in modo da poter supportare questa app più a lungo. Ogni piccola (ricorrente o non) sponsorizzazione mi invoglia a mettere più impegno nello sviluppo di questa app. </br> Mi piacerebbe accorciare la mia settimana lavorativa e nel tempo rimanente dedicarmi completamente a NetAlertX. Riceverai più funzionalità, un'applicazione più rifinita e con meno bug.</br> </br> Grazie per aver letto, ti sono grato per ogni tipo di supporto ❤🙏 </br> </br> TL;DR: Supportandomi otterrai: </br> </br> <ul><li>Aggiornamenti più regolari per mantenere i tuoi dati e la tua famiglia sicuri 🔄</li><li>Meno bug 🐛🔫</li><li>Funzionalità migliori e più numerose➕</li><li>Io non vado in burnout 🔥🤯</li><li>Rilasci meno affrettati 💨</li><li>Migliore documentazione 📚</li><li>Supporto migliore e più veloce in caso di problemi 🆘</li></ul> </br> 📧Invia una mail a <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> se vuoi contattarmi o chiedermi di aggiungere altre piattaforme di sponsorizzazione. </br>",
|
||||
"Donations_Title": "Donazioni",
|
||||
"ENABLE_PLUGINS_description": "Abilita la funzionalità <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugin</a>. Utilizzare i plugin richiede più risorse hardware, potresti voler disabilitare questa opzione sui dispositivi meno performanti.",
|
||||
"ENABLE_PLUGINS_name": "Abilita plugin",
|
||||
"ENCRYPTION_KEY_description": "Chiave di crittografia dei dati.",
|
||||
"ENCRYPTION_KEY_name": "Chiave di crittografia",
|
||||
"Email_display_name": "E-mail",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Caricamento...",
|
||||
@@ -278,7 +286,7 @@
|
||||
"Events_Tablelenght": "Mostra _MENU_ elementi",
|
||||
"Events_Tablelenght_all": "Tutti",
|
||||
"Events_Title": "Eventi",
|
||||
"GRAPHQL_PORT_description": "Il numero di porta del server GraphQL.",
|
||||
"GRAPHQL_PORT_description": "Il numero di porta del server GraphQL. Assicurati che la porta sia univoca in tutte le tue applicazioni su questo host e nelle istanze di NetAlertX.",
|
||||
"GRAPHQL_PORT_name": "Porta GraphQL",
|
||||
"Gen_Action": "Azione",
|
||||
"Gen_Add": "Aggiungi",
|
||||
@@ -305,6 +313,7 @@
|
||||
"Gen_ReadDocs": "Maggiori informazioni nella documentazione.",
|
||||
"Gen_Remove_All": "Rimuovi tutti",
|
||||
"Gen_Remove_Last": "Rimuovi ultimo",
|
||||
"Gen_Reset": "Reimposta",
|
||||
"Gen_Restore": "Esegui ripristino",
|
||||
"Gen_Run": "Esegui",
|
||||
"Gen_Save": "Salva",
|
||||
@@ -319,6 +328,7 @@
|
||||
"Gen_Upd_Fail": "Aggiornamento fallito",
|
||||
"Gen_Update": "Aggiorna",
|
||||
"Gen_Update_Value": "Aggiorna valore",
|
||||
"Gen_ValidIcon": "",
|
||||
"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_create_new_device": "Nuovo dispositivo",
|
||||
@@ -390,17 +400,23 @@
|
||||
"Maintenance_Running_Version": "Versione installata",
|
||||
"Maintenance_Status": "Stato",
|
||||
"Maintenance_Title": "Strumenti di manutenzione",
|
||||
"Maintenance_Tool_ExportCSV": "Esporta CSV",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Esporta CSV",
|
||||
"Maintenance_Tool_DownloadConfig": "Impostazioni Esporta",
|
||||
"Maintenance_Tool_DownloadConfig_text": "Scarica un backup completo della configurazione delle tue Impostazioni memorizzata nel file <code>app.conf</code>.",
|
||||
"Maintenance_Tool_ExportCSV": "Esporta dispositivi (csv)",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Esporta dispositivi (csv)",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Sei sicuro di voler generare un file CSV?",
|
||||
"Maintenance_Tool_ExportCSV_text": "Genera un file CSV (comma separated value) contenente la lista dei dispositivi incluse le relazioni di rete tra i nodi di rete e i dispositivi connessi. Puoi anche eseguire questa azione accedendo all'URL <code>il_tuo_NetAlertX/php/server/devices.php?action=ExportCSV</code> o abilitando il plugin <a href=\"settings.php#CSVBCKP_header\">Backup CSV</a>.",
|
||||
"Maintenance_Tool_ImportCSV": "Importa CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti": "Importa CSV",
|
||||
"Maintenance_Tool_ImportCSV": "Importa dispositivi (csv)",
|
||||
"Maintenance_Tool_ImportCSV_noti": "Importa dispositivi (csv)",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Sei sicuro di voler importare il file CSV? Questa operazione <b>sovrascriverà</b> tutti i dispositivi presenti nel database.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Prima di utilizzare questa funzione, esegui un backup. Importa un file CSV (comma separated value) contenente la lista dei dispositivi incluse le relazioni di rete tra i nodi di rete e i dispositivi connessi. Per far ciò posiziona il file CSV denominato <b>devices.csv</b> nella cartella <b>/config</b>.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Importazione CSV (incolla)",
|
||||
"Maintenance_Tool_ImportConfig_noti": "Importa impostazioni (app.conf)",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Importa dispositivi (csv) (incolla)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "Sei sicuro di voler importare il CSV incollato? Questo <b>sovrascriverà</b> completamente i dispositivi nel tuo database.",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "Prima di utilizzare questa funzione, esegui un backup. Importa un file CSV (valori separati da virgole) contenente l'elenco dei dispositivi, comprese le relazioni di rete tra i nodi di rete e i dispositivi collegati.",
|
||||
"Maintenance_Tool_ImportPastedConfig": "Importa impostazioni (incolla)",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "Vuoi davvero importare le impostazioni di configurazione incollate? Questo <b>sovrascriverà</b> completamente il file <code>app.conf</code>.",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "Importa il file <code>app.conf</code> contenente tutte le impostazioni dell'applicazione. Potresti voler scaricare prima il file <code>app.conf</code> corrente con <b>Esporta impostazioni</b>.",
|
||||
"Maintenance_Tool_arpscansw": "Attiva/disattiva arp-Scan",
|
||||
"Maintenance_Tool_arpscansw_noti": "Attiva o disattiva arp-Scan",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Una volta disattivata la scansione rimane disattivata finché non viene nuovamente attivata.",
|
||||
@@ -475,13 +491,13 @@
|
||||
"Maintenance_lang_selector_empty": "Scegli lingua",
|
||||
"Maintenance_lang_selector_lable": "Seleziona lingua",
|
||||
"Maintenance_lang_selector_text": "Questa modifica avviene lato client, quindi influisce solo sul browser attualmente in uso.",
|
||||
"Maintenance_new_version": "🆕 È disponibile una nuova versione. Controlla le <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">note di rilascio</a>.",
|
||||
"Maintenance_new_version": "È disponibile una nuova versione. Controlla le <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">note di rilascio</a>.",
|
||||
"Maintenance_themeselector_apply": "Applica",
|
||||
"Maintenance_themeselector_empty": "Scegli una skin",
|
||||
"Maintenance_themeselector_lable": "Seleziona skin",
|
||||
"Maintenance_themeselector_text": "Questa modifica avviene lato server, quindi influenza tutti i dispositivi in uso.",
|
||||
"Maintenance_version": "Aggiornamenti app",
|
||||
"NETWORK_DEVICE_TYPES_description": "Quali tipi di dispositivi possono essere utilizzati come dispositivi di rete nella visualizzazione di rete. Il tipo di dispositivo deve corrispondere esattamente all'impostazione <code>Tipo</code> su un dispositivo specifico in dettagli dispositivo. Non rimuovere i tipi esistenti, aggiungine solo di nuovi.",
|
||||
"NETWORK_DEVICE_TYPES_description": "Quali tipi di dispositivo possono essere utilizzati come dispositivi di rete nella vista Rete. Il tipo di dispositivo deve corrispondere esattamente all'impostazione <code>Tipo</code> su un dispositivo specifico nei Dettagli dispositivo. Aggiungilo sul Dispositivo tramite il pulsante <code>+</code>. Non rimuovere i tipi esistenti, aggiungine solo di nuovi.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Tipi di dispositivi di rete",
|
||||
"Navigation_About": "Informazioni su",
|
||||
"Navigation_Devices": "Dispositivi",
|
||||
@@ -702,6 +718,7 @@
|
||||
"general_event_title": "Esecuzione di un evento ad-hoc",
|
||||
"go_to_node_event_icon": "fa-square-up-right",
|
||||
"go_to_node_event_tooltip": "Passa alla pagina Rete del nodo specificato",
|
||||
"new_version_available": "È disponibile una nuova versione.",
|
||||
"report_guid": "GUID notifica:",
|
||||
"report_guid_missing": "Notifica collegata non trovata. C'è un piccolo ritardo tra la disponibilità delle notifiche inviate di recente e la loro disponibilità. Aggiorna la pagina e la cache dopo alcuni secondi. È anche possibile che la notifica selezionata sia stata eliminata durante la manutenzione come specificato nell'impostazione <code>DBCLNP_NOTIFI_HIST</code>. <br/> <br/>Viene invece visualizzata l'ultima notifica. La notifica mancante ha il seguente GUID:",
|
||||
"report_select_format": "Seleziona formato:",
|
||||
|
||||
@@ -60,12 +60,15 @@
|
||||
"BackDevices_darkmode_enabled": "Mørk modus Aktivert",
|
||||
"CLEAR_NEW_FLAG_description": "",
|
||||
"CLEAR_NEW_FLAG_name": "",
|
||||
"CustProps_cant_remove": "",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "Dette er en vedlikeholdsinnstilling. Dette spesifiserer antall dager verdt med hendelsesoppføringer som vil beholdes. Alle eldre hendelser vil bli slettet med jevne mellomrom. Gjelder også for plugin-hendelseshistorikk.",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Slett hendelser eldre enn",
|
||||
"DISCOVER_PLUGINS_description": "",
|
||||
"DISCOVER_PLUGINS_name": "",
|
||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Kopier detaljer fra enhet",
|
||||
"DevDetail_Copy_Device_Tooltip": "Kopier detaljer fra enheten via nedtrekks menyen. Alt på denne siden vil bli overskrevet",
|
||||
"DevDetail_CustomProperties_Title": "",
|
||||
"DevDetail_CustomProps_reset_info": "",
|
||||
"DevDetail_DisplayFields_Title": "",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Varsel Alle Hendelser",
|
||||
"DevDetail_EveandAl_AlertDown": "Varsel Nede",
|
||||
@@ -135,8 +138,8 @@
|
||||
"DevDetail_Shortcut_DownAlerts": "Nede Varslinger",
|
||||
"DevDetail_Shortcut_Presence": "Tilstedeværelse",
|
||||
"DevDetail_Shortcut_Sessions": "Sesjoner",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Detaljer",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Hendelser",
|
||||
"DevDetail_Tab_Details": "Detaljer",
|
||||
"DevDetail_Tab_Events": "Hendelser",
|
||||
"DevDetail_Tab_EventsTableDate": "Dato",
|
||||
"DevDetail_Tab_EventsTableEvent": "Hendelstype",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
@@ -151,10 +154,10 @@
|
||||
"DevDetail_Tab_NmapTableState": "Tilstand",
|
||||
"DevDetail_Tab_NmapTableText": "Konfigurer en tidsplan i <a href=\"/settings.php#NMAP_ACTIVE\">Innstillinger</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "Tidspunkt",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Tilstedeværelse",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Økter",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Verktøy",
|
||||
"DevDetail_Tab_Plugins": "Plugins",
|
||||
"DevDetail_Tab_Presence": "Tilstedeværelse",
|
||||
"DevDetail_Tab_Sessions": "Økter",
|
||||
"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_Error": "En feil har oppstått",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Start Internett-informasjonsverktøyet",
|
||||
@@ -182,6 +185,7 @@
|
||||
"DevDetail_button_Delete": "Slett Enhet",
|
||||
"DevDetail_button_DeleteEvents": "Slett Hendelser",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Er du sikker på at du vil slette alle hendelser på denne enheten?<br><br>(dette vil tømme <b>hendelsesloggen</b> og <b>øktene</b> og kan hjelpe med konstante (vedvarende) varslinger)",
|
||||
"DevDetail_button_Delete_ask": "",
|
||||
"DevDetail_button_OverwriteIcons": "Overskriv ikoner",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Overskriv ikoner på alle enheter med samme enhetstype",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Er du sikker på at du vil overskrive alle ikonene på alle enheter med samme enhetstype som gjeldende enhetstype?",
|
||||
@@ -205,6 +209,7 @@
|
||||
"Device_Shortcut_OnlineChart": "Enhetens tilstedeværelse",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "Tilkoblinger",
|
||||
"Device_TableHead_CustomProps": "",
|
||||
"Device_TableHead_Favorite": "Favoritt",
|
||||
"Device_TableHead_FirstSession": "Første Økt",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
@@ -237,12 +242,15 @@
|
||||
"Device_Tablelenght": "Show _MENU_ entries",
|
||||
"Device_Tablelenght_all": "Alle",
|
||||
"Device_Title": "Enheter",
|
||||
"Devices_Filters": "",
|
||||
"Donations_Others": "Andre",
|
||||
"Donations_Platforms": "Sponsorplattformer",
|
||||
"Donations_Text": "Hei 👋! </br> Takk for at du klikket på dette menyelementet 😅 </br> </br> Jeg prøver å samle inn noen donasjoner for å lage bedre programvare. Dessuten ville det hjelpe meg å ikke bli utbrent, så jeg kan støtte denne appen lenger. Enhver liten (tilbakevendende eller ikke) sponsing gjør at jeg ønsker å legge mer innsats i denne appen. </br> Jeg vil gjerne forkorte arbeidsuken min og i den gjenværende tiden fokusere fullt ut på NetAlertX. Du vil få mer funksjonalitet, en mer polert app og mindre feil. </br> </br> Takk for at du leste - jeg er takknemlig for all støtte ❤🙏 </br> </br> TL;DR: Ved å støtte meg får du: </br> </br> <ul> <li>Jevne oppdateringer for å holde dataene dine og familien din trygge 🔄</li><li>Mindre feil 🐛🔫</li><li>Bedre og mer funksjonalitet➕</li><li>Jeg blir ikke utbrent 🔥🤯</li><li>Mindre forhastede utgivelser 💨</li><li>Bedre dokumenter📚</li><li>Raskere og bedre støtte med problemer 🆘</li></ul> </br> 📧 Send meg en e-post til <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> hvis du ønsker å komme i kontakt eller hvis jeg skal legge til andre sponsorplattformer. </br>",
|
||||
"Donations_Title": "Donasjoner",
|
||||
"ENABLE_PLUGINS_description": "Aktiverer <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a> funksjonaliten. Å laste inn plugins krever mer maskinvareressurser, så det kan være lurt å deaktivere dem på et system med lav strøm.",
|
||||
"ENABLE_PLUGINS_name": "Aktiver Plugins",
|
||||
"ENCRYPTION_KEY_description": "",
|
||||
"ENCRYPTION_KEY_name": "",
|
||||
"Email_display_name": "E-post",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Laster...",
|
||||
@@ -305,6 +313,7 @@
|
||||
"Gen_ReadDocs": "Les mer i dokumentasjonen.",
|
||||
"Gen_Remove_All": "Fjern alle",
|
||||
"Gen_Remove_Last": "Fjern sist",
|
||||
"Gen_Reset": "",
|
||||
"Gen_Restore": "Kjør Gjenopprett",
|
||||
"Gen_Run": "Kjør",
|
||||
"Gen_Save": "Lagre",
|
||||
@@ -319,6 +328,7 @@
|
||||
"Gen_Upd_Fail": "Oppdatering feilet",
|
||||
"Gen_Update": "Oppdater",
|
||||
"Gen_Update_Value": "Oppdater verdi",
|
||||
"Gen_ValidIcon": "",
|
||||
"Gen_Warning": "Advarsel",
|
||||
"Gen_Work_In_Progress": "Work in progress, gjerne kom med tilbakemeldinger på https://github.com/jokob-sk/NetAlertX/issues",
|
||||
"Gen_create_new_device": "",
|
||||
@@ -390,6 +400,8 @@
|
||||
"Maintenance_Running_Version": "Installert versjon",
|
||||
"Maintenance_Status": "Status",
|
||||
"Maintenance_Title": "Vedlikeholdsverktøy",
|
||||
"Maintenance_Tool_DownloadConfig": "",
|
||||
"Maintenance_Tool_DownloadConfig_text": "",
|
||||
"Maintenance_Tool_ExportCSV": "Eksporter CSV",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Eksporter CSV",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Er du sikker på at du vil generere en CSV-fil?",
|
||||
@@ -398,9 +410,13 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "Importer CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Er du sikker på at du vil importere CSV-filen? Dette vil fullstendig overskrive enhetene i databasen din.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Før du bruker denne funksjonen, vennligst ta en sikkerhetskopi. Importer en CSV-fil (kommaseparert verdi) som inneholder listen over enheter, inkludert nettverksrelasjoner mellom nettverksnoder og tilkoblede enheter. For å gjøre det, plasser CSV-filen med navnet <b>devices.csv</b> i mappen <b>/config</b>.",
|
||||
"Maintenance_Tool_ImportConfig_noti": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "",
|
||||
"Maintenance_Tool_arpscansw": "Slå arp-Scan (på/av)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Slå arp-Scan på eller av",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Når skanningen er slått av, forblir den slått av til den aktiveres igjen.",
|
||||
@@ -475,7 +491,7 @@
|
||||
"Maintenance_lang_selector_empty": "Velg språk",
|
||||
"Maintenance_lang_selector_lable": "Velg språk",
|
||||
"Maintenance_lang_selector_text": "Endringen skjer på klientsiden, så den påvirker bare den nåværende nettleseren.",
|
||||
"Maintenance_new_version": "🆕 En ny versjon er tilgjengelig. Sjekk ut <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">utgivelsesnotater</a>.",
|
||||
"Maintenance_new_version": "En ny versjon er tilgjengelig. Sjekk ut <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">utgivelsesnotater</a>.",
|
||||
"Maintenance_themeselector_apply": "Bruk",
|
||||
"Maintenance_themeselector_empty": "Velg ett skinn",
|
||||
"Maintenance_themeselector_lable": "Velg skinn",
|
||||
@@ -702,6 +718,7 @@
|
||||
"general_event_title": "Utfører en ad-hoc hendelse",
|
||||
"go_to_node_event_icon": "",
|
||||
"go_to_node_event_tooltip": "",
|
||||
"new_version_available": "",
|
||||
"report_guid": "Notifikasjons GUID:",
|
||||
"report_guid_missing": "Koblet notifikasjon ikke funnet. Det er en liten forsinkelse mellom nylig sendt notifikasjoner og at de er tilgjengelige. Oppdater siden din og hurtigbufferen etter noen sekunder. Det er også mulig den valgte notifikasjonen er slettet under vedlikehold som spesifisert i <code>DBCLNP_NOTIFI_HIST</code> innstillingen. <br/> <br/> Den siste notifikasjonen vises i stedet. Den manglende notifikasjonen har følgende GUID:",
|
||||
"report_select_format": "Velg format:",
|
||||
|
||||
25
front/php/templates/language/pl_pl.json
Executable file → Normal file
@@ -60,12 +60,15 @@
|
||||
"BackDevices_darkmode_enabled": "Tryb ciemny Włączony",
|
||||
"CLEAR_NEW_FLAG_description": "",
|
||||
"CLEAR_NEW_FLAG_name": "",
|
||||
"CustProps_cant_remove": "",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "To jest ustawienie konserwacji. Określa ile dni mają być utrzymywane wpisy wydarzeń. Wszystkie starsze wpisy wydarzeń zostaną usunięte okresowo. Dotyczy także Historii Wydarzeń Pluginów.",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Usuń wydarzenia starsze niż",
|
||||
"DISCOVER_PLUGINS_description": "",
|
||||
"DISCOVER_PLUGINS_name": "",
|
||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i>Kopiuj opis z urządzenia",
|
||||
"DevDetail_Copy_Device_Tooltip": "Kopiuj opis z urządzenia z listy rozwijanej. Wszystko na tej stronie zostanie nadpisane",
|
||||
"DevDetail_CustomProperties_Title": "",
|
||||
"DevDetail_CustomProps_reset_info": "",
|
||||
"DevDetail_DisplayFields_Title": "",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Powiadamiaj o wszystkich wydarzeniach",
|
||||
"DevDetail_EveandAl_AlertDown": "Wyłącz powiadomienia",
|
||||
@@ -152,9 +155,9 @@
|
||||
"DevDetail_Tab_NmapTableText": "Ustaw harmonogram w <a href=\"/settings.php#NMAP_ACTIVE\">Ustawieniach</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "Czas",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i>Pluginy",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Obecność",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sesje",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Narzędzia",
|
||||
"DevDetail_Tab_Presence": "Obecność",
|
||||
"DevDetail_Tab_Sessions": "Sesje",
|
||||
"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_Error": "Wystąpił błąd",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Rozpocznij Informacje o Internecie",
|
||||
@@ -182,6 +185,7 @@
|
||||
"DevDetail_button_Delete": "Usuń Urządzenie",
|
||||
"DevDetail_button_DeleteEvents": "Usuń Wydarzenia",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Jesteś pewien, że chcesz usunąć wszystkie Wydarzenia tego urządzenia?<br><br>(wyczyści to <b>Historię Wydarzeń</b> i <b>Sesje</b> i może pomóc ze stałymi powiadomieniami)",
|
||||
"DevDetail_button_Delete_ask": "",
|
||||
"DevDetail_button_OverwriteIcons": "Nadpisz Ikony",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Nadpisz ikony dla urządzeń o tym samym typie",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Czy na pewno chcesz nadpisać wszystkie ikony dla urządzeń o tym samym typie co to urządzenie?",
|
||||
@@ -205,6 +209,7 @@
|
||||
"Device_Shortcut_OnlineChart": "Obecność urządzenia",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "Połączenia",
|
||||
"Device_TableHead_CustomProps": "",
|
||||
"Device_TableHead_Favorite": "Ulubione",
|
||||
"Device_TableHead_FirstSession": "Pierwsza Sesja",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
@@ -237,12 +242,15 @@
|
||||
"Device_Tablelenght": "Pokaż_wpisy_MENU",
|
||||
"Device_Tablelenght_all": "Wszystkie",
|
||||
"Device_Title": "Urządzenia",
|
||||
"Devices_Filters": "",
|
||||
"Donations_Others": "Inne",
|
||||
"Donations_Platforms": "Platforma Sponsora",
|
||||
"Donations_Text": "Cześć 👋! </br> Dziękuje że kliknąłeś w to menu 😅 </br> </br> Próbuje zebrać trochę dotacji by ulepszyć to oprogramowanie. Także pomaga mi to się nie wypalić bym dalej mógł ulepszać to narzędzie. Każdy mały (powtarzający się lub nie) sponsoring sprawia że chce wkładać więcej pracy w tą aplikację. </br> Chciałbym skrócić mój tydzień pracy i w wolnym czasie skupić się nad NetAlertX. Dostawalibyście wtedy więcej funkcjonalności i były by one ciągle udoskonalane i posiadające mniej błędów. </br> </br> Dziękuję że to przeczytałeś - Jestem wdzięczny za pomoc ❤🙏</br> </br> TL;DR: Wspierając mnie otrzymujesz: </br> </br> <ul><li> Regularne aktualizacje by zapewnić twoim danym i rodzinie bezpieczeństwo 🔄 </li><li>Mniej błędów (bugów) 🐛🔫</li><li>Nowe i lepsze funkcjonalności➕</li><li>Nie tracę zapału do dalszego tworzenia 🔥🤯</li><li>Mniej pośpieszne, bardziej dopracowane wydania💨</li><li>Lepsza dokumentacja📚</li><li>Szybsza i lepsza pomoc w problemach🆘</li></ul> </br>📧Napisz E-mail do mnie na<a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> jeżeli chcesz nawiązać kontakt albo czy powinien dodać kolejną platformę z sponsoringiem.</br>",
|
||||
"Donations_Title": "Dotacje",
|
||||
"ENABLE_PLUGINS_description": "Włącza funkcjonalność <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">pluginów</a>. Uruchomienie pluginów wymaga więcej zasobów sprzętu więcej możesz chcieć to wyłączyć dla słabszych systemów.",
|
||||
"ENABLE_PLUGINS_name": "Włącz Pluginy",
|
||||
"ENCRYPTION_KEY_description": "",
|
||||
"ENCRYPTION_KEY_name": "",
|
||||
"Email_display_name": "Email",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Wczytywanie...",
|
||||
@@ -305,6 +313,7 @@
|
||||
"Gen_ReadDocs": "Przeczytaj więcej w dokumentacji.",
|
||||
"Gen_Remove_All": "Usuń wszystko",
|
||||
"Gen_Remove_Last": "Usuń ostatnie",
|
||||
"Gen_Reset": "",
|
||||
"Gen_Restore": "Wykonaj Przywracanie",
|
||||
"Gen_Run": "Wykonaj",
|
||||
"Gen_Save": "Zapisz",
|
||||
@@ -319,6 +328,7 @@
|
||||
"Gen_Upd_Fail": "Aktualizacja nie powiodła się",
|
||||
"Gen_Update": "Aktualizuj",
|
||||
"Gen_Update_Value": "Aktualizuj Wartość",
|
||||
"Gen_ValidIcon": "",
|
||||
"Gen_Warning": "Uwaga",
|
||||
"Gen_Work_In_Progress": "Praca w toku, dobry czas na feedback https://github.com/jokob-sk/NetAlertX/issues",
|
||||
"Gen_create_new_device": "",
|
||||
@@ -390,6 +400,8 @@
|
||||
"Maintenance_Running_Version": "Zainstalowana wersja",
|
||||
"Maintenance_Status": "Status",
|
||||
"Maintenance_Title": "Narzędzia konserwacyjne",
|
||||
"Maintenance_Tool_DownloadConfig": "",
|
||||
"Maintenance_Tool_DownloadConfig_text": "",
|
||||
"Maintenance_Tool_ExportCSV": "Eksport CSV",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Eksport CSV",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Jesteś pewien, że chcesz wygenerować plik CSV?",
|
||||
@@ -398,9 +410,13 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "Import CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Jesteś pewien że chcesz zaimportować plik CSV? Nadpisze to wszystkie urządzenie w bazie danych.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Przed użyciem tej funkcji, wykonaj proszę kopię zapasową. Zaimportuj plik CSV (wartości oddzielone przecinkami) zawierający listę Urządzeń, w tym Relacji Sieci między sieciowymi węzłami i podłączonymi urządzeniami. By to zrobić umieść plik CSV nazwany <b>devices.csv</b> do twojego folderu <b>/config</b>.",
|
||||
"Maintenance_Tool_ImportConfig_noti": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "",
|
||||
"Maintenance_Tool_arpscansw": "Przełącz Skan-arp (wł/wył)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Przełącz Skan-arp na włączony lub wyłączony",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Kiedy skan zostanie przełączony na wył zostaje wyłączony do czasu ponownej aktywacji.",
|
||||
@@ -702,6 +718,7 @@
|
||||
"general_event_title": "Wykonywanie wydarzeń ad-hoc",
|
||||
"go_to_node_event_icon": "",
|
||||
"go_to_node_event_tooltip": "",
|
||||
"new_version_available": "",
|
||||
"report_guid": "Przewodnik powiadomień:",
|
||||
"report_guid_missing": "Linkowane powiadomienie nie znaleziono. Jest małe opóźnienie między wysłaniem powiadomienia a ich dostępnością. Odśwież stronę i cache za kilka sekund. Możliwe też że zaznaczone powiadomienie zostało usunięte podczas konserwacji tak jak określono w ustawieniu <code>DBCLNP_NOTIFI_HIST</code>. <br/><br/>Zamiast tego wyświetlane jest najnowsze powiadomienie. Brakujące powiadomienie ma następujące GUID:",
|
||||
"report_select_format": "Wybierz Format:",
|
||||
@@ -736,4 +753,4 @@
|
||||
"settings_update_item_warning": "Zaktualizuj poniższą wartość. Zachowaj ostrożność i postępuj zgodnie z poprzednim formatem. <b>Walidacja nie jest wykonywana.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Zapisz zmiany zanim będziesz testować swoje ustawienia."
|
||||
}
|
||||
}
|
||||
|
||||
29
front/php/templates/language/pt_br.json
Executable file → Normal file
@@ -60,12 +60,15 @@
|
||||
"BackDevices_darkmode_enabled": "Modo Noturno Habilitado",
|
||||
"CLEAR_NEW_FLAG_description": "Se habilitado (<code>0</code> está desativado), dispositivos marcados como<b>Novo Dispositivo</b> serão desmarcados se o limite (especificado em horas) exceder o tempo da <b>Primeira Sessão </b>.",
|
||||
"CLEAR_NEW_FLAG_name": "",
|
||||
"CustProps_cant_remove": "",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "Esta é uma definição de manutenção. Especifica o número de dias de entradas de eventos que serão mantidas. Todos os eventos mais antigos serão eliminados periodicamente. Também se aplica ao Histórico de eventos do plug-in.",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Excluir eventos mais antigos que",
|
||||
"DISCOVER_PLUGINS_description": "",
|
||||
"DISCOVER_PLUGINS_name": "",
|
||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copiar detalhes do dispositivo",
|
||||
"DevDetail_Copy_Device_Tooltip": "Copiar detalhes do dispositivo a partir da lista pendente. Tudo o que se encontra nesta página será substituído",
|
||||
"DevDetail_CustomProperties_Title": "",
|
||||
"DevDetail_CustomProps_reset_info": "",
|
||||
"DevDetail_DisplayFields_Title": "",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Alerte Todos os Eventos",
|
||||
"DevDetail_EveandAl_AlertDown": "Alerta Desligado",
|
||||
@@ -135,8 +138,8 @@
|
||||
"DevDetail_Shortcut_DownAlerts": "Alertas para baixo",
|
||||
"DevDetail_Shortcut_Presence": "Presença",
|
||||
"DevDetail_Shortcut_Sessions": "Sessões",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Detalhes",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Eventos",
|
||||
"DevDetail_Tab_Details": "Detalhes",
|
||||
"DevDetail_Tab_Events": "Eventos",
|
||||
"DevDetail_Tab_EventsTableDate": "Data",
|
||||
"DevDetail_Tab_EventsTableEvent": "Tipo de evento",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
@@ -152,9 +155,9 @@
|
||||
"DevDetail_Tab_NmapTableText": "Configure uma programação em <a href=\"/settings.php#NMAP_ACTIVE\">Configurações</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "Tempo",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"> </i> Plugins",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Presença",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sessões",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Ferramentas",
|
||||
"DevDetail_Tab_Presence": "Presença",
|
||||
"DevDetail_Tab_Sessions": "Sessões",
|
||||
"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_Error": "Um erro ocorreu",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Iniciar informações da Internet",
|
||||
@@ -182,6 +185,7 @@
|
||||
"DevDetail_button_Delete": "Excluir dispositivo",
|
||||
"DevDetail_button_DeleteEvents": "Excluir eventos",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Tem certeza de que deseja excluir todos os eventos deste dispositivo?<br><br>(isso limpará o <b>Histórico de eventos</b> e as <b>sessões</b> e poderá ajudar com constantes (persistentes) notificações)",
|
||||
"DevDetail_button_Delete_ask": "",
|
||||
"DevDetail_button_OverwriteIcons": "Substituir ícones",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Substituir ícones de todos os dispositivos pelo mesmo tipo de dispositivo",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Tem certeza de que deseja substituir todos os ícones de todos os dispositivos pelo mesmo tipo de dispositivo do tipo de dispositivo atual?",
|
||||
@@ -205,6 +209,7 @@
|
||||
"Device_Shortcut_OnlineChart": "Presença do dispositivo",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "Conexões",
|
||||
"Device_TableHead_CustomProps": "",
|
||||
"Device_TableHead_Favorite": "Favorito",
|
||||
"Device_TableHead_FirstSession": "Primeira sessão",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
@@ -237,12 +242,15 @@
|
||||
"Device_Tablelenght": "Mostrar entradas do _MENU_",
|
||||
"Device_Tablelenght_all": "Todos",
|
||||
"Device_Title": "Dispositivos",
|
||||
"Devices_Filters": "",
|
||||
"Donations_Others": "Outros",
|
||||
"Donations_Platforms": "Plataformas de patrocinadores",
|
||||
"Donations_Text": "Ei 👋! </br> Obrigado por clicar neste item de menu 😅 </br> </br> Estou tentando coletar algumas doações para melhorar o software. Além disso, isso me ajudaria a não ficar exausto, para que eu pudesse oferecer suporte a este aplicativo por mais tempo. Qualquer pequeno patrocínio (recorrente ou não) me faz querer colocar mais esforço neste aplicativo. </br> Eu adoraria encurtar minha semana de trabalho e no tempo restante focar totalmente no NetAlertX. Você obteria mais funcionalidades, um aplicativo mais sofisticado e menos bugs. </br> </br> Obrigado pela leitura - sou grato por qualquer apoio ❤🙏 </br> </br> TL;DR: Ao me apoiar, você obtém: </br> </br> <ul> <li>Atualizações regulares para manter seus dados e sua família seguros 🔄</li><li>Menos bugs 🐛🔫</li><li>Melhor e mais funcionalidade➕</li><li>Eu não fico exausto 🔥🤯</li><li>Lançamentos menos apressados 💨</li><li>Documentos melhores📚</li><li>Suporte melhor e mais rápido com problemas 🆘</li></ul> </br> 📧 Envie-me um e-mail para <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> se quiser entrar em contato ou se devo adicionar outras plataformas de patrocínio. </br>",
|
||||
"Donations_Title": "Doações",
|
||||
"ENABLE_PLUGINS_description": "Ativa a funcionalidade de <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a>. Carregar plug-ins requer mais recursos de hardware, então você pode querer desativá-los em sistemas de baixa potência.",
|
||||
"ENABLE_PLUGINS_name": "Habilitar plug-ins",
|
||||
"ENCRYPTION_KEY_description": "",
|
||||
"ENCRYPTION_KEY_name": "",
|
||||
"Email_display_name": "Email",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Carregando...",
|
||||
@@ -305,6 +313,7 @@
|
||||
"Gen_ReadDocs": "Leia mais em documentos.",
|
||||
"Gen_Remove_All": "Remover tudo",
|
||||
"Gen_Remove_Last": "Remover o último",
|
||||
"Gen_Reset": "",
|
||||
"Gen_Restore": "Executar restauração",
|
||||
"Gen_Run": "Executar",
|
||||
"Gen_Save": "Salvar",
|
||||
@@ -319,6 +328,7 @@
|
||||
"Gen_Upd_Fail": "A atualização falhou",
|
||||
"Gen_Update": "Atualizar",
|
||||
"Gen_Update_Value": "Atualizar valor",
|
||||
"Gen_ValidIcon": "",
|
||||
"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_create_new_device": "",
|
||||
@@ -390,6 +400,8 @@
|
||||
"Maintenance_Running_Version": "",
|
||||
"Maintenance_Status": "",
|
||||
"Maintenance_Title": "",
|
||||
"Maintenance_Tool_DownloadConfig": "",
|
||||
"Maintenance_Tool_DownloadConfig_text": "",
|
||||
"Maintenance_Tool_ExportCSV": "",
|
||||
"Maintenance_Tool_ExportCSV_noti": "",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "",
|
||||
@@ -398,9 +410,13 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportCSV_text": "",
|
||||
"Maintenance_Tool_ImportConfig_noti": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "",
|
||||
"Maintenance_Tool_arpscansw": "",
|
||||
"Maintenance_Tool_arpscansw_noti": "",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "",
|
||||
@@ -702,6 +718,7 @@
|
||||
"general_event_title": "",
|
||||
"go_to_node_event_icon": "",
|
||||
"go_to_node_event_tooltip": "",
|
||||
"new_version_available": "",
|
||||
"report_guid": "",
|
||||
"report_guid_missing": "",
|
||||
"report_select_format": "",
|
||||
@@ -736,4 +753,4 @@
|
||||
"settings_update_item_warning": "",
|
||||
"test_event_icon": "",
|
||||
"test_event_tooltip": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Вы можете указать собственный SQL-запрос, который будет генерировать файл JSON, а затем предоставлять его через конечную точку файла <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code></a>.",
|
||||
"API_CUSTOM_SQL_name": "Пользовательская конечная точка",
|
||||
"API_TOKEN_description": "API-токен для защиты соединения. Вы можете сгенерировать его или ввести любое значение. Он отправляется в заголовке запроса. Используется в плагине <code>SYNC</code> и GraphQL сервере.",
|
||||
"API_TOKEN_description": "API-токен для безопасной связи. Сгенерируйте его или введите любое значение. Он передается в заголовке запроса и используется в плагине <code>SYNC</code>, сервере GraphQL и других конечных точках API. Вы можете использовать конечные точки API для создания пользовательских интеграций, как описано в <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md\" target=\"_blank\">документации по API</a>.",
|
||||
"API_TOKEN_name": "API token",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
@@ -48,7 +48,7 @@
|
||||
"BackDevices_DBTools_ImportCSVError": "Не удалось импортировать файл CSV. Убедитесь, что формат правильный.",
|
||||
"BackDevices_DBTools_ImportCSVMissing": "CSV-файл не найден в<b>/config/devices.csv.</b>",
|
||||
"BackDevices_DBTools_Purge": "Самые старые резервные копии были удалены",
|
||||
"BackDevices_DBTools_UpdDev": "Устройство успешно обновлено",
|
||||
"BackDevices_DBTools_UpdDev": "Устройство успешно обновлено. При выполнении сканирования может потребоваться некоторое время для перезагрузки основного списка устройств.",
|
||||
"BackDevices_DBTools_UpdDevError": "Ошибка обновления устройства",
|
||||
"BackDevices_DBTools_Upgrade": "База данных успешно обновлена",
|
||||
"BackDevices_DBTools_UpgradeError": "Обновление базы данных не удалось",
|
||||
@@ -60,12 +60,15 @@
|
||||
"BackDevices_darkmode_enabled": "Темный режим включен",
|
||||
"CLEAR_NEW_FLAG_description": "Если этот параметр включен (<code>0</code> отключен), устройства, помеченные как <b>Новое устройство</b>, станут неотмеченными, если лимит времени, указанный в часах, превышает время их <b>первой сессии</b>.",
|
||||
"CLEAR_NEW_FLAG_name": "Удалить новый флаг",
|
||||
"CustProps_cant_remove": "Невозможно удалить, необходимо хотя бы одно свойство.",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "Это настройка обслуживания. Здесь указывается количество дней, в течение которых будут храниться записи о событиях. Все старые события будут периодически удаляться. Также применимо к истории событий плагина.",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Удалить события старше",
|
||||
"DISCOVER_PLUGINS_description": "",
|
||||
"DISCOVER_PLUGINS_name": "",
|
||||
"DISCOVER_PLUGINS_description": "Отключите эту опцию, чтобы ускорить инициализацию и сохранение настроек. При отключении этой опции плагины не обнаруживаются, и вы не можете добавлять новые плагины в параметр <code>LOADED_PLUGINS</code>.",
|
||||
"DISCOVER_PLUGINS_name": "Обзор плагинов",
|
||||
"DevDetail_Copy_Device_Title": "Скопировать данные с устройства",
|
||||
"DevDetail_Copy_Device_Tooltip": "Скопируйте данные с устройства из раскрывающегося списка. Все на этой странице будет перезаписано",
|
||||
"DevDetail_CustomProperties_Title": "Пользовательские свойства",
|
||||
"DevDetail_CustomProps_reset_info": "Это удалит ваши пользовательские свойства на этом устройстве и вернет их к значению по умолчанию.",
|
||||
"DevDetail_DisplayFields_Title": "Дисплей",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Оповещения о событиях",
|
||||
"DevDetail_EveandAl_AlertDown": "Оповещение о доступности",
|
||||
@@ -135,8 +138,8 @@
|
||||
"DevDetail_Shortcut_DownAlerts": "Оповещения о сбое",
|
||||
"DevDetail_Shortcut_Presence": "Присутствие",
|
||||
"DevDetail_Shortcut_Sessions": "Сеансы",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Детали",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> События",
|
||||
"DevDetail_Tab_Details": "Детали",
|
||||
"DevDetail_Tab_Events": "События",
|
||||
"DevDetail_Tab_EventsTableDate": "Дата",
|
||||
"DevDetail_Tab_EventsTableEvent": "Тип события",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
@@ -151,10 +154,10 @@
|
||||
"DevDetail_Tab_NmapTableState": "Состояние",
|
||||
"DevDetail_Tab_NmapTableText": "Настройте расписание в <a href=\"/settings.php#NMAP_ACTIVE\">Настройки</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "Время",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Плагины",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Присутствие",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Сеансы",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Инструменты",
|
||||
"DevDetail_Tab_Plugins": "Плагины",
|
||||
"DevDetail_Tab_Presence": "Присутствие",
|
||||
"DevDetail_Tab_Sessions": "Сеансы",
|
||||
"DevDetail_Tab_Tools": "Инструменты",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Description": "Инструмент «Информация об Интернете» отображает информацию о подключении к Интернету, такую как IP-адрес, город, страна, код города и часовой пояс.",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Error": "Произошла ошибка",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Показать инфо об Интернете",
|
||||
@@ -182,6 +185,7 @@
|
||||
"DevDetail_button_Delete": "Удалить устройство",
|
||||
"DevDetail_button_DeleteEvents": "Удалить события",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Вы уверены, что хотите удалить все события на этом устройстве?<br><br>(это очистит <b>Историю событий</b> и <b>Сеансы</b> и может помочь с постоянными (настойчивыми) уведомлениями)",
|
||||
"DevDetail_button_Delete_ask": "Вы уверены, что хотите удалить это устройство? Вместо этого вы можете заархивировать его.",
|
||||
"DevDetail_button_OverwriteIcons": "Перезаписать значки",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Перезаписать значки всех устройств одного типа",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Вы уверены, что хотите перезаписать все значки всех устройств с тем же типом устройства, что и текущий тип устройства?",
|
||||
@@ -205,6 +209,7 @@
|
||||
"Device_Shortcut_OnlineChart": "Присутствие устройств",
|
||||
"Device_TableHead_AlertDown": "Оповещение о сост. ВЫКЛ",
|
||||
"Device_TableHead_Connected_Devices": "Соединения",
|
||||
"Device_TableHead_CustomProps": "Свойства / Действия",
|
||||
"Device_TableHead_Favorite": "Избранное",
|
||||
"Device_TableHead_FirstSession": "Первый сеанс",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
@@ -237,12 +242,15 @@
|
||||
"Device_Tablelenght": "Показать _MENU_ записей",
|
||||
"Device_Tablelenght_all": "Все",
|
||||
"Device_Title": "Устройства",
|
||||
"Devices_Filters": "Фильтры",
|
||||
"Donations_Others": "Другие",
|
||||
"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_Title": "Пожертвования",
|
||||
"ENABLE_PLUGINS_description": "Включает функциональность <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">плагинов.</a> Загрузка плагинов требует больше аппаратных ресурсов, поэтому вы можете отключить их в маломощной системе.",
|
||||
"ENABLE_PLUGINS_name": "Разрешить плагины",
|
||||
"ENCRYPTION_KEY_description": "Ключ шифрования данных.",
|
||||
"ENCRYPTION_KEY_name": "Ключ шифрования",
|
||||
"Email_display_name": "Эл. почта",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Загрузка...",
|
||||
@@ -278,7 +286,7 @@
|
||||
"Events_Tablelenght": "Показать _MENU_ записей",
|
||||
"Events_Tablelenght_all": "Все",
|
||||
"Events_Title": "События",
|
||||
"GRAPHQL_PORT_description": "Номер порта сервера GraphQL.",
|
||||
"GRAPHQL_PORT_description": "Номер порта сервера GraphQL. Убедитесь, что порт уникален для всех ваших приложений на этом хосте и экземпляров NetAlertX.",
|
||||
"GRAPHQL_PORT_name": "Порт GraphQL",
|
||||
"Gen_Action": "Действия",
|
||||
"Gen_Add": "Добавить",
|
||||
@@ -305,13 +313,14 @@
|
||||
"Gen_ReadDocs": "Подробнее читайте в документации.",
|
||||
"Gen_Remove_All": "Удалить все",
|
||||
"Gen_Remove_Last": "Удалить последний",
|
||||
"Gen_Reset": "Сбросить",
|
||||
"Gen_Restore": "Запустить восстановление",
|
||||
"Gen_Run": "Запустить",
|
||||
"Gen_Save": "Сохранить",
|
||||
"Gen_Saved": "Сохранено",
|
||||
"Gen_Search": "Поиск",
|
||||
"Gen_Select": "Выбрать",
|
||||
"Gen_SelectIcon": "",
|
||||
"Gen_SelectIcon": "<i class=\"fa-solid fa-chevron-down fa-fade\"></i>",
|
||||
"Gen_SelectToPreview": "Выберите для предварительного просмотра",
|
||||
"Gen_Selected_Devices": "Выбранные устройства:",
|
||||
"Gen_Switch": "Переключить",
|
||||
@@ -319,10 +328,11 @@
|
||||
"Gen_Upd_Fail": "Не удалось обновить",
|
||||
"Gen_Update": "Обновление",
|
||||
"Gen_Update_Value": "Обновить значение",
|
||||
"Gen_ValidIcon": "",
|
||||
"Gen_Warning": "Предупреждение",
|
||||
"Gen_Work_In_Progress": "Работа продолжается, самое время оставить отзыв на https://github.com/jokob-sk/NetAlertX/issues",
|
||||
"Gen_create_new_device": "Создать фиктивное устройство",
|
||||
"Gen_create_new_device_info": "",
|
||||
"Gen_create_new_device": "Новое устройство",
|
||||
"Gen_create_new_device_info": "Устройства обычно обнаруживаются с помощью <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">плагинов</a>. Однако в некоторых случаях вам может потребоваться добавить устройства вручную. Для изучения конкретных сценариев ознакомьтесь с документацией <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/REMOTE_NETWORKS.md\">Remote Networks</a>.",
|
||||
"General_display_name": "Главное",
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "Это настройка обслуживания <b>УДАЛЕНИЕ устройств</b>. Если этот параметр включен (<code>0</code> отключен), устройства, помеченные как <b>Новое устройство</b>, будут удалены, если время их <b>Первого сеанса</b> было старше указанных в этой настройке часов. Используйте этот параметр, если вы хотите автоматически удалять <b>Новые устройства</b> через <code>X</code> часов.",
|
||||
@@ -390,17 +400,23 @@
|
||||
"Maintenance_Running_Version": "Установленная версия",
|
||||
"Maintenance_Status": "Статус",
|
||||
"Maintenance_Title": "Инструменты обслуживания",
|
||||
"Maintenance_Tool_ExportCSV": "Экспорт CSV",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Экспорт CSV",
|
||||
"Maintenance_Tool_DownloadConfig": "Экспорт настроек",
|
||||
"Maintenance_Tool_DownloadConfig_text": "Загрузите полную резервную копию конфигурации настроек, хранящуюся в файле <code>app.conf</code>.",
|
||||
"Maintenance_Tool_ExportCSV": "Экспорт устройств (csv)",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Экспорт устройств (csv)",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Вы уверены, что хотите создать файл CSV?",
|
||||
"Maintenance_Tool_ExportCSV_text": "Создайте файл CSV (значения, разделенные запятыми), содержащий список устройств, включая сетевые отношения между сетевыми узлами и подключенными устройствами. Вы также можете открыть этот URL-адрес <code> URL Вашего NetAlertX/php/server/devices.php?action=ExportCSV</code> или включить плагин <a href=\"settings.php#CSVBCKP_header\">Резервное копирование в CSV</a>.",
|
||||
"Maintenance_Tool_ImportCSV": "Импорт CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti": "Импорт CSV",
|
||||
"Maintenance_Tool_ImportCSV": "Импорт устройств (csv)",
|
||||
"Maintenance_Tool_ImportCSV_noti": "Импорт устройств (csv)",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Вы уверены, что хотите импортировать файл CSV? Это полностью <b>перезапишет</b> устройства в вашей базе данных.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Импортируйте файл CSV (значения, разделенные запятыми), содержащий список устройств, включая сетевые отношения между сетевыми узлами и подключенными устройствами. Для этого поместите файл CSV с именем <b>devices.csv</b> в папку <b>/config</b>.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Импорт CSV (вставка)",
|
||||
"Maintenance_Tool_ImportConfig_noti": "Импорт настроек (app.conf)",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Импорт устройств CSV (вставка)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "Вы уверены, что хотите импортировать вставленный CSV? Это полностью <b>перезапишет</b> устройства в вашей базе данных.",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "Перед использованием этой функции, пожалуйста, создайте резервную копию. Импортируйте файл формата CSV (значения, разделенные запятыми), содержащий список устройств, включая сетевые связи между узлами сети и подключенными устройствами.",
|
||||
"Maintenance_Tool_ImportPastedConfig": "Импорт настроек (вставка)",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "Вы уверены, что хотите импортировать вставленные настройки конфигурации? Это полностью <b>перезапишет</b> файл <code>app.conf</code>.",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "Импорт файла <code>app.conf</code>, содержащего все настройки приложения. Возможно, вам захочется сначала загрузить текущий файл <code>app.conf</code> с помощью команды <b>Экспорт настроек</b>.",
|
||||
"Maintenance_Tool_arpscansw": "Переключить arp-скан (ВКЛ./ВЫКЛ.)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Включить или выключить arp-скан",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Когда сканирование было выключено, оно остается выключенным до тех пор, пока не будет активировано снова.",
|
||||
@@ -475,13 +491,13 @@
|
||||
"Maintenance_lang_selector_empty": "Выберите язык",
|
||||
"Maintenance_lang_selector_lable": "Выбрать язык",
|
||||
"Maintenance_lang_selector_text": "Изменение происходит на стороне клиента, поэтому оно влияет только на текущий браузер.",
|
||||
"Maintenance_new_version": "🆕 Доступна новая версия. Ознакомьтесь с <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">примечаниями к выпуску</a>.",
|
||||
"Maintenance_new_version": "Доступна новая версия. Ознакомьтесь с <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">примечаниями к выпуску</a>.",
|
||||
"Maintenance_themeselector_apply": "Применить",
|
||||
"Maintenance_themeselector_empty": "Выбрать скин",
|
||||
"Maintenance_themeselector_lable": "Выбрать Скин",
|
||||
"Maintenance_themeselector_text": "Изменение происходит на стороне сервера, поэтому оно затрагивает все используемые устройства.",
|
||||
"Maintenance_version": "Обновления приложения",
|
||||
"NETWORK_DEVICE_TYPES_description": "Какие типы устройств разрешено использовать в качестве сетевых устройств в представлении «Сеть». Тип устройства должен точно соответствовать настройке <code>Тип</code> на конкретном устройстве в разделе «Сведения об устройстве». Не удаляйте существующие типы, а только добавляйте новые.",
|
||||
"NETWORK_DEVICE_TYPES_description": "Какие типы устройств разрешено использовать в качестве сетевых устройств в представлении Сеть. Тип устройства должен точно соответствовать настройке <code>Type</code> для конкретного устройства в сведениях об устройстве. Добавьте его на устройство с помощью кнопки <code>+</code>. Не удаляйте существующие типы, а только добавляйте новые.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Типы сетевых устройств",
|
||||
"Navigation_About": "О NetAlertX",
|
||||
"Navigation_Devices": "Устройства",
|
||||
@@ -702,6 +718,7 @@
|
||||
"general_event_title": "Выполнение специального события",
|
||||
"go_to_node_event_icon": "fa-square-up-right",
|
||||
"go_to_node_event_tooltip": "Переход на страницу \"Сеть\" данного узла",
|
||||
"new_version_available": "Доступна новая версия.",
|
||||
"report_guid": "Идентификатор уведомления:",
|
||||
"report_guid_missing": "Связанное уведомление не найдено. Между недавно отправленными уведомлениями и их доступностью существует небольшая задержка. Обновите страницу и кэшируйте ее через несколько секунд. Также возможно, что выбранное уведомление было удалено во время обслуживания, как указано в настройке <code>DBCLNP_NOTIFI_HIST</code>. <br/> <br/>Вместо этого отображается последнее уведомление. Отсутствующее уведомление имеет следующий GUID:",
|
||||
"report_select_format": "Выбрать формат:",
|
||||
|
||||
@@ -60,12 +60,15 @@
|
||||
"BackDevices_darkmode_enabled": "",
|
||||
"CLEAR_NEW_FLAG_description": "",
|
||||
"CLEAR_NEW_FLAG_name": "",
|
||||
"CustProps_cant_remove": "",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "",
|
||||
"DISCOVER_PLUGINS_description": "",
|
||||
"DISCOVER_PLUGINS_name": "",
|
||||
"DevDetail_Copy_Device_Title": "",
|
||||
"DevDetail_Copy_Device_Tooltip": "",
|
||||
"DevDetail_CustomProperties_Title": "",
|
||||
"DevDetail_CustomProps_reset_info": "",
|
||||
"DevDetail_DisplayFields_Title": "",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "",
|
||||
"DevDetail_EveandAl_AlertDown": "",
|
||||
@@ -135,7 +138,7 @@
|
||||
"DevDetail_Shortcut_DownAlerts": "",
|
||||
"DevDetail_Shortcut_Presence": "",
|
||||
"DevDetail_Shortcut_Sessions": "Oturumlar",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Detaylar",
|
||||
"DevDetail_Tab_Details": "Detaylar",
|
||||
"DevDetail_Tab_Events": "",
|
||||
"DevDetail_Tab_EventsTableDate": "Tarih",
|
||||
"DevDetail_Tab_EventsTableEvent": "",
|
||||
@@ -153,7 +156,7 @@
|
||||
"DevDetail_Tab_NmapTableTime": "Zaman",
|
||||
"DevDetail_Tab_Plugins": "",
|
||||
"DevDetail_Tab_Presence": "",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Oturumlar",
|
||||
"DevDetail_Tab_Sessions": "Oturumlar",
|
||||
"DevDetail_Tab_Tools": "",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Description": "",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Error": "Bir hata oluştu",
|
||||
@@ -182,6 +185,7 @@
|
||||
"DevDetail_button_Delete": "Cihazı Sil",
|
||||
"DevDetail_button_DeleteEvents": "",
|
||||
"DevDetail_button_DeleteEvents_Warning": "",
|
||||
"DevDetail_button_Delete_ask": "",
|
||||
"DevDetail_button_OverwriteIcons": "",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "",
|
||||
@@ -205,6 +209,7 @@
|
||||
"Device_Shortcut_OnlineChart": "",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "Bağlantılar",
|
||||
"Device_TableHead_CustomProps": "",
|
||||
"Device_TableHead_Favorite": "",
|
||||
"Device_TableHead_FirstSession": "İlk Oturum",
|
||||
"Device_TableHead_GUID": "",
|
||||
@@ -237,12 +242,15 @@
|
||||
"Device_Tablelenght": "",
|
||||
"Device_Tablelenght_all": "",
|
||||
"Device_Title": "Cihazlar",
|
||||
"Devices_Filters": "",
|
||||
"Donations_Others": "Diğerleri",
|
||||
"Donations_Platforms": "",
|
||||
"Donations_Text": "",
|
||||
"Donations_Title": "",
|
||||
"ENABLE_PLUGINS_description": "",
|
||||
"ENABLE_PLUGINS_name": "",
|
||||
"ENCRYPTION_KEY_description": "",
|
||||
"ENCRYPTION_KEY_name": "",
|
||||
"Email_display_name": "Eposta",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Yükleniyor...",
|
||||
@@ -305,6 +313,7 @@
|
||||
"Gen_ReadDocs": "",
|
||||
"Gen_Remove_All": "Tümünü kaldır",
|
||||
"Gen_Remove_Last": "",
|
||||
"Gen_Reset": "",
|
||||
"Gen_Restore": "",
|
||||
"Gen_Run": "Çalıştır",
|
||||
"Gen_Save": "Kaydet",
|
||||
@@ -319,6 +328,7 @@
|
||||
"Gen_Upd_Fail": "",
|
||||
"Gen_Update": "",
|
||||
"Gen_Update_Value": "",
|
||||
"Gen_ValidIcon": "",
|
||||
"Gen_Warning": "Uyarı",
|
||||
"Gen_Work_In_Progress": "",
|
||||
"Gen_create_new_device": "",
|
||||
@@ -390,6 +400,8 @@
|
||||
"Maintenance_Running_Version": "Yüklenmiş sürüm",
|
||||
"Maintenance_Status": "Durum",
|
||||
"Maintenance_Title": "",
|
||||
"Maintenance_Tool_DownloadConfig": "",
|
||||
"Maintenance_Tool_DownloadConfig_text": "",
|
||||
"Maintenance_Tool_ExportCSV": "",
|
||||
"Maintenance_Tool_ExportCSV_noti": "",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Bir CSV dosyası oluşturmak istediğinize emin misiniz?",
|
||||
@@ -398,9 +410,13 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportCSV_text": "",
|
||||
"Maintenance_Tool_ImportConfig_noti": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "",
|
||||
"Maintenance_Tool_arpscansw": "",
|
||||
"Maintenance_Tool_arpscansw_noti": "",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "",
|
||||
@@ -702,6 +718,7 @@
|
||||
"general_event_title": "",
|
||||
"go_to_node_event_icon": "",
|
||||
"go_to_node_event_tooltip": "",
|
||||
"new_version_available": "",
|
||||
"report_guid": "",
|
||||
"report_guid_missing": "",
|
||||
"report_select_format": "",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Ви можете вказати спеціальний SQL-запит, який створить файл JSON, а потім відкриє його через кінцеву точку файлу <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code></a>.",
|
||||
"API_CUSTOM_SQL_name": "Спеціальна кінцева точка",
|
||||
"API_TOKEN_description": "Маркер API для захисту зв’язку, ви можете створити його або ввести будь-яке значення. Його надсилають у заголовку запиту. Використовується в плагіні <code>SYNC</code>, сервер GraphQL.",
|
||||
"API_TOKEN_description": "Маркер API для безпечного зв’язку. Згенеруйте один або введіть будь-яке значення. Він надсилається в заголовку запиту та використовується в плагіні <code>SYNC</code>, сервері GraphQL та інших кінцевих точках API. Ви можете використовувати кінцеві точки API для створення спеціальних інтеграцій, як описано в <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md\" target=\"_blank\">API документація</a>.",
|
||||
"API_TOKEN_name": "Маркер API",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
@@ -48,7 +48,7 @@
|
||||
"BackDevices_DBTools_ImportCSVError": "Не вдалося імпортувати файл CSV. Переконайтеся, що формат правильний.",
|
||||
"BackDevices_DBTools_ImportCSVMissing": "Не вдалося знайти файл CSV у <b>/config/devices.csv.</b>",
|
||||
"BackDevices_DBTools_Purge": "Найстаріші резервні копії видалено",
|
||||
"BackDevices_DBTools_UpdDev": "Пристрій успішно оновлено",
|
||||
"BackDevices_DBTools_UpdDev": "Пристрій успішно оновлено. Перезавантаження основного списку пристроїв може знадобитися деякий час, якщо триває сканування.",
|
||||
"BackDevices_DBTools_UpdDevError": "Помилка оновлення пристрою",
|
||||
"BackDevices_DBTools_Upgrade": "Базу даних успішно оновлено",
|
||||
"BackDevices_DBTools_UpgradeError": "Не вдалося оновити базу даних",
|
||||
@@ -60,12 +60,15 @@
|
||||
"BackDevices_darkmode_enabled": "Темний режим увімкнено",
|
||||
"CLEAR_NEW_FLAG_description": "Якщо ввімкнено (<code>0</code> вимкнено), пристрої, позначені як <b>Новий пристрій</b>, не будуть позначені, якщо ліміт часу (вказаний у годинах) перевищує їхній <b>Перший сеанс</b> час.",
|
||||
"CLEAR_NEW_FLAG_name": "Очистити новий прапор",
|
||||
"CustProps_cant_remove": "Неможливо видалити, потрібна принаймні одна властивість.",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "Це налаштування обслуговування. Це визначає кількість днів записів про події, які зберігатимуться. Усі старіші події періодично видалятимуться. Також застосовується до історії подій плагінів.",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Видалити події, старші за",
|
||||
"DISCOVER_PLUGINS_description": "Вимкніть цю опцію, щоб прискорити ініціалізацію та збереження налаштувань. Якщо вимкнено, плагіни не виявляються, і ви не можете додавати нові плагіни до параметра <code>LOADED_PLUGINS</code>.",
|
||||
"DISCOVER_PLUGINS_name": "Відкрийте для себе плагіни",
|
||||
"DevDetail_Copy_Device_Title": "Скопіюйте деталі з пристрою",
|
||||
"DevDetail_Copy_Device_Tooltip": "Скопіюйте деталі пристрою зі спадного списку. Усе на цій сторінці буде перезаписано",
|
||||
"DevDetail_CustomProperties_Title": "Спеціальні властивості",
|
||||
"DevDetail_CustomProps_reset_info": "Це призведе до видалення настроюваних властивостей на цьому пристрої та скидання їх до значень за замовчуванням.",
|
||||
"DevDetail_DisplayFields_Title": "Дисплей",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Повідомлення про події",
|
||||
"DevDetail_EveandAl_AlertDown": "Сповіщення вниз",
|
||||
@@ -135,8 +138,8 @@
|
||||
"DevDetail_Shortcut_DownAlerts": "Сповіщення про падіння",
|
||||
"DevDetail_Shortcut_Presence": "Присутність",
|
||||
"DevDetail_Shortcut_Sessions": "Сеанси",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Подробиці",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Події",
|
||||
"DevDetail_Tab_Details": "Подробиці",
|
||||
"DevDetail_Tab_Events": "Події",
|
||||
"DevDetail_Tab_EventsTableDate": "Дата",
|
||||
"DevDetail_Tab_EventsTableEvent": "Тип події",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
@@ -151,10 +154,10 @@
|
||||
"DevDetail_Tab_NmapTableState": "Держава",
|
||||
"DevDetail_Tab_NmapTableText": "Налаштуйте розклад у <a href=\"/settings.php#NMAP_ACTIVE\">Settings</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "час",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Плагіни",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Присутність",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Сеанси",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Інструменти",
|
||||
"DevDetail_Tab_Plugins": "Плагіни",
|
||||
"DevDetail_Tab_Presence": "Присутність",
|
||||
"DevDetail_Tab_Sessions": "Сеанси",
|
||||
"DevDetail_Tab_Tools": "Інструменти",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Description": "Інструмент Інтернет-інформації відображає інформацію про підключення до Інтернету, таку як IP-адреса, місто, країна, код міста та часовий пояс.",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Error": "Сталася помилка",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Запустіть Internet Info",
|
||||
@@ -182,6 +185,7 @@
|
||||
"DevDetail_button_Delete": "Видалити пристрій",
|
||||
"DevDetail_button_DeleteEvents": "Видалити події",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Ви впевнені, що бажаєте видалити всі події цього пристрою?<br><br>(це очистить <b>історію подій</b> і <b>сеанси</b> та може допомогти з постійними (постійними) ) сповіщення)",
|
||||
"DevDetail_button_Delete_ask": "Ви впевнені, що хочете видалити цей пристрій? Натомість ви також можете заархівувати його.",
|
||||
"DevDetail_button_OverwriteIcons": "Перезаписати значки",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Перезаписати піктограми всіх пристроїв одним типом пристрою",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Ви впевнені, що бажаєте перезаписати всі піктограми всіх пристроїв тим самим типом пристрою, що й поточний тип пристрою?",
|
||||
@@ -205,6 +209,7 @@
|
||||
"Device_Shortcut_OnlineChart": "Наявність пристрою",
|
||||
"Device_TableHead_AlertDown": "Сповіщення вниз",
|
||||
"Device_TableHead_Connected_Devices": "Зв'язки",
|
||||
"Device_TableHead_CustomProps": "Реквізит / дії",
|
||||
"Device_TableHead_Favorite": "улюблений",
|
||||
"Device_TableHead_FirstSession": "Перша сесія",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
@@ -237,12 +242,15 @@
|
||||
"Device_Tablelenght": "Показати записи _МЕНЮ_",
|
||||
"Device_Tablelenght_all": "все",
|
||||
"Device_Title": "Пристрої",
|
||||
"Devices_Filters": "Фільтри",
|
||||
"Donations_Others": "інші",
|
||||
"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_Title": "Пожертви",
|
||||
"ENABLE_PLUGINS_description": "Вмикає функції <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">плагінів</a>. Завантаження плагінів вимагає більше апаратних ресурсів, тому ви можете вимкнути їх у системі з низьким енергоспоживанням.",
|
||||
"ENABLE_PLUGINS_name": "Увімкнути плагіни",
|
||||
"ENCRYPTION_KEY_description": "Ключ шифрування даних.",
|
||||
"ENCRYPTION_KEY_name": "Ключ шифрування",
|
||||
"Email_display_name": "Електронна пошта",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Завантаження...",
|
||||
@@ -278,7 +286,7 @@
|
||||
"Events_Tablelenght": "Показати записи _МЕНЮ_",
|
||||
"Events_Tablelenght_all": "все",
|
||||
"Events_Title": "Події",
|
||||
"GRAPHQL_PORT_description": "Номер порту сервера GraphQL.",
|
||||
"GRAPHQL_PORT_description": "Номер порту сервера GraphQL. Переконайтеся, що порт є унікальним для всіх ваших програм на цьому хості та екземплярах NetAlertX.",
|
||||
"GRAPHQL_PORT_name": "Порт GraphQL",
|
||||
"Gen_Action": "Дія",
|
||||
"Gen_Add": "додати",
|
||||
@@ -305,6 +313,7 @@
|
||||
"Gen_ReadDocs": "Детальніше читайте в документах.",
|
||||
"Gen_Remove_All": "Видалити Все",
|
||||
"Gen_Remove_Last": "Видаліть останнім",
|
||||
"Gen_Reset": "Скинути",
|
||||
"Gen_Restore": "Запустіть Restore",
|
||||
"Gen_Run": "бігти",
|
||||
"Gen_Save": "зберегти",
|
||||
@@ -319,6 +328,7 @@
|
||||
"Gen_Upd_Fail": "Не вдалося оновити",
|
||||
"Gen_Update": "оновлення",
|
||||
"Gen_Update_Value": "Оновити значення",
|
||||
"Gen_ValidIcon": "",
|
||||
"Gen_Warning": "УВАГА",
|
||||
"Gen_Work_In_Progress": "Робота триває, час залишити відгук на https://github.com/jokob-sk/NetAlertX/issues",
|
||||
"Gen_create_new_device": "новий пристрій",
|
||||
@@ -390,17 +400,23 @@
|
||||
"Maintenance_Running_Version": "Встановлена версія",
|
||||
"Maintenance_Status": "Статус",
|
||||
"Maintenance_Title": "Інструменти обслуговування",
|
||||
"Maintenance_Tool_ExportCSV": "Експорт CSV",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Експорт CSV",
|
||||
"Maintenance_Tool_DownloadConfig": "Експорт налаштувань",
|
||||
"Maintenance_Tool_DownloadConfig_text": "Завантажте повну резервну копію конфігурації налаштувань, яка зберігається у файлі <code>app.conf</code>.",
|
||||
"Maintenance_Tool_ExportCSV": "Експорт пристроїв (csv)",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Експорт пристроїв (csv)",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Ви впевнені, що хочете створити файл CSV?",
|
||||
"Maintenance_Tool_ExportCSV_text": "Створіть файл CSV (значення, розділене комами), що містить список пристроїв, включаючи мережеві зв’язки між мережевими вузлами та підключеними пристроями. Ви також можете активувати це, перейшовши за цією URL-адресою <code>ваш NetAlertX url/php/server/devices.php?action=ExportCSV</code> або ввімкнувши <a href=\"settings.php#CSVBCKP_header\">Резервне копіювання CSV</a> плагін.",
|
||||
"Maintenance_Tool_ImportCSV": "Імпорт CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti": "Імпорт CSV",
|
||||
"Maintenance_Tool_ExportCSV_text": "Створіть файл CSV (значення, розділене комами), що містить список пристроїв, включаючи мережеві зв’язки між мережевими вузлами та підключеними пристроями. Ви також можете активувати це, перейшовши за цією URL-адресою <code>your_NetAlertX_url/php/server/devices.php?action=ExportCSV</code> або ввімкнувши <a href=\"settings.php#CSVBCKP_header\">Резервне копіювання CSV</a > плагін.",
|
||||
"Maintenance_Tool_ImportCSV": "Імпорт пристроїв (csv)",
|
||||
"Maintenance_Tool_ImportCSV_noti": "Імпорт пристроїв (csv)",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Ви впевнені, що бажаєте імпортувати файл CSV? Це повністю <b>перезапише</b> пристрої у вашій базі даних.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Перед використанням цієї функції зробіть резервну копію. Імпортуйте файл CSV (значення, розділене комами), який містить список пристроїв, включаючи мережеві зв’язки між мережевими вузлами та підключеними пристроями. Для цього помістіть файл CSV під назвою <b>devices.csv</b> у папку <b>/config</b>.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Імпорт CSV (вставити)",
|
||||
"Maintenance_Tool_ImportConfig_noti": "Імпорт налаштувань (app.conf)",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Імпорт пристроїв (csv) (вставити)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "Ви впевнені, що бажаєте імпортувати вставлений CSV? Це повністю <b>перезапише</b> пристрої у вашій базі даних.",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "Перед використанням цієї функції зробіть резервну копію. Імпортуйте файл CSV (значення, розділене комами), що містить список пристроїв, включаючи мережеві зв’язки між мережевими вузлами та підключеним пристроєм.",
|
||||
"Maintenance_Tool_ImportPastedConfig": "Імпорт налаштувань (вставити)",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "Ви впевнені, що бажаєте імпортувати вставлені налаштування конфігурації? Це повністю <b>перезапише</b> файл <code>app.conf</code>.",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "Імпортує файл <code>app.conf</code>, який містить усі налаштування програми. Ви можете спочатку завантажити поточний файл <code>app.conf</code> за допомогою <b>Експорту налаштувань</b>.",
|
||||
"Maintenance_Tool_arpscansw": "Перемикач arp-сканування (увімк./вимк.)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Увімкніть або вимкніть arp-Scan",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Коли сканування було вимкнено, воно залишається вимкненим, доки не буде активовано знову.",
|
||||
@@ -475,13 +491,13 @@
|
||||
"Maintenance_lang_selector_empty": "Виберіть мову",
|
||||
"Maintenance_lang_selector_lable": "Виберіть мови",
|
||||
"Maintenance_lang_selector_text": "Зміна відбувається на стороні клієнта, тому вона впливає лише на поточний браузер.",
|
||||
"Maintenance_new_version": "🆕 Доступна нова версія. Перегляньте <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">примітки до випуску</a>.",
|
||||
"Maintenance_new_version": "Доступна нова версія. Перегляньте <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">примітки до випуску</a>.",
|
||||
"Maintenance_themeselector_apply": "Застосувати",
|
||||
"Maintenance_themeselector_empty": "Виберіть скін",
|
||||
"Maintenance_themeselector_lable": "Виберіть Скін",
|
||||
"Maintenance_themeselector_text": "Зміна відбувається на стороні сервера, тому вона впливає на всі пристрої, які використовуються.",
|
||||
"Maintenance_version": "Оновлення програми",
|
||||
"NETWORK_DEVICE_TYPES_description": "Які типи пристроїв можна використовувати як мережеві пристрої в поданні мережі. Тип пристрою має точно відповідати налаштуванню <code>Тип</code> на певному пристрої в Деталях пристрою. Не видаляйте існуючі типи, лише додайте нові.",
|
||||
"NETWORK_DEVICE_TYPES_description": "Які типи пристроїв дозволено використовувати як мережеві пристрої в поданні мережі. Тип пристрою має точно відповідати налаштуванню <code>Тип</code> на певному пристрої в Деталях пристрою. Додайте його на пристрій за допомогою кнопки <code>+</code>. Не видаляйте існуючі типи, лише додайте нові.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Типи мережевих пристроїв",
|
||||
"Navigation_About": "про",
|
||||
"Navigation_Devices": "Пристрої",
|
||||
@@ -702,6 +718,7 @@
|
||||
"general_event_title": "Виконання спеціальної події",
|
||||
"go_to_node_event_icon": "fa-квадрат-вгору-вправо",
|
||||
"go_to_node_event_tooltip": "Перейдіть на сторінку Мережа даного вузла",
|
||||
"new_version_available": "Доступна нова версія.",
|
||||
"report_guid": "Довідник сповіщень:",
|
||||
"report_guid_missing": "Пов’язане сповіщення не знайдено. Існує невелика затримка між нещодавно надісланими сповіщеннями та їх доступністю. Оновіть сторінку та кеш через кілька секунд. Також можливо, вибране сповіщення було видалено під час обслуговування, як зазначено в параметрі <code>DBCLNP_NOTIFI_HIST</code>. <br/> <br/>Натомість відображається останнє сповіщення. Відсутнє сповіщення має такий GUID:",
|
||||
"report_select_format": "Виберіть формат:",
|
||||
|
||||
@@ -60,12 +60,15 @@
|
||||
"BackDevices_darkmode_enabled": "已启用暗黑模式",
|
||||
"CLEAR_NEW_FLAG_description": "",
|
||||
"CLEAR_NEW_FLAG_name": "",
|
||||
"CustProps_cant_remove": "",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "这是维护设置。它指定将保留的事件条目的天数。所有较旧的事件将被定期删除。也适用于插件事件历史记录。",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "删除早于",
|
||||
"DISCOVER_PLUGINS_description": "",
|
||||
"DISCOVER_PLUGINS_name": "",
|
||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> 从设备复制详细信息",
|
||||
"DevDetail_Copy_Device_Tooltip": "从下拉列表中复制设备的详细信息。此页面上的所有内容都将被覆盖",
|
||||
"DevDetail_CustomProperties_Title": "",
|
||||
"DevDetail_CustomProps_reset_info": "",
|
||||
"DevDetail_DisplayFields_Title": "",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "提醒所有事件",
|
||||
"DevDetail_EveandAl_AlertDown": "警报关闭",
|
||||
@@ -135,8 +138,8 @@
|
||||
"DevDetail_Shortcut_DownAlerts": "下线警报",
|
||||
"DevDetail_Shortcut_Presence": "存在",
|
||||
"DevDetail_Shortcut_Sessions": "会话",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> 详细信息",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> 事件",
|
||||
"DevDetail_Tab_Details": "详细信息",
|
||||
"DevDetail_Tab_Events": "事件",
|
||||
"DevDetail_Tab_EventsTableDate": "日期",
|
||||
"DevDetail_Tab_EventsTableEvent": "事件类型",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
@@ -151,10 +154,10 @@
|
||||
"DevDetail_Tab_NmapTableState": "状态",
|
||||
"DevDetail_Tab_NmapTableText": "<a href=\"/settings.php#NMAP_ACTIVE\">设置</a>时间表",
|
||||
"DevDetail_Tab_NmapTableTime": "时间",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> 插件",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> 存在",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> 会话",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> 工具",
|
||||
"DevDetail_Tab_Plugins": "插件",
|
||||
"DevDetail_Tab_Presence": "存在",
|
||||
"DevDetail_Tab_Sessions": "会话",
|
||||
"DevDetail_Tab_Tools": "工具",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Description": "互联网信息工具显示有关互联网连接的信息,例如 IP 地址、城市、国家、区号和时区。",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Error": "发生了错误",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "开始互联网信息",
|
||||
@@ -182,6 +185,7 @@
|
||||
"DevDetail_button_Delete": "删除设备",
|
||||
"DevDetail_button_DeleteEvents": "删除事件",
|
||||
"DevDetail_button_DeleteEvents_Warning": "您确定要删除此设备的所有事件吗?<br><br>(这将清除<b>事件历史记录</b>和<b>会话</b>,并且可能有助于持续(持久)通知)",
|
||||
"DevDetail_button_Delete_ask": "",
|
||||
"DevDetail_button_OverwriteIcons": "覆盖图标",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "覆盖具有相同设备类型的所有设备的图标",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "您确定要覆盖与当前设备类型相同的所有设备的所有图标吗?",
|
||||
@@ -205,6 +209,7 @@
|
||||
"Device_Shortcut_OnlineChart": "设备统计",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "链接",
|
||||
"Device_TableHead_CustomProps": "",
|
||||
"Device_TableHead_Favorite": "收藏",
|
||||
"Device_TableHead_FirstSession": "加入",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
@@ -237,12 +242,15 @@
|
||||
"Device_Tablelenght": "显示 _MENU_ 页",
|
||||
"Device_Tablelenght_all": "所有",
|
||||
"Device_Title": "设备",
|
||||
"Devices_Filters": "",
|
||||
"Donations_Others": "其他",
|
||||
"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_Title": "捐款",
|
||||
"ENABLE_PLUGINS_description": "启用<a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">插件</a>功能。加载插件需要更多硬件资源,因此您可能需要在低功耗系统上禁用它们。",
|
||||
"ENABLE_PLUGINS_name": "启用插件",
|
||||
"ENCRYPTION_KEY_description": "",
|
||||
"ENCRYPTION_KEY_name": "",
|
||||
"Email_display_name": "Email",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "加载中...",
|
||||
@@ -305,6 +313,7 @@
|
||||
"Gen_ReadDocs": "在文档中阅读更多内容。",
|
||||
"Gen_Remove_All": "全部删除",
|
||||
"Gen_Remove_Last": "删除最后一个",
|
||||
"Gen_Reset": "",
|
||||
"Gen_Restore": "运行恢复",
|
||||
"Gen_Run": "运行",
|
||||
"Gen_Save": "保存",
|
||||
@@ -319,6 +328,7 @@
|
||||
"Gen_Upd_Fail": "更新失败",
|
||||
"Gen_Update": "更新",
|
||||
"Gen_Update_Value": "更新值",
|
||||
"Gen_ValidIcon": "",
|
||||
"Gen_Warning": "警告",
|
||||
"Gen_Work_In_Progress": "工作正在进行中,欢迎在 https://github.com/jokob-sk/NetAlertX/issues 上反馈",
|
||||
"Gen_create_new_device": "",
|
||||
@@ -390,6 +400,8 @@
|
||||
"Maintenance_Running_Version": "安装版本",
|
||||
"Maintenance_Status": "状态",
|
||||
"Maintenance_Title": "维护工具",
|
||||
"Maintenance_Tool_DownloadConfig": "",
|
||||
"Maintenance_Tool_DownloadConfig_text": "",
|
||||
"Maintenance_Tool_ExportCSV": "CSV 导出",
|
||||
"Maintenance_Tool_ExportCSV_noti": "CSV 导出",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "您确定要生成 CSV 文件吗?",
|
||||
@@ -398,9 +410,13 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "CSV 导入",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "您确定要导入 CSV 文件吗?这将完全<b>覆盖</b>数据库中的设备。",
|
||||
"Maintenance_Tool_ImportCSV_text": "在使用此功能之前,请先备份。导入一个 CSV(逗号分隔值)文件,其中包含设备列表,包括网络节点和连接设备之间的网络关系。为此,请将名为 <b>devices.csv</b> 的 CSV 文件放入您的 <b>/config</b> 文件夹中。",
|
||||
"Maintenance_Tool_ImportConfig_noti": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "CSV 导入(粘贴)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "您确定要导入粘贴的 CSV 吗?这将完全<b>覆盖</b>数据库中的设备。",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "使用此功能前,请先备份。导入一个包含设备列表(包括网络节点和所连接设备之间的网络关系)的 CSV(逗号分隔值)文件。",
|
||||
"Maintenance_Tool_ImportPastedConfig": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedConfig_text": "",
|
||||
"Maintenance_Tool_arpscansw": "切换 arp 扫描(开/关)",
|
||||
"Maintenance_Tool_arpscansw_noti": "打开或关闭 arp 扫描",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "当扫描关闭时,它会保持关闭状态,直到再次激活为止。",
|
||||
@@ -475,7 +491,7 @@
|
||||
"Maintenance_lang_selector_empty": "选择语言",
|
||||
"Maintenance_lang_selector_lable": "选择语言",
|
||||
"Maintenance_lang_selector_text": "该更改发生在客户端,因此只影响当前浏览器。",
|
||||
"Maintenance_new_version": "🆕 有新版本可用。查看<a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">发行说明</a>。",
|
||||
"Maintenance_new_version": "有新版本可用。查看<a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">发行说明</a>。",
|
||||
"Maintenance_themeselector_apply": "应用",
|
||||
"Maintenance_themeselector_empty": "选择皮肤",
|
||||
"Maintenance_themeselector_lable": "选择皮肤",
|
||||
@@ -702,6 +718,7 @@
|
||||
"general_event_title": "执行自组织网络事件",
|
||||
"go_to_node_event_icon": "",
|
||||
"go_to_node_event_tooltip": "",
|
||||
"new_version_available": "",
|
||||
"report_guid": "通知guid:",
|
||||
"report_guid_missing": "未找到链接的通知。最近发送的通知与可用通知之间存在短暂延迟。几秒钟后刷新页面并缓存。所选通知也可能已在维护期间被删除,如 <code>DBCLNP_NOTIFI_HIST</code> 设置中所述。<br/> <br/>系统将改为显示最新通知。缺失的通知具有以下 GUID:",
|
||||
"report_select_format": "选择格式:",
|
||||
|
||||
@@ -8,6 +8,7 @@ $configFolderPath = dirname(__FILE__)."/../../../config/";
|
||||
$config_file = "app.conf";
|
||||
$logFolderPath = "/app/log/";
|
||||
$log_file = "app_front.log";
|
||||
$default_tz = "Europe/Berlin";
|
||||
|
||||
|
||||
$fullConfPath = $configFolderPath.$config_file;
|
||||
@@ -29,7 +30,13 @@ foreach ($config_file_lines as $line)
|
||||
|
||||
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);
|
||||
|
||||
@@ -7,20 +7,9 @@
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
<div class="content-wrapper integrations-plugins">
|
||||
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
|
||||
<h1 id="pageTitle">
|
||||
<i class="fa fa-fw fa-plug"></i> <?= lang('Navigation_Plugins');?>
|
||||
<span class="pageHelp"> <a target="_blank" href="https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins"><i class="fa fa-circle-question"></i></a><span>
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
|
||||
<?php
|
||||
require 'pluginsCore.php';
|
||||
?>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -24,49 +24,51 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
|
||||
|
||||
|
||||
| ID | Type | Description | Features | Required | Data source | Detailed docs |
|
||||
|---------------|---------|--------------------------------------------|----------|----------|--------------------|---------------------------------------------------------------|
|
||||
|---------------|---------|--------------------------------------------|----------|----------|--------------|---------------------------------------------------------------------|
|
||||
| `APPRISE` | ▶️ | Apprise notification proxy | | | Script | [_publisher_apprise](/front/plugins/_publisher_apprise/) |
|
||||
| `ARPSCAN` | 🔍 | ARP-scan on current network | | | Script | [arp_scan](/front/plugins/arp_scan/) |
|
||||
| `AVAHISCAN` | 🆎 | Avahi (mDNS-based) name resolution | | | Script | [avahi_scan](/front/plugins/avahi_scan/) |
|
||||
| `ASUSWRT` | 🔍 | Import connected devices from AsusWRT | | | Script | [asuswrt_import](/front/plugins/asuswrt_import/) |
|
||||
| `CSVBCKP` | ⚙ | CSV devices backup | | | Script | [csv_backup](/front/plugins/csv_backup/) |
|
||||
| `CUSTPROP` | ⚙ | Managing custom device properties values | | Yes | Template | [custom_props](/front/plugins/custom_props/) |
|
||||
| `DBCLNP` | ⚙ | Database cleanup | | Yes* | Script | [db_cleanup](/front/plugins/db_cleanup/) |
|
||||
| `DDNS` | ⚙ | DDNS update | | | Script | [ddns_update](/front/plugins/ddns_update/) |
|
||||
| `DHCPLSS` | 🔍/📥/🆎| Import devices from DHCP leases | | | Script | [dhcp_leases](/front/plugins/dhcp_leases/) |
|
||||
| `DHCPLSS` | 🔍/📥/🆎| Import devices from DHCP leases | | | Script | [dhcp_leases](/front/plugins/dhcp_leases/) |
|
||||
| `DHCPSRVS` | ♻ | DHCP servers | | | Script | [dhcp_servers](/front/plugins/dhcp_servers/) |
|
||||
| `FREEBOX` | 🔍/♻/🆎 | Pull data and names from Freebox/Iliadbox | | | Script | [freebox](/front/plugins/freebox/) |
|
||||
| `FREEBOX` | 🔍/♻/🆎| Pull data and names from Freebox/Iliadbox | | | Script | [freebox](/front/plugins/freebox/) |
|
||||
| `ICMP` | 🔍 | ICMP (ping) status checker | | | Script | [icmp_scan](/front/plugins/icmp_scan/) |
|
||||
| `INTRNT` | 🔍 | Internet IP scanner | | | Script | [internet_ip](/front/plugins/internet_ip/) |
|
||||
| `INTRSPD` | ♻ | Internet speed test | | | Script | [internet_speedtest](/front/plugins/internet_speedtest/) |
|
||||
| `IPNEIGH` | 🔍 | Scan ARP (IPv4) and NDP (IPv6) tables | | | Script | [ipneigh](/front/plugins/ipneigh/) |
|
||||
| `LUCIRPC` | 🔍 | Import connected devices from OpenWRT | | | Script | [luci_import](/front/plugins/luci_import/) |
|
||||
| `MAINT` | ⚙ | Maintenance of logs, etc. | | | Script | [maintenance](/front/plugins/maintenance/) |
|
||||
| `MQTT` | ▶️ | MQTT for synching to Home Assistant | | | Script | [_publisher_mqtt](/front/plugins/_publisher_mqtt/) |
|
||||
| `NBTSCAN` | 🆎 | Nbtscan (NetBIOS-based) name resolution | | | Script | [nbtscan_scan](/front/plugins/nbtscan_scan/) |
|
||||
| `NBTSCAN` | 🆎 | Nbtscan (NetBIOS-based) name resolution | | | Script | [nbtscan_scan](/front/plugins/nbtscan_scan/) |
|
||||
| `NEWDEV` | ⚙ | New device template | | Yes | Template | [newdev_template](/front/plugins/newdev_template/) |
|
||||
| `NMAP` | ♻ | Nmap port scanning & discovery | | | Script | [nmap_scan](/front/plugins/nmap_scan/) |
|
||||
| `NMAPDEV` | 🔍 | Nmap dev scan on current network | | | Script | [nmap_dev_scan](/front/plugins/nmap_dev_scan/) |
|
||||
| `NSLOOKUP` | 🆎 | NSLookup (DNS-based) name resolution | | | Script | [nslookup_scan](/front/plugins/nslookup_scan/) |
|
||||
| `NSLOOKUP` | 🆎 | NSLookup (DNS-based) name resolution | | | Script | [nslookup_scan](/front/plugins/nslookup_scan/) |
|
||||
| `NTFPRCS` | ⚙ | Notification processing | | Yes | Template | [notification_processing](/front/plugins/notification_processing/)|
|
||||
| `NTFY` | ▶️ | NTFY notifications | | | Script | [_publisher_ntfy](/front/plugins/_publisher_ntfy/) |
|
||||
| `OMDSDN` | 📥/🆎 | OMADA TP-Link import | 🖧 🔄 | | Script | [omada_sdn_imp](/front/plugins/omada_sdn_imp/) |
|
||||
| `PIHOLE` | 🔍/🆎/📥| Pi-hole device import & sync | | | SQLite DB | [pihole_scan](/front/plugins/pihole_scan/) |
|
||||
| `OMDSDN` | 📥/🆎 | OMADA TP-Link import | 🖧 🔄 | | Script | [omada_sdn_imp](/front/plugins/omada_sdn_imp/) |
|
||||
| `PIHOLE` | 🔍/🆎/📥| Pi-hole device import & sync | | | SQLite DB | [pihole_scan](/front/plugins/pihole_scan/) |
|
||||
| `PUSHSAFER` | ▶️ | Pushsafer notifications | | | Script | [_publisher_pushsafer](/front/plugins/_publisher_pushsafer/) |
|
||||
| `PUSHOVER` | ▶️ | Pushover notifications | | | Script | [_publisher_pushover](/front/plugins/_publisher_pushover/) |
|
||||
| `SETPWD` | ⚙ | Set password | | Yes | Template | [set_password](/front/plugins/set_password/) |
|
||||
| `SMTP` | ▶️ | Email notifications | | | Script | [_publisher_email](/front/plugins/_publisher_email/) |
|
||||
| `SNMPDSC` | 🔍/📥 | SNMP device import & sync | | | Script | [snmp_discovery](/front/plugins/snmp_discovery/) |
|
||||
| `SYNC` | 🔍/⚙/📥| Sync & import from NetAlertX instances | 🖧 🔄 | 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/) |
|
||||
| `UNDIS` | 🔍/📥 | Create dummy devices | | | Script | [undiscoverables](/front/plugins/undiscoverables/) |
|
||||
| `UNFIMP` | 🔍/📥/🆎| UniFi device import & sync | 🖧 | | Script | [unifi_import](/front/plugins/unifi_import/) |
|
||||
| `UI` | ♻ | UI specific settings | | Yes | Template | [ui_settings](/front/plugins/ui_settings/) |
|
||||
| `UNFIMP` | 🔍/📥/🆎| UniFi device import & sync | 🖧 | | Script | [unifi_import](/front/plugins/unifi_import/) |
|
||||
| `VNDRPDT` | ⚙ | Vendor database update | | | Script | [vendor_update](/front/plugins/vendor_update/) |
|
||||
| `WEBHOOK` | ▶️ | Webhook notifications | | | Script | [_publisher_webhook](/front/plugins/_publisher_webhook/) |
|
||||
| `WEBMON` | ♻ | Website down monitoring | | | Script | [website_monitor](/front/plugins/website_monitor/) |
|
||||
| `WOL` | ♻ | Automatic wake-on-lan | | | Script | [wake_on_lan](/front/plugins/wake_on_lan/) |
|
||||
|
||||
|
||||
> \* The database cleanup plugin (`DBCLNP`) is not _required_ but the app will become unusable after a while if not executed.
|
||||
>
|
||||
> \** The Undiscoverables plugin (`UNDIS`) inserts only user-specified dummy devices.
|
||||
|
||||
> ❌ marked for removal
|
||||
> ⌚It's recommended to use the same schedule interval for all plugins responsible for discovering new devices.
|
||||
|
||||
## Plugin types
|
||||
@@ -79,7 +81,7 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
|
||||
| name discovery | 🆎 | Discovers names of devices via various protocols. | `before_name_updates`, `schedule` | ✖ | Script |
|
||||
| importer | 📥 | Importing devices from another service. | `schedule` | ✖ | Script / SQLite DB |
|
||||
| system | ⚙ | Providing core system functionality. | `schedule` / always on | ✖/✔ | Script / Template |
|
||||
| other | ♻ | Other scanners, e.g. for name resolution | misc | ✖ | Script / Template |
|
||||
| other | ♻ | Other plugins | misc | ✖ | Script / Template |
|
||||
|
||||
## Features
|
||||
|
||||
@@ -93,7 +95,7 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
|
||||
|
||||
Plugins can be enabled via Settings, and can be disabled as needed.
|
||||
|
||||
1. Research which plugin you'd like to use and load the required plugins in Settings via the `LOADED_PLUGINS` setting.
|
||||
1. Research which plugin you'd like to use, enable `DISCOVER_PLUGINS` and load the required plugins in Settings via the `LOADED_PLUGINS` setting.
|
||||
1. Save the changes and review the Settings of the newly loaded plugins.
|
||||
1. Change the `<prefix>_RUN` Setting to the recommended or custom value as per the documentation of the given setting
|
||||
- If using `schedule` on a `🔍 dev scanner` plugin, make sure the schedules are the same across all `🔍 dev scanner` plugins
|
||||
|
||||
@@ -20,4 +20,8 @@ To set up the plugin correctly, make sure...
|
||||
|
||||
### Notes
|
||||
|
||||
- Additional notes, limitations, Author info.
|
||||
- Additional notes, limitations, Author info.
|
||||
|
||||
- Version: 1.0.0
|
||||
- Author: `<your github handle>`
|
||||
- Release Date: `<release date>`
|
||||
@@ -75,7 +75,30 @@
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"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 * * * *",
|
||||
@@ -331,7 +354,7 @@
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"mapped_to_column": "cur_MAC",
|
||||
"css_classes": "col-sm-2",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
"default_value": "",
|
||||
@@ -340,7 +363,7 @@
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "MAC"
|
||||
"string": "MAC (name)"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -116,7 +116,7 @@ def get_device_data(some_setting):
|
||||
}
|
||||
]
|
||||
|
||||
# Return the data to be detected by teh main application
|
||||
# Return the data to be detected by the main application
|
||||
return device_data
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -361,7 +361,30 @@
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"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",
|
||||
|
||||
@@ -27,9 +27,7 @@ Logger(get_setting_value('LOG_LEVEL'))
|
||||
pluginName = "PUSHOVER"
|
||||
|
||||
LOG_PATH = logPath + '/plugins'
|
||||
RESULT_FILE = os.path.join(LOG_PATH, "last_result.log")
|
||||
|
||||
|
||||
RESULT_FILE = os.path.join(LOG_PATH, f'last_result.{pluginName}.log')
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -208,7 +208,30 @@
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"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 * * * *",
|
||||
@@ -385,7 +408,7 @@
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"mapped_to_column": "cur_MAC",
|
||||
"css_classes": "col-sm-2",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
"default_value": "",
|
||||
@@ -394,15 +417,7 @@
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "MAC"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "MAC"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "MAC"
|
||||
"string": "MAC (name)"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -419,14 +434,6 @@
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "IP"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "IP"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "IP"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
23
front/plugins/asuswrt_import/README.md
Executable file
@@ -0,0 +1,23 @@
|
||||
## Overview
|
||||
|
||||
Plugin that imports device IP, MAC, Name, Vendor and Online status from AsusWRT and AsusWRT-Merlin based routers.
|
||||
|
||||
This Plugin is using awesome [asusrouter](https://github.com/Vaskivskyi/asusrouter) library. Please check if your router is supported by it [here](https://github.com/Vaskivskyi/asusrouter?tab=readme-ov-file#supported-devices).
|
||||
|
||||
### Usage
|
||||
|
||||
- Enable the `ASUSWRT` plugin
|
||||
- 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
|
||||
|
||||
- In case an existing imported device is renamed in Asus Router it will not be renamed in NetAlertX. In this case it has to be done manually or the device should be removed and it will appear on the next scan.
|
||||
- Only clients listed in the main AsusWRT interface are imported. If using plugins, such as the `YazFi plugin`, check the [Asus routers DHCPLSS guide](/front/plugins/dhcp_leases/ASUS_ROUTERS.md) for a possible workaround.
|
||||
|
||||
## Other info
|
||||
|
||||
- Version: 1.0.0
|
||||
- Author: [labmonkey](https://github.com/labmonkey)
|
||||
- Release Date: 16.1.2025
|
||||
|
||||
578
front/plugins/asuswrt_import/config.json
Executable file
@@ -0,0 +1,578 @@
|
||||
{
|
||||
"code_name": "asuswrt_import",
|
||||
"show_ui": true,
|
||||
"unique_prefix": "ASUSWRT",
|
||||
"plugin_type": "device_scanner",
|
||||
"execution_order": "Layer_1",
|
||||
"enabled": true,
|
||||
"data_source": "script",
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
"compare_use_quotes": true
|
||||
}
|
||||
],
|
||||
"localized": [
|
||||
"display_name",
|
||||
"description",
|
||||
"icon"
|
||||
],
|
||||
"display_name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "AsusWRT device import"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The plugin is used to import connected devices from AsusWRT"
|
||||
}
|
||||
],
|
||||
"icon": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "<i class=\"fa fa-search\"></i>"
|
||||
}
|
||||
],
|
||||
"params": [],
|
||||
"settings": [
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": [
|
||||
"run"
|
||||
],
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
"once",
|
||||
"schedule"
|
||||
],
|
||||
"localized": [
|
||||
"name",
|
||||
"description"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "When to run"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "When the plugin should run. Good options are <code>schedule</code>"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"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 * * * *",
|
||||
"options": [],
|
||||
"localized": [
|
||||
"name",
|
||||
"description"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Schedule"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Only enabled if you select <code>schedule</code> in the <a href=\"#SYNC_RUN\"><code>SYNC_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{
|
||||
"readonly": "true"
|
||||
}
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/asuswrt_import/script.py",
|
||||
"options": [],
|
||||
"localized": [
|
||||
"name",
|
||||
"description"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Command"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Command to run. This can not be changed"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{
|
||||
"type": "number"
|
||||
}
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 30,
|
||||
"options": [],
|
||||
"localized": [
|
||||
"name",
|
||||
"description"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Run timeout"
|
||||
}
|
||||
],
|
||||
"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."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "host",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "192.168.1.1",
|
||||
"options": [],
|
||||
"localized": [
|
||||
"name",
|
||||
"description"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Router ip"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Router ip(do not include port, <code>http://</code> or <code>https://</code>)."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "user",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "admin",
|
||||
"options": [],
|
||||
"localized": [
|
||||
"name",
|
||||
"description"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Router user"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "User name used to login into your router."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "port",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": [
|
||||
"name",
|
||||
"description"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Router port"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Router port. Leave empty for default."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "password",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{
|
||||
"type": "password"
|
||||
}
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": [
|
||||
"name",
|
||||
"description"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Router password"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Password used to login into your router."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "ssl",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{
|
||||
"type": "checkbox"
|
||||
}
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": false,
|
||||
"options": [],
|
||||
"localized": [
|
||||
"name",
|
||||
"description"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Router SSL"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "If your router enforces SSL connections."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": [
|
||||
"name"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Index"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": [
|
||||
"name"
|
||||
],
|
||||
"mapped_to_column": "cur_MAC",
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "MAC address"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Dirección MAC"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "MAC Adresse"
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"show": true,
|
||||
"type": "device_mac"
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": [
|
||||
"name"
|
||||
],
|
||||
"mapped_to_column": "cur_IP",
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "IP"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "IP"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "IP"
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"show": true,
|
||||
"type": "device_ip"
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": [
|
||||
"name"
|
||||
],
|
||||
"mapped_to_column": "cur_Name",
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Hostname"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Nombre de host"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Name des Hosts"
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"show": true,
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"mapped_to_column": "cur_Vendor",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": [
|
||||
"name"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Vendor"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Proveedor"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Hersteller"
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"show": true,
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "Dummy",
|
||||
"mapped_to_column": "cur_ScanMethod",
|
||||
"mapped_to_column_data": {
|
||||
"value": "ASUSWRT"
|
||||
},
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": [
|
||||
"name"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Scan method"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": [
|
||||
"name"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Created"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": [
|
||||
"name"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Changed"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
"default_value": "",
|
||||
"options": [
|
||||
{
|
||||
"equals": "watched-not-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-square-check'></i><div></div>"
|
||||
},
|
||||
{
|
||||
"equals": "watched-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-triangle-exclamation'></i></div>"
|
||||
},
|
||||
{
|
||||
"equals": "new",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-circle-plus'></i></div>"
|
||||
},
|
||||
{
|
||||
"equals": "missing-in-last-scan",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-question'></i></div>"
|
||||
}
|
||||
],
|
||||
"localized": [
|
||||
"name"
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Status"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
108
front/plugins/asuswrt_import/script.py
Executable file
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
|
||||
INSTALL_PATH = "/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
pluginName = "ASUSWRT"
|
||||
|
||||
import asyncio
|
||||
|
||||
import aiohttp
|
||||
import conf
|
||||
from asusrouter import AsusData, AsusRouter
|
||||
from asusrouter.modules.connection import ConnectionState
|
||||
from const import logPath
|
||||
from helper import get_setting_value
|
||||
from logger import Logger, mylog
|
||||
from plugin_helper import (Plugin_Object, Plugin_Objects, decodeBase64,
|
||||
handleEmpty)
|
||||
from pytz import timezone
|
||||
|
||||
conf.tz = timezone(get_setting_value("TIMEZONE"))
|
||||
|
||||
Logger(get_setting_value("LOG_LEVEL"))
|
||||
|
||||
LOG_PATH = logPath + "/plugins"
|
||||
LOG_FILE = os.path.join(LOG_PATH, f"script.{pluginName}.log")
|
||||
RESULT_FILE = os.path.join(LOG_PATH, f"last_result.{pluginName}.log")
|
||||
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
|
||||
|
||||
def main():
|
||||
mylog("verbose", [f"[{pluginName}] started."])
|
||||
|
||||
device_data = get_device_data()
|
||||
|
||||
mylog(
|
||||
"verbose",
|
||||
[f"[{pluginName}] Found '{len(device_data)}' devices"],
|
||||
)
|
||||
|
||||
filtered_devices = [
|
||||
(key, device)
|
||||
for key, device in device_data.items()
|
||||
if device.state == ConnectionState.CONNECTED
|
||||
]
|
||||
|
||||
mylog(
|
||||
"verbose",
|
||||
[f"[{pluginName}] Processing '{len(filtered_devices)}' connected devices"],
|
||||
)
|
||||
|
||||
for mac, device in filtered_devices:
|
||||
entry_mac = str(device.description.mac).lower()
|
||||
|
||||
plugin_objects.add_object(
|
||||
primaryId=entry_mac,
|
||||
secondaryId=handleEmpty(device.connection.ip_address),
|
||||
watched1=handleEmpty(device.description.name),
|
||||
watched2=handleEmpty(device.description.vendor),
|
||||
extra=pluginName,
|
||||
foreignKey=entry_mac,
|
||||
)
|
||||
|
||||
plugin_objects.write_result_file()
|
||||
|
||||
mylog("verbose", [f"[{pluginName}] finished"])
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def get_device_data():
|
||||
# Create a new event loop
|
||||
loop = asyncio.new_event_loop()
|
||||
|
||||
# Create aiohttp session
|
||||
session = aiohttp.ClientSession(loop=loop)
|
||||
|
||||
port = get_setting_value("ASUSWRT_port").strip()
|
||||
|
||||
mylog("verbose", [f"[{pluginName}] Connecting to the Router..."])
|
||||
|
||||
router = AsusRouter( # required - both IP and URL supported
|
||||
hostname=get_setting_value("ASUSWRT_host"), # required
|
||||
port=(None if not port else port), # optional
|
||||
username=get_setting_value("ASUSWRT_user"), # required
|
||||
password=get_setting_value("ASUSWRT_password"), # required
|
||||
use_ssl=get_setting_value("ASUSWRT_ssl"), # optional
|
||||
session=session, # optional
|
||||
)
|
||||
|
||||
# Connect to the router
|
||||
# Throws an error in case of failure
|
||||
loop.run_until_complete(router.async_connect())
|
||||
|
||||
# Now you can use the router object to call methods
|
||||
clients = loop.run_until_complete(router.async_get_data(AsusData.CLIENTS))
|
||||
|
||||
# Remember to disconnect and close the session when you're done
|
||||
loop.run_until_complete(router.async_disconnect())
|
||||
loop.run_until_complete(session.close())
|
||||
|
||||
return clients
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -108,12 +108,12 @@ def execute_name_lookup(ip, timeout):
|
||||
output = ""
|
||||
|
||||
try:
|
||||
mylog('verbose', [f'[{pluginName}] DEBUG CMD :', args])
|
||||
mylog('debug', [f'[{pluginName}] DEBUG CMD :', args])
|
||||
|
||||
# Run the subprocess with a forced timeout
|
||||
output = subprocess.check_output(args, universal_newlines=True, stderr=subprocess.STDOUT, timeout=timeout)
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] DEBUG OUTPUT : {output}'])
|
||||
mylog('debug', [f'[{pluginName}] DEBUG OUTPUT : {output}'])
|
||||
|
||||
domain_name = ''
|
||||
|
||||
@@ -129,20 +129,20 @@ def execute_name_lookup(ip, timeout):
|
||||
else:
|
||||
mylog('verbose', [f'[{pluginName}] ⚠ ERROR - Unexpected output format: {line}'])
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] Domain Name: {domain_name}'])
|
||||
mylog('debug', [f'[{pluginName}] Domain Name: {domain_name}'])
|
||||
|
||||
return domain_name
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
mylog('verbose', [f'[{pluginName}] ⚠ ERROR - {e.output}'])
|
||||
mylog('none', [f'[{pluginName}] ⚠ ERROR - {e.output}'])
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
mylog('verbose', [f'[{pluginName}] TIMEOUT - the process forcefully terminated as timeout reached'])
|
||||
mylog('none', [f'[{pluginName}] TIMEOUT - the process forcefully terminated as timeout reached'])
|
||||
|
||||
if output == "":
|
||||
mylog('verbose', [f'[{pluginName}] Scan: FAIL - check logs'])
|
||||
mylog('none', [f'[{pluginName}] Scan: FAIL - check logs'])
|
||||
else:
|
||||
mylog('verbose', [f'[{pluginName}] Scan: SUCCESS'])
|
||||
mylog('debug', [f'[{pluginName}] Scan: SUCCESS'])
|
||||
|
||||
return ''
|
||||
|
||||
@@ -151,13 +151,13 @@ def ensure_avahi_running(attempt=1, max_retries=2):
|
||||
"""
|
||||
Ensure that D-Bus is running and the Avahi daemon is started, with recursive retry logic.
|
||||
"""
|
||||
mylog('verbose', [f'[{pluginName}] Attempt {attempt} - Ensuring D-Bus and Avahi daemon are running...'])
|
||||
mylog('debug', [f'[{pluginName}] Attempt {attempt} - Ensuring D-Bus and Avahi daemon are running...'])
|
||||
|
||||
# Check rc-status
|
||||
try:
|
||||
subprocess.run(['rc-status'], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
mylog('verbose', [f'[{pluginName}] ⚠ ERROR - Failed to check rc-status: {e.output}'])
|
||||
mylog('none', [f'[{pluginName}] ⚠ ERROR - Failed to check rc-status: {e.output}'])
|
||||
return
|
||||
|
||||
# Create OpenRC soft level
|
||||
@@ -167,42 +167,42 @@ def ensure_avahi_running(attempt=1, max_retries=2):
|
||||
try:
|
||||
subprocess.run(['rc-update', 'add', 'avahi-daemon'], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
mylog('verbose', [f'[{pluginName}] ⚠ ERROR - Failed to add Avahi to runlevel: {e.output}'])
|
||||
mylog('none', [f'[{pluginName}] ⚠ ERROR - Failed to add Avahi to runlevel: {e.output}'])
|
||||
return
|
||||
|
||||
# Start the D-Bus service
|
||||
try:
|
||||
subprocess.run(['rc-service', 'dbus', 'start'], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
mylog('verbose', [f'[{pluginName}] ⚠ ERROR - Failed to start D-Bus: {e.output}'])
|
||||
mylog('none', [f'[{pluginName}] ⚠ ERROR - Failed to start D-Bus: {e.output}'])
|
||||
return
|
||||
|
||||
# Check Avahi status
|
||||
status_output = subprocess.run(['rc-service', 'avahi-daemon', 'status'], capture_output=True, text=True)
|
||||
if 'started' in status_output.stdout:
|
||||
mylog('verbose', [f'[{pluginName}] Avahi Daemon is already running.'])
|
||||
mylog('debug', [f'[{pluginName}] Avahi Daemon is already running.'])
|
||||
return
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] Avahi Daemon is not running, attempting to start... (Attempt {attempt})'])
|
||||
mylog('none', [f'[{pluginName}] Avahi Daemon is not running, attempting to start... (Attempt {attempt})'])
|
||||
|
||||
# Start the Avahi daemon
|
||||
try:
|
||||
subprocess.run(['rc-service', 'avahi-daemon', 'start'], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
mylog('verbose', [f'[{pluginName}] ⚠ ERROR - Failed to start Avahi daemon: {e.output}'])
|
||||
mylog('none', [f'[{pluginName}] ⚠ ERROR - Failed to start Avahi daemon: {e.output}'])
|
||||
|
||||
# Check status after starting
|
||||
status_output = subprocess.run(['rc-service', 'avahi-daemon', 'status'], capture_output=True, text=True)
|
||||
if 'started' in status_output.stdout:
|
||||
mylog('verbose', [f'[{pluginName}] Avahi Daemon successfully started.'])
|
||||
mylog('debug', [f'[{pluginName}] Avahi Daemon successfully started.'])
|
||||
return
|
||||
|
||||
# Retry if not started and attempts are left
|
||||
if attempt < max_retries:
|
||||
mylog('verbose', [f'[{pluginName}] Retrying... ({attempt + 1}/{max_retries})'])
|
||||
mylog('debug', [f'[{pluginName}] Retrying... ({attempt + 1}/{max_retries})'])
|
||||
ensure_avahi_running(attempt + 1, max_retries)
|
||||
else:
|
||||
mylog('verbose', [f'[{pluginName}] ⚠ ERROR - Avahi Daemon failed to start after {max_retries} attempts.'])
|
||||
mylog('none', [f'[{pluginName}] ⚠ ERROR - Avahi Daemon failed to start after {max_retries} attempts.'])
|
||||
|
||||
# rc-update add avahi-daemon
|
||||
# rc-service avahi-daemon status
|
||||
|
||||