Compare commits
130 Commits
23.01.22-H
...
v23.04.01
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8fcf6227e | ||
|
|
310b6de2cc | ||
|
|
306535a2a6 | ||
|
|
5944b1b6f5 | ||
|
|
6de9e1d4bd | ||
|
|
4bf6ab9c8c | ||
|
|
1e93dfa35e | ||
|
|
7f2567264c | ||
|
|
d9a9246f1b | ||
|
|
aa8fb62f15 | ||
|
|
6d5eeb88d3 | ||
|
|
ea1d710209 | ||
|
|
032b787b66 | ||
|
|
7024cd22de | ||
|
|
b9b66d5af1 | ||
|
|
b73a0d6347 | ||
|
|
a0bc318ff9 | ||
|
|
642e8464cd | ||
|
|
63a9e55d4e | ||
|
|
a07c73155f | ||
|
|
efbc32d3ed | ||
|
|
83f50bd0d8 | ||
|
|
87cb0f50b5 | ||
|
|
73c779c238 | ||
|
|
40615cf17a | ||
|
|
6dd1448667 | ||
|
|
d8b4091043 | ||
|
|
7ea920efa9 | ||
|
|
7306dfbdd3 | ||
|
|
53c8c41133 | ||
|
|
395dfe5fe7 | ||
|
|
2ec0074a45 | ||
|
|
93dce378ea | ||
|
|
df6fae7aa5 | ||
|
|
57e0705e64 | ||
|
|
f3b31479c4 | ||
|
|
b914be9f0e | ||
|
|
2d0a4b79d8 | ||
|
|
d090b29c55 | ||
|
|
5a8be94cdc | ||
|
|
176a436ad4 | ||
|
|
1a05435691 | ||
|
|
49ce3edbdb | ||
|
|
51df759e25 | ||
|
|
992aa00c3c | ||
|
|
d87d933058 | ||
|
|
e0d639cba0 | ||
|
|
1cbbfb25cc | ||
|
|
f205e6f5c1 | ||
|
|
5e67ea22f5 | ||
|
|
99f522e625 | ||
|
|
f04cd7e28b | ||
|
|
3392a1f17c | ||
|
|
d0d9a1a65d | ||
|
|
16d04fe485 | ||
|
|
43d5c51e7c | ||
|
|
647013f3ff | ||
|
|
2ef631a440 | ||
|
|
86315a245b | ||
|
|
b0ce1b87a9 | ||
|
|
541c16aea6 | ||
|
|
ee1a3fc683 | ||
|
|
b90edcccbd | ||
|
|
4614b93780 | ||
|
|
4f548803cb | ||
|
|
d16dd95d65 | ||
|
|
97f7494c34 | ||
|
|
6179dabfa6 | ||
|
|
05ca683f91 | ||
|
|
170e61e73f | ||
|
|
33f0356ca7 | ||
|
|
4b9117dcb4 | ||
|
|
ec274c90da | ||
|
|
e7a1f013df | ||
|
|
c287bc2f22 | ||
|
|
5b8f8f2c5d | ||
|
|
887c2d0f42 | ||
|
|
06d7aa6623 | ||
|
|
5ed142a6b8 | ||
|
|
da9ca8a1f4 | ||
|
|
1cb5375a92 | ||
|
|
fd11cc30f5 | ||
|
|
a1bfdc0f18 | ||
|
|
e88362ce80 | ||
|
|
b5f0a64e7c | ||
|
|
e3623420b0 | ||
|
|
3344ed4b99 | ||
|
|
b0c91f7804 | ||
|
|
f8cf7f0717 | ||
|
|
29a6b78f27 | ||
|
|
388370b49d | ||
|
|
4d67c25e5a | ||
|
|
eec0dcca82 | ||
|
|
f1dc33761d | ||
|
|
7ea74d0fe3 | ||
|
|
0c635534a1 | ||
|
|
f70a3a4207 | ||
|
|
0fc174b5b3 | ||
|
|
d4eddf042d | ||
|
|
a4210c7e6b | ||
|
|
106438d61d | ||
|
|
94365d2cc9 | ||
|
|
b633c43078 | ||
|
|
84c3f1d786 | ||
|
|
1c963e9aff | ||
|
|
a2fe7f79cc | ||
|
|
8dabdb3f11 | ||
|
|
b9f2957104 | ||
|
|
bdeda87600 | ||
|
|
e98a538f53 | ||
|
|
2e0cb923db | ||
|
|
2e532abf6b | ||
|
|
51e865c98d | ||
|
|
2c27248aa1 | ||
|
|
43c2084e15 | ||
|
|
14cb0f46f3 | ||
|
|
162d507468 | ||
|
|
8624851cf5 | ||
|
|
2d92e93b7b | ||
|
|
78f9018083 | ||
|
|
ecb8a01aaa | ||
|
|
cca2c99f6b | ||
|
|
028d0dd7d8 | ||
|
|
7753e0481c | ||
|
|
5b35e68cf2 | ||
|
|
8b4115fe48 | ||
|
|
8bc1c3e0ed | ||
|
|
69061ed537 | ||
|
|
f151b1268d | ||
|
|
35d9c0e548 |
15
.github/workflows/docker_prod.yml
vendored
@@ -12,7 +12,8 @@ name: Publish Docker image
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
tags:
|
||||
- '*.*.*'
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -39,14 +40,12 @@ jobs:
|
||||
jokobsk/pi.alert
|
||||
# generate Docker tags based on the following events/attributes
|
||||
tags: |
|
||||
type=raw,value=latest
|
||||
type=schedule
|
||||
type=ref,event=branch
|
||||
type=semver,pattern={{version}},value=${{ inputs.version }}
|
||||
type=semver,pattern={{major}}.{{minor}},value=${{ inputs.version }}
|
||||
type=semver,pattern={{major}},value=${{ inputs.version }}
|
||||
type=ref,event=branch,suffix=-{{ sha }}
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=sha
|
||||
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') }}
|
||||
- name: Login to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v2
|
||||
|
||||
4
.gitignore
vendored
@@ -1,4 +1,8 @@
|
||||
.vscode
|
||||
.DS_Store
|
||||
config/pialert.conf
|
||||
db/*
|
||||
front/log/*
|
||||
front/plugins/**/*.log
|
||||
**/%40eaDir/
|
||||
**/@eaDir/
|
||||
|
||||
@@ -8,7 +8,7 @@ ENV USER=pi USER_ID=1000 USER_GID=1000 TZ=Europe/London PORT=20211
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends tini ca-certificates curl libwww-perl arp-scan perl apt-utils cron sudo nginx-light php php-cgi php-fpm php-sqlite3 php-curl sqlite3 dnsutils net-tools python3 iproute2 nmap python3-pip zip -y \
|
||||
&& pip3 install requests paho-mqtt scapy cron-converter pytz \
|
||||
&& pip3 install requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi \
|
||||
&& update-alternatives --install /usr/bin/python python /usr/bin/python3 10 \
|
||||
&& apt-get clean autoclean \
|
||||
&& apt-get autoremove \
|
||||
|
||||
80
README.md
@@ -7,7 +7,6 @@ Scans for devices connected to your WIFI / LAN and alerts you if new and unknown
|
||||
|
||||
![Main screen][main]
|
||||
|
||||
|
||||
# 🐳 Docker image
|
||||
[](https://github.com/jokob-sk/Pi.Alert/actions/workflows/docker_prod.yml)
|
||||
[](https://github.com/jokob-sk/Pi.Alert)
|
||||
@@ -15,7 +14,7 @@ Scans for devices connected to your WIFI / LAN and alerts you if new and unknown
|
||||
[](https://hub.docker.com/r/jokobsk/pi.alert)
|
||||
[](https://hub.docker.com/r/jokobsk/pi.alert)
|
||||
|
||||
🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/pi.alert) | 📄 [Dockerfile](https://github.com/jokob-sk/Pi.Alert/blob/main/Dockerfile) | 📚 [Docker instructions](https://github.com/jokob-sk/Pi.Alert/blob/main//dockerfiles/README.md) | 🆕 [Release notes](https://github.com/jokob-sk/Pi.Alert/releases)
|
||||
🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/pi.alert) | 📄 [Dockerfile](https://github.com/jokob-sk/Pi.Alert/blob/main/Dockerfile) | 📚 [Docker instructions](https://github.com/jokob-sk/Pi.Alert/blob/main/dockerfiles/README.md) | 🆕 [Release notes](https://github.com/jokob-sk/Pi.Alert/releases)
|
||||
|
||||
## 🔍 Scan Methods
|
||||
The system continuously scans the network for, **New devices**, **New connections** (re-connections), **Disconnections**, **"Always Connected" devices down**, Devices **IP changes** and **Internet IP address changes**. Scanning methods are:
|
||||
@@ -30,67 +29,53 @@ The system continuously scans the network for, **New devices**, **New connection
|
||||
examines the DHCP leases (addresses assigned) to find active devices
|
||||
that were not discovered by the other methods.
|
||||
|
||||
|
||||
## 🧩 Notification Integrations
|
||||
## 🧩 Integrations
|
||||
- [Apprise](https://hub.docker.com/r/caronc/apprise), [Pushsafer](https://www.pushsafer.com/), [NTFY](https://ntfy.sh/)
|
||||
- [Webhooks](https://github.com/jokob-sk/Pi.Alert/blob/main/docs/WEBHOOK_N8N.md) ([sample JSON](docs/webhook_json_sample.json))
|
||||
- Home Assistant via [MQTT](https://www.home-assistant.io/integrations/mqtt/)
|
||||
- discovery ~10s per device, deleting not supported, use [MQTT Explorer](https://mqtt-explorer.com/) for now
|
||||
- Home Assistant via [MQTT](https://www.home-assistant.io/integrations/mqtt/) - discovery ~10s per device, use [MQTT Explorer](https://mqtt-explorer.com/) to delete devices
|
||||
- [API endpoint](https://github.com/jokob-sk/Pi.Alert/blob/main/docs/API.md)
|
||||
- [Plugin system](https://github.com/jokob-sk/Pi.Alert/tree/main/front/plugins) for custom script monitoring
|
||||
|
||||
# 📥 Installation
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
|
||||
## 🔐 Security
|
||||
⚠ Only tested as a [docker container - follow these instructions here](dockerfiles/README.md).
|
||||
> Check out [leiweibau's fork](https://github.com/leiweibau/Pi.Alert/) if you want to install Pi.Alert on the server directly or original instructions for [pucherot's original code](https://github.com/pucherot/Pi.Alert/)
|
||||
|
||||
- Configurable login to prevent unauthorized use.
|
||||
|
||||
## 📑 Features
|
||||
# 📑 Features
|
||||
- Display:
|
||||
- Sessions, Connected devices, Favorites, Events, Presence, Concurrent devices, Down alerts, IP's
|
||||
- Manual Nmap scans, Optional speedtest for Device "Internet"
|
||||
- Simple Network relationship display
|
||||
- Maintenance tasks and Settings like:
|
||||
- Status Infos (active scans, database size, backup counter)
|
||||
- Theme Selection (blue, red, green, yellow, black, purple) and Light/Dark-Mode Switch
|
||||
- Language Selection (English, German, Spanish)
|
||||
- Pause arp-scan
|
||||
- DB maintenance, Backup, Restore tools and CSV Export / Import
|
||||
- Help/FAQ Section
|
||||
- Simple login Support
|
||||
- 🌟(Experimental) [Plugin system](https://github.com/jokob-sk/Pi.Alert/tree/main/front/plugins)
|
||||
- Create custom plugins with automatically generated settings and UI.
|
||||
- Monitor anything for changes
|
||||
- Check the instructions carefully if you are up for a challenge! Current plugins include:
|
||||
- Detecting Rogue DHCP servers
|
||||
- Monitoring HTTP status changes of domains/URLs
|
||||
- Import devices from DHCP.leases files or a UniFi controller
|
||||
|
||||
| ![Screen 1][screen1] | ![Screen 2][screen2] |
|
||||
|----------------------|----------------------|
|
||||
| ![Screen 3][screen3] | ![Screen 4][screen4] |
|
||||
| ![Screen 5][screen5] | ![Screen 6][screen6] |
|
||||
| ![Report 1][report1] | ![Report 2][report2] |
|
||||
| ![Screen 1][screen1] | ![Screen 2][screen2] | ![Screen 5][screen5] |
|
||||
|----------------------|----------------------| ----------------------|
|
||||
| ![Screen 3][screen3] | ![Screen 4][screen4] | ![Screen 6][screen6] |
|
||||
| ![Screen 8][screen8] | ![Report 2][report2] | ![Screen 9][screen9] |
|
||||
|
||||
|
||||
# 📥 Installation
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
|
||||
⚠ This [fork (jokob-sk)](https://github.com/jokob-sk/Pi.Alert) is only tested as a [docker container](dockerfiles/README.md). Check out [leiweibau's fork](https://github.com/leiweibau/Pi.Alert/) if you want to install Pi.Alert on the server directly.
|
||||
|
||||
Instructions for [pucherot's original code can be found here](https://github.com/pucherot/Pi.Alert/)
|
||||
|
||||
|
||||
## 🔗 Other
|
||||
|
||||
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
### Alternatives
|
||||
### 🔗 Other Alternatives
|
||||
|
||||
- [WatchYourLAN](https://github.com/aceberg/WatchYourLAN) - Lightweight network IP scanner with web GUI (Open source)
|
||||
- [Fing](https://www.fing.com/) - Network scanner app for your Internet security (Commercial, Phone App, Proprietary hardware)
|
||||
|
||||
### Old docs
|
||||
|
||||
- [Device Management instructions](docs/DEVICE_MANAGEMENT.md)
|
||||
- [Versions History](docs/VERSIONS_HISTORY.md)
|
||||
Device Management [instructions](docs/DEVICE_MANAGEMENT.md) | Old Versions [History](docs/VERSIONS_HISTORY.md)
|
||||
|
||||
### License
|
||||
GPL 3.0
|
||||
- [Read more here](LICENSE.txt)
|
||||
- Source of the [animated GIF (Loading Animation)](https://commons.wikimedia.org/wiki/File:Loading_Animation.gif)
|
||||
- Source of the [selfhosted Fonts](https://github.com/adobe-fonts/source-sans)
|
||||
GPL 3.0 | [Read more here](LICENSE.txt) | Source of the [animated GIF (Loading Animation)](https://commons.wikimedia.org/wiki/File:Loading_Animation.gif) | Source of the [selfhosted Fonts](https://github.com/adobe-fonts/source-sans)
|
||||
|
||||
### 🥇 Special thanks
|
||||
|
||||
@@ -101,8 +86,15 @@ Instructions for [pucherot's original code can be found here](https://github.com
|
||||
- [Macleykun](https://github.com/Macleykun): Help with Dockerfile clean-up
|
||||
- [Final-Hawk](https://github.com/Final-Hawk): Help with NTFY, styling and other fixes
|
||||
- [TeroRERO](https://github.com/terorero): Spanish translation
|
||||
- [jokob-sk](https://github.com/jokob-sk/Pi.Alert): DB Maintenance tools
|
||||
- Please see the [Git commit history](https://github.com/jokob-sk/Pi.Alert/commits/main) for a full list of people and their contributions to the project
|
||||
- Please see the [Git contributors](https://github.com/jokob-sk/Pi.Alert/graphs/contributors) for a full list of people and their contributions to the project
|
||||
|
||||
## ☕ Support me
|
||||
|
||||
<a href="https://github.com/sponsors/jokob-sk" target="_blank"><img src="https://i.imgur.com/X6p5ACK.png" alt="Sponsor Me on GitHub" style="height: 30px !important;width: 117px !important;" width="150px" ></a>
|
||||
<a href="https://www.buymeacoffee.com/jokobsk" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 30px !important;width: 117px !important;" width="117px" height="30px" ></a>
|
||||
<a href="https://www.patreon.com/user?u=84385063" target="_blank"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/82/Patreon_logo_with_wordmark.svg/512px-Patreon_logo_with_wordmark.svg.png" alt="Support me on patreon" style="height: 30px !important;width: 117px !important;" width="117px" ></a>
|
||||
|
||||
BTC: 1N8tupjeCK12qRVU2XrV17WvKK7LCawyZM
|
||||
|
||||
<!--- --------------------------------------------------------------------- --->
|
||||
[main]: ./docs/img/devices_split.png "Main screen"
|
||||
@@ -112,7 +104,9 @@ Instructions for [pucherot's original code can be found here](https://github.com
|
||||
[screen4]: ./docs/img/maintenance.png "Screen 4"
|
||||
[screen5]: ./docs/img/network.png "Screen 5"
|
||||
[screen6]: ./docs/img/settings.png "Screen 6"
|
||||
[screen7]: ./docs/img/help_faq.png "Screen 6"
|
||||
[screen7]: ./docs/img/help_faq.png "Screen 7"
|
||||
[screen8]: ./docs/img/plugins_webmon.png "Screen 8"
|
||||
[screen9]: ./docs/img/device_nmap.png "Screen 9"
|
||||
[report1]: ./docs/img/4_report_1.jpg "Report sample 1"
|
||||
[report2]: ./docs/img/4_report_2.jpg "Report sample 2"
|
||||
[main_dark]: /docs/img/1_devices_dark.jpg "Main screen dark"
|
||||
|
||||
2110
back/pialert.py
173
back/report_sample.html
Executable file
@@ -0,0 +1,173 @@
|
||||
<!-- ---------------------------------------------------------------------------
|
||||
# Pi.Alert
|
||||
# Open Source Network Guard / WIFI & LAN intrusion detector
|
||||
#
|
||||
# repot_template.html - Back module. Template to email reporting in HTML format
|
||||
#-------------------------------------------------------------------------------
|
||||
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3
|
||||
#--------------------------------------------------------------------------- -->
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<font face=sans-serif>
|
||||
<table align=center width=100% cellpadding=0 cellspacing=0 style="border-radius: 5px;">
|
||||
<tr>
|
||||
<td bgcolor=#EFB956 align=center style="padding: 20px 10px 10px 10px; font-size: 30px; font-weight: bold; color:#000000; border-top-right-radius: 5px; border-top-left-radius: 5px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
|
||||
Pi.Alert Report
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td bgcolor=#2656f1 width=100% align=center style="padding: 20px 10px 10px 10px; font-size: 20px; font-weight: bold; color:#ffffff; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
|
||||
<a style="color:#ffffff;cursor:pointer;" href="https://github.com/jokob-sk/Pi.Alert/releases">🆕 New version available 🆕</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table width=100% border=0 bgcolor=#FFD966 cellpadding=5px cellspacing=0 style="border-collapse: collapse; font-size: 15px; text-align:center; color:#404040">
|
||||
<tr>
|
||||
<td width=100%> Report Date: <b>2023-01-30 22:17</b> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td bgcolor=#F5F5F5 height=200 valign=top style="padding: 10px">
|
||||
<table style="border-collapse: collapse; font-size: 12px; color:#70707" width="100%" cellspacing="0" cellpadding="3px" bordercolor="#C0C0C0" border="1">
|
||||
<tr>
|
||||
<th width='120px' style='color:blue; font-size: 12px;' bgcolor='#909090' >New devices</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table style="border-collapse: collapse; font-size: 12px; color:#70707" width="100%" cellspacing="0" cellpadding="3px" bordercolor="#C0C0C0" border="1">
|
||||
<tr>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >MAC</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Datetime</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >IP</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Event Type</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Device name</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="http://192.168.1.1:20211/deviceDetails.php?mac=00:00:00:ef:a5:6c">00:00:00:ef:a5:6c</a></td>
|
||||
<td>2023-01-30 22:15:09</td>
|
||||
<td>192.168.1.1</td>
|
||||
<td>New Device</td>
|
||||
<td>(name not found)</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="http://192.168.1.1:20211/deviceDetails.php?mac=00:00:00:ef:a5:6c">00:00:00:ef:a5:6c</a></td>
|
||||
<td>2023-01-30 22:17:59</td>
|
||||
<td>192.168.1.82</td>
|
||||
<td>New Device</td>
|
||||
<td>(name not found)</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table style="border-collapse: collapse; font-size: 12px; color:#70707" width="100%" cellspacing="0" cellpadding="3px" bordercolor="#C0C0C0" border="1">
|
||||
<tr>
|
||||
<th width='120px' style='color:blue; font-size: 12px;' bgcolor='#909090' >Events</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<ul>
|
||||
<li>
|
||||
<table style="border-collapse: collapse; font-size: 12px; color:#70707" width="100%" cellspacing="0" cellpadding="3px" bordercolor="#C0C0C0" border="1">
|
||||
<tr>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >MAC</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Datetime</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >IP</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Event Type</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Device name</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="http://192.168.1.1:20211/deviceDetails.php?mac=00:00:00:ef:a5:6c">00:00:00:ef:a5:6c</a></td>
|
||||
<td>2023-01-30 22:15:09</td>
|
||||
<td>192.168.1.92</td>
|
||||
<td>Disconnected</td>
|
||||
<td>(name not found)</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table style="border-collapse: collapse; font-size: 12px; color:#70707" width="100%" cellspacing="0" cellpadding="3px" bordercolor="#C0C0C0" border="1">
|
||||
<tr>
|
||||
<th width='120px' style='color:blue; font-size: 12px;' bgcolor='#909090' >Changed or new ports</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table style="border-collapse: collapse; font-size: 12px; color:#70707" width="100%" cellspacing="0" cellpadding="3px" bordercolor="#C0C0C0" border="1">
|
||||
<tr>
|
||||
<th>new</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table style="border-collapse: collapse; font-size: 12px; color:#70707" width="100%" cellspacing="0" cellpadding="3px" bordercolor="#C0C0C0" border="1">
|
||||
<tr>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Name</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >MAC</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Port</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >State</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Service</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Extra</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>New device</td>
|
||||
<td><a href="http://192.168.1.1:20211/deviceDetails.php?mac=00:00:00:ef:a5:6c">00:00:00:ef:a5:6c</a></td>
|
||||
<td>3263/tcp</td>
|
||||
<td>open</td>
|
||||
<td>ecolor-imager</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table style="border-collapse: collapse; font-size: 12px; color:#70707" width="100%" cellspacing="0" cellpadding="3px" bordercolor="#C0C0C0" border="1">
|
||||
<tr>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Name</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >MAC</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Port</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >State</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Service</th>
|
||||
<th width='120px' style='color:#F0F0F0' bgcolor='#909090' >Extra</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>New device</td>
|
||||
<td><a href="http://192.168.1.1:20211/deviceDetails.php?mac=00:00:00:ef:a5:6c">00:00:00:ef:a5:6c</a></td>
|
||||
<td>3264/tcp</td>
|
||||
<td>open</td>
|
||||
<td>ccmail</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<tr>
|
||||
<td>
|
||||
<table width=100% bgcolor=#46802e cellpadding=5px cellspacing=0 style="font-size: 13px; font-weight: bold; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px;">
|
||||
<tr>
|
||||
<td width=50% style="text-align:center"> Pi.Alert - Synology-NAS</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</font>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
<!-- ---------------------------------------------------------------------------
|
||||
# Pi.Alert
|
||||
# Open Source Network Guard / WIFI & LAN intrusion detector
|
||||
#
|
||||
# repot_sample.html - Back module. Sample email reporting in HTML format
|
||||
#-------------------------------------------------------------------------------
|
||||
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3
|
||||
#--------------------------------------------------------------------------- -->
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<font face=sans-serif>
|
||||
<table align=center width=80% border=1 bordercolor=#909090 cellpadding=0 cellspacing=0 style="border-collapse: collapse; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.5)">
|
||||
<tr>
|
||||
<td bgcolor=#EFB956 align=center style="padding: 20px 10px 10px 10px; font-size: 36px; font-weight: bold; color:#7F6000; text-shadow: 4px 4px 6px #909090">
|
||||
Pi.Alert Report
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<table width=100% border=0 bgcolor=#FFD966 cellpadding=5px cellspacing=0 style="border-collapse: collapse; font-size: 16px; text-align:center; color:#5F5000">
|
||||
<tr>
|
||||
<td width=33%> Report Date: <b>2021-01-01 08:00</b> </td>
|
||||
<td width=34%> Scan Cycle: <b>1</b> </td>
|
||||
<td width=33%> Server: <b>pi4</b> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
<td bgcolor=#F5F5F5 height=400 valign=top style="padding: 20px">
|
||||
|
||||
|
||||
|
||||
<p style="font-size: 14px; font-weight: bold; color:#C04040; text-shadow: 2px 2px 4px #A0A0A0"> New Devices: </p>
|
||||
|
||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
|
||||
<tr bgcolor=#909090 style="color:#F0F0F0">
|
||||
<th width=140> MAC </th>
|
||||
<th width=130> Datetime </th>
|
||||
<th width=100> IP </th>
|
||||
<th> Vendor </th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> f8:d0:27:00:00:00 </td>
|
||||
<td> 2021-01-01 08:00:00 </td>
|
||||
<td> 192.168.1.20 </td>
|
||||
<td> Seiko Epson Corporation </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> c8:6c:3d:00:00:00 </td>
|
||||
<td> 2021-01-01 08:00:00 </td>
|
||||
<td> 192.168.1.181 </td>
|
||||
<td> Amazon Technologies Inc. </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
<p style="font-size: 14px; font-weight: bold; color:#C04040; text-shadow: 2px 2px 4px #A0A0A0"> Devices Down: </p>
|
||||
|
||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
|
||||
<tr bgcolor=#909090 style="color:#F0F0F0">
|
||||
<th width=140> MAC </th>
|
||||
<th width=130> Datetime </th>
|
||||
<th width=100> IP </th>
|
||||
<th> Device Name </th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> 0c:ee:99:00:00:00 </td>
|
||||
<td> 2021-01-01 08:00:00 </td>
|
||||
<td> 192.168.1.171 </td>
|
||||
<td> Alexa - Echo </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
<p style="font-size: 14px; font-weight: bold; color:#409040; text-shadow: 2px 2px 4px #A0A0A0"> Events: </p>
|
||||
|
||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
|
||||
<tr bgcolor=#909090 style="color:#F0F0F0">
|
||||
<th width=140> MAC </th>
|
||||
<th width=130> Datetime </th>
|
||||
<th width=100> IP </th>
|
||||
<th width=100> Event Type </th>
|
||||
<th width=140> Device Name </th>
|
||||
<th> Additional Info </th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> 94:0c:98:00:00:00 </td>
|
||||
<td> 2021-01-01 08:00:00 </td>
|
||||
<td> 192.168.1.132 </td>
|
||||
<td> Connected </td>
|
||||
<td> Person 1 - iPhone 11 </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> 5c:41:5a:00:00:00 </td>
|
||||
<td> 2021-01-01 08:00:00 </td>
|
||||
<td> 192.168.1.170 </td>
|
||||
<td> IP Changed </td>
|
||||
<td> Alexa Dot </td>
|
||||
<td> Previous IP: 192.168.1.243 </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<table width=100% border=0 bgcolor=#70AD47 cellpadding=5px cellspacing=0 style="border-collapse: collapse; font-size: 12px; font-weight: bold; color:#385723">
|
||||
<tr>
|
||||
<td width=25% style="text-align:Left"> Puche 2021</td>
|
||||
<td width=50% style="text-align:center"> Pi.Alert 2.50 / 2021-01-01 </td>
|
||||
<td width=25% style="text-align:right"> GNU GPLv3</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</font>
|
||||
</body>
|
||||
</html>
|
||||
@@ -32,74 +32,13 @@
|
||||
|
||||
<tr>
|
||||
<td bgcolor=#F5F5F5 height=200 valign=top style="padding: 10px">
|
||||
<SECTION_INTERNET>
|
||||
<p style="font-size: 24px; font-weight: bold; color:#C04040"> Internet: </p>
|
||||
|
||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070">
|
||||
<tr bgcolor=#909090 style="color:#f0f0f0">
|
||||
<th width=140> Event Type </th>
|
||||
<th width=130> Datetime </th>
|
||||
<th width=100> IP </th>
|
||||
<th> Additional Info </th>
|
||||
</tr>
|
||||
|
||||
<TABLE_INTERNET>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
</SECTION_INTERNET>
|
||||
|
||||
<SECTION_NEW_DEVICES>
|
||||
<p style="font-size: 14px; font-weight: bold; color:#C04040"> New Devices: </p>
|
||||
|
||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070">
|
||||
<tr bgcolor=#909090 style="color:#F0F0F0">
|
||||
<th width=150> MAC </th>
|
||||
<th width=130> Datetime </th>
|
||||
<th width=100> IP </th>
|
||||
<th width=140> Device Name </th>
|
||||
<th> Vendor </th>
|
||||
</tr>
|
||||
|
||||
<TABLE_NEW_DEVICES>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
</SECTION_NEW_DEVICES>
|
||||
|
||||
<SECTION_DEVICES_DOWN>
|
||||
<p style="font-size: 14px; font-weight: bold; color:#C04040"> Devices Down: </p>
|
||||
|
||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070">
|
||||
<tr bgcolor=#909090 style="color:#F0F0F0">
|
||||
<th width=140> MAC </th>
|
||||
<th width=130> Datetime </th>
|
||||
<th width=100> IP </th>
|
||||
<th> Device Name </th>
|
||||
</tr>
|
||||
|
||||
<TABLE_DEVICES_DOWN>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
</SECTION_DEVICES_DOWN>
|
||||
|
||||
<SECTION_EVENTS>
|
||||
<p style="font-size: 14px; font-weight: bold; color:#409040"> Events: </p>
|
||||
|
||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070">
|
||||
<tr bgcolor=#909090 style="color:#F0F0F0">
|
||||
<th width=140> MAC </th>
|
||||
<th width=130> Datetime </th>
|
||||
<th width=100> IP </th>
|
||||
<th width=100> Event Type </th>
|
||||
<th width=140> Device Name </th>
|
||||
<th> Additional Info </th>
|
||||
</tr>
|
||||
|
||||
<TABLE_EVENTS>
|
||||
</table>
|
||||
</SECTION_EVENTS>
|
||||
<INTERNET_TABLE>
|
||||
<NEW_DEVICES_TABLE>
|
||||
<DOWN_DEVICES_TABLE>
|
||||
<EVENTS_TABLE>
|
||||
<PORTS_TABLE>
|
||||
<PLUGINS_TABLE>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
Report Date: <REPORT_DATE>
|
||||
Server: <SERVER_NAME>
|
||||
|
||||
<SECTION_NEW_DEVICES>
|
||||
New Devices
|
||||
----------------------
|
||||
<TABLE_NEW_DEVICES>
|
||||
</SECTION_NEW_DEVICES><SECTION_DEVICES_DOWN>
|
||||
Devices Down
|
||||
----------------------
|
||||
<TABLE_DEVICES_DOWN>
|
||||
</SECTION_DEVICES_DOWN><SECTION_EVENTS>
|
||||
Events
|
||||
----------------------
|
||||
<TABLE_EVENTS>
|
||||
</SECTION_EVENTS><SECTION_INTERNET>
|
||||
Internet
|
||||
----------------------
|
||||
<TABLE_INTERNET>
|
||||
</SECTION_INTERNET>
|
||||
<SECTION_DEVICES_DOWN>
|
||||
<SECTION_EVENTS>
|
||||
<SECTION_INTERNET>
|
||||
<PORTS_TABLE>
|
||||
<PLUGINS_TABLE>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td bgcolor=#2656f1 width=100% align=center style="padding: 20px 10px 10px 10px; font-size: 20px; 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)">
|
||||
<td bgcolor=#2656f1 width=100% align=center style="padding: 20px 10px 10px 10px; font-size: 20px; font-weight: bold; color:#ffffff; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
|
||||
<a style="color:#ffffff;cursor:pointer;" href="https://github.com/jokob-sk/Pi.Alert/releases">🆕 New version available 🆕</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -36,76 +36,13 @@
|
||||
|
||||
<tr>
|
||||
<td bgcolor=#F5F5F5 height=200 valign=top style="padding: 10px">
|
||||
<SECTION_INTERNET>
|
||||
<p style="font-size: 24px; font-weight: bold; color:#C04040"> Internet: </p>
|
||||
|
||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070">
|
||||
<tr bgcolor=#909090 style="color:#f0f0f0">
|
||||
<th width=140> Event Type </th>
|
||||
<th width=130> Datetime </th>
|
||||
<th width=100> IP </th>
|
||||
<th> Additional Info </th>
|
||||
</tr>
|
||||
|
||||
<TABLE_INTERNET>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
</SECTION_INTERNET>
|
||||
|
||||
<SECTION_NEW_DEVICES>
|
||||
<p style="font-size: 14px; font-weight: bold; color:#C04040"> New Devices: </p>
|
||||
|
||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070">
|
||||
<tr bgcolor=#909090 style="color:#F0F0F0">
|
||||
<th width=150> MAC </th>
|
||||
<th width=130> Datetime </th>
|
||||
<th width=100> IP </th>
|
||||
<th width=140> Device Name </th>
|
||||
<th> Vendor </th>
|
||||
</tr>
|
||||
|
||||
<TABLE_NEW_DEVICES>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
</SECTION_NEW_DEVICES>
|
||||
|
||||
<SECTION_DEVICES_DOWN>
|
||||
<p style="font-size: 14px; font-weight: bold; color:#C04040"> Devices Down: </p>
|
||||
|
||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070">
|
||||
<tr bgcolor=#909090 style="color:#F0F0F0">
|
||||
<th width=140> MAC </th>
|
||||
<th width=130> Datetime </th>
|
||||
<th width=100> IP </th>
|
||||
<th> Device Name </th>
|
||||
</tr>
|
||||
|
||||
<TABLE_DEVICES_DOWN>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
</SECTION_DEVICES_DOWN>
|
||||
|
||||
<SECTION_EVENTS>
|
||||
<p style="font-size: 14px; font-weight: bold; color:#409040"> Events: </p>
|
||||
|
||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070">
|
||||
<tr bgcolor=#909090 style="color:#F0F0F0">
|
||||
<th width=140> MAC </th>
|
||||
<th width=130> Datetime </th>
|
||||
<th width=100> IP </th>
|
||||
<th width=100> Event Type </th>
|
||||
<th width=140> Device Name </th>
|
||||
<th> Additional Info </th>
|
||||
</tr>
|
||||
|
||||
<TABLE_EVENTS>
|
||||
</table>
|
||||
</SECTION_EVENTS>
|
||||
</td>
|
||||
</tr>
|
||||
<INTERNET_TABLE>
|
||||
<NEW_DEVICES_TABLE>
|
||||
<DOWN_DEVICES_TABLE>
|
||||
<EVENTS_TABLE>
|
||||
<PORTS_TABLE>
|
||||
<PLUGINS_TABLE>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
@@ -118,5 +55,7 @@
|
||||
</tr>
|
||||
</table>
|
||||
</font>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -26,16 +26,16 @@ sudo cp *.csv 2_backup
|
||||
echo ""
|
||||
echo Download Start
|
||||
echo ""
|
||||
sudo curl $1 -O https://standards-oui.ieee.org/iab/iab.csv \
|
||||
-O https://standards-oui.ieee.org/iab/iab.txt \
|
||||
-O https://standards-oui.ieee.org/oui28/mam.csv \
|
||||
-O https://standards-oui.ieee.org/iab/iab.txt \
|
||||
-O https://standards-oui.ieee.org/oui28/mam.csv \
|
||||
-O https://standards-oui.ieee.org/oui28/mam.txt \
|
||||
-O https://standards-oui.ieee.org/oui36/oui36.csv \
|
||||
-O https://standards-oui.ieee.org/oui36/oui36.txt \
|
||||
-O https://standards-oui.ieee.org/oui/oui.csv \
|
||||
-O https://standards-oui.ieee.org/oui/oui.txt
|
||||
sudo curl $1 -LO https://standards-oui.ieee.org/iab/iab.csv \
|
||||
-LO https://standards-oui.ieee.org/iab/iab.txt \
|
||||
-LO https://standards-oui.ieee.org/oui28/mam.csv \
|
||||
-LO https://standards-oui.ieee.org/iab/iab.txt \
|
||||
-LO https://standards-oui.ieee.org/oui28/mam.csv \
|
||||
-LO https://standards-oui.ieee.org/oui28/mam.txt \
|
||||
-LO https://standards-oui.ieee.org/oui36/oui36.csv \
|
||||
-LO https://standards-oui.ieee.org/oui36/oui36.txt \
|
||||
-LO https://standards-oui.ieee.org/oui/oui.csv \
|
||||
-LO https://standards-oui.ieee.org/oui/oui.txt
|
||||
echo ""
|
||||
echo Download Finished
|
||||
|
||||
|
||||
@@ -17,197 +17,68 @@
|
||||
"title": "Pi.Alert Notifications",
|
||||
"title_link": "",
|
||||
"text": {
|
||||
"internet": [
|
||||
[
|
||||
"Internet",
|
||||
"243.243.243.243",
|
||||
"2022-01-06 18:32:03",
|
||||
"Internet IP Changed",
|
||||
"Previous Internet IP: 0.0.0.0",
|
||||
1,
|
||||
null
|
||||
],
|
||||
[
|
||||
"Internet",
|
||||
"243.243.243.243",
|
||||
"2022-01-06 18:32:03",
|
||||
"New Device",
|
||||
null,
|
||||
1,
|
||||
null
|
||||
]
|
||||
],
|
||||
"new_devices": [
|
||||
[
|
||||
"b8:b8:b8:b8:b8:b8",
|
||||
"192.168.1.19",
|
||||
"2023-01-06 18:32:03",
|
||||
"New Device",
|
||||
"Raspberry Pi Foundation",
|
||||
1,
|
||||
null,
|
||||
"b8:b8:b8:b8:b8:b8",
|
||||
"raspberrypi",
|
||||
"(unknown)",
|
||||
null,
|
||||
"Raspberry Pi Foundation",
|
||||
0,
|
||||
null,
|
||||
null,
|
||||
"2021-01-06 18:32:03",
|
||||
"2021-01-06 18:32:03",
|
||||
"192.168.1.19",
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
1,
|
||||
1,
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
null
|
||||
],
|
||||
[
|
||||
"b1:b8:b8:b8:b8:b8",
|
||||
"192.168.1.45",
|
||||
"2021-01-06 18:32:03",
|
||||
"New Device",
|
||||
"EliteGroup Computer Systems Co., LTD",
|
||||
1,
|
||||
null,
|
||||
"b1:b8:b8:b8:b8:b8",
|
||||
"my-NUC",
|
||||
"(unknown)",
|
||||
null,
|
||||
"EliteGroup Computer Systems Co., LTD",
|
||||
0,
|
||||
null,
|
||||
null,
|
||||
"2023-01-06 18:32:03",
|
||||
"2023-01-06 18:32:03",
|
||||
"192.168.1.45",
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
1,
|
||||
1,
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
null
|
||||
]
|
||||
],
|
||||
"down_devices": [
|
||||
[
|
||||
"aa:77:aa:77:aa:77",
|
||||
"192.168.1.151",
|
||||
"2021-01-07 14:20:53",
|
||||
"Device Down",
|
||||
"",
|
||||
1,
|
||||
25,
|
||||
"aa:77:aa:77:aa:77",
|
||||
"ttgo_tdisplay_weather",
|
||||
"(unknown)",
|
||||
"",
|
||||
"Espressif Inc.",
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
"2021-01-06 23:13:06",
|
||||
"2021-01-06 23:13:06",
|
||||
"192.168.1.151",
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
"2021-01-06 23:34:37.067330",
|
||||
0,
|
||||
0,
|
||||
"",
|
||||
0,
|
||||
"",
|
||||
""
|
||||
]
|
||||
],
|
||||
"events": [
|
||||
[
|
||||
"aa:77:aa:77:aa:77",
|
||||
"192.168.1.151",
|
||||
"2022-08-12 21:48:00",
|
||||
"Connected",
|
||||
"",
|
||||
1,
|
||||
null,
|
||||
"aa:77:aa:77:aa:77",
|
||||
"ESP32 - display",
|
||||
"House",
|
||||
"",
|
||||
"Espressif Inc.",
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
"2022-07-21 20:35:00",
|
||||
"2022-08-12 21:48:00",
|
||||
"192.168.1.151",
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
"2022-08-12 21:42:47.937413",
|
||||
1,
|
||||
0,
|
||||
"",
|
||||
0,
|
||||
"aa:77:aa:77:aa:77",
|
||||
""
|
||||
],
|
||||
[
|
||||
"aa:77:aa:77:aa:77",
|
||||
"192.168.1.149",
|
||||
"2022-08-12 21:48:00",
|
||||
"Connected",
|
||||
"",
|
||||
1,
|
||||
null,
|
||||
"aa:77:aa:77:aa:77",
|
||||
"ESP32 - 1",
|
||||
"House",
|
||||
"Singleboard Computer (SBC)",
|
||||
"Espressif Inc.",
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
"2022-07-15 05:30:00",
|
||||
"2022-08-12 21:48:00",
|
||||
"192.168.1.149",
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
"2022-08-12 21:42:47.937413",
|
||||
1,
|
||||
1,
|
||||
"",
|
||||
0,
|
||||
"aa:77:aa:77:aa:77",
|
||||
""
|
||||
]
|
||||
]
|
||||
"internet": [],
|
||||
"new_devices": [{
|
||||
"MAC": "74:ac:74:ac:74:ac",
|
||||
"Datetime": "2023-01-30 22:15:09",
|
||||
"IP": "192.168.1.1",
|
||||
"Event Type": "New Device",
|
||||
"Device name": "(name not found)",
|
||||
"Comments": null
|
||||
}],
|
||||
"down_devices": [],
|
||||
"events": [{
|
||||
"MAC": "74:ac:74:ac:74:ac",
|
||||
"Datetime": "2023-01-30 22:15:09",
|
||||
"IP": "192.168.1.92",
|
||||
"Event Type": "Disconnected",
|
||||
"Device name": "(name not found)",
|
||||
"Comments": null
|
||||
}, {
|
||||
"MAC": "74:ac:74:ac:74:ac",
|
||||
"Datetime": "2023-01-30 22:15:09",
|
||||
"IP": "192.168.1.150",
|
||||
"Event Type": "Disconnected",
|
||||
"Device name": "(name not found)",
|
||||
"Comments": null
|
||||
}],
|
||||
"ports": [{
|
||||
"new": {
|
||||
"Name": "New device",
|
||||
"MAC": "74:ac:74:ac:74:ac",
|
||||
"Port": "22/tcp",
|
||||
"State": "open",
|
||||
"Service": "ssh",
|
||||
"Extra": ""
|
||||
}
|
||||
}, {
|
||||
"new": {
|
||||
"Name": "New device",
|
||||
"MAC": "74:ac:74:ac:74:ac",
|
||||
"Port": "53/tcp",
|
||||
"State": "open",
|
||||
"Service": "domain",
|
||||
"Extra": ""
|
||||
}
|
||||
}, {
|
||||
"new": {
|
||||
"Name": "New device",
|
||||
"MAC": "74:ac:74:ac:74:ac",
|
||||
"Port": "80/tcp",
|
||||
"State": "open",
|
||||
"Service": "http",
|
||||
"Extra": ""
|
||||
}
|
||||
}, {
|
||||
"new": {
|
||||
"Name": "New device",
|
||||
"MAC": "74:ac:74:ac:74:ac",
|
||||
"Port": "443/tcp",
|
||||
"State": "open",
|
||||
"Service": "https",
|
||||
"Extra": ""
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -23,7 +23,8 @@ PIALERT_WEB_PASSWORD='8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923a
|
||||
INCLUDED_SECTIONS=['internet','new_devices','down_devices','events']
|
||||
SCAN_CYCLE_MINUTES=5
|
||||
DAYS_TO_KEEP_EVENTS=90
|
||||
REPORT_DASHBOARD_URL='http://pi.alert/'
|
||||
# Used for generating links in emails. Make sure not to add a trailing slash!
|
||||
REPORT_DASHBOARD_URL='http://pi.alert'
|
||||
|
||||
|
||||
# Email
|
||||
@@ -103,7 +104,7 @@ DHCP_ACTIVE=False
|
||||
# Pholus
|
||||
#---------------------------
|
||||
PHOLUS_ACTIVE=False
|
||||
PHOLUS_TIMEOUT=20
|
||||
PHOLUS_TIMEOUT=120
|
||||
PHOLUS_FORCE=False
|
||||
PHOLUS_DAYS_DATA=7
|
||||
PHOLUS_RUN='once'
|
||||
|
||||
@@ -7,18 +7,22 @@ services:
|
||||
network_mode: "host"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ${APP_DATA_LOCATION}/pialert/config2:/home/pi/pialert/config
|
||||
- ${APP_DATA_LOCATION}/pialert2/config:/home/pi/pialert/config
|
||||
# - ${APP_DATA_LOCATION}/pialert/db/pialert.db:/home/pi/pialert/db/pialert.db
|
||||
- ${APP_DATA_LOCATION}/pialert/db2:/home/pi/pialert/db
|
||||
- ${APP_DATA_LOCATION}/pialert2/db:/home/pi/pialert/db
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
- ${LOGS_LOCATION}:/home/pi/pialert/front/log
|
||||
# DELETE START anyone trying to use this file: comment out / delete BELOW lines, they are only for development purposes
|
||||
- ${APP_DATA_LOCATION}/pialert/dhcp_samples/dhcp1.leases:/mnt/dhcp1.leases
|
||||
- ${APP_DATA_LOCATION}/pialert/dhcp_samples/dhcp2.leases:/mnt/dhcp2.leases
|
||||
- ${DEV_LOCATION}/back/pialert.py:/home/pi/pialert/back/pialert.py
|
||||
- ${DEV_LOCATION}/back/update_vendors.sh:/home/pi/pialert/back/update_vendors.sh
|
||||
- ${DEV_LOCATION}/back/report_template.html:/home/pi/pialert/back/report_template.html
|
||||
- ${DEV_LOCATION}/back/report_template_new_version.html:/home/pi/pialert/back/report_template_new_version.html
|
||||
- ${DEV_LOCATION}/back/report_template.txt:/home/pi/pialert/back/report_template.txt
|
||||
- ${DEV_LOCATION}/pholus:/home/pi/pialert/pholus
|
||||
- ${DEV_LOCATION}/dockerfiles:/home/pi/pialert/dockerfiles
|
||||
- ${APP_DATA_LOCATION}/pialert/php.ini:/etc/php/7.4/fpm/php.ini
|
||||
# - ${DEV_LOCATION}/front/api:/home/pi/pialert/front/api
|
||||
- ${DEV_LOCATION}/front/css:/home/pi/pialert/front/css
|
||||
- ${DEV_LOCATION}/front/lib/AdminLTE:/home/pi/pialert/front/lib/AdminLTE
|
||||
- ${DEV_LOCATION}/front/js:/home/pi/pialert/front/js
|
||||
@@ -26,12 +30,14 @@ services:
|
||||
- ${DEV_LOCATION}/front/deviceDetails.php:/home/pi/pialert/front/deviceDetails.php
|
||||
- ${DEV_LOCATION}/front/devices.php:/home/pi/pialert/front/devices.php
|
||||
- ${DEV_LOCATION}/front/events.php:/home/pi/pialert/front/events.php
|
||||
- ${DEV_LOCATION}/front/plugins.php:/home/pi/pialert/front/plugins.php
|
||||
- ${DEV_LOCATION}/front/help_faq.php:/home/pi/pialert/front/help_faq.php
|
||||
- ${DEV_LOCATION}/front/index.php:/home/pi/pialert/front/index.php
|
||||
- ${DEV_LOCATION}/front/maintenance.php:/home/pi/pialert/front/maintenance.php
|
||||
- ${DEV_LOCATION}/front/network.php:/home/pi/pialert/front/network.php
|
||||
- ${DEV_LOCATION}/front/presence.php:/home/pi/pialert/front/presence.php
|
||||
- ${DEV_LOCATION}/front/settings.php:/home/pi/pialert/front/settings.php
|
||||
- ${DEV_LOCATION}/front/plugins:/home/pi/pialert/front/plugins
|
||||
# DELETE END anyone trying to use this file: comment out / delete ABOVE lines, they are only for development purposes
|
||||
environment:
|
||||
- TZ=${TZ}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
# 🐳 A docker image for Pi.Alert
|
||||
|
||||
🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/pi.alert) | 📄 [Dockerfile](https://github.com/jokob-sk/Pi.Alert/blob/main/Dockerfile) | 📚 [Docker instructions](https://github.com/jokob-sk/Pi.Alert/blob/main//dockerfiles/README.md) | 🆕 [Release notes](https://github.com/jokob-sk/Pi.Alert/releases)
|
||||
🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/pi.alert) | 📄 [Dockerfile](https://github.com/jokob-sk/Pi.Alert/blob/main/Dockerfile) | 📚 [Docker instructions](https://github.com/jokob-sk/Pi.Alert/blob/main/dockerfiles/README.md) | 🆕 [Release notes](https://github.com/jokob-sk/Pi.Alert/releases)
|
||||
|
||||
<a href="https://raw.githubusercontent.com/jokob-sk/Pi.Alert/main/docs/img/devices_split.png" target="_blank">
|
||||
<img src="https://raw.githubusercontent.com/jokob-sk/Pi.Alert/main/docs/img/devices_split.png" width="300px" />
|
||||
@@ -48,17 +48,20 @@ docker run -d --rm --network=host \
|
||||
|Optional| `:/home/pi/pialert/front/log` | Logs folder useful for debugging if you have issues setting up the container |
|
||||
|Optional| `:/etc/pihole/pihole-FTL.db` | PiHole's `pihole-FTL.db` database file. Required if you want to use PiHole |
|
||||
|Optional| `:/etc/pihole/dhcp.leases` | PiHole's `dhcp.leases` file. Required if you want to use PiHole |
|
||||
|Optional| `:/home/pi/pialert/front/api` | A simple [API endpoint](https://github.com/jokob-sk/Pi.Alert/blob/main/docs/API.md) containing static (but regularly updated) json and other files. |
|
||||
|
||||
|
||||
### Config (`pialert.conf`)
|
||||
|
||||
- Modify [pialert.conf](https://github.com/jokob-sk/Pi.Alert/tree/main/config) or manage the configuration via Settings.
|
||||
- ❗ Set the `SCAN_SUBNETS` variable.
|
||||
- The preferred wy is to manage the configuration via Settings
|
||||
- YOu can modify [pialert.conf](https://github.com/jokob-sk/Pi.Alert/tree/main/config) directly if needed
|
||||
- ❗ To use the arp-scan method, you need to set the `SCAN_SUBNETS` variable. ()
|
||||
* The adapter will probably be `eth0` or `eth1`. (Run `iwconfig` to find your interface name(s))
|
||||
* Specify the network filter (which **significantly** speeds up the scan process). For example, the filter `192.168.1.0/24` covers IP ranges 192.168.1.0 to 192.168.1.255.
|
||||
* Examples for one and two subnets (❗ Note the `['...', '...']` format for two or more subnets):
|
||||
* Examples for one and two subnets (❗ Note the `['...', '...']` format):
|
||||
* One subnet: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0']`
|
||||
* Two subnets: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0', '192.168.1.0/24 --interface=eth1']`
|
||||
* More documentation on how to [setup vlans](https://github.com/jokob-sk/Pi.Alert/blob/main/docs/SUBNETS.md)
|
||||
|
||||
|
||||
### 🛑 **Common issues**
|
||||
@@ -112,6 +115,27 @@ To run the container execute: `sudo docker-compose up -d`
|
||||
|
||||
### Example 2
|
||||
|
||||
Example by [SeimuS](https://github.com/SeimusS).
|
||||
|
||||
```yaml
|
||||
pialert:
|
||||
container_name: PiAlert
|
||||
hostname: PiAlert
|
||||
privileged: true
|
||||
image: jokobsk/pi.alert:latest
|
||||
environment:
|
||||
- TZ=Europe/Bratislava
|
||||
restart: always
|
||||
volumes:
|
||||
- ./pialert/pialert_db:/home/pi/pialert/db
|
||||
- ./pialert/pialert_config:/home/pi/pialert/config
|
||||
network_mode: host
|
||||
```
|
||||
|
||||
To run the container execute: `sudo docker-compose up -d`
|
||||
|
||||
### Example 3
|
||||
|
||||
`docker-compose.yml`
|
||||
|
||||
```yaml
|
||||
@@ -157,7 +181,7 @@ DEV_LOCATION=/path/to/local/source/code
|
||||
|
||||
To run the container execute: `sudo docker-compose --env-file /path/to/.env up`
|
||||
|
||||
### Example 3
|
||||
### Example 4
|
||||
|
||||
Courtesy of [pbek](https://github.com/pbek). The volume `pialert_db` is used by the db directory. The two config files are mounted directly from a local folder to their places in the config folder. You can backup the `docker-compose.yaml` folder and the docker volumes folder.
|
||||
|
||||
@@ -187,8 +211,8 @@ Big thanks to <a href="https://github.com/Macleykun">@Macleykun</a> for help and
|
||||
|
||||
## ☕ Support me
|
||||
|
||||
Disclaimer: Please only donate if you don't have any debt yourself. Support yourself first, then others.
|
||||
|
||||
<a href="https://github.com/sponsors/jokob-sk" target="_blank"><img src="https://i.imgur.com/X6p5ACK.png" alt="Sponsor Me on GitHub" style="height: 30px !important;width: 117px !important;" width="150px" ></a>
|
||||
<a href="https://www.buymeacoffee.com/jokobsk" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 30px !important;width: 117px !important;" width="117px" height="30px" ></a>
|
||||
<a href="https://www.patreon.com/user?u=84385063" target="_blank"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/82/Patreon_logo_with_wordmark.svg/512px-Patreon_logo_with_wordmark.svg.png" alt="Support me on patreon" style="height: 30px !important;width: 117px !important;" width="117px" ></a>
|
||||
|
||||
BTC: 1N8tupjeCK12qRVU2XrV17WvKK7LCawyZM
|
||||
|
||||
103
docs/API.md
Executable file
@@ -0,0 +1,103 @@
|
||||
## API endpoints
|
||||
|
||||
PiAlert comes with a simple API. These API endpoints are static files, that are periodically updated based on your settings.
|
||||
|
||||
|
||||
### When are the endpoints updated
|
||||
|
||||
Once you enable the API (`ENABLE_API` setting), the endpoints are updated during these events:
|
||||
|
||||
1) Always during a notification event.
|
||||
2) (optional) If `API_RUN` is set to `schedule` on a specified cron-like schedule specified by the `API_RUN_SCHD` setting.
|
||||
3) (optional) If `API_RUN` is set to `interval` every N seconds specified by the `API_RUN_INTERVAL` setting (minimum 5).
|
||||
|
||||
|
||||
### Location of the endpoints
|
||||
|
||||
In the container, these files are located under the `/home/pi/pialert/front/api/` folder and thus on the `<pialert_url>/api/<File name>` url.
|
||||
|
||||
### Available endpoints
|
||||
|
||||
You can access the following files:
|
||||
|
||||
| File name | Description |
|
||||
|----------------------|----------------------|
|
||||
| `notification_text.txt` | The plain text version of the last notification. |
|
||||
| `notification_text.html` | The full HTML of the last email notification. |
|
||||
| `notification_json_final.json` | The json version of the last notification (e.g. used for webhooks - [sample JSON](https://github.com/jokob-sk/Pi.Alert/blob/main/back/webhook_json_sample.json)). |
|
||||
| `table_devices.json` | The current (at the time of the last update as mentioned above on this page) state of all of the available Devices detected by the app. |
|
||||
| `table_nmap_scan.json` | The current state of the discovered ports by the regular NMAP scans. |
|
||||
| `table_pholus_scan.json` | The latest state of the [pholus](https://github.com/jokob-sk/Pi.Alert/tree/main/pholus) (A multicast DNS and DNS Service Discovery Security Assessment Tool) scan results. |
|
||||
| `table_plugins_events.json` | The list of the unprocessed (pending) notification events (plugins_events DB table). |
|
||||
| `table_plugins_history.json` | The list of notification events history. |
|
||||
| `table_plugins_objects.json` | The content of the plugins_objects table. Find more info on the [Plugin system here](https://github.com/jokob-sk/Pi.Alert/tree/main/front/plugins)|
|
||||
| `language_strings.json` | The content of the language_strings table, which in turn is loaded from the plugins `config.json` definitions. |
|
||||
| `table_custom_endpoint.json` | A custom endpoint generated by the SQL query specified by the `API_CUSTOM_SQL` setting. |
|
||||
| `table_settings.json` | The content of the settings table. |
|
||||
|
||||
Current/latest state of the aforementioned files depends on your settings.
|
||||
|
||||
### JSON Data format
|
||||
|
||||
The endpoints starting with the `table_` prefix contain most, if not all, data contained in the corresponding database table. The common format for those is:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"db_column_name": "data",
|
||||
"db_column_name2": "data2"
|
||||
},
|
||||
{
|
||||
"db_column_name": "data3",
|
||||
"db_column_name2": "data4"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Example JSON of the `table_devices.json` endpoint with two Devices (database rows):
|
||||
|
||||
```JSON
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"dev_MAC": "Internet",
|
||||
"dev_Name": "Net - Huawei",
|
||||
"dev_DeviceType": "Router",
|
||||
"dev_Vendor": null,
|
||||
"dev_Group": "Always on",
|
||||
"dev_FirstConnection": "2021-01-01 00:00:00",
|
||||
"dev_LastConnection": "2021-01-28 22:22:11",
|
||||
"dev_LastIP": "192.168.1.24",
|
||||
"dev_StaticIP": 0,
|
||||
"dev_PresentLastScan": 1,
|
||||
"dev_LastNotification": "2023-01-28 22:22:28.998715",
|
||||
"dev_NewDevice": 0,
|
||||
"dev_Network_Node_MAC_ADDR": "",
|
||||
"dev_Network_Node_port": "",
|
||||
"dev_Icon": "globe"
|
||||
},
|
||||
{
|
||||
"dev_MAC": "a4:8f:ff:aa:ba:1f",
|
||||
"dev_Name": "Net - USG",
|
||||
"dev_DeviceType": "Firewall",
|
||||
"dev_Vendor": "Ubiquiti Inc",
|
||||
"dev_Group": "",
|
||||
"dev_FirstConnection": "2021-02-12 22:05:00",
|
||||
"dev_LastConnection": "2021-07-17 15:40:00",
|
||||
"dev_LastIP": "192.168.1.1",
|
||||
"dev_StaticIP": 1,
|
||||
"dev_PresentLastScan": 1,
|
||||
"dev_LastNotification": "2021-07-17 15:40:10.667717",
|
||||
"dev_NewDevice": 0,
|
||||
"dev_Network_Node_MAC_ADDR": "Internet",
|
||||
"dev_Network_Node_port": 1,
|
||||
"dev_Icon": "shield-halved"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
31
docs/DEBUG_INVALID_JSON.md
Executable file
@@ -0,0 +1,31 @@
|
||||
# How to debug the Invalid JSON response error
|
||||
|
||||
Check the the HTTP response of the failing backend call by following these steps:
|
||||
|
||||
- Open developer console in your browser (usually, e. g. for Chrome, key F12 on the keyboard).
|
||||
- Follow the steps in this screenshot:
|
||||
|
||||
![F12DeveloperConsole][F12DeveloperConsole]
|
||||
|
||||
- Copy the URL causing the error and enter it in the address bar of your browser directly and hit enter. The copied URLs could look something like this (notice the query strings at the end):
|
||||
- `http://<pialert URL>:20211/php/server/devices.php?action=getDevicesTotals`
|
||||
- `http://<pialert URL>:20211/php/server/devices.php?action=getDevicesList&status=all`
|
||||
|
||||
- Post the error response in the existing issue thread on GitHub or create a new issue and include the redacted response of the failing query.
|
||||
|
||||
For reference, the above queries should return results in the following format:
|
||||
|
||||
First URL:
|
||||
|
||||
![array][array]
|
||||
|
||||
Second URL:
|
||||
|
||||
![json][json]
|
||||
|
||||
You can copy and paste any JSON result (result of the second query) into an online JSON checker, such as [this one](https://jsonchecker.com/) to check if it's valid.
|
||||
|
||||
|
||||
[F12DeveloperConsole]: ./img/DEBUG/Invalid_JSON_repsonse_debug.png "F12DeveloperConsole"
|
||||
[array]: ./img/DEBUG/array_result_example.png "array"
|
||||
[json]: ./img/DEBUG/JSON_result_example.png "json"
|
||||
43
docs/NETWORK_TREE.md
Executable file
@@ -0,0 +1,43 @@
|
||||
## How to setup your Network page
|
||||
|
||||
Make sure you have a root device with the MAC `Internet` (No other MAC addresses are currently support as root)
|
||||
|
||||
To setup a device named `rapberrypi` as a `Switch` in our network.
|
||||
|
||||
### 1) Device details page
|
||||
|
||||
- Go to the `Devices` (1) page:
|
||||
|
||||

|
||||
|
||||
- In the (2) `Details` tab navigate to the the `Type` (3) dropdown and select the type `Switch` (4).
|
||||
|
||||
> Note: Only the following device types will show up as selectable Network nodes ( = devices you can connect other devices to):
|
||||
> AP, Firewall, Gateway, PLC, Powerline, Router, Switch, USB LAN Adapter, USB WIFI Adapter and WLAN.
|
||||
|
||||
- Assign a device to your root device from the `Node` (5) dropdown which has the MAC `Internet` (6) (Your name may differ, but the MAC needs to be set to `Internet` - this is done by default).
|
||||
|
||||
- Save your changes (7)
|
||||
|
||||
### 1) Network page
|
||||
|
||||
- Navigate to your `Network` (1) page:
|
||||
|
||||

|
||||
|
||||
- Notice the newly added `raspberrypi` (2) tab which now represents a network node, also showing up in the tree (3).
|
||||
- As we asssigned the `raspberrypi` in the previous 1) Device details page section to the `Internet` parent network node in step (6), the link is also showing up in the tree diagram (4)
|
||||
- We can now assign the device `(AppleTV)` (5) to this `raspberrypi` node, representing a network Switch in this example
|
||||
|
||||
### 1) Network page with 2 levels
|
||||
|
||||
- After clicking the `Assign` button in the previous section, the `(AppleTV)` (1) device is now connected to our `raspberrypi` (2).
|
||||
|
||||

|
||||
|
||||
- You can see the `raspberrypi` represents the Network node type `Switch` (3)
|
||||
- The `(AppleTV)` to `raspberrypi` connection is also displayed in the table of `Connected devices` (4).
|
||||
- You can also see that our `raspberrypi` node is connected to it's Parent network device node with the MAC `Internet` (5). This connection again shows up in the tree (6) as well.
|
||||
|
||||
|
||||
|
||||
15
docs/SMTP_GMAIL.md
Executable file
@@ -0,0 +1,15 @@
|
||||
## Use the Gmail SMTP server
|
||||
|
||||
1) Create an app password by following the instructions from Google, you need to Enable 2FA for this to work.
|
||||
[https://support.google.com/accounts/answer/185833](https://support.google.com/accounts/answer/185833)
|
||||
|
||||
2) Specify the following settings:
|
||||
|
||||
```python
|
||||
SMTP_SKIP_TLS=True
|
||||
SMTP_FORCE_SSL=True
|
||||
SMTP_PORT=465
|
||||
SMTP_SERVER='smtp.gmail.com'
|
||||
SMTP_PASS='16-digit passcode from google'
|
||||
```
|
||||
|
||||
21
docs/SUBNETS.md
Executable file
@@ -0,0 +1,21 @@
|
||||
## Subnets configuration
|
||||
|
||||
The arp-scan time itself depends on the number of IP addresses to check.
|
||||
The number of IPs to check depends on the [network mask](https://www.calculator.net/ip-subnet-calculator.html) you set on the `SCAN_SUBNETS` setting.
|
||||
|
||||
For example, a `/24` mask results in 256 IPs to check, where as a `/16` mask checks around 65,536. Every IP takes a couple seconds. This means that with an incorrect configuration the arp-scan will take hours to complete instead of seconds.
|
||||
|
||||
- Specify the network mask. For example, the filter `192.168.1.0/24` covers IP ranges 192.168.1.0 to 192.168.1.255
|
||||
- Run `iwconfig` in your container to find your interface name(s) (e.g.: `eth0`, `eth1`).
|
||||
- Append e.g.: ` -vlan=107` to the interface field (e.g.: `eth0 -vlan=107`) for multiple vlans. More details in this [comment in this issue](https://github.com/jokob-sk/Pi.Alert/issues/170#issuecomment-1419902988)
|
||||
|
||||
### Example:
|
||||
|
||||

|
||||
|
||||
### Support for VLANS
|
||||
|
||||
Please note about the accessibility of the macvlans when they are configured on the same computer. My understanding this is a general networking behavior, but feel free to clarify via a PR/issue.
|
||||
|
||||
- Pi.Alert does not detect the macvlan container when it is running on the same computer.
|
||||
- Pi.Alert recognizes the macvlan container when it is running on a different computer.
|
||||
@@ -1,12 +1,18 @@
|
||||
### Create a simple n8n workflow
|
||||

|
||||
|
||||

|
||||
|
||||
### Specify your email template
|
||||
See [sample JSON](https://github.com/jokob-sk/Pi.Alert/blob/main/back/webhook_json_sample.json) if you want to see the JSON paths used in the email template below
|
||||

|
||||

|
||||
|
||||
```
|
||||
Events count: {{ $json["body"]["attachments"][0]["text"]["events"].length }}
|
||||
New devices count: {{ $json["body"]["attachments"][0]["text"]["new_devices"].length }}
|
||||
```
|
||||
|
||||
### Get your webhook in n8n
|
||||

|
||||

|
||||
|
||||
### Configure PiAlert to point to the above URL
|
||||

|
||||

|
||||
|
||||
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 32 KiB |
BIN
docs/img/DEBUG/Invalid_JSON_repsonse_debug.png
Executable file
|
After Width: | Height: | Size: 197 KiB |
BIN
docs/img/DEBUG/JSON_result_example.png
Executable file
|
After Width: | Height: | Size: 54 KiB |
BIN
docs/img/DEBUG/array_result_example.png
Executable file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
docs/img/NETWORK_TREE/Device_Details_Network_Type.png
Executable file
|
After Width: | Height: | Size: 100 KiB |
BIN
docs/img/NETWORK_TREE/Network_Page.png
Executable file
|
After Width: | Height: | Size: 185 KiB |
BIN
docs/img/NETWORK_TREE/Network_Page_2_Levels.png
Executable file
|
After Width: | Height: | Size: 89 KiB |
BIN
docs/img/SUBNETS/subnets_vlan.png
Executable file
|
After Width: | Height: | Size: 20 KiB |
BIN
docs/img/WEBHOOK_N8N/Webhook_settings.png
Executable file
|
After Width: | Height: | Size: 61 KiB |
BIN
docs/img/WEBHOOK_N8N/n8n_send_email_settings.png
Executable file
|
After Width: | Height: | Size: 38 KiB |
BIN
docs/img/WEBHOOK_N8N/n8n_webhook_settings.png
Executable file
|
After Width: | Height: | Size: 31 KiB |
BIN
docs/img/WEBHOOK_N8N/n8n_workflow.png
Executable file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
docs/img/device_nmap.png
Executable file
|
After Width: | Height: | Size: 157 KiB |
BIN
docs/img/plugins.png
Executable file
|
After Width: | Height: | Size: 218 KiB |
BIN
docs/img/plugins_json_settings.png
Executable file
|
After Width: | Height: | Size: 185 KiB |
BIN
docs/img/plugins_json_ui.png
Executable file
|
After Width: | Height: | Size: 173 KiB |
BIN
docs/img/plugins_settings.png
Executable file
|
After Width: | Height: | Size: 158 KiB |
BIN
docs/img/plugins_webmon.png
Executable file
|
After Width: | Height: | Size: 92 KiB |
@@ -1,80 +0,0 @@
|
||||
<!-- ---------------------------------------------------------------------------
|
||||
# Pi.Alert
|
||||
# Open Source Network Guard / WIFI & LAN intrusion detector
|
||||
#
|
||||
# repot_sample.html - Back module. Sample email reporting in HTML format
|
||||
#-------------------------------------------------------------------------------
|
||||
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3
|
||||
#--------------------------------------------------------------------------- -->
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<font face=sans-serif>
|
||||
<table align=center width=80% border=1 bordercolor=#909090 cellpadding=0 cellspacing=0 style="border-collapse: collapse; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.5)">
|
||||
<tr>
|
||||
<td bgcolor=#EFB956 align=center style="padding: 20px 10px 10px 10px; font-size: 36px; font-weight: bold; color:#7F6000; text-shadow: 4px 4px 6px #909090">
|
||||
Pi.Alert Report
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<table width=100% border=0 bgcolor=#FFD966 cellpadding=5px cellspacing=0 style="border-collapse: collapse; font-size: 16px; text-align:center; color:#5F5000">
|
||||
<tr>
|
||||
<td width=33%> Report Date: <b>2021-01-01 08:00</b> </td>
|
||||
<td width=34%> Scan Cycle: <b>Internet</b> </td>
|
||||
<td width=33%> Server: <b>pi4</b> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td bgcolor=#F5F5F5 valign=top height=400 style="padding: 20px">
|
||||
|
||||
<p style="font-size: 24px; font-weight: bold; color:#C04040; text-shadow: 2px 2px 4px #A0A0A0"> Internet: </p>
|
||||
|
||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
|
||||
<tr bgcolor=#909090 style="color:#F0F0F0">
|
||||
<th width=140> Event Type </th>
|
||||
<th width=130> Datetime </th>
|
||||
<th width=100> IP </th>
|
||||
<th> Additional Info </th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Internet IP Changed </td>
|
||||
<td> 2021-01-01 08:00:00 </td>
|
||||
<td style="font-size: 24px; color:#D02020"> 1.1.1.0 </td>
|
||||
<td> Previous Internet IP: 1.1.0.0 </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<br>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<table width=100% border=0 bgcolor=#70AD47 cellpadding=5px cellspacing=0 style="border-collapse: collapse; font-size: 12px; font-weight: bold; color:#385723">
|
||||
<tr>
|
||||
<td width=25% style="text-align:Left"> Puche 2021</td>
|
||||
<td width=50% style="text-align:center"> Pi.Alert 2.50 / 2021-01-01 </td>
|
||||
<td width=25% style="text-align:right"> GNU GPLv3</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</font>
|
||||
</body>
|
||||
</html>
|
||||
2
front/api/.gitignore
vendored
Executable file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
@@ -592,6 +592,13 @@ height: 50px;
|
||||
|
||||
.nav-tabs-custom .tab-content {
|
||||
background-color: white;
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.nav-tabs-custom .tab-content {
|
||||
overflow: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
.top_small_box_gray_text {
|
||||
@@ -623,13 +630,14 @@ height: 50px;
|
||||
width:30%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.setting_description {
|
||||
/* color: green; */
|
||||
display: block;
|
||||
}
|
||||
.setting_input{
|
||||
width:35%;
|
||||
width:40%;
|
||||
/* background-color: green; */
|
||||
}
|
||||
.setting_name
|
||||
@@ -663,7 +671,7 @@ height: 50px;
|
||||
|
||||
.setting_description
|
||||
{
|
||||
width:46%;
|
||||
width:40%;
|
||||
}
|
||||
|
||||
.myhidden
|
||||
@@ -741,6 +749,19 @@ height: 50px;
|
||||
background-color:#606060;
|
||||
}
|
||||
|
||||
.networkPageHelp{
|
||||
position: absolute;
|
||||
font-size: x-small;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.pageHelp{
|
||||
position: absolute;
|
||||
font-size: x-small;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
|
||||
#networkTree .box
|
||||
{
|
||||
padding:2px;
|
||||
@@ -793,5 +814,28 @@ height: 50px;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.plugin-content
|
||||
{
|
||||
padding-bottom: 7px;
|
||||
}
|
||||
.plugin-content #tabs-content-location
|
||||
{
|
||||
margin-top: 20px;
|
||||
margin-left: 7px;
|
||||
margin-right: 7px;
|
||||
margin-bottom: 9px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.plugins-description
|
||||
{
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.login-page .login-custom
|
||||
{
|
||||
width:480px;
|
||||
|
||||
}
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
<?php
|
||||
require 'php/templates/header.php';
|
||||
require 'php/server/db.php';
|
||||
?>
|
||||
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
@@ -26,11 +25,11 @@
|
||||
<!-- period selector -->
|
||||
<span class="breadcrumb" style="top: 0px;">
|
||||
<select class="form-control" id="period" onchange="javascript: periodChanged();">
|
||||
<option value="1 day"><?php echo lang('DevDetail_Periodselect_today');?></option>
|
||||
<option value="7 days"><?php echo lang('DevDetail_Periodselect_LastWeek');?></option>
|
||||
<option value="1 month" selected><?php echo lang('DevDetail_Periodselect_LastMonth');?></option>
|
||||
<option value="1 year"><?php echo lang('DevDetail_Periodselect_LastYear');?></option>
|
||||
<option value="100 years"><?php echo lang('DevDetail_Periodselect_All');?></option>
|
||||
<option value="1 day"><?= lang('DevDetail_Periodselect_today');?></option>
|
||||
<option value="7 days"><?= lang('DevDetail_Periodselect_LastWeek');?></option>
|
||||
<option value="1 month" selected><?= lang('DevDetail_Periodselect_LastMonth');?></option>
|
||||
<option value="1 year"><?= lang('DevDetail_Periodselect_LastYear');?></option>
|
||||
<option value="100 years"><?= lang('DevDetail_Periodselect_All');?></option>
|
||||
</select>
|
||||
</span>
|
||||
</section>
|
||||
@@ -45,7 +44,7 @@
|
||||
<a href="#" onclick="javascript: $('#tabDetails').trigger('click')">
|
||||
<div class="small-box bg-aqua">
|
||||
<div class="inner"> <h3 id="deviceStatus" style="margin-left: 0em"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('DevDetail_Shortcut_CurrentStatus');?></p>
|
||||
<p class="infobox_label"><?= lang('DevDetail_Shortcut_CurrentStatus');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i id="deviceStatusIcon" class=""></i></div>
|
||||
</div>
|
||||
@@ -57,7 +56,7 @@
|
||||
<a href="#" onclick="javascript: $('#tabSessions').trigger('click');">
|
||||
<div class="small-box bg-green">
|
||||
<div class="inner"> <h3 id="deviceSessions"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('DevDetail_Shortcut_Sessions');?></p>
|
||||
<p class="infobox_label"><?= lang('DevDetail_Shortcut_Sessions');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i class="fa fa-plug"></i> </div>
|
||||
</div>
|
||||
@@ -69,7 +68,7 @@
|
||||
<a href="#" onclick="javascript: $('#tabPresence').trigger('click')">
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner"> <h3 id="deviceEvents" style="margin-left: 0em"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('DevDetail_Shortcut_Presence');?></p>
|
||||
<p class="infobox_label"><?= lang('DevDetail_Shortcut_Presence');?></p>
|
||||
</div>
|
||||
<div id="deviceEventsIcon" class="icon"> <i class="fa fa-calendar"></i> </div>
|
||||
</div>
|
||||
@@ -81,7 +80,7 @@
|
||||
<a href="#" onclick="javascript: $('#tabEvents').trigger('click');">
|
||||
<div class="small-box bg-red">
|
||||
<div class="inner"> <h3 id="deviceDownAlerts"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('DevDetail_Shortcut_DownAlerts');?></p>
|
||||
<p class="infobox_label"><?= lang('DevDetail_Shortcut_DownAlerts');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i class="fa fa-warning"></i> </div>
|
||||
</div>
|
||||
@@ -99,15 +98,15 @@
|
||||
|
||||
<div id="navDevice" class="nav-tabs-custom">
|
||||
<ul class="nav nav-tabs" style="fon t-size:16px;">
|
||||
<li> <a id="tabDetails" href="#panDetails" data-toggle="tab"> <?php echo lang('DevDetail_Tab_Details');?> </a></li>
|
||||
<li> <a id="tabDetails" href="#panDetails" data-toggle="tab"> <?= lang('DevDetail_Tab_Details');?> </a></li>
|
||||
<?php
|
||||
if ($_REQUEST['mac'] == 'Internet') { $DevDetail_Tap_temp = "Tools"; } else { $DevDetail_Tap_temp = lang('DevDetail_Tab_Nmap');}
|
||||
?>
|
||||
<li> <a id="tabNmap" href="#panNmap" data-toggle="tab"> <?php echo $DevDetail_Tap_temp;?> </a></li>
|
||||
<li> <a id="tabSessions" href="#panSessions" data-toggle="tab"> <?php echo lang('DevDetail_Tab_Sessions');?> </a></li>
|
||||
<li> <a id="tabPresence" href="#panPresence" data-toggle="tab"> <?php echo lang('DevDetail_Tab_Presence');?> </a></li>
|
||||
<li> <a id="tabEvents" href="#panEvents" data-toggle="tab"> <?php echo lang('DevDetail_Tab_Events');?> </a></li>
|
||||
<li> <a id="tabPholus" href="#panPholus" data-toggle="tab"> <?php echo lang('DevDetail_Tab_Pholus');?> </a></li>
|
||||
<li> <a id="tabSessions" href="#panSessions" data-toggle="tab"> <?= lang('DevDetail_Tab_Sessions');?> </a></li>
|
||||
<li> <a id="tabPresence" href="#panPresence" data-toggle="tab"> <?= lang('DevDetail_Tab_Presence');?> </a></li>
|
||||
<li> <a id="tabEvents" href="#panEvents" data-toggle="tab"> <?= lang('DevDetail_Tab_Events');?> </a></li>
|
||||
<li> <a id="tabPholus" href="#panPholus" data-toggle="tab"> <?= lang('DevDetail_Tab_Pholus');?> </a></li>
|
||||
|
||||
<div class="btn-group pull-right">
|
||||
<button type="button" class="btn btn-default" style="padding: 10px; min-width: 30px;"
|
||||
@@ -134,12 +133,12 @@
|
||||
<div class="row">
|
||||
<!-- column 1 -->
|
||||
<div class="col-lg-4 col-sm-6 col-xs-12">
|
||||
<h4 class="bottom-border-aqua"><?php echo lang('DevDetail_MainInfo_Title');?></h4>
|
||||
<h4 class="bottom-border-aqua"><?= lang('DevDetail_MainInfo_Title');?></h4>
|
||||
<div class="box-body form-horizontal">
|
||||
|
||||
<!-- MAC -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_mac');?></label>
|
||||
<label class="col-sm-3 control-label"><?= lang('DevDetail_MainInfo_mac');?></label>
|
||||
<div class="col-sm-9">
|
||||
<input class="form-control" id="txtMAC" type="text" readonly value="--">
|
||||
</div>
|
||||
@@ -147,7 +146,7 @@
|
||||
|
||||
<!-- Name -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_Name');?></label>
|
||||
<label class="col-sm-3 control-label"><?= lang('DevDetail_MainInfo_Name');?></label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="txtName" type="text" value="--">
|
||||
@@ -158,7 +157,7 @@
|
||||
|
||||
<!-- Owner -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_Owner');?></label>
|
||||
<label class="col-sm-3 control-label"><?= lang('DevDetail_MainInfo_Owner');?></label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="txtOwner" type="text" value="--">
|
||||
@@ -175,7 +174,7 @@
|
||||
|
||||
<!-- Type -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_Type');?></label>
|
||||
<label class="col-sm-3 control-label"><?= lang('DevDetail_MainInfo_Type');?></label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="txtDeviceType" type="text" value="--">
|
||||
@@ -194,13 +193,13 @@
|
||||
<!-- Icon -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">
|
||||
<?php echo lang('DevDetail_Icon');?>
|
||||
<?= lang('DevDetail_Icon');?>
|
||||
<a href="https://fontawesome.com/search?q=laptop&o=r&m=free" target="_blank"> <span><i class="fa fa-fw fa-arrow-up-right-from-square"></i></a><span>
|
||||
</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input class="form-control" title="<?php echo lang('DevDetail_Icon_Descr');?>" id="txtIcon" type="text" value="--">
|
||||
<span class="input-group-addon" title='<?php echo lang('DevDetail_button_OverwriteIcons_Tooltip');?>'><i class="fa fa-copy pointer" onclick="askOverwriteIconType();"></i></span>
|
||||
<input class="form-control" title="<?= lang('DevDetail_Icon_Descr');?>" id="txtIcon" type="text" value="--">
|
||||
<span class="input-group-addon" title='<?= lang('DevDetail_button_OverwriteIcons_Tooltip');?>'><i class="fa fa-copy pointer" onclick="askOverwriteIconType();"></i></span>
|
||||
<span class="input-group-addon"><i class="fa fa-pencil pointer" onclick="editDrp('txtIcon');"></i></span>
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
|
||||
@@ -215,7 +214,7 @@
|
||||
|
||||
<!-- Vendor -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_Vendor');?></label>
|
||||
<label class="col-sm-3 control-label"><?= lang('DevDetail_MainInfo_Vendor');?></label>
|
||||
<div class="col-sm-9">
|
||||
<input class="form-control" id="txtVendor" type="text" value="--">
|
||||
</div>
|
||||
@@ -223,7 +222,7 @@
|
||||
|
||||
<!-- Favorite -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_Favorite');?></label>
|
||||
<label class="col-sm-3 control-label"><?= lang('DevDetail_MainInfo_Favorite');?></label>
|
||||
<div class="col-sm-9" style="padding-top:6px;">
|
||||
<input class="checkbox blue hidden" id="chkFavorite" type="checkbox">
|
||||
</div>
|
||||
@@ -231,7 +230,7 @@
|
||||
|
||||
<!-- Group -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_Group');?></label>
|
||||
<label class="col-sm-3 control-label"><?= lang('DevDetail_MainInfo_Group');?></label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="txtGroup" type="text" value="--">
|
||||
@@ -249,7 +248,7 @@
|
||||
|
||||
<!-- Location -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_Location');?></label>
|
||||
<label class="col-sm-3 control-label"><?= lang('DevDetail_MainInfo_Location');?></label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="txtLocation" type="text" value="--">
|
||||
@@ -267,7 +266,7 @@
|
||||
|
||||
<!-- Comments -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_Comments');?></label>
|
||||
<label class="col-sm-3 control-label"><?= lang('DevDetail_MainInfo_Comments');?></label>
|
||||
<div class="col-sm-9">
|
||||
<textarea class="form-control" rows="3" id="txtComments"></textarea>
|
||||
</div>
|
||||
@@ -280,12 +279,12 @@
|
||||
|
||||
<!-- column 2 -->
|
||||
<div class="col-lg-4 col-sm-6 col-xs-12">
|
||||
<h4 class="bottom-border-aqua"><?php echo lang('DevDetail_SessionInfo_Title');?></h4>
|
||||
<h4 class="bottom-border-aqua"><?= lang('DevDetail_SessionInfo_Title');?></h4>
|
||||
<div class="box-body form-horizontal">
|
||||
|
||||
<!-- Status -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label"><?php echo lang('DevDetail_SessionInfo_Status');?></label>
|
||||
<label class="col-sm-5 control-label"><?= lang('DevDetail_SessionInfo_Status');?></label>
|
||||
<div class="col-sm-7">
|
||||
<input class="form-control" id="txtStatus" type="text" readonly value="--">
|
||||
</div>
|
||||
@@ -293,7 +292,7 @@
|
||||
|
||||
<!-- First Session -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label"><?php echo lang('DevDetail_SessionInfo_FirstSession');?></label>
|
||||
<label class="col-sm-5 control-label"><?= lang('DevDetail_SessionInfo_FirstSession');?></label>
|
||||
<div class="col-sm-7">
|
||||
<input class="form-control" id="txtFirstConnection" type="text" readonly value="--">
|
||||
</div>
|
||||
@@ -301,7 +300,7 @@
|
||||
|
||||
<!-- Last Session -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label"><?php echo lang('DevDetail_SessionInfo_LastSession');?></label>
|
||||
<label class="col-sm-5 control-label"><?= lang('DevDetail_SessionInfo_LastSession');?></label>
|
||||
<div class="col-sm-7">
|
||||
<input class="form-control" id="txtLastConnection" type="text" readonly value="--">
|
||||
</div>
|
||||
@@ -309,7 +308,7 @@
|
||||
|
||||
<!-- Last IP -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label"><?php echo lang('DevDetail_SessionInfo_LastIP');?></label>
|
||||
<label class="col-sm-5 control-label"><?= lang('DevDetail_SessionInfo_LastIP');?></label>
|
||||
<div class="col-sm-7">
|
||||
<input class="form-control" id="txtLastIP" type="text" readonly value="--">
|
||||
</div>
|
||||
@@ -317,21 +316,21 @@
|
||||
|
||||
<!-- Static IP -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label"><?php echo lang('DevDetail_SessionInfo_StaticIP');?></label>
|
||||
<label class="col-sm-5 control-label"><?= lang('DevDetail_SessionInfo_StaticIP');?></label>
|
||||
<div class="col-sm-7" style="padding-top:6px;">
|
||||
<input class="checkbox blue hidden" id="chkStaticIP" type="checkbox">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Network -->
|
||||
<h4 class="bottom-border-aqua"><?php echo lang('DevDetail_MainInfo_Network_Title');?></h4>
|
||||
<h4 class="bottom-border-aqua"><?= lang('DevDetail_MainInfo_Network_Title');?><span class="networkPageHelp"> <a target="_blank" href="https://github.com/jokob-sk/Pi.Alert/blob/main/docs/NETWORK_TREE.md"><i class="fa fa-circle-question"></i></a><span></h4>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_Network');?></label>
|
||||
<label class="col-sm-3 control-label"><?= lang('DevDetail_MainInfo_Network');?></label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
|
||||
<input class="form-control" id="txtNetworkNodeMac" type="text" value="--">
|
||||
<span class="input-group-addon"><i title="<?php echo lang('DevDetail_GoToNetworkNode');?>" class="fa fa-square-up-right pointer" onclick="goToNetworkNode('txtNetworkNodeMac');"></i></span>
|
||||
<span class="input-group-addon"><i title="<?= lang('DevDetail_GoToNetworkNode');?>" class="fa fa-square-up-right pointer" onclick="goToNetworkNode('txtNetworkNodeMac');"></i></span>
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-info dropdown-toggle" data-mynodemac="" data-toggle="dropdown" aria-expanded="false" id="buttonNetworkNodeMac">
|
||||
<span class="fa fa-caret-down"></span></button>
|
||||
@@ -343,7 +342,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_Network_Port');?></label>
|
||||
<label class="col-sm-3 control-label"><?= lang('DevDetail_MainInfo_Network_Port');?></label>
|
||||
<div class="col-sm-9">
|
||||
<input class="form-control" id="txtNetworkPort" type="text" value="--">
|
||||
</div>
|
||||
@@ -354,12 +353,12 @@
|
||||
|
||||
<!-- column 3 -->
|
||||
<div class="col-lg-4 col-sm-6 col-xs-12">
|
||||
<h4 class="bottom-border-aqua"><?php echo lang('DevDetail_EveandAl_Title');?></h4>
|
||||
<h4 class="bottom-border-aqua"><?= lang('DevDetail_EveandAl_Title');?></h4>
|
||||
<div class="box-body form-horizontal">
|
||||
|
||||
<!-- Scan Cycle -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label"><?php echo lang('DevDetail_EveandAl_ScanCycle');?></label>
|
||||
<label class="col-sm-5 control-label"><?= lang('DevDetail_EveandAl_ScanCycle');?></label>
|
||||
<div class="col-sm-7">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="txtScanCycle" type="text" value="--" readonly >
|
||||
@@ -367,8 +366,8 @@
|
||||
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-expanded="false" id="dropdownButtonScanCycle">
|
||||
<span class="fa fa-caret-down"></span></button>
|
||||
<ul id="dropdownScanCycle" class="dropdown-menu dropdown-menu-right">
|
||||
<li><a href="javascript:void(0)" onclick="setTextValue('txtScanCycle','yes')"><?php echo lang('DevDetail_EveandAl_ScanCycle_a');?></a></li>
|
||||
<li><a href="javascript:void(0)" onclick="setTextValue('txtScanCycle','no');"><?php echo lang('DevDetail_EveandAl_ScanCycle_z');?></a></li>
|
||||
<li><a href="javascript:void(0)" onclick="setTextValue('txtScanCycle','yes')"><?= lang('DevDetail_EveandAl_ScanCycle_a');?></a></li>
|
||||
<li><a href="javascript:void(0)" onclick="setTextValue('txtScanCycle','no');"><?= lang('DevDetail_EveandAl_ScanCycle_z');?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -377,7 +376,7 @@
|
||||
|
||||
<!-- Alert events -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label"><?php echo lang('DevDetail_EveandAl_AlertAllEvents');?></label>
|
||||
<label class="col-sm-5 control-label"><?= lang('DevDetail_EveandAl_AlertAllEvents');?></label>
|
||||
<div class="col-sm-7" style="padding-top:6px;">
|
||||
<input class="checkbox blue hidden" id="chkAlertEvents" type="checkbox">
|
||||
</div>
|
||||
@@ -385,7 +384,7 @@
|
||||
|
||||
<!-- Alert Down -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label"><?php echo lang('DevDetail_EveandAl_AlertDown');?></label>
|
||||
<label class="col-sm-5 control-label"><?= lang('DevDetail_EveandAl_AlertDown');?></label>
|
||||
<div class="col-sm-7" style="padding-top:6px;">
|
||||
<input class="checkbox red hidden" id="chkAlertDown" type="checkbox">
|
||||
</div>
|
||||
@@ -393,7 +392,7 @@
|
||||
|
||||
<!-- Skip Notifications -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label" style="padding-top: 0px; padding-left: 0px;"><?php echo lang('DevDetail_EveandAl_Skip');?></label>
|
||||
<label class="col-sm-5 control-label" style="padding-top: 0px; padding-left: 0px;"><?= lang('DevDetail_EveandAl_Skip');?></label>
|
||||
<div class="col-sm-7">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="txtSkipRepeated" type="text" value="--" readonly >
|
||||
@@ -414,7 +413,7 @@
|
||||
|
||||
<!-- New Device -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label"><?php echo lang('DevDetail_EveandAl_NewDevice');?>:</label>
|
||||
<label class="col-sm-5 control-label"><?= lang('DevDetail_EveandAl_NewDevice');?>:</label>
|
||||
<div class="col-sm-7" style="padding-top:6px;">
|
||||
<input class="checkbox orange hidden" id="chkNewDevice" type="checkbox">
|
||||
</div>
|
||||
@@ -422,7 +421,7 @@
|
||||
|
||||
<!-- Archived -->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label"><?php echo lang('DevDetail_EveandAl_Archived');?>:</label>
|
||||
<label class="col-sm-5 control-label"><?= lang('DevDetail_EveandAl_Archived');?>:</label>
|
||||
<div class="col-sm-7" style="padding-top:6px;">
|
||||
<input class="checkbox blue hidden" id="chkArchived" type="checkbox">
|
||||
</div>
|
||||
@@ -430,7 +429,7 @@
|
||||
|
||||
<!-- Randomized MAC -->
|
||||
<div class="form-group" >
|
||||
<label class="col-sm-5 control-label"><?php echo lang('DevDetail_EveandAl_RandomMAC');?>:</label>
|
||||
<label class="col-sm-5 control-label"><?= lang('DevDetail_EveandAl_RandomMAC');?>:</label>
|
||||
<div class="col-sm-7" style="padding-top:6px;">
|
||||
<span id="iconRandomMACinactive" data-toggle="tooltip" data-placement="right" title="Random MAC is Inactive">
|
||||
<i style="font-size: 24px;" class="text-gray glyphicon glyphicon-random"></i>     </span>
|
||||
@@ -442,6 +441,29 @@
|
||||
<i class="fa fa-info-circle"></i> </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 col-sm-6 col-xs-12">
|
||||
<h4 class="bottom-border-aqua"><?= lang('DevDetail_Run_Actions_Title');?></h4>
|
||||
<div class="box-body form-horizontal">
|
||||
<label class="col-sm-3 control-label">
|
||||
<?= lang('Gen_Action');?>
|
||||
</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input class="form-control" title="<?= lang('DevDetail_Run_Actions_Tooltip');?>" id="txtAction" type="text" value="--">
|
||||
<span class="input-group-addon" title='<?= lang('Gen_Run');?>'><i class="fa fa-play pointer" onclick="askRunAction();"></i></span>
|
||||
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
|
||||
<span class="fa fa-caret-down"></span>
|
||||
</button>
|
||||
<ul id="dropdownAction" class="dropdown-menu dropdown-menu-right">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -450,13 +472,13 @@
|
||||
<div class="col-xs-12">
|
||||
<div class="pull-right">
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete" style="margin-left:0px;"
|
||||
id="btnDeleteEvents" onclick="askDeleteDeviceEvents()"> <?php echo lang('DevDetail_button_DeleteEvents');?> </button>
|
||||
id="btnDeleteEvents" onclick="askDeleteDeviceEvents()"> <?= lang('DevDetail_button_DeleteEvents');?> </button>
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete" style="margin-left:0px;"
|
||||
id="btnDelete" onclick="askDeleteDevice()"> <?php echo lang('DevDetail_button_Delete');?> </button>
|
||||
id="btnDelete" onclick="askDeleteDevice()"> <?= lang('DevDetail_button_Delete');?> </button>
|
||||
<button type="button" class="btn btn-default pa-btn" style="margin-left:6px;"
|
||||
id="btnRestore" onclick="getDeviceData(true)"> <?php echo lang('DevDetail_button_Reset');?> </button>
|
||||
id="btnRestore" onclick="getDeviceData(true)"> <?= lang('DevDetail_button_Reset');?> </button>
|
||||
<button type="button" disabled class="btn btn-primary pa-btn" style="margin-left:6px; "
|
||||
id="btnSave" onclick="setDeviceData()" > <?php echo lang('DevDetail_button_Save');?> </button>
|
||||
id="btnSave" onclick="setDeviceData()" > <?= lang('DevDetail_button_Save');?> </button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -470,12 +492,12 @@
|
||||
<table id="tableSessions" class="table table-bordered table-hover table-striped ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo lang('DevDetail_SessionTable_Order');?></th>
|
||||
<th><?php echo lang('DevDetail_SessionTable_Connection');?></th>
|
||||
<th><?php echo lang('DevDetail_SessionTable_Disconnection');?></th>
|
||||
<th><?php echo lang('DevDetail_SessionTable_Duration');?></th>
|
||||
<th><?php echo lang('DevDetail_SessionTable_IP');?></th>
|
||||
<th><?php echo lang('DevDetail_SessionTable_Additionalinfo');?></th>
|
||||
<th><?= lang('DevDetail_SessionTable_Order');?></th>
|
||||
<th><?= lang('DevDetail_SessionTable_Connection');?></th>
|
||||
<th><?= lang('DevDetail_SessionTable_Disconnection');?></th>
|
||||
<th><?= lang('DevDetail_SessionTable_Duration');?></th>
|
||||
<th><?= lang('DevDetail_SessionTable_IP');?></th>
|
||||
<th><?= lang('DevDetail_SessionTable_Additionalinfo');?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
@@ -516,10 +538,10 @@
|
||||
<div style="width:100%; text-align: center;">
|
||||
<script>
|
||||
setTimeout(function(){
|
||||
document.getElementById('piamanualnmap_fast').innerHTML='<?php echo lang('DevDetail_Nmap_buttonFast');?> (' + document.getElementById('txtLastIP').value +')';
|
||||
document.getElementById('piamanualnmap_normal').innerHTML='<?php echo lang('DevDetail_Nmap_buttonDefault');?> (' + document.getElementById('txtLastIP').value +')';
|
||||
document.getElementById('piamanualnmap_detail').innerHTML='<?php echo lang('DevDetail_Nmap_buttonDetail');?> (' + document.getElementById('txtLastIP').value +')';
|
||||
document.getElementById('piamanualnmap_skipdiscovery').innerHTML='<?php echo lang('DevDetail_Nmap_buttonSkipDiscovery');?> (' + document.getElementById('txtLastIP').value +')';
|
||||
document.getElementById('piamanualnmap_fast').innerHTML='<?= lang('DevDetail_Nmap_buttonFast');?> (' + document.getElementById('txtLastIP').value +')';
|
||||
document.getElementById('piamanualnmap_normal').innerHTML='<?= lang('DevDetail_Nmap_buttonDefault');?> (' + document.getElementById('txtLastIP').value +')';
|
||||
document.getElementById('piamanualnmap_detail').innerHTML='<?= lang('DevDetail_Nmap_buttonDetail');?> (' + document.getElementById('txtLastIP').value +')';
|
||||
document.getElementById('piamanualnmap_skipdiscovery').innerHTML='<?= lang('DevDetail_Nmap_buttonSkipDiscovery');?> (' + document.getElementById('txtLastIP').value +')';
|
||||
}, 2000);
|
||||
</script>
|
||||
|
||||
@@ -530,11 +552,11 @@
|
||||
|
||||
<div style="text-align: left;">
|
||||
<ul style="padding:20px;">
|
||||
<li><?php echo lang('DevDetail_Nmap_buttonFast_text');?></li>
|
||||
<li><?php echo lang('DevDetail_Nmap_buttonDefault_text');?></li>
|
||||
<li><?php echo lang('DevDetail_Nmap_buttonDetail_text');?></li>
|
||||
<li><?php echo lang('DevDetail_Nmap_buttonSkipDiscovery_text');?></li>
|
||||
<li><a onclick="setCache('activeMaintenanceTab', 'tab_Logging_id')" href="/maintenance.php#tab_Logging"><?php echo lang('DevDetail_Nmap_resultsLink');?></a></li>
|
||||
<li><?= lang('DevDetail_Nmap_buttonFast_text');?></li>
|
||||
<li><?= lang('DevDetail_Nmap_buttonDefault_text');?></li>
|
||||
<li><?= lang('DevDetail_Nmap_buttonDetail_text');?></li>
|
||||
<li><?= lang('DevDetail_Nmap_buttonSkipDiscovery_text');?></li>
|
||||
<li><a onclick="setCache('activeMaintenanceTab', 'tab_Logging_id')" href="/maintenance.php#tab_Logging"><?= lang('DevDetail_Nmap_resultsLink');?></a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
@@ -559,9 +581,9 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<h3><?php echo lang("DevDetail_Tab_NmapTableHeader");?></h3>
|
||||
<h3><?= lang("DevDetail_Tab_NmapTableHeader");?></h3>
|
||||
|
||||
<div><?php echo lang("DevDetail_Tab_NmapTableText");?></div>
|
||||
<div><?= lang("DevDetail_Tab_NmapTableText");?></div>
|
||||
|
||||
<table id="tableNmap" class="table table-bordered table-hover table-striped ">
|
||||
<thead>
|
||||
@@ -577,7 +599,7 @@
|
||||
<!-- Comment out tbody when trying to implement better table with datatables here -->
|
||||
<!-- IDEA: Show unmatched pholus entries? -->
|
||||
<tbody id="tableNmapBody">
|
||||
<tr id="tableNmapPlc" class="text-center"><td colspan='7'><span><?php echo lang("DevDetail_Tab_NmapEmpty"); ?></span></td></tr>
|
||||
<tr id="tableNmapPlc" class="text-center"><td colspan='7'><span><?= lang("DevDetail_Tab_NmapEmpty"); ?></span></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -614,7 +636,7 @@
|
||||
<div class="text-center">
|
||||
<label>
|
||||
<input class="checkbox blue hidden" id="chkHideConnectionEvents" type="checkbox" checked>
|
||||
<?php echo lang('DevDetail_Events_CheckBox');?>
|
||||
<?= lang('DevDetail_Events_CheckBox');?>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -648,7 +670,7 @@
|
||||
<!-- Comment out tbody when trying to implement better table with datatables here -->
|
||||
<!-- IDEA: Show unmatched pholus entries? -->
|
||||
<tbody id="tablePholusBody">
|
||||
<tr id="tablePholusPlc" class="text-center"><td colspan='7'><span><?php echo lang("DevDetail_Tab_PholusEmpty"); ?></span></td></tr>
|
||||
<tr id="tablePholusPlc" class="text-center"><td colspan='7'><span><?= lang("DevDetail_Tab_PholusEmpty"); ?></span></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -715,12 +737,15 @@ if ($ENABLED_DARKMODE === True) {
|
||||
// ------------------------------------------------------------
|
||||
function getDevicesListValue(idColumn, idValue, returnColumn)
|
||||
{
|
||||
if(emptyArr.includes(devicesList) || emptyArr.includes(idValue))
|
||||
// Read cache
|
||||
devicesListAll = JSON.parse(getCache('devicesListAll'));
|
||||
|
||||
if(emptyArr.includes(devicesListAll) || emptyArr.includes(idValue))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
return devicesList.find((item) => {return item[idColumn] == idValue})[returnColumn]
|
||||
return devicesListAll.find((item) => {return item[idColumn] == idValue})[returnColumn]
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
@@ -741,8 +766,29 @@ if ($ENABLED_DARKMODE === True) {
|
||||
|
||||
mac = getMac() // can also be rowID!! not only mac
|
||||
var devicesList = []; // this will contain a list the database row IDs of the devices ordered by the position displayed in the UI
|
||||
var devicesListAll = []; // this will contain a list off all devices
|
||||
|
||||
|
||||
$.get('php/server/devices.php?action=getDevicesList&status=all&forceDefaultOrder', function(data) {
|
||||
|
||||
rawData = JSON.parse (data)
|
||||
|
||||
devicesListAll = rawData["data"].map(item => { return {
|
||||
"name":item[0],
|
||||
"type":item[2],
|
||||
"icon":item[3],
|
||||
"mac":item[11],
|
||||
"parentMac":item[14],
|
||||
"rowid":item[13],
|
||||
"status":item[10]
|
||||
}})
|
||||
|
||||
setCache('devicesListAll', JSON.stringify(devicesListAll))
|
||||
|
||||
// Read parameters & Initialize components
|
||||
main();
|
||||
});
|
||||
|
||||
devicesList = getDevicesList();
|
||||
|
||||
var pos = -1;
|
||||
var parPeriod = 'Front_Details_Period';
|
||||
@@ -759,8 +805,7 @@ if ($ENABLED_DARKMODE === True) {
|
||||
var selectedTab = 'tabDetails';
|
||||
var emptyArr = ['undefined', "", undefined, null];
|
||||
|
||||
// Read parameters & Initialize components
|
||||
main();
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -903,6 +948,7 @@ function initializeCombos () {
|
||||
initializeCombo ( '#dropdownLocation', 'getLocations', 'txtLocation', true);
|
||||
initializeCombo ( '#dropdownNetworkNodeMac', 'getNetworkNodes', 'txtNetworkNodeMac', false);
|
||||
initializeCombo ( '#dropdownIcon', 'getIcons', 'txtIcon', false);
|
||||
initializeCombo ( '#dropdownAction', 'getActions', 'txtAction', false);
|
||||
|
||||
// Initialize static combos
|
||||
initializeComboSkipRepeated ();
|
||||
@@ -1042,13 +1088,13 @@ function initializeDatatables () {
|
||||
'<td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw">'+
|
||||
'</td></table>',
|
||||
emptyTable: 'No data',
|
||||
"lengthMenu": "<?php echo lang('Events_Tablelenght');?>",
|
||||
"search": "<?php echo lang('Events_Searchbox');?>: ",
|
||||
"lengthMenu": "<?= lang('Events_Tablelenght');?>",
|
||||
"search": "<?= lang('Events_Searchbox');?>: ",
|
||||
"paginate": {
|
||||
"next": "<?php echo lang('Events_Table_nav_next');?>",
|
||||
"previous": "<?php echo lang('Events_Table_nav_prev');?>"
|
||||
"next": "<?= lang('Events_Table_nav_next');?>",
|
||||
"previous": "<?= lang('Events_Table_nav_prev');?>"
|
||||
},
|
||||
"info": "<?php echo lang('Events_Table_info');?>",
|
||||
"info": "<?= lang('Events_Table_info');?>",
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1081,13 +1127,13 @@ function initializeDatatables () {
|
||||
'<td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw">'+
|
||||
'</td></table>',
|
||||
emptyTable: 'No data',
|
||||
"lengthMenu": "<?php echo lang('Events_Tablelenght');?>",
|
||||
"search": "<?php echo lang('Events_Searchbox');?>: ",
|
||||
"lengthMenu": "<?= lang('Events_Tablelenght');?>",
|
||||
"search": "<?= lang('Events_Searchbox');?>: ",
|
||||
"paginate": {
|
||||
"next": "<?php echo lang('Events_Table_nav_next');?>",
|
||||
"previous": "<?php echo lang('Events_Table_nav_prev');?>"
|
||||
"next": "<?= lang('Events_Table_nav_next');?>",
|
||||
"previous": "<?= lang('Events_Table_nav_prev');?>"
|
||||
},
|
||||
"info": "<?php echo lang('Events_Table_info');?>",
|
||||
"info": "<?= lang('Events_Table_info');?>",
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1126,7 +1172,7 @@ function initializeCalendar () {
|
||||
slotLabelInterval : '04:00:00',
|
||||
slotLabelFormat : 'H:mm',
|
||||
timeFormat : 'H:mm',
|
||||
locale : '<?php echo lang('Presence_CalHead_lang');?>',
|
||||
locale : '<?= lang('Presence_CalHead_lang');?>',
|
||||
header: {
|
||||
left : 'prev,next today',
|
||||
center : 'title',
|
||||
@@ -1137,14 +1183,14 @@ function initializeCalendar () {
|
||||
agendaYear: {
|
||||
type : 'agenda',
|
||||
duration : { year: 1 },
|
||||
buttonText : '<?php echo lang('Presence_CalHead_year');?>',
|
||||
buttonText : '<?= lang('Presence_CalHead_year');?>',
|
||||
columnHeaderFormat : ''
|
||||
},
|
||||
|
||||
agendaMonth: {
|
||||
type : 'agenda',
|
||||
duration : { month: 1 },
|
||||
buttonText : '<?php echo lang('Presence_CalHead_month');?>',
|
||||
buttonText : '<?= lang('Presence_CalHead_month');?>',
|
||||
columnHeaderFormat : 'D'
|
||||
}
|
||||
},
|
||||
@@ -1430,7 +1476,7 @@ function recordSwitch(direction) {
|
||||
if(somethingChanged)
|
||||
{
|
||||
showModalDefaultStrParam ('Unsaved changes', 'Do you want to discard your changes?',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Okay');?>', performSwitch, direction);
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', performSwitch, direction);
|
||||
} else
|
||||
{
|
||||
performSwitch(direction)
|
||||
@@ -1525,8 +1571,6 @@ function setDeviceData (direction='', refreshCallback='') {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function askSkipNotifications () {
|
||||
// Check MAC
|
||||
@@ -1538,7 +1582,7 @@ function askSkipNotifications () {
|
||||
if ($('#chkArchived')[0].checked && $('#txtScanCycle').val() != "no") {
|
||||
// Ask skip notifications
|
||||
showModalDefault ('Device Archived', 'Do you want to skip all notifications for this device?',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Okay');?>', 'skipNotifications');
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', 'skipNotifications');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1552,6 +1596,65 @@ function skipNotifications () {
|
||||
// Set cycle 0
|
||||
$('#txtScanCycle').val ('no');
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
function askDeleteDeviceEvents () {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ask delete device Events
|
||||
showModalWarning ('<?= lang('DevDetail_button_DeleteEvents');?>', '<?= lang('DevDetail_button_DeleteEvents_Warning');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteDeviceEvents');
|
||||
}
|
||||
|
||||
function deleteDeviceEvents () {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete device events
|
||||
$.get('php/server/devices.php?action=deleteDeviceEvents&mac='+ mac, function(msg) {
|
||||
showMessage (msg);
|
||||
});
|
||||
|
||||
// Deactivate controls
|
||||
$('#panDetails :input').attr('disabled', true);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function askRunAction() {
|
||||
// Ask
|
||||
showModalWarning('<?= lang('BackDevDetail_Actions_Title_Run');?>', '<?= lang('BackDevDetail_Actions_Ask_Run');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Run');?>', 'runAction');
|
||||
}
|
||||
|
||||
function runAction() {
|
||||
|
||||
action = $('#txtAction').val();
|
||||
|
||||
switch(action)
|
||||
{
|
||||
case 'wake-on-lan':
|
||||
wakeonlan();
|
||||
break;
|
||||
default:
|
||||
showMessage (`<?= lang('BackDevDetail_Actions_Not_Registered');?> ${action} `);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function wakeonlan() {
|
||||
// Execute
|
||||
$.get('php/server/devices.php?action=wakeonlan&'
|
||||
+ '&mac=' + $('#txtMAC').val()
|
||||
+ '&ip=' + $('#txtLastIP').val()
|
||||
, function(msg) {
|
||||
showMessage (msg);
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Overwrite all devices of the same type with the currently selected icon
|
||||
@@ -1562,8 +1665,8 @@ function askOverwriteIconType () {
|
||||
}
|
||||
|
||||
// Ask overwrite icon types
|
||||
showModalWarning ('<?php echo lang('DevDetail_button_OverwriteIcons');?>', '<?php echo lang('DevDetail_button_OverwriteIcons_Warning');?>',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Okay');?>', 'overwriteIconType');
|
||||
showModalWarning ('<?= lang('DevDetail_button_OverwriteIcons');?>', '<?= lang('DevDetail_button_OverwriteIcons_Warning');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', 'overwriteIconType');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -1575,7 +1678,7 @@ function overwriteIconType () {
|
||||
|
||||
var icon = $('#txtIcon').val();
|
||||
|
||||
// Delete device events
|
||||
// Mass update icons
|
||||
$.get('php/server/devices.php?action=overwriteIconType&mac='+ mac + '&icon=' + icon, function(msg) {
|
||||
showMessage (msg);
|
||||
});
|
||||
@@ -1593,7 +1696,7 @@ function askDeleteDevice () {
|
||||
|
||||
// Ask delete device
|
||||
showModalWarning ('Delete Device', 'Are you sure you want to delete this device?<br>(maybe you prefer to archive it)',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Delete');?>', 'deleteDevice');
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteDevice');
|
||||
}
|
||||
|
||||
|
||||
@@ -1621,7 +1724,7 @@ function askDeleteDevice () {
|
||||
|
||||
// Ask delete device
|
||||
showModalWarning ('Delete Device', 'Are you sure you want to delete this device?<br>(maybe you prefer to archive it)',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Delete');?>', 'deleteDevice');
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteDevice');
|
||||
}
|
||||
|
||||
|
||||
@@ -1727,7 +1830,7 @@ function initializeTabsNew () {
|
||||
|
||||
function loadNmap()
|
||||
{
|
||||
$(".deviceSpecific").remove(); // remove any previous data listed in teh table
|
||||
$(".deviceSpecific").remove(); // remove any previous data listed in the table
|
||||
|
||||
$.get('php/server/devices.php?action=getNmap&mac='+ mac, function(data) {
|
||||
|
||||
@@ -1843,13 +1946,13 @@ function initTable(tableId, mac){
|
||||
'<td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw">'+
|
||||
'</td></table>',
|
||||
emptyTable: 'No data',
|
||||
"lengthMenu": "<?php echo lang('Events_Tablelenght');?>",
|
||||
"search": "<?php echo lang('Events_Searchbox');?>: ",
|
||||
"lengthMenu": "<?= lang('Events_Tablelenght');?>",
|
||||
"search": "<?= lang('Events_Searchbox');?>: ",
|
||||
"paginate": {
|
||||
"next": "<?php echo lang('Events_Table_nav_next');?>",
|
||||
"previous": "<?php echo lang('Events_Table_nav_prev');?>"
|
||||
"next": "<?= lang('Events_Table_nav_next');?>",
|
||||
"previous": "<?= lang('Events_Table_nav_prev');?>"
|
||||
},
|
||||
"info": "<?php echo lang('Events_Table_info');?>",
|
||||
"info": "<?= lang('Events_Table_info');?>",
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
require 'php/templates/header.php';
|
||||
require 'php/templates/graph.php';
|
||||
require 'php/server/util.php';
|
||||
|
||||
|
||||
// check permissions
|
||||
@@ -27,7 +26,7 @@
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<h1 id="pageTitle">
|
||||
<?php echo lang('Device_Title');?>
|
||||
<?= lang('Device_Title');?>
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
@@ -40,7 +39,7 @@
|
||||
<a href="#" onclick="javascript: getDevicesList('all');">
|
||||
<div class="small-box bg-aqua">
|
||||
<div class="inner"><h3 id="devicesAll"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Device_Shortcut_AllDevices');?></p>
|
||||
<p class="infobox_label"><?= lang('Device_Shortcut_AllDevices');?></p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-laptop text-aqua-40"></i></div>
|
||||
</div>
|
||||
@@ -52,7 +51,7 @@
|
||||
<a href="#" onclick="javascript: getDevicesList('connected');">
|
||||
<div class="small-box bg-green">
|
||||
<div class="inner"><h3 id="devicesConnected"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Device_Shortcut_Connected');?></p>
|
||||
<p class="infobox_label"><?= lang('Device_Shortcut_Connected');?></p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-plug text-green-40"></i></div>
|
||||
</div>
|
||||
@@ -64,7 +63,7 @@
|
||||
<a href="#" onclick="javascript: getDevicesList('favorites');">
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner"><h3 id="devicesFavorites"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Device_Shortcut_Favorites');?></p>
|
||||
<p class="infobox_label"><?= lang('Device_Shortcut_Favorites');?></p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-star text-yellow-40"></i></div>
|
||||
</div>
|
||||
@@ -76,7 +75,7 @@
|
||||
<a href="#" onclick="javascript: getDevicesList('new');">
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner"><h3 id="devicesNew"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Device_Shortcut_NewDevices');?></p>
|
||||
<p class="infobox_label"><?= lang('Device_Shortcut_NewDevices');?></p>
|
||||
</div>
|
||||
<div class="icon"><i class="ion ion-plus-round text-yellow-40"></i></div>
|
||||
</div>
|
||||
@@ -88,7 +87,7 @@
|
||||
<a href="#" onclick="javascript: getDevicesList('down');">
|
||||
<div class="small-box bg-red">
|
||||
<div class="inner"><h3 id="devicesDown"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Device_Shortcut_DownAlerts');?></p>
|
||||
<p class="infobox_label"><?= lang('Device_Shortcut_DownAlerts');?></p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-warning text-red-40"></i></div>
|
||||
</div>
|
||||
@@ -100,7 +99,7 @@
|
||||
<a href="#" onclick="javascript: getDevicesList('archived');">
|
||||
<div class="small-box bg-gray top_small_box_gray_text">
|
||||
<div class="inner"><h3 id="devicesArchived"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Device_Shortcut_Archived');?></p>
|
||||
<p class="infobox_label"><?= lang('Device_Shortcut_Archived');?></p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-eye-slash text-gray-40"></i></div>
|
||||
</div>
|
||||
@@ -115,7 +114,7 @@
|
||||
<div class="col-md-12">
|
||||
<div class="box" id="clients">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><?php echo lang('Device_Shortcut_OnlineChart');?> </h3>
|
||||
<h3 class="box-title"><?= lang('Device_Shortcut_OnlineChart');?> </h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="chart">
|
||||
@@ -192,9 +191,10 @@
|
||||
var parTableOrder = 'Front_Devices_Order';
|
||||
var tableRows = 10;
|
||||
var tableOrder = [[3,'desc'], [0,'asc']];
|
||||
var tableColumnVisible = [0,1,2,3,4,5,6,7,8,9,10,12,13,14];
|
||||
var columnsStr = '[0,1,2,3,4,5,6,7,8,9,10,12,13,14]';
|
||||
var tableColumnOrder = [0,1,2,3,4,5,6,7,8,9,10,12,13,14] ;
|
||||
|
||||
var columnsStr = '[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]';
|
||||
var tableColumnOrder = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] ;
|
||||
var tableColumnVisible = tableColumnOrder;
|
||||
|
||||
// Read parameters & Initialize components
|
||||
main();
|
||||
@@ -203,32 +203,47 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
function main () {
|
||||
|
||||
// get visible columns
|
||||
$.get('php/server/parameters.php?action=get&expireMinutes=525600&defaultValue='+columnsStr+'¶meter=Front_Devices_Columns_Visible', function(data) {
|
||||
// get from cookie if available (need to use decodeURI as saved as part of URI in PHP)
|
||||
cookieColumnsVisibleStr = decodeURI(getCookie("Front_Devices_Columns_Visible")).replaceAll('%2C',',')
|
||||
|
||||
defaultValue = cookieColumnsVisibleStr == "" ? columnsStr : cookieColumnsVisibleStr;
|
||||
|
||||
// get visible columns
|
||||
$.get('php/server/parameters.php?action=get&expireMinutes=525600&defaultValue='+defaultValue+'¶meter=Front_Devices_Columns_Visible&skipcache', function(data) {
|
||||
|
||||
// save which columns are in the Devices page visible
|
||||
tableColumnVisible = numberArrayFromString(data);
|
||||
|
||||
// get the custom order specified by the user
|
||||
$.get('php/server/parameters.php?action=get&expireMinutes=525600&defaultValue='+columnsStr+'¶meter=Front_Devices_Columns_Order', function(data) {
|
||||
// get from cookie if available (need to use decodeURI as saved as part of URI in PHP)
|
||||
cookieColumnsOrderStr = decodeURI(getCookie("Front_Devices_Columns_Order")).replaceAll('%2C',',')
|
||||
|
||||
defaultValue = cookieColumnsOrderStr == "" ? columnsStr : cookieColumnsOrderStr;
|
||||
|
||||
// get the custom order specified by the user
|
||||
$.get('php/server/parameters.php?action=get&expireMinutes=525600&defaultValue='+defaultValue+'¶meter=Front_Devices_Columns_Order&skipcache', function(data) {
|
||||
|
||||
// save the columns order in the Devices page
|
||||
tableColumnOrder = numberArrayFromString(data);
|
||||
|
||||
//initialize the table headers in the correct order
|
||||
var headersDefaultOrder = [ '<?php echo lang('Device_TableHead_Name');?>',
|
||||
'<?php echo lang('Device_TableHead_Owner');?>',
|
||||
'<?php echo lang('Device_TableHead_Type');?>',
|
||||
'<?php echo lang('Device_TableHead_Icon');?>',
|
||||
'<?php echo lang('Device_TableHead_Favorite');?>',
|
||||
'<?php echo lang('Device_TableHead_Group');?>',
|
||||
'<?php echo lang('Device_TableHead_FirstSession');?>',
|
||||
'<?php echo lang('Device_TableHead_LastSession');?>',
|
||||
'<?php echo lang('Device_TableHead_LastIP');?>',
|
||||
'<?php echo lang('Device_TableHead_MAC');?>',
|
||||
'<?php echo lang('Device_TableHead_Status');?>',
|
||||
'<?php echo lang('Device_TableHead_MAC_full');?>',
|
||||
'<?php echo lang('Device_TableHead_LastIPOrder');?>',
|
||||
'<?php echo lang('Device_TableHead_Rowid');?>',
|
||||
'<?php echo lang('Device_TableHead_Parent_MAC');?>'
|
||||
var headersDefaultOrder = [ '<?= lang('Device_TableHead_Name');?>',
|
||||
'<?= lang('Device_TableHead_Owner');?>',
|
||||
'<?= lang('Device_TableHead_Type');?>',
|
||||
'<?= lang('Device_TableHead_Icon');?>',
|
||||
'<?= lang('Device_TableHead_Favorite');?>',
|
||||
'<?= lang('Device_TableHead_Group');?>',
|
||||
'<?= lang('Device_TableHead_FirstSession');?>',
|
||||
'<?= lang('Device_TableHead_LastSession');?>',
|
||||
'<?= lang('Device_TableHead_LastIP');?>',
|
||||
'<?= lang('Device_TableHead_MAC');?>',
|
||||
'<?= lang('Device_TableHead_Status');?>',
|
||||
'<?= lang('Device_TableHead_MAC_full');?>',
|
||||
'<?= lang('Device_TableHead_LastIPOrder');?>',
|
||||
'<?= lang('Device_TableHead_Rowid');?>',
|
||||
'<?= lang('Device_TableHead_Parent_MAC');?>',
|
||||
'<?= lang('Device_TableHead_Connected_Devices');?>',
|
||||
'<?= lang('Device_TableHead_Location');?>',
|
||||
'<?= lang('Device_TableHead_Vendor');?>'
|
||||
];
|
||||
|
||||
html = '';
|
||||
@@ -240,8 +255,6 @@ function main () {
|
||||
|
||||
$('#tableDevices tr').html(html);
|
||||
|
||||
|
||||
|
||||
// get parameter value
|
||||
$.get('php/server/parameters.php?action=get&defaultValue=50¶meter='+ parTableRows, function(data) {
|
||||
var result = JSON.parse(data);
|
||||
@@ -278,14 +291,13 @@ function main () {
|
||||
// -----------------------------------------------------------------------------
|
||||
var tableColumnHide = [];
|
||||
|
||||
// mapping the default order to the user specified one
|
||||
function mapIndx(oldIndex)
|
||||
{
|
||||
for(i=0;i<tableColumnOrder.length;i++)
|
||||
{
|
||||
if(tableColumnOrder[i] == oldIndex)
|
||||
{
|
||||
// console.log('newIndex')
|
||||
// console.log(i)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -315,7 +327,7 @@ function initializeDatatable () {
|
||||
$('#tableDevices').DataTable({
|
||||
'paging' : true,
|
||||
'lengthChange' : true,
|
||||
'lengthMenu' : [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, '<?php echo lang('Device_Tablelenght_all');?>']],
|
||||
'lengthMenu' : [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, '<?= lang('Device_Tablelenght_all');?>']],
|
||||
'searching' : true,
|
||||
|
||||
'ordering' : true,
|
||||
@@ -329,10 +341,10 @@ function initializeDatatable () {
|
||||
|
||||
'columnDefs' : [
|
||||
{visible: false, targets: tableColumnHide },
|
||||
{className: 'text-center', targets: [mapIndx(3), mapIndx(4), mapIndx(9), mapIndx(10)] },
|
||||
{width: '80px', targets: [mapIndx(6), mapIndx(7)] },
|
||||
{className: 'text-center', targets: [mapIndx(3), mapIndx(4), mapIndx(9), mapIndx(10), mapIndx(15)] },
|
||||
{width: '80px', targets: [mapIndx(6), mapIndx(7), mapIndx(15)] },
|
||||
{width: '30px', targets: [mapIndx(10), mapIndx(13)] },
|
||||
{orderData: [mapIndx(11)], targets: mapIndx(8) },
|
||||
{orderData: [mapIndx(12)], targets: mapIndx(8) },
|
||||
|
||||
// Device Name
|
||||
{targets: [mapIndx(0)],
|
||||
@@ -340,6 +352,12 @@ function initializeDatatable () {
|
||||
$(td).html ('<b class="anonymizeDev"><a href="deviceDetails.php?mac='+ rowData[mapIndx(11)] +'" class="">'+ cellData +'</a></b>');
|
||||
} },
|
||||
|
||||
// Connected Devices
|
||||
{targets: [mapIndx(15)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
$(td).html ('<b><a href="./network.php?mac='+ rowData[mapIndx(11)] +'" class="">'+ cellData +'</a></b>');
|
||||
} },
|
||||
|
||||
// Icon
|
||||
{targets: [mapIndx(3)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
@@ -417,13 +435,13 @@ function initializeDatatable () {
|
||||
'language' : {
|
||||
processing: '<table> <td width="130px" align="middle">Loading...</td><td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td> </table>',
|
||||
emptyTable: 'No data',
|
||||
"lengthMenu": "<?php echo lang('Device_Tablelenght');?>",
|
||||
"search": "<?php echo lang('Device_Searchbox');?>: ",
|
||||
"lengthMenu": "<?= lang('Device_Tablelenght');?>",
|
||||
"search": "<?= lang('Device_Searchbox');?>: ",
|
||||
"paginate": {
|
||||
"next": "<?php echo lang('Device_Table_nav_next');?>",
|
||||
"previous": "<?php echo lang('Device_Table_nav_prev');?>"
|
||||
"next": "<?= lang('Device_Table_nav_next');?>",
|
||||
"previous": "<?= lang('Device_Table_nav_prev');?>"
|
||||
},
|
||||
"info": "<?php echo lang('Device_Table_info');?>",
|
||||
"info": "<?= lang('Device_Table_info');?>",
|
||||
}
|
||||
});
|
||||
|
||||
@@ -505,13 +523,13 @@ function getDevicesList (status) {
|
||||
|
||||
// Define color & title for the status selected
|
||||
switch (deviceStatus) {
|
||||
case 'all': tableTitle = '<?php echo lang('Device_Shortcut_AllDevices');?>'; color = 'aqua'; break;
|
||||
case 'connected': tableTitle = '<?php echo lang('Device_Shortcut_Connected');?>'; color = 'green'; break;
|
||||
case 'favorites': tableTitle = '<?php echo lang('Device_Shortcut_Favorites');?>'; color = 'yellow'; break;
|
||||
case 'new': tableTitle = '<?php echo lang('Device_Shortcut_NewDevices');?>'; color = 'yellow'; break;
|
||||
case 'down': tableTitle = '<?php echo lang('Device_Shortcut_DownAlerts');?>'; color = 'red'; break;
|
||||
case 'archived': tableTitle = '<?php echo lang('Device_Shortcut_Archived');?>'; color = 'gray'; break;
|
||||
default: tableTitle = '<?php echo lang('Device_Shortcut_Devices');?>'; color = 'gray'; break;
|
||||
case 'all': tableTitle = '<?= lang('Device_Shortcut_AllDevices');?>'; color = 'aqua'; break;
|
||||
case 'connected': tableTitle = '<?= lang('Device_Shortcut_Connected');?>'; color = 'green'; break;
|
||||
case 'favorites': tableTitle = '<?= lang('Device_Shortcut_Favorites');?>'; color = 'yellow'; break;
|
||||
case 'new': tableTitle = '<?= lang('Device_Shortcut_NewDevices');?>'; color = 'yellow'; break;
|
||||
case 'down': tableTitle = '<?= lang('Device_Shortcut_DownAlerts');?>'; color = 'red'; break;
|
||||
case 'archived': tableTitle = '<?= lang('Device_Shortcut_Archived');?>'; color = 'gray'; break;
|
||||
default: tableTitle = '<?= lang('Device_Shortcut_Devices');?>'; color = 'gray'; break;
|
||||
}
|
||||
|
||||
// Set title and color
|
||||
|
||||
@@ -17,17 +17,17 @@
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<h1 id="pageTitle">
|
||||
<?php echo lang('Events_Title');?>
|
||||
<?= lang('Events_Title');?>
|
||||
</h1>
|
||||
|
||||
<!-- period selector -->
|
||||
<span class="breadcrumb" style="top: 0px;">
|
||||
<select class="form-control" id="period" onchange="javascript: periodChanged();">
|
||||
<option value="1 day"><?php echo lang('Events_Periodselect_today');?></option>
|
||||
<option value="7 days"><?php echo lang('Events_Periodselect_LastWeek');?></option>
|
||||
<option value="1 month" selected><?php echo lang('Events_Periodselect_LastMonth');?></option>
|
||||
<option value="1 year"><?php echo lang('Events_Periodselect_LastYear');?></option>
|
||||
<option value="100 years"><?php echo lang('Events_Periodselect_All');?></option>
|
||||
<option value="1 day"><?= lang('Events_Periodselect_today');?></option>
|
||||
<option value="7 days"><?= lang('Events_Periodselect_LastWeek');?></option>
|
||||
<option value="1 month" selected><?= lang('Events_Periodselect_LastMonth');?></option>
|
||||
<option value="1 year"><?= lang('Events_Periodselect_LastYear');?></option>
|
||||
<option value="100 years"><?= lang('Events_Periodselect_All');?></option>
|
||||
</select>
|
||||
</span>
|
||||
</section>
|
||||
@@ -42,7 +42,7 @@
|
||||
<a href="#" onclick="javascript: getEvents('all');">
|
||||
<div class="small-box bg-aqua">
|
||||
<div class="inner"> <h3 id="eventsAll"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Events_Shortcut_AllEvents');?></p>
|
||||
<p class="infobox_label"><?= lang('Events_Shortcut_AllEvents');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i class="fa fa-bolt text-aqua-40"></i> </div>
|
||||
</div>
|
||||
@@ -54,7 +54,7 @@
|
||||
<a href="#" onclick="javascript: getEvents('sessions');">
|
||||
<div class="small-box bg-green">
|
||||
<div class="inner"> <h3 id="eventsSessions"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Events_Shortcut_Sessions');?></p>
|
||||
<p class="infobox_label"><?= lang('Events_Shortcut_Sessions');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i class="fa fa-plug text-green-40"></i> </div>
|
||||
</div>
|
||||
@@ -66,7 +66,7 @@
|
||||
<a href="#" onclick="javascript: getEvents('missing');">
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner"> <h3 id="eventsMissing"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Events_Shortcut_MissSessions');?></p>
|
||||
<p class="infobox_label"><?= lang('Events_Shortcut_MissSessions');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i class="fa fa-exchange text-yellow-40"></i> </div>
|
||||
</div>
|
||||
@@ -78,7 +78,7 @@
|
||||
<a href="#" onclick="javascript: getEvents('voided');">
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner"> <h3 id="eventsVoided"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Events_Shortcut_VoidSessions');?></p>
|
||||
<p class="infobox_label"><?= lang('Events_Shortcut_VoidSessions');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i class="fa fa-exclamation-circle text-yellow-40"></i> </div>
|
||||
</div>
|
||||
@@ -90,7 +90,7 @@
|
||||
<a href="#" onclick="javascript: getEvents('new');">
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner"> <h3 id="eventsNewDevices"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Events_Shortcut_NewDevices');?></p>
|
||||
<p class="infobox_label"><?= lang('Events_Shortcut_NewDevices');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i class="ion ion-plus-round text-yellow-40"></i> </div>
|
||||
</div>
|
||||
@@ -102,7 +102,7 @@
|
||||
<a href="#" onclick="javascript: getEvents('down');">
|
||||
<div class="small-box bg-red">
|
||||
<div class="inner"> <h3 id="eventsDown"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Events_Shortcut_DownAlerts');?></p>
|
||||
<p class="infobox_label"><?= lang('Events_Shortcut_DownAlerts');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i class="fa fa-warning text-red-40"></i> </div>
|
||||
</div>
|
||||
@@ -127,18 +127,18 @@
|
||||
<table id="tableEvents" class="table table-bordered table-hover table-striped ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo lang('Events_TableHead_Order');?></th>
|
||||
<th><?php echo lang('Events_TableHead_Device');?></th>
|
||||
<th><?php echo lang('Events_TableHead_Owner');?></th>
|
||||
<th><?php echo lang('Events_TableHead_Date');?></th>
|
||||
<th><?php echo lang('Events_TableHead_EventType');?></th>
|
||||
<th><?php echo lang('Events_TableHead_Connection');?></th>
|
||||
<th><?php echo lang('Events_TableHead_Disconnection');?></th>
|
||||
<th><?php echo lang('Events_TableHead_Duration');?></th>
|
||||
<th><?php echo lang('Events_TableHead_DurationOrder');?></th>
|
||||
<th><?php echo lang('Events_TableHead_IP');?></th>
|
||||
<th><?php echo lang('Events_TableHead_IPOrder');?></th>
|
||||
<th><?php echo lang('Events_TableHead_AdditionalInfo');?></th>
|
||||
<th><?= lang('Events_TableHead_Order');?></th>
|
||||
<th><?= lang('Events_TableHead_Device');?></th>
|
||||
<th><?= lang('Events_TableHead_Owner');?></th>
|
||||
<th><?= lang('Events_TableHead_Date');?></th>
|
||||
<th><?= lang('Events_TableHead_EventType');?></th>
|
||||
<th><?= lang('Events_TableHead_Connection');?></th>
|
||||
<th><?= lang('Events_TableHead_Disconnection');?></th>
|
||||
<th><?= lang('Events_TableHead_Duration');?></th>
|
||||
<th><?= lang('Events_TableHead_DurationOrder');?></th>
|
||||
<th><?= lang('Events_TableHead_IP');?></th>
|
||||
<th><?= lang('Events_TableHead_IPOrder');?></th>
|
||||
<th><?= lang('Events_TableHead_AdditionalInfo');?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
@@ -253,13 +253,13 @@ function initializeDatatable () {
|
||||
'language' : {
|
||||
processing: '<table><td width="130px" align="middle">Loading...</td><td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td></table>',
|
||||
emptyTable: 'No data',
|
||||
"lengthMenu": "<?php echo lang('Events_Tablelenght');?>",
|
||||
"search": "<?php echo lang('Events_Searchbox');?>: ",
|
||||
"lengthMenu": "<?= lang('Events_Tablelenght');?>",
|
||||
"search": "<?= lang('Events_Searchbox');?>: ",
|
||||
"paginate": {
|
||||
"next": "<?php echo lang('Events_Table_nav_next');?>",
|
||||
"previous": "<?php echo lang('Events_Table_nav_prev');?>"
|
||||
"next": "<?= lang('Events_Table_nav_next');?>",
|
||||
"previous": "<?= lang('Events_Table_nav_prev');?>"
|
||||
},
|
||||
"info": "<?php echo lang('Events_Table_info');?>",
|
||||
"info": "<?= lang('Events_Table_info');?>",
|
||||
}
|
||||
});
|
||||
|
||||
@@ -311,13 +311,13 @@ function getEvents (p_eventsType) {
|
||||
|
||||
// Define color & title for the status selected
|
||||
switch (eventsType) {
|
||||
case 'all': tableTitle = '<?php echo lang('Events_Shortcut_AllEvents');?>'; color = 'aqua'; sesionCols = false; break;
|
||||
case 'sessions': tableTitle = '<?php echo lang('Events_Shortcut_Sessions');?>'; color = 'green'; sesionCols = true; break;
|
||||
case 'missing': tableTitle = '<?php echo lang('Events_Shortcut_MissSessions');?>'; color = 'yellow'; sesionCols = true; break;
|
||||
case 'voided': tableTitle = '<?php echo lang('Events_Shortcut_VoidSessions');?>'; color = 'yellow'; sesionCols = false; break;
|
||||
case 'new': tableTitle = '<?php echo lang('Events_Shortcut_NewDevices');?>'; color = 'yellow'; sesionCols = false; break;
|
||||
case 'down': tableTitle = '<?php echo lang('Events_Shortcut_DownAlerts');?>'; color = 'red'; sesionCols = false; break;
|
||||
default: tableTitle = '<?php echo lang('Events_Shortcut_Events');?>'; boxClass = ''; sesionCols = false; break;
|
||||
case 'all': tableTitle = '<?= lang('Events_Shortcut_AllEvents');?>'; color = 'aqua'; sesionCols = false; break;
|
||||
case 'sessions': tableTitle = '<?= lang('Events_Shortcut_Sessions');?>'; color = 'green'; sesionCols = true; break;
|
||||
case 'missing': tableTitle = '<?= lang('Events_Shortcut_MissSessions');?>'; color = 'yellow'; sesionCols = true; break;
|
||||
case 'voided': tableTitle = '<?= lang('Events_Shortcut_VoidSessions');?>'; color = 'yellow'; sesionCols = false; break;
|
||||
case 'new': tableTitle = '<?= lang('Events_Shortcut_NewDevices');?>'; color = 'yellow'; sesionCols = false; break;
|
||||
case 'down': tableTitle = '<?= lang('Events_Shortcut_DownAlerts');?>'; color = 'red'; sesionCols = false; break;
|
||||
default: tableTitle = '<?= lang('Events_Shortcut_Events');?>'; boxClass = ''; sesionCols = false; break;
|
||||
}
|
||||
|
||||
// Set title and color
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
<section class="content-header">
|
||||
<?php require 'php/templates/notification.php'; ?>
|
||||
<h1 id="pageTitle">
|
||||
<?php echo lang('HelpFAQ_Title');?>
|
||||
<?= lang('HelpFAQ_Title');?>
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
<!-- Main content ---------------------------------------------------------- -->
|
||||
<section class="content">
|
||||
<h4><?php echo lang('HelpFAQ_Cat_General');?></h4>
|
||||
<h4><?= lang('HelpFAQ_Cat_General');?></h4>
|
||||
|
||||
<div class="panel-group" id="accordion_gen">
|
||||
<div class="panel panel-default">
|
||||
@@ -22,16 +22,16 @@
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_gen" href="#collapse100">
|
||||
<?php echo lang('HelpFAQ_Cat_General_100_head');?></a>
|
||||
<?= lang('HelpFAQ_Cat_General_100_head');?></a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div id="collapse100" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body"><?php echo lang('HelpFAQ_Cat_General_100_text_a');?>
|
||||
<div class="panel-body"><?= lang('HelpFAQ_Cat_General_100_text_a');?>
|
||||
<span class="text-danger help_faq_code"><?php echo date_default_timezone_get(); ?></span><br>
|
||||
<?php echo lang('HelpFAQ_Cat_General_100_text_b');?>
|
||||
<?= lang('HelpFAQ_Cat_General_100_text_b');?>
|
||||
<span class="text-danger help_faq_code"><?php echo php_ini_loaded_file(); ?></span><br>
|
||||
<?php echo lang('HelpFAQ_Cat_General_100_text_c');?>
|
||||
<?= lang('HelpFAQ_Cat_General_100_text_c');?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -42,12 +42,12 @@
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_gen" href="#collapse101">
|
||||
<?php echo lang('HelpFAQ_Cat_General_101_head');?></a>
|
||||
<?= lang('HelpFAQ_Cat_General_101_head');?></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse101" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body">
|
||||
<?php echo lang('HelpFAQ_Cat_General_101_text');?>
|
||||
<?= lang('HelpFAQ_Cat_General_101_text');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,12 +55,12 @@
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_gen" href="#collapse102">
|
||||
<?php echo lang('HelpFAQ_Cat_General_102_head');?></a>
|
||||
<?= lang('HelpFAQ_Cat_General_102_head');?></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse102" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body">
|
||||
<?php echo lang('HelpFAQ_Cat_General_102_text');?>
|
||||
<?= lang('HelpFAQ_Cat_General_102_text');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -68,12 +68,12 @@
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_gen" href="#collapse102docker">
|
||||
<?php echo lang('HelpFAQ_Cat_General_102docker_head');?></a>
|
||||
<?= lang('HelpFAQ_Cat_General_102docker_head');?></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse102docker" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body">
|
||||
<?php echo lang('HelpFAQ_Cat_General_102docker_text');?>
|
||||
<?= lang('HelpFAQ_Cat_General_102docker_text');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -81,48 +81,48 @@
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_gen" href="#collapse103">
|
||||
<?php echo lang('HelpFAQ_Cat_General_103_head');?></a>
|
||||
<?= lang('HelpFAQ_Cat_General_103_head');?></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse103" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body">
|
||||
<?php echo lang('HelpFAQ_Cat_General_103_text');?>
|
||||
<?= lang('HelpFAQ_Cat_General_103_text');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4><?php echo lang('Navigation_Devices');?></h4>
|
||||
<h4><?= lang('Navigation_Devices');?></h4>
|
||||
<div class="panel-group" id="accordion_dev">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_dev" href="#collapse200">
|
||||
<?php echo lang('HelpFAQ_Cat_Device_200_head');?></a>
|
||||
<?= lang('HelpFAQ_Cat_Device_200_head');?></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse200" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body">
|
||||
<?php echo lang('HelpFAQ_Cat_Device_200_text');?>
|
||||
<?= lang('HelpFAQ_Cat_Device_200_text');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<h4><?php echo lang('HelpFAQ_Cat_Detail');?></h4>
|
||||
<h4><?= lang('HelpFAQ_Cat_Detail');?></h4>
|
||||
<div class="panel-group" id="accordion_det">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_det" href="#collapse300">
|
||||
<?php echo lang('HelpFAQ_Cat_Detail_300_head');?> "<?php echo lang('DevDetail_MainInfo_Network');?>" / "<?php echo lang('DevDetail_MainInfo_Network_Port');?>"?</a>
|
||||
<?= lang('HelpFAQ_Cat_Detail_300_head');?> "<?= lang('DevDetail_MainInfo_Network');?>" / "<?= lang('DevDetail_MainInfo_Network_Port');?>"?</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse300" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body">
|
||||
"<?php echo lang('DevDetail_MainInfo_Network');?>" <?php echo lang('HelpFAQ_Cat_Detail_300_text_a');?><br>
|
||||
"<?php echo lang('DevDetail_MainInfo_Network_Port');?>" <?php echo lang('HelpFAQ_Cat_Detail_300_text_b');?>
|
||||
"<?= lang('DevDetail_MainInfo_Network');?>" <?= lang('HelpFAQ_Cat_Detail_300_text_a');?><br>
|
||||
"<?= lang('DevDetail_MainInfo_Network_Port');?>" <?= lang('HelpFAQ_Cat_Detail_300_text_b');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -130,12 +130,12 @@
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_det" href="#collapse301">
|
||||
<?php echo lang('HelpFAQ_Cat_Detail_301_head_a');?> "<?php echo lang('DevDetail_EveandAl_ScanCycle');?>" <?php echo lang('HelpFAQ_Cat_Detail_301_head_b');?></a>
|
||||
<?= lang('HelpFAQ_Cat_Detail_301_head_a');?> "<?= lang('DevDetail_EveandAl_ScanCycle');?>" <?= lang('HelpFAQ_Cat_Detail_301_head_b');?></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse301" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body">
|
||||
<?php echo lang('HelpFAQ_Cat_Detail_301_text');?>
|
||||
<?= lang('HelpFAQ_Cat_Detail_301_text');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -143,12 +143,12 @@
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_det" href="#collapse302">
|
||||
<?php echo lang('HelpFAQ_Cat_Detail_302_head_a');?> "<?php echo lang('DevDetail_EveandAl_RandomMAC');?>" <?php echo lang('HelpFAQ_Cat_Detail_302_head_b');?></a>
|
||||
<?= lang('HelpFAQ_Cat_Detail_302_head_a');?> "<?= lang('DevDetail_EveandAl_RandomMAC');?>" <?= lang('HelpFAQ_Cat_Detail_302_head_b');?></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse302" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body">
|
||||
<?php echo lang('HelpFAQ_Cat_Detail_302_text');?>
|
||||
<?= lang('HelpFAQ_Cat_Detail_302_text');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -156,29 +156,29 @@
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_det" href="#collapse303">
|
||||
<?php echo lang('HelpFAQ_Cat_Detail_303_head');?></a>
|
||||
<?= lang('HelpFAQ_Cat_Detail_303_head');?></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse303" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body">
|
||||
<?php echo lang('HelpFAQ_Cat_Detail_303_text');?>
|
||||
<?= lang('HelpFAQ_Cat_Detail_303_text');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4><?php echo lang('Navigation_Presence');?></h4>
|
||||
<h4><?= lang('Navigation_Presence');?></h4>
|
||||
<div class="panel-group" id="accordion_pre">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_pre" href="#collapse400">
|
||||
<?php echo lang('HelpFAQ_Cat_Presence_400_head');?></a>
|
||||
<?= lang('HelpFAQ_Cat_Presence_400_head');?></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse400" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body">
|
||||
<?php echo lang('HelpFAQ_Cat_Presence_400_text');?>
|
||||
<?= lang('HelpFAQ_Cat_Presence_400_text');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -186,29 +186,29 @@
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_pre" href="#collapse401">
|
||||
<?php echo lang('HelpFAQ_Cat_Presence_401_head');?></a>
|
||||
<?= lang('HelpFAQ_Cat_Presence_401_head');?></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse401" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body">
|
||||
<?php echo lang('HelpFAQ_Cat_Presence_401_text');?>
|
||||
<?= lang('HelpFAQ_Cat_Presence_401_text');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4><?php echo lang('Navigation_Network');?></h4>
|
||||
<h4><?= lang('Navigation_Network');?></h4>
|
||||
<div class="panel-group" id="accordion_net">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_net" href="#collapse600">
|
||||
<?php echo lang('HelpFAQ_Cat_Network_600_head');?></a>
|
||||
<?= lang('HelpFAQ_Cat_Network_600_head');?></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse600" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body">
|
||||
<?php echo lang('HelpFAQ_Cat_Network_600_text');?>
|
||||
<?= lang('HelpFAQ_Cat_Network_600_text');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
<!-- Pi.Alert CSS -->
|
||||
<link rel="stylesheet" href="css/pialert.css">
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
require 'php/templates/language/lang.php';
|
||||
require dirname(__FILE__).'/php/server/init.php';
|
||||
require 'php/templates/security.php';
|
||||
|
||||
|
||||
|
||||
if ($Pia_WebProtection != 'true')
|
||||
{
|
||||
header('Location: devices.php');
|
||||
@@ -11,6 +14,15 @@ if ($Pia_WebProtection != 'true')
|
||||
exit;
|
||||
}
|
||||
|
||||
// Logout
|
||||
if (isset ($_GET["action"]) && $_GET["action"] == 'logout')
|
||||
{
|
||||
setcookie("PiAlert_SaveLogin", '', time()+1); // reset cookie
|
||||
$_SESSION["login"] = 0;
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Password without Cookie check -> pass and set initial cookie
|
||||
if (isset ($_POST["loginpassword"]) && $Pia_Password == hash('sha256',$_POST["loginpassword"]))
|
||||
{
|
||||
@@ -91,16 +103,16 @@ if ($ENABLED_DARKMODE === True) {
|
||||
<link rel="stylesheet" href="/front/css/offline-font.css">
|
||||
</head>
|
||||
<body class="hold-transition login-page">
|
||||
<div class="login-box">
|
||||
<div class="login-box login-custom">
|
||||
<div class="login-logo">
|
||||
<a href="/index2.php">Pi.<b>Alert</b></a>
|
||||
</div>
|
||||
<!-- /.login-logo -->
|
||||
<div class="login-box-body">
|
||||
<p class="login-box-msg"><?php echo lang('Login_Box');?></p>
|
||||
<p class="login-box-msg"><?= lang('Login_Box');?></p>
|
||||
<form action="index.php" method="post">
|
||||
<div class="form-group has-feedback">
|
||||
<input type="password" class="form-control" placeholder="<?php echo lang('Login_Psw-box');?>" name="loginpassword">
|
||||
<input type="password" class="form-control" placeholder="<?= lang('Login_Psw-box');?>" name="loginpassword">
|
||||
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
|
||||
</div>
|
||||
<div class="row">
|
||||
@@ -109,21 +121,21 @@ if ($ENABLED_DARKMODE === True) {
|
||||
<label>
|
||||
<input type="checkbox" name="PWRemember">
|
||||
<div style="margin-left: 10px; display: inline-block; vertical-align: top;">
|
||||
<?php echo lang('Login_Remember');?><br><span style="font-size: smaller"><?php echo lang('Login_Remember_small');?></span>
|
||||
<?= lang('Login_Remember');?><br><span style="font-size: smaller"><?= lang('Login_Remember_small');?></span>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
<div class="col-xs-4" style="padding-top: 10px;">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-flat"><?php echo lang('Login_Submit');?></button>
|
||||
<button type="submit" class="btn btn-primary btn-block btn-flat"><?= lang('Login_Submit');?></button>
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div style="padding-top: 10px;">
|
||||
<button class="btn btn-xs btn-primary btn-block btn-flat" onclick="Passwordhinfo()"><?php echo lang('Login_Toggle_Info');?></button>
|
||||
<button class="btn btn-xs btn-primary btn-block btn-flat" onclick="Passwordhinfo()"><?= lang('Login_Toggle_Info');?></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -136,7 +148,7 @@ if ($ENABLED_DARKMODE === True) {
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true"><3E></button>
|
||||
<h4><i class="icon fa <?php echo $login_icon;?>"></i><?php echo $login_headline;?></h4>
|
||||
<p><?php echo $login_info;?></p>
|
||||
<p><?php echo lang('Login_Psw_run');?><br><span style="border: solid 1px yellow; padding: 2px;">./reset_password.sh <?php echo lang('Login_Psw_new');?></span><br><?php echo lang('Login_Psw_folder');?></p>
|
||||
<p><?= lang('Login_Psw_run');?><br><span style="border: solid 1px yellow; padding: 2px;"> /home/pi/pialert/back/pialert-cli set_password <?= lang('Login_Psw_new');?></span><br><?= lang('Login_Psw_folder');?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
var timerRefreshData = ''
|
||||
var modalCallbackFunction = '';
|
||||
var emptyArr = ['undefined', "", undefined, null];
|
||||
var emptyArr = ['undefined', "", undefined, null, 'null'];
|
||||
|
||||
// urlParams = new Proxy(new URLSearchParams(window.location.search), {
|
||||
// get: (searchParams, prop) => searchParams.get(prop.toString()),
|
||||
@@ -290,6 +290,18 @@ function settingsChanged()
|
||||
};
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function getQueryString(key){
|
||||
params = new Proxy(new URLSearchParams(window.location.search), {
|
||||
get: (searchParams, prop) => searchParams.get(prop),
|
||||
});
|
||||
|
||||
tmp = params[key]
|
||||
|
||||
result = emptyArr.includes(tmp) ? "" : tmp;
|
||||
|
||||
return result
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
function translateHTMLcodes (text) {
|
||||
if (text == null || emptyArr.includes(text)) {
|
||||
@@ -333,4 +345,30 @@ function openInNewTab (url) {
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function navigateToDeviceWithIp (ip) {
|
||||
|
||||
$.get('api/table_devices.json', function(res) {
|
||||
|
||||
devices = res["data"];
|
||||
|
||||
mac = ""
|
||||
|
||||
$.each(devices, function(index, obj) {
|
||||
|
||||
if(obj.dev_LastIP.trim() == ip.trim())
|
||||
{
|
||||
mac = obj.dev_MAC;
|
||||
|
||||
window.open(window.location.origin +'/deviceDetails.php?mac=' + mac , "_blank");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,19 +11,6 @@
|
||||
// leiweibau 2022 https://github.com/leiweibau GNU GPLv3
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Language selector config ----------------------------------------------------
|
||||
//
|
||||
// For security reasons, new language files must be entered into this array.
|
||||
// The files in the language directory are compared with this array and only
|
||||
// then accepted.
|
||||
//
|
||||
$pia_installed_langs = array('en_us',
|
||||
'de_de',
|
||||
'es_es');
|
||||
//
|
||||
// In addition to this, the language must also be added to the select tag in
|
||||
// line 235. Later, the whole thing may become dynamic.
|
||||
|
||||
// Skin selector config ----------------------------------------------------
|
||||
//
|
||||
// For security reasons, new language files must be entered into this array.
|
||||
@@ -57,7 +44,7 @@ $pia_installed_skins = array('skin-black-light',
|
||||
<section class="content-header">
|
||||
<?php require 'php/templates/notification.php'; ?>
|
||||
<h1 id="pageTitle">
|
||||
<?php echo lang('Maintenance_Title');?>
|
||||
<?= lang('Maintenance_Title');?>
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
@@ -145,31 +132,31 @@ if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
|
||||
<div class="box-body" style="padding-bottom: 5px;">
|
||||
<div class="db_info_table">
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_info_table_cell" style="min-width: 140px"><?php echo lang('Maintenance_version');?></div>
|
||||
<div class="db_info_table_cell" style="min-width: 140px"><?= lang('Maintenance_version');?></div>
|
||||
<div class="db_info_table_cell">
|
||||
<div class="version" id="version" data-build-time="<?php echo file_get_contents( "buildtimestamp.txt");?>"><?php echo '<span id="new-version-text" class="myhidden">' .lang('Maintenance_new_version').'</span>'.'<span id="current-version-text" class="myhidden">' .lang('Maintenance_current_version').'</span>';?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_info_table_cell" style="min-width: 140px"><?php echo lang('Maintenance_database_path');?></div>
|
||||
<div class="db_info_table_cell" style="min-width: 140px"><?= lang('Maintenance_database_path');?></div>
|
||||
<div class="db_info_table_cell">
|
||||
<?php echo $pia_db;?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_info_table_cell"><?php echo lang('Maintenance_database_size');?></div>
|
||||
<div class="db_info_table_cell"><?= lang('Maintenance_database_size');?></div>
|
||||
<div class="db_info_table_cell">
|
||||
<?php echo $pia_db_size;?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_info_table_cell"><?php echo lang('Maintenance_database_lastmod');?></div>
|
||||
<div class="db_info_table_cell"><?= lang('Maintenance_database_lastmod');?></div>
|
||||
<div class="db_info_table_cell">
|
||||
<?php echo $pia_db_mod;?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_info_table_cell"><?php echo lang('Maintenance_database_backup');?></div>
|
||||
<div class="db_info_table_cell"><?= lang('Maintenance_database_backup');?></div>
|
||||
<div class="db_info_table_cell">
|
||||
<?php echo $Pia_Archive_count.' '.lang('Maintenance_database_backup_found').' / '.lang('Maintenance_database_backup_total').': '.$Pia_Archive_diskusage;?>
|
||||
</div>
|
||||
@@ -184,44 +171,27 @@ if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
|
||||
<div class="nav-tabs-custom">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active">
|
||||
<a id="tab_Settings_id" href="#tab_Settings" data-toggle="tab"><?php echo lang('Maintenance_Tools_Tab_UISettings');?></a>
|
||||
<a id="tab_Settings_id" href="#tab_Settings" data-toggle="tab"><?= lang('Maintenance_Tools_Tab_UISettings');?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a id="tab_DBTools_id" href="#tab_DBTools" data-toggle="tab"><?php echo lang('Maintenance_Tools_Tab_Tools');?></a>
|
||||
<a id="tab_DBTools_id" href="#tab_DBTools" data-toggle="tab"><?= lang('Maintenance_Tools_Tab_Tools');?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a id="tab_BackupRestore_id" href="#tab_BackupRestore" data-toggle="tab"><?php echo lang('Maintenance_Tools_Tab_BackupRestore');?></a>
|
||||
<a id="tab_BackupRestore_id" href="#tab_BackupRestore" data-toggle="tab"><?= lang('Maintenance_Tools_Tab_BackupRestore');?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a id="tab_Logging_id" href="#tab_Logging" data-toggle="tab"><?php echo lang('Maintenance_Tools_Tab_Logging');?></a>
|
||||
<a id="tab_Logging_id" href="#tab_Logging" data-toggle="tab"><?= lang('Maintenance_Tools_Tab_Logging');?></a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="tab_Settings">
|
||||
<div class="db_info_table">
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" style="text-align:center;">
|
||||
<form method="post" action="maintenance.php">
|
||||
<div style="display: inline-block;">
|
||||
<select name="langselector" id="langselector" class="form-control bg-green" style="width:160px; margin-bottom:5px;">
|
||||
<option value=""><?php echo lang('Maintenance_lang_selector_empty');?></option>
|
||||
<option value="en_us"><?php echo lang('Maintenance_lang_en_us');?></option>
|
||||
<option value="de_de"><?php echo lang('Maintenance_lang_de_de');?></option>
|
||||
<option value="es_es"><?php echo lang('Maintenance_lang_es_es');?></option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="db_info_table_cell" style="padding: 10px; height:40px; text-align:left; vertical-align: middle;">
|
||||
<?php echo lang('Maintenance_lang_selector_text');?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" style="text-align: center;">
|
||||
<form method="post" action="maintenance.php">
|
||||
<div style="display: inline-block; text-align: center;">
|
||||
<select name="skinselector" class="form-control bg-green" style="width:160px; margin-bottom:5px;">
|
||||
<option value=""><?php echo lang('Maintenance_themeselector_empty');?></option>
|
||||
<option value=""><?= lang('Maintenance_themeselector_empty');?></option>
|
||||
<option value="skin-black-light">black light</option>
|
||||
<option value="skin-black">black</option>
|
||||
<option value="skin-blue-light">blue light</option>
|
||||
@@ -235,49 +205,52 @@ if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
|
||||
<option value="skin-yellow-light">yellow light</option>
|
||||
<option value="skin-yellow">yellow</option>
|
||||
</select></div>
|
||||
<div style="display: block;"><input type="submit" name="skinselector_set" value="<?php echo lang('Maintenance_themeselector_apply');?>" class="btn bg-green" style="width:160px;">
|
||||
<div style="display: block;"><input type="submit" name="skinselector_set" value="<?= lang('Maintenance_themeselector_apply');?>" class="btn bg-green" style="width:160px;">
|
||||
<?php // echo $pia_skin_test; ?>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="db_info_table_cell" style="padding: 10px; height:40px; text-align:left; vertical-align: middle;">
|
||||
<?php echo lang('Maintenance_themeselector_text'); ?>
|
||||
<?= lang('Maintenance_themeselector_text'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a">
|
||||
<button type="button" class="btn bg-green dbtools-button" id="btnToggleDarkmode" onclick="askToggleDarkmode()"><?php echo lang('Maintenance_Tool_darkmode');?></button>
|
||||
<button type="button" class="btn bg-green dbtools-button" id="btnToggleDarkmode" onclick="askToggleDarkmode()"><?= lang('Maintenance_Tool_darkmode');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_darkmode_text');?></div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_darkmode_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a">
|
||||
<div class="form-group" >
|
||||
<div class="input-group" >
|
||||
<select id="columnsSelect" class="form-control select2 select2-hidden-accessible" multiple="" style="width: 100%;" tabindex="-1" aria-hidden="true">
|
||||
<option value="0"><?php echo lang('Device_TableHead_Name');?></option>
|
||||
<option value="1"><?php echo lang('Device_TableHead_Owner');?></option>
|
||||
<option value="2"><?php echo lang('Device_TableHead_Type');?></option>
|
||||
<option value="3"><?php echo lang('Device_TableHead_Icon');?></option>
|
||||
<option value="4"><?php echo lang('Device_TableHead_Favorite');?></option>
|
||||
<option value="5"><?php echo lang('Device_TableHead_Group');?></option>
|
||||
<option value="6"><?php echo lang('Device_TableHead_FirstSession');?></option>
|
||||
<option value="7"><?php echo lang('Device_TableHead_LastSession');?></option>
|
||||
<option value="8"><?php echo lang('Device_TableHead_LastIP');?></option>
|
||||
<option value="9"><?php echo lang('Device_TableHead_MAC');?></option>
|
||||
<option value="10"><?php echo lang('Device_TableHead_Status');?></option>
|
||||
<option value="11"><?php echo lang('Device_TableHead_MAC_full');?></option>
|
||||
<option value="12"><?php echo lang('Device_TableHead_LastIPOrder');?></option>
|
||||
<option value="13"><?php echo lang('Device_TableHead_Rowid');?></option>
|
||||
<option value="14"><?php echo lang('Device_TableHead_Parent_MAC');?></option>
|
||||
<option value="0"><?= lang('Device_TableHead_Name');?></option>
|
||||
<option value="1"><?= lang('Device_TableHead_Owner');?></option>
|
||||
<option value="2"><?= lang('Device_TableHead_Type');?></option>
|
||||
<option value="3"><?= lang('Device_TableHead_Icon');?></option>
|
||||
<option value="4"><?= lang('Device_TableHead_Favorite');?></option>
|
||||
<option value="5"><?= lang('Device_TableHead_Group');?></option>
|
||||
<option value="6"><?= lang('Device_TableHead_FirstSession');?></option>
|
||||
<option value="7"><?= lang('Device_TableHead_LastSession');?></option>
|
||||
<option value="8"><?= lang('Device_TableHead_LastIP');?></option>
|
||||
<option value="9"><?= lang('Device_TableHead_MAC');?></option>
|
||||
<option value="10"><?= lang('Device_TableHead_Status');?></option>
|
||||
<option value="11"><?= lang('Device_TableHead_MAC_full');?></option>
|
||||
<option value="12"><?= lang('Device_TableHead_LastIPOrder');?></option>
|
||||
<option value="13"><?= lang('Device_TableHead_Rowid');?></option>
|
||||
<option value="14"><?= lang('Device_TableHead_Parent_MAC');?></option>
|
||||
<option value="15"><?= lang('Device_TableHead_Connected_Devices');?></option>
|
||||
<option value="16"><?= lang('Device_TableHead_Location');?></option>
|
||||
<option value="17"><?= lang('Device_TableHead_Vendor');?></option>
|
||||
</select>
|
||||
<span class="input-group-addon"><i title="<?php echo lang('DevDetail_GoToNetworkNode');?>" class="fa fa-save pointer" onclick="saveSelectedColumns();"></i></span>
|
||||
<span class="input-group-addon"><i title="<?= lang('Gen_Save');?>" class="fa fa-save pointer" onclick="saveSelectedColumns();"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_displayed_columns_text');?></div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_displayed_columns_text');?></div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -287,39 +260,39 @@ if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
|
||||
<div class="db_info_table">
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" style="">
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteMAC" onclick="askDeleteDevicesWithEmptyMACs()"><?php echo lang('Maintenance_Tool_del_empty_macs');?></button>
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteMAC" onclick="askDeleteDevicesWithEmptyMACs()"><?= lang('Maintenance_Tool_del_empty_macs');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_del_empty_macs_text');?></div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_empty_macs_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" style="">
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteMAC" onclick="askDeleteAllDevices()"><?php echo lang('Maintenance_Tool_del_alldev');?></button>
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteMAC" onclick="askDeleteAllDevices()"><?= lang('Maintenance_Tool_del_alldev');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_del_alldev_text');?></div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_alldev_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" style="">
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteUnknown" onclick="askDeleteUnknown()"><?php echo lang('Maintenance_Tool_del_unknowndev');?></button>
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteUnknown" onclick="askDeleteUnknown()"><?= lang('Maintenance_Tool_del_unknowndev');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_del_unknowndev_text');?></div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_unknowndev_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" style="">
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteEvents" onclick="askDeleteEvents()"><?php echo lang('Maintenance_Tool_del_allevents');?></button>
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteEvents" onclick="askDeleteEvents()"><?= lang('Maintenance_Tool_del_allevents');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_del_allevents_text');?></div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_allevents_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" style="">
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteEvents30" onclick="askDeleteEvents30()"><?php echo lang('Maintenance_Tool_del_allevents30');?></button>
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteEvents30" onclick="askDeleteEvents30()"><?= lang('Maintenance_Tool_del_allevents30');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_del_allevents30_text');?></div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_allevents30_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" style="">
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteActHistory" onclick="askDeleteActHistory()"><?php echo lang('Maintenance_Tool_del_ActHistory');?></button>
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteActHistory" onclick="askDeleteActHistory()"><?= lang('Maintenance_Tool_del_ActHistory');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_del_ActHistory_text');?></div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_ActHistory_text');?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -327,33 +300,33 @@ if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
|
||||
<div class="db_info_table">
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" style="">
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnPiaBackupDBtoArchive" onclick="askPiaBackupDBtoArchive()"><?php echo lang('Maintenance_Tool_backup');?></button>
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnPiaBackupDBtoArchive" onclick="askPiaBackupDBtoArchive()"><?= lang('Maintenance_Tool_backup');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_backup_text');?></div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_backup_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" style="">
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnPiaRestoreDBfromArchive" onclick="askPiaRestoreDBfromArchive()"><?php echo lang('Maintenance_Tool_restore');?><br><?php echo $latestbackup_date;?></button>
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnPiaRestoreDBfromArchive" onclick="askPiaRestoreDBfromArchive()"><?= lang('Maintenance_Tool_restore');?><br><?php echo $latestbackup_date;?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_restore_text');?></div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_restore_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" style="">
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnPiaPurgeDBBackups" onclick="askPiaPurgeDBBackups()"><?php echo lang('Maintenance_Tool_purgebackup');?></button>
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnPiaPurgeDBBackups" onclick="askPiaPurgeDBBackups()"><?= lang('Maintenance_Tool_purgebackup');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_purgebackup_text');?></div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_purgebackup_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" style="">
|
||||
<button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnExportCSV" onclick="askExportCSV()"><?php echo lang('Maintenance_Tool_ExportCSV');?></button>
|
||||
<button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnExportCSV" onclick="askExportCSV()"><?= lang('Maintenance_Tool_ExportCSV');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_ExportCSV_text');?></div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ExportCSV_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" style="">
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportCSV" onclick="askImportCSV()"><?php echo lang('Maintenance_Tool_ImportCSV');?></button>
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportCSV" onclick="askImportCSV()"><?= lang('Maintenance_Tool_ImportCSV');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_ImportCSV_text');?></div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ImportCSV_text');?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -371,7 +344,7 @@ if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
|
||||
<span class="span-padding"><a href="./log/pialert.log" target="_blank"><i class="fa fa-download"></i> </a></span>
|
||||
</div></div>
|
||||
<div class="log-purge">
|
||||
<button class="btn btn-primary" onclick="logManage('pialert.log','cleanLog')"><?php echo lang('Gen_Purge');?></button>
|
||||
<button class="btn btn-primary" onclick="logManage('pialert.log','cleanLog')"><?= lang('Gen_Purge');?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -387,29 +360,11 @@ if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
|
||||
<span class="span-padding"><a href="./log/pialert_front.log"><i class="fa fa-download"></i> </a></span>
|
||||
</div></div>
|
||||
<div class="log-purge">
|
||||
<button class="btn btn-primary" onclick="logManage('pialert_front.log','cleanLog')"><?php echo lang('Gen_Purge');?></button>
|
||||
<button class="btn btn-primary" onclick="logManage('pialert_front.log','cleanLog')"><?= lang('Gen_Purge');?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="log-area">
|
||||
|
||||
<div class="row logs-row">
|
||||
<textarea id="pialert_pholus_log" class="logs" cols="70" rows="10" wrap='off' readonly><?php echo file_get_contents( "./log/pialert_pholus.log" ); ?>
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="row logs-row" >
|
||||
<div>
|
||||
<div class="log-file">pialert_pholus.log<div class="logs-size"><?php echo number_format((filesize("./log/pialert_pholus.log") / 1000000),2,",",".") . ' MB';?>
|
||||
<span class="span-padding"><a href="./log/pialert_pholus.log"><i class="fa fa-download"></i> </a></span>
|
||||
</div></div>
|
||||
<div class="log-purge">
|
||||
<button class="btn btn-primary" onclick="logManage('pialert_pholus.log','cleanLog')"><?php echo lang('Gen_Purge');?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="log-area">
|
||||
|
||||
<div class="row logs-row">
|
||||
@@ -422,7 +377,7 @@ if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
|
||||
<span class="span-padding"><a href="./log/pialert_pholus_lastrun.log"><i class="fa fa-download"></i> </a></span>
|
||||
</div></div>
|
||||
<div class="log-purge">
|
||||
<button class="btn btn-primary" onclick="logManage('pialert_pholus_lastrun.log','cleanLog')"><?php echo lang('Gen_Purge');?></button>
|
||||
<button class="btn btn-primary" onclick="logManage('pialert_pholus_lastrun.log','cleanLog')"><?= lang('Gen_Purge');?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -440,7 +395,7 @@ if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
|
||||
<span class="span-padding"><a href="./log/IP_changes.log"><i class="fa fa-download"></i> </a></span>
|
||||
</div></div>
|
||||
<div class="log-purge">
|
||||
<button class="btn btn-primary" onclick="logManage('IP_changes.log','cleanLog')"><?php echo lang('Gen_Purge');?></button>
|
||||
<button class="btn btn-primary" onclick="logManage('IP_changes.log','cleanLog')"><?= lang('Gen_Purge');?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -457,7 +412,7 @@ if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
|
||||
<span class="span-padding"><a href="./log/stdout.log"><i class="fa fa-download"></i> </a></span>
|
||||
</div></div>
|
||||
<div class="log-purge">
|
||||
<button class="btn btn-primary" onclick="logManage('stdout.log','cleanLog')"><?php echo lang('Gen_Purge');?></button>
|
||||
<button class="btn btn-primary" onclick="logManage('stdout.log','cleanLog')"><?= lang('Gen_Purge');?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -474,7 +429,7 @@ if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
|
||||
<span class="span-padding"><a href="./log/stderr.log"><i class="fa fa-download"></i> </a></span>
|
||||
</div></div>
|
||||
<div class="log-purge">
|
||||
<button class="btn btn-primary" onclick="logManage('stderr.log','cleanLog')"><?php echo lang('Gen_Purge');?></button>
|
||||
<button class="btn btn-primary" onclick="logManage('stderr.log','cleanLog')"><?= lang('Gen_Purge');?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -525,7 +480,7 @@ initializeTabs();
|
||||
// delete devices with emty macs
|
||||
function askDeleteDevicesWithEmptyMACs () {
|
||||
// Ask
|
||||
showModalWarning('<?php echo lang('Maintenance_Tool_del_empty_macs_noti');?>', '<?php echo lang('Maintenance_Tool_del_empty_macs_noti_text');?>',
|
||||
showModalWarning('<?= lang('Maintenance_Tool_del_empty_macs_noti');?>', '<?= lang('Maintenance_Tool_del_empty_macs_noti_text');?>',
|
||||
'Cancel', 'Delete', 'deleteDevicesWithEmptyMACs');
|
||||
}
|
||||
function deleteDevicesWithEmptyMACs()
|
||||
@@ -539,8 +494,8 @@ function deleteDevicesWithEmptyMACs()
|
||||
// delete all devices
|
||||
function askDeleteAllDevices () {
|
||||
// Ask
|
||||
showModalWarning('<?php echo lang('Maintenance_Tool_del_alldev_noti');?>', '<?php echo lang('Maintenance_Tool_del_alldev_noti_text');?>',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Delete');?>', 'deleteAllDevices');
|
||||
showModalWarning('<?= lang('Maintenance_Tool_del_alldev_noti');?>', '<?= lang('Maintenance_Tool_del_alldev_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteAllDevices');
|
||||
}
|
||||
function deleteAllDevices()
|
||||
{
|
||||
@@ -553,8 +508,8 @@ function deleteAllDevices()
|
||||
// delete all (unknown) devices
|
||||
function askDeleteUnknown () {
|
||||
// Ask
|
||||
showModalWarning('<?php echo lang('Maintenance_Tool_del_unknowndev_noti');?>', '<?php echo lang('Maintenance_Tool_del_unknowndev_noti_text');?>',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Delete');?>', 'deleteUnknownDevices');
|
||||
showModalWarning('<?= lang('Maintenance_Tool_del_unknowndev_noti');?>', '<?= lang('Maintenance_Tool_del_unknowndev_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteUnknownDevices');
|
||||
}
|
||||
function deleteUnknownDevices()
|
||||
{
|
||||
@@ -567,8 +522,8 @@ function deleteUnknownDevices()
|
||||
// delete all Events
|
||||
function askDeleteEvents () {
|
||||
// Ask
|
||||
showModalWarning('<?php echo lang('Maintenance_Tool_del_allevents_noti');?>', '<?php echo lang('Maintenance_Tool_del_allevents_noti_text');?>',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Delete');?>', 'deleteEvents');
|
||||
showModalWarning('<?= lang('Maintenance_Tool_del_allevents_noti');?>', '<?= lang('Maintenance_Tool_del_allevents_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteEvents');
|
||||
}
|
||||
function deleteEvents()
|
||||
{
|
||||
@@ -581,8 +536,8 @@ function deleteEvents()
|
||||
// delete all Events older than 30 days
|
||||
function askDeleteEvents30 () {
|
||||
// Ask
|
||||
showModalWarning('<?php echo lang('Maintenance_Tool_del_allevents30_noti');?>', '<?php echo lang('Maintenance_Tool_del_allevents30_noti_text');?>',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Delete');?>', 'deleteEvents30');
|
||||
showModalWarning('<?= lang('Maintenance_Tool_del_allevents30_noti');?>', '<?= lang('Maintenance_Tool_del_allevents30_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteEvents30');
|
||||
}
|
||||
function deleteEvents30()
|
||||
{
|
||||
@@ -595,8 +550,8 @@ function deleteEvents30()
|
||||
// delete History
|
||||
function askDeleteActHistory () {
|
||||
// Ask
|
||||
showModalWarning('<?php echo lang('Maintenance_Tool_del_ActHistory_noti');?>', '<?php echo lang('Maintenance_Tool_del_ActHistory_noti_text');?>',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Delete');?>', 'deleteActHistory');
|
||||
showModalWarning('<?= lang('Maintenance_Tool_del_ActHistory_noti');?>', '<?= lang('Maintenance_Tool_del_ActHistory_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteActHistory');
|
||||
}
|
||||
function deleteActHistory()
|
||||
{
|
||||
@@ -609,8 +564,8 @@ function deleteActHistory()
|
||||
// Backup DB to Archive
|
||||
function askPiaBackupDBtoArchive () {
|
||||
// Ask
|
||||
showModalWarning('<?php echo lang('Maintenance_Tool_backup_noti');?>', '<?php echo lang('Maintenance_Tool_backup_noti_text');?>',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Backup');?>', 'PiaBackupDBtoArchive');
|
||||
showModalWarning('<?= lang('Maintenance_Tool_backup_noti');?>', '<?= lang('Maintenance_Tool_backup_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Backup');?>', 'PiaBackupDBtoArchive');
|
||||
}
|
||||
function PiaBackupDBtoArchive()
|
||||
{
|
||||
@@ -623,8 +578,8 @@ function PiaBackupDBtoArchive()
|
||||
// Restore DB from Archive
|
||||
function askPiaRestoreDBfromArchive () {
|
||||
// Ask
|
||||
showModalWarning('<?php echo lang('Maintenance_Tool_restore_noti');?>', '<?php echo lang('Maintenance_Tool_restore_noti_text');?>',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Restore');?>', 'PiaRestoreDBfromArchive');
|
||||
showModalWarning('<?= lang('Maintenance_Tool_restore_noti');?>', '<?= lang('Maintenance_Tool_restore_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Restore');?>', 'PiaRestoreDBfromArchive');
|
||||
}
|
||||
function PiaRestoreDBfromArchive()
|
||||
{
|
||||
@@ -637,8 +592,8 @@ function PiaRestoreDBfromArchive()
|
||||
// Purge Backups
|
||||
function askPiaPurgeDBBackups() {
|
||||
// Ask
|
||||
showModalWarning('<?php echo lang('Maintenance_Tool_purgebackup_noti');?>', '<?php echo lang('Maintenance_Tool_purgebackup_noti_text');?>',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Purge');?>', 'PiaPurgeDBBackups');
|
||||
showModalWarning('<?= lang('Maintenance_Tool_purgebackup_noti');?>', '<?= lang('Maintenance_Tool_purgebackup_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Purge');?>', 'PiaPurgeDBBackups');
|
||||
}
|
||||
function PiaPurgeDBBackups()
|
||||
{
|
||||
@@ -651,8 +606,8 @@ function PiaPurgeDBBackups()
|
||||
// Export CSV
|
||||
function askExportCSV() {
|
||||
// Ask
|
||||
showModalWarning('<?php echo lang('Maintenance_Tool_ExportCSV_noti');?>', '<?php echo lang('Maintenance_Tool_ExportCSV_noti_text');?>',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Okay');?>', 'ExportCSV');
|
||||
showModalWarning('<?= lang('Maintenance_Tool_ExportCSV_noti');?>', '<?= lang('Maintenance_Tool_ExportCSV_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', 'ExportCSV');
|
||||
}
|
||||
function ExportCSV()
|
||||
{
|
||||
@@ -663,8 +618,8 @@ function ExportCSV()
|
||||
// Import CSV
|
||||
function askImportCSV() {
|
||||
// Ask
|
||||
showModalWarning('<?php echo lang('Maintenance_Tool_ImportCSV_noti');?>', '<?php echo lang('Maintenance_Tool_ImportCSV_noti_text');?>',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Okay');?>', 'ImportCSV');
|
||||
showModalWarning('<?= lang('Maintenance_Tool_ImportCSV_noti');?>', '<?= lang('Maintenance_Tool_ImportCSV_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', 'ImportCSV');
|
||||
}
|
||||
function ImportCSV()
|
||||
{
|
||||
@@ -679,8 +634,8 @@ function ImportCSV()
|
||||
// Switch Darkmode
|
||||
function askToggleDarkmode() {
|
||||
// Ask
|
||||
showModalWarning('<?php echo lang('Maintenance_Tool_darkmode_noti');?>', '<?php echo lang('Maintenance_Tool_darkmode_noti_text');?>',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Switch');?>', 'ToggleDarkmode');
|
||||
showModalWarning('<?= lang('Maintenance_Tool_darkmode_noti');?>', '<?= lang('Maintenance_Tool_darkmode_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Switch');?>', 'ToggleDarkmode');
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
@@ -724,8 +679,8 @@ function logManage(callback) {
|
||||
targetLogFile = arguments[0]; // target
|
||||
logFileAction = arguments[1]; // action
|
||||
// Ask
|
||||
showModalWarning('<?php echo lang('Gen_Purge');?>' + ' ' + arguments[1], '<?php echo lang('Gen_AreYouSure');?>',
|
||||
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Okay');?>', "performLogManage");
|
||||
showModalWarning('<?= lang('Gen_Purge');?>' + ' ' + arguments[1], '<?= lang('Gen_AreYouSure');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', "performLogManage");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
@@ -760,6 +715,9 @@ function scrollDown()
|
||||
// --------------------------------------------------------
|
||||
// Manage displayed columns
|
||||
// --------------------------------------------------------
|
||||
colDefaultOrder = ['0','1','2','3','4','5','6','7','8','9','10','12','13','14','15','16','17'];
|
||||
colDefaultOrderTxt = '[0,1,2,3,4,5,6,7,8,9,10,12,13,14,15,16,17]';
|
||||
|
||||
|
||||
function saveSelectedColumns () {
|
||||
$.get('php/server/parameters.php?action=set&expireMinutes=525600&value=['+ $('#columnsSelect').val().toString() +']¶meter=Front_Devices_Columns_Visible', function(data) {
|
||||
@@ -767,7 +725,7 @@ function saveSelectedColumns () {
|
||||
|
||||
colDisplayed = $('#columnsSelect').val();
|
||||
|
||||
colDefaultOrder = ['0','1','2','3','4','5','6','7','8','9','10','12','13','14'];
|
||||
|
||||
|
||||
colNewOrder = colDisplayed;
|
||||
|
||||
@@ -791,7 +749,7 @@ function saveSelectedColumns () {
|
||||
|
||||
// --------------------------------------------------------
|
||||
function initializeSelectedColumns () {
|
||||
$.get('php/server/parameters.php?action=get&expireMinutes=525600&defaultValue=[0,1,2,3,4,5,6,7,8,9,10,12,13,14]¶meter=Front_Devices_Columns_Visible', function(data) {
|
||||
$.get('php/server/parameters.php?action=get&expireMinutes=525600&defaultValue='+colDefaultOrderTxt+'¶meter=Front_Devices_Columns_Visible', function(data) {
|
||||
|
||||
tableColumnShow = numberArrayFromString(data);
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<?php
|
||||
|
||||
require 'php/templates/header.php';
|
||||
require 'php/server/db.php';
|
||||
require 'php/server/util.php';
|
||||
|
||||
// online / offline badges HTML snippets
|
||||
define('badge_online', '<div class="badge bg-green text-white" style="width: 60px;">Online</div>');
|
||||
@@ -20,7 +18,8 @@
|
||||
<section class="content-header">
|
||||
<?php require 'php/templates/notification.php'; ?>
|
||||
<h1 id="pageTitle">
|
||||
<i class="fa fa-network-wired"></i> <?php echo lang('Network_Title');?>
|
||||
<i class="fa fa-network-wired"></i> <?= lang('Network_Title');?>
|
||||
<span class="networkPageHelp"> <a target="_blank" href="https://github.com/jokob-sk/Pi.Alert/blob/main/docs/NETWORK_TREE.md"><i class="fa fa-circle-question"></i></a><span>
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
@@ -126,7 +125,7 @@
|
||||
<b>'.lang('Network_Parent').'</b>
|
||||
</td>
|
||||
<td>
|
||||
<a onclick="setCache(\'activeNetworkTab\',\''.$idParentMac.'_id\')" href="./network.php">
|
||||
<a href="./network.php?mac='.$idParentMac.'">
|
||||
<b class="anonymize">'.$idParentMac.' <i class="fa fa-square-up-right"></i></b>
|
||||
</a>
|
||||
</td>
|
||||
@@ -359,7 +358,7 @@
|
||||
dev_Name as name,
|
||||
dev_LastIP as last_ip,
|
||||
dev_Network_Node_MAC_ADDR
|
||||
FROM Devices WHERE (dev_Network_Node_MAC_ADDR is null or dev_Network_Node_MAC_ADDR = "" or dev_Network_Node_MAC_ADDR = " " ) and dev_MAC not like "%internet%" order by name asc';
|
||||
FROM Devices WHERE (dev_Network_Node_MAC_ADDR is null or dev_Network_Node_MAC_ADDR = "" or dev_Network_Node_MAC_ADDR = " " or dev_Network_Node_MAC_ADDR = "undefined") and dev_MAC not like "%internet%" order by name asc';
|
||||
|
||||
global $db;
|
||||
$func_result = $db->query($func_sql);
|
||||
@@ -453,8 +452,34 @@
|
||||
<script src="lib/treeviz/require.js"></script>
|
||||
<script src="js/pialert_common.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
$.get('php/server/devices.php?action=getDevicesList&status=all&forceDefaultOrder', function(data) {
|
||||
|
||||
rawData = JSON.parse (data)
|
||||
|
||||
devicesListnew = rawData["data"].map(item => { return {
|
||||
"name":item[0],
|
||||
"type":item[2],
|
||||
"icon":item[3],
|
||||
"mac":item[11],
|
||||
"parentMac":item[14],
|
||||
"rowid":item[13],
|
||||
"status":item[10],
|
||||
"childrenQty":item[15]
|
||||
}})
|
||||
|
||||
setCache('devicesListNew', JSON.stringify(devicesListnew))
|
||||
|
||||
// create tree
|
||||
initTree(getHierarchy());
|
||||
|
||||
// attach on-click events
|
||||
attachTreeEvents();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<script defer>
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tree functionality
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -462,7 +487,7 @@
|
||||
function getDevicesList()
|
||||
{
|
||||
// Read cache
|
||||
devicesList = getCache('devicesList');
|
||||
devicesList = getCache('devicesListNew');
|
||||
|
||||
if (devicesList != '') {
|
||||
devicesList = JSON.parse (devicesList);
|
||||
@@ -475,9 +500,15 @@
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
var leafNodesCount = 0;
|
||||
var treeLoadedAlready = false;
|
||||
var hiddenMacs = [];
|
||||
var visibleNodesCount = 0;
|
||||
var parentNodesCount = 0;
|
||||
var hiddenMacs = []; // hidden children
|
||||
var hiddenChildren = [];
|
||||
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
function getChildren(node, list, path)
|
||||
{
|
||||
var children = [];
|
||||
@@ -485,24 +516,32 @@
|
||||
// loop thru all items and find childern...
|
||||
for(var i in list)
|
||||
{
|
||||
//... of teh current node
|
||||
//... of the current node
|
||||
if(list[i].parentMac == node.mac && !hiddenMacs.includes(list[i].parentMac))
|
||||
{
|
||||
visibleNodesCount++
|
||||
|
||||
// and process them
|
||||
children.push(getChildren(list[i], list, path + ((path == "") ? "" : '|') + list[i].parentMac, hiddenMacs))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// note the total number of leaf nodes to calculate the font scaling
|
||||
if(!treeLoadedAlready && children.length == 0)
|
||||
if(children.length == 0)
|
||||
{
|
||||
leafNodesCount++
|
||||
} else
|
||||
{
|
||||
parentNodesCount++
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
name: node.name,
|
||||
path: path,
|
||||
mac: node.mac,
|
||||
id: node.mac,
|
||||
parentMac: node.parentMac,
|
||||
icon: node.icon,
|
||||
type: node.type,
|
||||
@@ -516,9 +555,11 @@
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
list = getDevicesList();
|
||||
|
||||
function getHierarchy()
|
||||
{
|
||||
list = getDevicesList();
|
||||
|
||||
for(i in list)
|
||||
{
|
||||
if(list[i].mac == 'Internet')
|
||||
@@ -567,24 +608,29 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
var myTree;
|
||||
var treeAreaHeight = 600;
|
||||
var emSize;
|
||||
var nodeHeight;
|
||||
|
||||
function initTree(myHierarchy)
|
||||
{
|
||||
// to prevent font scaling everytime we collapse/expand a subtree
|
||||
treeLoadedAlready = true;
|
||||
// calculate the font size of the leaf nodes to fit everything into the tree area
|
||||
leafNodesCount == 0 ? 1 : leafNodesCount;
|
||||
emSize = ((600/(20*leafNodesCount)).toFixed(2));
|
||||
emSize = emSize > 1 ? 1 : emSize;
|
||||
|
||||
$("#networkTree").attr('style', "height:"+treeAreaHeight+"px; width:1070px")
|
||||
nodeHeight = ((emSize*100*0.30).toFixed(0))
|
||||
|
||||
$("#networkTree").attr('style', `height:${treeAreaHeight}px; width:${$('.content-header').width()}px`)
|
||||
|
||||
myTree = Treeviz.create({
|
||||
htmlId: "networkTree",
|
||||
|
||||
renderNode: nodeData => {
|
||||
|
||||
// calculate the font size of the leaf nodes to fit everything into the tree area
|
||||
var fontSize = (nodeData.data.hasChildren) ? "" : "font-size:"+((600/(20*leafNodesCount)).toFixed(2))+"em;";
|
||||
var fontSize = "font-size:"+emSize+"em;";
|
||||
|
||||
deviceIcon = (!emptyArr.includes(nodeData.data.icon )) ? "<div class='netIcon ' ><i class='fa fa-"+nodeData.data.icon +"'></i></div>" : "";
|
||||
collapseExpandIcon = nodeData.data.hiddenChildren ? "square-plus" :"square-minus";
|
||||
collapseExpandHtml = (nodeData.data.hasChildren) ? "<div class='netCollapse' data-mytreepath='"+nodeData.data.path+"' data-mytreemac='"+nodeData.data.mac+"'><i class='fa fa-"+ collapseExpandIcon +" pointer'></i></div>" : "";
|
||||
collapseExpandHtml = (nodeData.data.hasChildren) ? "<div class='netCollapse' style='font-size:"+emSize*2.5+"em;' data-mytreepath='"+nodeData.data.path+"' data-mytreemac='"+nodeData.data.mac+"'><i class='fa fa-"+ collapseExpandIcon +" pointer'></i></div>" : "";
|
||||
statusCss = " netStatus-" + nodeData.data.status;
|
||||
|
||||
selectedNodeMac = $(".nav-tabs-custom .active a").attr('data-mytabmac')
|
||||
@@ -599,7 +645,6 @@
|
||||
justify-content:center;\
|
||||
" + fontSize + "\
|
||||
align-items:center;\
|
||||
background-color:" +nodeData.data.color+";\
|
||||
border-radius:5px;'\
|
||||
>\
|
||||
<div class='netNodeText '>\
|
||||
@@ -614,20 +659,20 @@
|
||||
// console.log(this)
|
||||
},
|
||||
mainAxisNodeSpacing: 'auto',
|
||||
// mainAxisNodeSpacing: 3,
|
||||
secondaryAxisNodeSpacing: 0.3,
|
||||
nodeHeight: '25',
|
||||
nodeHeight: nodeHeight.toString(),
|
||||
marginTop: '5',
|
||||
hasZoom: false,
|
||||
hasPan: false,
|
||||
marginLeft: '15',
|
||||
idKey: "name",
|
||||
// marginLeft: '15',
|
||||
idKey: "id",
|
||||
hasFlatData: false,
|
||||
linkWidth: (nodeData) => 3,
|
||||
relationnalField: "children",
|
||||
});
|
||||
|
||||
myTree.refresh(myHierarchy);
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -637,25 +682,7 @@
|
||||
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
|
||||
// init parent node
|
||||
var currentNodeMac = $(".tab-content .active td[data-mynodemac]").attr('data-mynodemac');
|
||||
|
||||
initButtons(currentNodeMac);
|
||||
|
||||
// change highlighted node in the tree
|
||||
selNode = $("#networkTree .highlightedNode")[0]
|
||||
|
||||
// console.log(selNode)
|
||||
|
||||
if(selNode)
|
||||
{
|
||||
$(selNode).attr('class', $(selNode).attr('class').replace('highlightedNode'))
|
||||
}
|
||||
|
||||
newSelNode = $("#networkTree div[data-mytreemacmain='"+currentNodeMac+"']")[0]
|
||||
|
||||
$(newSelNode).attr('class', $(newSelNode).attr('class') + ' highlightedNode')
|
||||
|
||||
initButtons()
|
||||
|
||||
});
|
||||
|
||||
@@ -669,12 +696,12 @@
|
||||
selectedTab = "Internet_id"
|
||||
|
||||
// the #target from the url
|
||||
target = window.location.hash.substr(1)
|
||||
target = getQueryString('mac')
|
||||
|
||||
// update cookie if target specified
|
||||
if(target != "")
|
||||
{
|
||||
setCache(key, target+'_id') // _id is added so it doesn't conflict with AdminLTE tab behavior
|
||||
setCache(key, target.replaceAll(":","_")+'_id') // _id is added so it doesn't conflict with AdminLTE tab behavior
|
||||
}
|
||||
|
||||
// get the tab id from the cookie (already overriden by the target)
|
||||
@@ -691,13 +718,29 @@
|
||||
setCache(key, $(e.target).attr('id'))
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
function initButtons(currentNodeMac)
|
||||
function initButtons()
|
||||
{
|
||||
|
||||
var currentNodeMac = $(".tab-content .active td[data-mynodemac]").attr('data-mynodemac');
|
||||
|
||||
// change highlighted node in the tree
|
||||
selNode = $("#networkTree .highlightedNode")[0]
|
||||
|
||||
// console.log(selNode)
|
||||
|
||||
if(selNode)
|
||||
{
|
||||
$(selNode).attr('class', $(selNode).attr('class').replace('highlightedNode'))
|
||||
}
|
||||
|
||||
newSelNode = $("#networkTree div[data-mytreemacmain='"+currentNodeMac+"']")[0]
|
||||
|
||||
$(newSelNode).attr('class', $(newSelNode).attr('class') + ' highlightedNode')
|
||||
|
||||
|
||||
// init the Assign buttons
|
||||
$('#unassignedDevices button[data-myleafmac]').each(function(){
|
||||
$(this).attr('onclick', 'updateLeaf("'+$(this).attr('data-myleafmac')+'","'+currentNodeMac+'")')
|
||||
@@ -712,6 +755,8 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
function updateLeaf(leafMac,nodeMac)
|
||||
{
|
||||
console.log(leafMac)
|
||||
console.log(nodeMac)
|
||||
saveData('updateNetworkLeaf', leafMac, nodeMac);
|
||||
setTimeout("location.reload();", 1000); // refresh page after 1s
|
||||
}
|
||||
@@ -720,11 +765,8 @@
|
||||
// init selected (first) tab
|
||||
initTab();
|
||||
|
||||
// create tree
|
||||
initTree(getHierarchy());
|
||||
|
||||
// attach on-click events
|
||||
attachTreeEvents();
|
||||
// init Assign/Unassign buttons
|
||||
initButtons()
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
@@ -8,11 +8,9 @@
|
||||
# Puche 2021 / 2022+ jokob jokob@duck.com GNU GPLv3
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
require '/home/pi/pialert/front/php/templates/timezone.php';
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// DB File Path
|
||||
$DBFILE = '/home/pi/pialert/db/pialert.db';
|
||||
$DBFILE = dirname(__FILE__).'/../../../db/pialert.db';
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Connect DB
|
||||
@@ -74,6 +72,3 @@ function OpenDB (...$DBPath) {
|
||||
// # Open DB once and keep open
|
||||
// # Opening / closing DB frequently actually casues more issues
|
||||
OpenDB (); // main
|
||||
|
||||
|
||||
?>
|
||||
193
front/php/server/dbHelper.php
Executable file
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
//------------------------------------------------------------------------------
|
||||
// Pi.Alert
|
||||
// Open Source Network Guard / WIFI & LAN intrusion detector
|
||||
//
|
||||
// parameters.php - Front module. Server side. Manage Parameters
|
||||
//------------------------------------------------------------------------------
|
||||
# Puche 2022+ jokob jokob@duck.com GNU GPLv3
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// External files
|
||||
require dirname(__FILE__).'/init.php';
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Action selector
|
||||
//------------------------------------------------------------------------------
|
||||
// Set maximum execution time to 15 seconds
|
||||
ini_set ('max_execution_time','15');
|
||||
|
||||
$skipCache = FALSE;
|
||||
$expireMinutes = 5;
|
||||
$defaultValue = '';
|
||||
$dbtable = '';
|
||||
$columns = '';
|
||||
$values = '';
|
||||
|
||||
|
||||
if (isset ($_REQUEST['skipcache'])) {
|
||||
$skipCache = TRUE;
|
||||
}
|
||||
|
||||
if (isset ($_REQUEST['defaultValue'])) {
|
||||
$defaultValue = $_REQUEST['defaultValue'];
|
||||
}
|
||||
|
||||
if (isset ($_REQUEST['expireMinutes'])) {
|
||||
$expireMinutes = $_REQUEST['expireMinutes'];
|
||||
}
|
||||
|
||||
if (isset ($_REQUEST['columnName'])) {
|
||||
$columnName = $_REQUEST['columnName'];
|
||||
}
|
||||
|
||||
if (isset ($_REQUEST['id'])) {
|
||||
$id = $_REQUEST['id'];
|
||||
}
|
||||
|
||||
if (isset ($_REQUEST['values'])) {
|
||||
$values = $_REQUEST['values'];
|
||||
}
|
||||
|
||||
if (isset ($_REQUEST['columns'])) {
|
||||
$columns = $_REQUEST['columns'];
|
||||
}
|
||||
|
||||
if (isset ($_REQUEST['dbtable'])) {
|
||||
$dbtable = $_REQUEST['dbtable'];
|
||||
}
|
||||
// TODO: Security, read, delete, edge cases
|
||||
// Action functions
|
||||
if (isset ($_REQUEST['action']) && !empty ($_REQUEST['action'])) {
|
||||
$action = $_REQUEST['action'];
|
||||
switch ($action) {
|
||||
case 'create': create($skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values ); break;
|
||||
// case 'read' : read($skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values); break;
|
||||
case 'update': update($columnName, $id, $skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values); break;
|
||||
case 'delete': delete($columnName, $id, $dbtable); break;
|
||||
default: logServerConsole ('Action: '. $action); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// update
|
||||
//------------------------------------------------------------------------------
|
||||
function update($columnName, $id, $skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values) {
|
||||
|
||||
global $db;
|
||||
|
||||
// handle one or multiple columns
|
||||
if(strpos($columns, ',') !== false)
|
||||
{
|
||||
$columnsArr = explode(",", $columns);
|
||||
}else
|
||||
{
|
||||
$columnsArr = array($columns);
|
||||
}
|
||||
|
||||
// handle one or multiple values
|
||||
if(strpos($values, ',') !== false)
|
||||
{
|
||||
$valuesArr = explode(",", $values);
|
||||
} else
|
||||
{
|
||||
$valuesArr = array($values);
|
||||
}
|
||||
|
||||
$columnValues = '';
|
||||
|
||||
$index = 0;
|
||||
foreach($columnsArr as $column)
|
||||
{
|
||||
$columnValues = $columnValues .' "' .$column.'" = "'.$valuesArr[$index] . '",' ;
|
||||
$index = $index + 1;
|
||||
}
|
||||
|
||||
$columnValues = substr($columnValues, 0, -1);
|
||||
|
||||
// Update value
|
||||
$sql = 'UPDATE '.$dbtable.' SET '. $columnValues .'
|
||||
WHERE "'. $columnName .'"="'. $id.'"';
|
||||
$result = $db->query($sql);
|
||||
|
||||
if (! $result == TRUE) {
|
||||
echo "Error updating parameter\n\n$sql \n\n". $db->lastErrorMsg();
|
||||
return;
|
||||
}
|
||||
|
||||
$changes = $db->changes();
|
||||
if ($changes == 0) {
|
||||
// Insert new value
|
||||
create($skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values);
|
||||
}
|
||||
|
||||
// update cache
|
||||
$uniqueHash = hash('ripemd160', $dbtable . $columns);
|
||||
setCache($uniqueHash, $values, $expireMinutes);
|
||||
|
||||
echo 'OK';
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// create
|
||||
//------------------------------------------------------------------------------
|
||||
function create($skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values)
|
||||
{
|
||||
global $db;
|
||||
|
||||
// Insert new value
|
||||
$sql = 'INSERT INTO '.$dbtable.' ('.$columns.')
|
||||
VALUES ("'. quotes($parameter) .'",
|
||||
"'. $values .'")';
|
||||
$result = $db->query($sql);
|
||||
|
||||
if (! $result == TRUE) {
|
||||
echo "Error creating entry\n\n$sql \n\n". $db->lastErrorMsg();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// delete
|
||||
//------------------------------------------------------------------------------
|
||||
function delete($columnName, $id, $dbtable)
|
||||
{
|
||||
global $db;
|
||||
|
||||
// handle one or multiple ids
|
||||
if(strpos($id, ',') !== false)
|
||||
{
|
||||
$idsArr = explode(",", $id);
|
||||
}else
|
||||
{
|
||||
$idsArr = array($id);
|
||||
}
|
||||
|
||||
$idsStr = "";
|
||||
|
||||
foreach ($idsArr as $item)
|
||||
{
|
||||
$idsStr = $idsStr . '"' .$item.'"';
|
||||
}
|
||||
|
||||
// Insert new value
|
||||
$sql = 'DELETE FROM '.$dbtable.' WHERE "'.$columnName.'" IN ('. $idsStr .')';
|
||||
$result = $db->query($sql);
|
||||
|
||||
if (! $result == TRUE) {
|
||||
echo "Error deleting entry\n\n$sql \n\n". $db->lastErrorMsg();
|
||||
return;
|
||||
} else
|
||||
{
|
||||
echo lang('Gen_DataUpdatedUITakesTime');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -9,15 +9,13 @@
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// External files
|
||||
require '/home/pi/pialert/front/php/templates/timezone.php';
|
||||
require '/home/pi/pialert/front/php/templates/language/lang.php';
|
||||
require '/home/pi/pialert/front/php/server/db.php';
|
||||
require '/home/pi/pialert/front/php/server/util.php';
|
||||
require dirname(__FILE__).'/init.php';
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Action selector
|
||||
//------------------------------------------------------------------------------
|
||||
// Set maximum execution time to 15 seconds
|
||||
|
||||
ini_set ('max_execution_time','30');
|
||||
|
||||
// Action functions
|
||||
@@ -59,6 +57,8 @@
|
||||
case 'updateNetworkLeaf': updateNetworkLeaf(); break;
|
||||
case 'overwriteIconType': overwriteIconType(); break;
|
||||
case 'getIcons': getIcons(); break;
|
||||
case 'getActions': getActions(); break;
|
||||
case 'wakeonlan': wakeonlan(); break;
|
||||
|
||||
default: logServerConsole ('Action: '. $action); break;
|
||||
}
|
||||
@@ -481,22 +481,29 @@ function ImportCSV() {
|
||||
|
||||
// sql
|
||||
$sql = 'DELETE FROM Devices';
|
||||
|
||||
// execute sql
|
||||
$result = $db->query($sql);
|
||||
|
||||
// Open the CSV file with read-only mode
|
||||
$csvFile = fopen($file, 'r');
|
||||
|
||||
// Skip the first line
|
||||
fgetcsv($csvFile);
|
||||
$data = file_get_contents($file);
|
||||
$data = explode("\n", $data);
|
||||
|
||||
$columns = getDevicesColumns();
|
||||
|
||||
// Parse data from CSV file line by line (max 10000 lines)
|
||||
while (($row = fgetcsv($csvFile, 10000, ",")) !== FALSE)
|
||||
{
|
||||
$sql = 'INSERT INTO Devices ('.implode(',', $columns).') VALUES ("' .implode('","', $row).'")';
|
||||
|
||||
// Parse data from CSV file line by line (max 10000 lines)
|
||||
foreach($data as $row)
|
||||
{
|
||||
// Check if not empty and skipping first line
|
||||
$rowArray = explode(',',$row);
|
||||
|
||||
if(count($rowArray) > 20)
|
||||
{
|
||||
$cleanMac = str_replace("\"","",$rowArray[0]);
|
||||
|
||||
if(filter_var($cleanMac , FILTER_VALIDATE_MAC) == True || $cleanMac == "Internet")
|
||||
{
|
||||
$sql = "INSERT INTO Devices (".implode(',', $columns).") VALUES (" . $row.")";
|
||||
$result = $db->query($sql);
|
||||
|
||||
// check result
|
||||
@@ -506,9 +513,9 @@ function ImportCSV() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close opened CSV file
|
||||
fclose($csvFile);
|
||||
}
|
||||
|
||||
if($error == "")
|
||||
{
|
||||
@@ -518,7 +525,7 @@ function ImportCSV() {
|
||||
}
|
||||
else{
|
||||
// an error occurred while writing to the DB, display the last error message
|
||||
echo lang('BackDevices_DBTools_ImportCSVError')."\n\n$sql \n\n".$error;
|
||||
echo lang('BackDevices_DBTools_ImportCSVError')."\n\n$sql \n\n".$result;
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -563,12 +570,85 @@ function getDevicesTotals() {
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query the List of devices in a determined Status
|
||||
//------------------------------------------------------------------------------
|
||||
// function getDevicesListForNetworkTree() {
|
||||
// global $db;
|
||||
|
||||
// $sql = 'SELECT *, CASE
|
||||
// WHEN t1.dev_AlertDeviceDown=1 AND t1.dev_PresentLastScan=0 THEN "Down"
|
||||
// WHEN t1.dev_NewDevice=1 THEN "New"
|
||||
// WHEN t1.dev_PresentLastScan=1 THEN "On-line"
|
||||
// ELSE "Off-line" END AS dev_Status
|
||||
// FROM (Devices ) t1
|
||||
// LEFT JOIN
|
||||
// (
|
||||
// SELECT *,
|
||||
// count() as connected_devices
|
||||
// FROM Devices b
|
||||
// WHERE b.dev_Network_Node_MAC_ADDR NOT NULL group by b.dev_Network_Node_MAC_ADDR
|
||||
// ) t2
|
||||
// ON (t1.dev_MAC = t2.dev_MAC); ';
|
||||
|
||||
// $result = $db->query($sql);
|
||||
|
||||
// // arrays of rows
|
||||
// $tableData = array();
|
||||
// while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
|
||||
// $defaultOrder = array ($row['dev_Name'],
|
||||
// $row['dev_Owner'],
|
||||
// handleNull($row['dev_DeviceType']),
|
||||
// handleNull($row['dev_Icon'], "laptop"),
|
||||
// $row['dev_Favorite'],
|
||||
// $row['dev_Group'],
|
||||
// formatDate ($row['dev_FirstConnection']),
|
||||
// formatDate ($row['dev_LastConnection']),
|
||||
// $row['dev_LastIP'],
|
||||
// ( in_array($row['dev_MAC'][1], array("2","6","A","E","a","e")) ? 1 : 0),
|
||||
// $row['dev_Status'],
|
||||
// $row['dev_MAC'], // MAC (hidden)
|
||||
// formatIPlong ($row['dev_LastIP']), // IP orderable
|
||||
// $row['rowid'], // Rowid (hidden)
|
||||
// handleNull($row['dev_Network_Node_MAC_ADDR']), //
|
||||
// handleNull($row['connected_devices']) //
|
||||
// );
|
||||
|
||||
// $newOrder = array();
|
||||
|
||||
// // reorder columns based on user settings
|
||||
// for($index = 0; $index < count($columnOrderMapping); $index++)
|
||||
// {
|
||||
// array_push($newOrder, $defaultOrder[$columnOrderMapping[$index][2]]);
|
||||
// }
|
||||
|
||||
// $tableData['data'][] = $newOrder;
|
||||
// }
|
||||
|
||||
// // Control no rows
|
||||
// if (empty($tableData['data'])) {
|
||||
// $tableData['data'] = '';
|
||||
// }
|
||||
|
||||
// // Return json
|
||||
// echo (json_encode ($tableData));
|
||||
|
||||
// }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query the List of devices in a determined Status
|
||||
//------------------------------------------------------------------------------
|
||||
function getDevicesList() {
|
||||
global $db;
|
||||
|
||||
$forceDefaultOrder = FALSE;
|
||||
|
||||
if (isset ($_REQUEST['forceDefaultOrder']) )
|
||||
{
|
||||
$forceDefaultOrder = TRUE;
|
||||
}
|
||||
|
||||
// This object is used to map from the old order ( second parameter, first number) to the 3rd parameter (Second number (here initialized to -1))
|
||||
$columnOrderMapping = array(
|
||||
array("dev_Name", 0, 0),
|
||||
@@ -585,9 +665,14 @@ function getDevicesList() {
|
||||
array("dev_MAC_full", 11, 11),
|
||||
array("dev_LastIP_orderable", 12, 12),
|
||||
array("rowid", 13, 13),
|
||||
array("dev_Network_Node_MAC_ADDR", 14, 14)
|
||||
array("dev_Network_Node_MAC_ADDR", 14, 14),
|
||||
array("connected_devices", 15, 15),
|
||||
array("dev_Location", 16, 16),
|
||||
array("dev_Vendor", 17, 17)
|
||||
);
|
||||
|
||||
if($forceDefaultOrder == FALSE)
|
||||
{
|
||||
// get device columns order
|
||||
$sql = 'SELECT par_Value FROM Parameters where par_ID = "Front_Devices_Columns_Order"';
|
||||
$result = $db->query($sql);
|
||||
@@ -603,17 +688,27 @@ function getDevicesList() {
|
||||
$columnOrderMapping[$i][2] = $orderedColumns[$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SQL
|
||||
$condition = getDeviceCondition ($_REQUEST['status']);
|
||||
|
||||
$sql = 'SELECT rowid, *, CASE
|
||||
WHEN dev_AlertDeviceDown=1 AND dev_PresentLastScan=0 THEN "Down"
|
||||
WHEN dev_NewDevice=1 THEN "New"
|
||||
WHEN dev_PresentLastScan=1 THEN "On-line"
|
||||
ELSE "Off-line"
|
||||
END AS dev_Status
|
||||
FROM Devices '. $condition;
|
||||
$sql = 'SELECT * FROM (
|
||||
SELECT rowid, *, CASE
|
||||
WHEN t1.dev_AlertDeviceDown=1 AND t1.dev_PresentLastScan=0 THEN "Down"
|
||||
WHEN t1.dev_NewDevice=1 THEN "New"
|
||||
WHEN t1.dev_PresentLastScan=1 THEN "On-line"
|
||||
ELSE "Off-line" END AS dev_Status
|
||||
FROM Devices t1 '.$condition.') t3
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT dev_Network_Node_MAC_ADDR as dev_Network_Node_MAC_ADDR_t2, dev_MAC as dev_MAC_t2,
|
||||
count() as connected_devices
|
||||
FROM Devices b
|
||||
WHERE b.dev_Network_Node_MAC_ADDR NOT NULL group by b.dev_Network_Node_MAC_ADDR
|
||||
) t2
|
||||
ON (t3.dev_MAC = t2.dev_Network_Node_MAC_ADDR_t2);';
|
||||
|
||||
$result = $db->query($sql);
|
||||
|
||||
// arrays of rows
|
||||
@@ -622,8 +717,8 @@ function getDevicesList() {
|
||||
|
||||
$defaultOrder = array ($row['dev_Name'],
|
||||
$row['dev_Owner'],
|
||||
$row['dev_DeviceType'],
|
||||
$row['dev_Icon'],
|
||||
handleNull($row['dev_DeviceType']),
|
||||
handleNull($row['dev_Icon'], "laptop"),
|
||||
$row['dev_Favorite'],
|
||||
$row['dev_Group'],
|
||||
formatDate ($row['dev_FirstConnection']),
|
||||
@@ -634,12 +729,15 @@ function getDevicesList() {
|
||||
$row['dev_MAC'], // MAC (hidden)
|
||||
formatIPlong ($row['dev_LastIP']), // IP orderable
|
||||
$row['rowid'], // Rowid (hidden)
|
||||
$row['dev_Network_Node_MAC_ADDR'] //
|
||||
handleNull($row['dev_Network_Node_MAC_ADDR']),
|
||||
handleNull($row['connected_devices']),
|
||||
handleNull($row['dev_Location']),
|
||||
handleNull($row['dev_Vendor'])
|
||||
);
|
||||
|
||||
$newOrder = array();
|
||||
|
||||
|
||||
// reorder columns based on user settings
|
||||
for($index = 0; $index < count($columnOrderMapping); $index++)
|
||||
{
|
||||
array_push($newOrder, $defaultOrder[$columnOrderMapping[$index][2]]);
|
||||
@@ -758,9 +856,10 @@ function getIcons() {
|
||||
// arrays of rows
|
||||
$tableData = array();
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
$icon = handleNull($row['dev_Icon'], "laptop");
|
||||
// Push row data
|
||||
$tableData[] = array('id' => $row['dev_Icon'],
|
||||
'name' => '<i class="fa fa-'.$row['dev_Icon'].'"></i> - '.$row['dev_Icon'] );
|
||||
$tableData[] = array('id' => $icon,
|
||||
'name' => '<i class="fa fa-'.$icon.'"></i> - '.$icon );
|
||||
}
|
||||
|
||||
// Control no rows
|
||||
@@ -772,6 +871,18 @@ function getIcons() {
|
||||
echo (json_encode ($tableData));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
function getActions() {
|
||||
|
||||
$tableData = array(
|
||||
array('id' => 'wake-on-lan',
|
||||
'name' => lang('DevDetail_WOL_Title'))
|
||||
);
|
||||
|
||||
// Return json
|
||||
echo (json_encode ($tableData));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query the List of types
|
||||
@@ -1095,12 +1206,33 @@ function overwriteIconType()
|
||||
if ($result == TRUE) {
|
||||
echo 'OK';
|
||||
} else {
|
||||
echo 'KO';
|
||||
echo lang('BackDevices_Device_UpdDevError');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Wake-on-LAN
|
||||
// Inspired by @leiweibau: https://github.com/leiweibau/Pi.Alert/commit/30427c7fea180670c71a2b790699e5d9e9e88ffd
|
||||
//------------------------------------------------------------------------------
|
||||
function wakeonlan() {
|
||||
|
||||
$WOL_HOST_IP = $_REQUEST['ip'];
|
||||
$WOL_HOST_MAC = $_REQUEST['mac'];
|
||||
|
||||
if (!filter_var($WOL_HOST_IP, FILTER_VALIDATE_IP)) {
|
||||
echo "Invalid IP! ". lang('BackDevDetail_Tools_WOL_error'); exit;
|
||||
}
|
||||
elseif (!filter_var($WOL_HOST_MAC, FILTER_VALIDATE_MAC)) {
|
||||
echo "Invalid MAC! ". lang('BackDevDetail_Tools_WOL_error'); exit;
|
||||
}
|
||||
|
||||
exec('wakeonlan '.$WOL_HOST_MAC , $output);
|
||||
|
||||
echo lang('BackDevDetail_Tools_WOL_okay');
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Status Where conditions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
// External files
|
||||
require 'db.php';
|
||||
require 'util.php';
|
||||
require dirname(__FILE__).'/init.php';
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
6
front/php/server/init.php
Executable file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
require dirname(__FILE__).'/../templates/timezone.php';
|
||||
require dirname(__FILE__).'/db.php';
|
||||
require dirname(__FILE__).'/util.php';
|
||||
require dirname(__FILE__).'/../templates/language/lang.php';
|
||||
?>
|
||||
@@ -33,4 +33,3 @@ if(filter_var($PIA_HOST_IP, FILTER_VALIDATE_IP)) // Vulnerability fix v22.12.20
|
||||
{
|
||||
echo '<h4>Internal error.</h4>';
|
||||
}
|
||||
?>
|
||||
@@ -11,8 +11,7 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// External files
|
||||
require 'db.php';
|
||||
require 'util.php';
|
||||
require dirname(__FILE__).'/init.php';
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -80,6 +79,9 @@ function getParameter($skipCache, $defaultValue, $expireMinutes) {
|
||||
$value = $row[0];
|
||||
} else{
|
||||
$value = $defaultValue;
|
||||
|
||||
// Nothing found in the DB, Insert new value
|
||||
insertNew($parameter, $value);
|
||||
}
|
||||
|
||||
// update cache
|
||||
@@ -112,6 +114,20 @@ function setParameter($expireMinutes) {
|
||||
|
||||
$changes = $db->changes();
|
||||
if ($changes == 0) {
|
||||
// Insert new value
|
||||
insertNew($parameter, $value);
|
||||
}
|
||||
|
||||
// update cache
|
||||
setCache($parameter, $value, $expireMinutes);
|
||||
|
||||
echo 'OK';
|
||||
}
|
||||
|
||||
function insertNew($parameter, $value)
|
||||
{
|
||||
global $db;
|
||||
|
||||
// Insert new value
|
||||
$sql = 'INSERT INTO Parameters (par_ID, par_Value)
|
||||
VALUES ("'. quotes($parameter) .'",
|
||||
@@ -124,10 +140,5 @@ function setParameter($expireMinutes) {
|
||||
}
|
||||
}
|
||||
|
||||
// update cache
|
||||
setCache($parameter, $value, $expireMinutes);
|
||||
|
||||
echo 'OK';
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
# Puche 2021 / 2022+ jokob jokob@duck.com GNU GPLv3
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
require '/home/pi/pialert/front/php/templates/timezone.php';
|
||||
require '/home/pi/pialert/front/php/templates/skinUI.php';
|
||||
require dirname(__FILE__).'/../templates/timezone.php';
|
||||
require dirname(__FILE__).'/../templates/skinUI.php';
|
||||
|
||||
$FUNCTION = [];
|
||||
$SETTINGS = [];
|
||||
@@ -35,7 +35,6 @@ elseif ($FUNCTION == 'cleanLog')
|
||||
cleanLog($SETTINGS);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Formatting data functions
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -203,7 +202,7 @@ function cleanLog($logFile)
|
||||
|
||||
$path = "";
|
||||
|
||||
$allowedFiles = ['pialert.log', 'pialert_front.log', 'IP_changes.log', 'stdout.log', 'stderr.log', "pialert_pholus.log", "pialert_pholus_lastrun.log"];
|
||||
$allowedFiles = ['pialert.log', 'pialert_front.log', 'IP_changes.log', 'stdout.log', 'stderr.log', "pialert_pholus_lastrun.log"];
|
||||
|
||||
if(in_array($logFile, $allowedFiles))
|
||||
{
|
||||
@@ -275,28 +274,35 @@ function saveSettings()
|
||||
{
|
||||
if($group == $setting[0])
|
||||
{
|
||||
if($setting[3] == 'text' or $setting[3] == 'password' or $setting[3] == 'readonly' or $setting[3] == 'selecttext')
|
||||
if($setting[2] == 'text' or $setting[2] == 'password' or $setting[2] == 'readonly' or $setting[2] == 'selecttext')
|
||||
{
|
||||
$txt = $txt.$setting[1]."='".$setting[2]."'\n" ;
|
||||
} elseif($setting[3] == 'integer' or $setting[3] == 'selectinteger')
|
||||
$val = encode_single_quotes($setting[3]);
|
||||
$txt = $txt.$setting[1]."='".$val."'\n" ;
|
||||
} elseif($setting[2] == 'integer' or $setting[2] == 'selectinteger')
|
||||
{
|
||||
$txt = $txt.$setting[1]."=".$setting[2]."\n" ;
|
||||
} elseif($setting[3] == 'boolean')
|
||||
$txt = $txt.$setting[1]."=".$setting[3]."\n" ;
|
||||
} elseif($setting[2] == 'boolean')
|
||||
{
|
||||
$val = "False";
|
||||
if($setting[2] == 'true')
|
||||
if($setting[3] == 'true')
|
||||
{
|
||||
$val = "True";
|
||||
}
|
||||
$txt = $txt.$setting[1]."=".$val."\n" ;
|
||||
}elseif($setting[3] == 'multiselect' or $setting[3] == 'subnets')
|
||||
}elseif($setting[2] == 'multiselect' or $setting[2] == 'subnets' or $setting[2] == 'list')
|
||||
{
|
||||
$temp = '[';
|
||||
foreach($setting[2] as $val)
|
||||
|
||||
if (count($setting) > 3 && is_array( $setting[3]) == True){
|
||||
foreach($setting[3] as $val)
|
||||
{
|
||||
$temp = $temp."'". $val."',";
|
||||
$temp = $temp."'". encode_single_quotes($val)."',";
|
||||
}
|
||||
$temp = substr_replace($temp, "", -1).']'; // close brackets and remove last comma ','
|
||||
|
||||
$temp = substr_replace($temp, "", -1); // remove last comma ','
|
||||
}
|
||||
|
||||
$temp = $temp.']'; // close brackets
|
||||
$txt = $txt.$setting[1]."=".$temp."\n" ;
|
||||
}
|
||||
}
|
||||
@@ -322,8 +328,6 @@ function saveSettings()
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
function getString ($codeName, $default) {
|
||||
|
||||
$result = lang($codeName);
|
||||
@@ -338,6 +342,16 @@ function getString ($codeName, $default) {
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
function encode_single_quotes ($val) {
|
||||
|
||||
$result = str_replace ('\'','{s-quote}',$val);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
|
||||
function getDateFromPeriod () {
|
||||
$period = $_REQUEST['period'];
|
||||
return '"'. date ('Y-m-d', strtotime ('+1 day -'. $period) ) .'"';
|
||||
@@ -354,6 +368,18 @@ function logServerConsole ($text) {
|
||||
$y = $x['__________'. $text .'__________'];
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
function handleNull ($text, $default = "") {
|
||||
if($text == NULL || $text == 'NULL')
|
||||
{
|
||||
return $default;
|
||||
} else
|
||||
{
|
||||
return $text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
|
||||
function getNetworkTypes(){
|
||||
@@ -391,7 +417,8 @@ function getDevicesColumns(){
|
||||
"dev_Location",
|
||||
"dev_Archived",
|
||||
"dev_Network_Node_port",
|
||||
"dev_Network_Node_MAC_ADDR"];
|
||||
"dev_Network_Node_MAC_ADDR",
|
||||
"dev_Icon"];
|
||||
|
||||
return $columns;
|
||||
}
|
||||
@@ -415,5 +442,3 @@ function setCache($key, $value, $expireMinutes = 5) {
|
||||
|
||||
|
||||
?>
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require 'php/server/db.php';
|
||||
|
||||
global $db;
|
||||
|
||||
$Pia_Graph_Device_Time = array();
|
||||
@@ -27,6 +25,3 @@ function pia_graph_devices_data($Pia_Graph_Array) {
|
||||
echo ",";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -8,10 +8,8 @@
|
||||
#--------------------------------------------------------------------------- -->
|
||||
|
||||
<?php
|
||||
|
||||
require '/home/pi/pialert/front/php/templates/timezone.php';
|
||||
require '/home/pi/pialert/front/php/templates/language/lang.php';
|
||||
require '/home/pi/pialert/front/php/templates/security.php';
|
||||
require dirname(__FILE__).'/../server/init.php';
|
||||
require dirname(__FILE__).'/security.php';
|
||||
|
||||
?>
|
||||
|
||||
@@ -114,7 +112,7 @@ if ($ENABLED_DARKMODE === True) {
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<!-- Layout Boxed Yellow -->
|
||||
<body class="hold-transition <?php echo $pia_skin_selected;?> layout-boxed sidebar-mini" <?php echo $BACKGROUND_IMAGE_PATCH;?> onLoad="show_pia_servertime();" >
|
||||
<body class="hold-transition <?php echo $pia_skin_selected;?> sidebar-mini" <?php echo $BACKGROUND_IMAGE_PATCH;?> onLoad="show_pia_servertime();" >
|
||||
<!-- Site wrapper -->
|
||||
<div class="wrapper">
|
||||
|
||||
@@ -169,8 +167,8 @@ if ($ENABLED_DARKMODE === True) {
|
||||
<li class="user-header" style=" height: 100px;">
|
||||
<img src="img/pialertLogoWhite.png" class="img-circle" alt="Pi.Alert Logo" style="border-color:transparent; height: 50px; width: 50px; margin-top:15px;">
|
||||
<p style="float: right; width: 200px">
|
||||
<?php echo lang('About_Title');?>
|
||||
<small><?php echo lang('About_Design');?> Raspberry Pi</small>
|
||||
<?= lang('About_Title');?>
|
||||
<small><?= lang('About_Design');?> Raspberry Pi</small>
|
||||
</p>
|
||||
</li>
|
||||
|
||||
@@ -178,7 +176,7 @@ if ($ENABLED_DARKMODE === True) {
|
||||
|
||||
<li class="user-footer">
|
||||
<div class="pull-right">
|
||||
<a href="index.php?action=logout" class="btn btn-danger"><?php echo lang('About_Exit');?></a>
|
||||
<a href="index.php?action=logout" class="btn btn-danger"><?= lang('About_Exit');?></a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -209,31 +207,35 @@ if ($ENABLED_DARKMODE === True) {
|
||||
<ul class="sidebar-menu" data-widget="tree">
|
||||
|
||||
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('devices.php', 'deviceDetails.php') ) ){ echo 'active'; } ?>">
|
||||
<a href="devices.php"><span><?php echo lang('Navigation_Devices');?></span></a>
|
||||
<a href="devices.php"><span><i class="fa fa-laptop"></i> <?= lang('Navigation_Devices');?></span></a>
|
||||
</li>
|
||||
|
||||
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('presence.php') ) ){ echo 'active'; } ?>">
|
||||
<a href="presence.php"><?php echo lang('Navigation_Presence');?></span></a>
|
||||
<a href="presence.php"><i class="fa fa-calendar"></i> <?= lang('Navigation_Presence');?></span></a>
|
||||
</li>
|
||||
|
||||
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('events.php') ) ){ echo 'active'; } ?>">
|
||||
<a href="events.php"><i class="fa fa-bolt"></i> <span><?php echo lang('Navigation_Events');?></span></a>
|
||||
<a href="events.php"><i class="fa fa-bolt"></i> <span><?= lang('Navigation_Events');?></span></a>
|
||||
</li>
|
||||
|
||||
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('network.php') ) ){ echo 'active'; } ?>">
|
||||
<a href="network.php"><span><?php echo lang('Navigation_Network');?></span></a>
|
||||
<a href="network.php"><span><i class="fa fa-fw fa-network-wired"></i> <?= lang('Navigation_Network');?></span></a>
|
||||
</li>
|
||||
|
||||
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('plugins.php') ) ){ echo 'active'; } ?>">
|
||||
<a href="plugins.php"><span><i class="fa fa-fw fa-plug"></i> <?= lang('Navigation_Plugins');?></span></a>
|
||||
</li>
|
||||
|
||||
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('maintenance.php') ) ){ echo 'active'; } ?>">
|
||||
<div class="new-version myhidden" id="version" data-build-time="<?php echo file_get_contents( "buildtimestamp.txt");?>">🆕</div>
|
||||
<a href="maintenance.php"><i class="fa fa-wrench "></i> <span><?php echo lang('Navigation_Maintenance');?></span></a>
|
||||
<a href="maintenance.php"><i class="fa fa-wrench "></i> <span><?= lang('Navigation_Maintenance');?></span></a>
|
||||
</li>
|
||||
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('settings.php') ) ){ echo 'active'; } ?>">
|
||||
<a href="settings.php"><i class="fa fa-cog"></i> <span><?php echo lang('Navigation_Settings');?></span></a>
|
||||
<a href="settings.php"><i class="fa fa-cog"></i> <span><?= lang('Navigation_Settings');?></span></a>
|
||||
</li>
|
||||
|
||||
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('help_faq.php') ) ){ echo 'active'; } ?>">
|
||||
<a href="help_faq.php"><i class="fa fa-question"></i> <span><?php echo lang('Navigation_HelpFAQ');?></span></a>
|
||||
<a href="help_faq.php"><i class="fa fa-question"></i> <span><?= lang('Navigation_HelpFAQ');?></span></a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -13,10 +13,13 @@ $lang['en_us'] = array(
|
||||
// General
|
||||
//////////////////////////////////////////////////////////////////
|
||||
'Gen_Delete' => 'Delete',
|
||||
'Gen_DeleteAll' => 'Delete all',
|
||||
'Gen_Cancel' => 'Cancel',
|
||||
'Gen_Okay' => 'Ok',
|
||||
'Gen_Save' => 'Save',
|
||||
'Gen_Saved' => 'Saved',
|
||||
'Gen_Run' => 'Run',
|
||||
'Gen_Action' => 'Action',
|
||||
'Gen_Purge' => 'Purge',
|
||||
'Gen_Backup' => 'Run Backup',
|
||||
'Gen_Restore' => 'Run Restore',
|
||||
@@ -24,6 +27,9 @@ $lang['en_us'] = array(
|
||||
'Gen_AreYouSure' => 'Are you sure?',
|
||||
'Gen_Upd' => 'Updated successfully',
|
||||
'Gen_Upd_Fail' => 'Update failed',
|
||||
'Gen_Help' => 'Need help?',
|
||||
'Gen_DataUpdatedUITakesTime' => 'OK - It may take a while for the UI to update if a scan is runnig.',
|
||||
'Gen_LockedDB' => 'ERROR - DB might be locked - Check F12 Dev tools -> Console or try later.',
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Login Page - Update by @TeroRERO 03ago2022
|
||||
@@ -47,12 +53,13 @@ $lang['en_us'] = array(
|
||||
// Device Page
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
'Navigation_Devices' => '<i class="fa fa-laptop"></i> Devices',
|
||||
'Navigation_Presence' => '<i class="fa fa-calendar"></i> Presence',
|
||||
'Navigation_Devices' => 'Devices',
|
||||
'Navigation_Presence' => 'Presence',
|
||||
'Navigation_Events' => 'Events',
|
||||
'Navigation_Network' => 'Network',
|
||||
'Navigation_Plugins' => 'Plugins',
|
||||
'Navigation_Maintenance' => 'Maintenance',
|
||||
'Navigation_Settings' => 'Settings',
|
||||
'Navigation_Network' => '<i class="fa fa-fw fa-network-wired"></i> Network',
|
||||
'Navigation_HelpFAQ' => 'Help / FAQ',
|
||||
'Device_Title' => 'Devices',
|
||||
'Device_Shortcut_AllDevices' => 'All Devices',
|
||||
@@ -70,6 +77,9 @@ $lang['en_us'] = array(
|
||||
'Device_TableHead_RowID' => 'Row ID',
|
||||
'Device_TableHead_Rowid' => 'Row ID',
|
||||
'Device_TableHead_Parent_MAC' => 'Parent node MAC',
|
||||
'Device_TableHead_Connected_Devices' => 'Connected Devices',
|
||||
'Device_TableHead_Location' => 'Location',
|
||||
'Device_TableHead_Vendor' => 'Vendor',
|
||||
'Device_TableHead_Favorite' => 'Favorite',
|
||||
'Device_TableHead_Group' => 'Group',
|
||||
'Device_TableHead_FirstSession' => 'First Session',
|
||||
@@ -172,7 +182,7 @@ $lang['en_us'] = array(
|
||||
'DevDetail_MainInfo_Owner' => 'Owner',
|
||||
'DevDetail_MainInfo_Type' => 'Type',
|
||||
'DevDetail_Icon' => 'Icon',
|
||||
'DevDetail_Icon_Descr' => 'Enter a font awesome icon name without the fa- prefix.',
|
||||
'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_MainInfo_Vendor' => 'Vendor',
|
||||
'DevDetail_MainInfo_Favorite' => 'Favorite',
|
||||
'DevDetail_MainInfo_Group' => 'Group',
|
||||
@@ -192,7 +202,7 @@ $lang['en_us'] = array(
|
||||
'DevDetail_EveandAl_ScanCycle' => 'Scan device',
|
||||
'DevDetail_EveandAl_AlertAllEvents' => 'Alert All Events',
|
||||
'DevDetail_EveandAl_AlertDown' => 'Alert Down',
|
||||
'DevDetail_EveandAl_Skip' => 'Skip repeated notifications during',
|
||||
'DevDetail_EveandAl_Skip' => 'Skip repeated notifications for',
|
||||
'DevDetail_EveandAl_NewDevice' => 'New Device',
|
||||
'DevDetail_EveandAl_Archived' => 'Archived',
|
||||
'DevDetail_EveandAl_RandomMAC' => 'Random MAC',
|
||||
@@ -222,6 +232,17 @@ $lang['en_us'] = array(
|
||||
'DevDetail_Nmap_buttonSkipDiscovery' => 'Skip host discovery',
|
||||
'DevDetail_Nmap_buttonSkipDiscovery_text' => 'Skip host discovery (-Pn option): Default scan without host discovery',
|
||||
'DevDetail_Nmap_resultsLink' => 'You can leave this page after starting a scan. Results will be also available in the <code>pialert_front.log</code> file.',
|
||||
'BackDevDetail_Actions_Title_Run' => 'Run action',
|
||||
'BackDevDetail_Actions_Not_Registered' => 'Action not registered: ',
|
||||
'BackDevDetail_Actions_Ask_Run' => 'Do you want to execute the action?',
|
||||
'BackDevDetail_Tools_WOL_okay' => 'The command was executed.',
|
||||
'BackDevDetail_Tools_WOL_error' => 'The command was NOT executed.',
|
||||
'DevDetail_Tools_WOL_noti' => 'Wake-on-LAN',
|
||||
'DevDetail_Tools_WOL_noti_text' => 'The Wake-on-LAN command is sent to the broadcast address. If the target is not in the subnet/vlan of Pi.Alert, the target device will not respond.',
|
||||
'DevDetail_Tools_WOL' => 'Send Wol command to ',
|
||||
'DevDetail_WOL_Title' => '<i class="fa fa-power-off"></i> Wake-on-LAN',
|
||||
'DevDetail_Run_Actions_Title' => '<i class="fa fa-play"></i> Run action on device',
|
||||
'DevDetail_Run_Actions_Tooltip' => 'Run an action on the current device from the dropdown list.',
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Maintenance Page
|
||||
@@ -344,6 +365,7 @@ $lang['en_us'] = array(
|
||||
'BackDevices_DBTools_ImportCSV' => 'The devices from the CSV file were imported successfully.',
|
||||
'BackDevices_DBTools_ImportCSVError' => 'The CSV file couldn\'t be imported. Make sure the format is correct.',
|
||||
'BackDevices_DBTools_ImportCSVMissing' => 'The CSV file couldn\'t be found under <b>/config/devices.csv.</b>',
|
||||
'BackDevices_Device_UpdDevError' => 'Error updating devices, try later. The database is probable locked due to an ongoing task.',
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
@@ -429,7 +451,7 @@ $lang['en_us'] = array(
|
||||
If yes, delete them there as well. Now you can start Pi.Alert again. Now the device(s) should not show up anymore.',
|
||||
'HelpFAQ_Cat_Detail_300_head' => 'What means ',
|
||||
'HelpFAQ_Cat_Detail_300_text_a' => 'means a network device (a device of the type AP, Gateway, Firewall, Powerline, Switch, WLAN, PLC, Router,USB LAN Adapter, USB WIFI Adapter, or Internet).',
|
||||
'HelpFAQ_Cat_Detail_300_text_b' => 'designates the port number where the currently edited device is connected to this network device.',
|
||||
'HelpFAQ_Cat_Detail_300_text_b' => 'designates the port number where the currently edited device is connected to this network device. Read <a target="_blank" href="https://github.com/jokob-sk/Pi.Alert/blob/main/docs/NETWORK_TREE.md">this guide</a> for more info.',
|
||||
'HelpFAQ_Cat_Detail_301_head_a' => 'When is scanning now? At ',
|
||||
'HelpFAQ_Cat_Detail_301_head_b' => ' says 1min but the graph shows 5min intervals.',
|
||||
'HelpFAQ_Cat_Detail_301_text' => 'The time interval between the scans is defined by the "Cronjob", which is set to 5min by default. The designation "1min" refers to the expected duration of the scan.
|
||||
@@ -451,7 +473,7 @@ $lang['en_us'] = array(
|
||||
and then simply switch the device off again. Now Pi.Alert should properly note the state of the device in the database with the next scan.',
|
||||
'HelpFAQ_Cat_Network_600_head' => 'What is this page for?',
|
||||
'HelpFAQ_Cat_Network_600_text' => 'This page should offer you the possibility to map the assignment of your network devices. For this purpose, you can create one or more switches, WLANs, routers, etc., provide them with a port number if necessary and assign already detected
|
||||
devices to them. This assignment is done in the detailed view of the device to be assigned. So it is possible for you to quickly determine to which port a host is connected and if it is online.',
|
||||
devices to them. This assignment is done in the detailed view of the device to be assigned. So it is possible for you to quickly determine to which port a host is connected and if it is online. Read <a target="_blank" href="https://github.com/jokob-sk/Pi.Alert/blob/main/docs/NETWORK_TREE.md">this guide</a> for more info.',
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Front end events
|
||||
@@ -459,11 +481,21 @@ $lang['en_us'] = array(
|
||||
|
||||
'test_event_tooltip' => 'Save your changes at first before you test your settings.',
|
||||
'test_event_icon' => 'fa-vial-circle-check',
|
||||
'run_event_tooltip' => 'Enable the setting and save your changes at first before you run it.',
|
||||
'run_event_icon' => 'fa-play',
|
||||
'general_event_title' => 'Executing an ad-hoc event',
|
||||
'general_event_description' => 'The event you\'ve triggered might take a while until background processes finish. The execution ended once you see <code>finished</code> below. Check the <a onclick=\'setCache(\"activeMaintenanceTab\", \"tab_Logging_id\")\' href=\"/maintenance.php#tab_Logging\">error log</a> if you didn\'t get the expected result. <br/> <br/> Status: ',
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Plugins
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
'Plugins_Unprocessed_Events' => 'Unprocessed Events',
|
||||
'Plugins_Objects' => 'Plugin Objects',
|
||||
'Plugins_History' => 'Events History',
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Settings
|
||||
//////////////////////////////////////////////////////////////////
|
||||
@@ -477,25 +509,20 @@ $lang['en_us'] = array(
|
||||
|
||||
|
||||
//General
|
||||
'General_settings_group' => '<i class="fa fa-gears"></i> General',
|
||||
'General_display_name' => 'General',
|
||||
'General_icon' => '<i class="fa fa-gears"></i>',
|
||||
'ENABLE_ARPSCAN_name' => 'Enable ARP scan',
|
||||
'ENABLE_ARPSCAN_description' => 'Arp-scan is a command-line tool that uses the ARP protocol to discover and fingerprint IP hosts on the local network. An alternative to ARP scan is to enable the <a onclick="toggleAllSettings()" href="#PIHOLE_ACTIVE"><code>PIHOLE_ACTIVE</code>PiHole integration settings</a>.',
|
||||
'SCAN_SUBNETS_name' => 'Subnets to scan',
|
||||
'SCAN_SUBNETS_description' => '
|
||||
The arp-scan time itself depends on the number of IP addresses to check.
|
||||
The number of IPs to check depends on the <a target="_blank" href="https://www.calculator.net/ip-subnet-calculator.html">network mask</a> you set here.
|
||||
For example, a <code>/24</code> mask results in 256 IPs to check, where as a <code>/16</code>
|
||||
mask checks around 65,536. Every IP takes a couple seconds. This means that with an incorrect configuration
|
||||
the arp-scan will take hours to complete instead of seconds.
|
||||
<ol>
|
||||
<li>Specify the network mask. For example, the filter <code>192.168.1.0/24</code> covers IP ranges 192.168.1.0 to 192.168.1.255.</li>
|
||||
<li>Run <code>iwconfig</code> in your container to find your interface name(s) (e.g.: <code>eth0</code>, <code>eth1</code>)</li>
|
||||
</ol>
|
||||
The arp-scan time itself depends on the number of IP addresses to check so set this up carefully with the appropriate network mask and interface. Check the <a href="https://github.com/jokob-sk/Pi.Alert/blob/main/docs/SUBNETS.md" target="_blank">subnets documentation</a> for details.
|
||||
',
|
||||
'PRINT_LOG_name' => 'Print additional logging',
|
||||
'PRINT_LOG_description' => 'This setting will enable more verbose logging. Useful for debugging events writing into the database.',
|
||||
'LOG_LEVEL_name' => 'Print additional logging',
|
||||
'LOG_LEVEL_description' => 'This setting will enable more verbose logging. Useful for debugging events writing into the database.',
|
||||
'TIMEZONE_name' => 'Time zone',
|
||||
'TIMEZONE_description' => 'Time zone to display stats correctly. Find your time zone <a target="_blank" href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones" rel="nofollow">here</a>.',
|
||||
'ENABLE_PLUGINS_name' => 'Enable Plugins',
|
||||
'ENABLE_PLUGINS_description' => 'Enables the <a target="_blank" href="https://github.com/jokob-sk/Pi.Alert/tree/main/front/plugins">plugins</a> functionality. Loading plugins requires more hardware resources so you might want to disable them on low-powered system.',
|
||||
'PIALERT_WEB_PROTECTION_name' => 'Enable login',
|
||||
'PIALERT_WEB_PROTECTION_description' => 'When enabled a login dialog is displayed. Read below carefully if you get locked out of your instance.',
|
||||
'PIALERT_WEB_PASSWORD_name' => 'Login password',
|
||||
@@ -503,20 +530,23 @@ the arp-scan will take hours to complete instead of seconds.
|
||||
'INCLUDED_SECTIONS_name' => 'Notify on',
|
||||
'INCLUDED_SECTIONS_description' => 'Specifies which events trigger notifications. Remove the event type(s) you don\'t want to get notified on. This setting overrides device-specific settings in the UI. (<code>CTRL + Click</code> to select / deselect).',
|
||||
'SCAN_CYCLE_MINUTES_name' => 'Scan cycle delay',
|
||||
'SCAN_CYCLE_MINUTES_description' => 'The delay between scans. If using arp-scan, the scan time itself depends on the number of IP addresses to check. This is influenced by the network mask set in the <a href="#SCAN_SUBNETS"><code>SCAN_SUBNETS</code> setting</a> at the top. Every IP takes a couple seconds to scan.',
|
||||
'SCAN_CYCLE_MINUTES_description' => 'The delay between scans in minutes. If using arp-scan, the scan time itself depends on the number of IP addresses to check. This is influenced by the network mask set in the <a href="#SCAN_SUBNETS"><code>SCAN_SUBNETS</code> setting</a> at the top. Every IP takes a couple seconds to scan.',
|
||||
'DAYS_TO_KEEP_EVENTS_name' => 'Delete events older than',
|
||||
'DAYS_TO_KEEP_EVENTS_description' => 'This is a maintenance setting. This specifies the number of days worth of event entries that will be kept. All older events will be deleted periodically.',
|
||||
'DAYS_TO_KEEP_EVENTS_description' => 'This is a maintenance setting. This specifies the number of days worth of event entries that will be kept. All older events will be deleted periodically. Also applies on Plugin Events History.',
|
||||
'REPORT_DASHBOARD_URL_name' => 'Pi.Alert URL',
|
||||
'REPORT_DASHBOARD_URL_description' => 'This URL is used as the base for generating links in the emails. Enter full URL starting with <code>http://</code> including the port number (no trailig slash <code>/</code>).',
|
||||
'DIG_GET_IP_ARG_name' => 'Internet IP discovery',
|
||||
'DIG_GET_IP_ARG_description' => 'Change the <a href="https://linux.die.net/man/1/dig" target="_blank">dig utility</a> arguments if you have issues resolving your Internet IP. Arguments are added at the end of the following command: <code>dig +short </code>.',
|
||||
'UI_LANG_name' => 'UI Language',
|
||||
'UI_LANG_description' => 'Select the preferred UI language.',
|
||||
|
||||
//Email
|
||||
'Email_settings_group' => '<i class="fa fa-at"></i> Email',
|
||||
'Email_display_name' => 'Email',
|
||||
'Email_icon' => '<i class="fa fa-at"></i>',
|
||||
'REPORT_MAIL_name' => 'Enable email',
|
||||
'REPORT_MAIL_description' => 'If enabled an email is sent out with a list of changes you\'ve subscribed to. Please also fill out all remaining settings related to the SMTP setup below.',
|
||||
'SMTP_SERVER_name' => 'SMTP server URL',
|
||||
'SMTP_SERVER_description' => 'The SMTP server host URL. For example <code>smtp-relay.sendinblue.com</code>. I don\'t recommend using Gmail as an SMTP server as the setup is <a target="_blank" href="https://support.google.com/a/answer/176600">quite complex</a> (I couldn\'t get it to work - Please reach out with a guide if you did)',
|
||||
'SMTP_SERVER_description' => 'The SMTP server host URL. For example <code>smtp-relay.sendinblue.com</code>. To use Gmail as an SMTP server <a target="_blank" href="https://github.com/jokob-sk/Pi.Alert/blob/main/docs/SMTP_GMAIL.md">follow this guide</a>',
|
||||
'SMTP_PORT_name' => 'SMTP server PORT',
|
||||
'SMTP_PORT_description' => 'Port number used for the SMTP connection. Set to <code>0</code> if you don\'t want to use a port when connecting to the SMTP server.',
|
||||
'SMTP_SKIP_LOGIN_name' => 'Skip authentication',
|
||||
@@ -535,7 +565,8 @@ the arp-scan will take hours to complete instead of seconds.
|
||||
'REPORT_FROM_description' => 'Notification email subject line.',
|
||||
|
||||
//Webhooks
|
||||
'Webhooks_settings_group' => '<i class="fa fa-circle-nodes"></i> Webhooks',
|
||||
'Webhooks_display_name' => 'Webhooks',
|
||||
'Webhooks_icon' => '<i class="fa fa-circle-nodes"></i>',
|
||||
'REPORT_WEBHOOK_name' => 'Enable Webhooks',
|
||||
'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/Pi.Alert/blob/main/docs/WEBHOOK_N8N.md" target="_blank">n8n guide here</a> to get started. If enabled, configure related settings below.',
|
||||
'WEBHOOK_URL_name' => 'Target URL',
|
||||
@@ -546,16 +577,18 @@ the arp-scan will take hours to complete instead of seconds.
|
||||
'WEBHOOK_REQUEST_METHOD_description' => 'The HTTP request method to be used for the webhook call.',
|
||||
|
||||
// Apprise
|
||||
'Apprise_settings_group' => '<i class="fa fa-bullhorn"></i> Apprise',
|
||||
'Apprise_display_name' => 'Apprise',
|
||||
'Apprise_icon' => '<i class="fa fa-bullhorn"></i>',
|
||||
'REPORT_APPRISE_name' => 'Enable Apprise',
|
||||
'REPORT_APPRISE_description' => 'Enable sending notifications via <a target="_blank" href="https://hub.docker.com/r/caronc/apprise">Apprise</a>.',
|
||||
'APPRISE_HOST_name' => 'Apprise host URL',
|
||||
'APPRISE_HOST_description' => 'Apprise host URL starting with <code>http://</code> or <code>https://</code>. (don\'t forget to include <code>/notify</code> at the end)',
|
||||
'APPRISE_URL_name' => 'Apprise notification URL',
|
||||
'APPRISE_URL_description' => 'Apprise notification target URL.',
|
||||
'APPRISE_URL_description' => 'Apprise notification target URL. For example for Telegram it would be <code>tgram://{bot_token}/{chat_id}</code>.',
|
||||
|
||||
// NTFY
|
||||
'NTFY_settings_group' => '<i class="fa fa-terminal"></i> NTFY',
|
||||
'NTFY_display_name' => 'NTFY',
|
||||
'NTFY_icon' => '<i class="fa fa-terminal"></i>',
|
||||
'REPORT_NTFY_name' => 'Enable NTFY',
|
||||
'REPORT_NTFY_description' => 'Enable sending notifications via <a target="_blank" href="https://ntfy.sh/">NTFY</a>.',
|
||||
'NTFY_HOST_name' => 'NTFY host URL',
|
||||
@@ -568,15 +601,19 @@ the arp-scan will take hours to complete instead of seconds.
|
||||
'NTFY_PASSWORD_description' => 'Enter password if you need (host) an instance with enabled authetication.',
|
||||
|
||||
// Pushsafer
|
||||
'PUSHSAFER_settings_group' => '<i class="fa fa-bell"></i> Pushsafer',
|
||||
'PUSHSAFER_display_name' => 'Pushsafer',
|
||||
'PUSHSAFER_icon' => '<i class="fa fa-bell"></i>',
|
||||
'REPORT_PUSHSAFER_name' => 'Enable Pushsafer',
|
||||
'REPORT_PUSHSAFER_description' => 'Enable sending notifications via <a target="_blank" href="https://www.pushsafer.com/">Pushsafer</a>.',
|
||||
'PUSHSAFER_TOKEN_name' => 'Pushsafer token',
|
||||
'PUSHSAFER_TOKEN_description' => 'Your secret Pushsafer API key (token).',
|
||||
'APPRISE_PAYLOAD_name' => 'Payload type',
|
||||
'APPRISE_PAYLOAD_description' => 'Select the payoad type sent to Apprise. For example <code>html</code> works well with emails, <code>text</code> with chat apps, such as Telegram.',
|
||||
|
||||
|
||||
// MQTT
|
||||
'MQTT_settings_group' => '<i class="fa fa-square-rss"></i> MQTT',
|
||||
'MQTT_display_name' => 'MQTT',
|
||||
'MQTT_icon' => '<i class="fa fa-square-rss"></i>',
|
||||
'REPORT_MQTT_name' => 'Enable MQTT',
|
||||
'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.',
|
||||
'MQTT_BROKER_name' => 'MQTT broker URL',
|
||||
@@ -593,7 +630,8 @@ the arp-scan will take hours to complete instead of seconds.
|
||||
'MQTT_DELAY_SEC_description' => 'A little hack - delay adding to the queue in case the process is restarted and previous publish processes aborted (it takes ~<code>2</code>s to update a sensor config on the broker). Tested with <code>2</code>-<code>3</code> seconds of delay. This delay is only applied when devices are created (during the first notification loop). It doesn\'t affect subsequent scans or notifications.',
|
||||
|
||||
//DynDNS
|
||||
'DynDNS_settings_group' => '<i class="fa fa-globe"></i> DynDNS',
|
||||
'DynDNS_display_name' => 'DynDNS',
|
||||
'DynDNS_icon' => '<i class="fa fa-globe"></i>',
|
||||
'DDNS_ACTIVE_name' => 'Enable DynDNS',
|
||||
'DDNS_ACTIVE_description' => '',
|
||||
'DDNS_DOMAIN_name' => 'DynDNS domain URL',
|
||||
@@ -606,14 +644,16 @@ the arp-scan will take hours to complete instead of seconds.
|
||||
'DDNS_UPDATE_URL_description' => 'Update URL starting with <code>http://</code> or <code>https://</code>.',
|
||||
|
||||
// PiHole
|
||||
'PiHole_settings_group' => '<i class="fa fa-seedling"></i> PiHole',
|
||||
'PiHole_display_name' => 'PiHole',
|
||||
'PiHole_icon' => '<i class="fa fa-seedling"></i>',
|
||||
'PIHOLE_ACTIVE_name' => 'Enable PiHole mapping',
|
||||
'PIHOLE_ACTIVE_description' => 'You need to map<code>:/etc/pihole/pihole-FTL.db</code> in the <code>docker-compose.yml</code> file if you enable this setting.',
|
||||
'DHCP_ACTIVE_name' => 'Enable PiHole DHCP',
|
||||
'DHCP_ACTIVE_description' => 'You need to map <code>:/etc/pihole/dhcp.leases</code> in the <code>docker-compose.yml</code> file if you enable this setting.',
|
||||
|
||||
// Pholus
|
||||
'Pholus_settings_group' => '<i class="fa fa-search"></i> Pholus',
|
||||
'Pholus_display_name' => 'Pholus',
|
||||
'Pholus_icon' => '<i class="fa fa-search"></i>',
|
||||
'PHOLUS_ACTIVE_name' => 'Cycle run',
|
||||
'PHOLUS_ACTIVE_description' => '<a href="https://github.com/jokob-sk/Pi.Alert/tree/main/pholus" target="_blank" >Pholus</a> is a sniffing tool to discover additional information about the devices on the network, including the device name. If enabled this will execute the scan before every network scan cycle until there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Please be aware it can spam the network with unnecessary traffic. Depends on the <a onclick="toggleAllSettings()" href="#SCAN_SUBNETS"><code>SCAN_SUBNETS</code> setting</a>. For a scheduled or one-off scan, check the <a href="#PHOLUS_RUN"><code>PHOLUS_RUN</code> setting</a>.',
|
||||
'PHOLUS_TIMEOUT_name' => 'Cycle run timeout',
|
||||
@@ -628,14 +668,15 @@ the arp-scan will take hours to complete instead of seconds.
|
||||
'PHOLUS_RUN_SCHD_description' => 'Only enabled if you select <code>schedule</code> in the <a href="#PHOLUS_RUN"><code>PHOLUS_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format
|
||||
(e.g. validate at <a href="https://crontab.guru/" target="_blank">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick="toggleAllSettings()" href="#TIMEZONE"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes.',
|
||||
'PHOLUS_DAYS_DATA_name' => 'Data retention',
|
||||
'PHOLUS_DAYS_DATA_description' => 'How many days of Pholus scan entries should be kept (globally, not device specific!). The <a href="/maintenance.php#tab_Logging">pialert_pholus.log</a> file is not touched. Enter <code>0</code> to disable.',
|
||||
'PHOLUS_DAYS_DATA_description' => 'How many days of Pholus scan entries should be kept (globally, not device specific!) Enter <code>0</code> to disable.',
|
||||
|
||||
// Nmap
|
||||
'Nmap_settings_group' => '<i class="fa fa-ethernet"></i> Nmap',
|
||||
'Nmap_display_name' => 'Nmap',
|
||||
'Nmap_icon' => '<i class="fa fa-ethernet"></i>',
|
||||
'NMAP_ACTIVE_name' => 'Cycle run',
|
||||
'NMAP_ACTIVE_description' => 'If enabled this will execute a scan on a newly found device. For a scheduled or one-off scan, check the <a href="#NMAP_RUN"><code>NMAP_RUN</code> setting</a>.',
|
||||
'NMAP_TIMEOUT_name' => 'Run timeout',
|
||||
'NMAP_TIMEOUT_description' => 'Maximum time to wait for an Nmap scan to finish on any device.',
|
||||
'NMAP_TIMEOUT_description' => 'Maximum time in seconds to wait for an Nmap scan to finish on any device.',
|
||||
'NMAP_RUN_name' => 'Scheduled run',
|
||||
'NMAP_RUN_description' => 'Enable a regular Nmap scan on your network on all devices. The scheduling settings can be found below. If you select <code>once</code> Nmap is run only once on start for the time specified in <a href="#NMAP_TIMEOUT"><code>NMAP_TIMEOUT</code> setting</a>.',
|
||||
'NMAP_RUN_SCHD_name' => 'Schedule',
|
||||
@@ -643,6 +684,16 @@ the arp-scan will take hours to complete instead of seconds.
|
||||
'NMAP_ARGS_name' => 'Arguments',
|
||||
'NMAP_ARGS_description' => 'Arguments used to run the Nmap scan. Be careful to specify <a href="https://linux.die.net/man/1/nmap" target="_blank">the arguments</a> correctly. For example <code>-p -10000</code> scans ports from 1 to 10000.',
|
||||
|
||||
// API
|
||||
'API_display_name' => 'API',
|
||||
'API_icon' => '<i class="fa fa-arrow-down-up-across-line"></i>',
|
||||
'API_CUSTOM_SQL_name' => 'Custom endpoint',
|
||||
'API_CUSTOM_SQL_description' => 'You can specify a custom SQL query which will generate a JSON file and then expose it via the <a href="/api/table_custom_endpoint.json" target="_blank"><code>table_custom_endpoint.json</code> file endpoint</a>.',
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
);
|
||||
|
||||
?>
|
||||
|
||||
@@ -46,7 +46,7 @@ $lang['es_es'] = array(
|
||||
'Navigation_Devices' => 'Dispositivos',
|
||||
'Navigation_Presence' => 'Historial',
|
||||
'Navigation_Events' => 'Eventos',
|
||||
'Navigation_Maintenance' => 'Cantenimiento',
|
||||
'Navigation_Maintenance' => 'Mantenimiento',
|
||||
'Navigation_Settings' => 'Configuración',
|
||||
'Navigation_Network' => 'Red',
|
||||
'Navigation_HelpFAQ' => 'Ayuda / FAQ',
|
||||
@@ -412,8 +412,196 @@ $lang['es_es'] = array(
|
||||
puertos (agrupación de puertos), así como múltiples dispositivos a un puerto (máquinas virtuales).',
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Settings
|
||||
// Settings (based on work of https://github.com/mariorodriguezlopez/Pi.Alert/)
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
'API_settings_group' => '<i class="fa fa-arrow-down-up-across-line"></i> API',
|
||||
|
||||
// General
|
||||
|
||||
'DAYS_TO_KEEP_EVENTS_description' => 'Esta es una configuración de mantenimiento. Esto especifica el número de días de entradas de eventos que se guardarán. Todos los eventos anteriores se eliminarán periódicamente.',
|
||||
'DAYS_TO_KEEP_EVENTS_name' => 'Eliminar eventos anteriores a',
|
||||
'PIALERT_WEB_PASSWORD_description' => 'La contraseña predeterminada es <code>123456</code>. Para cambiar la contraseña, ejecute <code>/home/pi/pialert/back/pialert-cli</code> en el contenedor',
|
||||
'PIALERT_WEB_PASSWORD_name' => 'Contraseña de inicio de sesión',
|
||||
'PIALERT_WEB_PROTECTION_description' => 'Cuando está habilitado, se muestra un cuadro de diálogo de inicio de sesión. Lea detenidamente a continuación si se le bloquea el acceso a su instancia.',
|
||||
'PIALERT_WEB_PROTECTION_name' => 'Habilitar inicio de sesión',
|
||||
'REPORT_DASHBOARD_URL_description' => 'Esta URL se utiliza como base para generar enlaces en los correos electrónicos. Ingrese la URL completa que comienza con <code>http://</code>, incluido el número de puerto (sin barra inclinada al final <code>/</code>).',
|
||||
'REPORT_DASHBOARD_URL_name' => 'Pi.Alert URL',
|
||||
'REPORT_FROM_description' => 'Asunto del correo electrónico de notificación.',
|
||||
'REPORT_FROM_name' => 'Asunto del email',
|
||||
'REPORT_MAIL_description' => 'Si está habilitado, se envía un correo electrónico con una lista de cambios a los que se ha suscrito. Complete también todas las configuraciones restantes relacionadas con la configuración de SMTP a continuación',
|
||||
'REPORT_MAIL_name' => 'Habilitar email',
|
||||
'REPORT_TO_description' => 'Dirección de correo electrónico a la que se enviará la notificación.',
|
||||
'REPORT_TO_name' => 'Enviar el email a',
|
||||
'SCAN_CYCLE_MINUTES_description' => 'El retraso entre escaneos. Si usa arp-scan, el tiempo de escaneo en sí depende de la cantidad de direcciones IP para verificar. Esto está influenciado por la máscara de red configurada en la configuración <a href="#SCAN_SUBNETS"><code>SCAN_SUBNETS</code></a> en la parte superior. Cada IP toma un par de segundos para escanear.',
|
||||
'SCAN_CYCLE_MINUTES_name' => 'Retraso del ciclo de escaneo',
|
||||
'SCAN_SUBNETS_description' => 'El tiempo de escaneo arp en sí depende de la cantidad de direcciones IP para verificar.
|
||||
El número de direcciones IP para comprobar depende de la <a target="_blank" href="https://www.calculator.net/ip-subnet-calculator.html">máscara de red</a> que establezca aquí.
|
||||
Por ejemplo, una máscara <code>/24</code> da como resultado 256 IP para verificar, mientras que <code>/16</code>
|
||||
controles de máscara alrededor de 65,536. Cada IP toma un par de segundos. Esto significa que con una configuración incorrecta
|
||||
el arp-scan tardará horas en completarse en lugar de segundos.
|
||||
<ol>
|
||||
<li>Especifique la máscara de red. Por ejemplo, el filtro <code>192.168.1.0/24</code> cubre los rangos de IP 192.168.1.0 a 192.168.1.255.</li>
|
||||
<li>Ejecute <code>ifconfig</code> en su contenedor para encontrar los nombres de su interfaz (por ejemplo: <code>eth0</code>, <code>eth1</code>)</li>
|
||||
</ol>
|
||||
',
|
||||
'SCAN_SUBNETS_name' => 'Subredes para escanear',
|
||||
'TIMEZONE_description' => 'Zona horaria para mostrar las estadísticas correctamente. Encuentra tu zona horaria<a target="_blank" href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones" rel="nofollow">aquí</a>.',
|
||||
'TIMEZONE_name' => 'Zona horaria',
|
||||
'UI_LANG_description' => 'Seleccione el idioma de interfaz de usuario preferido.',
|
||||
'UI_LANG_name' => 'Idioma de interfaz',
|
||||
|
||||
// Email
|
||||
|
||||
'SMTP_FORCE_SSL_description' => 'Forzar SSL al conectarse a su servidor SMTP',
|
||||
'SMTP_FORCE_SSL_name' => 'Forzar SSL',
|
||||
'SMTP_PASS_description' => 'La contraseña del servidor SMTP.',
|
||||
'SMTP_PASS_name' => 'SMTP password',
|
||||
'SMTP_PORT_description' => 'Número de puerto utilizado para la conexión SMTP. Establézcalo en <code>0</code> si no desea utilizar un puerto al conectarse al servidor SMTP.',
|
||||
'SMTP_PORT_name' => 'SMTP server PORT',
|
||||
'SMTP_SERVER_description' => 'La URL del host del servidor SMTP. Por ejemplo, <code>smtp-relay.sendinblue.com</code>. Para utilizar Gmail como servidor SMTP <a target="_blank" href="https://github.com/jokob-sk/Pi.Alert/blob/main/docs/SMTP_GMAIL.md">siga esta guía</a >',
|
||||
'SMTP_SERVER_name' => 'SMTP server URL',
|
||||
'SMTP_SKIP_LOGIN_description' => 'No utilice la autenticación cuando se conecte al servidor SMTP.',
|
||||
'SMTP_SKIP_LOGIN_name' => 'Omitir autenticación',
|
||||
'SMTP_SKIP_TLS_description' => 'Deshabilite TLS cuando se conecte a su servidor SMTP.',
|
||||
'SMTP_SKIP_TLS_name' => 'No usar TLS',
|
||||
'SMTP_USER_description' => 'El nombre de usuario utilizado para iniciar sesión en el servidor SMTP (a veces, una dirección de correo electrónico completa).',
|
||||
'SMTP_USER_name' => 'SMTP user',
|
||||
|
||||
//API
|
||||
|
||||
'API_CUSTOM_SQL_description' => 'Puede especificar una consulta SQL personalizada que generará un archivo JSON y luego lo expondrá a través del <a href="/api/table_custom_endpoint.json" target="_blank">archivo <code>table_custom_endpoint.json</code ></a>.',
|
||||
'API_CUSTOM_SQL_name' => 'Endpoint personalizado',
|
||||
|
||||
|
||||
// Apprise
|
||||
|
||||
'APPRISE_HOST_description' => 'Apprise host URL que comienza con <code>http://</code> o <code>https://</code>. (no olvide incluir <code>/notify</code> al final)',
|
||||
'APPRISE_HOST_name' => 'Apprise host URL',
|
||||
'APPRISE_PAYLOAD_description' => 'Seleccione el tipo de carga útil enviada a Apprise. Por ejemplo, <code>html</code> funciona bien con correos electrónicos, <code>text</code> con aplicaciones de chat, como Telegram.',
|
||||
'APPRISE_PAYLOAD_name' => 'Tipo de carga',
|
||||
'APPRISE_URL_description' => 'Informar de la URL de destino de la notificación. Por ejemplo, para Telegram sería <code>tgram://{bot_token}/{chat_id}</code>.',
|
||||
'APPRISE_URL_name' => 'URL de notificación de Apprise',
|
||||
|
||||
// Pushsafer
|
||||
'REPORT_PUSHSAFER_description' => 'Habilitar el envío de notificaciones a través de <a target="_blank" href="https://www.pushsafer.com/">Pushsafer</a>.',
|
||||
'REPORT_PUSHSAFER_name' => 'Habilitar Pushsafer',
|
||||
|
||||
|
||||
//DYNDNS
|
||||
|
||||
|
||||
'DDNS_ACTIVE_name' => 'Habilitar DynDNS',
|
||||
'DDNS_DOMAIN_name' => 'URL del dominio DynDNS',
|
||||
'DDNS_PASSWORD_name' => 'DynDNS password',
|
||||
'DDNS_UPDATE_URL_description' => 'Actualice la URL que comienza con <code>http://</code> o <code>https://</code>.',
|
||||
'DDNS_UPDATE_URL_name' => 'DynDNS update URL',
|
||||
'DDNS_USER_name' => 'DynDNS user',
|
||||
'DHCP_ACTIVE_description' => 'Debe asignar <code>:/etc/pihole/dhcp.leases</code> en el archivo <code>docker-compose.yml</code> si habilita esta configuración.',
|
||||
'DHCP_ACTIVE_name' => 'Habilitar PiHole DHCP',
|
||||
'DIG_GET_IP_ARG_description' => 'Cambie los argumentos de la <a href="https://linux.die.net/man/1/dig" target="_blank">utilidad de dig</a> si tiene problemas para resolver su IP de Internet. Los argumentos se agregan al final del siguiente comando: <code>dig +short </code>.',
|
||||
'DIG_GET_IP_ARG_name' => 'Descubrir de IP de Internet',
|
||||
|
||||
// MQTT
|
||||
'REPORT_MQTT_description' => 'Habilitar el envío de notificaciones a través de <a target="_blank" href="https://www.home-assistant.io/integrations/mqtt/">MQTT</a> a su Home Assistance.',
|
||||
'REPORT_MQTT_name' => 'Habilitar MQTT',
|
||||
'MQTT_BROKER_description' => 'URL del host MQTT (no incluya <code>http://</code> o <code>https://</code>).',
|
||||
'MQTT_BROKER_name' => 'MQTT broker URL',
|
||||
'MQTT_DELAY_SEC_description' => 'Un pequeño truco: retrase la adición a la cola en caso de que el proceso se reinicie y los procesos de publicación anteriores se anulen (se necesitan ~<code>2</code>s para actualizar la configuración de un sensor en el intermediario). Probado con <code>2</code>-<code>3</code> segundos de retraso. Este retraso solo se aplica cuando se crean dispositivos (durante el primer bucle de notificación). No afecta los escaneos o notificaciones posteriores.',
|
||||
'MQTT_DELAY_SEC_name' => 'Retraso de MQTT por dispositivo',
|
||||
'MQTT_PASSWORD_description' => 'Contraseña utilizada para iniciar sesión en su instancia de agente de MQTT.',
|
||||
'MQTT_PASSWORD_name' => 'MQTT password',
|
||||
'MQTT_PORT_description' => 'Puerto donde escucha el broker MQTT. Normalmente <code>1883</code>.',
|
||||
'MQTT_PORT_name' => 'MQTT broker puerto',
|
||||
'MQTT_QOS_description' => 'Configuración de calidad de servicio para el envío de mensajes MQTT. <code>0</code>: baja calidad a <code>2</code>: alta calidad. Cuanto mayor sea la calidad, mayor será el retraso.',
|
||||
'MQTT_QOS_name' => 'Calidad de servicio MQTT',
|
||||
'MQTT_USER_description' => 'Nombre de usuario utilizado para iniciar sesión en su instancia de agente de MQTT.',
|
||||
'MQTT_USER_name' => 'MQTT user',
|
||||
'MQTT_settings_group' => '<i class="fa fa-square-rss"></i> MQTT',
|
||||
|
||||
// NMAP
|
||||
|
||||
'NMAP_ACTIVE_description' => 'Si está habilitado, ejecutará un escaneo en un dispositivo recién encontrado. Para un análisis programado o único, verifique la configuración de <a href="#NMAP_RUN"><code>NMAP_RUN</code></a>.',
|
||||
'NMAP_ACTIVE_name' => 'Ejecución del ciclo',
|
||||
'NMAP_ARGS_description' => 'Argumentos utilizados para ejecutar el análisis de Nmap. Tenga cuidado de especificar <a href="https://linux.die.net/man/1/nmap" target="_blank">los argumentos</a> correctamente. Por ejemplo, <code>-p -10000</code> escanea los puertos del 1 al 10000.',
|
||||
'NMAP_ARGS_name' => 'Argumentos',
|
||||
'NMAP_RUN_SCHD_description' => 'Solo está habilitado si selecciona <code>programar</code> en la configuración de <a href="#NMAP_RUN"><code>NMAP_RUN</code></a>. Asegúrese de ingresar el cronograma en el formato tipo cron correcto.',
|
||||
'NMAP_RUN_SCHD_name' => 'Programar',
|
||||
'NMAP_RUN_description' => 'Habilite un escaneo regular de Nmap en su red en todos los dispositivos. Los ajustes de programación se pueden encontrar a continuación. Si selecciona <code>una vez</code>, Nmap se ejecuta solo una vez al inicio durante el tiempo especificado en la configuración de <a href="#NMAP_TIMEOUT"><code>NMAP_TIMEOUT</code></a>.',
|
||||
'NMAP_RUN_name' => 'Ejecución programada',
|
||||
'NMAP_TIMEOUT_description' => 'Tiempo máximo en segundos para esperar a que finalice un escaneo de Nmap en cualquier dispositivo.',
|
||||
|
||||
// NTFY
|
||||
'REPORT_NTFY_description' => 'Habilitar el envío de notificaciones a través de <a target="_blank" href="https://ntfy.sh/">NTFY</a>.',
|
||||
'REPORT_NTFY_name' => 'Habilitar NTFY',
|
||||
'NTFY_HOST_description' => 'URL de host NTFY que comienza con <code>http://</code> o <code>https://</code>. Puede usar la instancia alojada en <a target="_blank" href="https://ntfy.sh/">https://ntfy.sh</a> simplemente ingresando <code>https://ntfy. sh</código>.',
|
||||
'NTFY_HOST_name' => 'NTFY host URL',
|
||||
'NTFY_PASSWORD_description' => 'Ingrese la contraseña si necesita (host) una instancia con autenticación habilitada.',
|
||||
'NTFY_PASSWORD_name' => 'NTFY password',
|
||||
'NTFY_TOPIC_name' => 'NTFY topic',
|
||||
'NTFY_USER_description' => 'Ingrese usuario si necesita (alojar) una instancia con autenticación habilitada.',
|
||||
'NTFY_USER_name' => 'NTFY user',
|
||||
'NTFY_settings_group' => '<i class="fa fa-terminal"></i> NTFY',
|
||||
|
||||
// Pholus
|
||||
|
||||
'Pholus_settings_group' => '<i class="fa fa-search"></i> Pholus',
|
||||
'PHOLUS_ACTIVE_description' => '<a href="https://github.com/jokob-sk/Pi.Alert/tree/main/pholus" target="_blank" >Pholus</a> es una herramienta de rastreo para descubrir información adicional sobre los dispositivos en la red, incluido el nombre del dispositivo. Si está habilitado, ejecutará el escaneo antes de cada ciclo de escaneo de red hasta que no haya dispositivos <code>(unknown)</code> o <code>(name not found)</code>. Tenga en cuenta que puede enviar spam a la red con tráfico innecesario. Depende de la configuración de <a onclick="toggleAllSettings()" href="#SCAN_SUBNETS"><code>SCAN_SUBNETS</code></a>. Para un análisis programado o único, verifique la configuración de <a href="#PHOLUS_RUN"><code>PHOLUS_RUN</code></a>.',
|
||||
'PHOLUS_ACTIVE_name' => 'Ejecución del ciclo',
|
||||
'PHOLUS_DAYS_DATA_description' => 'Cuántos días de entradas de escaneo de Pholus deben conservarse (globalmente, ¡no específico del dispositivo!). El archivo <a href="/maintenance.php#tab_Logging">pialert_pholus.log</a> no se modifica. Introduzca <code>0</code> para desactivar.',
|
||||
'PHOLUS_DAYS_DATA_name' => 'Retención de datos',
|
||||
'PHOLUS_FORCE_description' => 'Fuerce el escaneo de cada escaneo de red, incluso si no hay dispositivos <code>(unknown)</code> o <code>(name not found)</code>. Tenga cuidado al habilitar esto, ya que la detección puede inundar fácilmente su red.',
|
||||
'PHOLUS_FORCE_name' => 'Escaneo de fuerza de ciclo',
|
||||
'PHOLUS_RUN_SCHD_description' => 'Solo está habilitado si selecciona <code>programar</code> en la configuración de <a href="#PHOLUS_RUN"><code>PHOLUS_RUN</code></a>. Asegúrese de ingresar el horario en el formato similar a cron correcto
|
||||
(por ejemplo, validar en <a href="https://crontab.guru/" target="_blank">crontab.guru</a>). Por ejemplo, ingresar <code>0 4 * * *</code> ejecutará el escaneo después de las 4 am en el <a onclick="toggleAllSettings()" href="#TIMEZONE"><code>TIMEZONE</code> que configuró arriba</a>. Se ejecutará la PRÓXIMA vez que pase el tiempo.',
|
||||
'PHOLUS_RUN_SCHD_name' => 'Programar',
|
||||
'PHOLUS_RUN_TIMEOUT_description' => 'El tiempo de espera en segundos para el escaneo Pholus programado. Se aplican las mismas notas con respecto a la duración que en la configuración de <a href="#PHOLUS_TIMEOUT"><code>PHOLUS_TIMEOUT</code></a>. Un escaneo programado no verifica si hay dispositivos <code>(unknown)</code> o <code>(name not found)</code>, el escaneo se ejecuta de cualquier manera.',
|
||||
'PHOLUS_RUN_TIMEOUT_name' => 'Tiempo de espera de ejecución programado',
|
||||
'PHOLUS_RUN_description' => 'Habilite un escaneo regular de Pholus en su red. Los ajustes de programación se pueden encontrar a continuación. Si selecciona <code>una vez</code>, Pholus se ejecuta solo una vez al inicio durante el tiempo especificado en la configuración de <a href="#PHOLUS_RUN_TIMEOUT"><code>PHOLUS_RUN_TIMEOUT</code></a>.',
|
||||
'PHOLUS_RUN_name' => 'Ejecución programada',
|
||||
'PHOLUS_TIMEOUT_description' => '¿Cuánto tiempo en segundos debe rastrear Pholus en cada interfaz si se cumple la condición anterior? Cuanto más tiempo lo deje encendido, es más probable que los dispositivos transmitan más información. Este tiempo de espera se suma al tiempo que lleva realizar un escaneo arp en su red.',
|
||||
'PHOLUS_TIMEOUT_name' => 'Tiempo de espera de ciclo',
|
||||
|
||||
// PiHole
|
||||
|
||||
'PiHole_settings_group' => '<i class="fa fa-seedling"></i> PiHole',
|
||||
'PIHOLE_ACTIVE_description' => 'Debe mapear <code>:/etc/pihole/pihole-FTL.db</code> en el archivo <code>docker-compose.yml</code> si habilita esta configuración.',
|
||||
'PIHOLE_ACTIVE_name' => 'Habilitar el mapeo de PiHole',
|
||||
'PRINT_LOG_description' => 'Esta configuración habilitará un registro más detallado. Útil para depurar eventos que se escriben en la base de datos.',
|
||||
'PRINT_LOG_name' => 'Imprimir registro adicional',
|
||||
'PUSHSAFER_TOKEN_description' => 'Su clave secreta de la API de Pushsafer (token).',
|
||||
'PUSHSAFER_TOKEN_name' => 'Pushsafer token',
|
||||
'PUSHSAFER_settings_group' => '<i class="fa fa-bell"></i> Pushsafer',
|
||||
|
||||
//Apprise
|
||||
|
||||
'REPORT_APPRISE_description' => 'Habilitar el envío de notificaciones a través de <a target="_blank" href="https://hub.docker.com/r/caronc/apprise">Apprise</a>.',
|
||||
'REPORT_APPRISE_name' => 'Habilitar Apprise',
|
||||
|
||||
// Webhooks
|
||||
'REPORT_WEBHOOK_description' => 'Habilite webhooks para notificaciones. Los webhooks lo ayudan a conectarse a muchas herramientas de terceros, como IFTTT, Zapier o <a href="https://n8n.io/" target="_blank">n8n</a>, por nombrar algunas. Consulte esta sencilla <a href="https://github.com/jokob-sk/Pi.Alert/blob/main/docs/WEBHOOK_N8N.md" target="_blank">guía de n8n aquí</a> para obtener comenzó. Si está habilitado, configure los ajustes relacionados a continuación.',
|
||||
'REPORT_WEBHOOK_name' => 'Habilitar webhooks',
|
||||
'WEBHOOK_PAYLOAD_description' => 'El formato de datos de carga de Webhook para el atributo <code>body</code> > <code>attachments</code> > <code>text</code> en el json de carga. Vea un ejemplo de la carga <a target="_blank" href="https://github.com/jokob-sk/Pi.Alert/blob/main/back/webhook_json_sample.json">aquí</a>. (por ejemplo: para discord use <code>html</code>)',
|
||||
'WEBHOOK_PAYLOAD_name' => 'Tipo de carga',
|
||||
'WEBHOOK_REQUEST_METHOD_description' => 'El método de solicitud HTTP que se utilizará para la llamada de webhook.',
|
||||
'WEBHOOK_REQUEST_METHOD_name' => 'Método de solicitud',
|
||||
'WEBHOOK_URL_description' => 'URL de destino comienza con <code>http://</code> o <code>https://</code>.',
|
||||
'WEBHOOK_URL_name' => 'URL de destino',
|
||||
'Webhooks_settings_group' => '<i class="fa fa-circle-nodes"></i> Webhooks',
|
||||
|
||||
// Other
|
||||
|
||||
'general_event_description' => 'El evento que ha activado puede tardar un tiempo hasta que finalicen los procesos en segundo plano. La ejecución terminó una vez que vea <code>finished</code> a continuación. Consulte el <a onclick=\'setCache("activeMaintenanceTab", "tab_Logging_id")\' href="/maintenance.php#tab_Logging">registro de errores</a> si no obtuvo el resultado esperado. <br/> <br/> Estado:',
|
||||
'general_event_title' => 'Ejecución de un evento ad-hoc',
|
||||
'run_event_icon' => 'fa-play',
|
||||
'run_event_tooltip' => 'Habilite la configuración y guarde sus cambios al principio antes de ejecutarlo.',
|
||||
'settings_expand_all' => 'Expandir todo',
|
||||
'settings_imported' => 'La última vez que se importó la configuración desde el archivo pialert.conf:',
|
||||
'settings_missing' => 'No se han cargado todos los ajustes, actualice la página. Esto probablemente se deba a una gran carga en la base de datos.',
|
||||
'settings_missing_block' => 'No puede guardar su configuración sin especificar todas las claves de configuración. Recarga la página. Esto probablemente se deba a una gran carga en la base de datos.',
|
||||
'settings_old' => 'La configuración en la base de datos (que se muestra en esta página) está desactualizada. Esto probablemente se deba a un análisis en ejecución. La configuración se guardó en el archivo <code>pialert.conf</code>, pero el proceso en segundo plano aún no tuvo tiempo de importarlo a la base de datos. Puede esperar hasta que la configuración se actualice para no sobrescribir sus valores anteriores. Siéntase libre de guardar su configuración de cualquier manera si no le importa perder la configuración entre la última vez que guardó y ahora. También se crean archivos de respaldo si necesita comparar su configuración más adelante.',
|
||||
'test_event_icon' => 'fa-vial-circle-check',
|
||||
'test_event_tooltip' => 'Guarde sus cambios antes de probar su configuración.',
|
||||
|
||||
);
|
||||
?>
|
||||
|
||||
@@ -5,23 +5,47 @@
|
||||
// ###################################
|
||||
|
||||
$defaultLang = "en_us";
|
||||
$allLanguages = ["en_us","es_es","de_de"];
|
||||
|
||||
if(!isset($_COOKIE["language"])) {
|
||||
$pia_lang_selected = $defaultLang;
|
||||
} else {
|
||||
$pia_lang_selected = $_COOKIE["language"];
|
||||
global $db;
|
||||
|
||||
$result = $db->querySingle("SELECT Value FROM Settings WHERE Code_Name = 'UI_LANG'");
|
||||
switch($result){
|
||||
case 'Spanish': $pia_lang_selected = 'es_es'; break;
|
||||
case 'German': $pia_lang_selected = 'de_de'; break;
|
||||
default: $pia_lang_selected = 'en_us'; break;
|
||||
}
|
||||
|
||||
if (isset($pia_lang_selected) == FALSE or (strlen($pia_lang_selected) == 0)) {$pia_lang_selected = defaultLang;}
|
||||
if (isset($pia_lang_selected) == FALSE or (strlen($pia_lang_selected) == 0)) {$pia_lang_selected = $defaultLang;}
|
||||
|
||||
require '/home/pi/pialert/front/php/templates/skinUI.php';
|
||||
require 'en_us.php';
|
||||
require 'de_de.php';
|
||||
require 'es_es.php';
|
||||
//Language_Strings ("Language_Code", "String_Key", "String_Value", "Extra")
|
||||
$result = $db->query("SELECT * FROM Plugins_Language_Strings");
|
||||
|
||||
// array
|
||||
$strings = array();
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
// Push row data
|
||||
$strings[] = array( 'Language_Code' => $row['Language_Code'],
|
||||
'String_Key' => $row['String_Key'],
|
||||
'String_Value' => $row['String_Value'],
|
||||
'Extra' => $row['Extra']
|
||||
);
|
||||
}
|
||||
|
||||
require dirname(__FILE__).'/../skinUI.php';
|
||||
require dirname(__FILE__).'/en_us.php';
|
||||
require dirname(__FILE__).'/de_de.php';
|
||||
require dirname(__FILE__).'/es_es.php';
|
||||
|
||||
function lang($key)
|
||||
{
|
||||
global $pia_lang_selected, $lang, $defaultLang;
|
||||
global $pia_lang_selected, $lang, $defaultLang, $strings;
|
||||
|
||||
// get strings from the DB and append them to the ones from the files
|
||||
foreach ($strings as $string)
|
||||
{
|
||||
$lang[$string["Language_Code"]][$string["String_Key"]] = $string["String_Value"];
|
||||
}
|
||||
|
||||
// check if key exists in selected language
|
||||
if(array_key_exists($key, $lang[$pia_lang_selected]) == FALSE)
|
||||
@@ -45,4 +69,3 @@ function lang($key)
|
||||
|
||||
return $temp;
|
||||
}
|
||||
?>
|
||||
@@ -4,9 +4,9 @@
|
||||
// ## TimeZone processing start
|
||||
// ###################################
|
||||
|
||||
$configFolderPath = "/home/pi/pialert/config/";
|
||||
$configFolderPath = dirname(__FILE__)."/../../../config/";
|
||||
$config_file = "pialert.conf";
|
||||
$logFolderPath = "/home/pi/pialert/front/log/";
|
||||
$logFolderPath = dirname(__FILE__)."/../../log/";
|
||||
$log_file = "pialert_front.log";
|
||||
|
||||
|
||||
@@ -40,5 +40,3 @@ $timestamp = $date->format('Y-m-d_H-i-s');
|
||||
// ###################################
|
||||
// ## TimeZone processing end
|
||||
// ###################################
|
||||
|
||||
?>
|
||||
468
front/plugins.php
Executable file
@@ -0,0 +1,468 @@
|
||||
<?php
|
||||
|
||||
require 'php/templates/header.php';
|
||||
?>
|
||||
|
||||
<script src="js/pialert_common.js"></script>
|
||||
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<?php require 'php/templates/notification.php'; ?>
|
||||
<h1 id="pageTitle">
|
||||
<i class="fa fa-fw fa-plug"></i> <?= lang('Navigation_Plugins');?>
|
||||
<span class="pageHelp"> <a target="_blank" href="https://github.com/jokob-sk/Pi.Alert/tree/main/front/plugins"><i class="fa fa-circle-question"></i></a><span>
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
<!-- Main content ---------------------------------------------------------- -->
|
||||
<section class="content">
|
||||
<div class="nav-tabs-custom plugin-content" style="margin-bottom: 0px;">
|
||||
<ul id="tabs-location" class="nav nav-tabs">
|
||||
<!-- PLACEHOLDER -->
|
||||
</ul>
|
||||
<div id="tabs-content-location" class="tab-content">
|
||||
<!-- PLACEHOLDER -->
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script defer>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Get form control according to the column definition from config.json > database_column_definitions
|
||||
function getFormControl(dbColumnDef, value, index) {
|
||||
|
||||
result = ''
|
||||
|
||||
switch(dbColumnDef.type)
|
||||
{
|
||||
case 'label':
|
||||
result = `<span>${value}<span>`;
|
||||
break;
|
||||
case 'textboxsave':
|
||||
|
||||
value = value == 'null' ? '' : value; // hide 'null' values
|
||||
|
||||
id = `${dbColumnDef.column}_${index}`
|
||||
|
||||
result = `<span class="form-group">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" value="${value}" id="${id}" data-my-column="${dbColumnDef.column}" data-my-index="${index}" name="${dbColumnDef.column}">
|
||||
<span class="input-group-addon"><i class="fa fa-save pointer" onclick="saveData('${id}');"></i></span>
|
||||
</div>
|
||||
<span>`;
|
||||
break;
|
||||
case 'url':
|
||||
result = `<span><a href="${value}" target="_blank">${value}</a><span>`;
|
||||
break;
|
||||
case 'devicemac':
|
||||
result = `<span class="anonymizeMac"><a href="/deviceDetails.php?mac=${value}" target="_blank">${value}</a><span>`;
|
||||
break;
|
||||
case 'deviceip':
|
||||
result = `<span class="anonymizeIp"><a href="#" onclick="navigateToDeviceWithIp('${value}')" >${value}</a><span>`;
|
||||
break;
|
||||
case 'threshold':
|
||||
$.each(dbColumnDef.options, function(index, obj) {
|
||||
if(Number(value) < obj.maximum && result == '')
|
||||
{
|
||||
result = `<div style="background-color:${obj.hexColor}">${value}</div>`
|
||||
// return;
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'replace':
|
||||
$.each(dbColumnDef.options, function(index, obj) {
|
||||
if(value == obj.equals)
|
||||
{
|
||||
result = `<span title="${value}">${obj.replacement}</span>`
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
result = value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Update the coresponding DB column and entry
|
||||
function saveData (id) {
|
||||
columnName = $(`#${id}`).attr('data-my-column')
|
||||
index = $(`#${id}`).attr('data-my-index')
|
||||
columnValue = $(`#${id}`).val()
|
||||
|
||||
$.get(`php/server/dbHelper.php?action=update&dbtable=Plugins_Objects&columnName=Index&id=${index}&columns=UserData&values=${columnValue}`, function(data) {
|
||||
|
||||
// var result = JSON.parse(data);
|
||||
console.log(data)
|
||||
|
||||
if(sanitize(data) == 'OK')
|
||||
{
|
||||
showMessage('<?= lang('Gen_DataUpdatedUITakesTime');?>')
|
||||
// Remove navigation prompt "Are you sure you want to leave..."
|
||||
window.onbeforeunload = null;
|
||||
} else
|
||||
{
|
||||
showMessage('<?= lang('Gen_LockedDB');?>')
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Get translated string
|
||||
function localize (obj, key) {
|
||||
|
||||
currLangCode = getCookie("language")
|
||||
|
||||
result = ""
|
||||
en_us = ""
|
||||
|
||||
if(obj.localized && obj.localized.includes(key))
|
||||
{
|
||||
for(i=0;i<obj[key].length;i++)
|
||||
{
|
||||
code = obj[key][i]["language_code"]
|
||||
|
||||
// console.log(code)
|
||||
|
||||
if( code == 'en_us')
|
||||
{
|
||||
en_us = obj[key][i]["string"]
|
||||
}
|
||||
|
||||
if(code == currLangCode)
|
||||
{
|
||||
result = obj[key][i]["string"]
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
result == "" ? en_us : result ;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
pluginDefinitions = []
|
||||
pluginUnprocessedEvents = []
|
||||
pluginObjects = []
|
||||
pluginHistory = []
|
||||
|
||||
function getData(){
|
||||
|
||||
$.get('api/plugins.json', function(res) {
|
||||
|
||||
pluginDefinitions = res["data"];
|
||||
|
||||
$.get('api/table_plugins_events.json', function(res) {
|
||||
|
||||
pluginUnprocessedEvents = res["data"];
|
||||
|
||||
$.get('api/table_plugins_objects.json', function(res) {
|
||||
|
||||
pluginObjects = res["data"];
|
||||
|
||||
$.get('api/table_plugins_history.json', function(res) {
|
||||
|
||||
pluginHistory = res["data"];
|
||||
|
||||
generateTabs()
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function generateTabs()
|
||||
{
|
||||
activetab = 'active'
|
||||
|
||||
$.each(pluginDefinitions, function(index, obj) {
|
||||
$('#tabs-location').append(
|
||||
`<li class=" ${activetab}">
|
||||
<a href="#${obj.unique_prefix}" data-plugin-prefix="${obj.unique_prefix}" id="${obj.unique_prefix}_id" data-toggle="tab" >
|
||||
${localize(obj, 'icon')} ${localize(obj, 'display_name')}
|
||||
</a>
|
||||
</li>`
|
||||
);
|
||||
activetab = '' // only first tab is active
|
||||
});
|
||||
|
||||
activetab = 'active'
|
||||
|
||||
$.each(pluginDefinitions, function(index, obj) {
|
||||
|
||||
headersHtml = ""
|
||||
colDefinitions = []
|
||||
evRows = ""
|
||||
obRows = ""
|
||||
hiRows = ""
|
||||
|
||||
// Generate the header
|
||||
$.each(obj["database_column_definitions"], function(index, colDef){
|
||||
if(colDef.show == true) // select only the ones to show
|
||||
{
|
||||
colDefinitions.push(colDef)
|
||||
headersHtml += `<th class="${colDef.css_classes}" >${localize(colDef, "name" )}</th>`
|
||||
}
|
||||
});
|
||||
|
||||
// Generate the event rows
|
||||
var eveCount = 0;
|
||||
for(i=0;i<pluginUnprocessedEvents.length;i++)
|
||||
{
|
||||
if(pluginUnprocessedEvents[i].Plugin == obj.unique_prefix)
|
||||
{
|
||||
clm = ""
|
||||
|
||||
for(j=0;j<colDefinitions.length;j++)
|
||||
{
|
||||
clm += '<td>'+ pluginUnprocessedEvents[i][colDefinitions[j].column] +'</td>'
|
||||
}
|
||||
evRows += `<tr data-my-index="${pluginUnprocessedEvents[i]["Index"]}" >${clm}</tr>`
|
||||
eveCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the history rows
|
||||
var histCount = 0
|
||||
var histCountDisplayed = 0
|
||||
|
||||
for(i=pluginHistory.length-1;i >= 0;i--) // from latest to the oldest
|
||||
{
|
||||
if(pluginHistory[i].Plugin == obj.unique_prefix)
|
||||
{
|
||||
if(histCount < 50) // only display 50 entries to optimize performance
|
||||
{
|
||||
clm = ""
|
||||
|
||||
for(j=0;j<colDefinitions.length;j++)
|
||||
{
|
||||
clm += '<td>'+ pluginHistory[i][colDefinitions[j].column] +'</td>'
|
||||
}
|
||||
hiRows += `<tr data-my-index="${pluginHistory[i]["Index"]}" >${clm}</tr>`
|
||||
|
||||
histCountDisplayed++;
|
||||
}
|
||||
histCount++; // count and display the total
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the object rows
|
||||
var obCount = 0;
|
||||
for(var i=0;i<pluginObjects.length;i++)
|
||||
{
|
||||
if(pluginObjects[i].Plugin == obj.unique_prefix)
|
||||
{
|
||||
clm = ""
|
||||
|
||||
for(var j=0;j<colDefinitions.length;j++)
|
||||
{
|
||||
clm += '<td>'+ getFormControl(colDefinitions[j], pluginObjects[i][colDefinitions[j].column], pluginObjects[i]["Index"]) +'</td>'
|
||||
}
|
||||
obRows += `<tr data-my-index="${pluginObjects[i]["Index"]}" >${clm}</tr>`
|
||||
obCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$('#tabs-content-location').append(
|
||||
`
|
||||
<div id="${obj.unique_prefix}" class="tab-pane ${activetab}">
|
||||
<div class="nav-tabs-custom" style="margin-bottom: 0px">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active" >
|
||||
<a href="#objectsTarget_${obj.unique_prefix}" data-toggle="tab" >
|
||||
|
||||
<i class="fa fa-cube"></i> <?= lang('Plugins_Objects');?> (${obCount})
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="#eventsTarget_${obj.unique_prefix}" data-toggle="tab" >
|
||||
|
||||
<i class="fa fa-bolt"></i> <?= lang('Plugins_Unprocessed_Events');?> (${eveCount})
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="#historyTarget_${obj.unique_prefix}" data-toggle="tab" >
|
||||
|
||||
<i class="fa fa-clock"></i> <?= lang('Plugins_History');?> (${histCountDisplayed} out of ${histCount} )
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div id="objectsTarget_${obj.unique_prefix}" class="tab-pane ${activetab}">
|
||||
<table class="table table-striped" data-my-dbtable="Plugins_Objects">
|
||||
<tbody>
|
||||
<tr>
|
||||
${headersHtml}
|
||||
</tr>
|
||||
${obRows}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="plugin-obj-purge">
|
||||
<button class="btn btn-primary" onclick="purgeAll('${obj.unique_prefix}', 'Plugins_Objects' )"><?= lang('Gen_DeleteAll');?></button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="eventsTarget_${obj.unique_prefix}" class="tab-pane">
|
||||
<table class="table table-striped" data-my-dbtable="Plugins_Events">
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
${headersHtml}
|
||||
</tr>
|
||||
${evRows}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="plugin-obj-purge">
|
||||
<button class="btn btn-primary" onclick="purgeAll('${obj.unique_prefix}', 'Plugins_Events' )"><?= lang('Gen_DeleteAll');?></button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="historyTarget_${obj.unique_prefix}" class="tab-pane">
|
||||
<table class="table table-striped" data-my-dbtable="Plugins_History">
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
${headersHtml}
|
||||
</tr>
|
||||
${hiRows}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="plugin-obj-purge">
|
||||
<button class="btn btn-primary" onclick="purgeAll('${obj.unique_prefix}', 'Plugins_History' )"><?= lang('Gen_DeleteAll');?></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class='plugins-description'>
|
||||
|
||||
${localize(obj, 'description')}
|
||||
|
||||
<span>
|
||||
<a href="https://github.com/jokob-sk/Pi.Alert/tree/main/front/plugins/${obj.code_name}" target="_blank"><?= lang('Gen_Help');?></a>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
|
||||
activetab = '' // only first tab is active
|
||||
});
|
||||
|
||||
initTabs()
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// handle first tab (objectsTarget_) display
|
||||
function initTabs()
|
||||
{
|
||||
// events on tab change
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
var target = $(e.target).attr("href") // activated tab
|
||||
|
||||
// save the last prefix
|
||||
if(target.includes('_') == false )
|
||||
{
|
||||
pref = target.split('#')[1]
|
||||
} else
|
||||
{
|
||||
pref = target.split('_')[1]
|
||||
}
|
||||
|
||||
everythingHidden = false;
|
||||
|
||||
if($('#objectsTarget_'+ pref) != undefined && $('#historyTarget_'+ pref) != undefined && $('#eventsTarget_'+ pref) != undefined)
|
||||
{
|
||||
everythingHidden = $('#objectsTarget_'+ pref).attr('class').includes('active') == false && $('#historyTarget_'+ pref).attr('class').includes('active') == false && $('#eventsTarget_'+ pref).attr('class').includes('active') == false;
|
||||
}
|
||||
|
||||
// show the objectsTarget if no specific pane selected or if selected is hidden
|
||||
if((target == '#'+pref ) && everythingHidden)
|
||||
{
|
||||
var classTmp = $('#objectsTarget_'+ pref).attr('class');
|
||||
|
||||
if($('#objectsTarget_'+ pref).attr('class').includes('active') == false)
|
||||
{
|
||||
classTmp += ' active';
|
||||
$('#objectsTarget_'+ pref).attr('class', classTmp)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
plugPrefix = ''
|
||||
dbTable = ''
|
||||
|
||||
function purgeAll(callback) {
|
||||
plugPrefix = arguments[0]; // plugin prefix
|
||||
dbTable = arguments[1]; // DB table
|
||||
// Ask
|
||||
showModalWarning('<?= lang('Gen_Purge');?>' + ' ' + plugPrefix + ' ' + dbTable , '<?= lang('Gen_AreYouSure');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', "purgeAllExecute");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
function purgeAllExecute() {
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: "php/server/dbHelper.php",
|
||||
data: { action: "delete", dbtable: dbTable, columnName: 'Plugin', id:plugPrefix },
|
||||
success: function(data, textStatus) {
|
||||
showModalOk ('Result', data );
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
function purgeVisible() {
|
||||
|
||||
idArr = $(`#${plugPrefix} table[data-my-dbtable="${dbTable}"] tr[data-my-index]`).map(function(){return $(this).attr("data-my-index");}).get();
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: "php/server/dbHelper.php",
|
||||
data: { action: "delete", dbtable: dbTable, columnName: 'Index', id:idArr.toString() },
|
||||
success: function(data, textStatus) {
|
||||
showModalOk ('Result', data );
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
getData()
|
||||
|
||||
</script>
|
||||
|
||||
<?php
|
||||
require 'php/templates/footer.php';
|
||||
?>
|
||||
|
||||
448
front/plugins/README.md
Executable file
@@ -0,0 +1,448 @@
|
||||
# ⚠ Disclaimer
|
||||
|
||||
Highly experimental feature. Follow the below very carefully and check example plugin(s). Plugin UI is not my priority right now, happy to approve PRs if you are interested in extending/improvintg the UI experience (e.g. making the tables sortable/filterable).
|
||||
|
||||
## ❗ Known issues:
|
||||
|
||||
These issues will be hopefully fixed with time, so please don't report them. Instead, if you know how, feel free to investigate and submit a PR to fix the below. Keep the PRs small as it's easier to approve them:
|
||||
|
||||
* Existing plugin objects sometimes not interpreted correctly and a new object is created instead, resulting in duplicate entries.
|
||||
* Occasional (experienced twice) hanging of processing plugin script file.
|
||||
* UI displaying outdated values until the API endpoints get refreshed.
|
||||
|
||||
## Overview
|
||||
|
||||
PiAlert comes with a plugin system to feed events from third-party scripts into the UI and then send notifications, if desired. The highlighted functionality this plugin system supports, is dynamic creation of a simple UI to interact with the discovered objects, a mechanism to surface settings of plugins in the UI, or to import objects into existing PiAlert database tables. (Currently update/overwriting of existing objects is not supported.)
|
||||
|
||||
Example use cases for plugins could be:
|
||||
|
||||
* Monitor a web service and alert me if it's down
|
||||
* Import devices from dhcp.leases files instead/complementary to using PiHole or arp-scans
|
||||
* Creating ad-hoc UI tables from existing data in the PiAlert database, e.g. to show all open ports on devices, to list devices that disconnected in the last hour, etc.
|
||||
* Using other device discovery methods on the network and importing the data as new devices
|
||||
* Creating a script to create FAKE devices based on user input via custom settings
|
||||
* ...at this point the limitation is mostly the creativity than the capability (there might be edge cases and need to support more form controls for user input off custom settings, but you probably get the idea)
|
||||
|
||||
If you wish to develop a plugin, please check the existing plugin structure. Once the settings are saved by the user they need to be removed from the `pialert.conf` file manually if you want to re-initialize them from the `config.json` of the plugin.
|
||||
|
||||
Again, please read the below carefully if you'd like to contribute with a plugin yourself. This documentation file might be outdated, so double check the sample plugins as well.
|
||||
|
||||
## Plugin file structure overview
|
||||
|
||||
> Folder name must be the same as the code name value in: `"code_name": "<value>"`
|
||||
> Unique prefix needs to be unique compared to the other settings prefixes, e.g.: the prefix `APPRISE` is already in use.
|
||||
|
||||
| File | Required | Description |
|
||||
|----------------------|----------------------|----------------------|
|
||||
| `config.json` | yes | Contains the plugin configuration (manifest) including the settings available to the user. |
|
||||
| `script.py` | yes (script) | The Python script itself |
|
||||
| `last_result.log` | yes (script) | The file used to interface between PiAlert and the plugin (script). |
|
||||
| `script.log` | no | Logging output (recommended) |
|
||||
| `README.md` | no | Any setup considerations or overview (recommended) |
|
||||
|
||||
More on specifics below.
|
||||
|
||||
### Column order and values
|
||||
|
||||
| Order | Represented Column | Required | Description |
|
||||
|----------------------|----------------------|----------------------|----------------------|
|
||||
| 0 | `Object_PrimaryID` | yes | The primary ID used to group Events under. |
|
||||
| 1 | `Object_SecondaryID` | no | Optional secondary ID to create a relationship beween other entities, such as a MAC address |
|
||||
| 2 | `DateTime` | yes | When the event occured in the format `2023-01-02 15:56:30` |
|
||||
| 3 | `Watched_Value1` | yes | A value that is watched and users can receive notifications if it changed compared to the previously saved entry. For example IP address |
|
||||
| 4 | `Watched_Value2` | no | As above |
|
||||
| 5 | `Watched_Value3` | no | As above |
|
||||
| 6 | `Watched_Value4` | no | As above |
|
||||
| 7 | `Extra` | no | Any other data you want to pass and display in PiAlert and the notifications |
|
||||
| 8 | `ForeignKey` | no | A foreign key that can be used to link to the parent object (usually a MAC address) |
|
||||
|
||||
|
||||
# config.json structure
|
||||
|
||||
## Supported data sources
|
||||
|
||||
Currently only two data sources are supported:
|
||||
|
||||
- Script
|
||||
- SQL query on the PiAlert database
|
||||
|
||||
You need to set the `data_source` to either `pialert-db-query` or `python-script`:
|
||||
|
||||
```json
|
||||
"data_source": "pialert-db-query"
|
||||
```
|
||||
Any of the above datasources have to return a "table" of the exact structure as outlined above.
|
||||
|
||||
### "data_source": "python-script"
|
||||
|
||||
If the datasource is set to `python-script` the `CMD` setting (that you specify in the `settings` array section in the `config.json`) needs to contain a executable linux command, that generates a `last_result.log` file. This file needs to be stored in the same folder as the plugin.
|
||||
|
||||
The content of the `last_result.log` file needs to contain the columns as defined in the "Column order and values" section above. The order of columns can't be changed. After every scan it should contain only the results from the latest scan/execution.
|
||||
|
||||
- The format of the `last_result.log` is a `csv`-like file with the pipe `|` as a separator.
|
||||
- 9 (nine) values need to be supplied, so every line needs to contain 8 pipe separators. Empty values are represented by `null`.
|
||||
- Don't render "headers" for these "columns".
|
||||
- Every scan result / event entry needs to be on a new line.
|
||||
- You can find which "columns" need to be present, and if the value is required or optional, in the "Column order and values" section.
|
||||
- The order of these "columns" can't be changed.
|
||||
|
||||
#### Examples
|
||||
|
||||
Valid CSV:
|
||||
|
||||
```csv
|
||||
|
||||
https://www.google.com|null|2023-01-02 15:56:30|200|0.7898|null|null|null|null
|
||||
https://www.duckduckgo.com|192.168.0.1|2023-01-02 15:56:30|200|0.9898|null|null|Best search engine|ff:ee:ff:11:ff:11
|
||||
|
||||
```
|
||||
|
||||
Invalid CSV with different errors on each line:
|
||||
|
||||
```csv
|
||||
|
||||
https://www.google.com|null|2023-01-02 15:56:30|200|0.7898||null|null|null
|
||||
https://www.duckduckgo.com|null|2023-01-02 15:56:30|200|0.9898|null|null|Best search engine|
|
||||
|https://www.duckduckgo.com|null|2023-01-02 15:56:30|200|0.9898|null|null|Best search engine|null
|
||||
null|192.168.1.1|2023-01-02 15:56:30|200|0.9898|null|null|Best search engine
|
||||
https://www.duckduckgo.com|192.168.1.1|2023-01-02 15:56:30|null|0.9898|null|null|Best search engine
|
||||
https://www.google.com|null|2023-01-02 15:56:30|200|0.7898|||
|
||||
https://www.google.com|null|2023-01-02 15:56:30|200|0.7898|
|
||||
|
||||
```
|
||||
|
||||
### "data_source": "pialert-db-query"
|
||||
|
||||
If the datasource is set to `pialert-db-query` the `CMD` setting needs to contain a SQL query rendering the columns as defined in the "Column order and values" section above. The order of columns is important.
|
||||
|
||||
#### Examples
|
||||
|
||||
SQL query example:
|
||||
|
||||
```SQL
|
||||
SELECT dv.dev_Name as Object_PrimaryID,
|
||||
cast(dv.dev_LastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID,
|
||||
datetime() as DateTime,
|
||||
ns.Service as Watched_Value1,
|
||||
ns.State as Watched_Value2,
|
||||
'null' as Watched_Value3,
|
||||
'null' as Watched_Value4,
|
||||
ns.Extra as Extra,
|
||||
dv.dev_MAC as ForeignKey
|
||||
FROM
|
||||
(SELECT * FROM Nmap_Scan) ns
|
||||
LEFT JOIN
|
||||
(SELECT dev_Name, dev_MAC, dev_LastIP FROM Devices) dv
|
||||
ON ns.MAC = dv.dev_MAC
|
||||
```
|
||||
|
||||
Required `CMD` setting example with above query (you can set `"type": "label"` if you want it to make uneditable in the UI):
|
||||
|
||||
```json
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"default_value":"SELECT dv.dev_Name as Object_PrimaryID, cast(dv.dev_LastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID, datetime() as DateTime, ns.Service as Watched_Value1, ns.State as Watched_Value2, 'null' as Watched_Value3, 'null' as Watched_Value4, ns.Extra as Extra FROM (SELECT * FROM Nmap_Scan) ns LEFT JOIN (SELECT dev_Name, dev_MAC, dev_LastIP FROM Devices) dv ON ns.MAC = dv.dev_MAC",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "SQL to run"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "This SQL query is used to populate the coresponding UI tables under the Plugins section."
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
### Mapping the plugin results into a database table
|
||||
|
||||
PiAlert will take the results of the plugin execution and insert these results into a database table, if a plugin contains the property `"mapped_to_table"` in the `config.json` root. The mapping of the columns is defined in the `database_column_definitions` array.
|
||||
|
||||
This approach is used to implement the `DHCPLSS` plugin. The script parses all supplied "dhcp.leases" files, get's the results in the generic table format outlined in the "Column order and values" section above and takes individual values and inserts them into the `"DHCP_Leases"` database table in the PiAlert database. All this is achieved by:
|
||||
|
||||
1) Specifying the database table into which the results are inserted by defining `"mapped_to_table": "DHCP_Leases"` in the root of the `config.json` file as shown below:
|
||||
|
||||
```json
|
||||
{
|
||||
"code_name": "dhcp_leases",
|
||||
"unique_prefix": "DHCPLSS",
|
||||
...
|
||||
"data_source": "python-script",
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"mapped_to_table": "DHCP_Leases",
|
||||
...
|
||||
}
|
||||
```
|
||||
2) Defining the target column with the `mapped_to_column` property for individual columns in the `database_column_definitions` array of the `config.json` file. For example in the `DHCPLSS` plugin, I needed to map the value of the `Object_PrimaryID` column returned by the plugin, to the `DHCP_MAC` column in the PiAlert database `DHCP_Leases` table. Notice the `"mapped_to_column": "DHCP_MAC"` key-value pair in the sample below.
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"mapped_to_column": "DHCP_MAC",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "devicemac",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "MAC address"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
3) That's it. PiAlert takes care of the rest. It loops thru the objects discovered by the plugin, takes the results line, by line and inserts them into the database table specified in `"mapped_to_table"`. The columns are translated from the generic plugin columns to the target table via the `"mapped_to_column"` property in the column definitions.
|
||||
|
||||
#### params
|
||||
|
||||
The `params` array in the `config.json` is used to enable the user to change the parameters of the executed script. For example, the user wants to monitor a specific URL.
|
||||
|
||||
##### Example:
|
||||
|
||||
Passing user defined settings to a command. Let's say, you want to have a script, that is called with a user-defined parameter called `urls`:
|
||||
|
||||
```bash
|
||||
root@server# python3 /home/pi/pialert/front/plugins/website_monitor/script.py urls=https://google.com,https://duck.com
|
||||
```
|
||||
|
||||
* You can allow the user to add URLs to a setting with the `function` property set to a custom name, such as `urls_to_check` (this is not a reserved name from the section "Supported settings `function` values" below).
|
||||
* You specify the parameter `urls` in the `params` section of the `config.json` the following way (`WEBMON_` is the plugin prefix automatically added to all the settings):
|
||||
```json
|
||||
{
|
||||
"params" : [
|
||||
{
|
||||
"name" : "urls",
|
||||
"type" : "setting",
|
||||
"value" : "WEBMON_urls_to_check"
|
||||
}]
|
||||
}
|
||||
```
|
||||
* Then you use this setting as an input parameter for your command in the `CMD` setting. Notice `urls={urls}` in the below json:
|
||||
|
||||
```json
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"default_value":"python3 /home/pi/pialert/front/plugins/website_monitor/script.py urls={urls}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Command"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Command to run"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
During script execution, the app will take the command `"python3 /home/pi/pialert/front/plugins/website_monitor/script.py urls={urls}"`, take the `{urls}` wildcard and replace it by with the value from the `WEBMON_urls_to_check` setting. This is because:
|
||||
|
||||
1) The app checks the `params` entries
|
||||
2) It finds `"name" : "urls"`
|
||||
3) Checks the type of the `urls` params and finds `"type" : "setting"`
|
||||
4) Gets the setting name from `"value" : "WEBMON_urls_to_check"`
|
||||
- IMPORTANT: in the `config.json` this setting is identified by `"function":"urls_to_check"`, not `"function":"WEBMON_urls_to_check"`
|
||||
- You can also use a global setting, or a setting from a different plugin
|
||||
5) The app gets the user defined value from the setting with the code name `WEBMON_urls_to_check`
|
||||
- let's say the setting with the code name `WEBMON_urls_to_check` contains 2 values entered by the user:
|
||||
- `WEBMON_urls_to_check=['https://google.com','https://duck.com']`
|
||||
6) The app takes the value from `WEBMON_urls_to_check` and replaces the `{urls}` wildcard in the setting where `"function":"CMD"`, so you go from:
|
||||
- `python3 /home/pi/pialert/front/plugins/website_monitor/script.py urls={urls}`
|
||||
- to
|
||||
- `python3 /home/pi/pialert/front/plugins/website_monitor/script.py urls=https://google.com,https://duck.com`
|
||||
|
||||
Below are some general additional notes, when definig `params`:
|
||||
|
||||
- `"name":"name_value"` - is used as a wildcard replacement in the `CMD` setting value by using curly brackets `{name_value}`. The wildcard is replaced by the result of the `"value" : "param_value"` and `"type":"type_value"` combo configuration below.
|
||||
- `"type":"<sql|setting>"` - is used to specify the type of the params, currently only 2 supported (`sql`,`setting`).
|
||||
- `"type":"sql"` - will execute the SQL query specified in the `value` property. The sql query needs to return only one column. The column is flattened and separated by commas (`,`), e.g: `SELECT dev_MAC from DEVICES` -> `Internet,74:ac:74:ac:74:ac,44:44:74:ac:74:ac`. This is then used to replace the wildcards in the `CMD` setting.
|
||||
- `"type":"setting"` - The setting code name. A combination of the value from `unique_prefix` + `_` + `function` value, or otherwise the code name you can find in the Settings page under the Setting dispaly name, e.g. `SCAN_CYCLE_MINUTES`.
|
||||
- `"value" : "param_value"` - Needs to contain a setting code name or sql query without wildcards.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"params" : [{
|
||||
"name" : "macs",
|
||||
"type" : "sql",
|
||||
"value" : "SELECT dev_MAC from DEVICES"
|
||||
},
|
||||
{
|
||||
"name" : "urls",
|
||||
"type" : "setting",
|
||||
"value" : "WEBMON_urls_to_check"
|
||||
},
|
||||
{
|
||||
"name" : "internet_ip",
|
||||
"type" : "setting",
|
||||
"value" : "WEBMON_SQL_internet_ip"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### Setting object struncture
|
||||
|
||||
- `"function": "<see Supported settings function values>"` - What function the setting drives or a simple unique code name
|
||||
- `"type": "<text|integer|boolean|password|readonly|selectinteger|selecttext|multiselect|list>"` - The form control used for the setting displayed in the Settings page and what values are accepted.
|
||||
- `"localized"` - a list of properties on the current JSON level which need to be localized
|
||||
- `"name"` and `"description"` - Displayed in the Settings page. An array of localized strings. (see Localized strings below).
|
||||
|
||||
##### Supported settings `function` values
|
||||
|
||||
You can have any `"function": "my_custom_name"` custom name, however, the ones listed below have a specific functionality attached to them. If you use a custom name, then the setting is mostly used as an input parameter for the `params` section.
|
||||
|
||||
- `RUN` - (required) Specifies when the service is executed
|
||||
- Supported Options: "disabled", "once", "schedule" (if included then a `RUN_SCHD` setting needs to be specified), "always_after_scan", "on_new_device"
|
||||
- `RUN_SCHD` - (required if you include the above `RUN` function) Cron-like scheduling used if the `RUN` setting set to `schedule`
|
||||
- `CMD` - (required) What command should be executed.
|
||||
- `API_SQL` - (optional) Generates a `table_` + code_name + `.json` file as per [API docs](https://github.com/jokob-sk/Pi.Alert/blob/main/docs/API.md).
|
||||
- `RUN_TIMEOUT` - (optional) Max execution time of the script. If not specified a default value of 10 seconds is used to prevent hanging.
|
||||
- `WATCH` - (optional) Which database columns are watched for changes for this particular plugin. If not specified no notifications are sent.
|
||||
- `REPORT_ON` - (optional) Send a notification only on these statuses. Supported options are:
|
||||
- `new` means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered.
|
||||
- `watched-changed` - means that selected `Watched_ValueN` columns changed
|
||||
- `watched-not-changed` - reports even on events where selected `Watched_ValueN` did not change
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"function": "RUN",
|
||||
"type": "selecttext",
|
||||
"default_value":"disabled",
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan", "on_new_device"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "When to run"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Enable a regular scan of your services. If you select <code>schedule</code> the scheduling settings from below are applied. If you select <code>once</code> the scan is run only once on start of the application (container) for the time specified in <a href=\"#WEBMON_RUN_TIMEOUT\"><code>WEBMON_RUN_TIMEOUT</code> setting</a>."
|
||||
}]
|
||||
}
|
||||
```
|
||||
##### Localized strings
|
||||
|
||||
- `"language_code":"<en_us|es_es|de_de>"` - code name of the language string. Only these three currently supported. At least the `"language_code":"en_us"` variant has to be defined.
|
||||
- `"string"` - The string to be displayed in the given language.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
|
||||
{
|
||||
"language_code":"en_us",
|
||||
"string" : "When to run"
|
||||
}
|
||||
|
||||
```
|
||||
##### UI settings in database_column_definitions
|
||||
|
||||
The UI will adjust how columns are displayed in the UI based on the definition of the `database_column_definitions` object. Thease are the supported form controls and related functionality:
|
||||
|
||||
- Only columns with `"show": true` and also with at least an English translation will be shown in the UI.
|
||||
- Supported types: `label`, `text`, `threshold`, `replace`
|
||||
- `label` makes a column display only
|
||||
- `text` makes a column editable
|
||||
- See below for information on `threshold`, `replace`
|
||||
- The `options` property is used in conjunction with these types:
|
||||
- `threshold` - The `options` array contains objects from lowest `maximum` to highest with corresponding `hexColor` used for the value background color if it's less than the specified `maximum`, but more than the previous one in the `options` array
|
||||
- `replace` - The `options` array contains objects with an `equals` property, that is compared to the "value" and if the values are the same, the string in `replacement` is displayed in the UI instead of the actual "value"
|
||||
- `devicemac` - The value is considered to be a mac adress and a link pointing to the device with the given mac address is generated.
|
||||
- `url` - The value is considered to be a url so a link is generated.
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "threshold",
|
||||
"default_value":"",
|
||||
"options": [
|
||||
{
|
||||
"maximum": 199,
|
||||
"hexColor": "#792D86"
|
||||
},
|
||||
{
|
||||
"maximum": 299,
|
||||
"hexColor": "#5B862D"
|
||||
},
|
||||
{
|
||||
"maximum": 399,
|
||||
"hexColor": "#7D862D"
|
||||
},
|
||||
{
|
||||
"maximum": 499,
|
||||
"hexColor": "#BF6440"
|
||||
},
|
||||
{
|
||||
"maximum": 599,
|
||||
"hexColor": "#D33115"
|
||||
}
|
||||
],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Status code"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
"default_value":"",
|
||||
"options": [
|
||||
{
|
||||
"equals": "watched-not-changed",
|
||||
"replacement": "<i class='fa-solid fa-square-check'></i>"
|
||||
},
|
||||
{
|
||||
"equals": "watched-changed",
|
||||
"replacement": "<i class='fa-solid fa-triangle-exclamation'></i>"
|
||||
},
|
||||
{
|
||||
"equals": "new",
|
||||
"replacement": "<i class='fa-solid fa-circle-plus'></i>"
|
||||
}
|
||||
],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Status"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
## Full Examples
|
||||
|
||||
### Script based plugins
|
||||
|
||||
- [website_monitor (WEBMON) config.json](https://github.com/jokob-sk/Pi.Alert/blob/main/front/plugins/website_monitor/config.json)
|
||||
- [dhcp_servers (DHCPSRVS) config.json](https://github.com/jokob-sk/Pi.Alert/blob/main/front/plugins/dhcp_servers/config.json)
|
||||
- [dhcp_leases (DHCPLSS) config.json](https://github.com/jokob-sk/Pi.Alert/blob/main/front/plugins/dhcp_leases/config.json)
|
||||
- [unifi_import (UNFIMP) config.json](https://github.com/jokob-sk/Pi.Alert/blob/main/front/plugins/unifi_import/config.json)
|
||||
|
||||
### SQL query based plugins
|
||||
- [nmap_services (NMAPSERV) config.json](https://github.com/jokob-sk/Pi.Alert/blob/main/front/plugins/nmap_services/config.json)
|
||||
|
||||
### Screenshots
|
||||
|
||||
| ![Screen 1][screen1] | ![Screen 2][screen2] |
|
||||
|----------------------|----------------------|
|
||||
| ![Screen 3][screen3] | ![Screen 4][screen4] |
|
||||
|
||||
[screen1]: https://raw.githubusercontent.com/jokob-sk/Pi.Alert/main/docs/img/plugins.png "Screen 1"
|
||||
[screen2]: https://raw.githubusercontent.com/jokob-sk/Pi.Alert/main/docs/img/plugins_settings.png "Screen 2"
|
||||
[screen3]: https://raw.githubusercontent.com/jokob-sk/Pi.Alert/main/docs/img/plugins_json_settings.png "Screen 3"
|
||||
[screen4]: https://raw.githubusercontent.com/jokob-sk/Pi.Alert/main/docs/img/plugins_json_ui.png "Screen 4"
|
||||
32
front/plugins/dhcp_leases/README.md
Executable file
@@ -0,0 +1,32 @@
|
||||
## Overview
|
||||
|
||||
A plugin allowing for importing devices from DHCP.leases files.
|
||||
|
||||
### Usage
|
||||
|
||||
- Specify full paths of all `dhcp.leases` files you want to import and watch in the `DHCPLSS_paths_to_check`setting.
|
||||
- Map the paths specified in the `DHCPLSS_paths_to_check`setting in your `docker-compose.yml` file.
|
||||
|
||||
#### Example:
|
||||
|
||||
|
||||
`docker-compose.yml` excerpt:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
...
|
||||
# mapping different dhcp.leases files
|
||||
- /first/location/dhcp.leases:/mnt/dhcp1.leases
|
||||
- /second/location/dhcp.leases:/mnt/dhcp2.leases
|
||||
...
|
||||
```
|
||||
|
||||
`DHCPLSS_paths_to_check` Setting:
|
||||
|
||||
```python
|
||||
DHCPLSS_paths_to_check = ['/mnt/dhcp1.leases','/mnt/dhcp2.leases']
|
||||
```
|
||||
|
||||
### Notes
|
||||
|
||||
- No specific configuration needed.
|
||||
327
front/plugins/dhcp_leases/config.json
Executable file
@@ -0,0 +1,327 @@
|
||||
{
|
||||
"code_name": "dhcp_leases",
|
||||
"unique_prefix": "DHCPLSS",
|
||||
"enabled": true,
|
||||
"data_source": "python-script",
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"mapped_to_table": "DHCP_Leases",
|
||||
"display_name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "DHCP Leases"
|
||||
}],
|
||||
"icon":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "<i class=\"fa-solid fa-hourglass-half\"></i>"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "This plugin is to import devices from dhcp.leases files."
|
||||
}],
|
||||
"params" : [
|
||||
{
|
||||
"name" : "paths",
|
||||
"type" : "setting",
|
||||
"value" : "DHCPLSS_paths_to_check"
|
||||
}],
|
||||
"database_column_definitions":
|
||||
[
|
||||
{
|
||||
"column": "Index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"mapped_to_column": "DHCP_MAC",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "devicemac",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "MAC address"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"mapped_to_column": "DHCP_IP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "deviceip",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "IP"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Created"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"mapped_to_column": "DHCP_DateTime",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Changed"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Is active"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"mapped_to_column": "DHCP_Name",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Hostname"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Hardware"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "State"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "UserData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textboxsave",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Comments"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "DHCP leases file"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
"default_value":"",
|
||||
"options": [
|
||||
{
|
||||
"equals": "watched-not-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-square-check'></i><div></div>"
|
||||
},
|
||||
{
|
||||
"equals": "watched-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-triangle-exclamation'></i></div>"
|
||||
},
|
||||
{
|
||||
"equals": "new",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-circle-plus'></i></div>"
|
||||
}
|
||||
],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Status"
|
||||
}]
|
||||
}
|
||||
],
|
||||
"settings":[
|
||||
{
|
||||
"function": "RUN",
|
||||
"type": "selecttext",
|
||||
"default_value":"disabled",
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan", "on_new_device"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "When to run"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Enable import of devices from <code>dhcp.leases</code> files. If you select <code>schedule</code> the scheduling settings from below are applied. If you select <code>once</code> the scan is run only once on start of the application (container) or after you update your settings."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"default_value":"python3 /home/pi/pialert/front/plugins/dhcp_leases/script.py paths={paths}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Command"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Command to run"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "paths_to_check",
|
||||
"type": "list",
|
||||
"default_value":["/mnt/dhcp1.leases", "/mnt/dhcp2.leases"],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Files"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Add all dhcp.leases mapped paths to watch. Enter full path within the container, e.g. <code>/mnt/dhcp2.leases</code>. You must map these files accordingly in your <code>docker-compose.yml</code> file."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"default_value":"0 2 * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Schedule"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Only enabled if you select <code>schedule</code> in the <a href=\"#DHCPLSS_RUN\"><code>DHCPLSS_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"default_value":5,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Run timeout"
|
||||
},
|
||||
{
|
||||
"language_code":"de_de",
|
||||
"string" : "Wartezeit"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "multiselect",
|
||||
"default_value":["Watched_Value1", "Watched_Value4"],
|
||||
"options": ["Watched_Value1","Watched_Value2","Watched_Value3","Watched_Value4"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Watched"
|
||||
}] ,
|
||||
"description":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Active </li><li><code>Watched_Value2</code> is Hostname </li><li><code>Watched_Value3</code> is hardware </li><li><code>Watched_Value4</code> is State </li></ul>"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "multiselect",
|
||||
"default_value":["new","watched-changed"],
|
||||
"options": ["new","watched-changed","watched-not-changed"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Report on"
|
||||
}] ,
|
||||
"description":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
116
front/plugins/dhcp_leases/script.py
Executable file
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env python
|
||||
# Based on the work of https://github.com/leiweibau/Pi.Alert
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from time import sleep, time, strftime
|
||||
import requests
|
||||
import pathlib
|
||||
import threading
|
||||
import subprocess
|
||||
import socket
|
||||
import argparse
|
||||
import io
|
||||
import sys
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
import pwd
|
||||
import os
|
||||
from dhcp_leases import DhcpLeases
|
||||
|
||||
curPath = str(pathlib.Path(__file__).parent.resolve())
|
||||
log_file = curPath + '/script.log'
|
||||
last_run = curPath + '/last_result.log'
|
||||
|
||||
print(last_run)
|
||||
|
||||
# Workflow
|
||||
|
||||
def main():
|
||||
|
||||
last_run_logfile = open(last_run, 'a')
|
||||
|
||||
# empty file
|
||||
last_run_logfile.write("")
|
||||
|
||||
parser = argparse.ArgumentParser(description='Import devices from dhcp.leases files')
|
||||
parser.add_argument('paths', action="store", help="absolute dhcp.leases file paths to check separated by ','")
|
||||
values = parser.parse_args()
|
||||
|
||||
# parse output
|
||||
newEntries = []
|
||||
|
||||
if values.paths:
|
||||
for path in values.paths.split('=')[1].split(','):
|
||||
|
||||
|
||||
newEntries = get_entries(newEntries, path)
|
||||
|
||||
|
||||
for e in newEntries:
|
||||
# Insert list into the log
|
||||
service_monitoring_log(e.primaryId, e.secondaryId, e.created, e.watched1, e.watched2, e.watched3, e.watched4, e.extra, e.foreignKey )
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def service_monitoring_log(primaryId, secondaryId, created, watched1, watched2 = '', watched3 = '', watched4 = '', extra ='', foreignKey ='' ):
|
||||
|
||||
if watched1 == '':
|
||||
watched1 = 'null'
|
||||
if watched2 == '':
|
||||
watched2 = 'null'
|
||||
if watched3 == '':
|
||||
watched3 = 'null'
|
||||
if watched4 == '':
|
||||
watched4 = 'null'
|
||||
|
||||
with open(last_run, 'a') as last_run_logfile:
|
||||
# https://www.duckduckgo.com|192.168.0.1|2023-01-02 15:56:30|200|0.9898|null|null|Best search engine|null
|
||||
last_run_logfile.write("{}|{}|{}|{}|{}|{}|{}|{}|{}\n".format(
|
||||
primaryId,
|
||||
secondaryId,
|
||||
created,
|
||||
watched1,
|
||||
watched2,
|
||||
watched3,
|
||||
watched4,
|
||||
extra,
|
||||
foreignKey
|
||||
)
|
||||
)
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_entries(newEntries, path):
|
||||
|
||||
|
||||
leases = DhcpLeases(path)
|
||||
leasesList = leases.get()
|
||||
|
||||
for lease in leasesList:
|
||||
|
||||
tmpPlugObj = plugin_object_class(lease.ethernet, lease.ip, lease.active, lease.hostname, lease.hardware, lease.binding_state, path)
|
||||
|
||||
newEntries.append(tmpPlugObj)
|
||||
|
||||
return newEntries
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
class plugin_object_class:
|
||||
def __init__(self, primaryId = '',secondaryId = '', watched1 = '',watched2 = '',watched3 = '',watched4 = '',extra = '',foreignKey = ''):
|
||||
self.pluginPref = ''
|
||||
self.primaryId = primaryId
|
||||
self.secondaryId = secondaryId
|
||||
self.created = strftime("%Y-%m-%d %H:%M:%S")
|
||||
self.changed = ''
|
||||
self.watched1 = watched1
|
||||
self.watched2 = watched2
|
||||
self.watched3 = watched3
|
||||
self.watched4 = watched4
|
||||
self.status = ''
|
||||
self.extra = extra
|
||||
self.userData = ''
|
||||
self.foreignKey = foreignKey
|
||||
|
||||
#===============================================================================
|
||||
# BEGIN
|
||||
#===============================================================================
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
11
front/plugins/dhcp_servers/README.md
Executable file
@@ -0,0 +1,11 @@
|
||||
## Overview
|
||||
|
||||
A simple sample plugin allowing for detecting rogue DHCP servers on the network.
|
||||
|
||||
### Usage
|
||||
|
||||
- No specific configuration needed.
|
||||
|
||||
### Notes
|
||||
|
||||
- No specific configuration needed.
|
||||
302
front/plugins/dhcp_servers/config.json
Executable file
@@ -0,0 +1,302 @@
|
||||
{
|
||||
"code_name": "dhcp_servers",
|
||||
"unique_prefix": "DHCPSRVS",
|
||||
"enabled": true,
|
||||
"data_source": "python-script",
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"display_name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Rogue DHCP"
|
||||
}],
|
||||
"icon":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "<i class=\"fa-solid fa-skull-crossbones\"></i>"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "This plugin is to use NMAP to monitor for rogue DHCP servers."
|
||||
}],
|
||||
"params" : [],
|
||||
"database_column_definitions":
|
||||
[
|
||||
{
|
||||
"column": "Index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "deviceip",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Server Identifier"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Domain Name"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Created"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Changed"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Domain Name Server"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "IP Offered"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Interface"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Router"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "UserData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "textboxsave",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Comments"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
"default_value":"",
|
||||
"options": [
|
||||
{
|
||||
"equals": "watched-not-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-square-check'></i><div></div>"
|
||||
},
|
||||
{
|
||||
"equals": "watched-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-triangle-exclamation'></i></div>"
|
||||
},
|
||||
{
|
||||
"equals": "new",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-circle-plus'></i></div>"
|
||||
}
|
||||
],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Status"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Extra info"
|
||||
}]
|
||||
}
|
||||
],
|
||||
"settings":[
|
||||
{
|
||||
"function": "RUN",
|
||||
"type": "selecttext",
|
||||
"default_value":"disabled",
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan", "on_new_device"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "When to run"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Enable a regular scan of rogue DHCP servers. If you select <code>schedule</code> the scheduling settings from below are applied. If you select <code>once</code> the scan is run only once on start of the application (container) or after you update your settings."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"default_value":"python3 /home/pi/pialert/front/plugins/dhcp_servers/script.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Command"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Command to run"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"default_value":"0 2 * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Schedule"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Only enabled if you select <code>schedule</code> in the <a href=\"#DHCPSRVS_RUN\"><code>DHCPSRVS_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"default_value":5,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Run timeout"
|
||||
},
|
||||
{
|
||||
"language_code":"de_de",
|
||||
"string" : "Wartezeit"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "multiselect",
|
||||
"default_value":["Watched_Value1"],
|
||||
"options": ["Watched_Value1","Watched_Value2","Watched_Value3","Watched_Value4"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Watched"
|
||||
}] ,
|
||||
"description":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Domain Name Server</li><li><code>Watched_Value2</code> is IP Offered</li><li><code>Watched_Value3</code> is Interface </li><li><code>Watched_Value4</code> is Router </li></ul>"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "multiselect",
|
||||
"default_value":["new","watched-changed"],
|
||||
"options": ["new","watched-changed","watched-not-changed"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Report on"
|
||||
}] ,
|
||||
"description":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
133
front/plugins/dhcp_servers/script.py
Executable file
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env python
|
||||
# Based on the work of https://github.com/leiweibau/Pi.Alert
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from time import sleep, time, strftime
|
||||
import requests
|
||||
import pathlib
|
||||
import threading
|
||||
import subprocess
|
||||
import socket
|
||||
import argparse
|
||||
import io
|
||||
import sys
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
import pwd
|
||||
import os
|
||||
|
||||
curPath = str(pathlib.Path(__file__).parent.resolve())
|
||||
log_file = curPath + '/script.log'
|
||||
last_run = curPath + '/last_result.log'
|
||||
|
||||
print(last_run)
|
||||
|
||||
# Workflow
|
||||
|
||||
def main():
|
||||
|
||||
last_run_logfile = open(last_run, 'a')
|
||||
|
||||
timeoutSec = 10
|
||||
|
||||
nmapArgs = ['sudo', 'nmap', '--script', 'broadcast-dhcp-discover']
|
||||
|
||||
# Execute N probes and insert in list
|
||||
dhcp_probes = 1 # N probes
|
||||
newLines = []
|
||||
newLines.append(strftime("%Y-%m-%d %H:%M:%S"))
|
||||
#dhcp_server_list_time = []
|
||||
for _ in range(dhcp_probes):
|
||||
output = subprocess.check_output (nmapArgs, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(timeoutSec ))
|
||||
newLines = newLines + output.split("\n")
|
||||
|
||||
# parse output
|
||||
newEntries = []
|
||||
|
||||
duration = ""
|
||||
for line in newLines:
|
||||
|
||||
if newEntries is None:
|
||||
index = 0
|
||||
else:
|
||||
index = len(newEntries) - 1
|
||||
|
||||
if 'Response ' in line and ' of ' in line:
|
||||
newEntries.append(plugin_object_class())
|
||||
elif 'Server Identifier' in line :
|
||||
newEntries[index].primaryId = line.split(':')[1].strip()
|
||||
elif 'Domain Name' in line :
|
||||
newEntries[index].secondaryId = line.split(':')[1].strip()
|
||||
elif 'Domain Name Server' in line :
|
||||
newEntries[index].watched1 = line.split(':')[1].strip()
|
||||
elif 'IP Offered' in line :
|
||||
newEntries[index].watched2 = line.split(':')[1].strip()
|
||||
elif 'Interface' in line :
|
||||
newEntries[index].watched3 = line.split(':')[1].strip()
|
||||
elif 'Router' in line :
|
||||
newEntries[index].watched4 = line.split(':')[1].strip()
|
||||
newEntries[index].foreignKey = line.split(':')[1].strip()
|
||||
elif ('IP Address Lease Time' in line or 'Subnet Mask' in line or 'Broadcast Address' in line) :
|
||||
|
||||
newVal = line.split(':')[1].strip()
|
||||
|
||||
if newEntries[index].extra == '':
|
||||
newEntries[index].extra = newVal
|
||||
else:
|
||||
newEntries[index].extra = newEntries[index].extra + ',' + newVal
|
||||
|
||||
|
||||
|
||||
for e in newEntries:
|
||||
# Insert list into the log
|
||||
service_monitoring_log(e.primaryId, e.secondaryId, e.created, e.watched1, e.watched2, e.watched3, e.watched4, e.extra, e.foreignKey )
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def service_monitoring_log(primaryId, secondaryId, created, watched1, watched2 = '', watched3 = '', watched4 = '', extra ='', foreignKey ='' ):
|
||||
|
||||
if watched1 == '':
|
||||
watched1 = 'null'
|
||||
if watched2 == '':
|
||||
watched2 = 'null'
|
||||
if watched3 == '':
|
||||
watched3 = 'null'
|
||||
if watched4 == '':
|
||||
watched4 = 'null'
|
||||
|
||||
with open(last_run, 'a') as last_run_logfile:
|
||||
# https://www.duckduckgo.com|192.168.0.1|2023-01-02 15:56:30|200|0.9898|null|null|Best search engine|null
|
||||
last_run_logfile.write("{}|{}|{}|{}|{}|{}|{}|{}|{}\n".format(
|
||||
primaryId,
|
||||
secondaryId,
|
||||
created,
|
||||
watched1,
|
||||
watched2,
|
||||
watched3,
|
||||
watched4,
|
||||
extra,
|
||||
foreignKey
|
||||
)
|
||||
)
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
class plugin_object_class:
|
||||
def __init__(self, primaryId = '',secondaryId = '', watched1 = '',watched2 = '',watched3 = '',watched4 = '',extra = '',foreignKey = ''):
|
||||
self.pluginPref = ''
|
||||
self.primaryId = primaryId
|
||||
self.secondaryId = secondaryId
|
||||
self.created = strftime("%Y-%m-%d %H:%M:%S")
|
||||
self.changed = ''
|
||||
self.watched1 = watched1
|
||||
self.watched2 = watched2
|
||||
self.watched3 = watched3
|
||||
self.watched4 = watched4
|
||||
self.status = ''
|
||||
self.extra = extra
|
||||
self.userData = ''
|
||||
self.foreignKey = foreignKey
|
||||
|
||||
#===============================================================================
|
||||
# BEGIN
|
||||
#===============================================================================
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
|
||||
11
front/plugins/nmap_services/README.md
Executable file
@@ -0,0 +1,11 @@
|
||||
## Overview
|
||||
|
||||
This plugin shows all Services discovered by regular NMAP scans. It's also a sample plugin showcasing how to use a SQL Query to show existing data from the PiAlert database.
|
||||
|
||||
### Usage
|
||||
|
||||
- The sql query from the `NMAPSRV_CMD` setting is used to create source data for this plugin. Column order and values need to adhere to the ones specified in the [documentation](https://github.com/jokob-sk/Pi.Alert/tree/main/front/plugins).
|
||||
|
||||
### Notes
|
||||
|
||||
- N/A
|
||||
282
front/plugins/nmap_services/config.json
Executable file
@@ -0,0 +1,282 @@
|
||||
{
|
||||
"code_name": "nmap_services",
|
||||
"unique_prefix": "NMAPSRV",
|
||||
"enabled": true,
|
||||
"data_source": "pialert-db-query",
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"display_name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Services (NMAP)"
|
||||
}],
|
||||
"icon":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "<i class=\"fa-solid fa-satellite-dish\"></i>"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "This plugin shows all services discovered by NMAP scans."
|
||||
}],
|
||||
"params" : [],
|
||||
"database_column_definitions":
|
||||
[
|
||||
{
|
||||
"column": "Index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Device name"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "url",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Ip and Port"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Created"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Changed"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Service"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "State"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Extra"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "ForeignKey",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "devicemac",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "MAC"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
"default_value":"",
|
||||
"options": [
|
||||
{
|
||||
"equals": "watched-not-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-square-check'></i><div></div>"
|
||||
},
|
||||
{
|
||||
"equals": "watched-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-triangle-exclamation'></i></div>"
|
||||
},
|
||||
{
|
||||
"equals": "new",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-circle-plus'></i></div>"
|
||||
}
|
||||
],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Status"
|
||||
}]
|
||||
}
|
||||
],
|
||||
"settings":[
|
||||
{
|
||||
"function": "RUN",
|
||||
"type": "selecttext",
|
||||
"default_value":"disabled",
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan", "on_new_device"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "When to run"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Specify when the SQL query is executed."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"default_value":"SELECT dv.dev_Name as Object_PrimaryID, cast('http://' || dv.dev_LastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID, datetime() as DateTime, ns.Service as Watched_Value1, ns.State as Watched_Value2, 'null' as Watched_Value3, 'null' as Watched_Value4, ns.Extra as Extra, dv.dev_MAC as ForeignKey FROM (SELECT * FROM Nmap_Scan) ns LEFT JOIN (SELECT dev_Name, dev_MAC, dev_LastIP FROM Devices) dv ON ns.MAC = dv.dev_MAC",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "SQL to run"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "This SQL query is used to populate the coresponding UI tables under the Plugins section."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"default_value":"0 2 * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Schedule"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Only enabled if you select <code>schedule</code> in the <a href=\"#NMAPSRV_RUN\"><code>NMAPSRV_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "multiselect",
|
||||
"default_value":["Watched_Value1"],
|
||||
"options": ["Watched_Value1","Watched_Value2","Watched_Value3","Watched_Value4"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Watched"
|
||||
}] ,
|
||||
"description":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is service type (e.g.: http, ssh)</li><li><code>Watched_Value2</code> is Status (open or closed)</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> unused </li></ul>"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "multiselect",
|
||||
"default_value":["new","watched-changed"],
|
||||
"options": ["new","watched-changed","watched-not-changed"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Report on"
|
||||
}] ,
|
||||
"description":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
18
front/plugins/unifi_import/README.md
Executable file
@@ -0,0 +1,18 @@
|
||||
## Overview
|
||||
|
||||
A plugin allowing for importing devices from a UniFi controller.
|
||||
|
||||
### Usage
|
||||
|
||||
Spedify the following settings in the Settings section of PiAlert:
|
||||
|
||||
- `UNFIMP_username` - Username used to login into the UNIFI controller.
|
||||
- `UNFIMP_password` - Password used to login into the UNIFI controller.
|
||||
- `UNFIMP_host` - Host url or IP address where the UNIFI controller is hosted (excluding http://)
|
||||
- `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
|
||||
|
||||
### Notes
|
||||
|
||||
- Currently only used to import devices, not their status, type or network map.
|
||||
428
front/plugins/unifi_import/config.json
Executable file
@@ -0,0 +1,428 @@
|
||||
{
|
||||
"code_name": "unifi_import",
|
||||
"unique_prefix": "UNFIMP",
|
||||
"enabled": true,
|
||||
"data_source": "python-script",
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"mapped_to_table": "DHCP_Leases",
|
||||
"display_name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "UniFi import"
|
||||
}],
|
||||
"icon":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "<i class=\"fa-solid fa-upload\"></i>"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "This plugin is used to import devices from an UNIFI controller."
|
||||
}],
|
||||
"params" : [
|
||||
{
|
||||
"name" : "username",
|
||||
"type" : "setting",
|
||||
"value" : "UNFIMP_username"
|
||||
},
|
||||
{
|
||||
"name" : "password",
|
||||
"type" : "setting",
|
||||
"value" : "UNFIMP_password"
|
||||
},
|
||||
{
|
||||
"name" : "host",
|
||||
"type" : "setting",
|
||||
"value" : "UNFIMP_host"
|
||||
},
|
||||
{
|
||||
"name" : "sites",
|
||||
"type" : "setting",
|
||||
"value" : "UNFIMP_sites"
|
||||
},
|
||||
{
|
||||
"name" : "protocol",
|
||||
"type" : "setting",
|
||||
"value" : "UNFIMP_protocol"
|
||||
},
|
||||
{
|
||||
"name" : "port",
|
||||
"type" : "setting",
|
||||
"value" : "UNFIMP_port"
|
||||
}
|
||||
],
|
||||
"database_column_definitions":
|
||||
[
|
||||
{
|
||||
"column": "Index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"mapped_to_column": "DHCP_MAC",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "devicemac",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "MAC address"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"mapped_to_column": "DHCP_IP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "deviceip",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "IP"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Created"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"mapped_to_column": "DHCP_DateTime",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Changed"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"mapped_to_column": "DHCP_Name",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Hostname"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Vendor"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Type"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Network"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "UserData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textboxsave",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Comments"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Hostname"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
"default_value":"",
|
||||
"options": [
|
||||
{
|
||||
"equals": "watched-not-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-square-check'></i><div></div>"
|
||||
},
|
||||
{
|
||||
"equals": "watched-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-triangle-exclamation'></i></div>"
|
||||
},
|
||||
{
|
||||
"equals": "new",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-circle-plus'></i></div>"
|
||||
}
|
||||
],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Status"
|
||||
}]
|
||||
}
|
||||
],
|
||||
"settings":[
|
||||
{
|
||||
"function": "RUN",
|
||||
"type": "selecttext",
|
||||
"default_value":"disabled",
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan", "on_new_device"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "When to run"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Enable import of devices from a UNIFI controller. If you select <code>schedule</code> the scheduling settings from below are applied. If you select <code>once</code> the scan is run only once on start of the application (container) or after you update your settings."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"default_value":"python3 /home/pi/pialert/front/plugins/unifi_import/script.py username={username} password={password} host={host} sites={sites} protocol={protocol} port={port}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Command"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Command to run. Not recommended to change."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "username",
|
||||
"type": "text",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Username"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "The username used to login into your UNIFI controller. It is recommended to create a read-only user account."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "password",
|
||||
"type": "password",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Password"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "The password used to login into your UNIFI controller."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "protocol",
|
||||
"type": "selecttext",
|
||||
"default_value":"https://",
|
||||
"options": ["https://", "http://"],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Protocol"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "The protocol to use to access the controller."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "host",
|
||||
"type": "text",
|
||||
"default_value":"192.168.1.1",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Host"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "The host (IP) where the UNIFI controller is runnig. Do NOT include the protocol (e.g. <code>https://</code>)"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "port",
|
||||
"type": "text",
|
||||
"default_value":"8443",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Port number"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "The port number where the UNIFI controller is runnig. Usually it is <code>8443</code>."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "sites",
|
||||
"type": "list",
|
||||
"default_value":["default"],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "UNIFI sites"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "The sites you want to connect to. Usually it is only one and the name is <code>default</code>. Check the URL in your UniFi controller UI if unsure."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"default_value":"0 2 * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Schedule"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Only enabled if you select <code>schedule</code> in the <a href=\"#DHCPLSS_RUN\"><code>DHCPLSS_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"default_value":5,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Run timeout"
|
||||
},
|
||||
{
|
||||
"language_code":"de_de",
|
||||
"string" : "Wartezeit"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "multiselect",
|
||||
"default_value":["Watched_Value1", "Watched_Value4"],
|
||||
"options": ["Watched_Value1","Watched_Value2","Watched_Value3","Watched_Value4"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Watched"
|
||||
}] ,
|
||||
"description":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Hostname </li><li><code>Watched_Value2</code> is Vendor </li><li><code>Watched_Value3</code> is Type </li><li><code>Watched_Value4</code> is Network </li></ul>"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "multiselect",
|
||||
"default_value":["new","watched-changed"],
|
||||
"options": ["new","watched-changed","watched-not-changed"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Report on"
|
||||
}] ,
|
||||
"description":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
243
front/plugins/unifi_import/script.py
Executable file
@@ -0,0 +1,243 @@
|
||||
#!/usr/bin/env python
|
||||
# Inspired by https://github.com/stevehoek/Pi.Alert
|
||||
|
||||
# Example call
|
||||
# python3 /home/pi/pialert/front/plugins/unifi_import/script.py username=pialert password=passw0rd host=192.168.1.1 site=default protocol=https:// port=8443
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from time import sleep, time, strftime
|
||||
import requests
|
||||
from requests import Request, Session, packages
|
||||
import pathlib
|
||||
import threading
|
||||
import subprocess
|
||||
import socket
|
||||
import json
|
||||
import argparse
|
||||
import io
|
||||
import sys
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
import pwd
|
||||
import os
|
||||
from pyunifi.controller import Controller
|
||||
|
||||
|
||||
curPath = str(pathlib.Path(__file__).parent.resolve())
|
||||
log_file = curPath + '/script.log'
|
||||
last_run = curPath + '/last_result.log'
|
||||
|
||||
# Workflow
|
||||
|
||||
def main():
|
||||
|
||||
# init global variables
|
||||
global UNIFI_USERNAME, UNIFI_PASSWORD, UNIFI_HOST
|
||||
global UNIFI_SITES, PORT, PROTOCOL
|
||||
|
||||
last_run_logfile = open(last_run, 'a')
|
||||
|
||||
# empty file
|
||||
last_run_logfile.write("")
|
||||
|
||||
parser = argparse.ArgumentParser(description='Import devices from an UNIFI controller')
|
||||
|
||||
parser.add_argument('username', action="store", help="Username used to login into the UNIFI controller")
|
||||
parser.add_argument('password', action="store", help="Password used to login into the UNIFI controller")
|
||||
parser.add_argument('host', action="store", help="Host url or IP address where the UNIFI controller is hosted (excluding http://)")
|
||||
parser.add_argument('sites', action="store", help="Name of the sites (usually 'default', check the URL in your UniFi controller UI). Separated by comma (,) if passing multiple sites")
|
||||
parser.add_argument('protocol', action="store", help="https:// or http://")
|
||||
parser.add_argument('port', action="store", help="Usually 8443")
|
||||
|
||||
values = parser.parse_args()
|
||||
|
||||
# parse output
|
||||
newEntries = []
|
||||
|
||||
if values.username and values.password and values.host and values.sites:
|
||||
|
||||
UNIFI_USERNAME = values.username.split('=')[1]
|
||||
UNIFI_PASSWORD = values.password.split('=')[1]
|
||||
UNIFI_HOST = values.host.split('=')[1]
|
||||
UNIFI_SITES = values.sites.split('=')[1]
|
||||
PROTOCOL = values.protocol.split('=')[1]
|
||||
PORT = values.port.split('=')[1]
|
||||
|
||||
newEntries = get_entries(newEntries)
|
||||
|
||||
|
||||
for e in newEntries:
|
||||
# Insert list into the log
|
||||
service_monitoring_log(e.primaryId, e.secondaryId, e.created, e.watched1, e.watched2, e.watched3, e.watched4, e.extra, e.foreignKey )
|
||||
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_entries(newEntries):
|
||||
|
||||
sites = []
|
||||
|
||||
if ',' in UNIFI_SITES:
|
||||
sites = UNIFI_SITES.split(',')
|
||||
|
||||
else:
|
||||
sites.append(UNIFI_SITES)
|
||||
|
||||
|
||||
for site in sites:
|
||||
|
||||
c = Controller(UNIFI_HOST, UNIFI_USERNAME, UNIFI_PASSWORD, ssl_verify=False, site_id=site )
|
||||
|
||||
for ap in c.get_aps():
|
||||
|
||||
# print(f'{json.dumps(ap)}')
|
||||
|
||||
deviceType = ''
|
||||
if (ap['type'] == 'udm'):
|
||||
deviceType = 'Router'
|
||||
elif (ap['type'] == 'usg'):
|
||||
deviceType = 'Router'
|
||||
elif (ap['type'] == 'usw'):
|
||||
deviceType = 'Switch'
|
||||
elif (ap['type'] == 'uap'):
|
||||
deviceType = 'AP'
|
||||
|
||||
name = get_unifi_val(ap, 'name')
|
||||
hostName = get_unifi_val(ap, 'hostname')
|
||||
|
||||
if name == 'null' and hostName != 'null':
|
||||
name = hostName
|
||||
|
||||
tmpPlugObj = plugin_object_class(
|
||||
ap['mac'],
|
||||
get_unifi_val(ap, 'ip'),
|
||||
name,
|
||||
'Ubiquiti Networks Inc.',
|
||||
deviceType,
|
||||
ap['state'],
|
||||
get_unifi_val(ap, 'connection_network_name')
|
||||
)
|
||||
|
||||
newEntries.append(tmpPlugObj)
|
||||
|
||||
# print(f'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
|
||||
|
||||
for cl in c.get_clients():
|
||||
|
||||
# print(f'{json.dumps(cl)}')
|
||||
|
||||
name = get_unifi_val(cl, 'name')
|
||||
hostName = get_unifi_val(cl, 'hostname')
|
||||
|
||||
if name == 'null' and hostName != 'null':
|
||||
name = hostName
|
||||
|
||||
tmpPlugObj = plugin_object_class(
|
||||
cl['mac'],
|
||||
get_unifi_val(cl, 'ip'),
|
||||
name,
|
||||
get_unifi_val(cl, 'oui'),
|
||||
'Other',
|
||||
1,
|
||||
get_unifi_val(cl, 'connection_network_name')
|
||||
)
|
||||
|
||||
# print(f'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
|
||||
|
||||
for us in c.get_clients():
|
||||
|
||||
# print(f'{json.dumps(us)}')
|
||||
|
||||
name = get_unifi_val(us, 'name')
|
||||
hostName = get_unifi_val(us, 'hostname')
|
||||
|
||||
if name == 'null' and hostName != 'null':
|
||||
name = hostName
|
||||
|
||||
tmpPlugObj = plugin_object_class(
|
||||
us['mac'],
|
||||
get_unifi_val(us, 'ip'),
|
||||
name,
|
||||
get_unifi_val(us, 'oui'),
|
||||
'Other',
|
||||
1,
|
||||
get_unifi_val(us, 'connection_network_name')
|
||||
)
|
||||
|
||||
newEntries.append(tmpPlugObj)
|
||||
|
||||
return newEntries
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_unifi_val(obj, key):
|
||||
|
||||
res = ''
|
||||
|
||||
if key in obj:
|
||||
res = obj[key]
|
||||
|
||||
if res not in ['','None']:
|
||||
return res
|
||||
|
||||
if obj.get(key) is not None:
|
||||
res = obj.get(key)
|
||||
|
||||
if res not in ['','None']:
|
||||
return res
|
||||
|
||||
return 'null'
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
class plugin_object_class:
|
||||
def __init__(self, primaryId = '',secondaryId = '', watched1 = '',watched2 = '',watched3 = '',watched4 = '',extra = '',foreignKey = ''):
|
||||
self.pluginPref = ''
|
||||
self.primaryId = primaryId
|
||||
self.secondaryId = secondaryId
|
||||
self.created = strftime("%Y-%m-%d %H:%M:%S")
|
||||
self.changed = ''
|
||||
self.watched1 = watched1
|
||||
self.watched2 = watched2
|
||||
self.watched3 = watched3
|
||||
self.watched4 = watched4
|
||||
self.status = ''
|
||||
self.extra = extra
|
||||
self.userData = ''
|
||||
self.foreignKey = foreignKey
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def service_monitoring_log(primaryId, secondaryId, created, watched1, watched2 = 'null', watched3 = 'null', watched4 = 'null', extra ='null', foreignKey ='null' ):
|
||||
|
||||
if watched1 == '':
|
||||
watched1 = 'null'
|
||||
if watched2 == '':
|
||||
watched2 = 'null'
|
||||
if watched3 == '':
|
||||
watched3 = 'null'
|
||||
if watched4 == '':
|
||||
watched4 = 'null'
|
||||
if extra == '':
|
||||
extra = 'null'
|
||||
if foreignKey == '':
|
||||
foreignKey = 'null'
|
||||
|
||||
with open(last_run, 'a') as last_run_logfile:
|
||||
last_run_logfile.write("{}|{}|{}|{}|{}|{}|{}|{}|{}\n".format(
|
||||
primaryId,
|
||||
secondaryId,
|
||||
created,
|
||||
watched1,
|
||||
watched2,
|
||||
watched3,
|
||||
watched4,
|
||||
extra,
|
||||
foreignKey
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# BEGIN
|
||||
#===============================================================================
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
12
front/plugins/website_monitor/README.md
Executable file
@@ -0,0 +1,12 @@
|
||||
## Overview
|
||||
|
||||
A simple sample plugin allowing for monitoring web services or urls. The status code corresponds to the commonly used [HTTP response status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status).
|
||||
|
||||
### Usage
|
||||
|
||||
- The user can specify which services (websites) to monitor via the `WEBMON_urls_to_check` setting.
|
||||
|
||||
### Notes
|
||||
|
||||
- Setting `(WEBMON_)SQL_internet_ip` is not used and specified for demonstration purposes only.
|
||||
- Parameters `macs` and `internet_ip` in the `config.json` file are not used and specified for demonstration purposes only.
|
||||
383
front/plugins/website_monitor/config.json
Executable file
@@ -0,0 +1,383 @@
|
||||
{
|
||||
"code_name": "website_monitor",
|
||||
"unique_prefix": "WEBMON",
|
||||
"enabled": true,
|
||||
"data_source": "python-script",
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"display_name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Website monitor"
|
||||
}],
|
||||
"icon":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "<i class=\"fa-solid fa-globe\"></i>"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "This plugin is to monitor status changes of services or websites."
|
||||
}],
|
||||
"params" : [{
|
||||
"name" : "macs",
|
||||
"type" : "sql",
|
||||
"value" : "SELECT dev_MAC from DEVICES"
|
||||
},
|
||||
{
|
||||
"name" : "urls",
|
||||
"type" : "setting",
|
||||
"value" : "WEBMON_urls_to_check"
|
||||
},
|
||||
{
|
||||
"name" : "internet_ip",
|
||||
"type" : "setting",
|
||||
"value" : "WEBMON_SQL_internet_ip"
|
||||
}],
|
||||
"database_column_definitions":
|
||||
[
|
||||
{
|
||||
"column": "Index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "url",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Monitored URL"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Created"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Changed"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "threshold",
|
||||
"default_value":"",
|
||||
"options": [
|
||||
{
|
||||
"maximum": 199,
|
||||
"hexColor": "#792D86"
|
||||
},
|
||||
{
|
||||
"maximum": 299,
|
||||
"hexColor": "#5B862D"
|
||||
},
|
||||
{
|
||||
"maximum": 399,
|
||||
"hexColor": "#7D862D"
|
||||
},
|
||||
{
|
||||
"maximum": 499,
|
||||
"hexColor": "#BF6440"
|
||||
},
|
||||
{
|
||||
"maximum": 599,
|
||||
"hexColor": "#D33115"
|
||||
}
|
||||
],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Status code"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Latency"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "UserData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "textboxsave",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Comments"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
"default_value":"",
|
||||
"options": [
|
||||
{
|
||||
"equals": "watched-not-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-square-check'></i><div></div>"
|
||||
},
|
||||
{
|
||||
"equals": "watched-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-triangle-exclamation'></i></div>"
|
||||
},
|
||||
{
|
||||
"equals": "new",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-circle-plus'></i></div>"
|
||||
}
|
||||
],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Status"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Extra"
|
||||
}]
|
||||
}
|
||||
],
|
||||
"settings":[
|
||||
{
|
||||
"function": "RUN",
|
||||
"type": "selecttext",
|
||||
"default_value":"disabled",
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan", "on_new_device"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "When to run"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Enable a regular scan of your services. If you select <code>schedule</code> the scheduling settings from below are applied. If you select <code>once</code> the scan is run only once on start of the application (container) for the time specified in <a href=\"#WEBMON_RUN_TIMEOUT\"><code>WEBMON_RUN_TIMEOUT</code> setting</a>."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"default_value":"python3 /home/pi/pialert/front/plugins/website_monitor/script.py urls={urls}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Command"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Command to run"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"default_value":"0 2 * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Schedule"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Only enabled if you select <code>schedule</code> in the <a href=\"#WEBMON_RUN\"><code>WEBMON_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "API_SQL",
|
||||
"type": "text",
|
||||
"default_value":"SELECT * FROM plugin_website_monitor",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "API endpoint (not implemented)"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "You can specify a custom SQL query which will generate a JSON file and then expose it via the <a href=\"/api/plugin_website_monitor.json\" target=\"_blank\"><code>plugin_website_monitor.json</code> file endpoint</a>."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"default_value":5,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Run timeout"
|
||||
},
|
||||
{
|
||||
"language_code":"de_de",
|
||||
"string" : "Wartezeit"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "multiselect",
|
||||
"default_value":["Watched_Value1"],
|
||||
"options": ["Watched_Value1","Watched_Value2","Watched_Value3","Watched_Value4"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Watched"
|
||||
}] ,
|
||||
"description":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is response status code (e.g.: 200, 404)</li><li><code>Watched_Value2</code> is Latency (not recommended)</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> unused </li></ul>"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "multiselect",
|
||||
"default_value":["new","watched-changed"],
|
||||
"options": ["new","watched-changed","watched-not-changed"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Report on"
|
||||
}] ,
|
||||
"description":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "urls_to_check",
|
||||
"type": "list",
|
||||
"default_value":["https://google.com", "https://duck.com"],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Arguments"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Services to watch. Enter full URL, e.g. <code>https://google.com</code>. The values from this setting will be used to replace the <code>{urls}</code> wildcard in the <code>WEBMON_CMD</code> setting."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "SQL_internet_ip",
|
||||
"type": "readonly",
|
||||
"default_value":"SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet'",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Helper variable"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Unused setting - for demonstration only. Getting the IP address of the Router / Internet. "
|
||||
}]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
148
front/plugins/website_monitor/script.py
Executable file
@@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env python
|
||||
# Based on the work of https://github.com/leiweibau/Pi.Alert
|
||||
|
||||
# /home/pi/pialert/front/plugins/website_monitor/script.py urls=http://google.com,http://bing.com
|
||||
from __future__ import unicode_literals
|
||||
from time import sleep, time, strftime
|
||||
import requests
|
||||
import pathlib
|
||||
|
||||
import argparse
|
||||
import io
|
||||
#import smtplib
|
||||
import sys
|
||||
#from smtp_config import sender, password, receivers, host, port
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
|
||||
import pwd
|
||||
import os
|
||||
|
||||
curPath = str(pathlib.Path(__file__).parent.resolve())
|
||||
log_file = curPath + '/script.log'
|
||||
last_run = curPath + '/last_result.log'
|
||||
|
||||
print(last_run)
|
||||
|
||||
# Workflow
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Simple URL monitoring tool')
|
||||
parser.add_argument('urls', action="store", help="urls to check separated by ','")
|
||||
values = parser.parse_args()
|
||||
|
||||
if values.urls:
|
||||
with open(last_run, 'w') as last_run_logfile:
|
||||
# empty file
|
||||
last_run_logfile.write("")
|
||||
service_monitoring(values.urls.split('=')[1].split(','))
|
||||
else:
|
||||
return
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def service_monitoring_log(site, status, latency):
|
||||
# global monitor_logfile
|
||||
|
||||
# Log status message to log file
|
||||
with open(log_file, 'a') as monitor_logfile:
|
||||
monitor_logfile.write("{} | {} | {} | {}\n".format(strftime("%Y-%m-%d %H:%M:%S"),
|
||||
site,
|
||||
status,
|
||||
latency,
|
||||
)
|
||||
)
|
||||
with open(last_run, 'a') as last_run_logfile:
|
||||
# https://www.duckduckgo.com|192.168.0.1|2023-01-02 15:56:30|200|0.9898|null|null|Best search engine|null
|
||||
last_run_logfile.write("{}|{}|{}|{}|{}|{}|{}|{}|{}\n".format(
|
||||
site,
|
||||
'null',
|
||||
strftime("%Y-%m-%d %H:%M:%S"),
|
||||
status,
|
||||
latency,
|
||||
'null',
|
||||
'null',
|
||||
'null',
|
||||
'null',
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def check_services_health(site):
|
||||
# Enable self signed SSL
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
"""Send GET request to input site and return status code"""
|
||||
try:
|
||||
resp = requests.get(site, verify=False, timeout=10)
|
||||
latency = resp.elapsed
|
||||
latency_str = str(latency)
|
||||
latency_str_seconds = latency_str.split(":")
|
||||
format_latency_str = latency_str_seconds[2]
|
||||
if format_latency_str[0] == "0" and format_latency_str[1] != "." :
|
||||
format_latency_str = format_latency_str[1:]
|
||||
return resp.status_code, format_latency_str
|
||||
except requests.exceptions.SSLError:
|
||||
pass
|
||||
except:
|
||||
latency = "99999"
|
||||
return 503, latency
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_username():
|
||||
|
||||
return pwd.getpwuid(os.getuid())[0]
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def service_monitoring(urls):
|
||||
|
||||
# Empty Log and write new header
|
||||
print("Prepare Services Monitoring")
|
||||
print("... Prepare Logfile")
|
||||
with open(log_file, 'w') as monitor_logfile:
|
||||
monitor_logfile.write("Pi.Alert [Prototype]:\n---------------------------------------------------------\n")
|
||||
monitor_logfile.write("Current User: %s \n\n" % get_username())
|
||||
monitor_logfile.write("Monitor Web-Services\n")
|
||||
monitor_logfile.write("Timestamp: " + strftime("%Y-%m-%d %H:%M:%S") + "\n")
|
||||
monitor_logfile.close()
|
||||
|
||||
print("... Get Services List")
|
||||
sites = urls
|
||||
|
||||
|
||||
print("Start Services Monitoring")
|
||||
with open(log_file, 'a') as monitor_logfile:
|
||||
monitor_logfile.write("\nStart Services Monitoring\n\n| Timestamp | URL | StatusCode | ResponseTime |\n-----------------------------------------------\n")
|
||||
monitor_logfile.close()
|
||||
|
||||
while sites:
|
||||
for site in sites:
|
||||
status,latency = check_services_health(site)
|
||||
scantime = strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# Debugging
|
||||
# print("{} - {} STATUS: {} ResponseTime: {}".format(strftime("%Y-%m-%d %H:%M:%S"),
|
||||
# site,
|
||||
# status,
|
||||
# latency)
|
||||
# )
|
||||
|
||||
# Write Logfile
|
||||
service_monitoring_log(site, status, latency)
|
||||
|
||||
sys.stdout.flush()
|
||||
|
||||
break
|
||||
|
||||
else:
|
||||
with open(log_file, 'a') as monitor_logfile:
|
||||
monitor_logfile.write("\n\nNo site(s) to monitor!")
|
||||
monitor_logfile.close()
|
||||
|
||||
#===============================================================================
|
||||
# BEGIN
|
||||
#===============================================================================
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<h1 id="pageTitle">
|
||||
<?php echo lang('Presence_Title');?>
|
||||
<?= lang('Presence_Title');?>
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<a href="#" onclick="javascript: getDevicesPresence('all');">
|
||||
<div class="small-box bg-aqua">
|
||||
<div class="inner"><h3 id="devicesAll"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Presence_Shortcut_AllDevices');?></p>
|
||||
<p class="infobox_label"><?= lang('Presence_Shortcut_AllDevices');?></p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-laptop text-aqua-40"></i></div>
|
||||
</div>
|
||||
@@ -44,7 +44,7 @@
|
||||
<a href="#" onclick="javascript: getDevicesPresence('connected');">
|
||||
<div class="small-box bg-green">
|
||||
<div class="inner"> <h3 id="devicesConnected"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Presence_Shortcut_Connected');?></p>
|
||||
<p class="infobox_label"><?= lang('Presence_Shortcut_Connected');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i class="fa fa-plug text-green-40"></i> </div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
<a href="#" onclick="javascript: getDevicesPresence('favorites');">
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner"> <h3 id="devicesFavorites"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Presence_Shortcut_Favorites');?></p>
|
||||
<p class="infobox_label"><?= lang('Presence_Shortcut_Favorites');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i class="fa fa-star text-yellow-40"></i> </div>
|
||||
</div>
|
||||
@@ -68,7 +68,7 @@
|
||||
<a href="#" onclick="javascript: getDevicesPresence('new');">
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner"> <h3 id="devicesNew"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Presence_Shortcut_NewDevices');?></p>
|
||||
<p class="infobox_label"><?= lang('Presence_Shortcut_NewDevices');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i class="ion ion-plus-round text-yellow-40"></i> </div>
|
||||
</div>
|
||||
@@ -80,7 +80,7 @@
|
||||
<a href="#" onclick="javascript: getDevicesPresence('down');">
|
||||
<div class="small-box bg-red">
|
||||
<div class="inner"> <h3 id="devicesDown"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Presence_Shortcut_DownAlerts');?></p>
|
||||
<p class="infobox_label"><?= lang('Presence_Shortcut_DownAlerts');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i class="fa fa-warning text-red-40"></i> </div>
|
||||
</div>
|
||||
@@ -92,7 +92,7 @@
|
||||
<a href="#" onclick="javascript: getDevicesPresence('archived');">
|
||||
<div class="small-box bg-gray top_small_box_gray_text">
|
||||
<div class="inner"> <h3 id="devicesHidden"> -- </h3>
|
||||
<p class="infobox_label"><?php echo lang('Presence_Shortcut_Archived');?></p>
|
||||
<p class="infobox_label"><?= lang('Presence_Shortcut_Archived');?></p>
|
||||
</div>
|
||||
<div class="icon"> <i class="fa fa-eye-slash text-gray-40"></i> </div>
|
||||
</div>
|
||||
@@ -106,7 +106,7 @@
|
||||
<div class="col-md-12">
|
||||
<div class="box" id="clients">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><?php echo lang('Device_Shortcut_OnlineChart');?></h3>
|
||||
<h3 class="box-title"><?= lang('Device_Shortcut_OnlineChart');?></h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="chart">
|
||||
@@ -242,12 +242,12 @@ function initializeCalendar () {
|
||||
allDaySlot : false,
|
||||
timeFormat : 'H:mm',
|
||||
|
||||
resourceLabelText : '<?php echo lang('Presence_CallHead_Devices');?>',
|
||||
resourceLabelText : '<?= lang('Presence_CallHead_Devices');?>',
|
||||
resourceAreaWidth : '160px',
|
||||
slotWidth : '1px',
|
||||
|
||||
resourceOrder : '-favorite,title',
|
||||
locale : '<?php echo lang('Presence_CalHead_lang');?>',
|
||||
locale : '<?= lang('Presence_CalHead_lang');?>',
|
||||
|
||||
//schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
|
||||
schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
|
||||
@@ -256,7 +256,7 @@ function initializeCalendar () {
|
||||
timelineYear: {
|
||||
type : 'timeline',
|
||||
duration : { year: 1 },
|
||||
buttonText : '<?php echo lang('Presence_CalHead_year');?>',
|
||||
buttonText : '<?= lang('Presence_CalHead_year');?>',
|
||||
slotLabelFormat : 'MMM',
|
||||
// Hack to show partial day events not as fullday events
|
||||
slotDuration : {minutes: 44641}
|
||||
@@ -265,7 +265,7 @@ function initializeCalendar () {
|
||||
timelineQuarter: {
|
||||
type : 'timeline',
|
||||
duration : { month: 3 },
|
||||
buttonText : '<?php echo lang('Presence_CalHead_quarter');?>',
|
||||
buttonText : '<?= lang('Presence_CalHead_quarter');?>',
|
||||
slotLabelFormat : 'MMM',
|
||||
// Hack to show partial day events not as fullday events
|
||||
slotDuration : {minutes: 44641}
|
||||
@@ -274,7 +274,7 @@ function initializeCalendar () {
|
||||
timelineMonth: {
|
||||
type : 'timeline',
|
||||
duration : { month: 1 },
|
||||
buttonText : '<?php echo lang('Presence_CalHead_month');?>',
|
||||
buttonText : '<?= lang('Presence_CalHead_month');?>',
|
||||
slotLabelFormat : 'D',
|
||||
// Hack to show partial day events not as fullday events
|
||||
slotDuration : '24:00:01'
|
||||
@@ -283,7 +283,7 @@ function initializeCalendar () {
|
||||
timelineWeek: {
|
||||
type : 'timeline',
|
||||
duration : { week: 1 },
|
||||
buttonText : '<?php echo lang('Presence_CalHead_week');?>',
|
||||
buttonText : '<?= lang('Presence_CalHead_week');?>',
|
||||
slotLabelFormat : 'D',
|
||||
slotDuration : '24:00:01'
|
||||
}
|
||||
@@ -361,13 +361,13 @@ function getDevicesPresence (status) {
|
||||
|
||||
// Defini color & title for the status selected
|
||||
switch (deviceStatus) {
|
||||
case 'all': tableTitle = '<?php echo lang('Presence_Shortcut_AllDevices');?>'; color = 'aqua'; break;
|
||||
case 'connected': tableTitle = '<?php echo lang('Presence_Shortcut_Connected');?>'; color = 'green'; break;
|
||||
case 'favorites': tableTitle = '<?php echo lang('Presence_Shortcut_Favorites');?>'; color = 'yellow'; break;
|
||||
case 'new': tableTitle = '<?php echo lang('Presence_Shortcut_NewDevices');?>'; color = 'yellow'; break;
|
||||
case 'down': tableTitle = '<?php echo lang('Presence_Shortcut_DownAlerts');?>'; color = 'red'; break;
|
||||
case 'archived': tableTitle = '<?php echo lang('Presence_Shortcut_Archived');?>'; color = 'gray'; break;
|
||||
default: tableTitle = '<?php echo lang('Presence_Shortcut_Devices');?>'; color = 'gray'; break;
|
||||
case 'all': tableTitle = '<?= lang('Presence_Shortcut_AllDevices');?>'; color = 'aqua'; break;
|
||||
case 'connected': tableTitle = '<?= lang('Presence_Shortcut_Connected');?>'; color = 'green'; break;
|
||||
case 'favorites': tableTitle = '<?= lang('Presence_Shortcut_Favorites');?>'; color = 'yellow'; break;
|
||||
case 'new': tableTitle = '<?= lang('Presence_Shortcut_NewDevices');?>'; color = 'yellow'; break;
|
||||
case 'down': tableTitle = '<?= lang('Presence_Shortcut_DownAlerts');?>'; color = 'red'; break;
|
||||
case 'archived': tableTitle = '<?= lang('Presence_Shortcut_Archived');?>'; color = 'gray'; break;
|
||||
default: tableTitle = '<?= lang('Presence_Shortcut_Devices');?>'; color = 'gray'; break;
|
||||
}
|
||||
|
||||
// Set title and color
|
||||
|
||||
@@ -2,12 +2,6 @@
|
||||
|
||||
require 'php/templates/header.php';
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// External files
|
||||
require 'php/server/db.php';
|
||||
require 'php/server/util.php';
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Action selector
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -20,11 +14,25 @@ $confPath = "../config/pialert.conf";
|
||||
|
||||
checkPermissions([$dbPath, $confPath]);
|
||||
|
||||
// get settings from the API json file
|
||||
|
||||
// path to your JSON file
|
||||
$file = '../front/api/table_settings.json';
|
||||
// put the content of the file in a variable
|
||||
$data = file_get_contents($file);
|
||||
// JSON decode
|
||||
$settingsJson = json_decode($data);
|
||||
|
||||
// get settings from the DB
|
||||
|
||||
global $db;
|
||||
global $settingKeyOfLists;
|
||||
|
||||
$result = $db->query("SELECT * FROM Settings");
|
||||
|
||||
// array
|
||||
$settingKeyOfLists = array();
|
||||
$settingCoreGroups = array('General', 'Email', 'Webhooks', 'Apprise', 'NTFY', 'PUSHSAFER', 'MQTT', 'DynDNS', 'PiHole', 'Pholus', 'Nmap', 'API');
|
||||
$settings = array();
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
// Push row data
|
||||
@@ -49,14 +57,14 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
<section class="content-header">
|
||||
<?php require 'php/templates/notification.php'; ?>
|
||||
<h1 id="pageTitle">
|
||||
<?php echo lang('Navigation_Settings');?>
|
||||
<?= lang('Navigation_Settings');?>
|
||||
<a style="cursor:pointer">
|
||||
<span>
|
||||
<i id='toggleSettings' onclick="toggleAllSettings()" class="settings-expand-icon fa fa-angle-double-down"></i>
|
||||
</span>
|
||||
</a>
|
||||
</h1>
|
||||
<div class="settingsImported"><?php echo lang("settings_imported");?> <span id="lastImportedTime"></span></div>
|
||||
<div class="settingsImported"><?= lang("settings_imported");?> <span id="lastImportedTime"></span></div>
|
||||
</section>
|
||||
<div class="content " id='accordion_gen'>
|
||||
<?php
|
||||
@@ -75,10 +83,18 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
$isIn = ' in ';
|
||||
foreach ($groups as $group)
|
||||
{
|
||||
if (in_array($group, $settingCoreGroups))
|
||||
{
|
||||
$settingGroupTypeHtml = "";
|
||||
} else
|
||||
{
|
||||
$settingGroupTypeHtml = ' (<i class="fa-regular fa-plug fa-sm"></i>) ';
|
||||
}
|
||||
|
||||
$html = $html.'<div class=" box panel panel-default">
|
||||
<a data-toggle="collapse" data-parent="#accordion_gen" href="#'.$group.'">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">'.lang($group.'_settings_group').'</h4>
|
||||
<h4 class="panel-title">'.lang($group.'_icon')." ".lang($group.'_display_name').$settingGroupTypeHtml.'</h4>
|
||||
</div>
|
||||
</a>
|
||||
<div id="'.$group.'" data-myid="collapsible" class="panel-collapse collapse '.$isIn.'">
|
||||
@@ -114,7 +130,7 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
// text - textbox
|
||||
if($set['Type'] == 'text' )
|
||||
{
|
||||
$input = '<input class="form-control" onChange="settingsChanged()" input" id="'.$set['Code_Name'].'" value="'.$set['Value'].'"/>';
|
||||
$input = '<input class="form-control" onChange="settingsChanged()" id="'.$set['Code_Name'].'" value="'.$set['Value'].'"/>';
|
||||
}
|
||||
// password - hidden text
|
||||
elseif ($set['Type'] == 'password')
|
||||
@@ -202,12 +218,12 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
{
|
||||
$input = $input.
|
||||
'<div class="row form-group">
|
||||
<div class="col-xs-6">
|
||||
<div class="col-xs-5">
|
||||
<input class="form-control" id="ipMask" type="text" placeholder="192.168.1.0/24"/>
|
||||
</div>';
|
||||
// Add interface button
|
||||
$input = $input.
|
||||
'<div class="col-xs-3">
|
||||
'<div class="col-xs-4">
|
||||
<input class="form-control " id="ipInterface" type="text" placeholder="eth0" />
|
||||
</div>
|
||||
<div class="col-xs-3"><button class="btn btn-primary" onclick="addInterface()" >Add</button></div>
|
||||
@@ -227,6 +243,37 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
// Remove all interfaces button
|
||||
$input = $input.'<div><button class="btn btn-primary" onclick="removeInterfaces()">Remove all</button></div>';
|
||||
|
||||
}
|
||||
// list
|
||||
elseif ($set['Type'] == 'list')
|
||||
{
|
||||
|
||||
$settingKeyOfLists[] = $set['Code_Name'];
|
||||
|
||||
$input = $input.
|
||||
'<div class="row form-group">
|
||||
<div class="col-xs-9">
|
||||
<input class="form-control" type="text" id="'.$set['Code_Name'].'_input" placeholder="Enter value"/>
|
||||
</div>';
|
||||
// Add interface button
|
||||
$input = $input.
|
||||
'<div class="col-xs-3"><button class="btn btn-primary" onclick="addList'.$set['Code_Name'].'()" >Add</button></div>
|
||||
</div>';
|
||||
|
||||
// list all interfaces as options
|
||||
$input = $input.'<div class="form-group">
|
||||
<select class="form-control" name="'.$set['Code_Name'].'" id="'.$set['Code_Name'].'" multiple readonly>';
|
||||
|
||||
$options = createArray($set['Value']);
|
||||
|
||||
foreach ($options as $option) {
|
||||
|
||||
$input = $input.'<option value="'.$option.'" disabled>'.$option.'</option>';
|
||||
}
|
||||
$input = $input.'</select></div>';
|
||||
// Remove all interfaces button
|
||||
$input = $input.'<div><button class="btn btn-primary" onclick="removeFromList'.$set['Code_Name'].'()">Remove last</button></div>';
|
||||
|
||||
}
|
||||
|
||||
$html = $html.$input;
|
||||
@@ -244,10 +291,11 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
if(count($eventsList) > 0)
|
||||
{
|
||||
foreach ($eventsList as $event) {
|
||||
$eventsHtml = $eventsHtml.'<span class="input-group-addon">
|
||||
<i title="'.lang($event."_event_tooltip").'" class="fa '.lang($event."_event_icon").' pointer"
|
||||
$eventsHtml = $eventsHtml.'<span class="input-group-addon pointer"
|
||||
data-myparam="'.$set['Code_Name'].'"
|
||||
data-myevent="'.$event.'">
|
||||
data-myevent="'.$event.'"
|
||||
>
|
||||
<i title="'.lang($event."_event_tooltip").'" class="fa '.lang($event."_event_icon").' " >
|
||||
</i>
|
||||
</span>';
|
||||
}
|
||||
@@ -268,7 +316,7 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
<!-- /.content -->
|
||||
<div class="row" >
|
||||
<div class="row">
|
||||
<button type="button" class="center top-margin btn btn-primary btn-default pa-btn bg-green dbtools-button" id="save" onclick="saveSettings()"><?php echo lang('DevDetail_button_Save');?></button>
|
||||
<button type="button" class="center top-margin btn btn-primary btn-default pa-btn bg-green dbtools-button" id="save" onclick="saveSettings()"><?= lang('DevDetail_button_Save');?></button>
|
||||
</div>
|
||||
<div id="result"></div>
|
||||
</div>
|
||||
@@ -285,16 +333,46 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
<script>
|
||||
|
||||
// number of settings has to be equal to
|
||||
var settingsNumber = 61;
|
||||
|
||||
// display the name of the first person
|
||||
// echo $settingsJson[0]->name;
|
||||
var settingsNumber = <?php echo count($settingsJson->data)?>;
|
||||
|
||||
// Wrong number of settings processing
|
||||
if(<?php echo count($settings)?> != settingsNumber)
|
||||
{
|
||||
showModalOk('WARNING', "<?php echo lang("settings_missing")?>");
|
||||
showModalOk('WARNING', "<?= lang("settings_missing")?>");
|
||||
}
|
||||
|
||||
<?php
|
||||
// generate javascript methods to handle add and remove items to lists
|
||||
foreach($settingKeyOfLists as $settingKey )
|
||||
{
|
||||
$addList = 'function addList'.$settingKey.'()
|
||||
{
|
||||
input = $("#'.$settingKey.'_input").val();
|
||||
$("#'.$settingKey.'").append($("<option disabled></option>").attr("value", input).text(input));
|
||||
|
||||
|
||||
$("#'.$settingKey.'_input").val("");
|
||||
|
||||
settingsChanged();
|
||||
}
|
||||
';
|
||||
|
||||
|
||||
$remList = 'function removeFromList'.$settingKey.'()
|
||||
{
|
||||
settingsChanged();
|
||||
// $("#'.$settingKey.'").empty();
|
||||
$("#'.$settingKey.'").find("option:last").remove();
|
||||
}';
|
||||
|
||||
echo $remList;
|
||||
echo $addList;
|
||||
}
|
||||
?>
|
||||
|
||||
// ---------------------------------------------------------
|
||||
function addInterface()
|
||||
{
|
||||
@@ -333,17 +411,18 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
// generate javascript to collect values
|
||||
<?php
|
||||
|
||||
$noConversion = array('text', 'integer', 'password', 'readonly', 'selecttext', 'selectinteger', "multiselect");
|
||||
$noConversion = array('text', 'integer', 'password', 'readonly', 'selecttext', 'selectinteger', 'multiselect');
|
||||
|
||||
foreach ($settings as $set) {
|
||||
if(in_array($set['Type'] , $noConversion))
|
||||
{
|
||||
echo 'settingsArray.push(["'.$set["Group"].'", "'.$set["Code_Name"].'", $("#'.$set["Code_Name"].'").val(), "'.$set["Type"].'" ]);';
|
||||
|
||||
echo 'settingsArray.push(["'.$set["Group"].'", "'.$set["Code_Name"].'", "'.$set["Type"].'", $("#'.$set["Code_Name"].'").val() ]);';
|
||||
}
|
||||
elseif ($set['Type'] == "boolean")
|
||||
{
|
||||
echo 'temp = $("#'.$set["Code_Name"].'").is(":checked") ;';
|
||||
echo 'settingsArray.push(["'.$set["Group"].'", "'.$set["Code_Name"].'", temp, "'.$set["Type"].'" ]);';
|
||||
echo 'settingsArray.push(["'.$set["Group"].'", "'.$set["Code_Name"].'", "'.$set["Type"].'", temp ]);';
|
||||
}
|
||||
elseif ($set["Code_Name"] == "SCAN_SUBNETS")
|
||||
{
|
||||
@@ -354,7 +433,23 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
});
|
||||
|
||||
";
|
||||
echo 'settingsArray.push(["'.$set["Group"].'", "'.$set["Code_Name"].'", temps, "'.$set["Type"].'" ]);';
|
||||
echo 'settingsArray.push(["'.$set["Group"].'", "'.$set["Code_Name"].'", "'.$set["Type"].'", temps ]);';
|
||||
}
|
||||
elseif ($set['Type'] == "list")
|
||||
{
|
||||
echo 'console.log($("#'.$set["Code_Name"].'"));';
|
||||
echo "var temps = [];
|
||||
|
||||
$( '#".$set["Code_Name"]." option' ).each( function( i, selected ) {
|
||||
vl = $( selected ).val()
|
||||
if (vl != '')
|
||||
{
|
||||
temps.push(vl);
|
||||
}
|
||||
});
|
||||
console.log(temps);
|
||||
";
|
||||
echo 'settingsArray.push(["'.$set["Group"].'", "'.$set["Code_Name"].'", "'.$set["Type"].'", temps ]);';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,7 +462,7 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
function saveSettings() {
|
||||
if(<?php echo count($settings)?> != settingsNumber)
|
||||
{
|
||||
showModalOk('WARNING', "<?php echo lang("settings_missing_block")?>");
|
||||
showModalOk('WARNING', "<?= lang("settings_missing_block")?>");
|
||||
} else
|
||||
{
|
||||
$.ajax({
|
||||
@@ -408,7 +503,7 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
// check if displayed settings are outdated
|
||||
if(fileModificationTime > importedMiliseconds)
|
||||
{
|
||||
showModalOk('WARNING: Outdated settings displayed', "<?php echo lang("settings_old")?>");
|
||||
showModalOk('WARNING: Outdated settings displayed', "<?= lang("settings_old")?>");
|
||||
}
|
||||
} else{
|
||||
result = result.replaceAll('"', '');
|
||||
@@ -457,7 +552,7 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
// handling events on the backend initiated by the front end START
|
||||
// -----------------------------------------------------------------------------
|
||||
$(window).on('load', function() {
|
||||
$('i[data-myevent]').each(function(index, element){
|
||||
$('span[data-myevent]').each(function(index, element){
|
||||
$(element).attr('onclick',
|
||||
'handleEvent(\"' + $(element).attr('data-myevent') + '|'+ $(element).attr('data-myparam') + '\")'
|
||||
);
|
||||
@@ -469,10 +564,8 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
function handleEvent (value){
|
||||
setParameter ('Front_Event', value)
|
||||
|
||||
// console.log(value)
|
||||
|
||||
// show message
|
||||
showModalOk("<?php echo lang("general_event_title")?>", "<?php echo lang("general_event_description")?> <code id='"+modalEventStatusId+"'></code>");
|
||||
showModalOk("<?= lang("general_event_title")?>", "<?= lang("general_event_description")?> <code id='"+modalEventStatusId+"'></code>");
|
||||
|
||||
// Periodically update state of the requested action
|
||||
getParam(modalEventStatusId,"Front_Event", true, updateModalState)
|
||||
@@ -486,9 +579,6 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
setTimeout(function(){
|
||||
displayedEvent = $('#'+modalEventStatusId).html()
|
||||
|
||||
// console.log(displayedEvent)
|
||||
// console.log(displayedEvent.indexOf('finished') == -1)
|
||||
|
||||
// loop until finished
|
||||
if(displayedEvent.indexOf('finished') == -1) // if the message is different from finished, check again in 4s
|
||||
{
|
||||
|
||||
@@ -21,6 +21,8 @@ logging.getLogger("scapy.runtime").setLevel(logging.ERROR)#supress Scapy warning
|
||||
runPath = os.path.dirname(os.path.abspath(__file__))
|
||||
runPathTmp = runPath + "/.."
|
||||
logPath = runPathTmp + '/front/log'
|
||||
# DEBUG
|
||||
isDebug = False
|
||||
|
||||
|
||||
#===============================================================================
|
||||
@@ -61,6 +63,8 @@ write_file(logPath + "/pialert_pholus_subp_pr.log", "")
|
||||
|
||||
# For separate logging of the multiprocess subprocess
|
||||
def file_print_pr(*args):
|
||||
if isDebug == False:
|
||||
return
|
||||
|
||||
result = ''
|
||||
|
||||
@@ -139,10 +143,10 @@ def get_my_ipv4_addr(interface):
|
||||
##########################
|
||||
class Sniffer():
|
||||
def __init__ (self,filter,interface,sniffer_timeout,queue,dns,show_ttl,dos_ttl, conflict, ttl,d4, d6, target_mac, auto_fake_responses,source_IPv6, source_IPv4, target_mac1, target_mac2,source_mac,hlimit,workstation,printer,googlecast,airtv,flood,flooding_timeout,flooding_interval, v4, v6):
|
||||
file_print(">>>>>>> sniffer_args: ", filter," ",interface," ",sniffer_timeout," ",queue," ",dns," ",show_ttl," ",dos_ttl," ", conflict," ", ttl," ",d4," ", d6," ", target_mac," ", auto_fake_responses," ",source_IPv6," ", source_IPv4," ", target_mac1," ", target_mac2," ",source_mac," ",hlimit," ",workstation," ",printer," ",googlecast," ",airtv," ",flood," ",flooding_timeout," ",flooding_interval," ", v4," ", v6)
|
||||
file_print_pr("[DEBUG] sniffer_args: ", filter," ",interface," ",sniffer_timeout," ",queue," ",dns," ",show_ttl," ",dos_ttl," ", conflict," ", ttl," ",d4," ", d6," ", target_mac," ", auto_fake_responses," ",source_IPv6," ", source_IPv4," ", target_mac1," ", target_mac2," ",source_mac," ",hlimit," ",workstation," ",printer," ",googlecast," ",airtv," ",flood," ",flooding_timeout," ",flooding_interval," ", v4," ", v6)
|
||||
self.filter = filter
|
||||
self.interface = interface
|
||||
file_print(">>>>>>> sniffer_timeout: ", sniffer_timeout)
|
||||
file_print_pr("[DEBUG] sniffer_timeout: ", sniffer_timeout)
|
||||
self.sniffer_timeout=sniffer_timeout
|
||||
self.queue=queue
|
||||
self.dns=dns
|
||||
@@ -178,7 +182,7 @@ class Sniffer():
|
||||
##################################
|
||||
class Sniffer_Offline():
|
||||
def __init__ (self,interface,queue,show_ttl,d4, d6, target_mac,auto_fake_responses,source_IPv6, source_IPv4, target_mac1, target_mac2,source_mac,hlimit):
|
||||
file_print(">>>>>>> Timestamp 0.0210aa: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 1: ", timeNow())
|
||||
self.interface = interface
|
||||
self.queue=queue
|
||||
self.show_ttl=show_ttl
|
||||
@@ -201,9 +205,8 @@ class Sniffer_Offline():
|
||||
########################################################################
|
||||
def ext_handler(packets,queue,unidns,show_ttl,print_res,dos_ttl,conflict,ttl,interface,d4,d6,target_mac,auto_fake_responses,source_IPv6,source_IPv4,target_mac1,target_mac2,source_mac,hlimit,workstation,printer,googlecast,airtv,flood,flooding_timeout,flodding_interval,v4,v6):
|
||||
|
||||
# file_print(">>>>>>> Timestamp 0.0210: ", timeNow())
|
||||
file_print_pr(">>>>>>> Timestamp 0.0210: ", timeNow())
|
||||
file_print_pr(">>>>>>> Test ")
|
||||
file_print_pr("[DEBUG] Timestamp 2: ", timeNow())
|
||||
file_print_pr("[DEBUG] 3 ")
|
||||
|
||||
dns_type = {12: "PTR", 28: "AAAA", 13: "HINFO",33: "SRV", 1: "A", 255: "* (ANY)", 16: "TXT", 15: "MX", 6: "SOA", 256: "URI", 5: "CNAME",39: "DNAME"}
|
||||
Ether_src=packets.getlayer(Ether).src
|
||||
@@ -213,12 +216,11 @@ def ext_handler(packets,queue,unidns,show_ttl,print_res,dos_ttl,conflict,ttl,int
|
||||
elif packets.haslayer(IP):
|
||||
IP_src=packets.getlayer(IP).src
|
||||
else:
|
||||
file_print(">>>>>>> Timestamp 0.021: ", timeNow())
|
||||
file_print_pr(">>>>>>> Test 2")
|
||||
file_print_pr("[DEBUG] Timestamp 4: ", timeNow())
|
||||
|
||||
res0= Ether_src + " | " + IP_src.ljust(27)
|
||||
if packets.haslayer(DNS):
|
||||
file_print_pr(">>>>>>> Test 4")
|
||||
file_print_pr("[DEBUG] Timestamp 5: ", timeNow())
|
||||
dns=packets.getlayer(DNS)
|
||||
if (conflict or dos_ttl) and dns.ancount>0:
|
||||
DNSBlocks = [ ]
|
||||
@@ -274,13 +276,13 @@ def ext_handler(packets,queue,unidns,show_ttl,print_res,dos_ttl,conflict,ttl,int
|
||||
else:
|
||||
new_packet=new_packet/UDP(dport=5353,sport=5353)/new_DNS_packet
|
||||
for x in range(0,2):#Send each packet twice
|
||||
file_print_pr(">>>>>>> Test 6")
|
||||
file_print_pr("[DEBUG] Timestamp 6: ", timeNow())
|
||||
sendp(new_packet,iface=interface)
|
||||
file_print_pr(">>>>>>> Test 6.1")
|
||||
file_print_pr("[DEBUG] Timestamp 7: ", timeNow())
|
||||
|
||||
elif auto_fake_responses or (not (dos_ttl or conflict)):
|
||||
## IF THIS IS A QUERY ##
|
||||
file_print_pr(">>>>>>> Test 6.2")
|
||||
file_print_pr("[DEBUG] Timestamp 8: ", timeNow())
|
||||
if dns.opcode==0:
|
||||
res0 = res0 + ""
|
||||
if dns.qdcount>0:
|
||||
@@ -488,9 +490,9 @@ def ext_handler(packets,queue,unidns,show_ttl,print_res,dos_ttl,conflict,ttl,int
|
||||
dns_packet=UDP(sport=5353,dport=5353)/DNS(qr=1,aa=1,rd=0,ancount=1)/DNSRR(rrname=qname,ttl=myttl,rdata=source_IPv4,type="A")
|
||||
else:
|
||||
dns_packet=UDP(sport=5353,dport=5353)/DNS(qr=1,aa=1,rd=0,ancount=1)/DNSRR(rrname=qname,ttl=myttl,rdata=source_IPv4,type="A")
|
||||
file_print_pr(">>>>>>> Test 6.23")
|
||||
file_print_pr("[DEBUG] Timestamp 9: ", timeNow())
|
||||
send_packets(v4,v6,source_mac,target_mac1,target_mac2,source_IPv4,d4,source_IPv6,d6,interface,hlimit,dns_packet,False,10.0,0.1)#CHANGE DEFAULT VALUES
|
||||
file_print_pr(">>>>>>> Test 6.24")
|
||||
file_print_pr("[DEBUG] Timestamp 10: ", timeNow())
|
||||
### END "IF WE NEED TO AUTO RESPOND WITH A FAKE RESPONSE
|
||||
### NEXT LINES ARE ONLY USED TO PRINT RESULTS ###
|
||||
if dnsqr.qclass==32769:
|
||||
@@ -526,7 +528,7 @@ def ext_handler(packets,queue,unidns,show_ttl,print_res,dos_ttl,conflict,ttl,int
|
||||
else:
|
||||
ARtype=str(dnsrropt.type)
|
||||
res = res0 + " | Additional_Record | " + rrname.decode("utf-8") + " " + ARtype
|
||||
file_print_pr(">>>>>>> Test 6.24")
|
||||
file_print_pr("[DEBUG] Timestamp 11: ", timeNow())
|
||||
if dnsrropt.haslayer(EDNS0TLV):
|
||||
edns0tlv=dnsrropt.getlayer(EDNS0TLV)
|
||||
if edns0tlv.optcode==4:
|
||||
@@ -595,26 +597,27 @@ def ext_handler(packets,queue,unidns,show_ttl,print_res,dos_ttl,conflict,ttl,int
|
||||
str_type = str(b_to_str(dns_type[dnsrr.type])) + ""
|
||||
str_rdata = str(b_to_str(dnsrr.rdata)) + ""
|
||||
str_rclass = str(b_to_str(dnsrr.rclass)) + ""
|
||||
|
||||
file_print_pr("[DEBUG] Timestamp 12: ", timeNow())
|
||||
res = str_res0 + " | Additional_Record | "+str_rrname + " " + str_type+" " + str_rclass + ' "' +str_rdata+'"'
|
||||
if show_ttl:
|
||||
res = res + " TTL:"+str(dnsrr.ttl)
|
||||
if print_res==1:
|
||||
file_print(res)
|
||||
file_print_pr(">>>>>>> Test 6.27")
|
||||
file_print_pr("[DEBUG] Timestamp 13: ", timeNow())
|
||||
queue.put(res)
|
||||
block = block.payload
|
||||
file_print_pr(">>>>>>> Test 6.270")
|
||||
file_print_pr("[DEBUG] Timestamp 14: ", timeNow())
|
||||
|
||||
if dns.ancount>0:
|
||||
DNSBlocks = [ ]
|
||||
DNSBlocks.append(dns.an)
|
||||
for block in DNSBlocks:
|
||||
file_print_pr(">>>>>>> Test 6.271")
|
||||
file_print_pr("[DEBUG] Timestamp 15: ", timeNow())
|
||||
while isinstance(block,DNSRR):
|
||||
dnsrr=block.getlayer(DNSRR)
|
||||
if dnsrr.rclass==1:
|
||||
rclass="Class:IN"
|
||||
file_print_pr("[DEBUG] Timestamp 16: ", timeNow())
|
||||
else:
|
||||
rclass="Class:"+str(dnsrr.rclass)
|
||||
rdata=dnsrr.rdata
|
||||
@@ -632,24 +635,28 @@ def ext_handler(packets,queue,unidns,show_ttl,print_res,dos_ttl,conflict,ttl,int
|
||||
if isinstance(rdata,list):
|
||||
rdata = b" ".join(rdata).decode("utf-8")
|
||||
res = res0 + " | Answer | "+dnsrr.rrname.decode("utf-8") + " " + dns_type[dnsrr.type]+" " + rclass + ' "' +rdata+'"'
|
||||
file_print_pr(">>>>>>> Test 6.272004")
|
||||
file_print_pr("[DEBUG] Timestamp 17: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 18: ", timeNow())
|
||||
if show_ttl:
|
||||
res = res + " TTL:"+str(dnsrr.ttl)
|
||||
if print_res==1:
|
||||
file_print(res)
|
||||
file_print_pr("[DEBUG] Timestamp 19: ", timeNow())
|
||||
queue.put(res)
|
||||
block = block.payload
|
||||
file_print_pr(">>>>>>> Test 6.272")
|
||||
if dns.nscount>0:
|
||||
file_print_pr(">>>>>>> Test 6.273")
|
||||
file_print_pr("[DEBUG] Timestamp 20: ", timeNow())
|
||||
if dns.nscount>0: #MAYBE HERE
|
||||
file_print_pr("[DEBUG] Timestamp 21: ", timeNow())
|
||||
DNSBlocks = [ ]
|
||||
DNSBlocks.append(dns.ns)
|
||||
file_print_pr("[DEBUG] Timestamp 22: ", timeNow())
|
||||
for block in DNSBlocks:
|
||||
file_print_pr(">>>>>>> Test 6.28")
|
||||
file_print_pr("[DEBUG] Timestamp 23: ", timeNow())
|
||||
while isinstance(block,DNSRR):
|
||||
dnsrr=block.getlayer(DNSRR)
|
||||
if dnsrr.rclass==1:
|
||||
rclass="Class:IN"
|
||||
file_print_pr("[DEBUG] Timestamp 24: ", timeNow())
|
||||
else:
|
||||
rclass="Class:"+str(dnsrr.rclass)
|
||||
|
||||
@@ -664,20 +671,22 @@ def ext_handler(packets,queue,unidns,show_ttl,print_res,dos_ttl,conflict,ttl,int
|
||||
res = res + " TTL:"+str(dnsrr.ttl)
|
||||
if print_res==1:
|
||||
file_print(res)
|
||||
file_print_pr(">>>>>>> Test 6.274")
|
||||
file_print_pr("[DEBUG] Timestamp 25: ", timeNow())
|
||||
queue.put(res)
|
||||
block = block.payload
|
||||
file_print_pr("[DEBUG] Timestamp 26: ", timeNow())
|
||||
else:
|
||||
file_print_pr(">>>>>>> Test 6.27200")
|
||||
file_print_pr("[DEBUG] Timestamp 27: ", timeNow())
|
||||
else:
|
||||
file_print("not a DNS Query", dns.summary())
|
||||
file_print_pr(">>>>>>> Test 6.272001")
|
||||
file_print_pr("[DEBUG] Timestamp 28: ", timeNow())
|
||||
else:
|
||||
file_print_pr(">>>>>>> Test 6.2720055")
|
||||
file_print_pr("[DEBUG] Timestamp 29: ", timeNow())
|
||||
else:
|
||||
file_print_pr(">>>>>>> Test 3")
|
||||
file_print_pr("[DEBUG] Timestamp 30: ", timeNow())
|
||||
|
||||
file_print_pr(">>>>>>> Test 6.272005599")
|
||||
file_print_pr("[DEBUG] Timestamp 31: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 32: ", timeNow(), " ", res0)
|
||||
file_print_pr("[DEBUG] Timestamp 33: ", timeNow(), " ", res)
|
||||
|
||||
|
||||
########################################
|
||||
@@ -852,11 +861,13 @@ def main():
|
||||
exit(0)
|
||||
file_print("Press Ctrl-C to exit and print the results")
|
||||
q = multiprocessing.Queue()
|
||||
file_print(">>>>>>> Timestamp 0.1: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 34: ", timeNow())
|
||||
pr = multiprocessing.Process(target=Sniffer_Offline, args=(values.interface,q,values.show_ttl,values.d4, values.d6, values.target_mac, values.auto_fake_responses,values.source6,values.source4,values.target_mac,values.target_mac,values.source_mac,values.hlimit))
|
||||
pr.start()
|
||||
pr.join()
|
||||
file_print(">>>>>>> Timestamp 0.2: ", timeNow())
|
||||
pr.join(15)
|
||||
if pr.is_alive():
|
||||
file_print("SUB-PROCESS KILLED TIMESTAMP: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 35: ", timeNow())
|
||||
results=[]
|
||||
while not q.empty():
|
||||
results.append(q.get())
|
||||
@@ -928,9 +939,9 @@ def main():
|
||||
file_print("I will sniff for ",values.sniffer_timeout," seconds, unless interrupted by Ctrl-C")
|
||||
file_print("Press Ctrl-C to exit")
|
||||
try:
|
||||
file_print(">>>>>>> Timestamp 0.0210ab: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 36: ", timeNow())
|
||||
Sniffer(myfilter, values.interface, float(values.sniffer_timeout),q,values.dns,values.show_ttl, values.dos_ttl, values.conflict, values.ttl,values.d4, values.d6, values.target_mac, values.auto_fake_responses,source_IPv6, source_IPv4, target_mac1, target_mac2,source_mac,values.hlimit,values.workstation,values.printer,values.googlecast,values.airtv,values.flood,values.flooding_timeout,values.flooding_interval,values.v4,values.v6)
|
||||
file_print(">>>>>>> Timestamp 0.0210abc: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 37: ", timeNow())
|
||||
except KeyboardInterrupt:
|
||||
file_print("Exiting on user's request 1")
|
||||
exit(0)
|
||||
@@ -940,25 +951,25 @@ def main():
|
||||
file_print("I will sniff for ",values.sniffer_timeout," seconds, unless interrupted by Ctrl-C")
|
||||
pr = multiprocessing.Process(target=Sniffer, args=(myfilter, values.interface, float(values.sniffer_timeout),q,values.dns,values.show_ttl, values.dos_ttl, values.conflict, values.ttl,values.d4,values.d6, values.target_mac, values.auto_fake_responses,source_IPv6, source_IPv4, target_mac1, target_mac2, source_mac,values.hlimit,values.workstation,values.printer,values.googlecast,values.airtv,values.flood,values.flooding_timeout,values.flooding_interval,values.v4,values.v6))
|
||||
pr.daemon = True
|
||||
file_print(">>>>>>> Timestamp 0.01: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 38: ", timeNow())
|
||||
pr.start()
|
||||
file_print(">>>>>>> Timestamp 0.02: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 39: ", timeNow())
|
||||
file_print("------------------------------------------------------------------------")
|
||||
time.sleep(1)#to make sure than sniffer has started before we proceed, otherwise you may miss some traffic
|
||||
file_print(">>>>>>> Timestamp 0.03: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 40: ", timeNow())
|
||||
##########################################################################################################
|
||||
if values.request:
|
||||
file_print(">>>>>>> Timestamp 1: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 41: ", timeNow())
|
||||
requests(values.interface,values.v4,values.v6,source_mac,target_mac1,target_mac2,source_IPv4,source_IPv6,values.d4,values.d6,values.hlimit,values.dns,values.domain,values.query,values.qtype,True,q_class,values.flood,values.flooding_interval,values.flooding_timeout)
|
||||
file_print(">>>>>>> Timestamp 2: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 42: ", timeNow())
|
||||
elif values.response:
|
||||
#qr=1=>Response, aa=1=>Server is an authority for the domain, rd=0=> Do not query recursively
|
||||
file_print(">>>>>>> Timestamp 3: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 43: ", timeNow())
|
||||
if values.dns:
|
||||
dns_packet=UDP(dport=53)/DNS(qr=1,aa=1,rd=0)
|
||||
else:
|
||||
dns_packet=UDP(sport=5353,dport=5353)/DNS(qr=1,aa=1,rd=0)
|
||||
file_print(">>>>>>> Timestamp 4: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 44: ", timeNow())
|
||||
responses = values.dns_response.split(",")
|
||||
no_of_answers=0
|
||||
no_of_additional_records=0
|
||||
@@ -1046,7 +1057,7 @@ def main():
|
||||
dns_packet[DNS].arcount=no_of_additional_records
|
||||
send_packets(values.v4,values.v6,source_mac,target_mac1,target_mac2,source_IPv4,values.d4,source_IPv6,values.d6,values.interface,values.hlimit,dns_packet,values.flood,values.flooding_timeout,values.flooding_interval)
|
||||
elif values.rdns_scanning:
|
||||
file_print(">>>>>>> Timestamp 5: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 45: ", timeNow())
|
||||
dns_query=None
|
||||
ipn = ipaddress.ip_network(values.rdns_scanning)
|
||||
for ip in ipn.hosts():
|
||||
@@ -1060,22 +1071,28 @@ def main():
|
||||
else:
|
||||
dns_packet=UDP(sport=5353,dport=5353)/DNS(qr=0,qd=dns_query)
|
||||
send_packets(values.v4,values.v6,source_mac,target_mac1,target_mac2,source_IPv4,values.d4,source_IPv6,values.d6,values.interface,values.hlimit,dns_packet,values.flood,values.flooding_timeout,values.flooding_interval)
|
||||
file_print(">>>>>>> Timestamp 6: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 46: ", timeNow())
|
||||
elif values.service_scan:
|
||||
file_print(">>>>>>> Timestamp 7: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 47: ", timeNow())
|
||||
requests(values.interface,values.v4,values.v6,source_mac,target_mac1,target_mac2,source_IPv4,source_IPv6,values.d4,values.d6,values.hlimit,values.dns,values.domain,values.query,values.qtype,True,q_class,values.flood,values.flooding_interval,values.flooding_timeout)
|
||||
file_print(">>>>>>> Timestamp 8: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 48: ", timeNow())
|
||||
############################################################################################
|
||||
############################################################################################
|
||||
if pr:
|
||||
file_print_pr("[DEBUG] Timestamp 49: ", timeNow())
|
||||
try:
|
||||
file_print(">>>>>>> Timestamp 6.1000: ", timeNow())
|
||||
pr.join()
|
||||
file_print(">>>>>>> Timestamp 6.2: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 50: ", timeNow()) #HERE STUCK
|
||||
pr.join(20)
|
||||
if pr.is_alive():
|
||||
file_print("SUB-PROCESS KILLED TIMESTAMP: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 51: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 52: ", timeNow())
|
||||
except KeyboardInterrupt:
|
||||
file_print("Exiting on user's request 2")
|
||||
exit(0)
|
||||
|
||||
file_print_pr("[DEBUG] Timestamp 53: ", timeNow())
|
||||
|
||||
#### AFTER EXITING, PRINT THE RESULTS ####
|
||||
results=[]
|
||||
while not q.empty():
|
||||
@@ -1083,12 +1100,12 @@ def main():
|
||||
if values.rdns_scanning:
|
||||
targets=[]
|
||||
q2 = multiprocessing.Queue()
|
||||
file_print(">>>>>>> Timestamp 9: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 54: ", timeNow())
|
||||
pr2 = multiprocessing.Process(target=Sniffer, args=(myfilter, values.interface, float(values.sniffer_timeout),q2,values.dns,values.show_ttl, values.dos_ttl,values.conflict, values.ttl,values.d4, values.d6, values.target_mac, values.auto_fake_responses,source_IPv6, source_IPv4, target_mac1, target_mac2,source_mac,values.hlimit,values.workstation,values.printer,values.googlecast,values.airtv,values.flood,values.flooding_timeout,values.flooding_interval,values.v4,values.v6))
|
||||
pr2.daemon = True
|
||||
pr2.start()
|
||||
time.sleep(1) #to make sure than sniffer has started before we proceed, otherwise you may miss some traffic
|
||||
file_print(">>>>>>> Timestamp 10: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 55: ", timeNow())
|
||||
for r in results:
|
||||
r2=r.split(" ")
|
||||
service=r2[7].strip('"')
|
||||
@@ -1100,8 +1117,13 @@ def main():
|
||||
targets.append((r2[1],service))
|
||||
requests(values.interface,values.v4,values.v6,source_mac,target_mac1,target_mac2,source_IPv4,source_IPv6,values.d4,values.d6,values.hlimit,values.dns,values.domain,service,values.qtype,True,q_class,values.flood,values.flooding_interval,values.flooding_timeout)
|
||||
if pr2:
|
||||
file_print_pr("[DEBUG] Timestamp 56: ", timeNow())
|
||||
try:
|
||||
pr2.join()
|
||||
file_print_pr("[DEBUG] Timestamp 57: ", timeNow())
|
||||
pr2.join(15)
|
||||
if pr.is_alive():
|
||||
file_print("SUB-PROCESS KILLED TIMESTAMP: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 58: ", timeNow())
|
||||
except KeyboardInterrupt:
|
||||
file_print("Exiting on user's request 3")
|
||||
while not q2.empty():
|
||||
@@ -1109,12 +1131,12 @@ def main():
|
||||
elif values.service_scan:
|
||||
targets=[]
|
||||
q2 = multiprocessing.Queue()
|
||||
file_print(">>>>>>> Timestamp 11: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 59: ", timeNow())
|
||||
pr2 = multiprocessing.Process(target=Sniffer, args=(myfilter, values.interface, float(values.sniffer_timeout),q2,values.dns,values.show_ttl, values.dos_ttl,values.conflict, values.ttl,values.d4, values.d6, values.target_mac, values.auto_fake_responses,source_IPv6, source_IPv4, target_mac1, target_mac2,source_mac,values.hlimit,values.workstation,values.printer,values.googlecast,values.airtv,values.flood,values.flooding_timeout,values.flooding_interval,values.v4,values.v6))
|
||||
pr2.daemon = True
|
||||
pr2.start()
|
||||
time.sleep(1) #to make sure than sniffer has started before we proceed, otherwise you may miss some traffic
|
||||
file_print(">>>>>>> Timestamp 12: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 60: ", timeNow())
|
||||
for r in results:
|
||||
r2=r.split(" ")
|
||||
service=r2[7].strip('"')[:-1]
|
||||
@@ -1124,19 +1146,23 @@ def main():
|
||||
requests(values.interface,values.v4,values.v6,source_mac,target_mac1,target_mac2,source_IPv4,source_IPv6,values.d4,values.d6,values.hlimit,values.dns,values.domain,service,values.qtype,True,q_class,values.flood,values.flooding_interval,values.flooding_timeout)
|
||||
if pr2:
|
||||
try:
|
||||
pr2.join()
|
||||
file_print_pr("[DEBUG] Timestamp 61: ", timeNow())
|
||||
pr2.join(15)
|
||||
if pr.is_alive():
|
||||
file_print("SUB-PROCESS KILLED TIMESTAMP: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 62: ", timeNow())
|
||||
except KeyboardInterrupt:
|
||||
file_print("Exiting on user's request 4")
|
||||
while not q2.empty():
|
||||
results.append(q2.get())
|
||||
targets2=[]
|
||||
q3 = multiprocessing.Queue()
|
||||
file_print(">>>>>>> Timestamp 13: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 63: ", timeNow())
|
||||
pr3 = multiprocessing.Process(target=Sniffer, args=(myfilter, values.interface, float(values.sniffer_timeout),q3,values.dns,values.show_ttl, values.dos_ttl, values.conflict,values.ttl,values.d4, values.d6, values.target_mac, values.auto_fake_responses,source_IPv6, source_IPv4, target_mac1, target_mac2,source_mac,values.hlimit,values.workstation,values.printer,values.googlecast,values.airtv,values.flood,values.flooding_timeout,values.flooding_interval,values.v4,values.v6))
|
||||
pr3.daemon = True
|
||||
pr3.start()
|
||||
time.sleep(1) #to make sure than sniffer has started before we proceed, otherwise you may miss some traffic
|
||||
file_print(">>>>>>> Timestamp 14: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 64: ", timeNow())
|
||||
for r in results:
|
||||
r2=r.split(" ")
|
||||
service=r2[4]
|
||||
@@ -1149,7 +1175,11 @@ def main():
|
||||
requests(values.interface,values.v4,values.v6,source_mac,target_mac1,target_mac2,source_IPv4,source_IPv6,values.d4,values.d6,values.hlimit,values.dns,values.domain,service,values.qtype,True,q_class,values.flood,values.flooding_interval,values.flooding_timeout)
|
||||
if pr3:
|
||||
try:
|
||||
pr3.join()
|
||||
file_print_pr("[DEBUG] Timestamp 65: ", timeNow())
|
||||
pr3.join(15)
|
||||
if pr.is_alive():
|
||||
file_print("SUB-PROCESS KILLED TIMESTAMP: ", timeNow())
|
||||
file_print_pr("[DEBUG] Timestamp 66: ", timeNow())
|
||||
except KeyboardInterrupt:
|
||||
file_print("Exiting on user's request 5")
|
||||
while not q3.empty():
|
||||
|
||||