mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-05-24 06:27:07 -04:00
Merge remote-tracking branch 'upstream/master' into 4757-hls-fragment-tracking
This commit is contained in:
@@ -58,7 +58,9 @@ ajaxError('Unrecognised action '.$_REQUEST['action'].' or insufficient permissio
|
||||
function queryRequest() {
|
||||
global $user, $Servers;
|
||||
require_once('includes/Monitor.php');
|
||||
require_once('includes/Group.php');
|
||||
require_once('includes/Group_Monitor.php');
|
||||
require_once getSkinFile('views/_monitor_filters.php');
|
||||
|
||||
$data = array(
|
||||
'total' => 0,
|
||||
@@ -92,34 +94,46 @@ function queryRequest() {
|
||||
$sort = isset($_REQUEST['sort']) ? $_REQUEST['sort'] : 'Sequence';
|
||||
$order = isset($_REQUEST['order']) ? strtoupper($_REQUEST['order']) : 'ASC';
|
||||
|
||||
// Build monitor query with filters from request parameters (stateless)
|
||||
// Build monitor query with filters from request parameters, falling back to cookies
|
||||
$conditions = array();
|
||||
$values = array();
|
||||
|
||||
// Get filter values directly from request
|
||||
// Get filter values from request, falling back to cookies for persistence after page refresh.
|
||||
// getFilterSelection() reads $_REQUEST first, then the zmFilter_* cookie.
|
||||
$request_filters = array(
|
||||
'GroupId' => isset($_REQUEST['GroupId']) ? $_REQUEST['GroupId'] : null,
|
||||
'ServerId' => isset($_REQUEST['ServerId']) ? $_REQUEST['ServerId'] : null,
|
||||
'StorageId' => isset($_REQUEST['StorageId']) ? $_REQUEST['StorageId'] : null,
|
||||
'Capturing' => isset($_REQUEST['Capturing']) ? $_REQUEST['Capturing'] : null,
|
||||
'Analysing' => isset($_REQUEST['Analysing']) ? $_REQUEST['Analysing'] : null,
|
||||
'Recording' => isset($_REQUEST['Recording']) ? $_REQUEST['Recording'] : null,
|
||||
'Status' => isset($_REQUEST['Status']) ? $_REQUEST['Status'] : null,
|
||||
'MonitorId' => isset($_REQUEST['MonitorId']) ? $_REQUEST['MonitorId'] : null,
|
||||
'MonitorName' => isset($_REQUEST['MonitorName']) ? $_REQUEST['MonitorName'] : null,
|
||||
'Source' => isset($_REQUEST['Source']) ? $_REQUEST['Source'] : null
|
||||
'GroupId' => getFilterSelection('GroupId'),
|
||||
'ServerId' => getFilterSelection('ServerId'),
|
||||
'StorageId' => getFilterSelection('StorageId'),
|
||||
'Capturing' => getFilterSelection('Capturing'),
|
||||
'Analysing' => getFilterSelection('Analysing'),
|
||||
'Recording' => getFilterSelection('Recording'),
|
||||
'Status' => getFilterSelection('Status'),
|
||||
'MonitorId' => getFilterSelection('MonitorId'),
|
||||
'MonitorName' => getFilterSelection('MonitorName'),
|
||||
'Source' => getFilterSelection('Source')
|
||||
);
|
||||
// Text filters must be strings; guard against a cookie value that happens to be valid JSON.
|
||||
if (is_array($request_filters['MonitorName'])) $request_filters['MonitorName'] = '';
|
||||
if (is_array($request_filters['Source'])) $request_filters['Source'] = '';
|
||||
|
||||
// Apply request filters to SQL
|
||||
// Apply GroupId filter using get_group_sql() to include child groups.
|
||||
// Use validCardinal() to sanitize ID values before use.
|
||||
if ($request_filters['GroupId']) {
|
||||
$GroupIds = is_array($request_filters['GroupId']) ? $request_filters['GroupId'] : array($request_filters['GroupId']);
|
||||
$conditions[] = 'M.Id IN (SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (' . implode(',', array_fill(0, count($GroupIds), '?')) . '))';
|
||||
$values = array_merge($values, $GroupIds);
|
||||
$groupIds = is_array($request_filters['GroupId']) ? $request_filters['GroupId'] : array($request_filters['GroupId']);
|
||||
$groupIds = array_values(array_filter(array_map('validCardinal', $groupIds)));
|
||||
if (count($groupIds)) {
|
||||
$groupSql = ZM\Group::get_group_sql($groupIds);
|
||||
if ($groupSql) {
|
||||
$conditions[] = $groupSql;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (array('ServerId','StorageId') as $filter) {
|
||||
if ($request_filters[$filter]) {
|
||||
$filter_values = is_array($request_filters[$filter]) ? $request_filters[$filter] : array($request_filters[$filter]);
|
||||
// Use validCardinal() to sanitize ID values
|
||||
$filter_values = array_values(array_filter(array_map('validCardinal', $filter_values)));
|
||||
if (count($filter_values)) {
|
||||
$conditions[] = 'M.'.$filter.' IN (' . implode(',', array_fill(0, count($filter_values), '?')) . ')';
|
||||
$values = array_merge($values, $filter_values);
|
||||
@@ -203,12 +217,15 @@ function queryRequest() {
|
||||
});
|
||||
}
|
||||
|
||||
// Apply MonitorId filter
|
||||
// Apply MonitorId filter (use validCardinal() to sanitize ID values)
|
||||
if ($request_filters['MonitorId']) {
|
||||
$monitor_ids = is_array($request_filters['MonitorId']) ? $request_filters['MonitorId'] : array($request_filters['MonitorId']);
|
||||
$filtered_monitors = array_filter($filtered_monitors, function($monitor) use ($monitor_ids) {
|
||||
return in_array($monitor['Id'], $monitor_ids);
|
||||
});
|
||||
$monitor_ids = array_values(array_filter(array_map('validCardinal', $monitor_ids)));
|
||||
if (count($monitor_ids)) {
|
||||
$filtered_monitors = array_filter($filtered_monitors, function($monitor) use ($monitor_ids) {
|
||||
return in_array($monitor['Id'], $monitor_ids);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$data['total'] = count($filtered_monitors);
|
||||
|
||||
@@ -262,9 +262,14 @@ class EventsController extends AppController {
|
||||
return;
|
||||
}
|
||||
|
||||
# Get the previous and next events for any monitor
|
||||
# Get the previous and next events for any monitor.
|
||||
# Only Id is used below, so skip the wide SELECT + Monitor/Storage joins + Frames hasMany expansion
|
||||
# that recursive=1 from above would otherwise pull in for each neighbor row.
|
||||
$this->Event->id = $id;
|
||||
$event_neighbors = $this->Event->find('neighbors');
|
||||
$event_neighbors = $this->Event->find('neighbors', array(
|
||||
'fields' => array('Event.Id'),
|
||||
'recursive' => -1,
|
||||
));
|
||||
$event['Event']['Next'] = isset($event_neighbors['next']) ? $event_neighbors['next']['Event']['Id'] : 0;
|
||||
$event['Event']['Prev'] = isset($event_neighbors['prev']) ? $event_neighbors['prev']['Event']['Id'] : 0;
|
||||
|
||||
@@ -274,7 +279,9 @@ class EventsController extends AppController {
|
||||
|
||||
# Also get the previous and next events for the same monitor
|
||||
$event_monitor_neighbors = $this->Event->find('neighbors', array(
|
||||
'conditions'=>array('Event.MonitorId'=>$event['Event']['MonitorId'])
|
||||
'fields' => array('Event.Id'),
|
||||
'recursive' => -1,
|
||||
'conditions' => array('Event.MonitorId' => $event['Event']['MonitorId']),
|
||||
));
|
||||
$event['Event']['NextOfMonitor'] = isset($event_monitor_neighbors['next']) ? $event_monitor_neighbors['next']['Event']['Id'] : 0;
|
||||
$event['Event']['PrevOfMonitor'] = isset($event_monitor_neighbors['prev']) ? $event_monitor_neighbors['prev']['Event']['Id'] : 0;
|
||||
|
||||
@@ -193,15 +193,6 @@ function getAuthUser($auth) {
|
||||
$sessionUser = isset($_SESSION['username']) ? $_SESSION['username'] : null;
|
||||
$filterUser = $requestedUser !== null ? $requestedUser : $sessionUser;
|
||||
|
||||
if ($requestedUser !== null && $sessionUser !== null) {
|
||||
$usersMatch = ZM_CASE_INSENSITIVE_USERNAMES
|
||||
? (strcasecmp($requestedUser, $sessionUser) === 0)
|
||||
: ($requestedUser === $sessionUser);
|
||||
if (!$usersMatch) {
|
||||
ZM\Warning("Auth user mismatch: URL user='$requestedUser' but session username='$sessionUser'. This may indicate a stale auth hash from a previous login, cross-tab session contamination, or a tampered request.");
|
||||
}
|
||||
}
|
||||
|
||||
ZM\Debug("getAuthUser: validating auth='$auth' filterUser='".($filterUser ?? '')."' xff='$xff' directAddr='$directAddr' usingRemoteAddr='$remoteAddr' session_username='".($sessionUser ?? '')."'");
|
||||
|
||||
$sql = 'SELECT * FROM Users WHERE Enabled = 1';
|
||||
@@ -257,7 +248,7 @@ function getAuthUser($auth) {
|
||||
} // end foreach user
|
||||
} // end if
|
||||
|
||||
ZM\Info("Unable to authenticate user from auth hash '$auth' (filterUser='".($filterUser ?? '')."' xff='$xff' directAddr='$directAddr' rowsTried=$rowsTried ttl=".ZM_AUTH_HASH_TTL.'h)');
|
||||
ZM\Info("Unable to authenticate user from auth hash '$auth' (filterUser='".($filterUser ?? '')."' sessionUser='".($sessionUser ?? '')."' xff='$xff' directAddr='$directAddr' rowsTried=$rowsTried ttl=".ZM_AUTH_HASH_TTL.'h)');
|
||||
return null;
|
||||
} // end if using auth hash
|
||||
|
||||
|
||||
@@ -615,7 +615,10 @@ function submitThisForm(param = null) {
|
||||
// Let's hide the old filter so that it doesn't appear during the transfer...
|
||||
filter.style.display = 'none';
|
||||
// We return the filter to its place in the form, since in the left side menu the filter should always be inside the form.
|
||||
form.prepend(filter);
|
||||
// Skip if filter is already an ancestor of form (e.g. console: #fbpanel > #monitorFiltersForm), which would cause HierarchyRequestError.
|
||||
if (!filter.contains(form)) {
|
||||
form.prepend(filter);
|
||||
}
|
||||
}
|
||||
if (param && typeof param === 'string') { //ON WATCH PAGE WHEN SELECTING A MONITOR, the object is transferred as PARAM!!!
|
||||
var uri = "?" + $j(form).serialize() + param;
|
||||
|
||||
Reference in New Issue
Block a user