This commit is contained in:
pucherot
2021-02-01 21:30:51 +01:00
parent da454c0762
commit d5a236f793
24 changed files with 2011 additions and 1662 deletions

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# #
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Pi.Alert v2.61 / 2021-01-25 # Pi.Alert v2.70 / 2021-02-01
# Open Source Network Guard / WIFI & LAN intrusion detector # Open Source Network Guard / WIFI & LAN intrusion detector
# #
# pialert.py - Back module. Network scanner # pialert.py - Back module. Network scanner
@@ -398,6 +398,10 @@ def scan_network ():
print (' Updating Devices Info...') print (' Updating Devices Info...')
update_devices_data_from_scan () update_devices_data_from_scan ()
# Resolve devices names
print_log (' Resolve devices names...')
update_devices_names()
# Void false connection - disconnections # Void false connection - disconnections
print (' Voiding false (ghost) disconnections...') print (' Voiding false (ghost) disconnections...')
void_ghost_disconnections () void_ghost_disconnections ()
@@ -905,6 +909,78 @@ def update_devices_data_from_scan ():
print_log ('Update devices end') print_log ('Update devices end')
#-------------------------------------------------------------------------------
# Feature #43 - Resoltion name for unknown devices
def update_devices_names ():
# Initialize variables
recordsToUpdate = []
ignored = 0
notFound = 0
# Devices without name
print (' Trying to resolve devices without name...', end='')
for device in sql.execute ("SELECT * FROM Devices WHERE dev_Name IN ('(unknown)','') ") :
# Resolve device name
newName = resolve_device_name (device['dev_MAC'], device['dev_LastIP'])
if newName == -1 :
notFound += 1
elif newName == -2 :
ignored += 1
else :
recordsToUpdate.append ([newName, device['dev_MAC']])
# progress bar
print ('.', end='')
sys.stdout.flush()
# Print log
print ('')
print (" Names updated: ", len(recordsToUpdate) )
# DEBUG - print list of record to update
# print (recordsToUpdate)
# update devices
sql.executemany ("UPDATE Devices SET dev_Name = ? WHERE dev_MAC = ? ", recordsToUpdate )
# DEBUG - print number of rows updated
# print (sql.rowcount)
#-------------------------------------------------------------------------------
def resolve_device_name (pMAC, pIP):
try :
pMACstr = str(pMAC)
# Check MAC parameter
mac = pMACstr.replace (':','')
if len(pMACstr) != 17 or len(mac) != 12 :
return -2
# Resolve name with DIG
dig_args = ['dig', '+short', '-x', pIP]
newName = subprocess.check_output (dig_args, universal_newlines=True)
# Check if Eliminate local domain
newName = newName.strip()
if len(newName) == 0 :
return -2
# Eliminate local domain
if newName.endswith('.') :
newName = newName[:-1]
if newName.endswith('.lan') :
newName = newName[:-4]
if newName.endswith('.local') :
newName = newName[:-6]
if newName.endswith('.home') :
newName = newName[:-5]
# Return newName
return newName
# not Found
except subprocess.CalledProcessError :
return -1
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
def void_ghost_disconnections (): def void_ghost_disconnections ():
# Void connect ghost events (disconnect event exists in last X min.) # Void connect ghost events (disconnect event exists in last X min.)

View File

@@ -3,7 +3,7 @@
# Pi.Alert # Pi.Alert
# Open Source Network Guard / WIFI & LAN intrusion detector # Open Source Network Guard / WIFI & LAN intrusion detector
# #
# vendors_db_update.sh - Back module. IEEE Vendors db update # update_vendors.sh - Back module. IEEE Vendors db update
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3 # Puche 2021 pi.alert.application@gmail.com GNU GPLv3
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@@ -1,3 +1,3 @@
VERSION = '2.61' VERSION = '2.70'
VERSION_YEAR = '2021' VERSION_YEAR = '2021'
VERSION_DATE = '2021-01-25' VERSION_DATE = '2021-02-01'

View File

@@ -3,6 +3,8 @@
| Version | Description | | Version | Description |
| ------- | --------------------------------------------------------------- | | ------- | --------------------------------------------------------------- |
| v2.70 | New features & Usability improvements in the web prontal |
| v2.61 | Bug fixing |
| v2.60 | Improved the compability of installation process (Ubuntu) | | v2.60 | Improved the compability of installation process (Ubuntu) |
| v2.56 | Bug fixing | | v2.56 | Bug fixing |
| v2.55 | Bug fixing | | v2.55 | Bug fixing |
@@ -11,6 +13,21 @@
| v2.50 | First public release | | v2.50 | First public release |
## Pi.Alert v2.70
<!--- --------------------------------------------------------------------- --->
- Added Client names resolution #43
- Added Check to mark devices as "known" #16
- Remember "Show XXX entries" dropdown value #16 #26
- Remember "sorting" in devices #16
- Remember "Device panel " in device detail #16
- Added "All" option to "Show x Entries" option #16
- Added optional Location field (Door, Basement, etc.) to devices #16
- "Device updated successfully" message now is not modal #16
- Now is possible to delete Devices #16
- Added Device Type Singleboard Computer (SBC) #16
- Allowed to use " in device name #42
## Pi.Alert v2.60 ## Pi.Alert v2.60
<!--- --------------------------------------------------------------------- ---> <!--- --------------------------------------------------------------------- --->
- `pialert.conf` moved from `back` to `config` folder - `pialert.conf` moved from `back` to `config` folder

View File

@@ -1,6 +1,11 @@
/******************************************************************************* /* -----------------------------------------------------------------------------
* Pi.alert CSS # Pi.Alert
*******************************************************************************/ # Open Source Network Guard / WIFI & LAN intrusion detector
#
# pialert.css - Front module. CSS styles
#-------------------------------------------------------------------------------
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3
----------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Global Variables Global Variables
@@ -371,3 +376,28 @@
z-index: 100; z-index: 100;
} }
/* -----------------------------------------------------------------------------
Notification float banner
----------------------------------------------------------------------------- */
.pa_alert_notification {
text-align: center;
font-size: large;
font-weight: bold;
color: #258744;
background-color: #d4edda;
border-color: #c3e6cb;
border-radius: 5px;
max-width: 1000px; /* 80% wrapper 1250px */
width: 80%;
z-index: 9999;
position: fixed;
top: 30px;
margin: auto;
transform: translate(0,0);
display: none;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,12 @@
<!-- ----------------------------------------------------------------------- --> <!-- ---------------------------------------------------------------------------
# Pi.Alert
# Open Source Network Guard / WIFI & LAN intrusion detector
#
# devices.php - Front module. Devices list page
#-------------------------------------------------------------------------------
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3
#--------------------------------------------------------------------------- -->
<?php <?php
require 'php/templates/header.php'; require 'php/templates/header.php';
?> ?>
@@ -11,102 +19,73 @@
<h1 id="pageTitle"> <h1 id="pageTitle">
Devices Devices
</h1> </h1>
<!-- period selector -->
<span class="breadcrumb text-gray50">
New Devices period:
<select id="period" onchange="javascript: periodChanged();">
<option value="1 day">Today</option>
<option value="7 days">Last Week</option>
<option value="1 month" selected>Last Month</option>
<option value="1 year">Last Year</option>
<option value="100 years">All info</option>
</select>
</span>
</section> </section>
<!-- Main content ---------------------------------------------------------- --> <!-- Main content ---------------------------------------------------------- -->
<section class="content"> <section class="content">
<!-- top small box 1 ------------------------------------------------------- -->
<div class="row"> <div class="row">
<!-- top small box --------------------------------------------------------- -->
<div class="col-lg-3 col-sm-6 col-xs-6"> <div class="col-lg-3 col-sm-6 col-xs-6">
<a href="#" onclick="javascript: queryList('all');"> <a href="#" onclick="javascript: getDevicesList('all');">
<div class="small-box bg-aqua pa-small-box-aqua"> <div class="small-box bg-aqua pa-small-box-aqua">
<div class="inner"> <div class="inner">
<h4>Total Devices</h4> <h4>Total Devices</h4>
<h3 id="devicesAll"> -- </h3> <h3 id="devicesAll"> -- </h3>
</div>
<div class="icon">
<i class="fa fa-laptop"></i>
</div>
<div class="small-box-footer">
Details <i class="fa fa-arrow-circle-right"></i>
</div> </div>
<div class="icon"> <i class="fa fa-laptop"></i> </div>
<div class="small-box-footer"> Details <i class="fa fa-arrow-circle-right"></i> </div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box 2 ------------------------------------------------------- -->
<div class="col-lg-3 col-sm-6 col-xs-6"> <div class="col-lg-3 col-sm-6 col-xs-6">
<a href="#" onclick="javascript: queryList('connected');"> <a href="#" onclick="javascript: getDevicesList('connected');">
<div class="small-box bg-green pa-small-box-green"> <div class="small-box bg-green pa-small-box-green">
<div class="inner"> <div class="inner">
<h4>Connected</h4> <h4>Connected</h4>
<h3 id="devicesConnected"> -- </h3> <h3 id="devicesConnected"> -- </h3>
</div>
<div class="icon">
<i class="fa fa-plug"></i>
</div>
<div class="small-box-footer">
Details <i class="fa fa-arrow-circle-right"></i>
</div> </div>
<div class="icon"> <i class="fa fa-plug"></i> </div>
<div class="small-box-footer"> Details <i class="fa fa-arrow-circle-right"></i> </div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box 3 ------------------------------------------------------- -->
<div class="col-lg-3 col-sm-6 col-xs-6"> <div class="col-lg-3 col-sm-6 col-xs-6">
<a href="#" onclick="javascript: queryList('new');"> <a href="#" onclick="javascript: getDevicesList('new');">
<div class="small-box bg-yellow pa-small-box-yellow"> <div class="small-box bg-yellow pa-small-box-yellow">
<div class="inner"> <div class="inner">
<h4>New Devices</h4> <h4>New Devices</h4>
<h3 id="devicesNew"> -- </h3> <h3 id="devicesNew"> -- </h3>
</div>
<div class="icon">
<i class="ion ion-plus-round"></i>
</div>
<div class="small-box-footer">
Details <i class="fa fa-arrow-circle-right"></i>
</div> </div>
<div class="icon"> <i class="ion ion-plus-round"></i> </div>
<div class="small-box-footer"> Details <i class="fa fa-arrow-circle-right"></i> </div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box 4 ------------------------------------------------------- -->
<div class="col-lg-3 col-sm-6 col-xs-6"> <div class="col-lg-3 col-sm-6 col-xs-6">
<a href="#" onclick="javascript: queryList('down');"> <a href="#" onclick="javascript: getDevicesList('down');">
<div class="small-box bg-red pa-small-box-red"> <div class="small-box bg-red pa-small-box-red">
<div class="inner"> <div class="inner">
<h4>Down Alerts</h4> <h4>Down Alerts</h4>
<h3 id="devicesDown"> -- </h3> <h3 id="devicesDown"> -- </h3>
</div>
<div class="icon">
<i class="fa fa-warning"></i>
</div>
<div class="small-box-footer">
Details <i class="fa fa-arrow-circle-right"></i>
</div> </div>
<div class="icon"> <i class="fa fa-warning"></i> </div>
<div class="small-box-footer"> Details <i class="fa fa-arrow-circle-right"></i> </div>
</div> </div>
</a> </a>
</div> </div>
@@ -118,12 +97,15 @@
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<div id="tableDevicesBox" class="box"> <div id="tableDevicesBox" class="box">
<!-- box-header -->
<div class="box-header"> <div class="box-header">
<h3 id="tableDevicesTitle" class="box-title text-gray">Devices</h3> <h3 id="tableDevicesTitle" class="box-title text-gray">Devices</h3>
</div> </div>
<!-- /.box-header -->
<!-- table -->
<div class="box-body table-responsive"> <div class="box-body table-responsive">
<table id="tableDevices" class="table table-bordered table-hover table-striped "> <table id="tableDevices" class="table table-bordered table-hover table-striped">
<thead> <thead>
<tr> <tr>
<th>Name</th> <th>Name</th>
@@ -142,6 +124,7 @@
</table> </table>
</div> </div>
<!-- /.box-body --> <!-- /.box-body -->
</div> </div>
<!-- /.box --> <!-- /.box -->
</div> </div>
@@ -171,169 +154,165 @@
<!-- page script ----------------------------------------------------------- --> <!-- page script ----------------------------------------------------------- -->
<script> <script>
var deviceStatus = 'all';
var parTableRows = 'Front_Devices_Rows';
var parTableOrder = 'Front_Devices_Order';
var tableRows = 10;
var tableOrder = [[3,'desc'], [0,'asc']];
// Read parameters & Initialize components
main();
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
var deviceStatus = ''; function main () {
var period = ''; // get parameter value
$.get('php/server/parameters.php?action=get&parameter='+ parTableRows, function(data) {
var result = JSON.parse(data);
if (Number.isInteger (result) ) {
tableRows = result;
}
// Initialize MAC // get parameter value
var urlParams = new URLSearchParams(window.location.search); $.get('php/server/parameters.php?action=get&parameter='+ parTableOrder, function(data) {
if (urlParams.has ('status') == true) { var result = JSON.parse(data);
deviceStatus = urlParams.get ('status'); result = JSON.parse(result);
} else { if (Array.isArray (result) ) {
deviceStatus = 'all'; tableOrder = result;
} }
// Initialize components // Initialize components with parameters
$(function () { initializeDatatable();
initializeDatatable();
periodChanged(); // query data
getDevicesTotals();
getDevicesList (deviceStatus);
});
}); });
// -----------------------------------------------------------------------------
function periodChanged () {
// Requery totals and list
queryTotals();
queryList (deviceStatus);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function initializeDatatable () { function initializeDatatable () {
var table=
$('#tableDevices').DataTable({ $('#tableDevices').DataTable({
'paging' : true, 'paging' : true,
'lengthChange': true, 'lengthChange' : true,
'searching' : true, 'lengthMenu' : [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, 'All']],
'ordering' : true, 'searching' : true,
'info' : true, 'ordering' : true,
'autoWidth' : false, 'info' : true,
'autoWidth' : false,
'order' : [[3,"desc"], [0,"asc"]],
'columnDefs' : [ // Parameters
{visible: false, targets: [9, 10] }, 'pageLength' : tableRows,
{className: 'text-center', targets: [3, 8] }, 'order' : tableOrder,
{width: '0px', targets: 8 }, // 'order' : [[3,'desc'], [0,'asc']],
{orderData: [10], targets: 7 },
// Device Name 'columnDefs' : [
{targets: [0], {visible: false, targets: [9, 10] },
"createdCell": function (td, cellData, rowData, row, col) { {className: 'text-center', targets: [3, 8] },
$(td).html ('<b><a href="deviceDetails.php?mac='+ rowData[9]+ '&period='+ period +'" class="">'+ cellData +'</a></b>'); {width: '0px', targets: 8 },
} }, {orderData: [10], targets: 7 },
// Favorite // Device Name
{targets: [3], {targets: [0],
"createdCell": function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
if (cellData == 1){ $(td).html ('<b><a href="deviceDetails.php?mac='+ rowData[9] +'" class="">'+ cellData +'</a></b>');
$(td).html ('<i class="fa fa-star text-yellow" style="font-size:16px"></i>'); } },
} else {
$(td).html (''); // Favorite
} {targets: [3],
} }, 'createdCell': function (td, cellData, rowData, row, col) {
if (cellData == 1){
$(td).html ('<i class="fa fa-star text-yellow" style="font-size:16px"></i>');
} else {
$(td).html ('');
}
} },
// Dates // Dates
{targets: [5, 6], {targets: [5, 6],
"createdCell": function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
$(td).html (translateHTMLcodes (cellData)); $(td).html (translateHTMLcodes (cellData));
} }, } },
// Status color // Status color
{targets: [8], {targets: [8],
"createdCell": function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
switch (cellData) { switch (cellData) {
case 'Down': case 'Down': color='red'; break;
color='red'; break; case 'New': color='yellow'; break;
case 'New': case 'On-line': color='green'; break;
color='yellow'; break; case 'Off-line': color='gray text-white'; break;
case 'On-line': default: color='aqua'; break;
color='green'; break; };
case 'Off-line':
color='gray text-white'; break;
default:
color='aqua'; break;
};
$(td).html ('<a href="deviceDetails.php?mac='+ rowData[9]+ '&period='+ period +'" class="badge bg-'+ color +'">'+ cellData +'</a>'); $(td).html ('<a href="deviceDetails.php?mac='+ rowData[9] +'" class="badge bg-'+ color +'">'+ cellData +'</a>');
} }, } },
], ],
// Processing
'processing' : true, 'processing' : true,
'language' : { '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>', 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' emptyTable: 'No data'
} }
}); });
// Save Parameters rows & order when changed
$('#tableDevices').on( 'length.dt', function ( e, settings, len ) {
setParameter (parTableRows, len);
} );
$('#tableDevices').on( 'order.dt', function () {
setParameter (parTableOrder, JSON.stringify (table.order()) );
} );
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function queryTotals () { function getDevicesTotals () {
// debugTimer();
// stop timer // stop timer
stopTimerRefreshData(); stopTimerRefreshData();
// period
period = document.getElementById('period').value;
// get totals and put in boxes // get totals and put in boxes
$.get('php/server/devices.php?action=totals&period='+ period, function(data) { $.get('php/server/devices.php?action=getDevicesTotals', function(data) {
var totalsDevices = JSON.parse(data); var totalsDevices = JSON.parse(data);
$('#devicesAll').html (totalsDevices[0].toLocaleString()); $('#devicesAll').html (totalsDevices[0].toLocaleString());
$('#devicesConnected').html (totalsDevices[1].toLocaleString()); $('#devicesConnected').html (totalsDevices[1].toLocaleString());
$('#devicesNew').html (totalsDevices[2].toLocaleString()); $('#devicesNew').html (totalsDevices[2].toLocaleString());
$('#devicesDown').html (totalsDevices[3].toLocaleString()); $('#devicesDown').html (totalsDevices[3].toLocaleString());
});
// Timer for refresh data // Timer for refresh data
newTimerRefreshData (queryTotals); newTimerRefreshData (getDevicesTotals);
} );
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function queryList (status) { function getDevicesList (status) {
// Save status and period selected // Save status selected
deviceStatus = status; deviceStatus = status;
period = document.getElementById('period').value;
// Defini color & title for the status selected // Define color & title for the status selected
switch (deviceStatus) { switch (deviceStatus) {
case 'all': case 'all': tableTitle = 'Total Devices'; color = 'aqua'; break;
tableTitle = 'Total Devices'; case 'connected': tableTitle = 'Connected Devices'; color = 'green'; break;
color = 'aqua'; case 'new': tableTitle = 'New Devices'; color = 'yellow'; break;
break; case 'down': tableTitle = 'Down Alerts'; color = 'red'; break;
case 'connected': case 'favorites': tableTitle = 'Favorites'; color = 'yellow'; break;
tableTitle = 'Connected Devices'; default: tableTitle = 'Devices'; boxClass = ''; break;
color = 'green';
break;
case 'new':
tableTitle = 'New Devices';
color = 'yellow';
break;
case 'down':
tableTitle = 'Down Alerts';
color = 'red';
break;
case 'favorites':
tableTitle = 'Favorites';
color = 'yellow';
break;
default:
tableTitle = 'Devices';
boxClass = '';
break;
} }
// Set title and color // Set title and color
document.getElementById('tableDevicesTitle').className = 'box-title text-' + color; $('#tableDevicesTitle')[0].className = 'box-title text-'+ color;
document.getElementById('tableDevicesBox').className = 'box box-' + color; $('#tableDevicesBox')[0].className = 'box box-'+ color;
$('#tableDevicesTitle').html (tableTitle); $('#tableDevicesTitle').html (tableTitle);
// Define new datasource URL and reload // Define new datasource URL and reload
$('#tableDevices').DataTable().ajax.url('php/server/devices.php?action=list&status=' + deviceStatus +'&period='+ period ).load(); $('#tableDevices').DataTable().ajax.url(
'php/server/devices.php?action=getDevicesList&status=' + deviceStatus).load();
}; };
</script> </script>

View File

@@ -1,4 +1,12 @@
<!-- ----------------------------------------------------------------------- --> <!-- ---------------------------------------------------------------------------
# Pi.Alert
# Open Source Network Guard / WIFI & LAN intrusion detector
#
# events.php - Front module. Events page
#-------------------------------------------------------------------------------
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3
#--------------------------------------------------------------------------- -->
<?php <?php
require 'php/templates/header.php'; require 'php/templates/header.php';
?> ?>
@@ -13,9 +21,8 @@
</h1> </h1>
<!-- period selector --> <!-- period selector -->
<span class="breadcrumb text-gray50"> <span class="breadcrumb" style="top: 0px;">
Events period: <select class="form-control" id="period" onchange="javascript: periodChanged();">
<select id="period" onchange="javascript: periodChanged();">
<option value="1 day">Today</option> <option value="1 day">Today</option>
<option value="7 days">Last Week</option> <option value="7 days">Last Week</option>
<option value="1 month" selected>Last Month</option> <option value="1 month" selected>Last Month</option>
@@ -23,126 +30,81 @@
<option value="100 years">All info</option> <option value="100 years">All info</option>
</select> </select>
</span> </span>
</section> </section>
<!-- Main content ---------------------------------------------------------- --> <!-- Main content ---------------------------------------------------------- -->
<section class="content"> <section class="content">
<!-- top small box --------------------------------------------------------- -->
<div class="row"> <div class="row">
<!-- top small box --------------------------------------------------------- -->
<div class="col-lg-2 col-sm-4 col-xs-6"> <div class="col-lg-2 col-sm-4 col-xs-6">
<a href="#" onclick="javascript: queryList('all');"> <a href="#" onclick="javascript: getEvents('all');">
<div class="small-box bg-aqua pa-small-box-aqua pa-small-box-2"> <div class="small-box bg-aqua pa-small-box-aqua pa-small-box-2">
<div class="inner"> <div class="inner"> <h3 id="eventsAll"> -- </h3> </div>
<div class="icon"> <i class="fa fa-bolt text-aqua-20"></i> </div>
<h3 id="eventsAll"> -- </h3>
<div class="small-box-footer"> All events <i class="fa fa-arrow-circle-right"></i> </div>
</div>
<div class="icon">
<i class="fa fa-bolt text-aqua-20"></i>
</div>
<div class="small-box-footer">
All events <i class="fa fa-arrow-circle-right"></i>
</div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box --------------------------------------------------------- -->
<div class="col-lg-2 col-sm-4 col-xs-6"> <div class="col-lg-2 col-sm-4 col-xs-6">
<a href="#" onclick="javascript: queryList('sessions');"> <a href="#" onclick="javascript: getEvents('sessions');">
<div class="small-box bg-green pa-small-box-green pa-small-box-2"> <div class="small-box bg-green pa-small-box-green pa-small-box-2">
<div class="inner"> <div class="inner"> <h3 id="eventsSessions"> -- </h3> </div>
<div class="icon"> <i class="fa fa-plug text-green-20"></i> </div>
<h3 id="eventsSessions"> -- </h3>
<div class="small-box-footer"> Sessions <i class="fa fa-arrow-circle-right"></i> </div>
</div>
<div class="icon">
<i class="fa fa-plug text-green-20"></i>
</div>
<div class="small-box-footer">
Sessions <i class="fa fa-arrow-circle-right"></i>
</div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box --------------------------------------------------------- -->
<div class="col-lg-2 col-sm-4 col-xs-6"> <div class="col-lg-2 col-sm-4 col-xs-6">
<a href="#" onclick="javascript: queryList('missing');"> <a href="#" onclick="javascript: getEvents('missing');">
<div class="small-box bg-yellow pa-small-box-yellow pa-small-box-2"> <div class="small-box bg-yellow pa-small-box-yellow pa-small-box-2">
<div class="inner"> <div class="inner"> <h3 id="eventsMissing"> -- </h3> </div>
<div class="icon"> <i class="fa fa-exchange text-yellow-20"></i> </div>
<h3 id="eventsMissing"> -- </h3>
<div class="small-box-footer"> Missing Sessions <i class="fa fa-arrow-circle-right"></i> </div>
</div>
<div class="icon">
<i class="fa fa-exchange text-yellow-20"></i>
</div>
<div class="small-box-footer">
Missing Sessions <i class="fa fa-arrow-circle-right"></i>
</div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box --------------------------------------------------------- -->
<div class="col-lg-2 col-sm-4 col-xs-6"> <div class="col-lg-2 col-sm-4 col-xs-6">
<a href="#" onclick="javascript: queryList('voided');"> <a href="#" onclick="javascript: getEvents('voided');">
<div class="small-box bg-yellow pa-small-box-yellow pa-small-box-2"> <div class="small-box bg-yellow pa-small-box-yellow pa-small-box-2">
<div class="inner"> <div class="inner"> <h3 id="eventsVoided"> -- </h3> </div>
<div class="icon text-aqua-20"> <i class="fa fa-exclamation-circle text-yellow-20"></i> </div>
<h3 id="eventsVoided"> -- </h3>
<div class="small-box-footer"> Voided Sessions <i class="fa fa-arrow-circle-right"></i> </div>
</div>
<div class="icon text-aqua-20">
<i class="fa fa-exclamation-circle text-yellow-20"></i>
</div>
<div class="small-box-footer">
Voided Sessions <i class="fa fa-arrow-circle-right"></i>
</div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box --------------------------------------------------------- -->
<div class="col-lg-2 col-sm-4 col-xs-6"> <div class="col-lg-2 col-sm-4 col-xs-6">
<a href="#" onclick="javascript: queryList('new');"> <a href="#" onclick="javascript: getEvents('new');">
<div class="small-box bg-yellow pa-small-box-yellow pa-small-box-2"> <div class="small-box bg-yellow pa-small-box-yellow pa-small-box-2">
<div class="inner"> <div class="inner"> <h3 id="eventsNewDevices"> -- </h3> </div>
<div class="icon"> <i class="ion ion-plus-round text-yellow-20"></i> </div>
<h3 id="eventsNewDevices"> -- </h3>
<div class="small-box-footer"> New Devices <i class="fa fa-arrow-circle-right"></i> </div>
</div>
<div class="icon">
<i class="ion ion-plus-round text-yellow-20"></i>
</div>
<div class="small-box-footer">
New Devices <i class="fa fa-arrow-circle-right"></i>
</div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box --------------------------------------------------------- -->
<div class="col-lg-2 col-sm-4 col-xs-6"> <div class="col-lg-2 col-sm-4 col-xs-6">
<a href="#" onclick="javascript: queryList('down');"> <a href="#" onclick="javascript: getEvents('down');">
<div class="small-box bg-red pa-small-box-red pa-small-box-2"> <div class="small-box bg-red pa-small-box-red pa-small-box-2">
<div class="inner"> <div class="inner"> <h3 id="eventsDown"> -- </h3> </div>
<div class="icon"> <i class="fa fa-warning text-red-20"></i> </div>
<h3 id="eventsDown"> -- </h3>
<div class="small-box-footer"> Down Alerts <i class="fa fa-arrow-circle-right"></i> </div>
</div>
<div class="icon">
<i class="fa fa-warning text-red-20"></i>
</div>
<div class="small-box-footer">
Down Alerts <i class="fa fa-arrow-circle-right"></i>
</div>
</div> </div>
</a> </a>
</div> </div>
@@ -154,10 +116,13 @@
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<div id="tableEventsBox" class="box"> <div id="tableEventsBox" class="box">
<!-- box-header -->
<div class="box-header"> <div class="box-header">
<h3 id="tableEventsTitle" class="box-title text-gray">Events</h3> <h3 id="tableEventsTitle" class="box-title text-gray">Events</h3>
</div> </div>
<!-- /.box-header -->
<!-- table -->
<div class="box-body table-responsive"> <div class="box-body table-responsive">
<table id="tableEvents" class="table table-bordered table-hover table-striped "> <table id="tableEvents" class="table table-bordered table-hover table-striped ">
<thead> <thead>
@@ -179,6 +144,7 @@
</table> </table>
</div> </div>
<!-- /.box-body --> <!-- /.box-body -->
</div> </div>
<!-- /.box --> <!-- /.box -->
</div> </div>
@@ -208,86 +174,113 @@
<!-- page script ----------------------------------------------------------- --> <!-- page script ----------------------------------------------------------- -->
<script> <script>
var parPeriod = 'Front_Events_Period';
var parTableRows = 'Front_Events_Rows';
// ----------------------------------------------------------------------------- var eventsType = 'all';
var eventsType = ''; var period = '';
var period = ''; var tableRows = 10;
// Initialize MAC // Read parameters & Initialize components
var urlParams = new URLSearchParams(window.location.search); main();
if (urlParams.has ('status') == true) {
eventsType = urlParams.get ('type');
} else {
eventsType = 'all';
}
// Initialize components
$(function () {
initializeDatatable();
periodChanged();
});
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function periodChanged () { function main () {
// Requery totals and list // get parameter value
queryTotals(); $.get('php/server/parameters.php?action=get&parameter='+ parPeriod, function(data) {
queryList (eventsType); var result = JSON.parse(data);
if (result) {
period = result;
$('#period').val(period);
}
// get parameter value
$.get('php/server/parameters.php?action=get&parameter='+ parTableRows, function(data) {
var result = JSON.parse(data);
if (Number.isInteger (result) ) {
tableRows = result;
}
// Initialize components
initializeDatatable();
// query data
getEventsTotals();
getEvents (eventsType);
});
});
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function initializeDatatable () { function initializeDatatable () {
$('#tableEvents').DataTable({ $('#tableEvents').DataTable({
'paging' : true, 'paging' : true,
'lengthChange': true, 'lengthChange' : true,
'searching' : true, 'lengthMenu' : [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, 'All']],
'ordering' : true, 'searching' : true,
'info' : true, 'ordering' : true,
'autoWidth' : false, 'info' : true,
'autoWidth' : false,
'order' : [[0,"desc"], [3,"desc"], [5,"desc"]], 'order' : [[0,"desc"], [3,"desc"], [5,"desc"]],
// Parameters
'pageLength' : tableRows,
'columnDefs' : [ 'columnDefs' : [
{visible: false, targets: [0,5,6,7,8,10] }, {visible: false, targets: [0,5,6,7,8,10] },
{className: 'text-center', targets: [] }, {className: 'text-center', targets: [] },
{orderData: [8], targets: 7 }, {orderData: [8], targets: 7 },
{orderData: [10], targets: 9 }, {orderData: [10], targets: 9 },
// Device Name // Device Name
{targets: [1], {targets: [1],
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
$(td).html ('<b><a href="deviceDetails.php?mac='+ rowData[13]+ '&period='+ period +'" class="">'+ cellData +'</a></b>'); $(td).html ('<b><a href="deviceDetails.php?mac='+ rowData[13] +'" class="">'+ cellData +'</a></b>');
} }, } },
// Replace HTML codes // Replace HTML codes
{targets: [3,4,5,6,7], {targets: [3,4,5,6,7],
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
$(td).html (translateHTMLcodes (cellData)); $(td).html (translateHTMLcodes (cellData));
} } } }
], ],
// Processing
'processing' : true, 'processing' : true,
'language' : { '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>', 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' emptyTable: 'No data'
} }
}); });
// Save Parameter rows when changed
$('#tableEvents').on( 'length.dt', function ( e, settings, len ) {
setParameter (parTableRows, len);
} );
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function queryTotals () { function periodChanged () {
// debugTimer(); // Save Parameter Period
period = $('#period').val();
setParameter (parPeriod, period);
// Requery totals and events
getEventsTotals();
getEvents (eventsType);
}
// -----------------------------------------------------------------------------
function getEventsTotals () {
// stop timer // stop timer
stopTimerRefreshData(); stopTimerRefreshData();
// period
period = document.getElementById('period').value;
// get totals and put in boxes // get totals and put in boxes
$.get('php/server/events.php?action=totals&period='+ period, function(data) { $.get('php/server/events.php?action=getEventsTotals&period='+ period, function(data) {
var totalsEvents = JSON.parse(data); var totalsEvents = JSON.parse(data);
$('#eventsAll').html (totalsEvents[0].toLocaleString()); $('#eventsAll').html (totalsEvents[0].toLocaleString());
@@ -296,57 +289,32 @@ function queryTotals () {
$('#eventsVoided').html (totalsEvents[3].toLocaleString()); $('#eventsVoided').html (totalsEvents[3].toLocaleString());
$('#eventsNewDevices').html (totalsEvents[4].toLocaleString()); $('#eventsNewDevices').html (totalsEvents[4].toLocaleString());
$('#eventsDown').html (totalsEvents[5].toLocaleString()); $('#eventsDown').html (totalsEvents[5].toLocaleString());
});
// Timer for refresh data // Timer for refresh data
newTimerRefreshData (queryTotals); newTimerRefreshData (getEventsTotals);
});
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function queryList (p_eventsType) { function getEvents (p_eventsType) {
// Save status and period selected // Save status selected
eventsType = p_eventsType; eventsType = p_eventsType;
period = document.getElementById('period').value;
// Define color & title for the status selected // Define color & title for the status selected
sesionCols = false;
switch (eventsType) { switch (eventsType) {
case 'all': case 'all': tableTitle = 'All Events'; color = 'aqua'; sesionCols = false; break;
tableTitle = 'All Events'; case 'sessions': tableTitle = 'Sessions'; color = 'green'; sesionCols = true; break;
color = 'aqua'; case 'missing': tableTitle = 'Missing Events'; color = 'yellow'; sesionCols = true; break;
break; case 'voided': tableTitle = 'Voided Events'; color = 'yellow'; sesionCols = false; break;
case 'sessions': case 'new': tableTitle = 'New Devices Events'; color = 'yellow'; sesionCols = false; break;
tableTitle = 'Sessions'; case 'down': tableTitle = 'Down Alerts'; color = 'red'; sesionCols = false; break;
color = 'green'; default: tableTitle = 'Events'; boxClass = ''; sesionCols = false; break;
sesionCols = true;
break;
case 'missing':
tableTitle = 'Missing Events';
color = 'yellow';
sesionCols = true;
break;
case 'voided':
tableTitle = 'Voided Events';
color = 'yellow';
break;
case 'new':
tableTitle = 'New Devices Events';
color = 'yellow';
break;
case 'down':
tableTitle = 'Down Alerts';
color = 'red';
break;
default:
tableTitle = 'Events';
boxClass = '';
break;
} }
// Set title and color // Set title and color
document.getElementById('tableEventsTitle').className = 'box-title text-' + color; $('#tableEventsTitle')[0].className = 'box-title text-' + color;
document.getElementById('tableEventsBox').className = 'box box-' + color; $('#tableEventsBox')[0].className = 'box box-' + color;
$('#tableEventsTitle').html (tableTitle); $('#tableEventsTitle').html (tableTitle);
// Coluumns Visibility // Coluumns Visibility
@@ -360,7 +328,7 @@ function queryList (p_eventsType) {
$('#tableEvents').DataTable().clear(); $('#tableEvents').DataTable().clear();
$('#tableEvents').DataTable().draw(); $('#tableEvents').DataTable().draw();
$('#tableEvents').DataTable().order ([0,"desc"], [3,"desc"], [5,"desc"]); $('#tableEvents').DataTable().order ([0,"desc"], [3,"desc"], [5,"desc"]);
$('#tableEvents').DataTable().ajax.url('php/server/events.php?action=list&type=' + eventsType +'&period='+ period ).load(); $('#tableEvents').DataTable().ajax.url('php/server/events.php?action=getEvents&type=' + eventsType +'&period='+ period ).load();
}; };
</script> </script>

View File

@@ -1,4 +1,12 @@
<!-- ----------------------------------------------------------------------- --> <!-- ---------------------------------------------------------------------------
# Pi.Alert
# Open Source Network Guard / WIFI & LAN intrusion detector
#
# devices.php - Front module. Devices list page
#-------------------------------------------------------------------------------
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3
#--------------------------------------------------------------------------- -->
<?php <?php
require 'php/templates/header.php'; require 'php/templates/header.php';
?> ?>
@@ -11,102 +19,73 @@
<h1 id="pageTitle"> <h1 id="pageTitle">
Devices Devices
</h1> </h1>
<!-- period selector -->
<span class="breadcrumb text-gray50">
New Devices period:
<select id="period" onchange="javascript: periodChanged();">
<option value="1 day">Today</option>
<option value="7 days">Last Week</option>
<option value="1 month" selected>Last Month</option>
<option value="1 year">Last Year</option>
<option value="100 years">All info</option>
</select>
</span>
</section> </section>
<!-- Main content ---------------------------------------------------------- --> <!-- Main content ---------------------------------------------------------- -->
<section class="content"> <section class="content">
<!-- top small box 1 ------------------------------------------------------- -->
<div class="row"> <div class="row">
<!-- top small box --------------------------------------------------------- -->
<div class="col-lg-3 col-sm-6 col-xs-6"> <div class="col-lg-3 col-sm-6 col-xs-6">
<a href="#" onclick="javascript: queryList('all');"> <a href="#" onclick="javascript: getDevicesList('all');">
<div class="small-box bg-aqua pa-small-box-aqua"> <div class="small-box bg-aqua pa-small-box-aqua">
<div class="inner"> <div class="inner">
<h4>Total Devices</h4> <h4>Total Devices</h4>
<h3 id="devicesAll"> -- </h3> <h3 id="devicesAll"> -- </h3>
</div>
<div class="icon">
<i class="fa fa-laptop"></i>
</div>
<div class="small-box-footer">
Details <i class="fa fa-arrow-circle-right"></i>
</div> </div>
<div class="icon"> <i class="fa fa-laptop"></i> </div>
<div class="small-box-footer"> Details <i class="fa fa-arrow-circle-right"></i> </div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box 2 ------------------------------------------------------- -->
<div class="col-lg-3 col-sm-6 col-xs-6"> <div class="col-lg-3 col-sm-6 col-xs-6">
<a href="#" onclick="javascript: queryList('connected');"> <a href="#" onclick="javascript: getDevicesList('connected');">
<div class="small-box bg-green pa-small-box-green"> <div class="small-box bg-green pa-small-box-green">
<div class="inner"> <div class="inner">
<h4>Connected</h4> <h4>Connected</h4>
<h3 id="devicesConnected"> -- </h3> <h3 id="devicesConnected"> -- </h3>
</div>
<div class="icon">
<i class="fa fa-plug"></i>
</div>
<div class="small-box-footer">
Details <i class="fa fa-arrow-circle-right"></i>
</div> </div>
<div class="icon"> <i class="fa fa-plug"></i> </div>
<div class="small-box-footer"> Details <i class="fa fa-arrow-circle-right"></i> </div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box 3 ------------------------------------------------------- -->
<div class="col-lg-3 col-sm-6 col-xs-6"> <div class="col-lg-3 col-sm-6 col-xs-6">
<a href="#" onclick="javascript: queryList('new');"> <a href="#" onclick="javascript: getDevicesList('new');">
<div class="small-box bg-yellow pa-small-box-yellow"> <div class="small-box bg-yellow pa-small-box-yellow">
<div class="inner"> <div class="inner">
<h4>New Devices</h4> <h4>New Devices</h4>
<h3 id="devicesNew"> -- </h3> <h3 id="devicesNew"> -- </h3>
</div>
<div class="icon">
<i class="ion ion-plus-round"></i>
</div>
<div class="small-box-footer">
Details <i class="fa fa-arrow-circle-right"></i>
</div> </div>
<div class="icon"> <i class="ion ion-plus-round"></i> </div>
<div class="small-box-footer"> Details <i class="fa fa-arrow-circle-right"></i> </div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box 4 ------------------------------------------------------- -->
<div class="col-lg-3 col-sm-6 col-xs-6"> <div class="col-lg-3 col-sm-6 col-xs-6">
<a href="#" onclick="javascript: queryList('down');"> <a href="#" onclick="javascript: getDevicesList('down');">
<div class="small-box bg-red pa-small-box-red"> <div class="small-box bg-red pa-small-box-red">
<div class="inner"> <div class="inner">
<h4>Down Alerts</h4> <h4>Down Alerts</h4>
<h3 id="devicesDown"> -- </h3> <h3 id="devicesDown"> -- </h3>
</div>
<div class="icon">
<i class="fa fa-warning"></i>
</div>
<div class="small-box-footer">
Details <i class="fa fa-arrow-circle-right"></i>
</div> </div>
<div class="icon"> <i class="fa fa-warning"></i> </div>
<div class="small-box-footer"> Details <i class="fa fa-arrow-circle-right"></i> </div>
</div> </div>
</a> </a>
</div> </div>
@@ -118,12 +97,15 @@
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<div id="tableDevicesBox" class="box"> <div id="tableDevicesBox" class="box">
<!-- box-header -->
<div class="box-header"> <div class="box-header">
<h3 id="tableDevicesTitle" class="box-title text-gray">Devices</h3> <h3 id="tableDevicesTitle" class="box-title text-gray">Devices</h3>
</div> </div>
<!-- /.box-header -->
<!-- table -->
<div class="box-body table-responsive"> <div class="box-body table-responsive">
<table id="tableDevices" class="table table-bordered table-hover table-striped "> <table id="tableDevices" class="table table-bordered table-hover table-striped">
<thead> <thead>
<tr> <tr>
<th>Name</th> <th>Name</th>
@@ -142,6 +124,7 @@
</table> </table>
</div> </div>
<!-- /.box-body --> <!-- /.box-body -->
</div> </div>
<!-- /.box --> <!-- /.box -->
</div> </div>
@@ -171,169 +154,165 @@
<!-- page script ----------------------------------------------------------- --> <!-- page script ----------------------------------------------------------- -->
<script> <script>
var deviceStatus = 'all';
var parTableRows = 'Front_Devices_Rows';
var parTableOrder = 'Front_Devices_Order';
var tableRows = 10;
var tableOrder = [[3,'desc'], [0,'asc']];
// Read parameters & Initialize components
main();
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
var deviceStatus = ''; function main () {
var period = ''; // get parameter value
$.get('php/server/parameters.php?action=get&parameter='+ parTableRows, function(data) {
var result = JSON.parse(data);
if (Number.isInteger (result) ) {
tableRows = result;
}
// Initialize MAC // get parameter value
var urlParams = new URLSearchParams(window.location.search); $.get('php/server/parameters.php?action=get&parameter='+ parTableOrder, function(data) {
if (urlParams.has ('status') == true) { var result = JSON.parse(data);
deviceStatus = urlParams.get ('status'); result = JSON.parse(result);
} else { if (Array.isArray (result) ) {
deviceStatus = 'all'; tableOrder = result;
} }
// Initialize components // Initialize components with parameters
$(function () { initializeDatatable();
initializeDatatable();
periodChanged(); // query data
getDevicesTotals();
getDevicesList (deviceStatus);
});
}); });
// -----------------------------------------------------------------------------
function periodChanged () {
// Requery totals and list
queryTotals();
queryList (deviceStatus);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function initializeDatatable () { function initializeDatatable () {
var table=
$('#tableDevices').DataTable({ $('#tableDevices').DataTable({
'paging' : true, 'paging' : true,
'lengthChange': true, 'lengthChange' : true,
'searching' : true, 'lengthMenu' : [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, 'All']],
'ordering' : true, 'searching' : true,
'info' : true, 'ordering' : true,
'autoWidth' : false, 'info' : true,
'autoWidth' : false,
'order' : [[3,"desc"], [0,"asc"]],
'columnDefs' : [ // Parameters
{visible: false, targets: [9, 10] }, 'pageLength' : tableRows,
{className: 'text-center', targets: [3, 8] }, 'order' : tableOrder,
{width: '0px', targets: 8 }, // 'order' : [[3,'desc'], [0,'asc']],
{orderData: [10], targets: 7 },
// Device Name 'columnDefs' : [
{targets: [0], {visible: false, targets: [9, 10] },
"createdCell": function (td, cellData, rowData, row, col) { {className: 'text-center', targets: [3, 8] },
$(td).html ('<b><a href="deviceDetails.php?mac='+ rowData[9]+ '&period='+ period +'" class="">'+ cellData +'</a></b>'); {width: '0px', targets: 8 },
} }, {orderData: [10], targets: 7 },
// Favorite // Device Name
{targets: [3], {targets: [0],
"createdCell": function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
if (cellData == 1){ $(td).html ('<b><a href="deviceDetails.php?mac='+ rowData[9] +'" class="">'+ cellData +'</a></b>');
$(td).html ('<i class="fa fa-star text-yellow" style="font-size:16px"></i>'); } },
} else {
$(td).html (''); // Favorite
} {targets: [3],
} }, 'createdCell': function (td, cellData, rowData, row, col) {
if (cellData == 1){
$(td).html ('<i class="fa fa-star text-yellow" style="font-size:16px"></i>');
} else {
$(td).html ('');
}
} },
// Dates // Dates
{targets: [5, 6], {targets: [5, 6],
"createdCell": function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
$(td).html (translateHTMLcodes (cellData)); $(td).html (translateHTMLcodes (cellData));
} }, } },
// Status color // Status color
{targets: [8], {targets: [8],
"createdCell": function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
switch (cellData) { switch (cellData) {
case 'Down': case 'Down': color='red'; break;
color='red'; break; case 'New': color='yellow'; break;
case 'New': case 'On-line': color='green'; break;
color='yellow'; break; case 'Off-line': color='gray text-white'; break;
case 'On-line': default: color='aqua'; break;
color='green'; break; };
case 'Off-line':
color='gray text-white'; break;
default:
color='aqua'; break;
};
$(td).html ('<a href="deviceDetails.php?mac='+ rowData[9]+ '&period='+ period +'" class="badge bg-'+ color +'">'+ cellData +'</a>'); $(td).html ('<a href="deviceDetails.php?mac='+ rowData[9] +'" class="badge bg-'+ color +'">'+ cellData +'</a>');
} }, } },
], ],
// Processing
'processing' : true, 'processing' : true,
'language' : { '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>', 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' emptyTable: 'No data'
} }
}); });
// Save Parameters rows & order when changed
$('#tableDevices').on( 'length.dt', function ( e, settings, len ) {
setParameter (parTableRows, len);
} );
$('#tableDevices').on( 'order.dt', function () {
setParameter (parTableOrder, JSON.stringify (table.order()) );
} );
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function queryTotals () { function getDevicesTotals () {
// debugTimer();
// stop timer // stop timer
stopTimerRefreshData(); stopTimerRefreshData();
// period
period = document.getElementById('period').value;
// get totals and put in boxes // get totals and put in boxes
$.get('php/server/devices.php?action=totals&period='+ period, function(data) { $.get('php/server/devices.php?action=getDevicesTotals', function(data) {
var totalsDevices = JSON.parse(data); var totalsDevices = JSON.parse(data);
$('#devicesAll').html (totalsDevices[0].toLocaleString()); $('#devicesAll').html (totalsDevices[0].toLocaleString());
$('#devicesConnected').html (totalsDevices[1].toLocaleString()); $('#devicesConnected').html (totalsDevices[1].toLocaleString());
$('#devicesNew').html (totalsDevices[2].toLocaleString()); $('#devicesNew').html (totalsDevices[2].toLocaleString());
$('#devicesDown').html (totalsDevices[3].toLocaleString()); $('#devicesDown').html (totalsDevices[3].toLocaleString());
});
// Timer for refresh data // Timer for refresh data
newTimerRefreshData (queryTotals); newTimerRefreshData (getDevicesTotals);
} );
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function queryList (status) { function getDevicesList (status) {
// Save status and period selected // Save status selected
deviceStatus = status; deviceStatus = status;
period = document.getElementById('period').value;
// Defini color & title for the status selected // Define color & title for the status selected
switch (deviceStatus) { switch (deviceStatus) {
case 'all': case 'all': tableTitle = 'Total Devices'; color = 'aqua'; break;
tableTitle = 'Total Devices'; case 'connected': tableTitle = 'Connected Devices'; color = 'green'; break;
color = 'aqua'; case 'new': tableTitle = 'New Devices'; color = 'yellow'; break;
break; case 'down': tableTitle = 'Down Alerts'; color = 'red'; break;
case 'connected': case 'favorites': tableTitle = 'Favorites'; color = 'yellow'; break;
tableTitle = 'Connected Devices'; default: tableTitle = 'Devices'; boxClass = ''; break;
color = 'green';
break;
case 'new':
tableTitle = 'New Devices';
color = 'yellow';
break;
case 'down':
tableTitle = 'Down Alerts';
color = 'red';
break;
case 'favorites':
tableTitle = 'Favorites';
color = 'yellow';
break;
default:
tableTitle = 'Devices';
boxClass = '';
break;
} }
// Set title and color // Set title and color
document.getElementById('tableDevicesTitle').className = 'box-title text-' + color; $('#tableDevicesTitle')[0].className = 'box-title text-'+ color;
document.getElementById('tableDevicesBox').className = 'box box-' + color; $('#tableDevicesBox')[0].className = 'box box-'+ color;
$('#tableDevicesTitle').html (tableTitle); $('#tableDevicesTitle').html (tableTitle);
// Define new datasource URL and reload // Define new datasource URL and reload
$('#tableDevices').DataTable().ajax.url('php/server/devices.php?action=list&status=' + deviceStatus +'&period='+ period ).load(); $('#tableDevices').DataTable().ajax.url(
'php/server/devices.php?action=getDevicesList&status=' + deviceStatus).load();
}; };
</script> </script>

View File

@@ -1,9 +1,89 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Pi.Alert Common Javascript functions * Pi.Alert
* Open Source Network Guard / WIFI & LAN intrusion detector
*
* pialert_common.js - Front module. Common Javascript functions
*-------------------------------------------------------------------------------
* Puche 2021 pi.alert.application@gmail.com GNU GPLv3
----------------------------------------------------------------------------- */ ----------------------------------------------------------------------------- */
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
var timerRefreshData = '' var timerRefreshData = ''
var modalCallbackFunction = '';
// -----------------------------------------------------------------------------
function showModal (title, message, btnCancel, btnOK, callbackFunction) {
// set captions
$('#modal-title').html (title);
$('#modal-message').html (message);
$('#modal-cancel').html (btnCancel);
$('#modal-OK').html (btnOK);
modalCallbackFunction = callbackFunction;
// Show modal
$('#modal-warning').modal('show');
}
// -----------------------------------------------------------------------------
function modalOK () {
// Hide modal
$('#modal-warning').modal('hide');
// timer to execute function
window.setTimeout( function() {
window[modalCallbackFunction]();
}, 100);
}
// -----------------------------------------------------------------------------
function showMessage (textMessage="") {
if (textMessage.toLowerCase().includes("error") ) {
// show error
alert (textMessage);
} else {
// show temporal notification
$("#alert-message").html (textMessage);
$("#notification").fadeIn(1, function () {
window.setTimeout( function() {
$("#notification").fadeOut(500)
}, 3000);
} );
}
}
// -----------------------------------------------------------------------------
function setParameter (parameter, value) {
// Retry
$.get('php/server/parameters.php?action=set&parameter=' + parameter +
'&value='+ value,
function(data) {
if (data != "OK") {
// Retry
sleep (200);
$.get('php/server/parameters.php?action=set&parameter=' + parameter +
'&value='+ value,
function(data) {
if (data != "OK") {
// alert (data);
} else {
// alert ("OK. Second attempt");
};
} );
};
} );
}
// -----------------------------------------------------------------------------
function sleep(milliseconds) {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
} while (currentDate - date < milliseconds);
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -35,5 +115,7 @@ function newTimerRefreshData (refeshFunction) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function debugTimer () { function debugTimer () {
document.getElementById ('pageTitle').innerHTML = (new Date().getSeconds()); $('#pageTitle').html (new Date().getSeconds());
} }

View File

@@ -1,32 +1,40 @@
<?php <?php
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// PHP Open DB // Pi.Alert
// Open Source Network Guard / WIFI & LAN intrusion detector
//
// db.php - Front module. Server side. DB common file
//------------------------------------------------------------------------------
// Puche 2021 pi.alert.application@gmail.com GNU GPLv3
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// DB File Path // DB File Path
$DBFILE = '../../../db/pialert.db'; $DBFILE = '../../../db/pialert.db';
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Connect DB // Connect DB
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function SQLite3_connect ($trytoreconnect) { function SQLite3_connect ($trytoreconnect) {
global $DBFILE; global $DBFILE;
try try
{
// connect to database
// return new SQLite3($DBFILE, SQLITE3_OPEN_READONLY);
return new SQLite3($DBFILE, SQLITE3_OPEN_READWRITE);
}
catch (Exception $exception)
{
// sqlite3 throws an exception when it is unable to connect
// try to reconnect one time after 3 seconds
if($trytoreconnect)
{ {
// connect to database sleep(3);
// return new SQLite3($DBFILE, SQLITE3_OPEN_READONLY); return SQLite3_connect(false);
return new SQLite3($DBFILE, SQLITE3_OPEN_READWRITE);
}
catch (Exception $exception)
{
// sqlite3 throws an exception when it is unable to connect
// try to reconnect one time after 3 seconds
if($trytoreconnect)
{
sleep(3);
return SQLite3_connect(false);
}
} }
}
} }
@@ -34,19 +42,19 @@ function SQLite3_connect ($trytoreconnect) {
// Open DB // Open DB
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function OpenDB () { function OpenDB () {
global $DBFILE; global $DBFILE;
global $db; global $db;
if(strlen($DBFILE) == 0) if(strlen($DBFILE) == 0)
{ {
die ('No database available'); die ('Database no available');
} }
$db = SQLite3_connect(true); $db = SQLite3_connect(true);
if(!$db) if(!$db)
{ {
die ('Error connecting to database'); die ('Error connecting to database');
} }
} }
?> ?>

View File

@@ -1,14 +1,25 @@
<?php <?php
//------------------------------------------------------------------------------
// Pi.Alert
// Open Source Network Guard / WIFI & LAN intrusion detector
//
// devices.php - Front module. Server side. Manage Devices
//------------------------------------------------------------------------------
// Puche 2021 pi.alert.application@gmail.com GNU GPLv3
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// External files // External files
require 'db.php'; require 'db.php';
require 'util.php'; require 'util.php';
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Action selector // Action selector
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Set maximum execution time to 1 minute // Set maximum execution time to 15 seconds
ini_set ('max_execution_time','60'); ini_set ('max_execution_time','15');
// Open DB // Open DB
OpenDB(); OpenDB();
@@ -17,23 +28,152 @@
if (isset ($_REQUEST['action']) && !empty ($_REQUEST['action'])) { if (isset ($_REQUEST['action']) && !empty ($_REQUEST['action'])) {
$action = $_REQUEST['action']; $action = $_REQUEST['action'];
switch ($action) { switch ($action) {
case 'totals': queryTotals(); break; case 'getDeviceData': getDeviceData(); break;
case 'list': queryList(); break; case 'setDeviceData': setDeviceData(); break;
case 'queryDeviceData': queryDeviceData(); break; case 'deleteDevice': deleteDevice(); break;
case 'updateData': updateDeviceData(); break;
case 'calendar': queryCalendarList(); break; case 'getDevicesTotals': getDevicesTotals(); break;
case 'queryOwners': queryOwners(); break; case 'getDevicesList': getDevicesList(); break;
case 'queryDeviceTypes': queryDeviceTypes(); break; case 'getDevicesListCalendar': getDevicesListCalendar(); break;
case 'queryGroups': queryGroups(); break;
default: logServerConsole ('Action: '. $action); break; case 'getOwners': getOwners(); break;
case 'getDeviceTypes': getDeviceTypes(); break;
case 'getGroups': getGroups(); break;
case 'getLocations': getLocations(); break;
default: logServerConsole ('Action: '. $action); break;
} }
} }
//------------------------------------------------------------------------------
// Query Device Data
//------------------------------------------------------------------------------
function getDeviceData() {
global $db;
// Request Parameters
$periodDate = getDateFromPeriod();
$mac = $_REQUEST['mac'];
// Device Data
$sql = 'SELECT *,
CASE WHEN dev_AlertDeviceDown=1 AND dev_PresentLastScan=0 THEN "Down"
WHEN dev_PresentLastScan=1 THEN "On-line"
ELSE "Off-line" END as dev_Status
FROM Devices
WHERE dev_MAC="'. $mac .'"';
$result = $db->query($sql);
$row = $result -> fetchArray (SQLITE3_ASSOC);
$deviceData = $row;
$deviceData['dev_FirstConnection'] = formatDate ($row['dev_FirstConnection']); // Date formated
$deviceData['dev_LastConnection'] = formatDate ($row['dev_LastConnection']); // Date formated
// Count Totals
$condition = ' WHERE eve_MAC="'. $mac .'" AND eve_DateTime >= '. $periodDate;
// Connections
$sql = 'SELECT COUNT(*) FROM Sessions
WHERE ses_MAC="'. $mac .'"
AND ( ses_DateTimeConnection >= '. $periodDate .'
OR ses_DateTimeDisconnection >= '. $periodDate .'
OR ses_StillConnected = 1 )';
$result = $db->query($sql);
$row = $result -> fetchArray (SQLITE3_NUM);
$deviceData['dev_Sessions'] = $row[0];
// Events
$sql = 'SELECT COUNT(*) FROM Events '. $condition .' AND eve_EventType <> "Connected" AND eve_EventType <> "Disconnected" ';
$result = $db->query($sql);
$row = $result -> fetchArray (SQLITE3_NUM);
$deviceData['dev_Events'] = $row[0];
// Donw Alerts
$sql = 'SELECT COUNT(*) FROM Events '. $condition .' AND eve_EventType = "Device Down"';
$result = $db->query($sql);
$row = $result -> fetchArray (SQLITE3_NUM);
$deviceData['dev_DownAlerts'] = $row[0];
// Presence hours
$sql = 'SELECT SUM (julianday (IFNULL (ses_DateTimeDisconnection, DATETIME("now")))
- julianday (CASE WHEN ses_DateTimeConnection < '. $periodDate .' THEN '. $periodDate .'
ELSE ses_DateTimeConnection END)) *24
FROM Sessions
WHERE ses_MAC="'. $mac .'"
AND ses_DateTimeConnection IS NOT NULL
AND (ses_DateTimeDisconnection IS NOT NULL OR ses_StillConnected = 1 )
AND ( ses_DateTimeConnection >= '. $periodDate .'
OR ses_DateTimeDisconnection >= '. $periodDate .'
OR ses_StillConnected = 1 )';
$result = $db->query($sql);
$row = $result -> fetchArray (SQLITE3_NUM);
$deviceData['dev_PresenceHours'] = round ($row[0]);
// Return json
echo (json_encode ($deviceData));
}
//------------------------------------------------------------------------------
// Update Device Data
//------------------------------------------------------------------------------
function setDeviceData() {
global $db;
// sql
$sql = 'UPDATE Devices SET
dev_Name = "'. quotes($_REQUEST['name']) .'",
dev_Owner = "'. quotes($_REQUEST['owner']) .'",
dev_DeviceType = "'. quotes($_REQUEST['type']) .'",
dev_Vendor = "'. quotes($_REQUEST['vendor']) .'",
dev_Favorite = "'. quotes($_REQUEST['favorite']) .'",
dev_Group = "'. quotes($_REQUEST['group']) .'",
dev_Location = "'. quotes($_REQUEST['location']) .'",
dev_Comments = "'. quotes($_REQUEST['comments']) .'",
dev_StaticIP = "'. quotes($_REQUEST['staticIP']) .'",
dev_ScanCycle = "'. quotes($_REQUEST['scancycle']) .'",
dev_AlertEvents = "'. quotes($_REQUEST['alertevents']) .'",
dev_AlertDeviceDown = "'. quotes($_REQUEST['alertdown']) .'",
dev_SkipRepeated = "'. quotes($_REQUEST['skiprepeated']) .'",
dev_NewDevice = "'. quotes($_REQUEST['newdevice']) .'"
WHERE dev_MAC="' . $_REQUEST['mac'] .'"';
// update Data
$result = $db->query($sql);
// check result
if ($result == TRUE) {
echo "Device updated successfully";
} else {
echo "Error updating device\n\n$sql \n\n". $db->lastErrorMsg();
}
}
//------------------------------------------------------------------------------
// Delete Device
//------------------------------------------------------------------------------
function deleteDevice() {
global $db;
// sql
$sql = 'DELETE FROM Devices WHERE dev_MAC="' . $_REQUEST['mac'] .'"';
// execute sql
$result = $db->query($sql);
// check result
if ($result == TRUE) {
echo "Device deleted successfully";
} else {
echo "Error deleting device\n\n$sql \n\n". $db->lastErrorMsg();
}
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Query total numbers of Devices by status // Query total numbers of Devices by status
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function queryTotals() { function getDevicesTotals() {
global $db; global $db;
// All // All
@@ -42,43 +182,42 @@ function queryTotals() {
$devices = $row[0]; $devices = $row[0];
// Connected // Connected
$result = $db->query('SELECT COUNT(*) FROM Devices ' . getDeviceCondition ('connected') ); $result = $db->query('SELECT COUNT(*) FROM Devices '. getDeviceCondition ('connected') );
$row = $result -> fetchArray (SQLITE3_NUM); $row = $result -> fetchArray (SQLITE3_NUM);
$connected = $row[0]; $connected = $row[0];
// New // New
$result = $db->query('SELECT COUNT(*) FROM Devices ' . getDeviceCondition ('new') ); $result = $db->query('SELECT COUNT(*) FROM Devices '. getDeviceCondition ('new') );
$row = $result -> fetchArray (SQLITE3_NUM); $row = $result -> fetchArray (SQLITE3_NUM);
$newDevices = $row[0]; $newDevices = $row[0];
// Down Alerts // Down Alerts
$result = $db->query('SELECT COUNT(*) FROM Devices ' . getDeviceCondition ('down')); $result = $db->query('SELECT COUNT(*) FROM Devices '. getDeviceCondition ('down'));
$row = $result -> fetchArray (SQLITE3_NUM); $row = $result -> fetchArray (SQLITE3_NUM);
$devicesDownAlert = $row[0]; $devicesDownAlert = $row[0];
echo (json_encode (array ($devices, $connected, $newDevices, $devicesDownAlert))); echo (json_encode (array ($devices, $connected, $newDevices,
$devicesDownAlert)));
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Query the List of devices in a determined Status // Query the List of devices in a determined Status
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function queryList() { function getDevicesList() {
global $db; global $db;
// Request Parameters
$periodDate = getDateFromPeriod();
// SQL // SQL
$condition = getDeviceCondition ($_REQUEST['status']); $condition = getDeviceCondition ($_REQUEST['status']);
$result = $db->query('SELECT *, $sql = 'SELECT *, CASE
CASE WHEN dev_AlertDeviceDown=1 AND dev_PresentLastScan=0 THEN "Down" WHEN dev_AlertDeviceDown=1 AND dev_PresentLastScan=0 THEN "Down"
WHEN dev_FirstConnection >= ' . $periodDate . ' THEN "New" WHEN dev_NewDevice=1 THEN "New"
WHEN dev_PresentLastScan=1 THEN "On-line" WHEN dev_PresentLastScan=1 THEN "On-line"
ELSE "Off-line" ELSE "Off-line"
END AS dev_Status END AS dev_Status
FROM Devices ' . $condition); FROM Devices '. $condition;
$result = $db->query($sql);
// arrays of rows // arrays of rows
$tableData = array(); $tableData = array();
@@ -94,7 +233,7 @@ function queryList() {
$row['dev_Status'], $row['dev_Status'],
$row['dev_MAC'], // MAC (hidden) $row['dev_MAC'], // MAC (hidden)
formatIPlong ($row['dev_LastIP']) // IP orderable formatIPlong ($row['dev_LastIP']) // IP orderable
); );
} }
// Control no rows // Control no rows
@@ -106,130 +245,13 @@ function queryList() {
echo (json_encode ($tableData)); echo (json_encode ($tableData));
} }
//------------------------------------------------------------------------------
// Query the List of Owners
//------------------------------------------------------------------------------
function queryOwners() {
global $db;
// SQL
$result = $db->query('SELECT DISTINCT 1 as dev_Order, dev_Owner
FROM Devices
WHERE dev_Owner <> "(unknown)" AND dev_Owner <> ""
AND dev_Favorite = 1
UNION
SELECT DISTINCT 2 as dev_Order, dev_Owner
FROM Devices
WHERE dev_Owner <> "(unknown)" AND dev_Owner <> ""
AND dev_Favorite = 0
AND dev_Owner NOT IN (SELECT dev_Owner FROM Devices WHERE dev_Favorite = 1)
ORDER BY 1,2 ');
// arrays of rows
$tableData = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
$tableData[] = array ('order' => $row['dev_Order'],
'name' => $row['dev_Owner']);
}
// Return json
echo (json_encode ($tableData));
}
//------------------------------------------------------------------------------
// Query the List of types
//------------------------------------------------------------------------------
function queryDeviceTypes() {
global $db;
// SQL
$result = $db->query('SELECT DISTINCT 9 as dev_Order, dev_DeviceType
FROM Devices
WHERE dev_DeviceType NOT IN ("",
"Smartphone", "Tablet",
"Laptop", "Mini PC", "PC", "Printer", "Server",
"Game Console", "SmartTV", "TV Decoder", "Virtual Assistance",
"Clock", "House Appliance", "Phone", "Radio",
"AP", "NAS", "PLC", "Router")
UNION SELECT 1 as dev_Order, "Smartphone"
UNION SELECT 1 as dev_Order, "Tablet"
UNION SELECT 2 as dev_Order, "Laptop"
UNION SELECT 2 as dev_Order, "Mini PC"
UNION SELECT 2 as dev_Order, "PC"
UNION SELECT 2 as dev_Order, "Printer"
UNION SELECT 2 as dev_Order, "Server"
UNION SELECT 3 as dev_Order, "Game Console"
UNION SELECT 3 as dev_Order, "SmartTV"
UNION SELECT 3 as dev_Order, "TV Decoder"
UNION SELECT 3 as dev_Order, "Virtual Assistance"
UNION SELECT 4 as dev_Order, "Clock"
UNION SELECT 4 as dev_Order, "House Appliance"
UNION SELECT 4 as dev_Order, "Phone"
UNION SELECT 4 as dev_Order, "Radio"
UNION SELECT 5 as dev_Order, "AP"
UNION SELECT 5 as dev_Order, "NAS"
UNION SELECT 5 as dev_Order, "PLC"
UNION SELECT 5 as dev_Order, "Router"
UNION SELECT 10 as dev_Order, "Other"
ORDER BY 1,2 ');
// arrays of rows
$tableData = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
$tableData[] = array ('order' => $row['dev_Order'],
'name' => $row['dev_DeviceType']);
}
// Return json
echo (json_encode ($tableData));
}
//------------------------------------------------------------------------------
// Query the List of groups
//------------------------------------------------------------------------------
function queryGroups() {
global $db;
// SQL
$result = $db->query('SELECT DISTINCT 1 as dev_Order, dev_Group
FROM Devices
WHERE dev_Group <> "(unknown)" AND dev_Group <> "Others" AND dev_Group <> ""
UNION SELECT 1 as dev_Order, "Always on"
UNION SELECT 1 as dev_Order, "Friends"
UNION SELECT 1 as dev_Order, "Personal"
UNION SELECT 2 as dev_Order, "Others"
ORDER BY 1,2 ');
// arrays of rows
$tableData = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
$tableData[] = array ('order' => $row['dev_Order'],
'name' => $row['dev_Group']);
}
// Return json
echo (json_encode ($tableData));
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Query the List of devices for calendar // Query the List of devices for calendar
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function queryCalendarList() { function getDevicesListCalendar() {
global $db; global $db;
// Request Parameters
$periodDate = getDateFromPeriod();
// SQL // SQL
$condition = getDeviceCondition ($_REQUEST['status']); $condition = getDeviceCondition ($_REQUEST['status']);
$result = $db->query('SELECT * FROM Devices ' . $condition); $result = $db->query('SELECT * FROM Devices ' . $condition);
@@ -252,67 +274,175 @@ function queryCalendarList() {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Query Device Data // Query the List of Owners
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function queryDeviceData() { function getOwners() {
global $db; global $db;
// Request Parameters // SQL
$periodDate = getDateFromPeriod(); $sql = 'SELECT DISTINCT 1 as dev_Order, dev_Owner
$mac = $_REQUEST['mac']; FROM Devices
WHERE dev_Owner <> "(unknown)" AND dev_Owner <> ""
// Device Data AND dev_Favorite = 1
$result = $db->query('SELECT *, UNION
CASE WHEN dev_AlertDeviceDown=1 AND dev_PresentLastScan=0 THEN "Down" SELECT DISTINCT 2 as dev_Order, dev_Owner
WHEN dev_PresentLastScan=1 THEN "On-line" FROM Devices
ELSE "Off-line" END as dev_Status WHERE dev_Owner <> "(unknown)" AND dev_Owner <> ""
FROM Devices AND dev_Favorite = 0
WHERE dev_MAC="' . $mac .'"'); AND dev_Owner NOT IN
(SELECT dev_Owner FROM Devices WHERE dev_Favorite = 1)
$row = $result -> fetchArray (SQLITE3_ASSOC); ORDER BY 1,2 ';
$deviceData = $row; $result = $db->query($sql);
$deviceData['dev_FirstConnection'] = formatDate ($row['dev_FirstConnection']); // Date formated
$deviceData['dev_LastConnection'] = formatDate ($row['dev_LastConnection']); // Date formated
// Count Totals
$condicion = ' WHERE eve_MAC="' . $mac .'" AND eve_DateTime >= ' . $periodDate;
// Connections
$result = $db->query('SELECT COUNT(*) FROM Sessions
WHERE ses_MAC="' . $mac .'"
AND ( ses_DateTimeConnection >= ' . $periodDate . '
OR ses_DateTimeDisconnection >= ' . $periodDate . '
OR ses_StillConnected = 1 ) ');
$row = $result -> fetchArray (SQLITE3_NUM);
$deviceData['dev_Sessions'] = $row[0];
// Events
$result = $db->query('SELECT COUNT(*) FROM Events ' . $condicion . ' AND eve_EventType <> "Connected" AND eve_EventType <> "Disconnected" ');
$row = $result -> fetchArray (SQLITE3_NUM);
$deviceData['dev_Events'] = $row[0];
// Donw Alerts
$result = $db->query('SELECT COUNT(*) FROM Events ' . $condicion . ' AND eve_EventType = "Device Down"');
$row = $result -> fetchArray (SQLITE3_NUM);
$deviceData['dev_DownAlerts'] = $row[0];
// Presence hours
$result = $db->query('SELECT SUM (julianday (IFNULL (ses_DateTimeDisconnection, DATETIME("now")))
- julianday (CASE WHEN ses_DateTimeConnection < ' . $periodDate . ' THEN ' . $periodDate . '
ELSE ses_DateTimeConnection END)) *24
FROM Sessions
WHERE ses_MAC="' . $mac .'"
AND ses_DateTimeConnection IS NOT NULL
AND (ses_DateTimeDisconnection IS NOT NULL OR ses_StillConnected = 1 )
AND ( ses_DateTimeConnection >= ' . $periodDate . '
OR ses_DateTimeDisconnection >= ' . $periodDate . '
OR ses_StillConnected = 1 ) ');
$row = $result -> fetchArray (SQLITE3_NUM);
$deviceData['dev_PresenceHours'] = round ($row[0]);
// arrays of rows
$tableData = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
$tableData[] = array ('order' => $row['dev_Order'],
'name' => $row['dev_Owner']);
}
// Return json // Return json
echo (json_encode ($deviceData)); echo (json_encode ($tableData));
}
//------------------------------------------------------------------------------
// Query the List of types
//------------------------------------------------------------------------------
function getDeviceTypes() {
global $db;
// SQL
$sql = 'SELECT DISTINCT 9 as dev_Order, dev_DeviceType
FROM Devices
WHERE dev_DeviceType NOT IN ("",
"Smartphone", "Tablet",
"Laptop", "Mini PC", "PC", "Printer", "Server", "Singleboard Computer (SBC)",
"Game Console", "SmartTV", "TV Decoder", "Virtual Assistance",
"Clock", "House Appliance", "Phone", "Radio",
"AP", "NAS", "PLC", "Router")
UNION SELECT 1 as dev_Order, "Smartphone"
UNION SELECT 1 as dev_Order, "Tablet"
UNION SELECT 2 as dev_Order, "Laptop"
UNION SELECT 2 as dev_Order, "Mini PC"
UNION SELECT 2 as dev_Order, "PC"
UNION SELECT 2 as dev_Order, "Printer"
UNION SELECT 2 as dev_Order, "Server"
UNION SELECT 2 as dev_Order, "Singleboard Computer (SBC)"
UNION SELECT 3 as dev_Order, "Game Console"
UNION SELECT 3 as dev_Order, "SmartTV"
UNION SELECT 3 as dev_Order, "TV Decoder"
UNION SELECT 3 as dev_Order, "Virtual Assistance"
UNION SELECT 4 as dev_Order, "Clock"
UNION SELECT 4 as dev_Order, "House Appliance"
UNION SELECT 4 as dev_Order, "Phone"
UNION SELECT 4 as dev_Order, "Radio"
UNION SELECT 5 as dev_Order, "AP"
UNION SELECT 5 as dev_Order, "NAS"
UNION SELECT 5 as dev_Order, "PLC"
UNION SELECT 5 as dev_Order, "Router"
UNION SELECT 10 as dev_Order, "Other"
ORDER BY 1,2';
$result = $db->query($sql);
// arrays of rows
$tableData = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
$tableData[] = array ('order' => $row['dev_Order'],
'name' => $row['dev_DeviceType']);
}
// Return json
echo (json_encode ($tableData));
}
//------------------------------------------------------------------------------
// Query the List of groups
//------------------------------------------------------------------------------
function getGroups() {
global $db;
// SQL
$sql = 'SELECT DISTINCT 1 as dev_Order, dev_Group
FROM Devices
WHERE dev_Group NOT IN ("(unknown)", "Others") AND dev_Group <> ""
UNION SELECT 1 as dev_Order, "Always on"
UNION SELECT 1 as dev_Order, "Friends"
UNION SELECT 1 as dev_Order, "Personal"
UNION SELECT 2 as dev_Order, "Others"
ORDER BY 1,2 ';
$result = $db->query($sql);
// arrays of rows
$tableData = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
$tableData[] = array ('order' => $row['dev_Order'],
'name' => $row['dev_Group']);
}
// Return json
echo (json_encode ($tableData));
}
//------------------------------------------------------------------------------
// Query the List of locations
//------------------------------------------------------------------------------
function getLocations() {
global $db;
// SQL
$sql = 'SELECT DISTINCT 9 as dev_Order, dev_Location
FROM Devices
WHERE dev_Location <> ""
AND dev_Location NOT IN (
"Bathroom", "Bedroom", "Dining room", "Hallway",
"Kitchen", "Laundry", "Living room", "Study",
"Attic", "Basement", "Garage",
"Back yard", "Garden", "Terrace",
"Other")
UNION SELECT 1 as dev_Order, "Bathroom"
UNION SELECT 1 as dev_Order, "Bedroom"
UNION SELECT 1 as dev_Order, "Dining room"
UNION SELECT 1 as dev_Order, "Hall"
UNION SELECT 1 as dev_Order, "Kitchen"
UNION SELECT 1 as dev_Order, "Laundry"
UNION SELECT 1 as dev_Order, "Living room"
UNION SELECT 1 as dev_Order, "Study"
UNION SELECT 2 as dev_Order, "Attic"
UNION SELECT 2 as dev_Order, "Basement"
UNION SELECT 2 as dev_Order, "Garage"
UNION SELECT 3 as dev_Order, "Back yard"
UNION SELECT 3 as dev_Order, "Garden"
UNION SELECT 3 as dev_Order, "Terrace"
UNION SELECT 10 as dev_Order, "Other"
ORDER BY 1,2 ';
$result = $db->query($sql);
// arrays of rows
$tableData = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
$tableData[] = array ('order' => $row['dev_Order'],
'name' => $row['dev_Location']);
}
// Return json
echo (json_encode ($tableData));
} }
@@ -320,58 +450,14 @@ function queryDeviceData() {
// Status Where conditions // Status Where conditions
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function getDeviceCondition ($deviceStatus) { function getDeviceCondition ($deviceStatus) {
// Request Parameters
$periodDate = getDateFromPeriod();
switch ($deviceStatus) { switch ($deviceStatus) {
case 'all': case 'all': return ''; break;
return ''; case 'connected': return 'WHERE dev_PresentLastScan=1'; break;
case 'connected': case 'new': return 'WHERE dev_NewDevice=1'; break;
return 'WHERE dev_PresentLastScan=1'; case 'down': return 'WHERE dev_AlertDeviceDown=1 AND dev_PresentLastScan=0'; break;
case 'new': case 'favorites': return 'WHERE dev_Favorite=1'; break;
return 'WHERE dev_FirstConnection >= ' . $periodDate; default: return 'WHERE 1=0'; break;
case 'down':
return 'WHERE dev_AlertDeviceDown=1 AND dev_PresentLastScan=0';
case 'favorites':
return 'WHERE dev_Favorite=1';
default:
return 'WHERE 1=0';
} }
} }
//------------------------------------------------------------------------------
// Update Device Data
//------------------------------------------------------------------------------
function updateDeviceData() {
global $db;
// sql
$sql = 'UPDATE Devices SET
dev_Name = "'. $_REQUEST['name'] .'",
dev_Owner = "'. $_REQUEST['owner'] .'",
dev_DeviceType = "'. $_REQUEST['type'] .'",
dev_Vendor = "'. $_REQUEST['vendor'] .'",
dev_Favorite = "'. $_REQUEST['favorite'] .'",
dev_Group = "'. $_REQUEST['group'] .'",
dev_Comments = "'. $_REQUEST['comments'] .'",
dev_StaticIP = "'. $_REQUEST['staticIP'] .'",
dev_ScanCycle = "'. $_REQUEST['scancycle'] .'",
dev_AlertEvents = "'. $_REQUEST['alertevents'] .'",
dev_AlertDeviceDown = "'. $_REQUEST['alertdown'] .'",
dev_SkipRepeated = "'. $_REQUEST['skiprepeated'] .'"
WHERE dev_MAC="' . $_REQUEST['mac'] .'"';
// update Data
$result = $db->query($sql);
// check result
if ($result == TRUE) {
echo "Device updated successfully";
} else {
echo "Error updating device\n\n". $sql .'\n\n' . $db->lastErrorMsg();
}
}
?> ?>

View File

@@ -1,9 +1,20 @@
<?php <?php
//------------------------------------------------------------------------------
// Pi.Alert
// Open Source Network Guard / WIFI & LAN intrusion detector
//
// events.php - Front module. Server side. Manage Events
//------------------------------------------------------------------------------
// Puche 2021 pi.alert.application@gmail.com GNU GPLv3
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// External files // External files
require 'db.php'; require 'db.php';
require 'util.php'; require 'util.php';
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Action selector // Action selector
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -17,13 +28,13 @@
if (isset ($_REQUEST['action']) && !empty ($_REQUEST['action'])) { if (isset ($_REQUEST['action']) && !empty ($_REQUEST['action'])) {
$action = $_REQUEST['action']; $action = $_REQUEST['action'];
switch ($action) { switch ($action) {
case 'totals': queryTotals(); break; case 'getEventsTotals': getEventsTotals(); break;
case 'list': queryList(); break; case 'getEvents': getEvents(); break;
case 'deviceSessions': queryDeviceSessions(); break; case 'getDeviceSessions': getDeviceSessions(); break;
case 'devicePresence': queryDevicePresence(); break; case 'getDevicePresence': getDevicePresence(); break;
case 'deviceEvents': queryDeviceEvents(); break; case 'getDeviceEvents': getDeviceEvents(); break;
case 'calendarPresence': queryCalendarPresence(); break; case 'getEventsCalendar': getEventsCalendar(); break;
default: logServerConsole ('Action: '. $action); break; default: logServerConsole ('Action: '. $action); break;
} }
} }
@@ -31,7 +42,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Query total numbers of Events // Query total numbers of Events
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function queryTotals() { function getEventsTotals() {
global $db; global $db;
// Request Parameters // Request Parameters
@@ -86,7 +97,7 @@ function queryTotals() {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Query the List of events // Query the List of events
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function queryList() { function getEvents() {
global $db; global $db;
// Request Parameters // Request Parameters
@@ -104,30 +115,18 @@ function queryList() {
// SQL Variations for status // SQL Variations for status
switch ($type) { switch ($type) {
case 'all': case 'all': $SQL = $SQL1; break;
$SQL = $SQL1;
break;
case 'sessions': case 'sessions':
$SQL = $SQL2 . ' WHERE ( ses_DateTimeConnection >= '. $periodDate .' $SQL = $SQL2 . ' WHERE ( ses_DateTimeConnection >= '. $periodDate .' OR ses_DateTimeDisconnection >= '. $periodDate .' OR ses_StillConnected = 1 ) ';
OR ses_DateTimeDisconnection >= '. $periodDate .'
OR ses_StillConnected = 1 ) ';
break; break;
case 'missing': case 'missing':
$SQL = $SQL2 . ' WHERE (ses_DateTimeConnection IS NULL AND ses_DateTimeDisconnection >= '. $periodDate .' ) $SQL = $SQL2 . ' WHERE (ses_DateTimeConnection IS NULL AND ses_DateTimeDisconnection >= '. $periodDate .' )
OR (ses_DateTimeDisconnection IS NULL AND ses_StillConnected = 0 AND ses_DateTimeConnection >= '. $periodDate .' )'; OR (ses_DateTimeDisconnection IS NULL AND ses_StillConnected = 0 AND ses_DateTimeConnection >= '. $periodDate .' )';
break; break;
case 'voided': case 'voided': $SQL = $SQL1 .' AND eve_EventType LIKE "VOIDED%" '; break;
$SQL = $SQL1 .' AND eve_EventType LIKE "VOIDED%" '; case 'new': $SQL = $SQL1 .' AND eve_EventType = "New Device" '; break;
break; case 'down': $SQL = $SQL1 .' AND eve_EventType = "Device Down" '; break;
case 'new': default: $SQL = $SQL1 .' AND 1==0 '; break;
$SQL = $SQL1 .' AND eve_EventType = "New Device" ';
break;
case 'down':
$SQL = $SQL1 .' AND eve_EventType = "Device Down" ';
break;
default:
$SQL = $SQL1 .' AND 1==0 ';
break;
} }
// Query // Query
@@ -187,7 +186,7 @@ function queryList() {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Query Device Sessions // Query Device Sessions
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function queryDeviceSessions() { function getDeviceSessions() {
global $db; global $db;
// Request Parameters // Request Parameters
@@ -195,16 +194,17 @@ function queryDeviceSessions() {
$periodDate = getDateFromPeriod(); $periodDate = getDateFromPeriod();
// SQL // SQL
$result = $db->query('SELECT IFNULL (ses_DateTimeConnection, ses_DateTimeDisconnection) ses_DateTimeOrder, $SQL = 'SELECT IFNULL (ses_DateTimeConnection, ses_DateTimeDisconnection) ses_DateTimeOrder,
ses_EventTypeConnection, ses_DateTimeConnection, ses_EventTypeConnection, ses_DateTimeConnection,
ses_EventTypeDisconnection, ses_DateTimeDisconnection, ses_StillConnected, ses_EventTypeDisconnection, ses_DateTimeDisconnection, ses_StillConnected,
ses_IP, ses_AdditionalInfo ses_IP, ses_AdditionalInfo
FROM Sessions FROM Sessions
WHERE ses_MAC="' . $mac .'" WHERE ses_MAC="' . $mac .'"
AND ( ses_DateTimeConnection >= '. $periodDate .' AND ( ses_DateTimeConnection >= '. $periodDate .'
OR ses_DateTimeDisconnection >= '. $periodDate .' OR ses_DateTimeDisconnection >= '. $periodDate .'
OR ses_StillConnected = 1 ) '); OR ses_StillConnected = 1 ) ';
$result = $db->query($SQL);
// arrays of rows // arrays of rows
$tableData = array(); $tableData = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
@@ -228,7 +228,7 @@ function queryDeviceSessions() {
if ($row['ses_EventTypeConnection'] == '<missing event>' || $row['ses_EventTypeDisconnection'] == '<missing event>') { if ($row['ses_EventTypeConnection'] == '<missing event>' || $row['ses_EventTypeDisconnection'] == '<missing event>') {
$dur = '...'; $dur = '...';
} elseif ($row['ses_StillConnected'] == true) { } elseif ($row['ses_StillConnected'] == true) {
$dur = formatDateDiff ($row['ses_DateTimeConnection'], ''); //******************************************************************************************* $dur = formatDateDiff ($row['ses_DateTimeConnection'], ''); //***********
} else { } else {
$dur = formatDateDiff ($row['ses_DateTimeConnection'], $row['ses_DateTimeDisconnection']); $dur = formatDateDiff ($row['ses_DateTimeConnection'], $row['ses_DateTimeDisconnection']);
} }
@@ -256,7 +256,7 @@ function queryDeviceSessions() {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Query Device Presence Calendar // Query Device Presence Calendar
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function queryDevicePresence() { function getDevicePresence() {
global $db; global $db;
// Request Parameters // Request Parameters
@@ -266,24 +266,26 @@ function queryDevicePresence() {
$endDate = '"'. formatDateISO ($_REQUEST ['end']) .'"'; $endDate = '"'. formatDateISO ($_REQUEST ['end']) .'"';
// SQL // SQL
$result = $db->query('SELECT ses_EventTypeConnection, ses_DateTimeConnection, $SQL = 'SELECT ses_EventTypeConnection, ses_DateTimeConnection,
ses_EventTypeDisconnection, ses_DateTimeDisconnection, ses_IP, ses_AdditionalInfo, ses_EventTypeDisconnection, ses_DateTimeDisconnection, ses_IP, ses_AdditionalInfo,
CASE WHEN ses_EventTypeConnection = "<missing event>" THEN CASE
IFNULL ((SELECT MAX(ses_DateTimeDisconnection) FROM Sessions AS SES2 WHERE SES2.ses_MAC = SES1.ses_MAC AND SES2.ses_DateTimeDisconnection < SES1.ses_DateTimeDisconnection), DATETIME(ses_DateTimeDisconnection, "-1 hour")) WHEN ses_EventTypeConnection = "<missing event>" THEN
ELSE ses_DateTimeConnection IFNULL ((SELECT MAX(ses_DateTimeDisconnection) FROM Sessions AS SES2 WHERE SES2.ses_MAC = SES1.ses_MAC AND SES2.ses_DateTimeDisconnection < SES1.ses_DateTimeDisconnection), DATETIME(ses_DateTimeDisconnection, "-1 hour"))
END AS ses_DateTimeConnectionCorrected, ELSE ses_DateTimeConnection
END AS ses_DateTimeConnectionCorrected,
CASE WHEN ses_EventTypeDisconnection = "<missing event>" THEN CASE
(SELECT MIN(ses_DateTimeConnection) FROM Sessions AS SES2 WHERE SES2.ses_MAC = SES1.ses_MAC AND SES2.ses_DateTimeConnection > SES1.ses_DateTimeConnection) WHEN ses_EventTypeDisconnection = "<missing event>" THEN
ELSE ses_DateTimeDisconnection (SELECT MIN(ses_DateTimeConnection) FROM Sessions AS SES2 WHERE SES2.ses_MAC = SES1.ses_MAC AND SES2.ses_DateTimeConnection > SES1.ses_DateTimeConnection)
END AS ses_DateTimeDisconnectionCorrected ELSE ses_DateTimeDisconnection
END AS ses_DateTimeDisconnectionCorrected
FROM Sessions AS SES1 FROM Sessions AS SES1
WHERE ses_MAC="' . $mac .'" WHERE ses_MAC="' . $mac .'"
AND (ses_DateTimeConnectionCorrected <= date('. $endDate .') AND (ses_DateTimeConnectionCorrected <= date('. $endDate .')
AND (ses_DateTimeDisconnectionCorrected >= date('. $startDate .') OR ses_StillConnected = 1 )) AND (ses_DateTimeDisconnectionCorrected >= date('. $startDate .') OR ses_StillConnected = 1 )) ';
'); $result = $db->query($SQL);
// arrays of rows // arrays of rows
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
@@ -300,10 +302,6 @@ function queryDevicePresence() {
'IP: ' . $row['ses_IP']; 'IP: ' . $row['ses_IP'];
// Save row data // Save row data
// 'start' => formatDateISO ($row['ses_DateTimeConnectionCorrected']),
// 'end' => formatDateISO ($row['ses_DateTimeDisconnectionCorrected']),
// 'start' => $row['ses_DateTimeConnectionCorrected'],
// 'end' => $row['ses_DateTimeDisconnectionCorrected'],
$tableData[] = array( $tableData[] = array(
'title' => '', 'title' => '',
'start' => formatDateISO ($row['ses_DateTimeConnectionCorrected']), 'start' => formatDateISO ($row['ses_DateTimeConnectionCorrected']),
@@ -326,32 +324,33 @@ function queryDevicePresence() {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Query Presence Calendar for all Devices // Query Presence Calendar for all Devices
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function queryCalendarPresence() { function getEventsCalendar() {
global $db; global $db;
// Request Parameters // Request Parameters
$periodDate = getDateFromPeriod();
$startDate = '"'. $_REQUEST ['start'] .'"'; $startDate = '"'. $_REQUEST ['start'] .'"';
$endDate = '"'. $_REQUEST ['end'] .'"'; $endDate = '"'. $_REQUEST ['end'] .'"';
// SQL // SQL
$result = $db->query('SELECT ses_MAC, ses_EventTypeConnection, ses_DateTimeConnection, $SQL = 'SELECT ses_MAC, ses_EventTypeConnection, ses_DateTimeConnection,
ses_EventTypeDisconnection, ses_DateTimeDisconnection, ses_IP, ses_AdditionalInfo, ses_EventTypeDisconnection, ses_DateTimeDisconnection, ses_IP, ses_AdditionalInfo,
CASE WHEN ses_EventTypeConnection = "<missing event>" THEN CASE
IFNULL ((SELECT MAX(ses_DateTimeDisconnection) FROM Sessions AS SES2 WHERE SES2.ses_MAC = SES1.ses_MAC AND SES2.ses_DateTimeDisconnection < SES1.ses_DateTimeDisconnection), DATETIME(ses_DateTimeDisconnection, "-1 hour")) WHEN ses_EventTypeConnection = "<missing event>" THEN
ELSE ses_DateTimeConnection IFNULL ((SELECT MAX(ses_DateTimeDisconnection) FROM Sessions AS SES2 WHERE SES2.ses_MAC = SES1.ses_MAC AND SES2.ses_DateTimeDisconnection < SES1.ses_DateTimeDisconnection), DATETIME(ses_DateTimeDisconnection, "-1 hour"))
END AS ses_DateTimeConnectionCorrected, ELSE ses_DateTimeConnection
END AS ses_DateTimeConnectionCorrected,
CASE WHEN ses_EventTypeDisconnection = "<missing event>" THEN CASE
(SELECT MIN(ses_DateTimeConnection) FROM Sessions AS SES2 WHERE SES2.ses_MAC = SES1.ses_MAC AND SES2.ses_DateTimeConnection > SES1.ses_DateTimeConnection) WHEN ses_EventTypeDisconnection = "<missing event>" THEN
ELSE ses_DateTimeDisconnection (SELECT MIN(ses_DateTimeConnection) FROM Sessions AS SES2 WHERE SES2.ses_MAC = SES1.ses_MAC AND SES2.ses_DateTimeConnection > SES1.ses_DateTimeConnection)
END AS ses_DateTimeDisconnectionCorrected ELSE ses_DateTimeDisconnection
END AS ses_DateTimeDisconnectionCorrected
FROM Sessions AS SES1 FROM Sessions AS SES1
WHERE ( ses_DateTimeConnectionCorrected <= Date('. $endDate .') WHERE ( ses_DateTimeConnectionCorrected <= Date('. $endDate .')
AND (ses_DateTimeDisconnectionCorrected >= Date('. $startDate .') OR ses_StillConnected = 1 )) AND (ses_DateTimeDisconnectionCorrected >= Date('. $startDate .') OR ses_StillConnected = 1 )) ';
'); $result = $db->query($SQL);
// arrays of rows // arrays of rows
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
@@ -392,7 +391,7 @@ function queryCalendarPresence() {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Query Device events // Query Device events
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function queryDeviceEvents() { function getDeviceEvents() {
global $db; global $db;
// Request Parameters // Request Parameters
@@ -401,13 +400,13 @@ function queryDeviceEvents() {
$hideConnections = $_REQUEST ['hideConnections']; $hideConnections = $_REQUEST ['hideConnections'];
// SQL // SQL
$result = $db->query('SELECT eve_DateTime, eve_EventType, eve_IP, eve_AdditionalInfo $SQL = 'SELECT eve_DateTime, eve_EventType, eve_IP, eve_AdditionalInfo
FROM Events FROM Events
WHERE eve_MAC="'. $mac .'" AND eve_DateTime >= '. $periodDate .' WHERE eve_MAC="'. $mac .'" AND eve_DateTime >= '. $periodDate .'
AND ( (eve_EventType <> "Connected" AND eve_EventType <> "Disconnected" AND AND ( (eve_EventType <> "Connected" AND eve_EventType <> "Disconnected" AND
eve_EventType <> "VOIDED - Connected" AND eve_EventType <> "VOIDED - Disconnected") eve_EventType <> "VOIDED - Connected" AND eve_EventType <> "VOIDED - Disconnected")
OR "'. $hideConnections .'" = "false" ) OR "'. $hideConnections .'" = "false" ) ';
'); $result = $db->query($SQL);
// arrays of rows // arrays of rows
$tableData = array(); $tableData = array();
@@ -425,5 +424,4 @@ function queryDeviceEvents() {
echo (json_encode ($tableData)); echo (json_encode ($tableData));
} }
?> ?>

View File

@@ -0,0 +1,88 @@
<?php
//------------------------------------------------------------------------------
// Pi.Alert
// Open Source Network Guard / WIFI & LAN intrusion detector
//
// parameters.php - Front module. Server side. Manage Parameters
//------------------------------------------------------------------------------
// Puche 2021 pi.alert.application@gmail.com GNU GPLv3
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// External files
require 'db.php';
require 'util.php';
//------------------------------------------------------------------------------
// Action selector
//------------------------------------------------------------------------------
// Set maximum execution time to 15 seconds
ini_set ('max_execution_time','15');
// Open DB
OpenDB();
// Action functions
if (isset ($_REQUEST['action']) && !empty ($_REQUEST['action'])) {
$action = $_REQUEST['action'];
switch ($action) {
case 'get': getParameter(); break;
case 'set': setParameter(); break;
default: logServerConsole ('Action: '. $action); break;
}
}
//------------------------------------------------------------------------------
// Get Parameter Value
//------------------------------------------------------------------------------
function getParameter() {
global $db;
$parameter = $_REQUEST['parameter'];
$sql = 'SELECT par_Value FROM Parameters
WHERE par_ID="'. quotes($_REQUEST['parameter']) .'"';
$result = $db->query($sql);
$row = $result -> fetchArray (SQLITE3_NUM);
$value = $row[0];
echo (json_encode ($value));
}
//------------------------------------------------------------------------------
// Set Parameter Value
//------------------------------------------------------------------------------
function setParameter() {
global $db;
// Update value
$sql = 'UPDATE Parameters SET par_Value="'. quotes ($_REQUEST['value']) .'"
WHERE par_ID="'. quotes($_REQUEST['parameter']) .'"';
$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
$sql = 'INSERT INTO Parameters (par_ID, par_Value)
VALUES ("'. quotes($_REQUEST['parameter']) .'",
"'. quotes($_REQUEST['value']) .'")';
$result = $db->query($sql);
if (! $result == TRUE) {
echo "Error creating parameter\n\n$sql \n\n". $db->lastErrorMsg();
return;
}
}
echo 'OK';
}
?>

View File

@@ -1,4 +1,13 @@
<?php <?php
//------------------------------------------------------------------------------
// Pi.Alert
// Open Source Network Guard / WIFI & LAN intrusion detector
//
// util.php - Front module. Server side. Common generic functions
//------------------------------------------------------------------------------
// Puche 2021 pi.alert.application@gmail.com GNU GPLv3
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Formatting data functions // Formatting data functions
@@ -37,12 +46,16 @@ function formatIPlong ($IP) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function getDateFromPeriod () { function getDateFromPeriod () {
$period = $_REQUEST['period']; $period = $_REQUEST['period'];
return '"'. date ('Y-m-d', strtotime ('+1 day -'.$period) ) .'"'; return '"'. date ('Y-m-d', strtotime ('+1 day -'. $period) ) .'"';
} }
function quotes ($text) {
return str_replace ('"','""',$text);
}
function logServerConsole ($text) { function logServerConsole ($text) {
$x = array(); $x = array();
$y = $x['__________'. $text .'__________']; $y = $x['__________'. $text .'__________'];
} }
?> ?>

View File

@@ -2,7 +2,7 @@
# Pi.Alert # Pi.Alert
# Open Source Network Guard / WIFI & LAN intrusion detector # Open Source Network Guard / WIFI & LAN intrusion detector
# #
# footer.php - Front module. Common footer to all the front pages # footer.php - Front module. Common footer to all the web pages
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3 # Puche 2021 pi.alert.application@gmail.com GNU GPLv3
#--------------------------------------------------------------------------- --> #--------------------------------------------------------------------------- -->
@@ -11,9 +11,7 @@
<footer class="main-footer"> <footer class="main-footer">
<!-- Default to the left --> <!-- Default to the left -->
<!-- <!-- &copy; 2020 Puche -->
&copy; 2020 Puche
-->
<?php <?php
$conf_file = '../config/version.conf'; $conf_file = '../config/version.conf';
$conf_data = parse_ini_file($conf_file); $conf_data = parse_ini_file($conf_file);
@@ -23,9 +21,7 @@
<!-- To the right --> <!-- To the right -->
<div class="pull-right no-hidden-xs"> <div class="pull-right no-hidden-xs">
<!-- <!-- Pi.Alert 2.50 <small>(2019-12-30)</small> -->
Pi.Alert&nbsp&nbsp2.50&nbsp&nbsp<small>(2019-12-30)</small>
-->
<?php <?php
$conf_file = '../config/version.conf'; $conf_file = '../config/version.conf';
$conf_data = parse_ini_file($conf_file); $conf_data = parse_ini_file($conf_file);
@@ -34,34 +30,36 @@
</div> </div>
</footer> </footer>
<!-- ----------------------------------------------------------------------- -->
<!-- Control Sidebar --> <!-- Control Sidebar -->
<!-- DELETED --> <!-- DELETED -->
</div> </div>
<!-- ./wrapper --> <!-- ./wrapper -->
<!-- ----------------------------------------------------------------------- -->
<!-- REQUIRED JS SCRIPTS --> <!-- REQUIRED JS SCRIPTS -->
<!-- jQuery 3 --> <!-- jQuery 3 -->
<script src="lib/AdminLTE/bower_components/jquery/dist/jquery.min.js"></script> <script src="lib/AdminLTE/bower_components/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap 3.3.7 --> <!-- Bootstrap 3.3.7 -->
<script src="lib/AdminLTE/bower_components/bootstrap/dist/js/bootstrap.min.js"></script> <script src="lib/AdminLTE/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- AdminLTE App --> <!-- AdminLTE App -->
<script src="lib/AdminLTE/dist/js/adminlte.min.js"></script> <script src="lib/AdminLTE/dist/js/adminlte.min.js"></script>
<!-- Optionally, you can add Slimscroll and FastClick plugins. <!-- Optionally, you can add Slimscroll and FastClick plugins.
Both of these plugins are recommended to enhance the Both of these plugins are recommended to enhance the
user experience. --> user experience. -->
<!-- SlimScroll --> <!-- SlimScroll -->
<script src="lib/AdminLTE/bower_components/jquery-slimscroll/jquery.slimscroll.min.js"></script> <!-- <script src="lib/AdminLTE/bower_components/jquery-slimscroll/jquery.slimscroll.min.js"></script> -->
<!-- FastClick --> <!-- FastClick -->
<script src="lib/AdminLTE/bower_components/fastclick/lib/fastclick.js"></script> <!-- <script src="lib/AdminLTE/bower_components/fastclick/lib/fastclick.js"></script> -->
<!-- Pi.Alert -------------------------------------------------------------- --> <!-- Pi.Alert -------------------------------------------------------------- -->
<script src="js/pialert_common.js"></script> <script src="js/pialert_common.js"></script>
</body> </body>
</html> </html>

View File

@@ -2,52 +2,58 @@
# Pi.Alert # Pi.Alert
# Open Source Network Guard / WIFI & LAN intrusion detector # Open Source Network Guard / WIFI & LAN intrusion detector
# #
# header.php - Front module. Common header to all the front pages # header.php - Front module. Common header to all the web pages
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3 # Puche 2021 pi.alert.application@gmail.com GNU GPLv3
#--------------------------------------------------------------------------- --> #--------------------------------------------------------------------------- -->
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<!-- ----------------------------------------------------------------------- -->
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Pi.Alert</title> <title>Pi.Alert</title>
<!-- Tell the browser to be responsive to screen width --> <!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.7 --> <!-- Bootstrap 3.3.7 -->
<link rel="stylesheet" href="lib/AdminLTE/bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="lib/AdminLTE/bower_components/bootstrap/dist/css/bootstrap.min.css">
<!-- Font Awesome --> <!-- Font Awesome -->
<link rel="stylesheet" href="lib/AdminLTE/bower_components/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="lib/AdminLTE/bower_components/font-awesome/css/font-awesome.min.css">
<!-- Ionicons --> <!-- Ionicons -->
<link rel="stylesheet" href="lib/AdminLTE/bower_components/Ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="lib/AdminLTE/bower_components/Ionicons/css/ionicons.min.css">
<!-- Theme style --> <!-- Theme style -->
<link rel="stylesheet" href="lib/AdminLTE/dist/css/AdminLTE.min.css"> <link rel="stylesheet" href="lib/AdminLTE/dist/css/AdminLTE.min.css">
<!-- AdminLTE Skins. We have chosen the skin-blue for this starter <!-- AdminLTE Skins. We have chosen the skin-blue for this starter
page. However, you can choose any other skin. Make sure you page. However, you can choose any other skin. Make sure you
apply the skin class to the body tag so the changes take effect. --> apply the skin class to the body tag so the changes take effect. -->
<link rel="stylesheet" href="lib/AdminLTE/dist/css/skins/skin-yellow-light.min.css"> <link rel="stylesheet" href="lib/AdminLTE/dist/css/skins/skin-yellow-light.min.css">
<!-- Pi.Alert CSS --> <!-- Pi.Alert CSS -->
<link rel="stylesheet" href="css/pialert.css"> <link rel="stylesheet" href="css/pialert.css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]--> <![endif]-->
<!-- Google Font --> <!-- Google Font -->
<link rel="stylesheet" <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">
href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">
<!-- Page Icon --> <!-- Page Icon -->
<link rel="icon" type="image/png" sizes="160x160" href="img/pialertLogoGray80.png" /> <link rel="icon" type="image/png" sizes="160x160" href="img/pialertLogoGray80.png" />
</head> </head>
<!-- ----------------------------------------------------------------------- -->
<!-- Layout Boxed Yellow --> <!-- Layout Boxed Yellow -->
<body class="hold-transition skin-yellow-light layout-boxed sidebar-mini" style="background-image: url('img/background.png');"> <body class="hold-transition skin-yellow-light layout-boxed sidebar-mini" style="background-image: url('img/background.png');">
<!-- Site wrapper --> <!-- Site wrapper -->
@@ -56,6 +62,7 @@
<!-- Main Header --> <!-- Main Header -->
<header class="main-header"> <header class="main-header">
<!-- ----------------------------------------------------------------------- -->
<!-- Logo --> <!-- Logo -->
<a href="/" class="logo"> <a href="/" class="logo">
<!-- mini logo for sidebar mini 50x50 pixels --> <!-- mini logo for sidebar mini 50x50 pixels -->
@@ -64,6 +71,7 @@
<span class="logo-lg">Pi<b>.Alert</b></span> <span class="logo-lg">Pi<b>.Alert</b></span>
</a> </a>
<!-- ----------------------------------------------------------------------- -->
<!-- Header Navbar --> <!-- Header Navbar -->
<nav class="navbar navbar-static-top" role="navigation"> <nav class="navbar navbar-static-top" role="navigation">
<!-- Sidebar toggle button--> <!-- Sidebar toggle button-->
@@ -90,12 +98,12 @@
<!-- The user image in the menu --> <!-- The user image in the menu -->
<li class="user-header"> <li class="user-header">
<img src="img/pialertLogoWhite.png" class="img-circle" alt="Pi.Alert Logo" style="border-color:transparent"> <img src="img/pialertLogoWhite.png" class="img-circle" alt="Pi.Alert Logo" style="border-color:transparent">
<p> <p>
Open Source Network Guard Open Source Network Guard
<small>Designed for Raspberry Pi</small> <small>Designed for Raspberry Pi</small>
</p> </p>
</li> </li>
<!-- Menu Body --> <!-- Menu Body -->
<li class="user-body"> <li class="user-body">
<div class="row"> <div class="row">
@@ -122,6 +130,8 @@
</div> </div>
</nav> </nav>
</header> </header>
<!-- ----------------------------------------------------------------------- -->
<!-- Left side column. contains the logo and sidebar --> <!-- Left side column. contains the logo and sidebar -->
<aside class="main-sidebar"> <aside class="main-sidebar">
@@ -133,117 +143,10 @@
<a href="/" class="logo"> <a href="/" class="logo">
<img src="img/pialertLogoGray80.png" class="img-responsive" alt="Pi.Alert Logo"/> <img src="img/pialertLogoGray80.png" class="img-responsive" alt="Pi.Alert Logo"/>
</a> </a>
<div class="pull-left image">
<!--
<br><img src="img/pialertLogoBlack.png" class="img-responsive" alt="Pi.Alert Logo" style="display: table; table-layout: fixed;" />
-->
</div>
<div class="pull-left info" style="display: none">
<p>Status</p>
<?php
$pistatus = exec('sudo pihole status web');
$pistatus=1;
$FTL=true;
$celsius=56.7;
$temperatureunit='C';
$nproc=2;
$loaddata=array();
$loaddata[]=1.1;
$loaddata[]=1.2;
$loaddata[]=1.3;
$memory_usage=0.452;
if ($pistatus == "1") {
echo '<a id="status"><i class="fa fa-circle" style="color:#7FFF00"></i> Active</a>';
} elseif ($pistatus == "0") {
echo '<a id="status"><i class="fa fa-circle" style="color:#FF0000"></i> Offline</a>';
} elseif ($pistatus == "-1") {
echo '<a id="status"><i class="fa fa-circle" style="color:#FF0000"></i> DNS service not running</a>';
} else {
echo '<a id="status"><i class="fa fa-circle" style="color:#ff9900"></i> Unknown</a>';
}
// CPU Temp
if($FTL)
{
if ($celsius >= -273.15) {
echo "<a id=\"temperature\"><i class=\"fa fa-fire\" style=\"color:";
if ($celsius > 60) {
echo "#FF0000";
}
else
{
echo "#3366FF";
}
echo "\"></i> Temp:&nbsp;";
if($temperatureunit === "F")
{
echo round($fahrenheit,1) . "&nbsp;&deg;F";
}
elseif($temperatureunit === "K")
{
echo round($kelvin,1) . "&nbsp;K";
}
else
{
echo round($celsius,1) . "&nbsp;&deg;C";
}
echo "</a>";
}
}
else
{
echo '<a id=\"temperature\"><i class="fa fa-circle" style="color:#FF0000"></i> FTL offline</a>';
}
?>
<br/>
<?php
echo "<a title=\"Detected $nproc cores\"><i class=\"fa fa-circle\" style=\"color:";
if ($loaddata[0] > $nproc) {
echo "#FF0000";
}
else
{
echo "#7FFF00";
}
echo "\"></i> Load:&nbsp;&nbsp;" . $loaddata[0] . "&nbsp;&nbsp;" . $loaddata[1] . "&nbsp;&nbsp;". $loaddata[2] . "</a>";
?>
<br/>
<?php
echo "<a><i class=\"fa fa-circle\" style=\"color:";
if ($memory_usage > 0.75 || $memory_usage < 0.0) {
echo "#FF0000";
}
else
{
echo "#7FFF00";
}
if($memory_usage > 0.0)
{
echo "\"></i> Memory usage:&nbsp;&nbsp;" . sprintf("%.1f",100.0*$memory_usage) . "&thinsp;%</a>";
}
else
{
echo "\"></i> Memory usage:&nbsp;&nbsp; N/A</a>";
}
?>
</div>
</div> </div>
<!-- search form (Optional) --> <!-- search form (Optional) -->
<!-- <!-- DELETED -->
<form action="#" method="get" class="sidebar-form">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search...">
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i>
</button>
</span>
</div>
</form>
-->
<!-- /.search form -->
<!-- Sidebar Menu --> <!-- Sidebar Menu -->
<ul class="sidebar-menu" data-widget="tree"> <ul class="sidebar-menu" data-widget="tree">

View File

@@ -0,0 +1,35 @@
<!-- ---------------------------------------------------------------------------
# Pi.Alert
# Open Source Network Guard / WIFI & LAN intrusion detector
#
# notificacion.php - Front module. Common notification & modal window
#-------------------------------------------------------------------------------
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3
#--------------------------------------------------------------------------- -->
<!-- Modal warning -->
<div class="modal modal-warning fade" id="modal-warning" style="display: none;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 id="modal-title" class="modal-title"> Modal Title </h4>
</div>
<div id="modal-message" class="modal-body"> Modal message </div>
<div class="modal-footer">
<button id="modal-cancel" type="button" class="btn btn-outline pull-left" data-dismiss="modal"> Cancel </button>
<button id="modal-OK" type="button" class="btn btn-outline" onclick="modalOK()"> OK </button>
</div>
</div>
</div>
</div>
<!-- Alert float -->
<div id="notification" class="alert alert-dimissible pa_alert_notification">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<div id="alert-message"> Alert message </div>
</div>

View File

@@ -1,4 +1,12 @@
<!-- ----------------------------------------------------------------------- --> <!-- ---------------------------------------------------------------------------
# Pi.Alert
# Open Source Network Guard / WIFI & LAN intrusion detector
#
# presence.php - Front module. Device Presence calendar page
#-------------------------------------------------------------------------------
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3
#--------------------------------------------------------------------------- -->
<?php <?php
require 'php/templates/header.php'; require 'php/templates/header.php';
?> ?>
@@ -11,102 +19,74 @@
<h1 id="pageTitle"> <h1 id="pageTitle">
Presence by Devices Presence by Devices
</h1> </h1>
<!-- period selector -->
<span class="breadcrumb text-gray50">
New Devices period:
<select id="period" onchange="javascript: periodChanged();">
<option value="1 day">Today</option>
<option value="7 days">Last Week</option>
<option value="1 month" selected>Last Month</option>
<option value="1 year">Last Year</option>
<option value="100 years">All info</option>
</select>
</span>
</section> </section>
<!-- Main content ---------------------------------------------------------- --> <!-- Main content ---------------------------------------------------------- -->
<section class="content"> <section class="content">
<!-- top small box 1 ------------------------------------------------------- -->
<div class="row"> <div class="row">
<!-- top small box --------------------------------------------------------- -->
<div class="col-lg-3 col-sm-6 col-xs-6"> <div class="col-lg-3 col-sm-6 col-xs-6">
<a href="#" onclick="javascript: queryPresence('all');"> <a href="#" onclick="javascript: getDevicesPresence('all');">
<div class="small-box bg-aqua pa-small-box-aqua"> <div class="small-box bg-aqua pa-small-box-aqua">
<div class="inner"> <div class="inner">
<h4>All Devices</h4> <h4>All Devices</h4>
<h3 id="devicesAll"> -- </h3> <h3 id="devicesAll"> -- </h3>
</div>
<div class="icon">
<i class="fa fa-laptop"></i>
</div>
<div class="small-box-footer">
Details <i class="fa fa-arrow-circle-right"></i>
</div> </div>
<div class="icon"> <i class="fa fa-laptop"></i> </div>
<div class="small-box-footer"> Details <i class="fa fa-arrow-circle-right"></i> </div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box 2 ------------------------------------------------------- -->
<div class="col-lg-3 col-sm-6 col-xs-6"> <div class="col-lg-3 col-sm-6 col-xs-6">
<a href="#" onclick="javascript: queryPresence('connected');"> <a href="#" onclick="javascript: getDevicesPresence('connected');">
<div class="small-box bg-green pa-small-box-green"> <div class="small-box bg-green pa-small-box-green">
<div class="inner"> <div class="inner">
<h4>Connected</h4> <h4>Connected</h4>
<h3 id="devicesConnected"> -- </h3> <h3 id="devicesConnected"> -- </h3>
</div>
<div class="icon">
<i class="fa fa-plug"></i>
</div>
<div class="small-box-footer">
Details <i class="fa fa-arrow-circle-right"></i>
</div> </div>
<div class="icon"> <i class="fa fa-plug"></i> </div>
<div class="small-box-footer"> Details <i class="fa fa-arrow-circle-right"></i> </div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box 3 ------------------------------------------------------- -->
<div class="col-lg-3 col-sm-6 col-xs-6"> <div class="col-lg-3 col-sm-6 col-xs-6">
<a href="#" onclick="javascript: queryPresence('new');"> <a href="#" onclick="javascript: getDevicesPresence('new');">
<div class="small-box bg-yellow pa-small-box-yellow"> <div class="small-box bg-yellow pa-small-box-yellow">
<div class="inner"> <div class="inner">
<h4>New Devices</h4> <h4>New Devices</h4>
<h3 id="devicesNew"> -- </h3> <h3 id="devicesNew"> -- </h3>
</div>
<div class="icon">
<i class="ion ion-plus-round"></i>
</div>
<div class="small-box-footer">
Details <i class="fa fa-arrow-circle-right"></i>
</div> </div>
<div class="icon"> <i class="ion ion-plus-round"></i> </div>
<div class="small-box-footer"> Details <i class="fa fa-arrow-circle-right"></i> </div>
</div> </div>
</a> </a>
</div> </div>
<!-- top small box --------------------------------------------------------- --> <!-- top small box 4 ------------------------------------------------------- -->
<div class="col-lg-3 col-sm-6 col-xs-6"> <div class="col-lg-3 col-sm-6 col-xs-6">
<a href="#" onclick="javascript: queryPresence('down');"> <a href="#" onclick="javascript: getDevicesPresence('down');">
<div class="small-box bg-red pa-small-box-red"> <div class="small-box bg-red pa-small-box-red">
<div class="inner"> <div class="inner">
<h4>Down Alerts</h4> <h4>Down Alerts</h4>
<h3 id="devicesDown"> -- </h3> <h3 id="devicesDown"> -- </h3>
</div>
<div class="icon">
<i class="fa fa-warning"></i>
</div>
<div class="small-box-footer">
Details <i class="fa fa-arrow-circle-right"></i>
</div> </div>
<div class="icon"> <i class="fa fa-warning"></i> </div>
<div class="small-box-footer"> Details <i class="fa fa-arrow-circle-right"></i> </div>
</div> </div>
</a> </a>
</div> </div>
@@ -118,20 +98,27 @@
<div class="row"> <div class="row">
<div class="col-lg-12 col-sm-12 col-xs-12"> <div class="col-lg-12 col-sm-12 col-xs-12">
<div id="tableDevicesBox" class="box" style="min-height: 500px"> <div id="tableDevicesBox" class="box" style="min-height: 500px">
<!-- box-header -->
<div class="box-header"> <div class="box-header">
<h3 id="tableDevicesTitle" class="box-title text-gray">Devices</h3> <h3 id="tableDevicesTitle" class="box-title text-gray">Devices</h3>
</div> </div>
<!-- box-body -->
<div class="box-body table-responsive"> <div class="box-body table-responsive">
<!-- spinner --> <!-- spinner -->
<div id="loading" style="display: none"> <div id="loading" style="display: none">
<div class="pa_semitransparent-panel"></div> <div class="pa_semitransparent-panel"></div>
<div class="panel panel-default pa_spinner"> <div class="panel panel-default pa_spinner">
<table><td width="130px" align="middle">Loading...</td><td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td></table> <table>
<td width="130px" align="middle">Loading...</td>
<td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td>
</table>
</div> </div>
</div> </div>
<!-- Calendar -->
<div id="calendar"></div> <div id="calendar"></div>
</div> </div>
@@ -156,15 +143,6 @@
<!-- ----------------------------------------------------------------------- --> <!-- ----------------------------------------------------------------------- -->
<!-- iCkeck -->
<link rel="stylesheet" href="lib/AdminLTE/plugins/iCheck/all.css">
<script src="lib/AdminLTE/plugins/iCheck/icheck.min.js"></script>
<!-- Datatable -->
<link rel="stylesheet" href="lib/AdminLTE/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css">
<script src="lib/AdminLTE/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
<script src="lib/AdminLTE/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
<!-- fullCalendar --> <!-- fullCalendar -->
<link rel="stylesheet" href="lib/AdminLTE/bower_components/fullcalendar/dist/fullcalendar.min.css"> <link rel="stylesheet" href="lib/AdminLTE/bower_components/fullcalendar/dist/fullcalendar.min.css">
<link rel="stylesheet" href="lib/AdminLTE/bower_components/fullcalendar/dist/fullcalendar.print.min.css" media="print"> <link rel="stylesheet" href="lib/AdminLTE/bower_components/fullcalendar/dist/fullcalendar.print.min.css" media="print">
@@ -178,23 +156,19 @@
<!-- page script ----------------------------------------------------------- --> <!-- page script ----------------------------------------------------------- -->
<script> <script>
var deviceStatus = 'all';
// Read parameters & Initialize components
main();
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
var deviceStatus = ''; function main () {
var period = '';
// Initialize MAC
var urlParams = new URLSearchParams(window.location.search);
if (urlParams.has ('status') == true) {
deviceStatus = urlParams.get ('status');
} else {
deviceStatus = 'all';
}
// Initialize components // Initialize components
$(function () { $(function () {
initializeiCheck();
initializeCalendar(); initializeCalendar();
periodChanged(); getDevicesTotals();
getDevicesPresence(deviceStatus);
}); });
// Force re-render calendar on tab change (bugfix for render error at left panel) // Force re-render calendar on tab change (bugfix for render error at left panel)
@@ -203,38 +177,12 @@
$('#calendar').fullCalendar('rerenderEvents'); $('#calendar').fullCalendar('rerenderEvents');
} }
}); });
// -----------------------------------------------------------------------------
function periodChanged () {
// Requery totals and list
queryTotals();
queryPresence(deviceStatus);
}
// -----------------------------------------------------------------------------
function initializeiCheck () {
// Default
$('input').iCheck({
checkboxClass: 'icheckbox_flat-blue',
radioClass: 'iradio_flat-blue',
increaseArea: '20%'
});
// readonly
$('#readonlyblock input').iCheck({
checkboxClass: 'icheckbox_flat-blue',
radioClass: 'iradio_flat-blue',
increaseArea: '-100%'
});
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function initializeCalendar () { function initializeCalendar () {
$('#calendar').fullCalendar({ $('#calendar').fullCalendar({
header: { header: {
left : 'prev,next today', left : 'prev,next today',
center : 'title', center : 'title',
@@ -253,8 +201,8 @@ function initializeCalendar () {
resourceOrder : '-favorite,title', resourceOrder : '-favorite,title',
schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives', //schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
// schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source', schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
views: { views: {
timelineYear: { timelineYear: {
@@ -299,7 +247,7 @@ function initializeCalendar () {
cell.removeClass('fc-sat'); cell.removeClass('fc-sat');
cell.removeClass('fc-sun'); cell.removeClass('fc-sun');
return; return;
} };
if (date.day() == 0) { if (date.day() == 0) {
cell.addClass('fc-sun'); }; cell.addClass('fc-sun'); };
@@ -312,7 +260,8 @@ function initializeCalendar () {
}, },
resourceRender: function (resourceObj, labelTds, bodyTds) { resourceRender: function (resourceObj, labelTds, bodyTds) {
labelTds.find('span.fc-cell-text').html ('<b><a href="deviceDetails.php?mac='+ resourceObj.id+ '&period='+ period +'" class="">'+ resourceObj.title +'</a></b>'); labelTds.find('span.fc-cell-text').html (
'<b><a href="deviceDetails.php?mac='+ resourceObj.id+ '" class="">'+ resourceObj.title +'</a></b>');
// Resize heihgt // Resize heihgt
// $(".fc-content table tbody tr .fc-widget-content div").addClass('fc-resized-row'); // $(".fc-content table tbody tr .fc-widget-content div").addClass('fc-resized-row');
@@ -336,78 +285,51 @@ function initializeCalendar () {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function queryTotals () { function getDevicesTotals () {
// debugTimer();
// stop timer // stop timer
stopTimerRefreshData(); stopTimerRefreshData();
// period
period = document.getElementById('period').value;
// get totals and put in boxes // get totals and put in boxes
$.get('php/server/devices.php?action=totals&period='+ period, function(data) { $.get('php/server/devices.php?action=getDevicesTotals', function(data) {
var totalsDevices = JSON.parse(data); var totalsDevices = JSON.parse(data);
$('#devicesAll').html (totalsDevices[0].toLocaleString()); $('#devicesAll').html (totalsDevices[0].toLocaleString());
$('#devicesConnected').html (totalsDevices[1].toLocaleString()); $('#devicesConnected').html (totalsDevices[1].toLocaleString());
$('#devicesNew').html (totalsDevices[2].toLocaleString()); $('#devicesNew').html (totalsDevices[2].toLocaleString());
$('#devicesDown').html (totalsDevices[3].toLocaleString()); $('#devicesDown').html (totalsDevices[3].toLocaleString());
});
// Timer for refresh data // Timer for refresh data
newTimerRefreshData (queryTotals); newTimerRefreshData (getDevicesTotals);
} );
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function queryPresence (status) { function getDevicesPresence (status) {
// Save status and period selected // Save status selected
deviceStatus = status; deviceStatus = status;
period = document.getElementById('period').value;
// Defini color & title for the status selected // Defini color & title for the status selected
switch (deviceStatus) { switch (deviceStatus) {
case 'all': case 'all': tableTitle = 'Total Devices'; color = 'aqua'; break;
tableTitle = 'Total Devices'; case 'connected': tableTitle = 'Connected Devices'; color = 'green'; break;
color = 'aqua'; case 'new': tableTitle = 'New Devices'; color = 'yellow'; break;
break; case 'down': tableTitle = 'Down Alerts'; color = 'red'; break;
case 'connected': case 'favorites': tableTitle = 'Favorites'; color = 'yellow'; break;
tableTitle = 'Connected Devices'; default: tableTitle = 'Devices'; boxClass = ''; break;
color = 'green';
break;
case 'new':
tableTitle = 'New Devices';
color = 'yellow';
break;
case 'down':
tableTitle = 'Down Alerts';
color = 'red';
break;
case 'favorites':
tableTitle = 'Favorites';
color = 'yellow';
break;
default:
tableTitle = 'Devices';
boxClass = '';
break;
} }
// Set title and color // Set title and color
document.getElementById('tableDevicesTitle').className = 'box-title text-' + color; $('#tableDevicesTitle')[0].className = 'box-title text-'+ color;
document.getElementById('tableDevicesBox').className = 'box box-' + color; $('#tableDevicesBox')[0].className = 'box box-'+ color;
$('#tableDevicesTitle').html (tableTitle); $('#tableDevicesTitle').html (tableTitle);
$('#calendar').fullCalendar ('option', 'resources', 'php/server/devices.php?action=calendar&status='+ deviceStatus +'&period='+ period); // Define new datasource URL and reload
$('#calendar').fullCalendar ('option', 'resources', 'php/server/devices.php?action=getDevicesListCalendar&status='+ deviceStatus);
$('#calendar').fullCalendar ('refetchResources'); $('#calendar').fullCalendar ('refetchResources');
// Query calendar
// resources : 'https://fullcalendar.io/demo-resources.json',
// events : 'https://fullcalendar.io/demo-events.json?with-resources',
$('#calendar').fullCalendar('removeEventSources'); $('#calendar').fullCalendar('removeEventSources');
$('#calendar').fullCalendar('addEventSource', { url: 'php/server/events.php?action=calendarPresence&period='+ period }); $('#calendar').fullCalendar('addEventSource', { url: 'php/server/events.php?action=getEventsCalendar' });
}; };
</script> </script>

View File

@@ -8,50 +8,49 @@
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3 # Puche 2021 pi.alert.application@gmail.com GNU GPLv3
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Variables # Variables
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
COLS=70 COLS=70
ROWS=12 ROWS=12
INSTALL_DIR=~ INSTALL_DIR=~
PIALERT_HOME="$INSTALL_DIR/pialert" PIALERT_HOME="$INSTALL_DIR/pialert"
LIGHTTPD_CONF_DIR="/etc/lighttpd" LIGHTTPD_CONF_DIR="/etc/lighttpd"
WEBROOT="/var/www/html" WEBROOT="/var/www/html"
PIALERT_DEFAULT_PAGE=false PIALERT_DEFAULT_PAGE=false
LOG="pialert_install_`date +"%Y-%m-%d_%H-%M"`.log" LOG="pialert_install_`date +"%Y-%m-%d_%H-%M"`.log"
MAIN_IP=`ip -o route get 1 | sed -n 's/.*src \([0-9.]\+\).*/\1/p'` MAIN_IP=`ip -o route get 1 | sed -n 's/.*src \([0-9.]\+\).*/\1/p'`
PIHOLE_INSTALL=false PIHOLE_INSTALL=false
PIHOLE_ACTIVE=false PIHOLE_ACTIVE=false
DHCP_ACTIVATE=false DHCP_ACTIVATE=false
DHCP_ACTIVE=false DHCP_ACTIVE=false
DHCP_RANGE_START="192.168.1.200" DHCP_RANGE_START="192.168.1.200"
DHCP_RANGE_END="192.168.1.251" DHCP_RANGE_END="192.168.1.251"
DHCP_ROUTER="192.168.1.1" DHCP_ROUTER="192.168.1.1"
DHCP_LEASE="1" DHCP_LEASE="1"
DHCP_DOMAIN="local" DHCP_DOMAIN="local"
USE_PYTHON_VERSION=0 USE_PYTHON_VERSION=0
PYTHON_BIN=python PYTHON_BIN=python
REPORT_MAIL=False REPORT_MAIL=False
REPORT_TO=user@gmail.com REPORT_TO=user@gmail.com
SMTP_SERVER=smtp.gmail.com SMTP_SERVER=smtp.gmail.com
SMTP_PORT=587 SMTP_PORT=587
SMTP_USER=user@gmail.com SMTP_USER=user@gmail.com
SMTP_PASS=password SMTP_PASS=password
DDNS_ACTIVE=False DDNS_ACTIVE=False
DDNS_DOMAIN='your_domain.freeddns.org' DDNS_DOMAIN='your_domain.freeddns.org'
DDNS_USER='dynu_user' DDNS_USER='dynu_user'
DDNS_PASSWORD='A0000000B0000000C0000000D0000000' DDNS_PASSWORD='A0000000B0000000C0000000D0000000'
DDNS_UPDATE_URL='https://api.dynu.com/nic/update?' DDNS_UPDATE_URL='https://api.dynu.com/nic/update?'
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -84,13 +83,14 @@ main() {
move_logfile move_logfile
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Ask config questions # Ask config questions
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
ask_config() { ask_config() {
# Ask installation # Ask installation
ask_yesno "This script will install Pi.Alert in this system using this path:\n$PIALERT_HOME" \ ask_yesno "This script will install Pi.Alert in this system using this path:\n$PIALERT_HOME" \
"Do you want to continue ?" "Do you want to continue ?"
if ! $ANSWER ; then if ! $ANSWER ; then
exit 1 exit 1
fi fi
@@ -107,11 +107,11 @@ ask_config() {
"Perfect: Pi-hole Installation not necessary" "Perfect: Pi-hole Installation not necessary"
else else
ask_yesno "Pi-hole is not installed." \ ask_yesno "Pi-hole is not installed." \
"Do you want to install Pi-hole before installing Pi.Alert ?" "YES" "Do you want to install Pi-hole before installing Pi.Alert ?" "YES"
if $ANSWER ; then if $ANSWER ; then
PIHOLE_INSTALL=true PIHOLE_INSTALL=true
msgbox "In the installation wizard of Pi-hole, select this options" \ msgbox "In the installation wizard of Pi-hole, select this options" \
"'Install web admin interface' & 'Install web server lighttpd'" "'Install web admin interface' & 'Install web server lighttpd'"
fi fi
fi fi
@@ -119,21 +119,20 @@ ask_config() {
DHCP_ACTIVE=false DHCP_ACTIVE=false
DHCP_ACTIVATE=false DHCP_ACTIVATE=false
if $PIHOLE_ACTIVE ; then if $PIHOLE_ACTIVE ; then
DHCP_ACTIVE=`sudo grep DHCP_ACTIVE /etc/pihole/setupVars.conf | DHCP_ACTIVE=`sudo grep DHCP_ACTIVE /etc/pihole/setupVars.conf | awk -F= '/./{print $2}'`
awk -F= '/./{print $2}'`
if [ "$DHCP_ACTIVE" = "" ] ; then DHCP_ACTIVE=false; fi if [ "$DHCP_ACTIVE" = "" ] ; then DHCP_ACTIVE=false; fi
if ! $DHCP_ACTIVE ; then if ! $DHCP_ACTIVE ; then
ask_yesno "Pi-hole DHCP server is not active." \ ask_yesno "Pi-hole DHCP server is not active." \
"Do you want to activate Pi-hole DHCP server ?" "Do you want to activate Pi-hole DHCP server ?"
if $ANSWER ; then if $ANSWER ; then
DHCP_ACTIVATE=true DHCP_ACTIVATE=true
fi fi
fi fi
elif $PIHOLE_INSTALL ; then elif $PIHOLE_INSTALL ; then
ask_yesno "Pi-hole installation." \ ask_yesno "Pi-hole installation." \
"Do you want to activate Pi-hole DHCP server ?" "Do you want to activate Pi-hole DHCP server ?"
if $ANSWER ; then if $ANSWER ; then
DHCP_ACTIVATE=true DHCP_ACTIVATE=true
fi fi
@@ -150,7 +149,7 @@ ask_config() {
PIALERT_DEFAULT_PAGE=false PIALERT_DEFAULT_PAGE=false
if ! $PIHOLE_ACTIVE && ! $PIHOLE_INSTALL; then if ! $PIHOLE_ACTIVE && ! $PIHOLE_INSTALL; then
ask_yesno "As Pi-hole is not going to be available in this system," \ ask_yesno "As Pi-hole is not going to be available in this system," \
"Do you want to use Pi.Alert as default web server page ?" "YES" "Do you want to use Pi.Alert as default web server page ?" "YES"
if $ANSWER ; then if $ANSWER ; then
PIALERT_DEFAULT_PAGE=true PIALERT_DEFAULT_PAGE=true
fi fi
@@ -158,10 +157,10 @@ ask_config() {
# Ask Python version # Ask Python version
ask_option "What Python version do you want to use ?" \ ask_option "What Python version do you want to use ?" \
3 \ 3 \
0 " - Use Python already installed in the system (DEFAULT)" \ 0 " - Use Python already installed in the system (DEFAULT)" \
2 " - Use Python 2" \ 2 " - Use Python 2" \
3 " - Use Python 3" 3 " - Use Python 3"
if [ "$ANSWER" = "" ] ; then if [ "$ANSWER" = "" ] ; then
USE_PYTHON_VERSION=0 USE_PYTHON_VERSION=0
else else
@@ -171,10 +170,10 @@ ask_config() {
# Ask e-mail notification config # Ask e-mail notification config
MAIL_REPORT=false MAIL_REPORT=false
ask_yesno "Pi.Alert can notify you by e-mail when a network event occurs" \ ask_yesno "Pi.Alert can notify you by e-mail when a network event occurs" \
"Do you want to activate this feature ?" "Do you want to activate this feature ?"
if $ANSWER ; then if $ANSWER ; then
ask_yesno "e-mail notification needs a SMTP server (i.e. smtp.gmail.com)" \ ask_yesno "e-mail notification needs a SMTP server (i.e. smtp.gmail.com)" \
"Do you want to continue activating this feature ?" "Do you want to continue activating this feature ?"
MAIL_REPORT=$ANSWER MAIL_REPORT=$ANSWER
fi fi
@@ -195,10 +194,10 @@ ask_config() {
# Ask Dynamic DNS config # Ask Dynamic DNS config
DDNS_ACTIVE=false DDNS_ACTIVE=false
ask_yesno "Pi.Alert can update your Dynamic DNS IP (i.e with www.dynu.net)" \ ask_yesno "Pi.Alert can update your Dynamic DNS IP (i.e with www.dynu.net)" \
"Do you want to activate this feature ?" "Do you want to activate this feature ?"
if $ANSWER ; then if $ANSWER ; then
ask_yesno "Dynamics DNS updater needs a DNS with IP Update Protocol" \ ask_yesno "Dynamics DNS updater needs a DNS with IP Update Protocol" \
"(i.e with www.dynu.net). Do you want to continue ?" "(i.e with www.dynu.net). Do you want to continue ?"
DDNS_ACTIVE=$ANSWER DDNS_ACTIVE=$ANSWER
fi fi
@@ -218,11 +217,12 @@ ask_config() {
# Final config message # Final config message
msgbox "Configuration finished. To updete the configuration, edit file:" \ msgbox "Configuration finished. To updete the configuration, edit file:" \
"$PIALERT_HOME/config/pialert.conf" "$PIALERT_HOME/config/pialert.conf"
msgbox "" "The installation will start now" msgbox "" "The installation will start now"
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Install Pi-hole # Install Pi-hole
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -250,6 +250,7 @@ install_pihole() {
PIHOLE_ACTIVE=true PIHOLE_ACTIVE=true
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Activate DHCP # Activate DHCP
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -264,8 +265,7 @@ activate_DHCP() {
print_msg "- Checking if DHCP is active..." print_msg "- Checking if DHCP is active..."
if [ -e /etc/pihole ]; then if [ -e /etc/pihole ]; then
DHCP_ACTIVE= \ DHCP_ACTIVE= `grep DHCP_ACTIVE /etc/pihole/setupVars.conf | awk -F= '/./{print $2}'`
`grep DHCP_ACTIVE /etc/pihole/setupVars.conf | awk -F= '/./{print $2}'`
fi fi
if $DHCP_ACTIVE ; then if $DHCP_ACTIVE ; then
@@ -273,11 +273,11 @@ activate_DHCP() {
fi fi
print_msg "- Activating DHCP..." print_msg "- Activating DHCP..."
sudo pihole -a enabledhcp "$DHCP_RANGE_START" "$DHCP_RANGE_END" \ sudo pihole -a enabledhcp "$DHCP_RANGE_START" "$DHCP_RANGE_END" "$DHCP_ROUTER" "$DHCP_LEASE" "$DHCP_DOMAIN" 2>&1 >> "$LOG"
"$DHCP_ROUTER" "$DHCP_LEASE" "$DHCP_DOMAIN" 2>&1 >> "$LOG"
DHCP_ACTIVE=true DHCP_ACTIVE=true
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Add Pi.Alert DNS # Add Pi.Alert DNS
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -322,6 +322,7 @@ install_lighttpd() {
sudo /etc/init.d/lighttpd restart 2>&1 >> "$LOG" sudo /etc/init.d/lighttpd restart 2>&1 >> "$LOG"
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Install arp-scan & dnsutils # Install arp-scan & dnsutils
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -384,6 +385,7 @@ install_python() {
fi fi
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Check Python versions available # Check Python versions available
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -426,6 +428,7 @@ install_pialert() {
set_pialert_default_page set_pialert_default_page
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Download and uncompress Pi.Alert # Download and uncompress Pi.Alert
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -436,19 +439,18 @@ download_pialert() {
fi fi
print_msg "- Downloading installation tar file..." print_msg "- Downloading installation tar file..."
curl -Lo "$INSTALL_DIR/pialert_latest.tar" \ curl -Lo "$INSTALL_DIR/pialert_latest.tar" https://github.com/pucherot/Pi.Alert/raw/main/tar/pialert_latest.tar
https://github.com/pucherot/Pi.Alert/raw/main/tar/pialert_latest.tar
echo "" echo ""
print_msg "- Uncompressing tar file" print_msg "- Uncompressing tar file"
tar xf "$INSTALL_DIR/pialert_latest.tar" -C "$INSTALL_DIR" \ tar xf "$INSTALL_DIR/pialert_latest.tar" -C "$INSTALL_DIR" --checkpoint=100 --checkpoint-action="ttyout=." 2>&1 >> "$LOG"
--checkpoint=100 --checkpoint-action="ttyout=." 2>&1 >> "$LOG"
echo "" echo ""
print_msg "- Deleting downloaded tar file..." print_msg "- Deleting downloaded tar file..."
rm -r "$INSTALL_DIR/pialert_latest.tar" rm -r "$INSTALL_DIR/pialert_latest.tar"
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Configure Pi.Alert parameters # Configure Pi.Alert parameters
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -474,6 +476,7 @@ configure_pialert() {
set_pialert_parameter DHCP_ACTIVE "$DHCP_ACTIVE" set_pialert_parameter DHCP_ACTIVE "$DHCP_ACTIVE"
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Set Pi.Alert parameter # Set Pi.Alert parameter
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -486,8 +489,7 @@ set_pialert_parameter() {
VALUE="$2" VALUE="$2"
fi fi
sed -i "/^$1.*=/s|=.*|= $VALUE|" $PIALERT_HOME/config/pialert.conf \ sed -i "/^$1.*=/s|=.*|= $VALUE|" $PIALERT_HOME/config/pialert.conf 2>&1 >> "$LOG"
2>&1 >> "$LOG"
} }
@@ -497,20 +499,16 @@ set_pialert_parameter() {
test_pialert() { test_pialert() {
print_msg "- Testing Pi.Alert HW vendors database update process..." print_msg "- Testing Pi.Alert HW vendors database update process..."
print_msg "*** PLEASE WAIT A COUPLE OF MINUTES..." print_msg "*** PLEASE WAIT A COUPLE OF MINUTES..."
stdbuf -i0 -o0 -e0 \ stdbuf -i0 -o0 -e0 $PYTHON_BIN $PIALERT_HOME/back/pialert.py update_vendors_silent 2>&1 | tee -ai "$LOG"
$PYTHON_BIN $PIALERT_HOME/back/pialert.py update_vendors_silent 2>&1 \
| tee -ai "$LOG"
echo "" echo ""
print_msg "- Testing Pi.Alert Internet IP Lookup..." print_msg "- Testing Pi.Alert Internet IP Lookup..."
stdbuf -i0 -o0 -e0 \ stdbuf -i0 -o0 -e0 $PYTHON_BIN $PIALERT_HOME/back/pialert.py internet_IP 2>&1 | tee -ai "$LOG"
$PYTHON_BIN $PIALERT_HOME/back/pialert.py internet_IP 2>&1 | tee -ai "$LOG"
echo "" echo ""
print_msg "- Testing Pi.Alert Network scan..." print_msg "- Testing Pi.Alert Network scan..."
print_msg "*** PLEASE WAIT A COUPLE OF MINUTES..." print_msg "*** PLEASE WAIT A COUPLE OF MINUTES..."
stdbuf -i0 -o0 -e0 \ stdbuf -i0 -o0 -e0 $PYTHON_BIN $PIALERT_HOME/back/pialert.py 1 2>&1 | tee -ai "$LOG"
$PYTHON_BIN $PIALERT_HOME/back/pialert.py 1 2>&1 | tee -ai "$LOG"
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -528,8 +526,7 @@ add_jobs_to_crontab() {
sed -i "s/\<python\>/$PYTHON_BIN/g" $PIALERT_HOME/install/pialert.cron sed -i "s/\<python\>/$PYTHON_BIN/g" $PIALERT_HOME/install/pialert.cron
fi fi
(crontab -l 2>/dev/null || : ; cat $PIALERT_HOME/install/pialert.cron) | \ (crontab -l 2>/dev/null || : ; cat $PIALERT_HOME/install/pialert.cron) | crontab -
crontab -
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -551,20 +548,16 @@ publish_pialert() {
print_msg "- Configuring http://pi.alert/ redirection..." print_msg "- Configuring http://pi.alert/ redirection..."
if [ -e "$LIGHTTPD_CONF_DIR/conf-available/pialert_front.conf" ] ; then if [ -e "$LIGHTTPD_CONF_DIR/conf-available/pialert_front.conf" ] ; then
sudo rm -r "$LIGHTTPD_CONF_DIR/conf-available/pialert_front.conf" \ sudo rm -r "$LIGHTTPD_CONF_DIR/conf-available/pialert_front.conf" 2>&1 >> "$LOG"
2>&1 >> "$LOG"
fi fi
sudo cp "$PIALERT_HOME/install/pialert_front.conf" \ sudo cp "$PIALERT_HOME/install/pialert_front.conf" "$LIGHTTPD_CONF_DIR/conf-available" 2>&1 >> "$LOG"
"$LIGHTTPD_CONF_DIR/conf-available" 2>&1 >> "$LOG"
if [ -e "$LIGHTTPD_CONF_DIR/conf-enabled/pialert_front.conf" ] || \ if [ -e "$LIGHTTPD_CONF_DIR/conf-enabled/pialert_front.conf" ] || \
[ -L "$LIGHTTPD_CONF_DIR/conf-enabled/pialert_front.conf" ] ; then [ -L "$LIGHTTPD_CONF_DIR/conf-enabled/pialert_front.conf" ] ; then
sudo rm -r "$LIGHTTPD_CONF_DIR/conf-enabled/pialert_front.conf" \ sudo rm -r "$LIGHTTPD_CONF_DIR/conf-enabled/pialert_front.conf" 2>&1 >> "$LOG"
2>&1 >> "$LOG"
fi fi
sudo ln -s ../conf-available/pialert_front.conf \ sudo ln -s ../conf-available/pialert_front.conf "$LIGHTTPD_CONF_DIR/conf-enabled/pialert_front.conf" 2>&1 >> "$LOG"
"$LIGHTTPD_CONF_DIR/conf-enabled/pialert_front.conf" 2>&1 >> "$LOG"
print_msg "- Restarting lighttpd..." print_msg "- Restarting lighttpd..."
sudo /etc/init.d/lighttpd restart 2>&1 >> "$LOG" sudo /etc/init.d/lighttpd restart 2>&1 >> "$LOG"
@@ -584,8 +577,7 @@ set_pialert_default_page() {
if [ -e "$WEBROOT/index.lighttpd.html.orig" ] ; then if [ -e "$WEBROOT/index.lighttpd.html.orig" ] ; then
sudo rm "$WEBROOT/index.lighttpd.html" 2>&1 >> "$LOG" sudo rm "$WEBROOT/index.lighttpd.html" 2>&1 >> "$LOG"
else else
sudo mv "$WEBROOT/index.lighttpd.html" \ sudo mv "$WEBROOT/index.lighttpd.html" "$WEBROOT/index.lighttpd.html.orig" 2>&1 >> "$LOG"
"$WEBROOT/index.lighttpd.html.orig" 2>&1 >> "$LOG"
fi fi
fi fi
@@ -638,8 +630,7 @@ msgbox() {
END_DIALOG=false END_DIALOG=false
while ! $END_DIALOG ; do while ! $END_DIALOG ; do
whiptail --title "Pi.Alert Installation" --msgbox "$LINE1\\n\\n$LINE2" \ whiptail --title "Pi.Alert Installation" --msgbox "$LINE1\\n\\n$LINE2" $ROWS $COLS
$ROWS $COLS
BUTTON=$? BUTTON=$?
ask_cancel ask_cancel
ANSWER=true ANSWER=true
@@ -658,8 +649,7 @@ ask_yesno() {
END_DIALOG=false END_DIALOG=false
while ! $END_DIALOG ; do while ! $END_DIALOG ; do
whiptail --title "Pi.Alert Installation" --yesno $DEF_BUTTON \ whiptail --title "Pi.Alert Installation" --yesno $DEF_BUTTON "$LINE1\\n\\n$LINE2" $ROWS $COLS
"$LINE1\\n\\n$LINE2" $ROWS $COLS
BUTTON=$? BUTTON=$?
ask_cancel ask_cancel
done done
@@ -677,8 +667,7 @@ ask_option() {
END_DIALOG=false END_DIALOG=false
while ! $END_DIALOG ; do while ! $END_DIALOG ; do
ANSWER=$(whiptail --title "Pi.Alert Installation" --menu "$1" $ROWS $COLS \ ANSWER=$(whiptail --title "Pi.Alert Installation" --menu "$1" $ROWS $COLS "${MENU_ARGS[@]}" 3>&2 2>&1 1>&3 )
"${MENU_ARGS[@]}" 3>&2 2>&1 1>&3 )
BUTTON=$? BUTTON=$?
ask_cancel CANCEL ask_cancel CANCEL
done done
@@ -690,8 +679,7 @@ ask_input() {
END_DIALOG=false END_DIALOG=false
while ! $END_DIALOG ; do while ! $END_DIALOG ; do
ANSWER=$(whiptail --title "Pi.Alert Installation" --inputbox \ ANSWER=$(whiptail --title "Pi.Alert Installation" --inputbox "$LINE1\\n\\n$LINE2" $ROWS $COLS "$3" 3>&2 2>&1 1>&3 )
"$LINE1\\n\\n$LINE2" $ROWS $COLS "$3" 3>&2 2>&1 1>&3 )
BUTTON=$? BUTTON=$?
ask_cancel CANCEL ask_cancel CANCEL
@@ -709,8 +697,7 @@ ask_cancel() {
if [ "$BUTTON" = "1" ] && [ "$1" = "CANCEL" ] ; then BUTTON="255"; fi if [ "$BUTTON" = "1" ] && [ "$1" = "CANCEL" ] ; then BUTTON="255"; fi
if [ "$BUTTON" = "255" ] ; then if [ "$BUTTON" = "255" ] ; then
whiptail --title "Pi.Alert Installation" --yesno --defaultno "$LINE0" \ whiptail --title "Pi.Alert Installation" --yesno --defaultno "$LINE0" $ROWS $COLS
$ROWS $COLS
if [ "$?" = "0" ] ; then if [ "$?" = "0" ] ; then
process_error "Installation Aborted by User" process_error "Installation Aborted by User"

View File

@@ -8,7 +8,6 @@
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3 # Puche 2021 pi.alert.application@gmail.com GNU GPLv3
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Variables # Variables
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -57,8 +56,7 @@ create_backup() {
print_msg "- Creating new Pi.Alert backup..." print_msg "- Creating new Pi.Alert backup..."
cd "$INSTALL_DIR" cd "$INSTALL_DIR"
tar cvf "$INSTALL_DIR"/pialert_update_backup_`date +"%Y-%m-%d_%H-%M"`.tar \ tar cvf "$INSTALL_DIR"/pialert_update_backup_`date +"%Y-%m-%d_%H-%M"`.tar pialert --checkpoint=100 --checkpoint-action="ttyout=." 2>&1 >> "$LOG"
pialert --checkpoint=100 --checkpoint-action="ttyout=." 2>&1 >> "$LOG"
echo "" echo ""
} }
@@ -97,13 +95,13 @@ download_pialert() {
fi fi
print_msg "- Downloading update file..." print_msg "- Downloading update file..."
curl -Lo "$INSTALL_DIR/pialert_latest.tar" \ curl -Lo "$INSTALL_DIR/pialert_latest.tar" https://github.com/pucherot/Pi.Alert/raw/main/tar/pialert_latest.tar
https://github.com/pucherot/Pi.Alert/raw/main/tar/pialert_latest.tar
echo "" echo ""
print_msg "- Uncompressing tar file" print_msg "- Uncompressing tar file"
tar xf "$INSTALL_DIR/pialert_latest.tar" -C "$INSTALL_DIR" \ tar xf "$INSTALL_DIR/pialert_latest.tar" -C "$INSTALL_DIR" \
--exclude='pialert/config/pialert.conf' --exclude='pialert/db/pialert.db' \ --exclude='pialert/config/pialert.conf' \
--exclude='pialert/db/pialert.db' \
--exclude='pialert/log/*' \ --exclude='pialert/log/*' \
--checkpoint=100 --checkpoint-action="ttyout=." 2>&1 >> "$LOG" --checkpoint=100 --checkpoint-action="ttyout=." 2>&1 >> "$LOG"
echo "" echo ""
@@ -117,32 +115,47 @@ download_pialert() {
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
update_config() { update_config() {
print_msg "- Config backup..." print_msg "- Config backup..."
cp "$PIALERT_HOME/config/pialert.conf" \ cp "$PIALERT_HOME/config/pialert.conf" "$PIALERT_HOME/config/pialert.conf.back" 2>&1 >> "$LOG"
"$PIALERT_HOME/config/pialert.conf.back" 2>&1 >> "$LOG"
print_msg "- Updating config file..." print_msg "- Updating config file..."
sed -i '/VERSION/d' "$PIALERT_HOME/config/pialert.conf" 2>&1 >> "$LOG" sed -i '/VERSION/d' "$PIALERT_HOME/config/pialert.conf" 2>&1 >> "$LOG"
sed -i 's/PA_FRONT_URL/REPORT_DEVICE_URL/g' \ sed -i 's/PA_FRONT_URL/REPORT_DEVICE_URL/g' "$PIALERT_HOME/config/pialert.conf" 2>&1 >> "$LOG"
"$PIALERT_HOME/config/pialert.conf" 2>&1 >> "$LOG"
if ! grep -Fq PIALERT_PATH "$PIALERT_HOME/config/pialert.conf" ; then if ! grep -Fq PIALERT_PATH "$PIALERT_HOME/config/pialert.conf" ; then
echo "PIALERT_PATH = '$PIALERT_HOME'" >> \ echo "PIALERT_PATH = '$PIALERT_HOME'" >> "$PIALERT_HOME/config/pialert.conf"
"$PIALERT_HOME/config/pialert.conf"
fi fi
if ! grep -Fq QUERY_MYIP_SERVER "$PIALERT_HOME/config/pialert.conf" ; then if ! grep -Fq QUERY_MYIP_SERVER "$PIALERT_HOME/config/pialert.conf" ; then
echo "QUERY_MYIP_SERVER = 'http://ipv4.icanhazip.com'" >> \ echo "QUERY_MYIP_SERVER = 'http://ipv4.icanhazip.com'" >> "$PIALERT_HOME/config/pialert.conf"
"$PIALERT_HOME/config/pialert.conf"
fi fi
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# # DB DDL
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
update_db() { update_db() {
print_msg "- Updating DB permissions..." print_msg "- Updating DB permissions..."
sudo chgrp -R www-data $PIALERT_HOME/db 2>&1 >> "$LOG" sudo chgrp -R www-data $PIALERT_HOME/db 2>&1 >> "$LOG"
chmod -R 770 $PIALERT_HOME/db 2>&1 >> "$LOG" chmod -R 770 $PIALERT_HOME/db 2>&1 >> "$LOG"
print_msg "- Checking Parameters table..."
TAB=`sqlite3 $PIALERT_HOME/db/pialert.db "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='Parameters' COLLATE NOCASE;"` 2>&1 >> "$LOG"
if [ "TAB" == "0" ] ; then
print_msg " - Checking Parameters table..."
sqlite3 $PIALERT_HOME/db/pialert.db "CREATE TABLE Parameters (par_ID STRING (50) PRIMARY KEY NOT NULL COLLATE NOCASE, par_Value STRING (250));" 2>&1 >> "$LOG"
sqlite3 $PIALERT_HOME/db/pialert.db "CREATE INDEX IDX_par_ID ON Parameters (par_ID COLLATE NOCASE);" 2>&1 >> "$LOG"
fi
print_msg "- Checking Devices new columns..."
COL=`sqlite3 pialert.db "SELECT COUNT(*) FROM PRAGMA_TABLE_INFO ('Devices') WHERE name='dev_NewDevice' COLLATE NOCASE";` 2>&1 >> "$LOG"
if [ "TAB" == "0" ] ; then
sqlite3 $PIALERT_HOME/db/pialert.db "ALTER TABLE Devices ADD COLUMN dev_NewDevice BOOLEAN NOT NULL DEFAULT (1) CHECK (dev_NewDevice IN (0, 1) );" 2>&1 >> "$LOG"
sqlite3 $PIALERT_HOME/db/pialert.db "CREATE INDEX IDX_dev_NewDevice ON Devices (dev_NewDevice);"
COL=`sqlite3 pialert.db "SELECT COUNT(*) FROM PRAGMA_TABLE_INFO ('Devices') WHERE name='dev_Location' COLLATE NOCASE";` 2>&1 >> "$LOG"
if [ "TAB" == "0" ] ; then
sqlite3 $PIALERT_HOME/db/pialert.db "ALTER TABLE Devices ADD COLUMN dev_Location STRING(250) COLLATE NOCASE);" 2>&1 >> "$LOG"
fi
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -151,20 +164,16 @@ update_db() {
test_pialert() { test_pialert() {
print_msg "- Testing Pi.Alert HW vendors database update process..." print_msg "- Testing Pi.Alert HW vendors database update process..."
print_msg "*** PLEASE WAIT A COUPLE OF MINUTES..." print_msg "*** PLEASE WAIT A COUPLE OF MINUTES..."
stdbuf -i0 -o0 -e0 \ stdbuf -i0 -o0 -e0 $PYTHON_BIN $PIALERT_HOME/back/pialert.py update_vendors_silent 2>&1 | tee -ai "$LOG"
$PYTHON_BIN $PIALERT_HOME/back/pialert.py update_vendors_silent 2>&1 \
| tee -ai "$LOG"
echo "" echo ""
print_msg "- Testing Pi.Alert Internet IP Lookup..." print_msg "- Testing Pi.Alert Internet IP Lookup..."
stdbuf -i0 -o0 -e0 \ stdbuf -i0 -o0 -e0 $PYTHON_BIN $PIALERT_HOME/back/pialert.py internet_IP 2>&1 | tee -ai "$LOG"
$PYTHON_BIN $PIALERT_HOME/back/pialert.py internet_IP 2>&1 | tee -ai "$LOG"
echo "" echo ""
print_msg "- Testing Pi.Alert Network scan..." print_msg "- Testing Pi.Alert Network scan..."
print_msg "*** PLEASE WAIT A COUPLE OF MINUTES..." print_msg "*** PLEASE WAIT A COUPLE OF MINUTES..."
stdbuf -i0 -o0 -e0 \ stdbuf -i0 -o0 -e0 $PYTHON_BIN $PIALERT_HOME/back/pialert.py 1 2>&1 | tee -ai "$LOG"
$PYTHON_BIN $PIALERT_HOME/back/pialert.py 1 2>&1 | tee -ai "$LOG"
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@@ -25,4 +25,3 @@ tar cvf pialert/tar/pialert_$PIALERT_VERSION.tar --exclude="pialert/tar" --exclu
ln -s pialert_$PIALERT_VERSION.tar pialert/tar/pialert_latest.tar ln -s pialert_$PIALERT_VERSION.tar pialert/tar/pialert_latest.tar
ls -l pialert/tar/pialert*.tar ls -l pialert/tar/pialert*.tar

Binary file not shown.