mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
Compare commits
71 Commits
v24.10.12
...
907a3e1df8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
907a3e1df8 | ||
|
|
27131af434 | ||
|
|
4d35013d3e | ||
|
|
4e481f9307 | ||
|
|
05e4de0dc8 | ||
|
|
14aa07c69b | ||
|
|
f0c90cef12 | ||
|
|
26503eaf52 | ||
|
|
c0f14e46ce | ||
|
|
439066510f | ||
|
|
500822327c | ||
|
|
ed933f91f1 | ||
|
|
bbb617ebda | ||
|
|
8b1e4635e6 | ||
|
|
44e217a924 | ||
|
|
400edd35d1 | ||
|
|
9d1fccfe29 | ||
|
|
6bad4764f6 | ||
|
|
d09bbbe73e | ||
|
|
7d0b583571 | ||
|
|
13a2e5ba26 | ||
|
|
4af9efa8f7 | ||
|
|
aa1a18015d | ||
|
|
abd2f66814 | ||
|
|
7dd77e06d4 | ||
|
|
4f859b5671 | ||
|
|
e24903a123 | ||
|
|
367a024860 | ||
|
|
987127302c | ||
|
|
8b1e732fa3 | ||
|
|
73b8ea9bfa | ||
|
|
77846df299 | ||
|
|
c91c31cfee | ||
|
|
ef2a102218 | ||
|
|
a8cc4de4d0 | ||
|
|
5f45308465 | ||
|
|
e62131b832 | ||
|
|
68fe5fffee | ||
|
|
8d198b34c4 | ||
|
|
166f700425 | ||
|
|
775f53d1d7 | ||
|
|
3c8dae5868 | ||
|
|
56f1e6adf8 | ||
|
|
12226cb899 | ||
|
|
2eb173b567 | ||
|
|
4ab8d67d76 | ||
|
|
a3aa81f369 | ||
|
|
53f798e50e | ||
|
|
eeb740f60d | ||
|
|
f3fd06725f | ||
|
|
eb16562e85 | ||
|
|
c77ae32736 | ||
|
|
7549a98877 | ||
|
|
02bf561c69 | ||
|
|
5fba247aaa | ||
|
|
cd4b556ee2 | ||
|
|
2471dfaf02 | ||
|
|
69d9584426 | ||
|
|
930f1a333e | ||
|
|
3d9bf32ec7 | ||
|
|
ff60ea82ea | ||
|
|
cb297aab8d | ||
|
|
7794380411 | ||
|
|
0c99c42b0a | ||
|
|
bb4f7616e4 | ||
|
|
1379923f30 | ||
|
|
60e9684084 | ||
|
|
2235a8cf8e | ||
|
|
15eb19fda1 | ||
|
|
3d51b1cd15 | ||
|
|
158ed324c2 |
@@ -2,7 +2,7 @@
|
||||
[](https://hub.docker.com/r/jokobsk/netalertx)
|
||||
[](https://hub.docker.com/r/jokobsk/netalertx)
|
||||
[](https://github.com/jokob-sk/NetAlertX/releases)
|
||||
[](https://discord.gg/UQnnHNYV)
|
||||
[](https://discord.gg/NczTUTWyRr)
|
||||
|
||||
# 🖧🔍 Network scanner & notification framework
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ services:
|
||||
# DELETE END anyone trying to use this file: comment out / delete ABOVE lines, they are only for development purposes
|
||||
# ---------------------------------------------------------------------------
|
||||
environment:
|
||||
# - APP_CONF_OVERRIDE={"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_dark_mode":"True"}
|
||||
# - APP_CONF_OVERRIDE={"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_theme":"Dark"}
|
||||
- TZ=${TZ}
|
||||
- PORT=${PORT}
|
||||
# ❗ DANGER ZONE BELOW - Setting ALWAYS_FRESH_INSTALL=true will delete the content of the /db & /config folders
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
[](https://hub.docker.com/r/jokobsk/netalertx)
|
||||
[](https://hub.docker.com/r/jokobsk/netalertx)
|
||||
[](https://github.com/jokob-sk/NetAlertX/releases)
|
||||
[](https://discord.gg/UQnnHNYV)
|
||||
[](https://discord.gg/NczTUTWyRr)
|
||||
|
||||
|
||||
# NetAlertX 🖧🔍 Network scanner & notification framework
|
||||
@@ -41,7 +41,7 @@ docker run -d --rm --network=host \
|
||||
| `PORT` |Port of the web interface | `20211` |
|
||||
| `LISTEN_ADDR` |Set the specific IP Address for the listener address for the nginx webserver (web interface). This could be useful when using multiple subnets to hide the web interface from all untrusted networks. | `0.0.0.0` |
|
||||
|`TZ` |Time zone to display stats correctly. Find your time zone [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) | `Europe/Berlin` |
|
||||
|`APP_CONF_OVERRIDE` | JSON override for settings, e.g. `{"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_dark_mode":"True"}` (Experimental 🧪) | `N/A` |
|
||||
|`APP_CONF_OVERRIDE` | JSON override for settings, e.g. `{"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_theme":"Dark"}` (Experimental 🧪) | `N/A` |
|
||||
|`ALWAYS_FRESH_INSTALL` | If `true` will delete the content of the `/db` & `/config` folders. For testing purposes. Can be coupled with [watchtower](https://github.com/containrrr/watchtower) to have an always freshly installed `netalertx`/`netalertx-dev` image. | `N/A` |
|
||||
|
||||
### Docker paths
|
||||
@@ -237,4 +237,4 @@ Big thanks to <a href="https://github.com/Macleykun">@Macleykun</a> & for help a
|
||||
- Bitcoin: `1N8tupjeCK12qRVU2XrV17WvKK7LCawyZM`
|
||||
- Ethereum: `0x6e2749Cb42F4411bc98501406BdcD82244e3f9C7`
|
||||
|
||||
> 📧 Email me at [jokob@duck.com](mailto:jokob@duck.com?subject=NetAlertX) if you want to get in touch or if I should add other sponsorship platforms.
|
||||
> 📧 Email me at [jokob@duck.com](mailto:jokob@duck.com?subject=NetAlertX) if you want to get in touch or if I should add other sponsorship platforms.
|
||||
|
||||
@@ -43,6 +43,10 @@ fi
|
||||
|
||||
# OVERRIDE settings: Handling APP_CONF_OVERRIDE
|
||||
# Check if APP_CONF_OVERRIDE is set
|
||||
|
||||
# remove old
|
||||
rm "${INSTALL_DIR}/config/app_conf_override.json"
|
||||
|
||||
if [ -z "$APP_CONF_OVERRIDE" ]; then
|
||||
echo "APP_CONF_OVERRIDE is not set. Skipping config file creation."
|
||||
else
|
||||
|
||||
@@ -73,7 +73,7 @@ End-result: Partial restore (historical data & configurations from the Maintenan
|
||||
|
||||
#### Recovery:
|
||||
|
||||
Even with a corrupted database you can recover what I would argue is 99% of the configuration (except of a couple of settings under Maintenance).
|
||||
Even with a corrupted database you can recover what I would argue is 99% of the configuration.
|
||||
|
||||
- map the `/config/app.conf` file as described in the [Setup documentation](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md#docker-paths).
|
||||
- rename the `devices_<timestamp>.csv` to `devices.csv` and place it in the `/config` folder
|
||||
|
||||
@@ -76,3 +76,16 @@ In the above output notice the section logging how many events are produced by t
|
||||
These values, if formatted correctly, will also show up in the UI:
|
||||
|
||||

|
||||
|
||||
|
||||
### Sharing application state
|
||||
|
||||
Sometimes specific log sections are needed to debug issues. The Devices and CurrentScan table data is sometimes needed to figure out what's wrong.
|
||||
|
||||
1. Please set `LOG_LEVEL` to `trace` (Disable it once you have the info as this produces big log files).
|
||||
2. Wait for the issue to occur.
|
||||
3. Search for `================ DEVICES table content ================` in your logs.
|
||||
4. Search for `================ CurrentScan table content ================` in your logs.
|
||||
5. Open a new issue and post (redacted) output into the issue description (or send to the netalertx@gmail.com email if sensitive data present).
|
||||
6. Please set `LOG_LEVEL` to `debug` or lower.
|
||||
|
||||
|
||||
@@ -49,6 +49,17 @@ services:
|
||||
# Other service configurations...
|
||||
```
|
||||
|
||||
## 5. Sharing application state
|
||||
|
||||
Sometimes specific log sections are needed to debug issues. The Devices and CurrentScan table data is sometimes needed to figure out what's wrong.
|
||||
|
||||
1. Please set `LOG_LEVEL` to `trace` (Disable it once you have the info as this produces big log files).
|
||||
2. Wait for the issue to occur.
|
||||
3. Search for `================ DEVICES table content ================` in your logs.
|
||||
4. Search for `================ CurrentScan table content ================` in your logs.
|
||||
5. Open a new issue and post (redacted) output into the issue description (or send to the netalertx@gmail.com email if sensitive data present).
|
||||
6. Please set `LOG_LEVEL` to `debug` or lower.
|
||||
|
||||
## 📃Common issues
|
||||
|
||||
### Permissions
|
||||
|
||||
@@ -22,3 +22,10 @@ The database cleanup plugin. Check details and related setting in the [DB Cleanu
|
||||
### Maintenance (MAINT)
|
||||
|
||||
The maintenance plugin. Check details and related setting in the [Maintenance plugin docs](/front/plugins/maintenance/README.md). Make sure the plugin is not failing by checking the logs. Try changing the schedule `MAINT_RUN_SCHD` and the timeout `MAINT_RUN_TIMEOUT` (increase) if the plugin is failing to execute.
|
||||
|
||||
## Scan frequency and coverage
|
||||
|
||||
The more often you scan the networks the more resources, traffic and DB read/write cycles are executed. Especially on busy networks and lower end hardware, consider increasing scan intervals (`<PLUGIN>_RUN_SCHD`) and timeouts (`<PLUGIN>_RUN_TIMEOUT`).
|
||||
|
||||
Also consider decreasing the scanned subnet, e.g. from `/16` to `/24` if need be.
|
||||
|
||||
|
||||
@@ -110,3 +110,21 @@ Please note the accessibility of macvlans when configured on the same computer.
|
||||
|
||||
- NetAlertX does not detect the macvlan container when it is running on the same computer.
|
||||
- NetAlertX recognizes the macvlan container when it is running on a different computer.
|
||||
|
||||
|
||||
### Wi-Fi Extenders
|
||||
|
||||
A Wi-Fi extender typically works by creating a separate network or subnet, which can cause certain network scanning tools, like `arp-scan`, to be unable to detect devices behind the extender.
|
||||
|
||||
This happens because `arp-scan` uses ARP (Address Resolution Protocol) to map IP addresses to MAC addresses on the local network. Since ARP is a Layer 2 (data link layer) protocol, it usually only works within a single broadcast domain, which is typically limited to a single router or network segment.
|
||||
|
||||
When you introduce a Wi-Fi extender, it may isolate devices on different segments of the network, meaning ARP packets cannot easily traverse from one segment (your main network) to another (the network behind the extender).
|
||||
|
||||
To scan devices behind the extender, you can try:
|
||||
|
||||
- Scanning the specific subnet that the extender uses, if it is separate from the main network.
|
||||
- Using [supplementing plugins](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md) that use alternate methods. Protocols used by the `SNMPDSC` or `DHCPLSS` plugins have good support and usually can be used as a workaround.
|
||||
|
||||
Check the [plugins list](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md) to find a plugin supported by your router and your network setup.
|
||||
|
||||
|
||||
|
||||
@@ -212,6 +212,12 @@
|
||||
{
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
background-image: url('../img/background.png');
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Customized Main Menu
|
||||
----------------------------------------------------------------------------- */
|
||||
@@ -1136,7 +1142,6 @@ input[readonly] {
|
||||
height: 200px; */
|
||||
background-color: #f3f3f3;
|
||||
border: 1px solid #ccc;
|
||||
margin: 20px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
@@ -1320,7 +1325,8 @@ input[readonly] {
|
||||
border: solid;
|
||||
border-color:cyan;
|
||||
}
|
||||
#networkTree .netStatus-Off-line i
|
||||
#networkTree .netStatus-Off-line i,
|
||||
#networkTree .netStatus-Off-line svg
|
||||
{
|
||||
color: #dd4b39;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,10 @@ html {
|
||||
background-color: #353c42;
|
||||
}
|
||||
|
||||
body {
|
||||
background-image: url('../img/boxed-bg-dark.png') !important;
|
||||
}
|
||||
|
||||
body, .bg-yellow, .callout.callout-warning, .alert-warning, .label-warning, .modal-warning .modal-body {
|
||||
|
||||
background-color: #353c42 !important;
|
||||
|
||||
21
front/css/system-dark-patch-cal.css
Executable file
21
front/css/system-dark-patch-cal.css
Executable file
@@ -0,0 +1,21 @@
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
.fc-sat {
|
||||
background-color: #444D56; }
|
||||
.fc-sun {
|
||||
background-color: #444D56; }
|
||||
.fc-today {
|
||||
background-color: #8D9AAC !important;
|
||||
border: none !important;
|
||||
}
|
||||
.fc-cell-content {
|
||||
background-color: #272c30;
|
||||
}
|
||||
.fc-widget-header {
|
||||
background-color: #353c42;
|
||||
}
|
||||
.fc-unthemed .fc-content, .fc-unthemed .fc-divider, .fc-unthemed .fc-list-heading td, .fc-unthemed .fc-list-view, .fc-unthemed .fc-popover, .fc-unthemed .fc-row, .fc-unthemed tbody, .fc-unthemed td, .fc-unthemed th, .fc-unthemed thead{
|
||||
border-color: #353c42 !important;
|
||||
}
|
||||
|
||||
}
|
||||
737
front/css/system-dark-patch.css
Executable file
737
front/css/system-dark-patch.css
Executable file
@@ -0,0 +1,737 @@
|
||||
/* Pi-hole: A black hole for Internet advertisements
|
||||
* (c) 2020 Pi-hole, LLC (https://pi-hole.net)
|
||||
* Network-wide ad blocking via your own hardware.
|
||||
*
|
||||
* This file is copyright under the latest version of the EUPL.
|
||||
* Please see LICENSE file for your rights under this license.
|
||||
*
|
||||
* The colors used in this theme has been inspired by
|
||||
* https://github.com/anvyst/adminlte-skin-midnight
|
||||
*
|
||||
* Additional fixes For Pi.Alert UI by leiweibau */
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
:root {
|
||||
--datatable-bgcolor: rgba(64, 76, 88, 0.8);
|
||||
}
|
||||
html {
|
||||
background-color: #353c42;
|
||||
}
|
||||
|
||||
body {
|
||||
background-image: url('../img/boxed-bg-dark.png') !important;
|
||||
}
|
||||
|
||||
body, .bg-yellow, .callout.callout-warning, .alert-warning, .label-warning, .modal-warning .modal-body {
|
||||
|
||||
background-color: #353c42 !important;
|
||||
color: #bec5cb !important;
|
||||
}
|
||||
h4 {
|
||||
color: #44def1;
|
||||
}
|
||||
.content-header > .breadcrumb > li > a {
|
||||
color: #bec5cb;
|
||||
}
|
||||
.table > thead > tr > th,
|
||||
.table > tbody > tr > th,
|
||||
.table > tfoot > tr > th,
|
||||
.table > thead > tr > td,
|
||||
.table > tbody > tr > td,
|
||||
.table > tfoot > tr > td {
|
||||
border-top: 0;
|
||||
}
|
||||
.table > thead > tr.odd,
|
||||
.table > tbody > tr.odd,
|
||||
.table > tfoot > tr.odd {
|
||||
background-color: #2a2f34;
|
||||
}
|
||||
.table > thead > tr.odd:hover,
|
||||
.table > tbody > tr.odd:hover,
|
||||
.table > tfoot > tr.odd:hover,
|
||||
.table > thead > tr.even:hover,
|
||||
.table > tbody > tr.even:hover,
|
||||
.table > tfoot > tr.even:hover {
|
||||
background-color: #1e2226;
|
||||
}
|
||||
.table-bordered,
|
||||
.table-bordered > thead > tr > th,
|
||||
.table-bordered > tbody > tr > th,
|
||||
.table-bordered > tfoot > tr > th,
|
||||
.table-bordered > thead > tr > td,
|
||||
.table-bordered > tbody > tr > td,
|
||||
.table-bordered > tfoot > tr > td {
|
||||
border: 1px solid #353c42;
|
||||
}
|
||||
.dataTables_wrapper input[type="search"] {
|
||||
border-radius: 4px;
|
||||
background-color: #353c42;
|
||||
border: 0;
|
||||
color: #bec5cb;
|
||||
}
|
||||
.dataTables_paginate .pagination li > a {
|
||||
background-color: #353c42;
|
||||
border-color: #353c42;
|
||||
}
|
||||
.pagination > .disabled > a,
|
||||
.pagination > .disabled > a:focus,
|
||||
.pagination > .disabled > a:hover,
|
||||
.pagination > .disabled > span,
|
||||
.pagination > .disabled > span:focus,
|
||||
.pagination > .disabled > span:hover {
|
||||
cursor: not-allowed;
|
||||
color: #bec5cb;
|
||||
background-color: #353c42;
|
||||
border-color: #353c42;
|
||||
}
|
||||
.pagination > li > a:focus,
|
||||
.pagination > li > a:hover,
|
||||
.pagination > li > span:focus,
|
||||
.pagination > li > span:hover {
|
||||
z-index: 2;
|
||||
color: #bec5cb;
|
||||
background-color: #54606b;
|
||||
border-color: #54606b;
|
||||
}
|
||||
.wrapper,
|
||||
.main-sidebar,
|
||||
.left-side {
|
||||
background-color: #272c30;
|
||||
}
|
||||
.user-panel > .info,
|
||||
.user-panel > .info > a {
|
||||
color: #fff;
|
||||
}
|
||||
.sidebar-menu > li.header {
|
||||
color: #556068;
|
||||
background-color: #1e2225;
|
||||
}
|
||||
.sidebar-menu > li > a {
|
||||
border-left: 3px solid transparent;
|
||||
}
|
||||
.sidebar-menu > li:hover > a,
|
||||
.sidebar-menu > li > a:focus,
|
||||
.sidebar-menu > li.active > a {
|
||||
color: #fff;
|
||||
background-color: #22272a;
|
||||
border-color: #3c8dbc;
|
||||
}
|
||||
.sidebar-menu > li > .treeview-menu {
|
||||
margin: 0 1px;
|
||||
background-color: #32393e;
|
||||
}
|
||||
.sidebar a {
|
||||
color: #bec5cb;
|
||||
}
|
||||
.sidebar a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
.treeview-menu > li > a {
|
||||
color: #949fa8;
|
||||
}
|
||||
.treeview-menu > li.active > a,
|
||||
.treeview-menu > li > a:hover,
|
||||
.treeview-menu > li > a:focus {
|
||||
color: #fff;
|
||||
}
|
||||
.sidebar-form {
|
||||
border-radius: 3px;
|
||||
border: 1px solid #3e464c;
|
||||
margin: 10px;
|
||||
}
|
||||
.sidebar-form input[type="text"],
|
||||
.sidebar-form .btn {
|
||||
box-shadow: none;
|
||||
background-color: #3e464c;
|
||||
border: 1px solid transparent;
|
||||
height: 35px;
|
||||
}
|
||||
.sidebar-form input[type="text"] {
|
||||
color: #666;
|
||||
border-top-left-radius: 2px;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 2px;
|
||||
}
|
||||
.sidebar-form input[type="text"]:focus,
|
||||
.sidebar-form input[type="text"]:focus + .input-group-btn .btn {
|
||||
background-color: #fff;
|
||||
color: #666;
|
||||
}
|
||||
.sidebar-form input[type="text"]:focus + .input-group-btn .btn {
|
||||
border-left-color: #fff;
|
||||
}
|
||||
.sidebar-form .btn {
|
||||
color: #999;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
.box,
|
||||
.box-footer,
|
||||
.info-box,
|
||||
.box-comment,
|
||||
.comment-text,
|
||||
.comment-text .username {
|
||||
color: #bec5cb;
|
||||
background-color: #272c30;
|
||||
}
|
||||
.box-comments .box-comment {
|
||||
border-bottom-color: #353c42;
|
||||
}
|
||||
.box-footer {
|
||||
border-top: 1px solid #353c42;
|
||||
}
|
||||
.box-header.with-border {
|
||||
border-bottom: 1px solid #353c42;
|
||||
}
|
||||
.box-solid,
|
||||
.box {
|
||||
border: 1px solid #272c30;
|
||||
}
|
||||
.box-solid > .box-header,
|
||||
.box > .box-header {
|
||||
color: #bec5cb;
|
||||
}
|
||||
.box-solid > .box-header .btn,
|
||||
.box > .box-header .btn {
|
||||
color: #bec5cb;
|
||||
}
|
||||
.box.box-info,
|
||||
.box.box-primary,
|
||||
.box.box-success,
|
||||
.box.box-warning,
|
||||
.box.box-danger {
|
||||
border-top-width: 3px;
|
||||
}
|
||||
.main-header .navbar {
|
||||
background-color: #272c30;
|
||||
}
|
||||
.main-header .navbar .nav > li > a,
|
||||
.main-header .navbar .nav > li > .navbar-text {
|
||||
color: #bec5cb;
|
||||
max-height: 50px;
|
||||
}
|
||||
.main-header .navbar .nav > li > a:hover,
|
||||
.main-header .navbar .nav > li > a:active,
|
||||
.main-header .navbar .nav > li > a:focus,
|
||||
.main-header .navbar .nav .open > a,
|
||||
.main-header .navbar .nav .open > a:hover,
|
||||
.main-header .navbar .nav .open > a:focus,
|
||||
.main-header .navbar .nav > .active > a {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
color: #f6f6f6;
|
||||
}
|
||||
.main-header .navbar .sidebar-toggle {
|
||||
color: #bec5cb;
|
||||
}
|
||||
.main-header .navbar .sidebar-toggle:hover {
|
||||
color: #f6f6f6;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.timeline li .timeline-item {
|
||||
color: #bec5cb;
|
||||
background-color: #272c30;
|
||||
border-color: #353c42;
|
||||
}
|
||||
.timeline li .timeline-header {
|
||||
border-bottom-color: #353c42;
|
||||
}
|
||||
.nav-stacked > li > a {
|
||||
color: #bec5cb;
|
||||
}
|
||||
.nav-stacked > li > a:hover {
|
||||
color: white;
|
||||
background-color: #1e2226;
|
||||
}
|
||||
.content-wrapper,
|
||||
.right-side {
|
||||
background-color: #353c42;
|
||||
}
|
||||
.main-footer,
|
||||
.nav-tabs-custom {
|
||||
background-color: #272c30;
|
||||
border-top-color: #353c42;
|
||||
color: #bec5cb;
|
||||
}
|
||||
.main-footer .nav-tabs,
|
||||
.nav-tabs-custom .nav-tabs {
|
||||
background-color: #30383f;
|
||||
border-bottom-color: #2f363b;
|
||||
}
|
||||
.main-footer .tab-content,
|
||||
.nav-tabs-custom .tab-content {
|
||||
background-color: #30383f;
|
||||
}
|
||||
.nav-tabs-custom > .nav-tabs {
|
||||
background: rgba(64, 72, 80, 0.666);
|
||||
}
|
||||
.nav-tabs-custom > .nav-tabs > li {
|
||||
margin-right: 1px;
|
||||
color: #bec5cb;
|
||||
}
|
||||
.nav-tabs-custom > .nav-tabs > li.active > a,
|
||||
.nav-tabs-custom > .nav-tabs > li.active:hover > a {
|
||||
border-left-color: #30383f;
|
||||
border-right-color: #30383f;
|
||||
background-color: #30383f;
|
||||
color: #bec5cb;
|
||||
}
|
||||
.nav-tabs-custom > .nav-tabs > li:not(.active):hover {
|
||||
border-top-color: #d2d6de;
|
||||
background-color: transparent;
|
||||
}
|
||||
.nav-tabs-custom > .nav-tabs > li > a {
|
||||
color: #8e959b;
|
||||
}
|
||||
.nav-tabs-custom > .nav-tabs > li > a:focus {
|
||||
color: #3c8dbc;
|
||||
}
|
||||
.nav-tabs-custom > .nav-tabs > li:hover > a,
|
||||
.nav-tabs-custom > .nav-tabs > li.active:hover > a {
|
||||
background-color: #353c42;
|
||||
color: #bec5cb;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
color: #bec5cb;
|
||||
background-color: #272c30;
|
||||
}
|
||||
.list-group .list-group-item {
|
||||
border-color: #353c42;
|
||||
background-color: #272c30;
|
||||
}
|
||||
.input-group .input-group-addon {
|
||||
border-right: 1px solid #272c30;
|
||||
}
|
||||
.select2 .select2-selection {
|
||||
background-color: #353c42;
|
||||
color: #bec5cb;
|
||||
border: 1px solid #353c42;
|
||||
}
|
||||
.select2 .select2-selection .select2-container--default,
|
||||
.select2 .select2-selection .select2-selection--single,
|
||||
.select2 .select2-selection .select2-selection--multiple,
|
||||
.select2 .select2-selection .select2-selection__rendered {
|
||||
color: #bec5cb;
|
||||
}
|
||||
.select2-dropdown {
|
||||
background-color: #353c42;
|
||||
color: #bec5cb;
|
||||
border: 1px solid #353c42;
|
||||
}
|
||||
.select2-dropdown .select2-search__field {
|
||||
background-color: #272c30;
|
||||
color: #bec5cb;
|
||||
border: 1px solid #353c42;
|
||||
}
|
||||
.select2-container--default.select2-container--open {
|
||||
background-color: #272c30;
|
||||
}
|
||||
|
||||
.layout-boxed {
|
||||
background: url("../../img/boxed-bg-dark.png") repeat fixed;
|
||||
}
|
||||
.not-used {
|
||||
background-color: #eee;
|
||||
}
|
||||
.not-used:hover {
|
||||
background-color: #c5c5c5;
|
||||
}
|
||||
.used {
|
||||
background-color: #fff;
|
||||
}
|
||||
.used:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.graphs-grid {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
.graphs-ticks {
|
||||
color: #b8c7ce;
|
||||
}
|
||||
.queries-permitted {
|
||||
background-color: #00a65a;
|
||||
}
|
||||
.queries-blocked {
|
||||
background-color: #999;
|
||||
}
|
||||
.progress {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
.bg-green {
|
||||
background-color: #005c32 !important;
|
||||
}
|
||||
.bg-aqua {
|
||||
background-color: #007997 !important;
|
||||
}
|
||||
.bg-yellow {
|
||||
background-color: #b1720c !important;
|
||||
}
|
||||
.bg-red {
|
||||
background-color: #913225 !important;
|
||||
}
|
||||
|
||||
code,
|
||||
pre {
|
||||
padding: 2px 4px;
|
||||
font-size: 90%;
|
||||
color: #bec5cb;
|
||||
background-color: #353c42;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Used in the Query Log table */
|
||||
.text-green-light {
|
||||
color: #5ca314 !important;
|
||||
}
|
||||
.text-green {
|
||||
color: #00aa60 !important;
|
||||
}
|
||||
.text-orange {
|
||||
color: #b1720c !important;
|
||||
}
|
||||
.text-red {
|
||||
color: #bd2c19 !important;
|
||||
}
|
||||
.text-vivid-blue {
|
||||
color: #007997 !important;
|
||||
}
|
||||
td.highlight {
|
||||
background-color: rgba(255, 204, 0, 0.333);
|
||||
}
|
||||
.btn-default {
|
||||
box-shadow: none;
|
||||
background-color: #3e464c;
|
||||
color: #bec5cb;
|
||||
border: 1px solid #353c42;
|
||||
}
|
||||
|
||||
/* Used in debug log page */
|
||||
.log-red {
|
||||
color: #ff4038;
|
||||
}
|
||||
.log-green {
|
||||
color: #4c4;
|
||||
}
|
||||
.log-yellow {
|
||||
color: #fb0;
|
||||
}
|
||||
.log-blue {
|
||||
color: #48f;
|
||||
}
|
||||
.log-purple {
|
||||
color: #b8e;
|
||||
}
|
||||
.log-cyan {
|
||||
color: #0df;
|
||||
}
|
||||
.log-gray {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
#output {
|
||||
border-color: #505458;
|
||||
background: #272c30;
|
||||
}
|
||||
|
||||
/* Used by the long-term pages */
|
||||
.daterangepicker {
|
||||
background-color: #3e464c;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #353c42;
|
||||
}
|
||||
.daterangepicker .ranges li:hover {
|
||||
background-color: #353c42;
|
||||
}
|
||||
.daterangepicker .ranges li.active {
|
||||
background-color: #1e2226; /* Color also used in table pagination */
|
||||
}
|
||||
.daterangepicker .calendar-table {
|
||||
background-color: #3e464c;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #353c42;
|
||||
}
|
||||
.daterangepicker td.off,
|
||||
.daterangepicker td.off.in-range,
|
||||
.daterangepicker td.off.start-date,
|
||||
.daterangepicker td.off.end-date {
|
||||
background-color: #485158;
|
||||
}
|
||||
.daterangepicker td.available:hover,
|
||||
.daterangepicker th.available:hover {
|
||||
background-color: #1e2226;
|
||||
}
|
||||
.daterangepicker td.active,
|
||||
.daterangepicker td.active:hover,
|
||||
.daterangepicker td.in-range:hover {
|
||||
background-color: #225e92;
|
||||
}
|
||||
.daterangepicker td.in-range {
|
||||
background-color: #1e2226;
|
||||
color: #bec5cb;
|
||||
}
|
||||
input,
|
||||
select,
|
||||
select.form-control,
|
||||
.form-group .input-group-addon,
|
||||
.input-group .input-group-addon,
|
||||
.form-group input,
|
||||
.input-group input,
|
||||
.form-group textarea,
|
||||
.input-group textarea,
|
||||
.daterangepicker select.hourselect,
|
||||
.daterangepicker select.minuteselect,
|
||||
.daterangepicker select.secondselect,
|
||||
.daterangepicker select.ampmselect,
|
||||
.form-control,
|
||||
div.dataTables_wrapper div.dataTables_length select {
|
||||
background-color: #353c42;
|
||||
color: #bec5cb;
|
||||
border: 1px solid #3d444b;
|
||||
}
|
||||
.form-control[disabled],
|
||||
.form-control[readonly],
|
||||
fieldset[disabled] .form-control {
|
||||
background-color: #353c42;
|
||||
opacity: 1;
|
||||
}
|
||||
.navbar-custom-menu > .navbar-nav > li > .dropdown-menu {
|
||||
background-color: #4c5761;
|
||||
color: #bec5cb;
|
||||
border: 1px solid #171c20;
|
||||
}
|
||||
.table-striped > tbody > tr:nth-of-type(2n + 1) {
|
||||
background-color: #2d343a;
|
||||
}
|
||||
.panel,
|
||||
.panel-body,
|
||||
.panel-default > .panel-heading {
|
||||
background-color: #3e464c;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #353c42;
|
||||
color: #bec5cb;
|
||||
}
|
||||
.box.box-solid.box-info,
|
||||
.box.box-solid.box-info > .box-header {
|
||||
color: #bec5cb;
|
||||
background-color: #367fa9 !important;
|
||||
border: 1px solid #367fa9;
|
||||
}
|
||||
input[type="password"]::-webkit-credentials-auto-fill-button {
|
||||
background: #bfc5ca;
|
||||
}
|
||||
input[type="password"]::-webkit-caps-lock-indicator {
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
.network-never {
|
||||
background-color: #661b02;
|
||||
}
|
||||
.network-recent {
|
||||
background-color: #114100;
|
||||
}
|
||||
.network-old {
|
||||
background-color: #525200;
|
||||
}
|
||||
.network-older {
|
||||
background-color: #502b00;
|
||||
}
|
||||
.network-gradient {
|
||||
background-image: linear-gradient(to right, #114100 0%, #525200 100%);
|
||||
}
|
||||
|
||||
.icheckbox_polaris,
|
||||
.icheckbox_futurico,
|
||||
.icheckbox_minimal-blue {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.iradio_polaris,
|
||||
.iradio_futurico,
|
||||
.iradio_minimal-blue {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* Overlay box with spinners as shown during data collection for graphs */
|
||||
.box .overlay,
|
||||
.overlay-wrapper .overlay {
|
||||
z-index: 50;
|
||||
background-color: rgba(53, 60, 66, 0.733);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.box .overlay > .fa,
|
||||
.overlay-wrapper .overlay > .fa,
|
||||
.navbar-nav > .user-menu > .dropdown-menu > .user-body a {
|
||||
color: #bec5cb !important;
|
||||
}
|
||||
|
||||
.navbar-nav > .user-menu > .dropdown-menu > .user-footer {
|
||||
background-color: #353c42bb;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background: #272c30;
|
||||
}
|
||||
.modal-header {
|
||||
border-bottom-color: #353c42;
|
||||
}
|
||||
.modal-footer {
|
||||
border-top-color: #353c42;
|
||||
}
|
||||
.close {
|
||||
color: #383838;
|
||||
}
|
||||
|
||||
/*** Fix login input visual misalignment ***/
|
||||
#loginform,
|
||||
#loginform input {
|
||||
color: rgb(120, 127, 133);
|
||||
}
|
||||
|
||||
.login-options input,
|
||||
.login-options [class*="icheck-"] > input:first-child + input[type="hidden"] + label::before,
|
||||
.login-options [class*="icheck-"] > input:first-child + label::before {
|
||||
background: none;
|
||||
border-color: rgb(120, 127, 133);
|
||||
}
|
||||
|
||||
/*** Additional fixes For Pi.Alert UI ***/
|
||||
.small-box {
|
||||
border-radius: 10px;
|
||||
border-top: 0px;
|
||||
}
|
||||
.pa-small-box-aqua .inner {
|
||||
background-color: rgb(45,108,133);
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
}
|
||||
.pa-small-box-green .inner {
|
||||
background-color: rgb(31,76,46);
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
}
|
||||
.pa-small-box-yellow .inner {
|
||||
background-color: rgb(151,104,37);
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
}
|
||||
.pa-small-box-red .inner {
|
||||
background-color: rgb(120,50,38);
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
}
|
||||
.pa-small-box-gray .inner {
|
||||
background-color: #777;
|
||||
/* color: rgba(20,20,20,30%); */
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
}
|
||||
.pa-small-box-gray .inner h3 {
|
||||
color: #bbb;
|
||||
}
|
||||
.text-gray-20 {
|
||||
color: rgba(220,220,220,30%);
|
||||
}
|
||||
.bg-gray {
|
||||
background-color: #888888 !important;
|
||||
}
|
||||
.badge.bg-green {
|
||||
background-color: #00A000 !important;
|
||||
}
|
||||
.badge.bg-gray {
|
||||
background-color: #888 !important;
|
||||
}
|
||||
#txtRecord {
|
||||
background-color: #353c42;
|
||||
border-color: #888888;
|
||||
}
|
||||
.table-hover tbody tr:hover td, .table-hover tbody tr:hover th {
|
||||
background-color: rgb(189,192,198);
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.db_info_table_cell:nth-child(1) {background: #272c30}
|
||||
.db_info_table_cell:nth-child(2) {background: #272c30}
|
||||
.db_tools_table_cell_a:nth-child(1) {background: #272c30}
|
||||
.db_tools_table_cell_a:nth-child(2) {background: #272c30}
|
||||
.db_tools_table_cell_b:nth-child(1) {background: #272c30}
|
||||
.db_tools_table_cell_b:nth-child(2) {background: #272c30}
|
||||
|
||||
.db_info_table {
|
||||
display: table;
|
||||
border-spacing: 0em;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.nav-tabs-custom > .nav-tabs > li:hover > a, .nav-tabs-custom > .nav-tabs > li.active:hover > a {
|
||||
background-color: #272c30;
|
||||
color: #bec5cb;
|
||||
}
|
||||
|
||||
.nav-tabs-custom > .nav-tabs > li.active > a, .nav-tabs-custom > .nav-tabs > li.active:hover > a {
|
||||
border-left-color: #30383f;
|
||||
border-right-color: #30383f;
|
||||
background-color: #272c30;
|
||||
color: #bec5cb;
|
||||
}
|
||||
.nav-tabs-custom > .nav-tabs {
|
||||
background-color: #353c42;
|
||||
}
|
||||
.nav-tabs-custom .tab-content {
|
||||
background-color: #272c30;
|
||||
}
|
||||
.top_small_box_gray_text {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
/* remove white border that appears on mobile screen sizes */
|
||||
.box-body {
|
||||
border: 0px;
|
||||
}
|
||||
/* remove white border that appears on mobile screen sizes */
|
||||
.table-responsive {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.login-page {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.login-logo a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.login-box-body {
|
||||
color: #bec5cb;
|
||||
background-color: #272c30;
|
||||
}
|
||||
/* Add border radius to bottom of the status boxes*/
|
||||
.pa-small-box-footer {
|
||||
border-bottom-left-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
}
|
||||
|
||||
.small-box > .inner h3, .small-box > .inner p {
|
||||
margin-bottom: 0px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
.small-box:hover .icon {
|
||||
font-size: 3.74em;
|
||||
}
|
||||
.small-box .icon {
|
||||
top: 0.01em;
|
||||
font-size: 3.25em;
|
||||
}
|
||||
.pa_semitransparent-panel{
|
||||
background-color: #000 !important;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -641,8 +641,14 @@
|
||||
|
||||
<!-- Dark-Mode Patch -->
|
||||
<?php
|
||||
if ($ENABLED_DARKMODE === True) {
|
||||
echo '<link rel="stylesheet" href="css/dark-patch-cal.css">';
|
||||
switch ($UI_THEME) {
|
||||
case "Dark":
|
||||
echo '<link rel="stylesheet" href="css/dark-patch-cal.css">';
|
||||
break;
|
||||
case "System":
|
||||
echo '<link rel="stylesheet" href="css/system-dark-patch-cal.css">';
|
||||
break;
|
||||
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
@@ -456,7 +456,8 @@ function initializeDatatable (status) {
|
||||
item.dev_GUID || "",
|
||||
item.dev_SyncHubNodeName || "",
|
||||
item.dev_NetworkSite || "",
|
||||
item.dev_SSID || ""
|
||||
item.dev_SSID || "",
|
||||
item.dev_SourcePlugin || ""
|
||||
];
|
||||
|
||||
var newRow = [];
|
||||
@@ -544,15 +545,33 @@ function initializeDatatable (status) {
|
||||
}
|
||||
} },
|
||||
|
||||
// IP address
|
||||
// IP address
|
||||
{targets: [mapIndx(8)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
if (!emptyArr.includes(cellData)){
|
||||
$(td).html (`<span class="anonymizeIp">
|
||||
<a href="http://${cellData}" class="pointer" target="_blank">
|
||||
${cellData}
|
||||
</a>
|
||||
<a href="https://${cellData}" class="pointer" target="_blank">
|
||||
<i class="fa fa-lock "></i>
|
||||
</a>
|
||||
<span>`);
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
}
|
||||
},
|
||||
// IP address (ordeable)
|
||||
{targets: [mapIndx(12)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
if (!emptyArr.includes(cellData)){
|
||||
$(td).html ('<span class="anonymizeIp">'+cellData+'</span>');
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
} },
|
||||
if (!emptyArr.includes(cellData)){
|
||||
$(td).html (`<span class="anonymizeIp">${cellData}<span>`);
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Favorite
|
||||
{targets: [mapIndx(4)],
|
||||
|
||||
@@ -103,10 +103,14 @@ if (isset ($_SESSION["login"]) == FALSE || $_SESSION["login"] != 1)
|
||||
|
||||
<!-- Dark-Mode Patch -->
|
||||
<?php
|
||||
if ($ENABLED_DARKMODE === True) {
|
||||
echo '<link rel="stylesheet" href="css/dark-patch.css">';
|
||||
$BACKGROUND_IMAGE_PATCH='style="background-image: url(\'img/boxed-bg-dark.png\');"';
|
||||
} else { $BACKGROUND_IMAGE_PATCH='style="background-image: url(\'img/background.png\');"';}
|
||||
switch ($UI_THEME) {
|
||||
case "Dark":
|
||||
echo '<link rel="stylesheet" href="css/dark-patch.css">';
|
||||
break;
|
||||
case "System":
|
||||
echo '<link rel="stylesheet" href="css/system-dark-patch.css">';
|
||||
break;
|
||||
}
|
||||
?>
|
||||
<link rel="stylesheet" href="/css/offline-font.css">
|
||||
</head>
|
||||
|
||||
@@ -1186,20 +1186,24 @@ function hideUIelements(settingKey) {
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// apply dark mode
|
||||
// apply theme
|
||||
|
||||
$(document).ready(function() {
|
||||
// Assume getSetting is a function that returns true or false for dark mode
|
||||
if (getSetting("UI_dark_mode") === "True") {
|
||||
// Add the dark mode stylesheet
|
||||
setCookie("UI_dark_mode", "True")
|
||||
$('head').append('<link rel="stylesheet" href="css/dark-patch.css">');
|
||||
// Set the background image for dark mode
|
||||
$('body').attr('style', 'background-image: url(\'img/boxed-bg-dark.png\');');
|
||||
let theme = getSetting("UI_theme");
|
||||
if (theme) {
|
||||
theme = theme.replace("['","").replace("']","");
|
||||
// Add the theme stylesheet
|
||||
setCookie("UI_theme", theme);
|
||||
switch(theme) {
|
||||
case "Dark":
|
||||
$('head').append('<link rel="stylesheet" href="css/dark-patch.css">');
|
||||
break;
|
||||
case "System":
|
||||
$('head').append('<link rel="stylesheet" href="css/system-dark-patch.css">');
|
||||
break
|
||||
}
|
||||
} else {
|
||||
setCookie("UI_dark_mode", "False")
|
||||
// Set the background image for light mode
|
||||
$('body').attr('style', 'background-image: url(\'img/background.png\');');
|
||||
setCookie("UI_theme", "Light");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -67,6 +67,35 @@ function initDeviceSelectors(devicesListAll_JSON) {
|
||||
}, 10);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Utility function to generate a random API token in the format t_<random string of specified length>
|
||||
function generateApiToken(elem, length) {
|
||||
// Retrieve and parse custom parameters from the element
|
||||
let params = $(elem).attr("my-customparams")?.split(',').map(param => param.trim());
|
||||
if (params && params.length >= 1) {
|
||||
var targetElementID = params[0]; // Get the target element's ID
|
||||
}
|
||||
|
||||
let targetElement = $('#' + targetElementID);
|
||||
|
||||
// Function to generate a random string of a specified length
|
||||
function generateRandomString(len) {
|
||||
let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let result = '';
|
||||
for (let i = 0; i < len; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * characters.length));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Generate the token in the format t_<random string of length>
|
||||
let randomToken = 't_' + generateRandomString(length);
|
||||
|
||||
// Set the generated token as the value of the target element
|
||||
if (targetElement.length) {
|
||||
targetElement.val(randomToken);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------
|
||||
// Updates the icon preview
|
||||
|
||||
@@ -525,53 +525,57 @@
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
function getChildren(node, list, path)
|
||||
// Recursively get children nodes and build a tree
|
||||
function getChildren(node, list, path, visited = [])
|
||||
{
|
||||
var children = [];
|
||||
|
||||
// loop thru all items and find childern...
|
||||
for(var i in list)
|
||||
{
|
||||
//... of the current node
|
||||
|
||||
if(list[i].parentMac.toLowerCase() == node.mac.toLowerCase() && !hiddenMacs.includes(list[i].parentMac))
|
||||
{
|
||||
|
||||
visibleNodesCount++
|
||||
|
||||
// and process them
|
||||
children.push(getChildren(list[i], list, path + ((path == "") ? "" : '|') + list[i].parentMac, hiddenMacs))
|
||||
var children = [];
|
||||
|
||||
// Check for infinite recursion by seeing if the node has been visited before
|
||||
if (visited.includes(node.mac.toLowerCase())) {
|
||||
console.error("Infinite recursion detected at node:", node.mac);
|
||||
write_notification("[ERROR] ⚠ Infinite recursion detected. You probably have assigned the Internet node to another children node or to itself. Please open a new issue on GitHub and describe how you did it.", 'interrupt')
|
||||
return { error: "Infinite recursion detected", node: node.mac };
|
||||
}
|
||||
}
|
||||
|
||||
// note the total number of leaf nodes to calculate the font scaling
|
||||
if(children.length == 0)
|
||||
{
|
||||
leafNodesCount++
|
||||
} else
|
||||
{
|
||||
parentNodesCount++
|
||||
}
|
||||
|
||||
return {
|
||||
name: node.name,
|
||||
path: path,
|
||||
mac: node.mac,
|
||||
port: node.port,
|
||||
id: node.mac,
|
||||
parentMac: node.parentMac,
|
||||
icon: node.icon,
|
||||
type: node.type,
|
||||
status: node.status,
|
||||
hasChildren: children.length > 0 || hiddenMacs.includes(node.mac),
|
||||
hiddenChildren: hiddenMacs.includes(node.mac),
|
||||
qty: children.length,
|
||||
children: children
|
||||
};
|
||||
|
||||
// Add current node to visited list
|
||||
visited.push(node.mac.toLowerCase());
|
||||
|
||||
// Loop through all items to find children of the current node
|
||||
for (var i in list) {
|
||||
if (list[i].parentMac.toLowerCase() == node.mac.toLowerCase() && !hiddenMacs.includes(list[i].parentMac)) {
|
||||
|
||||
visibleNodesCount++;
|
||||
|
||||
// Process children recursively, passing a copy of the visited list
|
||||
children.push(getChildren(list[i], list, path + ((path == "") ? "" : '|') + list[i].parentMac, visited));
|
||||
}
|
||||
}
|
||||
|
||||
// Track leaf and parent node counts
|
||||
if (children.length == 0) {
|
||||
leafNodesCount++;
|
||||
} else {
|
||||
parentNodesCount++;
|
||||
}
|
||||
|
||||
return {
|
||||
name: node.name,
|
||||
path: path,
|
||||
mac: node.mac,
|
||||
port: node.port,
|
||||
id: node.mac,
|
||||
parentMac: node.parentMac,
|
||||
icon: node.icon,
|
||||
type: node.type,
|
||||
status: node.status,
|
||||
hasChildren: children.length > 0 || hiddenMacs.includes(node.mac),
|
||||
hiddenChildren: hiddenMacs.includes(node.mac),
|
||||
qty: children.length,
|
||||
children: children
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function getHierarchy()
|
||||
|
||||
@@ -620,7 +620,8 @@ function getDevicesList() {
|
||||
array("dev_GUID", 19, 19),
|
||||
array("dev_SyncHubNodeName", 20, 20),
|
||||
array("dev_NetworkSite", 21, 21),
|
||||
array("dev_SSID", 22, 22)
|
||||
array("dev_SSID", 22, 22),
|
||||
array("dev_SourcePlugin", 23, 23)
|
||||
);
|
||||
|
||||
if($forceDefaultOrder == FALSE)
|
||||
@@ -693,7 +694,8 @@ function getDevicesList() {
|
||||
handleNull($row['dev_GUID']),
|
||||
handleNull($row['dev_SyncHubNodeName']),
|
||||
handleNull($row['dev_NetworkSite']),
|
||||
handleNull($row['dev_SSID'])
|
||||
handleNull($row['dev_SSID']),
|
||||
handleNull($row['dev_SourcePlugin'])
|
||||
);
|
||||
|
||||
$newOrder = array();
|
||||
|
||||
@@ -576,7 +576,8 @@ function getDevicesColumns(){
|
||||
"dev_GUID",
|
||||
"dev_SyncHubNodeName",
|
||||
"dev_NetworkSite",
|
||||
"dev_SSID"
|
||||
"dev_SSID",
|
||||
"dev_SourcePlugin"
|
||||
];
|
||||
|
||||
return $columns;
|
||||
|
||||
@@ -73,10 +73,14 @@
|
||||
<!-- Dark-Mode Patch -->
|
||||
|
||||
<?php
|
||||
if ($ENABLED_DARKMODE === True) {
|
||||
echo '<link rel="stylesheet" href="css/dark-patch.css">';
|
||||
$BACKGROUND_IMAGE_PATCH='style="background-image: url(\'img/boxed-bg-dark.png\');"';
|
||||
} else { $BACKGROUND_IMAGE_PATCH='style="background-image: url(\'img/background.png\');"';}
|
||||
switch ($UI_THEME) {
|
||||
case "Dark":
|
||||
echo '<link rel="stylesheet" href="css/dark-patch.css">';
|
||||
break;
|
||||
case "System":
|
||||
echo '<link rel="stylesheet" href="css/system-dark-patch.css">';
|
||||
break;
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
@@ -114,7 +118,7 @@
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<!-- Layout Boxed Yellow -->
|
||||
|
||||
<body class="hold-transition fixed <?php echo $pia_skin_selected;?> sidebar-mini" <?php echo $BACKGROUND_IMAGE_PATCH;?> onLoad="show_pia_servertime();" >
|
||||
<body class="hold-transition fixed <?php echo $pia_skin_selected;?> sidebar-mini" onLoad="show_pia_servertime();" >
|
||||
<!-- Site wrapper -->
|
||||
<div class="wrapper">
|
||||
|
||||
|
||||
@@ -217,6 +217,7 @@
|
||||
"Device_TableHead_RowID": "",
|
||||
"Device_TableHead_Rowid": "",
|
||||
"Device_TableHead_SSID": "",
|
||||
"Device_TableHead_SourcePlugin": "",
|
||||
"Device_TableHead_Status": "",
|
||||
"Device_TableHead_SyncHubNodeName": "",
|
||||
"Device_TableHead_Type": "",
|
||||
@@ -284,6 +285,7 @@
|
||||
"Gen_Description": "",
|
||||
"Gen_Error": "",
|
||||
"Gen_Filter": "",
|
||||
"Gen_Generate": "",
|
||||
"Gen_LockedDB": "",
|
||||
"Gen_Offline": "",
|
||||
"Gen_Okay": "",
|
||||
|
||||
@@ -217,6 +217,7 @@
|
||||
"Device_TableHead_RowID": "",
|
||||
"Device_TableHead_Rowid": "",
|
||||
"Device_TableHead_SSID": "",
|
||||
"Device_TableHead_SourcePlugin": "",
|
||||
"Device_TableHead_Status": "",
|
||||
"Device_TableHead_SyncHubNodeName": "",
|
||||
"Device_TableHead_Type": "",
|
||||
@@ -284,6 +285,7 @@
|
||||
"Gen_Description": "",
|
||||
"Gen_Error": "",
|
||||
"Gen_Filter": "",
|
||||
"Gen_Generate": "",
|
||||
"Gen_LockedDB": "",
|
||||
"Gen_Offline": "",
|
||||
"Gen_Okay": "",
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"APPRISE_SIZE_name": "Max payload size",
|
||||
"APPRISE_URL_description": "Apprise notification target URL. For example for Telegram it would be <code>tgram://{bot_token}/{chat_id}</code>.",
|
||||
"APPRISE_URL_name": "Apprise notification URL",
|
||||
"About_Design": "Designed for:",
|
||||
"About_Design": "Entworfen für:",
|
||||
"About_Exit": "Abmelden",
|
||||
"About_Title": "Netzwerksicherheitsscanner und Benachrichtigungsframework",
|
||||
"AppEvents_DateTimeCreated": "protokolliert",
|
||||
@@ -27,29 +27,29 @@
|
||||
"AppEvents_ObjectPlugin": "Verknüpfte Plugins",
|
||||
"AppEvents_ObjectPrimaryID": "Primär ID",
|
||||
"AppEvents_ObjectSecondaryID": "Sekundär ID",
|
||||
"AppEvents_ObjectStatus": "",
|
||||
"AppEvents_ObjectStatus": "Status (zum Log-Zeitpunkt)",
|
||||
"AppEvents_ObjectStatusColumn": "Statusspalte",
|
||||
"AppEvents_ObjectType": "Objekttyp",
|
||||
"AppEvents_Plugin": "Plugin",
|
||||
"AppEvents_Type": "Typ",
|
||||
"Apprise_display_name": "Apprise",
|
||||
"Apprise_icon": "<i class=\"fa fa-bullhorn\"></i>",
|
||||
"BackDevDetail_Actions_Ask_Run": "Do you want to execute the action?",
|
||||
"BackDevDetail_Actions_Not_Registered": "Action not registered: ",
|
||||
"BackDevDetail_Actions_Title_Run": "Run action",
|
||||
"BackDevDetail_Copy_Ask": "Copy details from device from the dropdown list (Everything on this page will be overwritten)?",
|
||||
"BackDevDetail_Copy_Title": "Copy details",
|
||||
"BackDevDetail_Actions_Ask_Run": "Möchtest du die Aktion ausführen?",
|
||||
"BackDevDetail_Actions_Not_Registered": "Aktion nicht registriert: ",
|
||||
"BackDevDetail_Actions_Title_Run": "Aktion ausführen",
|
||||
"BackDevDetail_Copy_Ask": "Details vom Gerät aus der Dropdown-Liste kopieren (alles auf dieser Seite wird überschrieben)?",
|
||||
"BackDevDetail_Copy_Title": "Details kopieren",
|
||||
"BackDevDetail_Tools_WOL_error": "Befehl wurde NICHT ausgeführt.",
|
||||
"BackDevDetail_Tools_WOL_okay": "Befehl wurde ausgeführt.",
|
||||
"BackDevices_Arpscan_disabled": "Automatischer Arp-Scan deaktiviert.",
|
||||
"BackDevices_Arpscan_enabled": "Automatischer Arp-Scan aktiviert.",
|
||||
"BackDevDetail_Tools_WOL_okay": "Der Befehl wurde ausgeführt.",
|
||||
"BackDevices_Arpscan_disabled": "Arp-Scan deaktiviert",
|
||||
"BackDevices_Arpscan_enabled": "Arp-Scan aktiviert",
|
||||
"BackDevices_Backup_CopError": "Die originale Datenbank konnte nicht gesichert werden.",
|
||||
"BackDevices_Backup_Failed": "Das Backup wurde teilweise ausgeführt. Das Archiv ist entweder leer oder nicht vorhanden.",
|
||||
"BackDevices_Backup_okay": "Das Backup wurde erfolgreich beendet.",
|
||||
"BackDevices_Backup_okay": "Die Sicherung wurde erfolgreich mit dem neuen Archiv ausgeführt",
|
||||
"BackDevices_DBTools_DelActHistory": "Die Anzeige der Netzwerkaktivität wurde zurückgesetzt.",
|
||||
"BackDevices_DBTools_DelActHistoryError": "Fehler beim Zurücksetzen der Netzwerkaktivitätsanzeige.",
|
||||
"BackDevices_DBTools_DelDevError_a": "Fehler beim Löschen des Gerätes.",
|
||||
"BackDevices_DBTools_DelDevError_b": "Fehler beim Löschen der Geräte.",
|
||||
"BackDevices_DBTools_DelDevError_a": "Fehler beim Löschen des Gerätes",
|
||||
"BackDevices_DBTools_DelDevError_b": "Fehler beim Löschen der Geräte",
|
||||
"BackDevices_DBTools_DelDev_a": "Gerät wurde gelöscht",
|
||||
"BackDevices_DBTools_DelDev_b": "Geräte wurden gelöscht",
|
||||
"BackDevices_DBTools_DelEvents": "Events wurden gelöscht",
|
||||
@@ -69,11 +69,11 @@
|
||||
"BackDevices_darkmode_disabled": "Heller Modus aktiviert",
|
||||
"BackDevices_darkmode_enabled": "Dunkler Modus aktiviert",
|
||||
"CLEAR_NEW_FLAG_description": "",
|
||||
"CLEAR_NEW_FLAG_name": "",
|
||||
"CLEAR_NEW_FLAG_name": "Neues Flag löschen",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "Dies ist eine Wartungseinstellung. Spezifiziert wie viele Tage Events gespeichert bleiben. Alle älteren Events werden periodisch gelöscht. Wird auch auf die Plugins History angewendet.",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Lösche Events älter als",
|
||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Details von Gerät kopieren",
|
||||
"DevDetail_Copy_Device_Tooltip": "Copy details from device from the dropdown list. Everything on this page will be overwritten",
|
||||
"DevDetail_Copy_Device_Tooltip": "Details vom Gerät aus der Dropdown-Liste kopieren. Alles auf dieser Seite wird überschrieben",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Melde alle Ereignisse",
|
||||
"DevDetail_EveandAl_AlertDown": "Melde Down",
|
||||
"DevDetail_EveandAl_Archived": "Archivierung",
|
||||
@@ -86,9 +86,9 @@
|
||||
"DevDetail_EveandAl_Skip": "pausiere wiederhol. Meldungen für",
|
||||
"DevDetail_EveandAl_Title": "Ereignisse & Alarme einstellen",
|
||||
"DevDetail_Events_CheckBox": "Blende Verbindungs-Ereignisse aus",
|
||||
"DevDetail_GoToNetworkNode": "Navigate to the Network page of the given node.",
|
||||
"DevDetail_GoToNetworkNode": "Zur Netzwerkseite des angegebenen Knotens navigieren.",
|
||||
"DevDetail_Icon": "Icon",
|
||||
"DevDetail_Icon_Descr": "Enter a font awesome icon name without the fa- prefix or with complete class, e.g.: fa fa-brands fa-apple.",
|
||||
"DevDetail_Icon_Descr": "",
|
||||
"DevDetail_Loading": "Laden ...",
|
||||
"DevDetail_MainInfo_Comments": "Notiz",
|
||||
"DevDetail_MainInfo_Favorite": "Favorit",
|
||||
@@ -97,7 +97,7 @@
|
||||
"DevDetail_MainInfo_Name": "Name",
|
||||
"DevDetail_MainInfo_Network": "<i class=\"fa fa-server\"></i> Knoten (MAC)",
|
||||
"DevDetail_MainInfo_Network_Port": "<i class=\"fa fa-ethernet\"></i> Port",
|
||||
"DevDetail_MainInfo_Network_Site": "",
|
||||
"DevDetail_MainInfo_Network_Site": "Seite",
|
||||
"DevDetail_MainInfo_Network_Title": "<i class=\"fa fa-network-wired\"></i> Network",
|
||||
"DevDetail_MainInfo_Owner": "Eigen­tümer",
|
||||
"DevDetail_MainInfo_SSID": "SSID",
|
||||
@@ -106,7 +106,7 @@
|
||||
"DevDetail_MainInfo_Vendor": "Hersteller",
|
||||
"DevDetail_MainInfo_mac": "MAC",
|
||||
"DevDetail_Network_Node_hover": "Wählen Sie das Elternnetzgerät aus, an das das aktuelle Gerät angeschlossen ist, um den Netzwerkbaum zu erstellen.",
|
||||
"DevDetail_Network_Port_hover": "The port this device is connected to on the parent network device. If left empty a wifi icon is displayed in the Network tree.",
|
||||
"DevDetail_Network_Port_hover": "Der Port, mit dem dieses Gerät am übergeordneten Netzwerkgerät verbunden ist. Bleibt er leer, wird ein WLAN-Symbol in der Netzwerkstruktur angezeigt.",
|
||||
"DevDetail_Nmap_Scans": "Nmap Scans",
|
||||
"DevDetail_Nmap_Scans_desc": "Hier kannst du manuelle NMAP Scans starten. Reguläre automatische NMAP Scans können mit dem Services & Ports (NMAP) Plugin geplant werden. Gehe zu den <a href='/settings.php' target='_blank'>Einstellungen</a> um erfahren",
|
||||
"DevDetail_Nmap_buttonDefault": "Standard Scan",
|
||||
@@ -137,7 +137,7 @@
|
||||
"DevDetail_SessionTable_Disconnection": "Trennung",
|
||||
"DevDetail_SessionTable_Duration": "Dauer",
|
||||
"DevDetail_SessionTable_IP": "IP",
|
||||
"DevDetail_SessionTable_Order": "Order",
|
||||
"DevDetail_SessionTable_Order": "Reihenfolge",
|
||||
"DevDetail_Shortcut_CurrentStatus": "aktueller Status",
|
||||
"DevDetail_Shortcut_DownAlerts": "Down Meldungen",
|
||||
"DevDetail_Shortcut_Presence": "Anwesenheit",
|
||||
@@ -161,7 +161,7 @@
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Anwesenheit",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sitzungen",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Tools",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Werkzeuge",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Description": "Das Internet-Info-Tool zeigt Informationen über die Internetverbindung an, wie z. B. IP-Adresse, Stadt, Land, Ortsvorwahl und Zeitzone.",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Error": "Es ist ein Fehler aufgetreten",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Internet-Info starten",
|
||||
@@ -181,24 +181,24 @@
|
||||
"DevDetail_Tools_WOL_noti": "Wake-on-LAN",
|
||||
"DevDetail_Tools_WOL_noti_text": "Der Wake-on-LAN Befehl wurde and die Broadcast Adresse gesendet. Wenn sich das zu startende Gerät nicht im gleichen Subnet / VLan wie NetAlertX befindet, wird das Gerät nicht reagieren.",
|
||||
"DevDetail_Type_hover": "Der Type des Gerätes. If you select any of the pre-defined network devices (e.g.: AP, Firewall, Router, Switch...) they will show up in the Network tree configuration as possible parent network nodes.",
|
||||
"DevDetail_Vendor_hover": "Vendor should be auto-detected. You can overwrite or add your custom value.",
|
||||
"DevDetail_Vendor_hover": "Der Anbieter sollte automatisch erkannt werden. Du kannst den Wert überschreiben oder deinen eigenen Wert hinzufügen.",
|
||||
"DevDetail_WOL_Title": "<i class=\"fa fa-power-off\"></i> Wake-on-LAN",
|
||||
"DevDetail_button_AddIcon": "Neues Symbol Hinzufügen",
|
||||
"DevDetail_button_AddIcon_Help": "Füge ein HTML SVG Tag oder Font Awesome HTML Tag ein. Siehe <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/ICONS.md\" target=\"_blank\">Icon Dokumentation</a> für details.",
|
||||
"DevDetail_button_AddIcon_Tooltip": "Neues Icon zu diesem Gerät hinzufügen, welches es noch nicht im dropdown gibt.",
|
||||
"DevDetail_button_Delete": "Lösche Gerät",
|
||||
"DevDetail_button_DeleteEvents": "Lösche Events",
|
||||
"DevDetail_button_Delete": "Gerät löschen",
|
||||
"DevDetail_button_DeleteEvents": "Ereignisse löschen",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Sind Sie sicher, dass Sie alle Ereignisse dieses Geräts löschen möchten? (dies löscht den Ereignisverlauf und die Sitzungen und könnte bei ständigen (anhaltenden) Benachrichtigungen helfen)",
|
||||
"DevDetail_button_OverwriteIcons": "Overwrite Icons",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Overwrite icons of all devices with the same device type",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Are you sure you want to overwrite all icons of all devices with the same device type as the current device type?",
|
||||
"DevDetail_button_OverwriteIcons": "Symbole überschreiben",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Symbole aller Geräte mit demselben Gerätetyp überschreiben",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Bist du sicher, dass du alle Symbole aller Geräte mit dem gleichen Gerätetyp wie dem aktuellen Gerätetyp überschreiben willst?",
|
||||
"DevDetail_button_Reset": "Verwerfen",
|
||||
"DevDetail_button_Save": "Speichern",
|
||||
"Device_MultiEdit": "Mehrfach-bearbeiten",
|
||||
"Device_MultiEdit_Backup": "",
|
||||
"Device_MultiEdit_Fields": "Felder bearbeiten:",
|
||||
"Device_MultiEdit_MassActions": "Massen aktionen:",
|
||||
"Device_MultiEdit_Tooltip": "",
|
||||
"Device_MultiEdit_Tooltip": "Achtung! Beim Drücken werden alle Werte auf die oben ausgewählten Geräte übertragen.",
|
||||
"Device_Searchbox": "Suche",
|
||||
"Device_Shortcut_AllDevices": "Meine Geräte",
|
||||
"Device_Shortcut_Archived": "Archiviert",
|
||||
@@ -209,26 +209,27 @@
|
||||
"Device_Shortcut_Favorites": "Favoriten",
|
||||
"Device_Shortcut_NewDevices": "Neue Geräte",
|
||||
"Device_Shortcut_OnlineChart": "Gerätepräsenz im Laufe der Zeit",
|
||||
"Device_TableHead_Connected_Devices": "Verbundene Geräte",
|
||||
"Device_TableHead_Connected_Devices": "Verbindungen",
|
||||
"Device_TableHead_Favorite": "Favorit",
|
||||
"Device_TableHead_FirstSession": "Erste Sitzung",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
"Device_TableHead_Group": "Gruppe",
|
||||
"Device_TableHead_Icon": "Icon",
|
||||
"Device_TableHead_LastIP": "Letzte IP",
|
||||
"Device_TableHead_LastIPOrder": "Last IP Order",
|
||||
"Device_TableHead_LastIPOrder": "Letzte erhaltene IP",
|
||||
"Device_TableHead_LastSession": "Zuletzt offline",
|
||||
"Device_TableHead_Location": "Standort",
|
||||
"Device_TableHead_MAC": "MAC",
|
||||
"Device_TableHead_MAC": "Zufälliger MAC",
|
||||
"Device_TableHead_MAC_full": "Gesamte MAC",
|
||||
"Device_TableHead_Name": "Name",
|
||||
"Device_TableHead_NetworkSite": "",
|
||||
"Device_TableHead_NetworkSite": "Netzwerkseite",
|
||||
"Device_TableHead_Owner": "Eigentümer",
|
||||
"Device_TableHead_Parent_MAC": "Übergeordnete MAC",
|
||||
"Device_TableHead_Port": "Port",
|
||||
"Device_TableHead_RowID": "Zeilen ID",
|
||||
"Device_TableHead_Rowid": "Zeilennummer",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_SourcePlugin": "",
|
||||
"Device_TableHead_Status": "Status",
|
||||
"Device_TableHead_SyncHubNodeName": "Synchronisationsknoten",
|
||||
"Device_TableHead_Type": "Typ",
|
||||
@@ -240,10 +241,10 @@
|
||||
"Device_Tablelenght": "Zeige _MENU_ Einträge",
|
||||
"Device_Tablelenght_all": "Alle",
|
||||
"Device_Title": "Geräte",
|
||||
"Donations_Others": "Others",
|
||||
"Donations_Platforms": "Sponsor platforms",
|
||||
"Donations_Others": "Andere",
|
||||
"Donations_Platforms": "Sponsor-Platformen",
|
||||
"Donations_Text": "Hey 👋! </br> Thanks for clicking on this menu item 😅 </br> </br> I'm trying to collect some donations to make you better software. Also, it would help me not to get burned out. Me burning out might mean end of support for this app. Any small (recurring or not) sponsorship makes me want ot put more effort into this app. I don't want to lock features (new plugins) behind paywalls 🔐. </br> Currently, I'm waking up 2h before work so I contribute to the app a bit. If I had some recurring income I could shorten my workweek and in the remaining time fully focus on NetAlertX. You'd get more functionality, a more polished app and less bugs. </br> </br> Thanks for reading - I'm super grateful for any support ❤🙏 </br> </br> TL;DR: By supporting me you get: </br> </br> <ul><li>Regular updates to keep your data and family safe 🔄</li><li>Less bugs 🐛🔫</li><li>Better and more functionality➕</li><li>I don't get burned out 🔥🤯</li><li>Less rushed releases 💨</li><li>Better docs📚</li><li>Quicker and better support with issues 🆘</li><li>Less grumpy me 😄</li></ul> </br> 📧Email me to <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> if you want to get in touch or if I should add other sponsorship platforms. </br>",
|
||||
"Donations_Title": "Donations",
|
||||
"Donations_Title": "Spenden",
|
||||
"ENABLE_PLUGINS_description": "NOTUSED Enables the <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a> functionality. Loading plugins requires more hardware resources so you might want to disable them on low-powered system.",
|
||||
"ENABLE_PLUGINS_name": "NOTUSED Enable Plugins",
|
||||
"Email_display_name": "Email",
|
||||
@@ -268,11 +269,11 @@
|
||||
"Events_TableHead_Device": "Gerät",
|
||||
"Events_TableHead_Disconnection": "Trennung",
|
||||
"Events_TableHead_Duration": "Dauer",
|
||||
"Events_TableHead_DurationOrder": "Duration Order",
|
||||
"Events_TableHead_DurationOrder": "Dauer-Reihenfolge",
|
||||
"Events_TableHead_EventType": "Ereignis Typ",
|
||||
"Events_TableHead_IP": "IP",
|
||||
"Events_TableHead_IPOrder": "IP Order",
|
||||
"Events_TableHead_Order": "Order",
|
||||
"Events_TableHead_IPOrder": "IP-Reihenfolge",
|
||||
"Events_TableHead_Order": "Reihenfolge",
|
||||
"Events_TableHead_Owner": "Eigentümer",
|
||||
"Events_TableHead_PendingAlert": "Ausstehender Alarm",
|
||||
"Events_Table_info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
|
||||
@@ -288,14 +289,15 @@
|
||||
"Gen_AreYouSure": "Sind Sie sich sicher?",
|
||||
"Gen_Backup": "Sichern",
|
||||
"Gen_Cancel": "Abbrechen",
|
||||
"Gen_Change": "",
|
||||
"Gen_Copy": "Run",
|
||||
"Gen_Change": "Ändern",
|
||||
"Gen_Copy": "Ausführen",
|
||||
"Gen_DataUpdatedUITakesTime": "OK – Es kann einen Moment dauern, bis die Benutzeroberfläche aktualisiert wird, während ein Scan ausgeführt wird.",
|
||||
"Gen_Delete": "Löschen",
|
||||
"Gen_DeleteAll": "Delete all",
|
||||
"Gen_Description": "",
|
||||
"Gen_DeleteAll": "Alles löschen",
|
||||
"Gen_Description": "Beschreibung",
|
||||
"Gen_Error": "Fehler",
|
||||
"Gen_Filter": "Filter",
|
||||
"Gen_Generate": "",
|
||||
"Gen_LockedDB": "ERROR - DB eventuell gesperrt - Nutze die Konsole in den Entwickler Werkzeugen (F12) zur Überprüfung oder probiere es später erneut.",
|
||||
"Gen_Offline": "Offline",
|
||||
"Gen_Okay": "Ok",
|
||||
@@ -304,11 +306,11 @@
|
||||
"Gen_Remove_All": "Alle entfernen",
|
||||
"Gen_Remove_Last": "Letzte entfernen",
|
||||
"Gen_Restore": "Wiederherstellen",
|
||||
"Gen_Run": "Run",
|
||||
"Gen_Run": "Ausführen",
|
||||
"Gen_Save": "Speichern",
|
||||
"Gen_Saved": "Gespeichert",
|
||||
"Gen_Search": "Suchen",
|
||||
"Gen_SelectToPreview": "",
|
||||
"Gen_SelectToPreview": "Zur Vorschau auswählen",
|
||||
"Gen_Selected_Devices": "Ausgewählte Geräte:",
|
||||
"Gen_Switch": "Umschalten",
|
||||
"Gen_Upd": "Aktualisierung erfolgreich",
|
||||
@@ -319,8 +321,8 @@
|
||||
"Gen_Work_In_Progress": "Keine Finalversion, feedback bitte unter: https://github.com/jokob-sk/NetAlertX/issues",
|
||||
"General_display_name": "Allgemein",
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "Dies ist eine Wartungseinstellung. Wenn aktiviert (<code>0</code> bedeutet deaktiviert), werden als <b>\"Neues Gerät\"</b> markierte Geräte gelöscht, wenn ihre <b>erste Sitzung</b> länger her ist als in dieser Einstellung angegeben. Verwenden Sie diese Einstellung, wenn Sie <b>Neue Geräte</b> nach <code>X</code> Stunden automatisch löschen wollen.",
|
||||
"HRS_TO_KEEP_NEWDEV_name": "Neue Geräte speichern für",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "Dies ist eine Wartungseinstellung <b>DELETING devices</b>. Wenn aktiviert (<code>0</code> bedeutet deaktiviert), werden als <b>\"Neues Gerät\"</b> markierte Geräte gelöscht, wenn ihre <b>erste Sitzung</b> länger her ist als in dieser Einstellung angegeben. Verwenden Sie diese Einstellung, wenn Sie <b>Neue Geräte</b> nach <code>X</code> Stunden automatisch löschen wollen.",
|
||||
"HRS_TO_KEEP_NEWDEV_name": "Neue Geräte löschen nach",
|
||||
"HelpFAQ_Cat_Detail": "Detailansicht",
|
||||
"HelpFAQ_Cat_Detail_300_head": "Was bedeutet ",
|
||||
"HelpFAQ_Cat_Detail_300_text_a": "meint ein Netzwerkgerät (ein Gerät vom Typ AP, Gateway, Firewall, Hypervisor, Powerline, Switch, WLAN, PLC, Router, USB-LAN-Adapter oder Internet). Benutzerdefinierte Typen können über die <code>NETWORK_DEVICE_TYPES</code> Einstellung hinzugefügt werden.",
|
||||
@@ -339,13 +341,13 @@
|
||||
"HelpFAQ_Cat_General_100_head": "Die Uhr oben rechts und die Zeiten der Events/Anwesenheit stimmen nicht überein (Zeitverschiebung).",
|
||||
"HelpFAQ_Cat_General_100_text_a": "Auf deinem PC ist für die PHP Umgebung folgende Zeitzone voreingestellt:",
|
||||
"HelpFAQ_Cat_General_100_text_b": "Sollte dies nicht die Zeitzone sein, in der du dich aufhältst, solltest du die Zeitzone in der PHP Konfigurationsdatei anpassen. Diese findest du in diesem Verzeichnis:",
|
||||
"HelpFAQ_Cat_General_100_text_c": "Suche in dieser Datei nach dem Eintrag 'date.timezone', entferne ggf. das führende ';' und trage die gewünschte Zeitzone ein. Eine Liste mit den unterstützten Zeitzonen findest du hier (<a href=\"https://www.php.net/manual/de/timezones.php\" target=\"blank\">Link</a>).",
|
||||
"HelpFAQ_Cat_General_100_text_c": "Suche in dieser Datei nach dem Eintrag 'date.timezone', entferne ggf. das führende ';' und trage die gewünschte Zeitzone ein. Eine Liste mit den unterstützten Zeitzonen findest du hier: (<a href=\"https://www.php.net/manual/de/timezones.php\" target=\"blank\">Link</a>)",
|
||||
"HelpFAQ_Cat_General_101_head": "Mein Netzwerk scheint langsamer zu werden, Streaming ruckelt.",
|
||||
"HelpFAQ_Cat_General_101_text": "Es kann durchaus sein, das leistungsschwache Geräte mit der Art und Weise, wie NetAlertX neue Geräte im Netzwerk erkennt, an ihre Leistungsgrenzen kommen. Dies verstärkt sich noch einmal, <br/> wenn diese Geräte per WLAN mit dem Netzwerk kommunizieren. Lösungen wären hier, wenn möglich ein Wechsel auf eine Kabelverbindung oder, falls das Geräte nur einen begrenzten Zeitraum genutzt <br/> werden soll, den arp-Scan auf der Wartungsseite zu pausieren.",
|
||||
"HelpFAQ_Cat_General_102_head": "Ich bekomme die Meldung, dass die Datenbank schreibgeschützt (read only) ist.",
|
||||
"HelpFAQ_Cat_General_102_text": "Prüfe im NetAlertX verzeichnis ob der Ordner der Datenbank (db) die richtigen Rechte zugewiesen bekommen hat:<br> <span class=\"text-danger help_faq_code\">drwxrwx--- 2 (dein Username) www-data</span><br> Sollte die Berechtigung nicht stimmen, kannst du sie mit folgenden Befehlen im Terminal oder der Konsole wieder setzen:<br> <span class=\"text-danger help_faq_code\"> sudo chgrp -R www-data /app/db<br> chmod -R 770 /app/db </span><br> Wenn die Datenbank danach noch immer schreibgeschützt ist, versuche eine erneute Installation, oder das Zuückspielen eines Datenbank-Backups über die Wartungsseite.",
|
||||
"HelpFAQ_Cat_General_102docker_head": "(🐳 Docker only) Database issues (AJAX errors, read-only, not found)",
|
||||
"HelpFAQ_Cat_General_102docker_text": "Double-check you have followed the <a href=\"https://github.com/jokob-sk/NetAlertX/tree/main/dockerfiles\">dockerfile readme (most up-to-date info)</a>. <br/> <br/> <ul data-sourcepos=\"49:4-52:146\" dir=\"auto\"> <li data-sourcepos=\"49:4-49:106\">Download the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/db/app.db\">original DB from GitHub</a>.</li> <li data-sourcepos=\"50:4-50:195\">Map the <code>app.db</code> file (<g-emoji class=\"g-emoji\" alias=\"warning\" fallback-src=\"https://github.githubassets.com/images/icons/emoji/unicode/26a0.png\">⚠</g-emoji> not folder) from above to <code>/app/db/app.db</code> (see <a href=\"https://github.com/jokob-sk/NetAlertX/tree/main/dockerfiles#-examples\">Examples</a> for details).</li><li data-sourcepos=\"51:4-51:161\">If facing issues (AJAX errors, can not write to DB, etc,) make sure permissions are set correctly, alternatively check the logs under <code>/app/front/log</code>.</li> <li data-sourcepos=\"52:4-52:146\">To solve permission issues you can also try to create a DB backup and then run a DB Restore via the <strong>Maintenance > Backup/Restore</strong> section.</li> <li data-sourcepos=\"53:4-53:228\">If the database is in read-only mode you can solve this by setting the owner and group by executing the following command on the host system: <code>docker exec netalertx chown -R www-data:www-data /app/db/app.db</code>.</li></ul>",
|
||||
"HelpFAQ_Cat_General_102docker_text": "",
|
||||
"HelpFAQ_Cat_General_103_head": "Die Login-Seite erscheint nicht, auch nicht nach der Passwortänderung.",
|
||||
"HelpFAQ_Cat_General_103_text": "Neben dem Passwort, muss in der Konfigurationsdatei <span class=\"text-danger help_faq_code\">/app/config/app.conf</span> auch der Parameter <span class=\"text-danger help_faq_code\">PIALERT_WEB_PROTECTION</span> auf <span class=\"text-danger help_faq_code\">True</span> gesetzt sein.",
|
||||
"HelpFAQ_Cat_Network_600_head": "Was bringt mir diese Seite?",
|
||||
@@ -367,7 +369,7 @@
|
||||
"Login_Info": "",
|
||||
"Login_Psw-box": "Passwort",
|
||||
"Login_Psw_alert": "Sicherheitshinweis!",
|
||||
"Login_Psw_folder": "im Ordner /app/config",
|
||||
"Login_Psw_folder": "im Konfigurationsordner.",
|
||||
"Login_Psw_new": "neues_passwort",
|
||||
"Login_Psw_run": "Um das Passwort zu ändern nutze:",
|
||||
"Login_Remember": "Passwort speichern",
|
||||
@@ -407,8 +409,8 @@
|
||||
"Maintenance_Tool_ImportPastedCSV": "CSV-Import (Einfügen)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_arpscansw": "arp-Scan stoppen/starten",
|
||||
"Maintenance_Tool_arpscansw_noti": "arp-Scan stoppen/starten",
|
||||
"Maintenance_Tool_arpscansw": "ARP-Scan umschalten (ein/aus)",
|
||||
"Maintenance_Tool_arpscansw_noti": "ARP-Scan ein- oder ausschalten",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Wenn der Scan aus ist, bleibt er so lange aus bis er wieder aktiviert wird.",
|
||||
"Maintenance_Tool_arpscansw_text": "Schaltet den arp-Scan an oder aus. Wenn der Scan aus ist, bleibt er so lange aus bis er wieder aktiviert wird. Bereits laufende Scans werden dabei nicht beendet.",
|
||||
"Maintenance_Tool_backup": "DB Sicherung",
|
||||
@@ -433,7 +435,7 @@
|
||||
"Maintenance_Tool_del_allevents30_noti": "Ereignisse löschen",
|
||||
"Maintenance_Tool_del_allevents30_noti_text": "Sind Sie sich sicher, dass Sie alle Ereignisse älter als 30 Tage löschen wollen? Dies setzt die Präsenz aller Geräte zurück.",
|
||||
"Maintenance_Tool_del_allevents30_text": "Machen Sie ein Backup, bevor Sie diese Funktion nutzen. Der Vorgang kann ohne Backup nicht rückgängig gemacht werden. Alle Ereignisse älter als 30 Tage werden aus der Datenbank gelöscht. Dies setzt auch die Anwesenheit zurück. Es kann ab dem Moment zu ungültigen Sitzungen kommen. Ein Scan, während das betreffende Gerät online ist, sollte das Problem lösen.",
|
||||
"Maintenance_Tool_del_allevents_noti": "Alle Ereignisse löschen",
|
||||
"Maintenance_Tool_del_allevents_noti": "Ereignisse löschen",
|
||||
"Maintenance_Tool_del_allevents_noti_text": "Sind Sie sicher, dass Sie alle Ereignisse aus der Datenbank löschen wollen. Dies setzt die Anwesenheit aller Geräte zurück.",
|
||||
"Maintenance_Tool_del_allevents_text": "Machen Sie ein Backup, bevor Sie diese Funk­tion nutzen. Der Vor­gang kann ohne Back­up nicht rück­gängig gemacht werden. Alle Ereignisse werden aus der Datenbank ge­löscht. Dies setzt auch die Anwesenheit zu­rück. Es kann ab dem Moment zu ungültigen Sitzungen kommen. Ein Scan, während das betreffende Gerät online ist, sollte das Problem lösen.",
|
||||
"Maintenance_Tool_del_empty_macs": "Alle Geräte ohne MAC löschen",
|
||||
@@ -446,7 +448,7 @@
|
||||
"Maintenance_Tool_del_unknowndev_noti": "Lösche (unknown) Geräte",
|
||||
"Maintenance_Tool_del_unknowndev_noti_text": "Sind Sie sicher, dass Sie alle (unknown) Geräte aus der Datenbank löschen wollen?",
|
||||
"Maintenance_Tool_del_unknowndev_text": "Machen Sie ein Backup, bevor Sie diese Funk­tion nutzen. Der Vor­gang kann ohne Back­up nicht rück­gängig gemacht werden. Alle Gräte mit dem Namen (unknown) werden aus der Datenbank ge­löscht.",
|
||||
"Maintenance_Tool_displayed_columns_text": "Ändere die Sichtbarkeit und Anordnung der Spalten in der <a href=\"devices.php\"><b> <i class=\"fa fa-laptop\"></i> Geräte</b></a>-Seite. (Drag-and-Drop funktioniert nicht einwandfrei, ist aber verwendbar. Ich habe <a href=\"https://github.com/jokob-sk/NetAlertX/commit/94b32f0f7332879f5a7d2af05dafa2e5d5cfa5da\">3 Stunden</a> versucht das zu beheben, werde es aber nicht weiter verfolgen. Über einen PR mit einem Fix würde ich mich freuen :) ).",
|
||||
"Maintenance_Tool_displayed_columns_text": "Ändere die Sichtbarkeit und Anordnung der Spalten in der <a href=\"devices.php\"><b> <i class=\"fa fa-laptop\"></i> Geräte</b></a>-Seite.",
|
||||
"Maintenance_Tool_drag_me": "Zieh mich um die Anordnung der Spalten zu ändern.",
|
||||
"Maintenance_Tool_order_columns_text": "",
|
||||
"Maintenance_Tool_purgebackup": "Sicherungen aufräumen",
|
||||
@@ -458,14 +460,14 @@
|
||||
"Maintenance_Tool_restore_noti_text": "Sind Sie sicher, dass Sie die Datenbank aus der neusten Sicherung wiederherstellen möchten? Prüfen Sie, dass gerade keine Scans stattfinden.",
|
||||
"Maintenance_Tool_restore_text": "Das neuste Backup kann über diese Funk­tion wiederhergestellt werden. Ältere Sicher­ungen müssen manuell wieder­hergestellt wer­den. Es empfiehlt sich eine Integritäts­prüfung nach der Wieder­her­stellung zu machen, falls die Datenbank bei der Sicherung geöffnet war.",
|
||||
"Maintenance_Tool_upgrade_database_noti": "Aktualisiere Datenbank",
|
||||
"Maintenance_Tool_upgrade_database_noti_text": "Machen Sie ein Backup, bevor Sie diese Funk­tion nutzen.",
|
||||
"Maintenance_Tool_upgrade_database_noti_text": "",
|
||||
"Maintenance_Tool_upgrade_database_text": "Mit dieser Schaltfläche wird die Datenbank aktualisiert, um das Diagramm der Netzwerkaktivitäten der letzten 12 Stunden zu aktivieren. Bitte sichern Sie Ihre Datenbank, falls Probleme auftreten.",
|
||||
"Maintenance_Tools_Tab_BackupRestore": "Sicherg. / Wiederherstellg.",
|
||||
"Maintenance_Tools_Tab_Logging": "Logs",
|
||||
"Maintenance_Tools_Tab_BackupRestore": "Sichern / Wiederherstellen",
|
||||
"Maintenance_Tools_Tab_Logging": "Protokolle",
|
||||
"Maintenance_Tools_Tab_Settings": "Einstellungen",
|
||||
"Maintenance_Tools_Tab_Tools": "Werkzeuge",
|
||||
"Maintenance_Tools_Tab_UISettings": "UI Einstellungen",
|
||||
"Maintenance_arp_status": "Scan Status",
|
||||
"Maintenance_arp_status": "Scan-Status",
|
||||
"Maintenance_arp_status_off": "ist im Moment deaktiviert",
|
||||
"Maintenance_arp_status_on": "Scan(s) sind gerade aktiv",
|
||||
"Maintenance_built_on": "Erstellt am",
|
||||
@@ -501,7 +503,7 @@
|
||||
"NTFY_icon": "<i class=\"fa fa-terminal\"></i>",
|
||||
"Navigation_About": "Über",
|
||||
"Navigation_Devices": "Geräte",
|
||||
"Navigation_Donations": "Donations",
|
||||
"Navigation_Donations": "Spenden",
|
||||
"Navigation_Events": "Ereignisse",
|
||||
"Navigation_Flows": "Flows",
|
||||
"Navigation_HelpFAQ": "Hilfe / FAQ",
|
||||
@@ -539,7 +541,7 @@
|
||||
"Network_ManageEdit_ID_text": "-- Gerät wählen --",
|
||||
"Network_ManageEdit_Name": "Neuer Name",
|
||||
"Network_ManageEdit_Name_text": "Name ohne Sonderzeichen",
|
||||
"Network_ManageEdit_Port": "Neue Portanzahl",
|
||||
"Network_ManageEdit_Port": " Neue Portanzahl",
|
||||
"Network_ManageEdit_Port_text": "bei WLAN oder Powerline leer lassen",
|
||||
"Network_ManageEdit_Submit": "Speichern",
|
||||
"Network_ManageEdit_Type": "Neuer Typ",
|
||||
@@ -564,21 +566,21 @@
|
||||
"PIALERT_WEB_PASSWORD_description": "Das Standardpasswort ist <code>123456</code>. Um das Passwort zu ändern, entweder <code>/app/back/pialert-cli</code> im Container starten oder <a onclick=\"toggleAllSettings()\" href=\"#SETPWD_RUN\"><code>SETPWD_RUN</code> Set password plugin</a> nutzen.",
|
||||
"PIALERT_WEB_PASSWORD_name": "Login-Passwort",
|
||||
"PIALERT_WEB_PROTECTION_description": "Ein Loginfenster wird angezeigt wenn aktiviert. Untere Beschreibung genau durchlesen falls Sie sich aus Ihrer Instanz aussperren.",
|
||||
"PIALERT_WEB_PROTECTION_name": "Login aktivieren",
|
||||
"PIALERT_WEB_PROTECTION_name": "Anmeldung aktivieren",
|
||||
"PLUGINS_KEEP_HIST_description": "Wie viele Plugin Scanresultate behalten werden (pro Plugin, nicht gerätespezifisch).",
|
||||
"PLUGINS_KEEP_HIST_name": "Plugins Verlauf",
|
||||
"PUSHSAFER_TOKEN_description": "Your secret Pushsafer API key (token).",
|
||||
"PUSHSAFER_TOKEN_name": "Pushsafer token",
|
||||
"PUSHSAFER_display_name": "Pushsafer",
|
||||
"PUSHSAFER_icon": "<i class=\"fa fa-bell\"></i>",
|
||||
"Plugins_DeleteAll": "Delete all (filters are ignored)",
|
||||
"Plugins_DeleteAll": "Alles löschen (Filter werden ignoriert)",
|
||||
"Plugins_Filters_Mac": "Mac Filter",
|
||||
"Plugins_History": "Events History",
|
||||
"Plugins_Obj_DeleteListed": "",
|
||||
"Plugins_Objects": "Plugin Objects",
|
||||
"Plugins_History": "Verlauf der Ereignisse",
|
||||
"Plugins_Obj_DeleteListed": "Aufgelistete Objekte löschen",
|
||||
"Plugins_Objects": "Plugin-Objekte",
|
||||
"Plugins_Out_of": "von",
|
||||
"Plugins_Unprocessed_Events": "Unprocessed Events",
|
||||
"Plugins_no_control": "No form control was found to render this value.",
|
||||
"Plugins_Unprocessed_Events": "Unverarbeitete Ereignisse",
|
||||
"Plugins_no_control": "",
|
||||
"Presence_CalHead_day": "Tag",
|
||||
"Presence_CalHead_lang": "de",
|
||||
"Presence_CalHead_month": "Monat",
|
||||
@@ -603,7 +605,7 @@
|
||||
"REPORT_FROM_description": "Notification email subject line. Some SMTP servers need this to be an email.",
|
||||
"REPORT_FROM_name": "Email subject",
|
||||
"REPORT_MAIL_description": "If enabled an email is sent out with a list of changes you nove subscribed to. Please also fill out all remaining settings related to the SMTP setup below. If facing issues, set <code>LOG_LEVEL</code> to <code>debug</code> and check the <a href=\"/maintenance.php#tab_Logging\">error log</a>.",
|
||||
"REPORT_MAIL_name": "Enable email",
|
||||
"REPORT_MAIL_name": "E-Mail aktivieren",
|
||||
"REPORT_MQTT_description": "Enable sending notifications via <a target=\"_blank\" href=\"https://www.home-assistant.io/integrations/mqtt/\">MQTT</a> to your Home Assistance instance.",
|
||||
"REPORT_MQTT_name": "Enable MQTT",
|
||||
"REPORT_NTFY_description": "Enable sending notifications via <a target=\"_blank\" href=\"https://ntfy.sh/\">NTFY</a>.",
|
||||
@@ -615,10 +617,10 @@
|
||||
"REPORT_TO_name": "Send email to",
|
||||
"REPORT_WEBHOOK_description": "Enable webhooks for notifications. Webhooks help you to connect to a lot of 3rd party tools, such as IFTTT, Zapier or <a href=\"https://n8n.io/\" target=\"_blank\">n8n</a> to name a few. Check out this simple <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/WEBHOOK_N8N.md\" target=\"_blank\">n8n guide here</a> to get started. If enabled, configure related settings below.",
|
||||
"REPORT_WEBHOOK_name": "Enable Webhooks",
|
||||
"RandomMAC_hover": "Autodetected - indicates if the device randomizes it's MAC address.",
|
||||
"RandomMAC_hover": "Automatisch erkannt - gibt an, ob das Gerät seine MAC-Adresse zufällig ermittelt.",
|
||||
"Reports_Sent_Log": "Protokoll gesendeter Berichte",
|
||||
"SCAN_SUBNETS_description": "",
|
||||
"SCAN_SUBNETS_name": "",
|
||||
"SCAN_SUBNETS_name": "scan Netzwerke",
|
||||
"SMTP_FORCE_SSL_description": "Force SSL when connecting to your SMTP server.",
|
||||
"SMTP_FORCE_SSL_name": "Force SSL",
|
||||
"SMTP_PASS_description": "The SMTP server password. ",
|
||||
@@ -634,10 +636,10 @@
|
||||
"SMTP_USER_description": "The user name used to login into the SMTP server (sometimes a full email address).",
|
||||
"SMTP_USER_name": "SMTP user",
|
||||
"SYSTEM_TITLE": "Systeminformationen",
|
||||
"Setting_Override": "Override value",
|
||||
"Setting_Override_Description": "Enabling this option will override an App supplied default value with the value specified above.",
|
||||
"Settings_Metadata_Toggle": "Show/hide metadata for the given setting.",
|
||||
"Settings_Show_Description": "",
|
||||
"Setting_Override": "Wert überschreiben",
|
||||
"Setting_Override_Description": "",
|
||||
"Settings_Metadata_Toggle": "Metadaten für die angegebene Einstellung anzeigen/ausblenden.",
|
||||
"Settings_Show_Description": "Beschreibung der Einstellung anzeigen.",
|
||||
"Settings_device_Scanners_desync": "⚠ Die Zeitpläne des Gerätescanners sind nicht synchronisiert.",
|
||||
"Settings_device_Scanners_desync_popup": "",
|
||||
"Speedtest_Results": "Ergebnisse des Geschwindigkeitstests",
|
||||
@@ -721,19 +723,19 @@
|
||||
"UI_DEV_SECTIONS_description": "Auswählen, welche Elemente in der Geräteseite versteckt werden sollen.",
|
||||
"UI_DEV_SECTIONS_name": "Geräteauswahl verstecken",
|
||||
"UI_ICONS_description": "",
|
||||
"UI_ICONS_name": "Vorgefertigte Icons",
|
||||
"UI_LANG_description": "Bevorzugte Oberflächensprache auswählen. Du möchtest beim Übersetzen helfen? Gerne hier: <a href=\"https://hosted.weblate.org/projects/pialert/core/\" target=\"_blank\">Weblate</a>.",
|
||||
"UI_LANG_name": "UI Sprache",
|
||||
"UI_ICONS_name": "Vordefinierte Symbole",
|
||||
"UI_LANG_description": "Bevorzugte Oberflächensprache auswählen. Du möchtest beim Übersetzen helfen? Gerne hier: <a href=\"https://hosted.weblate.org/projects/pialert/core/\" target=\"_blank\">Weblate</a>.",
|
||||
"UI_LANG_name": "Sprache der Benutzeroberfläche",
|
||||
"UI_MY_DEVICES_description": "",
|
||||
"UI_MY_DEVICES_name": "In \"Meine Geräte\" anzeigen",
|
||||
"UI_NOT_RANDOM_MAC_description": "",
|
||||
"UI_NOT_RANDOM_MAC_name": "",
|
||||
"UI_PRESENCE_description": "Auswählen, welche Status im <b>Gerätepräsenz im Laufe der Zeit</b>-Diagramm in der <a href=\"/devices.php\" target=\"_blank\">Geräte</a>-Seite angzeigt werden sollen. (<code>STRG + klicken</code> zum aus-/abwählen).",
|
||||
"UI_NOT_RANDOM_MAC_name": "Nicht als zufällig markieren",
|
||||
"UI_PRESENCE_description": "Auswählen, welche Status im <b>Gerätepräsenz im Laufe der Zeit</b>-Diagramm in der <a href=\"/devices.php\" target=\"_blank\">Geräte</a>-Seite angzeigt werden sollen.",
|
||||
"UI_PRESENCE_name": "Anzeige im Präsenzdiagramm",
|
||||
"UI_REFRESH_description": "",
|
||||
"UI_REFRESH_name": "Automatisch Aktualisieren",
|
||||
"UI_REFRESH_name": "Benutzeroberfläche automatisch auffrischen",
|
||||
"VERSION_description": "",
|
||||
"VERSION_name": "",
|
||||
"VERSION_name": "Version oder Zeitstempel",
|
||||
"WEBHOOK_PAYLOAD_description": "The Webhook payload data format for the <code>body</code> > <code>attachments</code> > <code>text</code> attribute in the payload json. See an example of the payload <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/front/report_templates/webhook_json_sample.json\">here</a>. (e.g.: for discord use <code>text</code>)",
|
||||
"WEBHOOK_PAYLOAD_name": "Payload type",
|
||||
"WEBHOOK_REQUEST_METHOD_description": "The HTTP request method to be used for the webhook call.",
|
||||
@@ -748,13 +750,13 @@
|
||||
"Webhooks_icon": "<i class=\"fa fa-circle-nodes\"></i>",
|
||||
"devices_old": "Aktualisiert...",
|
||||
"general_event_description": "Das Ereignis, das Sie ausgelöst haben, könnte eine Weile dauern, bis Hintergrundprozesse abgeschlossen sind. Die Ausführung endet, wenn die unten ausgeführte Warteschlangen abgearbeitet ist. (Siehe <a href='/maintenance.php#tab_Logging'>error log</a>, wenn Probleme auftreten.)<br/> <br/> Ausführungsschlange:",
|
||||
"general_event_title": "Executing an ad-hoc event",
|
||||
"general_event_title": "",
|
||||
"report_guid": "",
|
||||
"report_guid_missing": "",
|
||||
"report_select_format": "Format auswählen:",
|
||||
"report_time": "Benachrichtigungszeit:",
|
||||
"run_event_icon": "fa-play",
|
||||
"run_event_tooltip": "Enable the setting and save your changes at first before you run it.",
|
||||
"run_event_icon": "",
|
||||
"run_event_tooltip": "Aktiviere die Einstellung und speichere deine Änderungen, bevor du sie ausführst.",
|
||||
"settings_core_icon": "",
|
||||
"settings_core_label": "Kern",
|
||||
"settings_device_scanners": "",
|
||||
@@ -763,23 +765,23 @@
|
||||
"settings_device_scanners_label": "Gerätescanner",
|
||||
"settings_enabled": "Aktive Einstellungen",
|
||||
"settings_enabled_icon": "",
|
||||
"settings_expand_all": "Expand all",
|
||||
"settings_expand_all": "Alles ausklappen",
|
||||
"settings_imported": "Die letzten Einstellungen wurden aus der Datei app.conf importiert",
|
||||
"settings_imported_label": "Einstellungen importiert",
|
||||
"settings_missing": "",
|
||||
"settings_missing_block": "",
|
||||
"settings_old": "Importing settings and re-initializing...",
|
||||
"settings_old": "",
|
||||
"settings_other_scanners": "",
|
||||
"settings_other_scanners_icon": "",
|
||||
"settings_other_scanners_label": "Andere Scanner",
|
||||
"settings_publishers": "",
|
||||
"settings_publishers_icon": "fa-solid fa-paper-plane",
|
||||
"settings_publishers_info": "",
|
||||
"settings_publishers_icon": "",
|
||||
"settings_publishers_info": "Lade mehr Veröffentlicher mit den <a href=\"/settings.php#LOADED_PLUGINS\">geladene Plugins</a>-Einstellungen",
|
||||
"settings_publishers_label": "Veröffentlicher",
|
||||
"settings_saved": "",
|
||||
"settings_saved": "<br/>Einstellungen gespeichert. <br/> Wird geladen... <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
|
||||
"settings_system_icon": "",
|
||||
"settings_system_label": "System",
|
||||
"settings_update_item_warning": "",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Save your changes at first before you test your settings."
|
||||
"test_event_icon": "",
|
||||
"test_event_tooltip": "Speichere die Änderungen, bevor Sie die Einstellungen testen."
|
||||
}
|
||||
@@ -217,6 +217,7 @@
|
||||
"Device_TableHead_RowID": "Row ID",
|
||||
"Device_TableHead_Rowid": "Row ID",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_SourcePlugin": "Source Plugin",
|
||||
"Device_TableHead_Status": "Status",
|
||||
"Device_TableHead_SyncHubNodeName": "Sync Node",
|
||||
"Device_TableHead_Type": "Type",
|
||||
@@ -284,6 +285,7 @@
|
||||
"Gen_Description": "Description",
|
||||
"Gen_Error": "Error",
|
||||
"Gen_Filter": "Filter",
|
||||
"Gen_Generate": "Generate",
|
||||
"Gen_LockedDB": "ERROR - DB might be locked - Check F12 Dev tools -> Console or try later.",
|
||||
"Gen_Offline": "Offline",
|
||||
"Gen_Okay": "Ok",
|
||||
|
||||
@@ -227,6 +227,7 @@
|
||||
"Device_TableHead_RowID": "Row ID",
|
||||
"Device_TableHead_Rowid": "Row ID",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_SourcePlugin": "Fuente del plugin",
|
||||
"Device_TableHead_Status": "Situación",
|
||||
"Device_TableHead_SyncHubNodeName": "Nodo de sincronización",
|
||||
"Device_TableHead_Type": "Tipo",
|
||||
@@ -291,9 +292,10 @@
|
||||
"Gen_DataUpdatedUITakesTime": "Correcto - La interfaz puede tardar en actualizarse si se está ejecutando un escaneo.",
|
||||
"Gen_Delete": "Eliminar",
|
||||
"Gen_DeleteAll": "Eliminar todo",
|
||||
"Gen_Description": "",
|
||||
"Gen_Description": "Descripción",
|
||||
"Gen_Error": "Error",
|
||||
"Gen_Filter": "Filtro",
|
||||
"Gen_Generate": "Generar",
|
||||
"Gen_LockedDB": "Fallo - La base de datos puede estar bloqueada - Pulsa F1 -> Ajustes de desarrolladores -> Consola o prueba más tarde.",
|
||||
"Gen_Offline": "Desconectado",
|
||||
"Gen_Okay": "Aceptar",
|
||||
@@ -635,7 +637,7 @@
|
||||
"Setting_Override": "Sobreescribir el valor",
|
||||
"Setting_Override_Description": "Habilitar esta opción anulará un valor predeterminado proporcionado por la aplicación con el valor especificado anteriormente.",
|
||||
"Settings_Metadata_Toggle": "Mostrar/ocultar los metadatos de la configuración.",
|
||||
"Settings_Show_Description": "",
|
||||
"Settings_Show_Description": "Mostrar descripción de la configuración.",
|
||||
"Settings_Title": "<i class=\"fa fa-cog\"> Configuración</i>",
|
||||
"Settings_device_Scanners_desync": "⚠ Los horarios del escáner de los dispositivos no están sincronizados.",
|
||||
"Settings_device_Scanners_desync_popup": "Los horarios de escáneres de dispositivos (<code> *_RUN_SCHD</code> ) no son lo mismo. Esto resultará en notificaciones inconsistentes del dispositivo en línea/fuera de línea. A menos que sea así, utilice el mismo horario para todos los habilitados.<b> 🔍Escáneres de dispositivos</b> .",
|
||||
@@ -723,11 +725,11 @@
|
||||
"UI_ICONS_name": "Iconos predefinidos",
|
||||
"UI_LANG_description": "Seleccione el idioma preferido para la interfaz de usuario. Ayude a traducir o sugiera idiomas en el portal en línea de <a href=\"https://hosted.weblate.org/projects/pialert/core/\" target=\"_blank\">Weblate</a>.",
|
||||
"UI_LANG_name": "Idioma de interfaz",
|
||||
"UI_MY_DEVICES_description": "Dispositivos cuyos estados deben mostrarse en la vista por defecto <b>Mis dispositivos</b>. (<code>CTRL + Click</code> para seleccionar/deseleccionar)",
|
||||
"UI_MY_DEVICES_description": "Dispositivos cuyos estados deben mostrarse en la vista por defecto <b>Mis dispositivos</b>.",
|
||||
"UI_MY_DEVICES_name": "Mostrar en Mis dispositivos",
|
||||
"UI_NOT_RANDOM_MAC_description": "Prefijos Mac que no deberían marcarse como dispositivos aleatorios. Introduzca por ejemplo <code>52</code> para excluir los dispositivos que empiecen por <code>52:xx:xx:xx:xx</code> para ser marcados como dispositivos con una dirección MAC aleatoria.",
|
||||
"UI_NOT_RANDOM_MAC_name": "No marcar como aleatoria",
|
||||
"UI_PRESENCE_description": "Elige que estados del dispositivo deben mostrarse en la gráfica de <b>Presencia del dispositivo a lo largo del tiempo</b> de la página de <a href=\"/devices.php\" target=\"_blank\">Dispositivos</a>. (<code>CTRL + Clic</code> para seleccionar / deseleccionar)",
|
||||
"UI_PRESENCE_description": "Elige que estados del dispositivo deben mostrarse en la gráfica de <b>Presencia del dispositivo a lo largo del tiempo</b> de la página de <a href=\"/devices.php\" target=\"_blank\">Dispositivos</a>.",
|
||||
"UI_PRESENCE_name": "Mostrar en el gráfico de presencia",
|
||||
"UI_REFRESH_description": "Ingrese el número de segundos después de los cuales se recarga la interfaz de usuario. Ajustado a <code> 0 </code> para desactivar.",
|
||||
"UI_REFRESH_name": "Actualización automática de la interfaz de usuario",
|
||||
@@ -780,4 +782,4 @@
|
||||
"settings_update_item_warning": "Actualice el valor a continuación. Tenga cuidado de seguir el formato anterior. <b>O la validación no se realiza.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Guarda tus cambios antes de probar nuevos ajustes."
|
||||
}
|
||||
}
|
||||
|
||||
18
front/php/templates/language/fr_fr.json
Executable file → Normal file
18
front/php/templates/language/fr_fr.json
Executable file → Normal file
@@ -56,7 +56,7 @@
|
||||
"BackDevices_Restore_okay": "Restauration exécutée avec succès.",
|
||||
"BackDevices_darkmode_disabled": "Mode sombre désactivé",
|
||||
"BackDevices_darkmode_enabled": "Mode sombre activé",
|
||||
"CLEAR_NEW_FLAG_description": "Si activé (<code>0</code> est activé), les appareils marqués comme <b>Nouvel appareil</b> seront démarqués si la durée limite (spécifiée en heures) dépasse la durée de la <b>Première Session</b>.",
|
||||
"CLEAR_NEW_FLAG_description": "Si activé (<code>0</code> est désactivé), les appareils marqués comme <b>Nouvel appareil</b> seront démarqués si la limite de temps (spécifiée en heures) dépasse la durée de <b>Première Session</b>.",
|
||||
"CLEAR_NEW_FLAG_name": "Supprime le nouveau drapeau",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "Il s'agit d'un paramètre de maintenance. Il indique le nombre de jours pendant lesquels les entrées d'événements seront conservées. Tous les événements plus anciens seront supprimés périodiquement. S'applique également à l'historique des événements du plugin.",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Supprimer les événements plus anciens que",
|
||||
@@ -95,7 +95,7 @@
|
||||
"DevDetail_MainInfo_mac": "MAC",
|
||||
"DevDetail_Network_Node_hover": "Sélectionner l'appareil du réseau principal auquel cet appareil est connecté afin de compléter l'arborescence du Réseau.",
|
||||
"DevDetail_Network_Port_hover": "Le port auquel cet appareil est connecté sur l'appareil du réseau principal. Si vide, une icône Wifi est affichée dans l'arborescence du Réseau.",
|
||||
"DevDetail_Nmap_Scans": "Scans NMAP manuels",
|
||||
"DevDetail_Nmap_Scans": "Scans manuels via Nmap",
|
||||
"DevDetail_Nmap_Scans_desc": "Vous pouvez lancer des scans NMAP manuels. Vous pouvez aussi programmer des sans réguliers via le plugin Services & Ports (NMAP). Aller dans les <a href='/settings.php' target='_blank'>Paramètres</a> pour plus de details",
|
||||
"DevDetail_Nmap_buttonDefault": "Scan par défaut",
|
||||
"DevDetail_Nmap_buttonDefault_text": "Scan par défaut : NMAP scanne les 1 000 premiers ports pour chaque demande de scan de protocole. Cela couvre environ 93% des ports TCP et 49% des ports UDP (environ 5 secondes)",
|
||||
@@ -217,6 +217,7 @@
|
||||
"Device_TableHead_RowID": "ID de colonne",
|
||||
"Device_TableHead_Rowid": "ID de colonne",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_SourcePlugin": "Source du plugin",
|
||||
"Device_TableHead_Status": "État",
|
||||
"Device_TableHead_SyncHubNodeName": "Noeud de synchro",
|
||||
"Device_TableHead_Type": "Type",
|
||||
@@ -281,9 +282,10 @@
|
||||
"Gen_DataUpdatedUITakesTime": "OK - cela peut prendre du temps à l'interface pour se mettre à jour si un scan est en cours.",
|
||||
"Gen_Delete": "Supprimer",
|
||||
"Gen_DeleteAll": "Supprimer tous",
|
||||
"Gen_Description": "",
|
||||
"Gen_Description": "Description",
|
||||
"Gen_Error": "Erreur",
|
||||
"Gen_Filter": "Filtrer",
|
||||
"Gen_Generate": "Générer",
|
||||
"Gen_LockedDB": "Erreur - La base de données est peut-être verrouillée - Vérifier avec les outils de dév via F12 -> Console ou essayer plus tard.",
|
||||
"Gen_Offline": "Hors ligne",
|
||||
"Gen_Okay": "OK",
|
||||
@@ -307,7 +309,7 @@
|
||||
"Gen_Work_In_Progress": "Travaux en cours, c'est le bon moment pour faire un retour via la liste d'anomalies sur Github https://github.com/jokob-sk/NetAlertX/issues",
|
||||
"General_display_name": "Général",
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "Paramétrage de maintenance. S'il est activé (<code>0</code> s'il est désactivé), les appareils marqués comme <b>Nouvel appareil</b> seront supprimés si leur durée depuis la <b>première session</b> est plus ancienne que le nombre d'heures paramétré. Utilisez ce paramétrage si vous voulez supprimer automatiquement les <b>Nouveaux appareils</b> après <code>X</code> heures.",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "Paramètre de maintenance. S'il est activé (<code>0</code> s'il est désactivé), les appareils marqués comme <b>Nouvel appareil</b> seront supprimés si leur durée depuis la <b>première session</b> est plus ancienne que le nombre d'heures paramétré. Utilisez ce paramétrage si vous voulez supprimer automatiquement les <b>Nouveaux appareils</b> après <code>X</code> heures.",
|
||||
"HRS_TO_KEEP_NEWDEV_name": "Supprimer les nouveaux appareils après",
|
||||
"HelpFAQ_Cat_Detail": "Détails",
|
||||
"HelpFAQ_Cat_Detail_300_head": "Que signifie ",
|
||||
@@ -568,7 +570,7 @@
|
||||
"Setting_Override": "Remplacer la valeur",
|
||||
"Setting_Override_Description": "Activer cette option va remplacer la valeur fournie par défaut par une application par la valeur renseignée au-dessus.",
|
||||
"Settings_Metadata_Toggle": "Afficher/masquer les méta données pour le paramètre sélectionné.",
|
||||
"Settings_Show_Description": "",
|
||||
"Settings_Show_Description": "Montrer la description de la configuration.",
|
||||
"Settings_device_Scanners_desync": "⚠ La planification des différents scanners d'appareils est désynchronisée.",
|
||||
"Settings_device_Scanners_desync_popup": "La planification des scanners (<code>*_RUN_SCHD</code>) n'est pas identique entre scanners. Cela va entraîner des notifications en ligne/hors-ligne non cohérentes. À moins que cela soit attendu, utilisez la même planification pour tous les <b>🔍scanners d'appareils</b> activés.",
|
||||
"Speedtest_Results": "Résultats du test de débit",
|
||||
@@ -655,11 +657,11 @@
|
||||
"UI_ICONS_name": "Icones prédéfinies",
|
||||
"UI_LANG_description": "Sélectionnez votre langue préféré de l’interface. Aidez à traduire ou suggérez des langues dans le portail en ligne de <a href=\"https://hosted.weblate.org/projects/pialert/core/\" target=\"_blank\">Weblate</a>.",
|
||||
"UI_LANG_name": "Langue de l'interface graphique",
|
||||
"UI_MY_DEVICES_description": "Les états autorisant les appareils à être affichés par défaut dans la vue <b>Mes appareils</b>. (<code>CTRL + Clic</code> pour sélectionner/desélectionner",
|
||||
"UI_MY_DEVICES_description": "Les états autorisant les appareils à être affichés par défaut dans la vue <b>Mes appareils</b>.",
|
||||
"UI_MY_DEVICES_name": "Afficher dans la vue de mes appareils",
|
||||
"UI_NOT_RANDOM_MAC_description": "Les préfixes d'adresses MAC à ne pas considérer comme généré aléatoirement pour les appareils. Renseignez par exemple <code>52</code> pour que les appareils commençant par <code>52:xx:xx:xx:xx:xx</code> ne soient pas considérés comme disposant d'une adresse MAC aléatoire.",
|
||||
"UI_NOT_RANDOM_MAC_name": "Ne pas marquer comme aléatoire",
|
||||
"UI_PRESENCE_description": "Sélectionner les états qui doivent être affichés dans le graphique de <b>Présence des appareils</b> de la page <a href=\"/devices.php\" target=\"_blank\">Appareils</a>. (<code>CTRL + Clic</code> pour sélectionner/désélectionner)",
|
||||
"UI_PRESENCE_description": "Sélectionner les états qui doivent être affichés dans le graphique de <b>Présence des appareils</b> de la page <a href=\"/devices.php\" target=\"_blank\">Appareils</a>.",
|
||||
"UI_PRESENCE_name": "Afficher dans le graphique de présence",
|
||||
"UI_REFRESH_description": "Renseignez le nombre de secondes après lequel rafraîchir l'interface graphique. Renseignez <code>0</code> pour désactiver.",
|
||||
"UI_REFRESH_name": "Rafraîchir automatiquement l'interface graphique",
|
||||
@@ -701,4 +703,4 @@
|
||||
"settings_update_item_warning": "Mettre à jour la valeur ci-dessous. Veillez à bien suivre le même format qu'auparavant. <b>Il n'y a pas de pas de contrôle.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Enregistrer d'abord vos modifications avant de tester vôtre paramétrage."
|
||||
}
|
||||
}
|
||||
|
||||
8
front/php/templates/language/it_it.json
Normal file → Executable file
8
front/php/templates/language/it_it.json
Normal file → Executable file
@@ -217,6 +217,7 @@
|
||||
"Device_TableHead_RowID": "ID riga",
|
||||
"Device_TableHead_Rowid": "ID riga",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_SourcePlugin": "Plugin sorgente",
|
||||
"Device_TableHead_Status": "Stato",
|
||||
"Device_TableHead_SyncHubNodeName": "Sincronizza nodo",
|
||||
"Device_TableHead_Type": "Tipo",
|
||||
@@ -284,6 +285,7 @@
|
||||
"Gen_Description": "Descrizione",
|
||||
"Gen_Error": "Errore",
|
||||
"Gen_Filter": "Filtro",
|
||||
"Gen_Generate": "Genera",
|
||||
"Gen_LockedDB": "ERRORE: il DB potrebbe essere bloccato, controlla F12 Strumenti di sviluppo -> Console o riprova più tardi.",
|
||||
"Gen_Offline": "Offline",
|
||||
"Gen_Okay": "Ok",
|
||||
@@ -655,11 +657,11 @@
|
||||
"UI_ICONS_name": "Icone predefinite",
|
||||
"UI_LANG_description": "Seleziona la lingua preferita dell'interfaccia utente. Aiuta nella traduzione o suggerisci una nuova lingua sul portale online di <a href=\"https://hosted.weblate.org/projects/pialert/core/\" target=\"_blank\">Weblate</a>.",
|
||||
"UI_LANG_name": "Lingua UI",
|
||||
"UI_MY_DEVICES_description": "Dispositivi i cui stati devono essere visualizzati nella visualizzazione predefinita <b>Miei dispositivi</b>. (<code>CTRL + clic</code> per selezionare/deselezionare)",
|
||||
"UI_MY_DEVICES_description": "Dispositivi i cui stati devono essere visualizzati nella visualizzazione predefinita <b>Miei dispositivi</b>.",
|
||||
"UI_MY_DEVICES_name": "Mostra nella vista Miei dispositivi",
|
||||
"UI_NOT_RANDOM_MAC_description": "Prefissi MAC che non devono essere contrassegnati come dispositivi casuali. Inserisci ad esempio <code>52</code> per escludere i dispositivi che iniziano con <code>52:xx:xx:xx:xx:xx</code> dall'essere contrassegnati come dispositivi con un indirizzo MAC casuale.",
|
||||
"UI_NOT_RANDOM_MAC_name": "Non segnalare come casuale",
|
||||
"UI_PRESENCE_description": "Seleziona quali stati devono essere mostrati nel grafico <b>Presenza dispositivo</b> nella pagina <a href=\"/devices.php\" target=\"_blank\">Dispositivi</a>. (<code>CTRL + clic</code> per selezionare/deselezionare)",
|
||||
"UI_PRESENCE_description": "Seleziona quali stati devono essere mostrati nel grafico <b>Presenza dispositivo</b> nella pagina <a href=\"/devices.php\" target=\"_blank\">Dispositivi</a>.",
|
||||
"UI_PRESENCE_name": "Mostra nel grafico delle presenze",
|
||||
"UI_REFRESH_description": "Inserisci il numero di secondi dopo il quale la UI si ricarica. Imposta a <code>0</code> per disabilitare.",
|
||||
"UI_REFRESH_name": "Aggiorna automaticamente la UI",
|
||||
@@ -701,4 +703,4 @@
|
||||
"settings_update_item_warning": "Aggiorna il valore qui sotto. Fai attenzione a seguire il formato precedente. <b>La convalida non viene eseguita.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni."
|
||||
}
|
||||
}
|
||||
@@ -217,6 +217,7 @@
|
||||
"Device_TableHead_RowID": "Rad ID",
|
||||
"Device_TableHead_Rowid": "Rad ID",
|
||||
"Device_TableHead_SSID": "",
|
||||
"Device_TableHead_SourcePlugin": "",
|
||||
"Device_TableHead_Status": "Status",
|
||||
"Device_TableHead_SyncHubNodeName": "Synkroniser Node",
|
||||
"Device_TableHead_Type": "Type",
|
||||
@@ -284,6 +285,7 @@
|
||||
"Gen_Description": "",
|
||||
"Gen_Error": "Feil",
|
||||
"Gen_Filter": "Filter",
|
||||
"Gen_Generate": "",
|
||||
"Gen_LockedDB": "FEIL - DB kan være låst - Sjekk F12 Dev tools -> Konsoll eller prøv senere.",
|
||||
"Gen_Offline": "Frakoblet",
|
||||
"Gen_Okay": "Ok",
|
||||
|
||||
@@ -217,6 +217,7 @@
|
||||
"Device_TableHead_RowID": "ID wiersza",
|
||||
"Device_TableHead_Rowid": "ID wiersza",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_SourcePlugin": "",
|
||||
"Device_TableHead_Status": "Status",
|
||||
"Device_TableHead_SyncHubNodeName": "Węzeł Synchronizacji",
|
||||
"Device_TableHead_Type": "Typ",
|
||||
@@ -284,6 +285,7 @@
|
||||
"Gen_Description": "",
|
||||
"Gen_Error": "Błąd",
|
||||
"Gen_Filter": "Filtr",
|
||||
"Gen_Generate": "",
|
||||
"Gen_LockedDB": "BŁĄD - BAZA DANYCH może być zablokowana - Sprawdź F12 narzędzia dewelopera -> Konsola lub spróbuj ponownie później.",
|
||||
"Gen_Offline": "Wyłączone",
|
||||
"Gen_Okay": "Ok",
|
||||
|
||||
@@ -217,6 +217,7 @@
|
||||
"Device_TableHead_RowID": "ID da linha",
|
||||
"Device_TableHead_Rowid": "ID da linha",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_SourcePlugin": "",
|
||||
"Device_TableHead_Status": "Status",
|
||||
"Device_TableHead_SyncHubNodeName": "Nó de sincronização",
|
||||
"Device_TableHead_Type": "Tipo",
|
||||
@@ -284,6 +285,7 @@
|
||||
"Gen_Description": "",
|
||||
"Gen_Error": "Erro",
|
||||
"Gen_Filter": "Filtro",
|
||||
"Gen_Generate": "",
|
||||
"Gen_LockedDB": "ERRO - O banco de dados pode estar bloqueado - Verifique F12 Ferramentas de desenvolvimento -> Console ou tente mais tarde.",
|
||||
"Gen_Offline": "Offline",
|
||||
"Gen_Okay": "Ok",
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
"DevDetail_EveandAl_ScanCycle": "Сканировать устройство",
|
||||
"DevDetail_EveandAl_ScanCycle_a": "Сканировать Устройство",
|
||||
"DevDetail_EveandAl_ScanCycle_z": "Не сканировать устройство",
|
||||
"DevDetail_EveandAl_Skip": "Пропустить повторные уведомления для",
|
||||
"DevDetail_EveandAl_Skip": "Пропустить повторные уведомления",
|
||||
"DevDetail_EveandAl_Title": "<i class=\"fa fa-bolt\"></i> Конфигурация событий и оповещений",
|
||||
"DevDetail_Events_CheckBox": "Скрыть события подключения",
|
||||
"DevDetail_GoToNetworkNode": "Перейти на страницу Сеть данного узла.",
|
||||
@@ -116,7 +116,7 @@
|
||||
"DevDetail_Run_Actions_Tooltip": "Выполнить действие на текущем устройстве из раскрывающегося списка.",
|
||||
"DevDetail_SessionInfo_FirstSession": "Первый сеанс",
|
||||
"DevDetail_SessionInfo_LastIP": "Последний IP",
|
||||
"DevDetail_SessionInfo_LastSession": "Последние в оффлайн",
|
||||
"DevDetail_SessionInfo_LastSession": "Последний оффлайн",
|
||||
"DevDetail_SessionInfo_StaticIP": "Статический IP",
|
||||
"DevDetail_SessionInfo_Status": "Статус",
|
||||
"DevDetail_SessionInfo_Title": "<i class=\"fa fa-calendar\"></i> Информация о сеансе",
|
||||
@@ -196,7 +196,7 @@
|
||||
"Device_Shortcut_DownOnly": "Выключены",
|
||||
"Device_Shortcut_Favorites": "Избранные",
|
||||
"Device_Shortcut_NewDevices": "Новые устройства",
|
||||
"Device_Shortcut_OnlineChart": "Присутствие устройства",
|
||||
"Device_Shortcut_OnlineChart": "Присутствие устройств",
|
||||
"Device_TableHead_Connected_Devices": "Соединения",
|
||||
"Device_TableHead_Favorite": "Избранное",
|
||||
"Device_TableHead_FirstSession": "Первый сеанс",
|
||||
@@ -210,13 +210,14 @@
|
||||
"Device_TableHead_MAC": "Случайный MAC-адрес",
|
||||
"Device_TableHead_MAC_full": "Полный MAC-адрес",
|
||||
"Device_TableHead_Name": "Имя",
|
||||
"Device_TableHead_NetworkSite": "Сайт сети",
|
||||
"Device_TableHead_NetworkSite": "Сайт устройства",
|
||||
"Device_TableHead_Owner": "Владелец",
|
||||
"Device_TableHead_Parent_MAC": "MAC род. узла",
|
||||
"Device_TableHead_Port": "Порт",
|
||||
"Device_TableHead_RowID": "ID строки",
|
||||
"Device_TableHead_Rowid": "ID строки",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_SourcePlugin": "",
|
||||
"Device_TableHead_Status": "Статус",
|
||||
"Device_TableHead_SyncHubNodeName": "Узел синхронизации",
|
||||
"Device_TableHead_Type": "Тип",
|
||||
@@ -281,9 +282,10 @@
|
||||
"Gen_DataUpdatedUITakesTime": "ОК - Обновление UI может занять некоторое время, если сканирование выполняется.",
|
||||
"Gen_Delete": "Удалить",
|
||||
"Gen_DeleteAll": "Удалить все",
|
||||
"Gen_Description": "",
|
||||
"Gen_Description": "Описание",
|
||||
"Gen_Error": "Ошибка",
|
||||
"Gen_Filter": "Фильтр",
|
||||
"Gen_Generate": "",
|
||||
"Gen_LockedDB": "ОШИБКА - Возможно, база данных заблокирована. Проверьте инструменты разработчика F12 -> Консоль или повторите попытку позже.",
|
||||
"Gen_Offline": "Оффлайн",
|
||||
"Gen_Okay": "OK",
|
||||
@@ -364,7 +366,7 @@
|
||||
"Login_Toggle_Alert_headline": "Предупреждение о пароле!",
|
||||
"Login_Toggle_Info": "Информация о пароле",
|
||||
"Login_Toggle_Info_headline": "Информация о пароле",
|
||||
"Maint_PurgeLog": "Журнал очистки",
|
||||
"Maint_PurgeLog": "Очистить журнал",
|
||||
"Maint_RestartServer": "Перезапустить сервер",
|
||||
"Maint_Restart_Server_noti_text": "Вы уверены, что хотите перезапустить внутренний сервер? Это может привести к несогласованности работы приложения. Сначала создайте резервную копию настроек. <br/> <br/> Примечание: Это может занять несколько минут.",
|
||||
"Maintenance_Running_Version": "Установленная версия",
|
||||
@@ -402,7 +404,7 @@
|
||||
"Maintenance_Tool_del_alldev_noti": "Удалить устройства",
|
||||
"Maintenance_Tool_del_alldev_noti_text": "Вы уверены, что хотите удалить все устройства?",
|
||||
"Maintenance_Tool_del_alldev_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Все устройства будут удалены из базы данных.",
|
||||
"Maintenance_Tool_del_allevents": "Удалить события (Сбросить присутствие)",
|
||||
"Maintenance_Tool_del_allevents": "Удалить события (Сброс присутствия)",
|
||||
"Maintenance_Tool_del_allevents30": "Удалить все события старше 30 дней",
|
||||
"Maintenance_Tool_del_allevents30_noti": "Удалить события",
|
||||
"Maintenance_Tool_del_allevents30_noti_text": "Вы уверены, что хотите удалить все события старше 30 дней? Это сбрасывает состояние присутствия всех устройств.",
|
||||
@@ -410,13 +412,13 @@
|
||||
"Maintenance_Tool_del_allevents_noti": "Удалить события",
|
||||
"Maintenance_Tool_del_allevents_noti_text": "Вы уверены, что хотите удалить все события? Это сбрасывает состояние присутствия всех устройств.",
|
||||
"Maintenance_Tool_del_allevents_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Все события в базе данных будут удалены. В этот момент присутствие всех устройств будет сброшено. Это может привести к недействительным сеансам. Это означает, что устройства отображаются как «присутствующие», хотя они находятся в автономном режиме. Сканирование, когда рассматриваемое устройство находится в сети, решает проблему.",
|
||||
"Maintenance_Tool_del_empty_macs": "Удалить устройства с пустыми MAC-адресами",
|
||||
"Maintenance_Tool_del_empty_macs": "Удалить устройства с пустыми MAC",
|
||||
"Maintenance_Tool_del_empty_macs_noti": "Удалить устройства",
|
||||
"Maintenance_Tool_del_empty_macs_noti_text": "Вы уверены, что хотите удалить все устройства с пустыми MAC-адресами?<br>(возможно, вы предпочитаете заархивировать их)",
|
||||
"Maintenance_Tool_del_empty_macs_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Все устройства без MAC-адресов будут удалены из базы данных.",
|
||||
"Maintenance_Tool_del_selecteddev": "Удалить выбранные устройства",
|
||||
"Maintenance_Tool_del_selecteddev_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Выбранные устройства будут удалены из базы данных.",
|
||||
"Maintenance_Tool_del_unknowndev": "Удалить (неизвестные) устройства",
|
||||
"Maintenance_Tool_del_unknowndev": "Удалить неизвестные устройства",
|
||||
"Maintenance_Tool_del_unknowndev_noti": "Удалить (неизвестные) устройства",
|
||||
"Maintenance_Tool_del_unknowndev_noti_text": "Вы уверены, что хотите удалить все (неизвестные) и (имя не найдено) устройства?",
|
||||
"Maintenance_Tool_del_unknowndev_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Все названные устройства (неизвестные) будут удалены из базы данных.",
|
||||
@@ -475,7 +477,7 @@
|
||||
"Navigation_Notifications": "Уведомления",
|
||||
"Navigation_Plugins": "Плагины",
|
||||
"Navigation_Presence": "Присутствие",
|
||||
"Navigation_Report": "Отправить отчеты",
|
||||
"Navigation_Report": "Отчеты",
|
||||
"Navigation_Settings": "Настройки",
|
||||
"Navigation_SystemInfo": "О системе",
|
||||
"Navigation_Workflows": "Рабочие процессы",
|
||||
@@ -561,14 +563,14 @@
|
||||
"REPORT_MAIL_name": "Включить эл. почту",
|
||||
"REPORT_TITLE": "Отчет",
|
||||
"RandomMAC_hover": "Автоматически обнаружено — указывает, рандомизирует ли устройство свой MAC-адрес.",
|
||||
"Reports_Sent_Log": "Отправить журнал логов",
|
||||
"Reports_Sent_Log": "Отправленные уведомления",
|
||||
"SCAN_SUBNETS_description": "Большинство сетевых сканеров (ARP-SCAN, NMAP, NSLOOKUP, DIG, PHOLUS) полагаются на сканирование определенных сетевых интерфейсов и подсетей. Дополнительную информацию по этому параметру можно найти в <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md\" target=\"_blank\">документации по подсетям</a>, особенно VLAN, какие VLAN поддерживаются или как разобраться в маске сети и своем интерфейсе. <br/> <br/> Альтернативой сетевым сканерам является включение некоторых других сканеров/импортеров устройств, которые не полагаются на NetAlert<sup>X</sup>, имеющий доступ к сети (UNIFI, dhcp.leases , PiHole и др.). <br/> <br/> Примечание. Само время сканирования зависит от количества проверяемых IP-адресов, поэтому тщательно настройте его, указав соответствующую маску сети и интерфейс.",
|
||||
"SCAN_SUBNETS_name": "Сети для сканирования",
|
||||
"SYSTEM_TITLE": "Системная информация",
|
||||
"Setting_Override": "Переопределить значение",
|
||||
"Setting_Override_Description": "Включение этой опции приведет к переопределению значения по умолчанию, предоставленного приложением, на значение, указанное выше.",
|
||||
"Settings_Metadata_Toggle": "Показать/скрыть метаданные для данного параметра.",
|
||||
"Settings_Show_Description": "",
|
||||
"Settings_Show_Description": "Показать описание настройки.",
|
||||
"Settings_device_Scanners_desync": "⚠ Расписания сканера устройств не синхронизированы.",
|
||||
"Settings_device_Scanners_desync_popup": "Расписания сканеров устройств (<code>*_RUN_SCHD</code>) не совпадают. Это приведет к несогласованным онлайн/оффлайн уведомлениям устройства. Если это не предусмотрено, используйте одно и то же расписание для всех включенных <b>🔍Сканеров устройств</b>.",
|
||||
"Speedtest_Results": "Результаты теста скорости",
|
||||
@@ -655,11 +657,11 @@
|
||||
"UI_ICONS_name": "Предопределенные значки",
|
||||
"UI_LANG_description": "Выберите предпочтительный язык пользовательского интерфейса. Помогите перевести или предложите языки на онлайн-портале <a href=\"https://hosted.weblate.org/projects/pialert/core/\" target=\"_blank\">Weblate</a>.",
|
||||
"UI_LANG_name": "Язык интерфейса",
|
||||
"UI_MY_DEVICES_description": "Устройства, статусы которых должны отображаться в <b>Мои устройства</b> по умолчанию. (<code>CTRL + Click</code>, чтобы выбрать/отменить выбор)",
|
||||
"UI_MY_DEVICES_description": "Устройства, статусы которых должны отображаться в стандартном представлении <b>Мои устройства</b>.",
|
||||
"UI_MY_DEVICES_name": "Показать в «Мои устройства»",
|
||||
"UI_NOT_RANDOM_MAC_description": "Префиксы Mac, которые не следует помечать как случайные устройства. Введите, например, <code>52</code>, чтобы исключить устройства, начинающиеся с <code>52:xx:xx:xx:xx:xx</code>, из метки как устройства со случайным MAC-адресом.",
|
||||
"UI_NOT_RANDOM_MAC_name": "Не отмечать как случайные",
|
||||
"UI_PRESENCE_description": "Выберите, какие статусы должны отображаться на диаграмме <b>Присутствие устройства</b> · · на странице <a href=\"/devices.php\" target=\"_blank\">Устройства</a>. (<code>CTRL + Click</code>, чтобы выбрать/отменить выбор)",
|
||||
"UI_PRESENCE_description": "Выберите, какие статусы должны отображаться в диаграмме <b>Присутствие устройств</b>- на странице <a href=\"/devices.php\" target=\"_blank\">Устройства</a>.",
|
||||
"UI_PRESENCE_name": "Показать в диаграмме присутствия",
|
||||
"UI_REFRESH_description": "Введите количество секунд, по истечении которых пользовательский интерфейс перезагружается. Установите значение <code>0</code>, чтобы отключить.",
|
||||
"UI_REFRESH_name": "Автоматическое обновление интерфейса",
|
||||
@@ -668,7 +670,7 @@
|
||||
"devices_old": "Актуализируется...",
|
||||
"general_event_description": "Событие, которое вы инициировали, может занять некоторое время, прежде чем фоновые процессы завершатся. Выполнение завершится, как только очередь выполнения, указанная ниже, опустеет (Проверьте <a href='/maintenance.php#tab_Logging'>журнал ошибок</a> при возникновении проблем). <br/> <br/>· · Очередь выполнения:",
|
||||
"general_event_title": "Выполнение специального события",
|
||||
"report_guid": "Руководство по уведомлениям:",
|
||||
"report_guid": "Идентификатор уведомления:",
|
||||
"report_guid_missing": "Связанное уведомление не найдено. Между недавно отправленными уведомлениями и их доступностью существует небольшая задержка. Обновите страницу и кэшируйте ее через несколько секунд. Также возможно, что выбранное уведомление было удалено во время обслуживания, как указано в настройке <code>DBCLNP_NOTIFI_HIST</code>. <br/> <br/>Вместо этого отображается последнее уведомление. Отсутствующее уведомление имеет следующий GUID:",
|
||||
"report_select_format": "Выбрать формат:",
|
||||
"report_time": "Время уведомления:",
|
||||
|
||||
@@ -217,6 +217,7 @@
|
||||
"Device_TableHead_RowID": "",
|
||||
"Device_TableHead_Rowid": "",
|
||||
"Device_TableHead_SSID": "",
|
||||
"Device_TableHead_SourcePlugin": "",
|
||||
"Device_TableHead_Status": "Durum",
|
||||
"Device_TableHead_SyncHubNodeName": "",
|
||||
"Device_TableHead_Type": "",
|
||||
@@ -284,6 +285,7 @@
|
||||
"Gen_Description": "",
|
||||
"Gen_Error": "Hata",
|
||||
"Gen_Filter": "Filtre",
|
||||
"Gen_Generate": "",
|
||||
"Gen_LockedDB": "",
|
||||
"Gen_Offline": "Çevrimdışı",
|
||||
"Gen_Okay": "Tamam",
|
||||
|
||||
@@ -217,6 +217,7 @@
|
||||
"Device_TableHead_RowID": "排行",
|
||||
"Device_TableHead_Rowid": "排行",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_SourcePlugin": "",
|
||||
"Device_TableHead_Status": "状态",
|
||||
"Device_TableHead_SyncHubNodeName": "同步节点",
|
||||
"Device_TableHead_Type": "类型",
|
||||
@@ -284,6 +285,7 @@
|
||||
"Gen_Description": "",
|
||||
"Gen_Error": "错误",
|
||||
"Gen_Filter": "筛选",
|
||||
"Gen_Generate": "",
|
||||
"Gen_LockedDB": "错误 - DB 可能被锁定 - 检查 F12 开发工具 -> 控制台或稍后重试。",
|
||||
"Gen_Offline": "离线",
|
||||
"Gen_Okay": "Ok",
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
// ## GUI settings processing start
|
||||
// ###################################
|
||||
|
||||
if( isset($_COOKIE['UI_dark_mode']))
|
||||
if( isset($_COOKIE['UI_theme']))
|
||||
{
|
||||
$ENABLED_DARKMODE = $_COOKIE['UI_dark_mode'] == "True";
|
||||
$UI_THEME = $_COOKIE['UI_theme'];
|
||||
}else
|
||||
{
|
||||
$ENABLED_DARKMODE = False;
|
||||
$UI_THEME = "Light";
|
||||
}
|
||||
|
||||
$pia_skin_selected = 'skin-blue';
|
||||
@@ -18,4 +18,4 @@ $pia_skin_selected = 'skin-blue';
|
||||
// ## GUI settings processing end
|
||||
// ###################################
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -111,7 +111,7 @@ def send(pHTML, pText):
|
||||
mylog('debug', [f'[{pluginName}] SMTP_REPORT_TO: {hide_email(str(get_setting_value("SMTP_REPORT_TO")))} SMTP_USER: {hide_email(str(get_setting_value("SMTP_USER")))}'])
|
||||
|
||||
|
||||
subject, from_email, to_email, message_html, message_text = sanitize_email_content('Net AlertX Report', get_setting_value("SMTP_REPORT_FROM"), get_setting_value("SMTP_REPORT_TO"), pHTML, pText)
|
||||
subject, from_email, to_email, message_html, message_text = sanitize_email_content('NetAlertX Report', get_setting_value("SMTP_REPORT_FROM"), get_setting_value("SMTP_REPORT_TO"), pHTML, pText)
|
||||
|
||||
# Compose email
|
||||
msg = MIMEMultipart('alternative')
|
||||
|
||||
@@ -443,7 +443,7 @@
|
||||
"column": "Dummy",
|
||||
"mapped_to_column": "cur_ScanMethod",
|
||||
"mapped_to_column_data": {
|
||||
"value": "arp-scan"
|
||||
"value": "ARPSCAN"
|
||||
},
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
|
||||
@@ -28,6 +28,7 @@ CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log')
|
||||
|
||||
pluginName = 'ARPSCAN'
|
||||
|
||||
def main():
|
||||
|
||||
@@ -58,7 +59,7 @@ def main():
|
||||
userSubnetsParam = base64.b64decode(userSubnetsParamBase64).decode('ascii')
|
||||
|
||||
# Print the decoded subnet information.
|
||||
mylog('verbose', ['[ARP Scan] userSubnetsParam: ', userSubnetsParam])
|
||||
mylog('verbose', [f'[{pluginName}] userSubnetsParam: ', userSubnetsParam])
|
||||
|
||||
# Check if the decoded subnet information contains multiple subnets separated by commas.
|
||||
# If it does, split the string into a list of individual subnets.
|
||||
@@ -86,7 +87,7 @@ def main():
|
||||
watched2 = handleEmpty(device.get('hw', '')), # Vendor (assuming it's in the 'hw' field)
|
||||
watched3 = handleEmpty(device.get('interface', '')), # Add the interface
|
||||
watched4 = '',
|
||||
extra = 'arp-scan',
|
||||
extra = pluginName,
|
||||
foreignKey = "")
|
||||
|
||||
plugin_objects.write_result_file()
|
||||
@@ -105,7 +106,7 @@ def execute_arpscan(userSubnets):
|
||||
|
||||
arpscan_output = execute_arpscan_on_interface (interface)
|
||||
|
||||
mylog('verbose', ['[ARP Scan] arpscan_output: ', arpscan_output])
|
||||
mylog('verbose', [f'[{pluginName}] arpscan_output: ', arpscan_output])
|
||||
|
||||
# Search IP + MAC + Vendor as regular expresion
|
||||
re_ip = r'(?P<ip>((2[0-5]|1[0-9]|[0-9])?[0-9]\.){3}((2[0-5]|1[0-9]|[0-9])?[0-9]))'
|
||||
@@ -132,10 +133,10 @@ def execute_arpscan(userSubnets):
|
||||
unique_devices.append(device)
|
||||
|
||||
# return list
|
||||
mylog('verbose', ['[ARP Scan] Found: Devices without duplicates ', len(unique_devices) ])
|
||||
mylog('verbose', [f'[{pluginName}] Found: Devices without duplicates ', len(unique_devices) ])
|
||||
|
||||
mylog('verbose', ["Devices List len:", len(devices_list)]) # Add this line to print devices_list
|
||||
mylog('verbose',["Devices List:", devices_list]) # Add this line to print devices_list
|
||||
mylog('verbose', [f'[{pluginName}] Devices List len:', len(devices_list)])
|
||||
mylog('verbose', [f'[{pluginName}] Devices List:', devices_list])
|
||||
|
||||
return devices_list
|
||||
|
||||
|
||||
@@ -6,6 +6,15 @@
|
||||
"data_source": "script",
|
||||
"execution_order" : "Layer_3",
|
||||
"show_ui": true,
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
"compare_use_quotes": true
|
||||
}
|
||||
],
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"display_name": [
|
||||
{
|
||||
|
||||
@@ -424,7 +424,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 10,
|
||||
"default_value": 20,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
|
||||
@@ -27,7 +27,7 @@ def main():
|
||||
last_run_logfile.write("")
|
||||
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
timeoutSec = 10
|
||||
timeoutSec = get_setting_value('DHCPSRVS_RUN_TIMEOUT')
|
||||
|
||||
nmapArgs = ['sudo', 'nmap', '--script', 'broadcast-dhcp-discover']
|
||||
|
||||
@@ -42,6 +42,9 @@ def main():
|
||||
newEntries = []
|
||||
|
||||
for line in newLines:
|
||||
|
||||
mylog('verbose', [f'[DHCPSRVS] Processing line: {line} '])
|
||||
|
||||
if 'Response ' in line and ' of ' in line:
|
||||
newEntries.append(Plugin_Object())
|
||||
elif 'Server Identifier' in line:
|
||||
@@ -67,6 +70,7 @@ def main():
|
||||
newEntries[-1].extra += ',' + newVal
|
||||
|
||||
for e in newEntries:
|
||||
|
||||
plugin_objects.add_object(
|
||||
primaryId=e.primaryId,
|
||||
secondaryId=e.secondaryId,
|
||||
@@ -80,7 +84,7 @@ def main():
|
||||
|
||||
plugin_objects.write_result_file()
|
||||
except Exception as e:
|
||||
mylog('none', ['Error in main:', str(e)])
|
||||
mylog('verbose', ['[DHCPSRVS] Error in main:', str(e)])
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -188,8 +188,8 @@
|
||||
"hexColor": "#7D862D"
|
||||
},
|
||||
{
|
||||
"maximum": 100,
|
||||
"hexColor": "#05483C"
|
||||
"maximum": 1000000,
|
||||
"hexColor": "#82a39d"
|
||||
}
|
||||
],
|
||||
"localized": ["name"],
|
||||
@@ -224,8 +224,8 @@
|
||||
"hexColor": "#7D862D"
|
||||
},
|
||||
{
|
||||
"maximum": 100,
|
||||
"hexColor": "#05483C"
|
||||
"maximum": 1000000,
|
||||
"hexColor": "#82a39d"
|
||||
}
|
||||
],
|
||||
"localized": ["name"],
|
||||
|
||||
@@ -46,17 +46,19 @@ def main():
|
||||
|
||||
def run_speedtest():
|
||||
try:
|
||||
st = speedtest.Speedtest()
|
||||
st = speedtest.Speedtest(secure=True)
|
||||
st.get_best_server()
|
||||
download_speed = round(st.download() / 10**6, 2) # Convert to Mbps
|
||||
upload_speed = round(st.upload() / 10**6, 2) # Convert to Mbps
|
||||
|
||||
mylog('verbose', [f"[INTRSPD] Result (down|up): {str(download_speed)} Mbps|{upload_speed} Mbps"])
|
||||
|
||||
return {
|
||||
'download_speed': download_speed,
|
||||
'upload_speed': upload_speed,
|
||||
}
|
||||
except Exception as e:
|
||||
mylog('verbose', [f"Error running speedtest: {str(e)}"])
|
||||
mylog('verbose', [f"[INTRSPD] Error running speedtest: {str(e)}"])
|
||||
return {
|
||||
'download_speed': -1,
|
||||
'upload_speed': -1,
|
||||
|
||||
@@ -6,6 +6,15 @@
|
||||
"data_source": "script",
|
||||
"execution_order" : "Layer_3",
|
||||
"show_ui": true,
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
"compare_use_quotes": true
|
||||
}
|
||||
],
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"display_name": [
|
||||
{
|
||||
|
||||
@@ -6,6 +6,15 @@
|
||||
"enabled": true,
|
||||
"data_source": "script",
|
||||
"show_ui": true,
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
"compare_use_quotes": true
|
||||
}
|
||||
],
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"display_name": [
|
||||
{
|
||||
|
||||
@@ -80,7 +80,14 @@ def is_typical_router_ip(ip_address):
|
||||
# -------------------------------------------------------------------
|
||||
# Check if a valid MAC address
|
||||
def is_mac(input):
|
||||
return re.match("[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", input.lower())
|
||||
input_str = str(input).lower() # Convert to string and lowercase so non-string values won't raise errors
|
||||
|
||||
isMac = bool(re.match("[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", input_str))
|
||||
|
||||
if not isMac: # If it's not a MAC address, log the input
|
||||
mylog('verbose', [f'[is_mac] not a MAC: {input_str}'])
|
||||
|
||||
return isMac
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
def decodeBase64(inputParamBase64):
|
||||
|
||||
@@ -61,3 +61,66 @@ The plugin operates in three different modes based on the configuration settings
|
||||
- It is recommended to use Device synchronization primarily. Plugin data synchronization is more suitable for specific use cases.
|
||||
|
||||

|
||||
|
||||
### Example use case: Network Setup with Multiple VLANs and VM Scanning
|
||||
|
||||
> Thank you to [@richtj999](https://github.com/richtj999) for the use case 🙏
|
||||
|
||||
I have 6 VLANs, all isolated by a firewall, except for one VLAN that has access to all the others.
|
||||
|
||||
Initially, I had one virtual machine (VM) with 6 network cards, one for each VLAN. While this setup worked, it introduced delays due to other concurrent scans. To optimize this, I switched to a multi-VM setup:
|
||||
|
||||
- I created 6 VMs, each attached to a single VLAN.
|
||||
- One VM acts as the "server," and the other 5 as "clients."
|
||||
- The server has access to all VLANs (via firewall rules) and collects data from the client VMs, which each scan their own VLAN.
|
||||
|
||||
#### Summary
|
||||
|
||||
- **Single VM on six VLANs**: Slower because one VM scans all networks.
|
||||
- **Six VMs on six VLANs**: Faster because each VM scans its own network, sending the results to the server.
|
||||
|
||||
#### Example Setup
|
||||
|
||||
- **VM1 ("Server")**: Network 1 (can access all networks) - IP: `10.10.10.106`
|
||||
Receives data from all NetAlertX clients and scans network 1.
|
||||
|
||||
- **VM2 ("Client")**: Network 2 (can access only network 2) - IP: `192.168.x.x`
|
||||
Scans network 2; VM1 retrieves this data.
|
||||
|
||||
- **VM3 ("Client")**: Network 3 (can access only network 3) - IP: `192.168.x.x`
|
||||
Scans network 3; VM1 retrieves this data.
|
||||
|
||||
- **VM4 ("Client")**: Network 4 (can access only network 4) - IP: `192.168.x.x`
|
||||
Scans network 4; VM1 retrieves this data.
|
||||
|
||||
- **VM5 ("Client")**: Network 5 (can access only network 5) - IP: `192.168.x.x`
|
||||
Scans network 5; VM1 retrieves this data.
|
||||
|
||||
- **VM6 ("Client")**: Network 6 (can access only network 6) - IP: `192.168.x.x`
|
||||
Scans network 6; VM1 retrieves this data.
|
||||
|
||||
---
|
||||
|
||||
#### How to Set It Up
|
||||
|
||||
##### Server (VM1)
|
||||
|
||||
1. Go to **Settings > System > Sync Hub**.
|
||||
2. Set the schedule (5 minutes works for me).
|
||||
3. **API Token**: Use any string, but it must match the clients (e.g., `abc123`).
|
||||
4. **Encryption Key**: Use any string, but it must match the clients (e.g., `abc123`).
|
||||
5. Under **Nodes**, add the full URL for each client, e.g., `http://192.168.1.20.20211/`.
|
||||
6. **Node Name**: Leave blank.
|
||||
7. Check **Sync Devices**.
|
||||
|
||||
##### Clients (VM2, VM3, VM4, VM5, VM6)
|
||||
|
||||
1. Go to **Settings > System > Sync Hub**.
|
||||
2. Set **When to run** to "Always after scan."
|
||||
3. **API Token**: Use the same token as the server (e.g., `abc123`).
|
||||
4. **Encryption Key**: Use the same key as the server (e.g., `abc123`).
|
||||
5. Leave **Nodes** blank.
|
||||
6. Set **Node Name** to a unique, memorable name for each client.
|
||||
7. Check **Sync Devices**.
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
},
|
||||
|
||||
"default_value": "unused",
|
||||
"options": [
|
||||
"options": [
|
||||
"unused",
|
||||
"once",
|
||||
"schedule",
|
||||
@@ -115,7 +115,22 @@
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementHasInputValue": 1,
|
||||
"elementOptions": [{ "cssClasses": "col-xs-12" }],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "getStringKey": "Gen_Generate" },
|
||||
{ "customParams": "SYNC_api_token" },
|
||||
{ "onClick": "generateApiToken(this, 20)" },
|
||||
{ "cssClasses": "col-xs-12" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
@@ -131,7 +146,7 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "API token to secure communication. It's sent in the request header. The API token needs to be the same on the hub and on the nodes."
|
||||
"string": "API token to secure communication, you can generate one or enter any value. It's sent in the request header. The API token needs to be the same on the hub and on the nodes."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -140,7 +155,22 @@
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementHasInputValue": 1,
|
||||
"elementOptions": [{ "cssClasses": "col-xs-12" }],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "getStringKey": "Gen_Generate" },
|
||||
{ "customParams": "SYNC_encryption_key" },
|
||||
{ "onClick": "generateApiToken(this, 30)" },
|
||||
{ "cssClasses": "col-xs-12" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
@@ -159,7 +189,8 @@
|
||||
"string": "Encryption key used to encrypt the data before sending and for decryption on the hub. The key needs to be the same on the hub and on the nodes."
|
||||
}
|
||||
]
|
||||
},{
|
||||
},
|
||||
{
|
||||
"function": "nodes",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
|
||||
@@ -346,7 +346,8 @@
|
||||
"Device_TableHead_Type",
|
||||
"Device_TableHead_LastIP",
|
||||
"Device_TableHead_Status",
|
||||
"Device_TableHead_MAC_full"
|
||||
"Device_TableHead_MAC_full",
|
||||
"Device_TableHead_SourcePlugin"
|
||||
],
|
||||
"options": [
|
||||
"Device_TableHead_Name",
|
||||
@@ -371,7 +372,8 @@
|
||||
"Device_TableHead_GUID",
|
||||
"Device_TableHead_SyncHubNodeName",
|
||||
"Device_TableHead_NetworkSite",
|
||||
"Device_TableHead_SSID"
|
||||
"Device_TableHead_SSID",
|
||||
"Device_TableHead_SourcePlugin"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -461,30 +463,30 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dark_mode",
|
||||
"function": "theme",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "false", "orderable": "false" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": false,
|
||||
"options": [],
|
||||
"default_value": "Light",
|
||||
"options": ["Light","Dark","System"],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Dark mode"
|
||||
"string": "Theme"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Enable dark mode."
|
||||
"string": "UI theme to use. System will auto switch between Light and Dark."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -12,9 +12,16 @@ Specify the following settings in the Settings section of NetAlertX:
|
||||
- `UNFIMP_sites` - Name of the sites (usually 'default', check the URL in your UniFi controller UI if unsure. The site id is in the following part of the URL: `https://192.168.1.1:8443/manage/site/this-is-the-site-id/settings/`).
|
||||
- `UNFIMP_protocol` - https:// or http://
|
||||
- `UNFIMP_port` - Usually `8443` or `8843`
|
||||
- `UNFIMP_version` - e.g. `UDMP-unifiOS` is used for the "Cloud Gateway Ultra"
|
||||
- `UNFIMP_version` - see below table for details
|
||||
|
||||
|
||||
#### Version table
|
||||
|
||||
| Controller | `UNFIMP_version` |
|
||||
| ------------------------------------------------------ | ------------------------- |
|
||||
| Cloud Gateway Ultra / UCK cloudkey V2 plus (v4.0.18) | `UDMP-unifiOS` |
|
||||
| Docker hosted | `v5` |
|
||||
|
||||
### Notes
|
||||
|
||||
- It is recommended to create a read-only user in your UniFi controller
|
||||
@@ -19,7 +19,7 @@ from pyunifi.controller import Controller
|
||||
INSTALL_PATH="/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, rmBadChars, is_typical_router_ip
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, rmBadChars, is_typical_router_ip, is_mac
|
||||
from logger import mylog
|
||||
from helper import timeNowTZ, get_setting_value, normalize_string
|
||||
import conf
|
||||
@@ -165,31 +165,37 @@ def collect_details(device_type, devices, online_macs, processed_macs, plugin_ob
|
||||
name = get_name(get_unifi_val(device, 'name'), get_unifi_val(device, 'hostname'))
|
||||
ipTmp = get_ip(get_unifi_val(device, 'lan_ip'), get_unifi_val(device, 'last_ip'), get_unifi_val(device, 'fixed_ip'), get_unifi_val(device, 'ip'))
|
||||
macTmp = device['mac']
|
||||
status = 1 if macTmp in online_macs else device.get('state', 0)
|
||||
deviceType = device_type.get(device.get('type'), '')
|
||||
parentMac = get_parent_mac(get_unifi_val(device, 'uplink_mac'), get_unifi_val(device, 'ap_mac'), get_unifi_val(device, 'sw_mac'))
|
||||
|
||||
# override parent MAC if this is a router
|
||||
if parentMac == 'null' and is_typical_router_ip(ipTmp):
|
||||
parentMac = 'Internet'
|
||||
# continue only if valid MAC address
|
||||
if is_mac(macTmp):
|
||||
status = 1 if macTmp in online_macs else device.get('state', 0)
|
||||
deviceType = device_type.get(device.get('type'), '')
|
||||
parentMac = get_parent_mac(get_unifi_val(device, 'uplink_mac'), get_unifi_val(device, 'ap_mac'), get_unifi_val(device, 'sw_mac'))
|
||||
|
||||
# override parent MAC if this is a router
|
||||
if parentMac == 'null' and is_typical_router_ip(ipTmp):
|
||||
parentMac = 'Internet'
|
||||
|
||||
# Add object only if not processed
|
||||
if macTmp not in processed_macs and ( status == 1 or force_import is True ):
|
||||
plugin_objects.add_object(
|
||||
primaryId=macTmp,
|
||||
secondaryId=ipTmp,
|
||||
watched1=normalize_string(name),
|
||||
watched2=get_unifi_val(device, 'oui', device_vendor),
|
||||
watched3=deviceType,
|
||||
watched4=status,
|
||||
extra=get_unifi_val(device, 'connection_network_name', ''),
|
||||
foreignKey="",
|
||||
helpVal1=parentMac,
|
||||
helpVal2=get_port(get_unifi_val(device, 'sw_port'), get_unifi_val(device, 'uplink_remote_port')),
|
||||
helpVal3=device_label,
|
||||
helpVal4="",
|
||||
)
|
||||
processed_macs.append(macTmp)
|
||||
# Add object only if not processed
|
||||
if macTmp not in processed_macs and ( status == 1 or force_import is True ):
|
||||
plugin_objects.add_object(
|
||||
primaryId=macTmp,
|
||||
secondaryId=ipTmp,
|
||||
watched1=normalize_string(name),
|
||||
watched2=get_unifi_val(device, 'oui', device_vendor),
|
||||
watched3=deviceType,
|
||||
watched4=status,
|
||||
extra=get_unifi_val(device, 'connection_network_name', ''),
|
||||
foreignKey="",
|
||||
helpVal1=parentMac,
|
||||
helpVal2=get_port(get_unifi_val(device, 'sw_port'), get_unifi_val(device, 'uplink_remote_port')),
|
||||
helpVal3=device_label,
|
||||
helpVal4="",
|
||||
)
|
||||
processed_macs.append(macTmp)
|
||||
else:
|
||||
mylog('verbose', [f'[{pluginName}] Skipping, not a valid MAC address: {macTmp}'])
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_unifi_val(obj, key, default='null'):
|
||||
if isinstance(obj, dict):
|
||||
|
||||
@@ -216,8 +216,13 @@
|
||||
|
||||
<!-- Dark-Mode Patch -->
|
||||
<?php
|
||||
if ($ENABLED_DARKMODE === True) {
|
||||
echo '<link rel="stylesheet" href="css/dark-patch-cal.css">';
|
||||
switch ($UI_THEME) {
|
||||
case "Dark":
|
||||
echo '<link rel="stylesheet" href="css/dark-patch-cal.css">';
|
||||
break;
|
||||
case "System":
|
||||
echo '<link rel="stylesheet" href="css/system-dark-patch-cal.css">';
|
||||
break;
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<table align=center width=100% cellpadding=0 cellspacing=0 style="border-radius: 5px;">
|
||||
<tr>
|
||||
<td bgcolor=#3c8dbc align=center style="padding: 20px 10px 10px 10px; font-size: 30px; font-weight: bold; color:#ffffff; border-top-right-radius: 5px; border-top-left-radius: 5px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
|
||||
Net Alert<sup>x</sup>
|
||||
Net<b>Alert</b><sup>x</sup>
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" height="24pt" viewBox="0 0 30 30" width="24pt">
|
||||
<g fill="#000000" stroke="none" transform="translate(0.000000,30) scale(0.02,-0.02)">
|
||||
<path d="M605 1473 c-16 -3 -34 -9 -39 -14 -6 -5 -20 -9 -33 -9 -13 0 -23 -5 -23 -10 0 -5 -3 -9 -7 -8 -14 4 -53 -13 -53 -22 0 -5 -6 -7 -14 -4 -7 3 -27 -6 -44 -20 -16 -15 -34 -26 -39 -26 -6 0 -18 -10 -29 -21 -10 -12 -29 -25 -42 -30 -13 -5 -21 -13 -18 -18 3 -5 -4 -11 -15 -14 -12 -3 -18 -10 -15 -15 3 -5 -6 -14 -19 -20 -14 -7 -25 -18 -25 -27 0 -8 -5 -15 -12 -15 -9 0 -9 -3 -1 -11 9 -9 29 4 80 51 37 34 87 75 110 90 44 30 167 90 184 90 18 0 89 40 89 50 0 6 -1 9 -2 9 -2 -1 -16 -4 -33 -6z"></path>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<table align=center width=100% cellpadding=0 cellspacing=0 style="border-radius: 5px;">
|
||||
<tr>
|
||||
<td bgcolor=#3c8dbc align=center style="padding: 20px 10px 10px 10px; font-size: 30px; font-weight: bold; color:#ffffff; border-top-right-radius: 5px; border-top-left-radius: 5px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
|
||||
Net Alert<sup>x</sup>
|
||||
Net<b>Alert</b><sup>x</sup>
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" height="24pt" viewBox="0 0 30 30" width="24pt">
|
||||
<g fill="#000000" stroke="none" transform="translate(0.000000,30) scale(0.02,-0.02)">
|
||||
<path d="M605 1473 c-16 -3 -34 -9 -39 -14 -6 -5 -20 -9 -33 -9 -13 0 -23 -5 -23 -10 0 -5 -3 -9 -7 -8 -14 4 -53 -13 -53 -22 0 -5 -6 -7 -14 -4 -7 3 -27 -6 -44 -20 -16 -15 -34 -26 -39 -26 -6 0 -18 -10 -29 -21 -10 -12 -29 -25 -42 -30 -13 -5 -21 -13 -18 -18 3 -5 -4 -11 -15 -14 -12 -3 -18 -10 -15 -15 3 -5 -6 -14 -19 -20 -14 -7 -25 -18 -25 -27 0 -8 -5 -15 -12 -15 -9 0 -9 -3 -1 -11 9 -9 29 4 80 51 37 34 87 75 110 90 44 30 167 90 184 90 18 0 89 40 89 50 0 6 -1 9 -2 9 -2 -1 -16 -4 -33 -6z"></path>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<table align=center width=100% cellpadding=0 cellspacing=0 style="border-radius: 5px;">
|
||||
<tr>
|
||||
<td bgcolor=#3c8dbc align=center style="padding: 20px 10px 10px 10px; font-size: 30px; font-weight: bold; color:#ffffff; border-top-right-radius: 5px; border-top-left-radius: 5px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
|
||||
Net Alert<sup>x</sup>
|
||||
Net<b>Alert</b><sup>x</sup>
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" height="24pt" viewBox="0 0 30 30" width="24pt">
|
||||
<g fill="#000000" stroke="none" transform="translate(0.000000,30) scale(0.02,-0.02)">
|
||||
<path d="M605 1473 c-16 -3 -34 -9 -39 -14 -6 -5 -20 -9 -33 -9 -13 0 -23 -5 -23 -10 0 -5 -3 -9 -7 -8 -14 4 -53 -13 -53 -22 0 -5 -6 -7 -14 -4 -7 3 -27 -6 -44 -20 -16 -15 -34 -26 -39 -26 -6 0 -18 -10 -29 -21 -10 -12 -29 -25 -42 -30 -13 -5 -21 -13 -18 -18 3 -5 -4 -11 -15 -14 -12 -3 -18 -10 -15 -15 3 -5 -6 -14 -19 -20 -14 -7 -25 -18 -25 -27 0 -8 -5 -15 -12 -15 -9 0 -9 -3 -1 -11 9 -9 29 4 80 51 37 34 87 75 110 90 44 30 167 90 184 90 18 0 89 40 89 50 0 6 -1 9 -2 9 -2 -1 -16 -4 -33 -6z"></path>
|
||||
|
||||
@@ -471,6 +471,8 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
||||
|
||||
// Parse the setType JSON string into an object
|
||||
let inputHtml = '';
|
||||
console.log(setType);
|
||||
|
||||
const setTypeObject = JSON.parse(setType.replace(/'/g, '"'));
|
||||
|
||||
const dataType = setTypeObject.dataType;
|
||||
|
||||
@@ -127,7 +127,7 @@ require 'php/templates/header.php';
|
||||
"render": function(data, type, row) {
|
||||
if (data.includes("Report:")) {
|
||||
var guid = data.split(":")[1].trim();
|
||||
return `<a href="/report.php?guid=${guid}">Go to Report</a>`;
|
||||
return `<a href="report.php?guid=${guid}">Go to Report</a>`;
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -213,6 +213,17 @@ class DB():
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_SyncHubNodeName" TEXT
|
||||
""")
|
||||
|
||||
# dev_SourcePlugin column
|
||||
dev_SourcePlugin_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SourcePlugin'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_SourcePlugin_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_SourcePlugin to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_SourcePlugin" TEXT
|
||||
""")
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Settings table setup
|
||||
@@ -538,7 +549,8 @@ class DB():
|
||||
cur_SSID STRING(250),
|
||||
cur_NetworkNodeMAC STRING(250),
|
||||
cur_PORT STRING(250),
|
||||
cur_Type STRING(250)
|
||||
cur_Type STRING(250),
|
||||
UNIQUE(cur_MAC)
|
||||
);
|
||||
""")
|
||||
|
||||
@@ -566,9 +578,38 @@ class DB():
|
||||
WHERE e.row_num = 1;
|
||||
""")
|
||||
|
||||
self.commitDB()
|
||||
|
||||
# handling the Convert_Events_to_Sessions / Sessions screens
|
||||
self.sql.execute("""DROP VIEW IF EXISTS Convert_Events_to_Sessions;""")
|
||||
self.sql.execute("""CREATE VIEW Convert_Events_to_Sessions AS SELECT EVE1.eve_MAC,
|
||||
EVE1.eve_IP,
|
||||
EVE1.eve_EventType AS eve_EventTypeConnection,
|
||||
EVE1.eve_DateTime AS eve_DateTimeConnection,
|
||||
CASE WHEN EVE2.eve_EventType IN ('Disconnected', 'Device Down') OR
|
||||
EVE2.eve_EventType IS NULL THEN EVE2.eve_EventType ELSE '<missing event>' END AS eve_EventTypeDisconnection,
|
||||
CASE WHEN EVE2.eve_EventType IN ('Disconnected', 'Device Down') THEN EVE2.eve_DateTime ELSE NULL END AS eve_DateTimeDisconnection,
|
||||
CASE WHEN EVE2.eve_EventType IS NULL THEN 1 ELSE 0 END AS eve_StillConnected,
|
||||
EVE1.eve_AdditionalInfo
|
||||
FROM Events AS EVE1
|
||||
LEFT JOIN
|
||||
Events AS EVE2 ON EVE1.eve_PairEventRowID = EVE2.RowID
|
||||
WHERE EVE1.eve_EventType IN ('New Device', 'Connected','Down Reconnected')
|
||||
UNION
|
||||
SELECT eve_MAC,
|
||||
eve_IP,
|
||||
'<missing event>' AS eve_EventTypeConnection,
|
||||
NULL AS eve_DateTimeConnection,
|
||||
eve_EventType AS eve_EventTypeDisconnection,
|
||||
eve_DateTime AS eve_DateTimeDisconnection,
|
||||
0 AS eve_StillConnected,
|
||||
eve_AdditionalInfo
|
||||
FROM Events AS EVE1
|
||||
WHERE (eve_EventType = 'Device Down' OR
|
||||
eve_EventType = 'Disconnected') AND
|
||||
EVE1.eve_PairEventRowID IS NULL;
|
||||
""")
|
||||
|
||||
self.commitDB()
|
||||
|
||||
# Init the AppEvent database table
|
||||
AppEvent_obj(self)
|
||||
|
||||
|
||||
@@ -93,10 +93,7 @@ def save_scanned_devices (db):
|
||||
|
||||
# Proceed if variable contains valid MAC
|
||||
if check_mac_or_internet(local_mac):
|
||||
# Check if local mac has been detected with other methods
|
||||
sql.execute (f"SELECT COUNT(*) FROM CurrentScan WHERE cur_MAC = '{local_mac}'")
|
||||
if sql.fetchone()[0] == 0 :
|
||||
sql.execute (f"""INSERT INTO CurrentScan (cur_MAC, cur_IP, cur_Vendor, cur_ScanMethod) VALUES ( '{local_mac}', '{local_ip}', Null, 'local_MAC') """)
|
||||
sql.execute (f"""INSERT OR IGNORE INTO CurrentScan (cur_MAC, cur_IP, cur_Vendor, cur_ScanMethod) VALUES ( '{local_mac}', '{local_ip}', Null, 'local_MAC') """)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def print_scan_stats(db):
|
||||
@@ -229,7 +226,7 @@ def create_new_devices (db):
|
||||
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Location'))}'"""
|
||||
|
||||
# Fetch data from CurrentScan skipping ignored devices by IP and MAC
|
||||
query = f"""SELECT cur_MAC, cur_Name, cur_Vendor, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type
|
||||
query = f"""SELECT cur_MAC, cur_Name, cur_Vendor, cur_ScanMethod, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type
|
||||
FROM CurrentScan """
|
||||
|
||||
|
||||
@@ -237,7 +234,7 @@ def create_new_devices (db):
|
||||
current_scan_data = sql.execute(query).fetchall()
|
||||
|
||||
for row in current_scan_data:
|
||||
cur_MAC, cur_Name, cur_Vendor, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type = row
|
||||
cur_MAC, cur_Name, cur_Vendor, cur_ScanMethod, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type = row
|
||||
|
||||
# Handle NoneType
|
||||
cur_Name = cur_Name.strip() if cur_Name else '(unknown)'
|
||||
@@ -262,6 +259,7 @@ def create_new_devices (db):
|
||||
dev_NetworkSite,
|
||||
dev_SSID,
|
||||
dev_DeviceType,
|
||||
dev_SourcePlugin,
|
||||
{newDevColumns}
|
||||
)
|
||||
VALUES
|
||||
@@ -279,6 +277,7 @@ def create_new_devices (db):
|
||||
'{sanitize_SQL_input(cur_NetworkSite)}',
|
||||
'{sanitize_SQL_input(cur_SSID)}',
|
||||
'{sanitize_SQL_input(cur_Type)}',
|
||||
'{sanitize_SQL_input(cur_ScanMethod)}',
|
||||
{newDevDefaults}
|
||||
)"""
|
||||
|
||||
@@ -459,7 +458,7 @@ def update_devices_data_from_scan (db):
|
||||
default_icon = get_setting_value('NEWDEV_dev_Icon')
|
||||
|
||||
for device in sql.execute (query) :
|
||||
# Conditional logic for dev_Icon guessing
|
||||
# Conditional logic for dev_Icon guessing
|
||||
dev_Icon = guess_icon(device['dev_Vendor'], device['dev_MAC'], device['dev_LastIP'], device['dev_Name'], default_icon)
|
||||
|
||||
recordsToUpdate.append ([dev_Icon, device['dev_MAC']])
|
||||
@@ -677,7 +676,10 @@ icons = {
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Guess device icon
|
||||
def guess_icon(vendor, mac, ip, name, default):
|
||||
def guess_icon(vendor, mac, ip, name, default):
|
||||
|
||||
mylog('debug', [f"[guess_icon] Guessing icon for (vendor|mac|ip|name): ('{vendor}'|'{mac}'|{ip}|{name})"])
|
||||
|
||||
result = default
|
||||
mac = mac.upper()
|
||||
vendor = vendor.lower() if vendor else "unknown"
|
||||
@@ -706,7 +708,7 @@ def guess_icon(vendor, mac, ip, name, default):
|
||||
result = icons.get("microchip")
|
||||
|
||||
# Guess icon based on MAC address patterns
|
||||
elif mac == "INTERNET": # Apple
|
||||
elif mac == "INTERNET":
|
||||
result = icons.get("globe")
|
||||
elif mac.startswith("00:1A:79"): # Apple
|
||||
result = icons.get("apple")
|
||||
@@ -764,4 +766,4 @@ def guess_type(vendor, mac, ip, name, default):
|
||||
result = "Router"
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ def ccd(key, default, config_dir, name, inputtype, options, group, events=None,
|
||||
# Single quotes might break SQL queries, replacing them
|
||||
if inputtype == 'text':
|
||||
result = result.replace('\'', "{s-quote}")
|
||||
|
||||
|
||||
# Create the tuples
|
||||
sql_safe_tuple = (key, name, desc, str(inputtype), options, regex, str(result), group, str(events), overriddenByEnv)
|
||||
@@ -295,10 +296,10 @@ def importConfigs (db, all_plugins):
|
||||
mylog('none', ['[Config] Plugins to load: ', loaded_plugins_prefixes])
|
||||
|
||||
conf.plugins_once_run = False
|
||||
# -----------------
|
||||
# Plugins END
|
||||
|
||||
# -----------------
|
||||
# HANDLE APP_CONF_OVERRIDE via app_conf_override.json
|
||||
|
||||
# Assuming fullConfFolder is defined elsewhere
|
||||
app_conf_override_path = fullConfFolder + '/app_conf_override.json'
|
||||
|
||||
@@ -310,23 +311,24 @@ def importConfigs (db, all_plugins):
|
||||
|
||||
# Loop through settings_override dictionary
|
||||
for setting_name, value in settings_override.items():
|
||||
|
||||
# Ensure the value is treated as a string and passed directly
|
||||
if isinstance(value, str):
|
||||
# Log the value being passed
|
||||
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
|
||||
mylog('debug', [f"[Config] Setting override {setting_name} with value: {value}"])
|
||||
ccd(setting_name, value, c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True, 1)
|
||||
else:
|
||||
# Convert to string and log
|
||||
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
|
||||
mylog('debug', [f"[Config] Setting override {setting_name} with value: {str(value)}"])
|
||||
ccd(setting_name, str(value), c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True, 1)
|
||||
if isinstance(value, str) == False:
|
||||
value = str(value)
|
||||
|
||||
# Log the value being passed
|
||||
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
|
||||
mylog('debug', [f"[Config] Setting override {setting_name} with value: {value}"])
|
||||
ccd(setting_name, value, c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True, 1)
|
||||
|
||||
except json.JSONDecodeError:
|
||||
mylog('none', [f"[Config] [ERROR] Setting override decoding JSON from {app_conf_override_path}"])
|
||||
else:
|
||||
mylog('debug', [f"[Config] File {app_conf_override_path} does not exist."])
|
||||
|
||||
# -----------------
|
||||
# HANDLE APP was upgraded message - clear cache
|
||||
|
||||
# Check if app was upgraded
|
||||
with open(applicationPath + '/front/buildtimestamp.txt', 'r') as f:
|
||||
|
||||
@@ -346,6 +348,9 @@ def importConfigs (db, all_plugins):
|
||||
write_notification(f'[Upgrade] : App upgraded 🚀 Please clear the cache: <ol> <li>Click OK below</li> <li>Clear the browser cache (shift + browser refresh button)</li> <li> Clear app cache with the 🔄 (reload) button in the header</li><li>Go to Settings and click Save</li> </ol> Check out new features and what has changed in the <a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank">📓 release notes</a>.', 'interrupt', timeNowTZ())
|
||||
|
||||
|
||||
# -----------------
|
||||
# Initialization finished, update DB and API endpoints
|
||||
|
||||
# Insert settings into the DB
|
||||
sql.execute ("DELETE FROM Settings")
|
||||
# mylog('debug', [f"[Config] conf.mySettingsSQLsafe : '{conf.mySettingsSQLsafe}'"])
|
||||
|
||||
@@ -206,10 +206,9 @@ def insert_events (db):
|
||||
END,
|
||||
'',
|
||||
1
|
||||
FROM LatestEventsPerMAC AS d
|
||||
JOIN CurrentScan AS c ON d.dev_MAC = c.cur_MAC
|
||||
LEFT JOIN LatestEventsPerMAC AS last_event ON d.dev_MAC = last_event.eve_MAC
|
||||
WHERE d.dev_PresentLastScan = 0
|
||||
FROM CurrentScan AS c
|
||||
LEFT JOIN LatestEventsPerMAC AS last_event ON c.cur_MAC = last_event.eve_MAC
|
||||
WHERE last_event.dev_PresentLastScan = 0 OR last_event.eve_MAC IS NULL
|
||||
""")
|
||||
|
||||
# Check disconnections
|
||||
|
||||
@@ -747,7 +747,7 @@ def process_plugin_events(db, plugin, pluginsState, plugEventsArr):
|
||||
sqlParams.append(tuple(tmpList))
|
||||
|
||||
# Generate the SQL INSERT query using the collected information.
|
||||
q = f'INSERT into {dbTable} ({columnsStr}) VALUES ({valuesStr})'
|
||||
q = f'INSERT OR IGNORE INTO {dbTable} ({columnsStr}) VALUES ({valuesStr})'
|
||||
|
||||
# Log a debug message showing the generated SQL query for mapping.
|
||||
mylog('debug', ['[Plugins] SQL query for mapping: ', q])
|
||||
|
||||
Reference in New Issue
Block a user