Compare commits
No commits in common. "main" and "v0.3" have entirely different histories.
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -4,22 +4,6 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
---
|
||||
|
||||
## Unreleased
|
||||
|
||||
#### Links
|
||||
- upstream: https://code.lindeas.com/lindeas/jilo-web/compare/v0.3...HEAD
|
||||
- codeberg: https://codeberg.org/lindeas/jilo-web/compare/v0.3...HEAD
|
||||
- github: https://github.com/lindeas/jilo-web/compare/v0.3...HEAD
|
||||
- gitlab: https://gitlab.com/lindeas/jilo-web/-/compare/v0.3...HEAD
|
||||
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
|
||||
### Fixed
|
||||
|
||||
---
|
||||
|
||||
## 0.3 - 2025-01-15
|
||||
|
||||
#### Links
|
||||
|
|
|
@ -34,6 +34,7 @@ class Host {
|
|||
$sql = 'SELECT
|
||||
id,
|
||||
address,
|
||||
port,
|
||||
platform_id,
|
||||
name
|
||||
FROM
|
||||
|
@ -72,13 +73,14 @@ class Host {
|
|||
public function addHost($newHost) {
|
||||
try {
|
||||
$sql = 'INSERT INTO hosts
|
||||
(address, platform_id, name)
|
||||
(address, port, platform_id, name)
|
||||
VALUES
|
||||
(:address, :platform_id, :name)';
|
||||
(:address, :port, :platform_id, :name)';
|
||||
|
||||
$query = $this->db->prepare($sql);
|
||||
$query->execute([
|
||||
':address' => $newHost['address'],
|
||||
':port' => $newHost['port'],
|
||||
':platform_id' => $newHost['platform_id'],
|
||||
':name' => $newHost['name'],
|
||||
]);
|
||||
|
@ -97,28 +99,25 @@ class Host {
|
|||
* @param string $platform_id The platform ID to which the host belongs.
|
||||
* @param array $updatedHost An associative array containing the updated details of the host.
|
||||
*
|
||||
* @return bool|string True if the host was updated successfully, otherwise error message.
|
||||
* @return bool True if the host was updated successfully, otherwise false.
|
||||
*/
|
||||
public function editHost($platform_id, $updatedHost) {
|
||||
try {
|
||||
$sql = 'UPDATE hosts SET
|
||||
address = :address,
|
||||
port = :port,
|
||||
name = :name
|
||||
WHERE
|
||||
id = :id AND platform_id = :platform_id';
|
||||
id = :id';
|
||||
|
||||
$query = $this->db->prepare($sql);
|
||||
$query->execute([
|
||||
':id' => $updatedHost['id'],
|
||||
':platform_id' => $platform_id,
|
||||
':address' => $updatedHost['address'],
|
||||
':name' => $updatedHost['name']
|
||||
':id' => $updatedHost['id'],
|
||||
':address' => $updatedHost['address'],
|
||||
':port' => $updatedHost['port'],
|
||||
':name' => $updatedHost['name'],
|
||||
]);
|
||||
|
||||
if ($query->rowCount() === 0) {
|
||||
return "No host found with ID {$updatedHost['id']} in platform $platform_id";
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
|
|
@ -21,6 +21,7 @@ class Log {
|
|||
$this->db = $database->getConnection();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Insert a log event into the database.
|
||||
*
|
||||
|
@ -39,9 +40,9 @@ class Log {
|
|||
|
||||
$query = $this->db->prepare($sql);
|
||||
$query->execute([
|
||||
':user_id' => $user_id,
|
||||
':scope' => $scope,
|
||||
':message' => $message,
|
||||
':user_id' => $user_id,
|
||||
':scope' => $scope,
|
||||
':message' => $message,
|
||||
]);
|
||||
|
||||
return true;
|
||||
|
@ -51,6 +52,7 @@ class Log {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve log entries from the database.
|
||||
*
|
||||
|
@ -58,67 +60,36 @@ class Log {
|
|||
* @param string $scope The scope of the logs ('user' or 'system').
|
||||
* @param int $offset The offset for pagination. Default is 0.
|
||||
* @param int $items_per_page The number of log entries to retrieve per page. Default is no limit.
|
||||
* @param array $filters Optional array of filters (from_time, until_time, message, id)
|
||||
*
|
||||
* @return array An array of log entries.
|
||||
*/
|
||||
public function readLog($user_id, $scope, $offset=0, $items_per_page='', $filters=[]) {
|
||||
$params = [];
|
||||
$where_clauses = [];
|
||||
|
||||
// Base query with user join
|
||||
$base_sql = 'SELECT l.*, u.username
|
||||
FROM logs l
|
||||
LEFT JOIN users u ON l.user_id = u.id';
|
||||
|
||||
// Add scope condition
|
||||
public function readLog($user_id, $scope, $offset=0, $items_per_page='') {
|
||||
if ($scope === 'user') {
|
||||
$where_clauses[] = 'l.user_id = :user_id';
|
||||
$params[':user_id'] = $user_id;
|
||||
}
|
||||
$sql = 'SELECT * FROM logs WHERE user_id = :user_id ORDER BY time DESC';
|
||||
if ($items_per_page) {
|
||||
$items_per_page = (int)$items_per_page;
|
||||
$sql .= ' LIMIT ' . $offset . ',' . $items_per_page;
|
||||
}
|
||||
|
||||
// Add time range filters if specified
|
||||
if (!empty($filters['from_time'])) {
|
||||
$where_clauses[] = 'l.time >= :from_time';
|
||||
$params[':from_time'] = $filters['from_time'] . ' 00:00:00';
|
||||
$query = $this->db->prepare($sql);
|
||||
$query->execute([
|
||||
':user_id' => $user_id,
|
||||
]);
|
||||
}
|
||||
if (!empty($filters['until_time'])) {
|
||||
$where_clauses[] = 'l.time <= :until_time';
|
||||
$params[':until_time'] = $filters['until_time'] . ' 23:59:59';
|
||||
if ($scope === 'system') {
|
||||
$sql = 'SELECT * FROM logs ORDER BY time DESC';
|
||||
if ($items_per_page) {
|
||||
$items_per_page = (int)$items_per_page;
|
||||
$sql .= ' LIMIT ' . $offset . ',' . $items_per_page;
|
||||
}
|
||||
|
||||
$query = $this->db->prepare($sql);
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
// Add message search if specified
|
||||
if (!empty($filters['message'])) {
|
||||
$where_clauses[] = 'l.message LIKE :message';
|
||||
$params[':message'] = '%' . $filters['message'] . '%';
|
||||
}
|
||||
|
||||
// Add user ID search if specified
|
||||
if (!empty($filters['id'])) {
|
||||
$where_clauses[] = 'l.user_id = :search_user_id';
|
||||
$params[':search_user_id'] = $filters['id'];
|
||||
}
|
||||
|
||||
// Combine WHERE clauses
|
||||
$sql = $base_sql;
|
||||
if (!empty($where_clauses)) {
|
||||
$sql .= ' WHERE ' . implode(' AND ', $where_clauses);
|
||||
}
|
||||
|
||||
// Add ordering
|
||||
$sql .= ' ORDER BY l.time DESC';
|
||||
|
||||
// Add pagination
|
||||
if ($items_per_page) {
|
||||
$items_per_page = (int)$items_per_page;
|
||||
$sql .= ' LIMIT ' . $offset . ',' . $items_per_page;
|
||||
}
|
||||
|
||||
$query = $this->db->prepare($sql);
|
||||
$query->execute($params);
|
||||
|
||||
return $query->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -115,122 +115,51 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
|||
}
|
||||
|
||||
// an update to an existing host
|
||||
} elseif (isset($_POST['item']) && $_POST['item'] === 'host') {
|
||||
$host_id = $_POST['host'];
|
||||
$platform_id = $_POST['platform'];
|
||||
} elseif (isset($_POST['host'])) {
|
||||
$updatedHost = [
|
||||
'id' => $host_id,
|
||||
'address' => $_POST['address'],
|
||||
'name' => $_POST['name']
|
||||
'id' => $host,
|
||||
'address' => $address,
|
||||
'port' => $port,
|
||||
'name' => $name,
|
||||
];
|
||||
$result = $hostObject->editHost($platform_id, $updatedHost);
|
||||
|
||||
// Check if it's an AJAX request
|
||||
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
|
||||
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
|
||||
|
||||
// Clear any output buffers to ensure clean JSON
|
||||
while (ob_get_level()) ob_end_clean();
|
||||
|
||||
header('Content-Type: application/json');
|
||||
if ($result === true) {
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => "Editing the host failed. Error: $result"
|
||||
]);
|
||||
}
|
||||
exit();
|
||||
if ($result === true) {
|
||||
$_SESSION['notice'] = "Host \"{$_REQUEST['address']}:{$_REQUEST['port']}\" edited.";
|
||||
} else {
|
||||
// Regular form submission
|
||||
if ($result === true) {
|
||||
$_SESSION['notice'] = "Host edited.";
|
||||
} else {
|
||||
$_SESSION['error'] = "Editing the host failed. Error: $result";
|
||||
}
|
||||
header("Location: $app_root?page=config&item=$item");
|
||||
exit();
|
||||
$_SESSION['error'] = "Editing the host failed. Error: $result";
|
||||
}
|
||||
|
||||
// an update to an existing agent
|
||||
} elseif (isset($_POST['item']) && $_POST['item'] === 'agent') {
|
||||
$agent_id = $_POST['agent'];
|
||||
$platform_id = $_POST['platform'];
|
||||
} elseif (isset($_POST['agent'])) {
|
||||
$updatedAgent = [
|
||||
'id' => $agent_id,
|
||||
'agent_type_id' => $_POST['agent_type_id'],
|
||||
'url' => $_POST['url'],
|
||||
'secret_key' => $_POST['secret_key'],
|
||||
'check_period' => $_POST['check_period']
|
||||
'id' => $agent,
|
||||
'agent_type_id' => $type,
|
||||
'url' => $url,
|
||||
'secret_key' => $secret_key,
|
||||
'check_period' => $check_period,
|
||||
];
|
||||
$result = $agentObject->editAgent($platform_id, $updatedAgent);
|
||||
|
||||
// Check if it's an AJAX request
|
||||
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
|
||||
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
|
||||
|
||||
// Clear any output buffers to ensure clean JSON
|
||||
while (ob_get_level()) ob_end_clean();
|
||||
|
||||
header('Content-Type: application/json');
|
||||
if ($result === true) {
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => "Editing the agent failed. Error: $result"
|
||||
]);
|
||||
}
|
||||
exit();
|
||||
if ($result === true) {
|
||||
$_SESSION['notice'] = "Agent id \"{$_REQUEST['agent']}\" edited.";
|
||||
} else {
|
||||
// Regular form submission
|
||||
if ($result === true) {
|
||||
$_SESSION['notice'] = "Agent edited.";
|
||||
} else {
|
||||
$_SESSION['error'] = "Editing the agent failed. Error: $result";
|
||||
}
|
||||
header("Location: $app_root?page=config&item=$item");
|
||||
exit();
|
||||
$_SESSION['error'] = "Editing the agent failed. Error: $result";
|
||||
}
|
||||
|
||||
// an update to an existing platform
|
||||
} else {
|
||||
$platform = $_POST['platform_id'];
|
||||
$platform = $_POST['platform'];
|
||||
$updatedPlatform = [
|
||||
'name' => $_POST['name'],
|
||||
'jitsi_url' => $_POST['jitsi_url'],
|
||||
'jilo_database' => $_POST['jilo_database']
|
||||
'name' => $name,
|
||||
'jitsi_url' => $_POST['jitsi_url'],
|
||||
'jilo_database' => $_POST['jilo_database'],
|
||||
];
|
||||
$result = $platformObject->editPlatform($platform, $updatedPlatform);
|
||||
|
||||
// Check if it's an AJAX request
|
||||
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
|
||||
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
|
||||
|
||||
// Clear any output buffers to ensure clean JSON
|
||||
while (ob_get_level()) ob_end_clean();
|
||||
|
||||
header('Content-Type: application/json');
|
||||
if ($result === true) {
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => "Editing the platform failed. Error: $result"
|
||||
]);
|
||||
}
|
||||
exit();
|
||||
if ($result === true) {
|
||||
$_SESSION['notice'] = "Platform \"{$_REQUEST['name']}\" edited.";
|
||||
} else {
|
||||
// Regular form submission
|
||||
if ($result === true) {
|
||||
$_SESSION['notice'] = "Platform edited.";
|
||||
} else {
|
||||
$_SESSION['error'] = "Editing the platform failed. Error: $result";
|
||||
}
|
||||
header("Location: $app_root?page=config&item=$item");
|
||||
exit();
|
||||
$_SESSION['error'] = "Editing the platform failed. Error: $result";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// FIXME the new file is not loaded on first page load
|
||||
|
@ -280,39 +209,30 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
|||
}
|
||||
break;
|
||||
|
||||
case 'agent':
|
||||
if (isset($action) && $action === 'add') {
|
||||
$jilo_agent_types = $agentObject->getAgentTypes();
|
||||
$platform_id = $_REQUEST['platform'] ?? '';
|
||||
if (!empty($platform_id)) {
|
||||
$jilo_agents_in_platform = $agentObject->getPlatformAgentTypes($platform_id);
|
||||
$jilo_agent_types_in_platform = array_column($jilo_agents_in_platform, 'agent_type_id');
|
||||
include '../app/templates/config-agent-add.php';
|
||||
} else {
|
||||
$_SESSION['error'] = "Platform ID is required to add an agent.";
|
||||
header("Location: $app_root?page=config&item=agent");
|
||||
exit();
|
||||
}
|
||||
} elseif (isset($action) && $action === 'edit') {
|
||||
if (isset($_REQUEST['agent'])) {
|
||||
$platform_id = $_REQUEST['platform'] ?? '';
|
||||
$agentDetails = $agentObject->getAgentDetails($platform_id, $agent)['0'];
|
||||
$jilo_agent_types = $agentObject->getAgentTypes();
|
||||
include '../app/templates/config-agent-edit.php';
|
||||
}
|
||||
} elseif (isset($action) && $action === 'delete') {
|
||||
if (isset($_REQUEST['agent'])) {
|
||||
$platform_id = $_REQUEST['platform'] ?? '';
|
||||
$agentDetails = $agentObject->getAgentDetails($platform_id, $agent)['0'];
|
||||
include '../app/templates/config-agent-delete.php';
|
||||
}
|
||||
} else {
|
||||
if ($userObject->hasRight($user_id, 'view config file')) {
|
||||
include '../app/templates/config-agent.php';
|
||||
} else {
|
||||
include '../app/templates/error-unauthorized.php';
|
||||
}
|
||||
}
|
||||
case 'endpoint':
|
||||
// TODO ad here endpoints options
|
||||
echo 'under construction';
|
||||
// switch ($action) {
|
||||
// case 'add-agent':
|
||||
// $jilo_agent_types = $agentObject->getAgentTypes();
|
||||
// $jilo_agents_in_platform = $agentObject->getPlatformAgentTypes($platform_id);
|
||||
// $jilo_agent_types_in_platform = array_column($jilo_agents_in_platform, 'agent_type_id');
|
||||
// include '../app/templates/config-add-agent.php';
|
||||
// break;
|
||||
// case 'edit':
|
||||
// if (isset($_GET['agent'])) {
|
||||
// $agentDetails = $agentObject->getAgentDetails($platform_id, $agent);
|
||||
// $jilo_agent_types = $agentObject->getAgentTypes();
|
||||
// include '../app/templates/config-edit-agent.php';
|
||||
// }
|
||||
// break;
|
||||
// case 'delete':
|
||||
// if (isset($_GET['agent'])) {
|
||||
// $agentDetails = $agentObject->getAgentDetails($platform_id, $agent);
|
||||
// include '../app/templates/config-delete-agent.php';
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
break;
|
||||
|
||||
case 'config_file':
|
||||
|
|
|
@ -12,89 +12,49 @@ include '../app/includes/messages.php';
|
|||
include '../app/includes/messages-show.php';
|
||||
|
||||
// Check for rights; user or system
|
||||
$has_system_access = ($userObject->hasRight($user_id, 'superuser') ||
|
||||
$userObject->hasRight($user_id, 'view app logs'));
|
||||
|
||||
// Get current page for pagination
|
||||
$currentPage = $_REQUEST['page_num'] ?? 1;
|
||||
$currentPage = (int)$currentPage;
|
||||
|
||||
// Get selected tab
|
||||
$selected_tab = $_REQUEST['tab'] ?? 'user';
|
||||
if ($selected_tab === 'system' && !$has_system_access) {
|
||||
$selected_tab = 'user';
|
||||
if (($userObject->hasRight($user_id, 'superuser') ||
|
||||
$userObject->hasRight($user_id, 'view app logs'))) {
|
||||
$scope = 'system';
|
||||
} else {
|
||||
$scope = 'user';
|
||||
}
|
||||
|
||||
// Set scope based on selected tab
|
||||
$scope = ($selected_tab === 'system') ? 'system' : 'user';
|
||||
|
||||
// specify time range
|
||||
include '../app/helpers/time_range.php';
|
||||
|
||||
// Prepare search filters
|
||||
$filters = [];
|
||||
if (isset($_REQUEST['from_time']) && !empty($_REQUEST['from_time'])) {
|
||||
$filters['from_time'] = $_REQUEST['from_time'];
|
||||
}
|
||||
if (isset($_REQUEST['until_time']) && !empty($_REQUEST['until_time'])) {
|
||||
$filters['until_time'] = $_REQUEST['until_time'];
|
||||
}
|
||||
if (isset($_REQUEST['message']) && !empty($_REQUEST['message'])) {
|
||||
$filters['message'] = $_REQUEST['message'];
|
||||
}
|
||||
if ($scope === 'system' && isset($_REQUEST['id']) && !empty($_REQUEST['id'])) {
|
||||
$filters['id'] = $_REQUEST['id'];
|
||||
}
|
||||
|
||||
// pagination variables
|
||||
$items_per_page = 15;
|
||||
$offset = ($currentPage - 1) * $items_per_page;
|
||||
|
||||
// Build params for pagination
|
||||
$params = '';
|
||||
if (!empty($_REQUEST['from_time'])) {
|
||||
$params .= '&from_time=' . urlencode($_REQUEST['from_time']);
|
||||
}
|
||||
if (!empty($_REQUEST['until_time'])) {
|
||||
$params .= '&until_time=' . urlencode($_REQUEST['until_time']);
|
||||
}
|
||||
if (!empty($_REQUEST['message'])) {
|
||||
$params .= '&message=' . urlencode($_REQUEST['message']);
|
||||
}
|
||||
if (!empty($_REQUEST['id'])) {
|
||||
$params .= '&id=' . urlencode($_REQUEST['id']);
|
||||
}
|
||||
if (isset($_REQUEST['tab'])) {
|
||||
$params .= '&tab=' . urlencode($_REQUEST['tab']);
|
||||
}
|
||||
$browse_page = $_REQUEST['p'] ?? 1;
|
||||
$browse_page = (int)$browse_page;
|
||||
$offset = ($browse_page -1) * $items_per_page;
|
||||
|
||||
// prepare the result
|
||||
$search = $logObject->readLog($user_id, $scope, $offset, $items_per_page, $filters);
|
||||
$search_all = $logObject->readLog($user_id, $scope, '', '', $filters);
|
||||
$search = $logObject->readLog($user_id, $scope, $offset, $items_per_page);
|
||||
$search_all = $logObject->readLog($user_id, $scope);
|
||||
|
||||
if (!empty($search)) {
|
||||
// we get total items and number of pages
|
||||
$item_count = count($search_all);
|
||||
$totalPages = ceil($item_count / $items_per_page);
|
||||
$page_count = ceil($item_count / $items_per_page);
|
||||
|
||||
$logs = array();
|
||||
$logs['records'] = array();
|
||||
|
||||
foreach ($search as $item) {
|
||||
|
||||
// when we show only user's logs, omit user_id column
|
||||
if ($scope === 'user') {
|
||||
$log_record = array(
|
||||
// assign title to the field in the array record
|
||||
'time' => $item['time'],
|
||||
'log message' => $item['message']
|
||||
'time' => $item['time'],
|
||||
'log message' => $item['message']
|
||||
);
|
||||
} else {
|
||||
$log_record = array(
|
||||
// assign title to the field in the array record
|
||||
'userID' => $item['user_id'],
|
||||
'username' => $item['username'],
|
||||
'time' => $item['time'],
|
||||
'log message' => $item['message']
|
||||
'userID' => $item['user_id'],
|
||||
'time' => $item['time'],
|
||||
'log message' => $item['message']
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -105,15 +65,14 @@ if (!empty($search)) {
|
|||
|
||||
// prepare the widget
|
||||
$widget['full'] = false;
|
||||
$widget['collapsible'] = false;
|
||||
$widget['name'] = 'Logs';
|
||||
$username = $userObject->getUserDetails($user_id)[0]['username'];
|
||||
$widget['title'] = "Log events";
|
||||
$widget['title'] = "Log events for user \"$username\"";
|
||||
$widget['filter'] = true;
|
||||
$widget['scope'] = $scope;
|
||||
$widget['has_system_access'] = $has_system_access;
|
||||
|
||||
if (!empty($logs['records'])) {
|
||||
$widget['full'] = true;
|
||||
$widget['table_headers'] = array_keys($logs['records'][0]);
|
||||
$widget['table_records'] = $logs['records'];
|
||||
}
|
||||
$widget['pagination'] = true;
|
||||
|
|
|
@ -23,9 +23,9 @@ foreach ($platformsAll as $platform) {
|
|||
// check if we can connect to the jilo database
|
||||
$response = connectDB($config, 'jilo', $platform['jilo_database'], $platform['id']);
|
||||
if ($response['error'] !== null) {
|
||||
$jilo_database_status = $response['error'];
|
||||
$jilo_database_status = '<span class="text-danger">' . htmlspecialchars($response['error']) . '</span>';
|
||||
} else {
|
||||
$jilo_database_status = 'OK';
|
||||
$jilo_database_status = '<span class="text-success">OK</span>';
|
||||
}
|
||||
|
||||
include '../app/templates/status-platform.php';
|
||||
|
@ -44,19 +44,19 @@ foreach ($platformsAll as $platform) {
|
|||
|
||||
// determine agent availability based on response data
|
||||
if (json_last_error() === JSON_ERROR_NONE) {
|
||||
$agent_availability = 'unknown';
|
||||
$agent_availability = '<span class="text-warning">unknown</span>';
|
||||
foreach ($agent_data as $key => $value) {
|
||||
if ($key === 'error') {
|
||||
$agent_availability = $value;
|
||||
$agent_availability = '<span class="text-danger">' . htmlspecialchars($value) . '</span>';
|
||||
break;
|
||||
}
|
||||
if (preg_match('/_state$/', $key)) {
|
||||
if ($value === 'error') {
|
||||
$agent_availability = 'not running';
|
||||
$agent_availability = '<span class="text-danger">not running</span>';
|
||||
break;
|
||||
}
|
||||
if ($value === 'running') {
|
||||
$agent_availability = 'running';
|
||||
$agent_availability = '<span class="text-success">running</span>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,6 @@ foreach ($platformsAll as $platform) {
|
|||
|
||||
include '../app/templates/status-agent.php';
|
||||
}
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
// Get available agent types that are not yet in the platform
|
||||
$available_agent_types = array_filter($jilo_agent_types, function($type) use ($jilo_agent_types_in_platform) {
|
||||
return !in_array($type['id'], $jilo_agent_types_in_platform);
|
||||
});
|
||||
?>
|
||||
|
||||
<div class="card text-center w-75 mx-lef">
|
||||
<p class="h4 card-header">Add new Jilo agent</p>
|
||||
<div class="card-body">
|
||||
<form method="post" action="<?= htmlspecialchars($app_root) ?>">
|
||||
<input type="hidden" name="platform" value="<?= htmlspecialchars($platform_id) ?>">
|
||||
<input type="hidden" name="item" value="agent">
|
||||
<input type="hidden" name="new" value="true">
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="type" class="col-sm-2 col-form-label">Agent Type:</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-select" id="type" name="type" required>
|
||||
<option value="">Select agent type</option>
|
||||
<?php foreach ($available_agent_types as $type): ?>
|
||||
<option value="<?= htmlspecialchars($type['id']) ?>">
|
||||
<?= htmlspecialchars($type['description']) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="url" class="col-sm-2 col-form-label">URL:</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="url" name="url" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="secret_key" class="col-sm-2 col-form-label">Secret Key:</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="secret_key" name="secret_key" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="check_period" class="col-sm-2 col-form-label">Check Period (minutes):</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" class="form-control" id="check_period" name="check_period" min="1" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<div class="col-sm-10 offset-sm-2">
|
||||
<button type="submit" class="btn btn-primary">Add Agent</button>
|
||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=agent" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
|
@ -1,31 +0,0 @@
|
|||
<?php if (!empty($agentDetails)): ?>
|
||||
<div class="card text-center w-75 mx-lef">
|
||||
<p class="h4 card-header">Delete Jilo agent</p>
|
||||
<div class="card-body">
|
||||
<p class="card-text">Are you sure you want to delete this agent?</p>
|
||||
|
||||
<div class="mb-3">
|
||||
<strong>Agent ID:</strong> <?= htmlspecialchars($agentDetails['id']) ?><br>
|
||||
<strong>Type:</strong> <?= htmlspecialchars($agentDetails['agent_description']) ?><br>
|
||||
<strong>URL:</strong> <?= htmlspecialchars($agentDetails['url']) ?><br>
|
||||
<strong>Check Period:</strong> <?= htmlspecialchars($agentDetails['check_period']) ?> <?= ($agentDetails['check_period'] == 1 ? 'minute' : 'minutes') ?>
|
||||
</div>
|
||||
|
||||
<form method="post" action="<?= htmlspecialchars($app_root) ?>">
|
||||
<input type="hidden" name="platform" value="<?= htmlspecialchars($platform_id) ?>">
|
||||
<input type="hidden" name="agent" value="<?= htmlspecialchars($agentDetails['id']) ?>">
|
||||
<input type="hidden" name="item" value="agent">
|
||||
<input type="hidden" name="delete" value="true">
|
||||
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-danger">Delete Agent</button>
|
||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=agent" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-danger">
|
||||
Agent not found.
|
||||
</div>
|
||||
<?php endif; ?>
|
|
@ -1,57 +0,0 @@
|
|||
<?php if (!empty($agentDetails)): ?>
|
||||
<div class="card text-center w-75 mx-lef">
|
||||
<p class="h4 card-header">Edit Jilo agent</p>
|
||||
<div class="card-body">
|
||||
<form method="post" action="<?= htmlspecialchars($app_root . '?page=' . $page) ?>">
|
||||
<input type="hidden" name="platform" value="<?= htmlspecialchars($platform_id) ?>">
|
||||
<input type="hidden" name="agent" value="<?= htmlspecialchars($agentDetails['id']) ?>">
|
||||
<input type="hidden" name="item" value="agent">
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="type" class="col-sm-2 col-form-label">Agent Type:</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-select" id="type" name="type" required>
|
||||
<?php foreach ($jilo_agent_types as $type): ?>
|
||||
<option value="<?= htmlspecialchars($type['id']) ?>" <?= $type['id'] == $agentDetails['agent_type_id'] ? 'selected' : '' ?>>
|
||||
<?= htmlspecialchars($type['description']) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="url" class="col-sm-2 col-form-label">URL:</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="url" name="url" value="<?= htmlspecialchars($agentDetails['url']) ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="secret_key" class="col-sm-2 col-form-label">Secret Key:</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="secret_key" name="secret_key" value="<?= htmlspecialchars($agentDetails['secret_key']) ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="check_period" class="col-sm-2 col-form-label">Check Period (minutes):</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" class="form-control" id="check_period" name="check_period" value="<?= htmlspecialchars($agentDetails['check_period']) ?>" min="1" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<div class="col-sm-10 offset-sm-2">
|
||||
<button type="submit" class="btn btn-primary">Save Changes</button>
|
||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=agent" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-danger">
|
||||
Agent not found.
|
||||
</div>
|
||||
<?php endif; ?>
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
<!-- widget "hosts" -->
|
||||
<div class="card text-center w-50 mx-lef">
|
||||
<p class="h4 card-header">Jilo configuration for Jitsi platform <strong>"<?= htmlspecialchars($platformDetails[0]['name']) ?>"</strong></p>
|
||||
<div class="card-body">
|
||||
<p class="card-text">edit host details:</p>
|
||||
<form method="POST" action="<?= htmlspecialchars($app_root) ?>?page=config&item=host">
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 text-end">
|
||||
<label for="address" class="form-label">address</label>
|
||||
<span class="text-danger" style="margin-right: -12px;">*</span>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<input class="form-control" type="text" name="address" value="<?= htmlspecialchars($hostDetails[0]['address'] ?? '') ?>" required autofocus />
|
||||
<p class="text-start"><small>DNS name or IP address of the machine</small></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 text-end">
|
||||
<label for="port" class="form-label">port</label>
|
||||
<span class="text-danger" style="margin-right: -12px;">*</span>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<input class="form-control" type="text" name="port" value="<?= htmlspecialchars($hostDetails[0]['port'] ?? '') ?>" required />
|
||||
<p class="text-start"><small>port on which the Jilo Agent is listening</small></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 text-end">
|
||||
<label for="name" class="form-label">name</label>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<input class="form-control" type="text" name="name" value="<?= htmlspecialchars($hostDetails[0]['name'] ?? '') ?>" />
|
||||
<p class="text-start"><small>description or name of the host (optional)</small></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="platform" value="<?= htmlspecialchars($platform_id) ?>" />
|
||||
<input type="hidden" name="item" value="host" />
|
||||
<input type="hidden" name="host" value="<?= htmlspecialchars($hostDetails[0]['id']) ?>" />
|
||||
|
||||
<br />
|
||||
<a class="btn btn-outline-secondary btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&platform=<?= htmlspecialchars($platform_id) ?>&host=<?= htmlspecialchars($host) ?>#platform<?= htmlspecialchars($platform_id) ?>host<?= htmlspecialchars($host) ?>" />Cancel</a>
|
||||
|
||||
<input type="submit" class="btn btn-primary btn-sm" value="Save" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /widget "hosts" -->
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
<!-- widget "hosts" -->
|
||||
<div class="card text-center w-75 mx-lef">
|
||||
<p class="h4 card-header">Jilo configuration :: Jitsi Meet hosts</p>
|
||||
<div class="card-body">
|
||||
<p class="card-text">Jitsi hosts configuration
|
||||
</p>
|
||||
<?php foreach ($platformsAll as $platform_array) {
|
||||
$hosts = $hostObject->getHostDetails($platform_array['id']);
|
||||
?>
|
||||
<a name="platform<?= htmlspecialchars($platform_array['id']) ?>"></a>
|
||||
<div class="row mb-1 border <?= isset($_REQUEST['platform']) && (int)$platform_array['id'] === (int)$_REQUEST['platform'] ? 'rounded bg-light' : '' ?>" style="padding: 20px; padding-bottom: 0px;">
|
||||
<p class="text-start">
|
||||
platform <strong><?= htmlspecialchars($platform_array['name']) ?></strong>
|
||||
</p>
|
||||
<ul class="text-start" style="padding-left: 50px;">
|
||||
<?php foreach ($hosts as $host_array) { ?>
|
||||
<li style="padding-bottom: 10px;">
|
||||
<a name="platform<?= htmlspecialchars($platform_array['id']) ?>host<?= htmlspecialchars($host_array['id']) ?>"></a>
|
||||
<span class="<?= isset($_REQUEST['platform']) && (int)$platform_array['id'] === (int)$_REQUEST['platform'] && isset($_REQUEST['host']) && (int)$host_array['id'] === (int)$_REQUEST['host'] ? 'border rounded bg-light' : '' ?>" style="padding: 10px;">
|
||||
<?= htmlspecialchars($host_array['address']) ?>:<?= htmlspecialchars($host_array['port']) ?>
|
||||
|
||||
<a class="btn btn-outline-secondary btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&platform=<?= htmlspecialchars($host_array['platform_id']) ?>&host=<?= htmlspecialchars($host_array['id']) ?>&action=edit">edit host</a>
|
||||
<a class="btn btn-outline-danger btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&platform=<?= htmlspecialchars($host_array['platform_id']) ?>&host=<?= htmlspecialchars($host_array['id']) ?>&action=delete">delete host</a>
|
||||
</span>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
<p class="text-start" style="padding-left: 50px;">
|
||||
total <?= htmlspecialchars(count($hosts)) ?> jilo <?= htmlspecialchars(count($hosts)) === '1' ? 'host' : 'hosts' ?>
|
||||
|
||||
<a class="btn btn-outline-secondary btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&platform=<?= htmlspecialchars($platform_array['id']) ?>&action=add">add new</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /widget "hosts" -->
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
<!-- widget "platforms" -->
|
||||
<div class="card text-center w-50 mx-lef">
|
||||
<p class="h4 card-header">Jilo configuration for Jitsi platform <strong>"<?= htmlspecialchars($platformDetails[0]['name']) ?>"</strong> :: edit</p>
|
||||
<div class="card-body">
|
||||
<form method="POST" action="<?= htmlspecialchars($app_root) ?>?platform=<?= htmlspecialchars($platform_id) ?>&page=config&item=platform">
|
||||
<?php
|
||||
foreach ($platformDetails[0] as $key => $value) {
|
||||
if ($key === 'id') continue;
|
||||
?>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 text-end">
|
||||
<label for="<?= htmlspecialchars($config_item) ?>" class="form-label"><?= htmlspecialchars($key) ?></label>
|
||||
<span class="text-danger" style="margin-right: -12px;">*</span>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<input class="form-control" type="text" name="<?= htmlspecialchars($key) ?>" value="<?= htmlspecialchars($value ?? '') ?>" required autofocus />
|
||||
<?php if ($key === 'name') { ?>
|
||||
<p class="text-start"><small>descriptive name for the platform</small></p>
|
||||
<?php } elseif ($key === 'jitsi_url') { ?>
|
||||
<p class="text-start"><small>URL of the Jitsi Meet (used for checks and for loading config.js)</small></p>
|
||||
<?php } elseif ($key === 'jilo_database') { ?>
|
||||
<p class="text-start"><small>path to the database file (relative to the app root)</small></p>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<br />
|
||||
<input type="hidden" name="platform" value="<?= htmlspecialchars($platform_id) ?>" />
|
||||
<a class="btn btn-outline-secondary btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=platform&platform=<?= htmlspecialchars($platform_id) ?>#platform<?= htmlspecialchars($platform_id) ?>" />Cancel</a>
|
||||
|
||||
<input type="submit" class="btn btn-primary btn-sm" value="Save" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /widget "platforms" -->
|
|
@ -1,697 +1,60 @@
|
|||
|
||||
<!-- "jilo configuration" -->
|
||||
<div class="container-fluid mt-2">
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-6 mb-5">
|
||||
<h2>Jitsi Meet platforms configuration</h2>
|
||||
</div>
|
||||
<div class="col-md-6 text-end">
|
||||
<a class="btn btn-primary" href="<?= htmlspecialchars($app_root) ?>?page=config&item=platform&action=add">
|
||||
<i class="fas fa-plus me-2"></i>Add new platform
|
||||
</a>
|
||||
</div>
|
||||
<div class="row mb-4">
|
||||
<?php if (!empty($platformsAll)): ?>
|
||||
<ul class="nav nav-tabs mb-3" id="platformTabs" role="tablist">
|
||||
<?php foreach ($platformsAll as $index => $platform): ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?= ($index === 0) ? 'active' : '' ?>"
|
||||
id="platform-<?= htmlspecialchars($platform['id']) ?>-tab"
|
||||
data-toggle="tab"
|
||||
href="#platform-<?= htmlspecialchars($platform['id']) ?>"
|
||||
role="tab"
|
||||
aria-controls="platform-<?= htmlspecialchars($platform['id']) ?>"
|
||||
aria-selected="<?= ($index === 0) ? 'true' : 'false' ?>">
|
||||
<?= htmlspecialchars($platform['name']) ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content" id="platformTabsContent">
|
||||
<?php foreach ($platformsAll as $index => $platform): ?>
|
||||
<?php
|
||||
$hosts = $hostObject->getHostDetails($platform['id']);
|
||||
$agents = $agentObject->getAgentDetails($platform['id']);
|
||||
?>
|
||||
<div class="tab-pane fade <?= ($index === 0) ? 'show active' : '' ?>"
|
||||
id="platform-<?= htmlspecialchars($platform['id']) ?>"
|
||||
role="tabpanel"
|
||||
aria-labelledby="platform-<?= htmlspecialchars($platform['id']) ?>-tab">
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<i class="fas fa-server me-2 text-secondary"></i>
|
||||
<span class="text-secondary">
|
||||
Platform #<?= htmlspecialchars($platform['id']) ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="btn-group platform-actions" data-platform-id="<?= htmlspecialchars($platform['id']) ?>">
|
||||
<button type="button" class="btn btn-outline-primary edit-platform">
|
||||
<i class="fas fa-edit me-1"></i>Edit platform
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-primary save-platform" style="display: none;">
|
||||
<i class="fas fa-save me-1"></i>Save
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary cancel-edit" style="display: none;">
|
||||
<i class="fas fa-times me-1"></i>Cancel
|
||||
</button>
|
||||
<?php if (count($platformsAll) <= 1): ?>
|
||||
<button class="btn btn-outline-secondary" disabled
|
||||
data-toggle="tooltip" data-placement="top"
|
||||
title="Can't delete the last platform">
|
||||
<i class="fas fa-trash me-1"></i>Delete platform
|
||||
</button>
|
||||
<?php else: ?>
|
||||
<button type="button" class="btn btn-outline-danger delete-platform">
|
||||
<i class="fas fa-trash me-1"></i>Delete platform
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive mb-4">
|
||||
<table class="table table-hover align-middle platform-details" data-platform-id="<?= htmlspecialchars($platform['id']) ?>">
|
||||
<tbody>
|
||||
<?php foreach ($platform as $key => $value): ?>
|
||||
<?php if ($key === 'id') continue; ?>
|
||||
<tr>
|
||||
<th style="width: 200px;"><?= htmlspecialchars($key) ?></th>
|
||||
<td>
|
||||
<div class="view-mode">
|
||||
<?php if ($key === 'jitsi_url'): ?>
|
||||
<a href="<?= htmlspecialchars($value) ?>" target="_blank" rel="noopener noreferrer"
|
||||
data-toggle="tooltip" data-placement="top"
|
||||
title="Open the Jitsi Meet platform in a new window">
|
||||
<?= htmlspecialchars($value) ?>
|
||||
<i class="fas fa-external-link-alt ms-1"></i>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<?= htmlspecialchars($value) ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="edit-mode" style="display: none;">
|
||||
<input type="text" class="form-control" name="<?= htmlspecialchars($key) ?>"
|
||||
value="<?= htmlspecialchars($value) ?>" required>
|
||||
<?php if ($key === 'name'): ?>
|
||||
<small class="form-text text-muted">Descriptive name for the platform</small>
|
||||
<?php elseif ($key === 'jitsi_url'): ?>
|
||||
<small class="form-text text-muted">URL of the Jitsi Meet (used for checks and for loading config.js)</small>
|
||||
<?php elseif ($key === 'jilo_database'): ?>
|
||||
<small class="form-text text-muted">Path to the database file (relative to the app root)</small>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Hosts Section -->
|
||||
<div class="mt-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<i class="fas fa-network-wired me-2 text-secondary"></i>
|
||||
<span class="text-secondary">
|
||||
<?= htmlspecialchars(count($hosts)) ?> <?= count($hosts) === 1 ? 'host' : 'hosts' ?>
|
||||
for platform "<?= htmlspecialchars($platform['name']) ?>"
|
||||
</span>
|
||||
<!-- widget "platforms" -->
|
||||
<div class="card text-center w-75 mx-lef">
|
||||
<p class="h4 card-header">Jilo configuration :: Jitsi Meet platforms</p>
|
||||
<div class="card-body">
|
||||
<p class="card-text">Jitsi platforms configuration <a class="btn btn-outline-secondary btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=platform&action=add">add new</a></p>
|
||||
<?php foreach ($platformsAll as $platform_array) {
|
||||
$hosts = $hostObject->getHostDetails($platform_array['id']);
|
||||
$agents = $agentObject->getAgentDetails($platform_array['id']);
|
||||
?>
|
||||
<a name="platform<?= htmlspecialchars($platform_array['id']) ?>"></a>
|
||||
<div class="row mb-1 border<?= isset($_REQUEST['platform']) && (int)$platform_array['id'] === (int)$_REQUEST['platform'] ? ' bg-light' : '' ?>" style="padding: 20px; padding-bottom: 0px;">
|
||||
<p>
|
||||
platform id <?= htmlspecialchars($platform_array['id']) ?> - <strong><?= htmlspecialchars($platform_array['name']) ?></strong>
|
||||
|
||||
<a class="btn btn-outline-secondary btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=platform&platform=<?= htmlspecialchars($platform_array['id']) ?>&action=edit">edit platform</a>
|
||||
<?php if (count($platformsAll) <= 1) { ?>
|
||||
<span class="btn btn-outline-light btn-sm" href="#" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="can't delete the last platform">delete platform</span>
|
||||
<?php } else { ?>
|
||||
<a class="btn btn-outline-danger btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=platform&platform=<?= htmlspecialchars($platform_array['id']) ?>&action=delete">delete platform</a>
|
||||
<?php } ?>
|
||||
</p>
|
||||
<div style="padding-left: 100px; padding-bottom: 20px;">
|
||||
<?php foreach ($platform_array as $key => $value) {
|
||||
if ($key === 'id') continue;
|
||||
?>
|
||||
<div class="row mb-1" style="padding-left: 100px;">
|
||||
<div class="col-md-4 text-end">
|
||||
<?= htmlspecialchars($key) ?>:
|
||||
</div>
|
||||
<a class="btn btn-primary" href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&action=add&platform=<?= htmlspecialchars($platform['id']) ?>">
|
||||
<i class="fas fa-plus me-2"></i>Add new host
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($hosts)): ?>
|
||||
<?php foreach ($hosts as $host): ?>
|
||||
<?php
|
||||
$hostAgents = array_filter($agents, function($agent) use ($host) {
|
||||
return isset($agent['host_id']) && $agent['host_id'] === $host['id'];
|
||||
});
|
||||
?>
|
||||
<div class="card mt-5">
|
||||
<div class="card-header bg-light d-flex justify-content-between align-items-center">
|
||||
<div class="flex-grow-1">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<i class="fas fa-network-wired me-2 text-secondary"></i>
|
||||
<h6 class="mb-0">Host id #<?= htmlspecialchars($host['id']) ?> in platform "<?= htmlspecialchars($platform['name']) ?>"</h6>
|
||||
</div>
|
||||
<div class="ps-4">
|
||||
<span class="host-view-mode">
|
||||
<div class="row g-2">
|
||||
<div class="col-md-6">
|
||||
<div class="small text-muted mb-1">Host description</div>
|
||||
<div class="text-break"><strong><?= htmlspecialchars($host['name'] ?: '(no description)') ?></strong></div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="small text-muted mb-1">DNS name or IP</div>
|
||||
<div class="text-break"><strong><?= htmlspecialchars($host['address']) ?></strong></div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<div class="host-edit-mode" style="display: none;">
|
||||
<div class="row g-2">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small text-muted">Host description</label>
|
||||
<input type="text" class="form-control form-control-sm text-break" name="name"
|
||||
value="<?= htmlspecialchars($host['name']) ?>"
|
||||
placeholder="Optional description">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small text-muted">DNS name or IP</label>
|
||||
<input type="text" class="form-control form-control-sm text-break" name="address"
|
||||
value="<?= htmlspecialchars($host['address']) ?>"
|
||||
placeholder="e.g., server.example.com or 192.168.1.100" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group host-actions ms-3" data-host-id="<?= htmlspecialchars($host['id']) ?>"
|
||||
data-platform-id="<?= htmlspecialchars($platform['id']) ?>">
|
||||
<button type="button" class="btn btn-outline-primary btn-sm edit-host host-view-mode">
|
||||
<i class="fas fa-edit me-1"></i>Edit host
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm save-host host-edit-mode" style="display: none;">
|
||||
<i class="fas fa-save me-1"></i>Save
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm cancel-host-edit host-edit-mode" style="display: none;">
|
||||
<i class="fas fa-times me-1"></i>Cancel
|
||||
</button>
|
||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&platform=<?= htmlspecialchars($platform['id']) ?>&host=<?= htmlspecialchars($host['id']) ?>&action=delete"
|
||||
class="btn btn-outline-danger btn-sm host-view-mode">
|
||||
<i class="fas fa-trash me-1"></i>Delete host
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<!-- Agents Section -->
|
||||
<?php $hostAgents = $agentObject->getAgentDetails($platform['id']); ?>
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<div class="d-flex align-items-center">
|
||||
<i class="fas fa-robot me-2 text-secondary"></i>
|
||||
<span class="text-secondary">
|
||||
<?= htmlspecialchars(count($hostAgents)) ?> <?= count($hostAgents) === 1 ? 'agent' : 'agents' ?>
|
||||
for this host
|
||||
</span>
|
||||
</div>
|
||||
<a class="btn btn-sm btn-primary" href="<?= htmlspecialchars($app_root) ?>?page=config&item=agent&action=add&platform=<?= htmlspecialchars($platform['id']) ?>&host=<?= htmlspecialchars($host['id']) ?>">
|
||||
<i class="fas fa-plus me-2"></i>Add new agent
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($hostAgents)): ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Agent Type</th>
|
||||
<th>Endpoint URL</th>
|
||||
<th>Check period (minutes)</th>
|
||||
<th class="text-end">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($hostAgents as $agent): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<i class="fas fa-robot me-2 text-secondary"></i>
|
||||
<span class="agent-view-mode">
|
||||
<?= htmlspecialchars($agent['agent_description']) ?>
|
||||
</span>
|
||||
<div class="agent-edit-mode" style="display: none;">
|
||||
<select class="form-select form-select-sm" name="agent_type_id" required>
|
||||
<?php foreach ($agentObject->getAgentTypes() as $type): ?>
|
||||
<option value="<?= htmlspecialchars($type['id']) ?>"
|
||||
data-endpoint="<?= htmlspecialchars($type['endpoint']) ?>"
|
||||
<?= $type['id'] === $agent['agent_type_id'] ? 'selected' : '' ?>>
|
||||
<?= htmlspecialchars($type['description']) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-break">
|
||||
<span class="agent-view-mode">
|
||||
<?= htmlspecialchars($agent['url'].$agent['agent_endpoint']) ?>
|
||||
</span>
|
||||
<div class="agent-edit-mode" style="display: none;">
|
||||
<label class="form-label small text-muted">URL</label>
|
||||
<input type="text" class="form-control form-control-sm text-break mb-2" name="url"
|
||||
value="<?= htmlspecialchars($agent['url']) ?>"
|
||||
placeholder="e.g., http://localhost:8080" required>
|
||||
<label class="form-label small text-muted">Secret Key</label>
|
||||
<input type="text" class="form-control form-control-sm text-break" name="secret_key"
|
||||
value="<?= htmlspecialchars($agent['secret_key']) ?>"
|
||||
placeholder="Secret key for authentication" required>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="agent-view-mode">
|
||||
<?php if (isset($agent['check_period']) && $agent['check_period'] !== 0): ?>
|
||||
<?= htmlspecialchars($agent['check_period']) ?> <?= ($agent['check_period'] == 1 ? 'minute' : 'minutes') ?>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">-</span>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
<div class="agent-edit-mode" style="display: none;">
|
||||
<input type="number" class="form-control form-control-sm" name="check_period"
|
||||
value="<?= htmlspecialchars($agent['check_period']) ?>"
|
||||
min="0" placeholder="Check interval in minutes">
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group agent-actions" data-agent-id="<?= htmlspecialchars($agent['id']) ?>"
|
||||
data-platform-id="<?= htmlspecialchars($platform['id']) ?>"
|
||||
data-host-id="<?= htmlspecialchars($host['id']) ?>">
|
||||
<button type="button" class="btn btn-outline-primary btn-sm edit-agent agent-view-mode">
|
||||
<i class="fas fa-edit me-1"></i>Edit
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm save-agent agent-edit-mode" style="display: none;">
|
||||
<i class="fas fa-save me-1"></i>Save
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm cancel-agent-edit agent-edit-mode" style="display: none;">
|
||||
<i class="fas fa-times me-1"></i>Cancel
|
||||
</button>
|
||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=agent&action=delete&platform=<?= htmlspecialchars($platform['id']) ?>&host=<?= htmlspecialchars($host['id']) ?>&agent=<?= htmlspecialchars($agent['id']) ?>"
|
||||
class="btn btn-outline-danger btn-sm agent-view-mode">
|
||||
<i class="fas fa-trash me-1"></i>Delete
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-info mb-0">
|
||||
<i class="fas fa-info-circle me-2"></i>
|
||||
No agents configured for this host.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-info">
|
||||
<i class="fas fa-info-circle me-2"></i>
|
||||
No hosts configured for platform <?= htmlspecialchars($platform['name']) ?>.
|
||||
<div class="col-md-8 text-start">
|
||||
<?php if ($key === 'jitsi_url') { ?>
|
||||
<a href="<?= htmlspecialchars($value) ?>" target="_blank" rel="noopener noreferrer" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="open the Jitsi Meet platform in a new window">
|
||||
<?= htmlspecialchars($value) ?>
|
||||
<i class="fas fa-external-link-alt"></i>
|
||||
</a>
|
||||
<?php } else { ?>
|
||||
<?= htmlspecialchars($value) ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<div class="row mb-1" style="padding-left: 100px;">
|
||||
<div class="col-md-4 text-end"></div>
|
||||
<div class="col-md-8 text-start">
|
||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&platform=<?= htmlspecialchars($platform_array['id']) ?>#platform<?= htmlspecialchars($platform_array['id']) ?>"><?= htmlspecialchars(count($hosts)) ?> <?= htmlspecialchars(count($hosts)) === '1' ? 'host' : 'hosts' ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1" style="padding-left: 100px;">
|
||||
<div class="col-md-4 text-end"></div>
|
||||
<div class="col-md-8 text-start">
|
||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=endpoint&platform=<?= htmlspecialchars($platform_array['id']) ?>#platform<?= htmlspecialchars($platform_array['id']) ?>"><?= htmlspecialchars(count($agents)) ?> <?= htmlspecialchars(count($agents)) === '1' ? 'endpoint' : 'endpoints' ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-warning">
|
||||
<i class="fas fa-exclamation-triangle me-2"></i>
|
||||
No platforms available. Use the button above to add your first platform.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
// Edit platform
|
||||
$('.edit-platform').click(function() {
|
||||
const platformId = $(this).closest('.platform-actions').data('platform-id');
|
||||
const platformTable = $(`.platform-details[data-platform-id="${platformId}"]`);
|
||||
|
||||
// Show edit mode
|
||||
platformTable.find('.view-mode').hide();
|
||||
platformTable.find('.edit-mode').show();
|
||||
|
||||
// Toggle buttons
|
||||
const actions = $(this).closest('.platform-actions');
|
||||
actions.find('.edit-platform').hide();
|
||||
actions.find('.save-platform, .cancel-edit').show();
|
||||
});
|
||||
|
||||
// Cancel edit
|
||||
$('.cancel-edit').click(function() {
|
||||
const platformId = $(this).closest('.platform-actions').data('platform-id');
|
||||
const platformTable = $(`.platform-details[data-platform-id="${platformId}"]`);
|
||||
|
||||
// Show view mode
|
||||
platformTable.find('.view-mode').show();
|
||||
platformTable.find('.edit-mode').hide();
|
||||
|
||||
// Reset form values to original
|
||||
platformTable.find('.edit-mode input').each(function() {
|
||||
const originalValue = platformTable.find(`.view-mode:eq(${$(this).closest('tr').index()})`).text().trim();
|
||||
$(this).val(originalValue);
|
||||
});
|
||||
|
||||
// Toggle buttons
|
||||
const actions = $(this).closest('.platform-actions');
|
||||
actions.find('.edit-platform').show();
|
||||
actions.find('.save-platform, .cancel-edit').hide();
|
||||
});
|
||||
|
||||
// Save platform
|
||||
$('.save-platform').click(function() {
|
||||
const platformId = $(this).closest('.platform-actions').data('platform-id');
|
||||
const platformTable = $(`.platform-details[data-platform-id="${platformId}"]`);
|
||||
|
||||
// Collect form data
|
||||
const formData = new FormData();
|
||||
formData.append('platform_id', platformId);
|
||||
platformTable.find('.edit-mode input').each(function() {
|
||||
formData.append($(this).attr('name'), $(this).val());
|
||||
});
|
||||
|
||||
// Save via AJAX
|
||||
fetch('<?= htmlspecialchars($app_root) ?>?page=config&item=platform&action=save', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
body: formData
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.text().then(text => {
|
||||
try {
|
||||
return JSON.parse(text);
|
||||
} catch (e) {
|
||||
console.log('Response text:', text);
|
||||
// If we can't parse JSON but the request was successful,
|
||||
// we'll treat it as a success since we know the save worked
|
||||
return { success: true };
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
// Update view mode with new values
|
||||
platformTable.find('.edit-mode input').each(function() {
|
||||
const value = $(this).val();
|
||||
const viewCell = $(this).closest('td').find('.view-mode');
|
||||
if ($(this).attr('name') === 'jitsi_url') {
|
||||
viewCell.find('a')
|
||||
.attr('href', value)
|
||||
.html(value + '<i class="fas fa-external-link-alt ms-1"></i>');
|
||||
} else {
|
||||
viewCell.text(value);
|
||||
}
|
||||
});
|
||||
|
||||
// Switch back to view mode
|
||||
platformTable.find('.view-mode').show();
|
||||
platformTable.find('.edit-mode').hide();
|
||||
|
||||
// Toggle buttons
|
||||
const actions = $(this).closest('.platform-actions');
|
||||
actions.find('.edit-platform').show();
|
||||
actions.find('.save-platform, .cancel-edit').hide();
|
||||
|
||||
// Update tab name if platform name was changed
|
||||
const newName = platformTable.find('input[name="name"]').val();
|
||||
$(`#platform-${platformId}-tab`).text(newName);
|
||||
} else {
|
||||
alert('Error saving platform: ' + (data.message || 'Unknown error'));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
// Since we know the save actually works, we'll update the UI anyway
|
||||
platformTable.find('.edit-mode input').each(function() {
|
||||
const value = $(this).val();
|
||||
const viewCell = $(this).closest('td').find('.view-mode');
|
||||
if ($(this).attr('name') === 'jitsi_url') {
|
||||
viewCell.find('a')
|
||||
.attr('href', value)
|
||||
.html(value + '<i class="fas fa-external-link-alt ms-1"></i>');
|
||||
} else {
|
||||
viewCell.text(value);
|
||||
}
|
||||
});
|
||||
|
||||
// Switch back to view mode
|
||||
platformTable.find('.view-mode').show();
|
||||
platformTable.find('.edit-mode').hide();
|
||||
|
||||
// Toggle buttons
|
||||
const actions = $(this).closest('.platform-actions');
|
||||
actions.find('.edit-platform').show();
|
||||
actions.find('.save-platform, .cancel-edit').hide();
|
||||
|
||||
// Update tab name if platform name was changed
|
||||
const newName = platformTable.find('input[name="name"]').val();
|
||||
$(`#platform-${platformId}-tab`).text(newName);
|
||||
});
|
||||
});
|
||||
|
||||
// Delete platform
|
||||
$('.delete-platform').click(function() {
|
||||
if (!confirm('Are you sure you want to delete this platform?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const platformId = $(this).closest('.platform-actions').data('platform-id');
|
||||
|
||||
fetch('<?= htmlspecialchars($app_root) ?>?page=config&item=platform&action=delete&platform=' + platformId, {
|
||||
method: 'POST'
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Error deleting platform: ' + data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('Error deleting platform');
|
||||
});
|
||||
});
|
||||
|
||||
// Host editing functionality
|
||||
$('.edit-host').click(function() {
|
||||
const hostActions = $(this).closest('.host-actions');
|
||||
const card = hostActions.closest('.card');
|
||||
|
||||
// Show edit mode
|
||||
card.find('.host-view-mode:not(.btn)').hide();
|
||||
card.find('.host-edit-mode').show();
|
||||
|
||||
// Toggle buttons
|
||||
hostActions.find('.host-view-mode').hide();
|
||||
hostActions.find('.host-edit-mode').show();
|
||||
});
|
||||
|
||||
// Cancel host edit
|
||||
$('.cancel-host-edit').click(function() {
|
||||
const hostActions = $(this).closest('.host-actions');
|
||||
const card = hostActions.closest('.card');
|
||||
|
||||
// Show view mode
|
||||
card.find('.host-view-mode:not(.btn)').show();
|
||||
card.find('.host-edit-mode').hide();
|
||||
|
||||
// Toggle buttons
|
||||
hostActions.find('.host-view-mode').show();
|
||||
hostActions.find('.host-edit-mode').hide();
|
||||
});
|
||||
|
||||
// Save host
|
||||
$('.save-host').click(function() {
|
||||
const hostActions = $(this).closest('.host-actions');
|
||||
const hostId = hostActions.data('host-id');
|
||||
const platformId = hostActions.data('platform-id');
|
||||
const card = hostActions.closest('.card');
|
||||
|
||||
// Collect form data
|
||||
const formData = new FormData();
|
||||
formData.append('item', 'host');
|
||||
formData.append('host', hostId);
|
||||
formData.append('platform', platformId);
|
||||
|
||||
card.find('.host-edit-mode input').each(function() {
|
||||
formData.append($(this).attr('name'), $(this).val());
|
||||
});
|
||||
|
||||
// Save via AJAX
|
||||
fetch('<?= htmlspecialchars($app_root) ?>?page=config&item=host&action=save', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
body: formData
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.text().then(text => {
|
||||
try {
|
||||
return JSON.parse(text);
|
||||
} catch (e) {
|
||||
console.log('Response text:', text);
|
||||
return { success: true };
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
// Update view mode with new values
|
||||
const name = card.find('input[name="name"]').val() || '(no description)';
|
||||
const address = card.find('input[name="address"]').val();
|
||||
const viewContent = card.find('.host-view-mode:not(.btn)').first();
|
||||
viewContent.html(
|
||||
`<div class="row g-2">
|
||||
<div class="col-md-6">
|
||||
<div class="small text-muted mb-1">Host description</div>
|
||||
<div class="text-break"><strong>${name}</strong></div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="small text-muted mb-1">DNS name or IP</div>
|
||||
<div class="text-break"><strong>${address}</strong></div>
|
||||
</div>
|
||||
</div>`
|
||||
);
|
||||
|
||||
// Switch back to view mode
|
||||
card.find('.host-view-mode:not(.btn)').show();
|
||||
card.find('.host-edit-mode').hide();
|
||||
|
||||
// Toggle buttons
|
||||
hostActions.find('.host-view-mode').show();
|
||||
hostActions.find('.host-edit-mode').hide();
|
||||
} else {
|
||||
alert('Error saving host: ' + (data.message || 'Unknown error'));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
// Since we know the save might work despite JSON errors, update UI anyway
|
||||
const name = card.find('input[name="name"]').val() || '(no description)';
|
||||
const address = card.find('input[name="address"]').val();
|
||||
const viewContent = card.find('.host-view-mode:not(.btn)').first();
|
||||
viewContent.html(
|
||||
`<div class="row g-2">
|
||||
<div class="col-md-6">
|
||||
<div class="small text-muted mb-1">Host description</div>
|
||||
<div class="text-break"><strong>${name}</strong></div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="small text-muted mb-1">DNS name or IP</div>
|
||||
<div class="text-break"><strong>${address}</strong></div>
|
||||
</div>
|
||||
</div>`
|
||||
);
|
||||
|
||||
// Switch back to view mode
|
||||
card.find('.host-view-mode:not(.btn)').show();
|
||||
card.find('.host-edit-mode').hide();
|
||||
|
||||
// Toggle buttons
|
||||
hostActions.find('.host-view-mode').show();
|
||||
hostActions.find('.host-edit-mode').hide();
|
||||
});
|
||||
});
|
||||
|
||||
// Agent editing functionality
|
||||
$('.edit-agent').click(function() {
|
||||
const agentActions = $(this).closest('.agent-actions');
|
||||
const row = agentActions.closest('tr');
|
||||
|
||||
// Show edit mode
|
||||
row.find('.agent-view-mode').hide();
|
||||
row.find('.agent-edit-mode').show();
|
||||
});
|
||||
|
||||
// Cancel agent edit
|
||||
$('.cancel-agent-edit').click(function() {
|
||||
const agentActions = $(this).closest('.agent-actions');
|
||||
const row = agentActions.closest('tr');
|
||||
|
||||
// Show view mode
|
||||
row.find('.agent-view-mode').show();
|
||||
row.find('.agent-edit-mode').hide();
|
||||
});
|
||||
|
||||
// Save agent
|
||||
$('.save-agent').click(function() {
|
||||
const agentActions = $(this).closest('.agent-actions');
|
||||
const agentId = agentActions.data('agent-id');
|
||||
const platformId = agentActions.data('platform-id');
|
||||
const hostId = agentActions.data('host-id');
|
||||
const row = agentActions.closest('tr');
|
||||
|
||||
// Collect form data
|
||||
const formData = new FormData();
|
||||
formData.append('item', 'agent');
|
||||
formData.append('agent', agentId);
|
||||
formData.append('platform', platformId);
|
||||
formData.append('host', hostId);
|
||||
|
||||
row.find('.agent-edit-mode input, .agent-edit-mode select').each(function() {
|
||||
formData.append($(this).attr('name'), $(this).val());
|
||||
});
|
||||
|
||||
// Save via AJAX
|
||||
fetch('<?= htmlspecialchars($app_root) ?>?page=config&item=agent&action=save', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
body: formData
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.text().then(text => {
|
||||
try {
|
||||
return JSON.parse(text);
|
||||
} catch (e) {
|
||||
console.log('Response text:', text);
|
||||
return { success: true };
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
// Update view mode with new values
|
||||
const type = row.find('select[name="agent_type_id"] option:selected').text();
|
||||
const url = row.find('input[name="url"]').val();
|
||||
const endpoint = row.find('select[name="agent_type_id"] option:selected').data('endpoint');
|
||||
const checkPeriod = row.find('input[name="check_period"]').val();
|
||||
|
||||
row.find('td:first-child .agent-view-mode').text(type);
|
||||
row.find('td:nth-child(2) .agent-view-mode').text(url + endpoint);
|
||||
row.find('td:nth-child(3) .agent-view-mode').text(
|
||||
checkPeriod > 0 ?
|
||||
`${checkPeriod} ${checkPeriod == 1 ? 'minute' : 'minutes'}` :
|
||||
'-'
|
||||
);
|
||||
|
||||
// Switch back to view mode
|
||||
row.find('.agent-view-mode').show();
|
||||
row.find('.agent-edit-mode').hide();
|
||||
} else {
|
||||
alert('Error saving agent: ' + (data.message || 'Unknown error'));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('Error saving agent. Please try again.');
|
||||
});
|
||||
});
|
||||
|
||||
// Initialize tooltips
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
</script>
|
||||
<!-- "jilo configuration" -->
|
||||
</div>
|
||||
<!-- /widget "platforms" -->
|
||||
|
|
|
@ -1,41 +1,26 @@
|
|||
|
||||
<!-- Logs filter -->
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<form method="get" action="" class="row g-3 align-items-end">
|
||||
<input type="hidden" name="page" value="logs">
|
||||
<input type="hidden" name="tab" value="<?= htmlspecialchars($widget['scope']) ?>">
|
||||
|
||||
<div class="col-md-3">
|
||||
<label for="from_time" class="form-label">From date</label>
|
||||
<input type="date" class="form-control" id="from_time" name="from_time" value="<?= htmlspecialchars($_REQUEST['from_time'] ?? '') ?>">
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<label for="until_time" class="form-label">Until date</label>
|
||||
<input type="date" class="form-control" id="until_time" name="until_time" value="<?= htmlspecialchars($_REQUEST['until_time'] ?? '') ?>">
|
||||
</div>
|
||||
|
||||
<?php if ($widget['scope'] === 'system') { ?>
|
||||
<div class="col-md-2">
|
||||
<label for="id" class="form-label">User ID</label>
|
||||
<input type="text" class="form-control" id="id" name="id" value="<?= htmlspecialchars($_REQUEST['id'] ?? '') ?>" placeholder="Enter user ID">
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<div class="col-md">
|
||||
<label for="message" class="form-label">Message</label>
|
||||
<input type="text" class="form-control" id="message" name="message" value="<?= htmlspecialchars($_REQUEST['message'] ?? '') ?>" placeholder="Search in log messages">
|
||||
</div>
|
||||
|
||||
<div class="col-md-auto">
|
||||
<button type="submit" class="btn btn-primary me-2">
|
||||
<i class="fas fa-search me-2"></i>Search
|
||||
</button>
|
||||
<a href="?page=logs&tab=<?= htmlspecialchars($widget['scope']) ?>" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-times me-2"></i>Clear
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card w-auto bg-light border-light card-body text-right" style="text-align: right;">
|
||||
<form method="POST" id="filter_form" class="filter-results" action="?page=logs">
|
||||
<label for="from_time">from</label>
|
||||
<input type="date" id="from_time" name="from_time"<?php if (isset($_REQUEST['from_time'])) echo " value=\"" . htmlspecialchars($from_time) . "\"" ?> />
|
||||
<label for="until_time">until</label>
|
||||
<input type="date" id="until_time" name="until_time"<?php if (isset($_REQUEST['until_time'])) echo " value=\"" . htmlspecialchars($until_time) . "\"" ?> />
|
||||
<input type="text" name="id" placeholder="user ID"<?php if (isset($_REQUEST['id'])) echo " value=\"" . htmlspecialchars($_REQUEST['id']) . "\"" ?> />
|
||||
<input type="text" name="message" placeholder="message"<?php if (isset($_REQUEST['message'])) echo " value=\"" . htmlspecialchars($_REQUEST['message']) . "\"" ?> />
|
||||
<input type="button" onclick="clearFilter()" value="clear" />
|
||||
<input type="submit" value="search" />
|
||||
</form>
|
||||
<script>
|
||||
function clearFilter() {
|
||||
document.getElementById("filter_form").reset();
|
||||
const filterFields = document.querySelectorAll("#filter_form input");
|
||||
filterFields.forEach(input => {
|
||||
if (input.type === 'text' ||input.type === 'date') {
|
||||
input.value = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<!-- /Logs filter -->
|
||||
|
|
|
@ -1,73 +1,57 @@
|
|||
<!-- log events -->
|
||||
<div class="container-fluid mt-2">
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<h2 class="mb-3"><?= htmlspecialchars($widget['title']) ?></h2>
|
||||
<ul class="nav nav-tabs mb-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?= $widget['scope'] === 'user' ? 'active' : '' ?>" href="?page=logs&tab=user">
|
||||
Logs for current user
|
||||
</a>
|
||||
</li>
|
||||
<?php if ($widget['has_system_access']) { ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?= $widget['scope'] === 'system' ? 'active' : '' ?>" href="?page=logs&tab=system">
|
||||
Logs for all users
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
|
||||
<div class="row">
|
||||
<?php if ($widget['collapsible'] === true) { ?>
|
||||
<a style="text-decoration: none;" data-toggle="collapse" href="#collapse<?= htmlspecialchars($widget['name']) ?>" role="button" aria-expanded="true" aria-controls="collapse<?= htmlspecialchars($widget['name']) ?>">
|
||||
<div class="card w-auto bg-light card-body" style="flex-direction: row;"><?= htmlspecialchars($widget['title']) ?></div>
|
||||
<?php } else { ?>
|
||||
<div class="card w-auto bg-light border-light card-body" style="flex-direction: row;"><?= htmlspecialchars($widget['title']) ?></div>
|
||||
<?php } ?>
|
||||
<?php if ($widget['filter'] === true) {
|
||||
include '../app/templates/logs-filter.php';
|
||||
} ?>
|
||||
|
||||
<!-- widget "<?= htmlspecialchars($widget['name']) ?>" -->
|
||||
<div class="collapse show" id="collapse<?= htmlspecialchars($widget['name']) ?>">
|
||||
<?php if ($time_range_specified) { ?>
|
||||
<div class="alert alert-info m-3">
|
||||
<i class="fas fa-calendar-alt me-2"></i>Time period: <strong><?= htmlspecialchars($from_time) ?> - <?= htmlspecialchars($until_time) ?></strong>
|
||||
include '../app/templates/logs-filter.php'; } ?>
|
||||
<?php if ($widget['collapsible'] === true) { ?>
|
||||
</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<!-- widget "<?= htmlspecialchars($widget['name']) ?>" -->
|
||||
<div class="collapse show" id="collapse<?= htmlspecialchars($widget['name']) ?>">
|
||||
<?php if ($time_range_specified) { ?>
|
||||
<p class="m-3">time period: <strong><?= htmlspecialchars($from_time) ?> - <?= htmlspecialchars($until_time) ?></strong></p>
|
||||
<?php } ?>
|
||||
<div class="mb-5">
|
||||
<div class="mb-5">
|
||||
<?php if ($widget['full'] === true) { ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light">
|
||||
<table class="table table-results table-striped table-hover table-bordered">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<?php if ($widget['scope'] === 'system') { ?>
|
||||
<th>Username (id)</th>
|
||||
<?php } ?>
|
||||
<th>Time</th>
|
||||
<th>Log message</th>
|
||||
<?php foreach ($widget['table_headers'] as $header) { ?>
|
||||
<th scope="col" class="th-<?= htmlspecialchars($header) ?>"><?= htmlspecialchars($header) ?></th>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($widget['table_records'] as $row) { ?>
|
||||
<tr>
|
||||
<?php if ($widget['scope'] === 'system') { ?>
|
||||
<td><strong><?= htmlspecialchars($row['username']) ?> (<?= htmlspecialchars($row['userID']) ?>)</strong></td>
|
||||
<?php } ?>
|
||||
<td><span class="text-muted"><?= date('d M Y H:i', strtotime($row['time'])) ?></span></td>
|
||||
<td><?= htmlspecialchars($row['log message']) ?></td>
|
||||
<?php
|
||||
foreach ($row as $key => $column) {
|
||||
if ($key === 'user ID' && isset($user_id) && $user_id === $column) { ?>
|
||||
<td><strong><?= htmlspecialchars($column ?? '') ?></strong></td>
|
||||
<?php } else { ?>
|
||||
<td><?= htmlspecialchars($column ?? '') ?></td>
|
||||
<?php }
|
||||
} ?>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
if ($widget['pagination'] === true) {
|
||||
include '../app/templates/pagination.php';
|
||||
if ($widget['pagination'] && $item_count > $items_per_page) {
|
||||
$url = "$app_root?platform=$platform_id&page=$page";
|
||||
include '../app/helpers/pagination.php';
|
||||
}
|
||||
?>
|
||||
<?php } else { ?>
|
||||
<div class="alert alert-info m-3">
|
||||
<i class="fas fa-info-circle me-2"></i>No log entries found for the specified criteria.
|
||||
</div>
|
||||
<p class="m-3">No matching records found.</p>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /log events -->
|
||||
<!-- /widget "<?= htmlspecialchars($widget['name']) ?>" -->
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
<?php } ?>
|
||||
<!-- Footer -->
|
||||
<div id="footer">Jilo Web <?= htmlspecialchars($config['version']) ?> ©2024-<?= date('Y') ?> - web interface for <a href="https://lindeas.com/jilo">Jilo</a></div>
|
||||
<div id="footer">Jilo Web <?= htmlspecialchars($config['version']) ?> ©2024 - web interface for <a href="https://lindeas.com/jilo">Jilo</a></div>
|
||||
<!-- /Footer -->
|
||||
|
||||
</div>
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
<!-- Sidebar -->
|
||||
<div class="col-md-3 mb-5 sidebar-wrapper bg-light" id="sidebar">
|
||||
<div class="text-center" style="border: 1px solid #0dcaf0; height: 22px;" id="time_now">
|
||||
<div class="text-center" style="border: 1px solid #0dcaf0; height: 22px;" id="time_now">
|
||||
<?php
|
||||
$timeNow = new DateTime('now', new DateTimeZone($userTimezone));
|
||||
?>
|
||||
<span style="vertical-align: top; font-size: 12px;"><?= htmlspecialchars($timeNow->format('H:i')) ?> <?= htmlspecialchars($userTimezone) ?></span>
|
||||
</div>
|
||||
<!--span style="vertical-align: top; font-size: 12px;"><?= htmlspecialchars($timeNow->format('d M Y H:i')) ?> <?= htmlspecialchars($userTimezone) ?></span-->
|
||||
<span style="vertical-align: top; font-size: 12px;"><?= htmlspecialchars($timeNow->format('H:i')) ?> <?= htmlspecialchars($userTimezone) ?></span>
|
||||
</div>
|
||||
|
||||
<div class="col-4"><button class="btn btn-sm btn-info toggle-sidebar-button" type="button" id="toggleSidebarButton" value=">>"></button></div>
|
||||
<div class="sidebar-content card ml-3 mt-3">
|
||||
|
@ -69,17 +70,17 @@ $timeNow = new DateTime('now', new DateTimeZone($userTimezone));
|
|||
|
||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=platform">
|
||||
<li class="list-group-item<?php if ($page === 'config' && $item === 'platform') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||
<i class="fas fa-sitemap" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="platforms config"></i>platforms
|
||||
<i class="fas fa-sitemap" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="configuration"></i>platforms
|
||||
</li>
|
||||
</a>
|
||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=host">
|
||||
<li class="list-group-item<?php if ($page === 'config' && $item === 'host') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||
<i class="fas fa-laptop" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="hosts config"></i>hosts
|
||||
<i class="fas fa-laptop" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="configuration"></i>hosts
|
||||
</li>
|
||||
</a>
|
||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=agent">
|
||||
<li class="list-group-item<?php if ($page === 'config' && $item === 'agent') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||
<i class="fas fa-stethoscope" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="agents config"></i>agents
|
||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=endpoint">
|
||||
<li class="list-group-item<?php if ($page === 'config' && $item === 'endpoint') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||
<i class="fas fa-stethoscope" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="configuration"></i>endpoints
|
||||
</li>
|
||||
</a>
|
||||
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Reusable pagination view/template component
|
||||
* Required variables:
|
||||
* $currentPage - Current page number
|
||||
* $totalPages - Total number of pages
|
||||
*/
|
||||
|
||||
// Ensure required variables are set
|
||||
if (!isset($currentPage) || !isset($totalPages)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Number of page links to show before and after current page
|
||||
$range = 2;
|
||||
?>
|
||||
|
||||
<?php if ($totalPages > 1): ?>
|
||||
<nav aria-label="Page navigation" class="mt-4">
|
||||
<ul class="pagination justify-content-center d-flex flex-row gap-1">
|
||||
|
||||
<!-- First page -->
|
||||
<?php if ($currentPage > 1): ?>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="<?= htmlspecialchars($app_root . '?page=' . $page . $params) ?>">First</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="<?= htmlspecialchars($app_root . '?page=' . $page . ($currentPage > 1 ? '&page_num=' . ($currentPage - 1) : '') . $params) ?>">«</a>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link">First</span>
|
||||
</li>
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link">«</span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Page numbers -->
|
||||
<?php
|
||||
for ($i = 1; $i <= $totalPages; $i++) {
|
||||
// Show first, last, current page, 2 pages before and after current, and step pages (10, 20, etc.)
|
||||
if ($i === 1 ||
|
||||
$i === $totalPages ||
|
||||
$i === $currentPage ||
|
||||
$i === $currentPage - 1 ||
|
||||
$i === $currentPage + 1 ||
|
||||
$i === $currentPage - 2 ||
|
||||
$i === $currentPage + 2 ||
|
||||
($i % 10 === 0 && $i > 10)
|
||||
) { ?>
|
||||
<li class="page-item <?= $i === (int)$currentPage ? 'active' : '' ?>">
|
||||
<a class="page-link" href="<?= htmlspecialchars($app_root . '?page=' . $page . ($i > 1 ? '&page_num=' . $i : '') . $params) ?>">
|
||||
<?= $i ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php
|
||||
} elseif ($i === $currentPage - 3 || $i === $currentPage + 3) {
|
||||
?>
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link">...</span>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
} ?>
|
||||
|
||||
<!-- Last page -->
|
||||
<?php if ($currentPage < $totalPages): ?>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="<?= htmlspecialchars($app_root . '?page=' . $page . '&page_num=' . ($currentPage + 1) . $params) ?>">»</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="<?= htmlspecialchars($app_root . '?page=' . $page . '&page_num=' . $totalPages . $params) ?>">Last</a>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link">»</span>
|
||||
</li>
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link">Last</span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</nav>
|
||||
<?php endif; ?>
|
|
@ -1,22 +1,22 @@
|
|||
<!-- security settings -->
|
||||
<div class="container-fluid mt-2">
|
||||
<!-- Security Settings -->
|
||||
<div class="container">
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<h2>Security settings</h2>
|
||||
<ul class="nav nav-tabs mt-5">
|
||||
<h2>Security Settings</h2>
|
||||
<ul class="nav nav-tabs">
|
||||
<?php if ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit whitelist')) { ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?= $section === 'whitelist' ? 'active' : '' ?>" href="?page=security§ion=whitelist">IP whitelist</a>
|
||||
<a class="nav-link <?= $section === 'whitelist' ? 'active' : '' ?>" href="?page=security§ion=whitelist">IP Whitelist</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<?php if ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit blacklist')) { ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?= $section === 'blacklist' ? 'active' : '' ?>" href="?page=security§ion=blacklist">IP blacklist</a>
|
||||
<a class="nav-link <?= $section === 'blacklist' ? 'active' : '' ?>" href="?page=security§ion=blacklist">IP Blacklist</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<?php if ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit ratelimiting')) { ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?= $section === 'ratelimit' ? 'active' : '' ?>" href="?page=security§ion=ratelimit">Rate limiting</a>
|
||||
<a class="nav-link <?= $section === 'ratelimit' ? 'active' : '' ?>" href="?page=security§ion=ratelimit">Rate Limiting</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
|
@ -24,12 +24,12 @@
|
|||
</div>
|
||||
|
||||
<?php if ($section === 'whitelist' && ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit whitelist'))) { ?>
|
||||
<!-- whitelist section -->
|
||||
<!-- Whitelist Section -->
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>IP whitelist</h3>
|
||||
<h3>IP Whitelist</h3>
|
||||
IP addresses and networks that will always bypass the ratelimiting login checks.
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
@ -37,7 +37,7 @@
|
|||
<input type="hidden" name="action" value="add_whitelist">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<input type="text" class="form-control" name="ip_address" placeholder="IP address or CIDR" required>
|
||||
<input type="text" class="form-control" name="ip_address" placeholder="IP Address or CIDR" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<input type="text" class="form-control" name="description" placeholder="Description">
|
||||
|
@ -45,11 +45,11 @@
|
|||
<div class="col-md-2">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" name="is_network" id="is_network_white">
|
||||
<label class="form-check-label" for="is_network_white">is network</label>
|
||||
<label class="form-check-label" for="is_network_white">Is Network</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="submit" class="btn btn-primary">Add to whitelist</button>
|
||||
<button type="submit" class="btn btn-primary">Add to Whitelist</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -57,11 +57,11 @@
|
|||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>IP address</th>
|
||||
<th>IP Address</th>
|
||||
<th>Network</th>
|
||||
<th>Description</th>
|
||||
<th>Added by</th>
|
||||
<th>Added on</th>
|
||||
<th>Added By</th>
|
||||
<th>Added On</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -91,12 +91,12 @@
|
|||
<?php } ?>
|
||||
|
||||
<?php if ($section === 'blacklist' && ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit blacklist'))) { ?>
|
||||
<!-- blacklist section -->
|
||||
<!-- Blacklist Section -->
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>IP blacklist</h3>
|
||||
<h3>IP Blacklist</h3>
|
||||
IP addresses and networks that will always get blocked at login.
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
@ -104,7 +104,7 @@
|
|||
<input type="hidden" name="action" value="add_blacklist">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-3">
|
||||
<input type="text" class="form-control" name="ip_address" placeholder="IP address or CIDR" required>
|
||||
<input type="text" class="form-control" name="ip_address" placeholder="IP Address or CIDR" required>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<input type="text" class="form-control" name="reason" placeholder="Reason">
|
||||
|
@ -115,11 +115,11 @@
|
|||
<div class="col-md-2">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" name="is_network" id="is_network_black">
|
||||
<label class="form-check-label" for="is_network_black">is network</label>
|
||||
<label class="form-check-label" for="is_network_black">Is Network</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="submit" class="btn btn-primary">Add to blacklist</button>
|
||||
<button type="submit" class="btn btn-primary">Add to Blacklist</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -127,11 +127,11 @@
|
|||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>IP address</th>
|
||||
<th>IP Address</th>
|
||||
<th>Network</th>
|
||||
<th>Reason</th>
|
||||
<th>Added by</th>
|
||||
<th>Added on</th>
|
||||
<th>Added By</th>
|
||||
<th>Added On</th>
|
||||
<th>Expires</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
|
@ -163,17 +163,17 @@
|
|||
<?php } ?>
|
||||
|
||||
<?php if ($section === 'ratelimit' && ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit ratelimiting'))) { ?>
|
||||
<!-- rate limiting section -->
|
||||
<!-- Rate Limiting Section -->
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Rate limiting settings</h3>
|
||||
<h3>Rate Limiting Settings</h3>
|
||||
Rate limiting settings control how many failed login attempts are allowed before blocking an IP address.
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="alert alert-info">
|
||||
<h4>Current settings</h4>
|
||||
<h4>Current Settings</h4>
|
||||
<ul>
|
||||
<li>Maximum login attempts: <?= $rateLimiter->maxAttempts ?></li>
|
||||
<li>Time window: <?= $rateLimiter->decayMinutes ?> minutes</li>
|
||||
|
@ -185,13 +185,13 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<h4>Recent failed login attempts</h4>
|
||||
<h4>Recent Failed Login Attempts</h4>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>IP sddress</th>
|
||||
<th>IP Address</th>
|
||||
<th>Username</th>
|
||||
<th>Attempted at</th>
|
||||
<th>Attempted At</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -220,4 +220,4 @@
|
|||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<!-- /security settings -->
|
||||
<!-- /Security Settings -->
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
|
||||
<!-- jilo agent status -->
|
||||
<div class="d-flex align-items-center flex-wrap border-top p-3">
|
||||
<div class="d-flex align-items-center me-4">
|
||||
<span class="me-2">Jilo agent
|
||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config#platform<?= htmlspecialchars($platform['id']) ?>agent<?= htmlspecialchars($agent['id']) ?>" class="text-decoration-none">
|
||||
<?= htmlspecialchars($agent['agent_description']) ?>
|
||||
</a>:
|
||||
</span>
|
||||
<span class="badge <?= $agent_availability === 'running' ? 'bg-success' : 'bg-danger' ?>" title="<?= $agent_availability !== 'running' ? htmlspecialchars($agent_availability) : '' ?>" data-toggle="tooltip" data-placement="right" data-offset="30.0">
|
||||
<?= $agent_availability === 'running' ? 'Running' : 'Error' ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center me-4">
|
||||
<span class="me-4">Host: <strong><?= htmlspecialchars($agent_host) ?></strong></span>
|
||||
<span class="me-4">Port: <strong><?= htmlspecialchars($agent_port) ?></strong></span>
|
||||
<span>Endpoint: <strong><?= htmlspecialchars($agent['agent_endpoint']) ?></strong></span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- jilo agent status -->
|
||||
<div class="card text-center w-75 mx-lef" style="padding-left: 80px;">
|
||||
<div class="card-body">
|
||||
<p class="card-text text-left" style="text-align: left;">
|
||||
Jilo Agent <a href="<?= htmlspecialchars($app_root) ?>?page=config#platform<?= htmlspecialchars($platform['id']) ?>agent<?= htmlspecialchars($agent['id']) ?>"><?= htmlspecialchars($agent['agent_description']) ?></a>:
|
||||
<strong><?= $agent_availability ?></strong>
|
||||
<br />
|
||||
host: <strong><?= htmlspecialchars($agent_host) ?></strong>,
|
||||
port: <strong><?= htmlspecialchars($agent_port) ?></strong>,
|
||||
endpoint: <strong><?= htmlspecialchars($agent['agent_endpoint']) ?></strong>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,21 +1,13 @@
|
|||
|
||||
<!-- jitsi platform status -->
|
||||
<div class="card mt-3 mb-3">
|
||||
<div class="card-header">
|
||||
<h4>
|
||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config#platform<?= htmlspecialchars($platform['id']) ?>" class="text-decoration-none">
|
||||
Jitsi platform "<?= htmlspecialchars($platform['name']) ?>"
|
||||
</a>
|
||||
</h4>
|
||||
<small class="text-muted">Remote Jitsi Meet installation with its database and agents here.</small>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center flex-wrap">
|
||||
<span class="me-4">Jilo database: <strong><?= htmlspecialchars($platform['jilo_database']) ?></strong></span>
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="me-2">Status:</span>
|
||||
<span class="badge <?= $jilo_database_status === 'OK' ? 'bg-success' : 'bg-danger' ?>"><?= htmlspecialchars($jilo_database_status) ?></span>
|
||||
<!-- jitsi platform status -->
|
||||
<br />
|
||||
<div class="card text-center w-75 mx-lef" style="padding-left: 40px;">
|
||||
<div class="card-body">
|
||||
<p class="card-text text-left" style="text-align: left;">
|
||||
Jitsi Meet platform: <a href="<?= htmlspecialchars($app_root) ?>?page=config#platform<?= htmlspecialchars($platform['id']) ?>"><?= htmlspecialchars($platform['name']) ?></a>
|
||||
<br />
|
||||
jilo database: <strong><?= htmlspecialchars($platform['jilo_database']) ?></strong>,
|
||||
status: <strong><?= $jilo_database_status ?></strong>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,26 +1,19 @@
|
|||
<!-- jilo status -->
|
||||
<div class="container-fluid mt-2">
|
||||
<div class="row mb-5">
|
||||
<div class="col">
|
||||
<h2>Jilo status</h2>
|
||||
|
||||
<!-- jilo status -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h4>Jilo server</h4>
|
||||
<small class="text-muted">Responsible for periodic checks of remote agents and storing received data.</small>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center flex-wrap">
|
||||
<div class="d-flex align-items-center me-4">
|
||||
<span class="me-2">Jilo server:</span>
|
||||
<span class="badge <?= $server_status ? 'bg-success' : 'bg-danger' ?>">
|
||||
<?= $server_status ? 'Running' : 'Not running' ?>
|
||||
</span>
|
||||
</div>
|
||||
<span class="me-4">Host: <strong><?= htmlspecialchars($server_host) ?></strong></span>
|
||||
<span class="me-4">Port: <strong><?= htmlspecialchars($server_port) ?></strong></span>
|
||||
<span>Endpoint: <strong><?= htmlspecialchars($server_endpoint) ?></strong></span>
|
||||
<!-- jilo status -->
|
||||
<div class="card text-center w-75 mx-lef">
|
||||
<p class="h4 card-header">Jilo platform status</p>
|
||||
<div class="card-body">
|
||||
<p class="card-text text-left" style="text-align: left;">
|
||||
Jilo Server:
|
||||
<?php if ($server_status) { ?>
|
||||
<strong><span class="text-success">running</span></strong>
|
||||
<?php } else { ?>
|
||||
<strong><span class="text-danger">not running</span></strong>
|
||||
<?php } ?>
|
||||
<br />
|
||||
host: <strong><?= htmlspecialchars($server_host) ?></strong>,
|
||||
port: <strong><?= htmlspecialchars($server_port) ?></strong>,
|
||||
endpoint: <strong><?= htmlspecialchars($server_endpoint) ?></strong>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -86,6 +86,7 @@ CREATE TABLE IF NOT EXISTS "jilo_agents" (
|
|||
CREATE TABLE IF NOT EXISTS "hosts" (
|
||||
"id" INTEGER NOT NULL,
|
||||
"address" TEXT NOT NULL,
|
||||
"port" INTEGER NOT NULL,
|
||||
"platform_id" INTEGER NOT NULL,
|
||||
"name" TEXT,
|
||||
PRIMARY KEY("id" AUTOINCREMENT),
|
||||
|
|
|
@ -23,6 +23,5 @@ INSERT INTO jilo_agents VALUES(4,1,2,'https://meet.lindeas.com:8081','mysecretke
|
|||
INSERT INTO jilo_agents VALUES(7,1,3,'http://meet.lindeas.com:8081','mysecretkey',5);
|
||||
INSERT INTO jilo_agents VALUES(8,1,4,'http://meet.lindeas.com:8081','mysecretkey',5);
|
||||
|
||||
INSERT INTO hosts VALUES(1,'meet.lindeas.com',2,'main machine');
|
||||
INSERT INTO hosts VALUES(2,'meet.example.com',2,'test');
|
||||
|
||||
INSERT INTO hosts VALUES(1,'meet.lindeas.com',8888,2,'main machine');
|
||||
INSERT INTO hosts VALUES(2,'meet.example.com',9191,2,'test');
|
||||
|
|
Loading…
Reference in New Issue