487 lines
15 KiB
JavaScript
487 lines
15 KiB
JavaScript
/**
|
|
* SIEM-Wazuh Plugin for GLPI - Main JavaScript
|
|
* Handles all interactive features for the Wazuh plugin
|
|
*/
|
|
|
|
// Plugin namespace
|
|
var WazuhPlugin = WazuhPlugin || {};
|
|
|
|
/**
|
|
* Initialize the plugin
|
|
*/
|
|
WazuhPlugin.init = function() {
|
|
// Initialize tooltips
|
|
this.initTooltips();
|
|
|
|
// Initialize auto-refresh
|
|
this.initAutoRefresh();
|
|
|
|
// Initialize form validation
|
|
this.initFormValidation();
|
|
|
|
// Initialize keyboard shortcuts
|
|
this.initKeyboardShortcuts();
|
|
|
|
console.log('SIEM-Wazuh Plugin initialized');
|
|
};
|
|
|
|
/**
|
|
* Test connection to Wazuh server
|
|
*/
|
|
WazuhPlugin.testConnection = function(serverId) {
|
|
const button = document.querySelector('.test-connection-' + serverId);
|
|
const resultDiv = document.getElementById('test-result-' + serverId);
|
|
|
|
if (!button || !resultDiv) {
|
|
console.error('Test connection elements not found');
|
|
return;
|
|
}
|
|
|
|
// Show loading state
|
|
button.disabled = true;
|
|
button.innerHTML = '<span class="loading-spinner"></span>' + LANG.TESTING;
|
|
|
|
const formData = new FormData();
|
|
formData.append('server_id', serverId);
|
|
formData.append('_glpi_csrf_token', getAjaxCsrfToken());
|
|
|
|
fetch(CFG_GLPI.root_doc + '/plugins/siem-wazuh/ajax/test_connection.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('HTTP ' + response.status);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
let alertClass = data.success ? 'alert-success' : 'alert-danger';
|
|
let message = data.message;
|
|
|
|
if (data.success && data.server_info) {
|
|
message += '<br><small><strong>Server Info:</strong><br>';
|
|
message += 'Version: ' + (data.server_info.api_version || 'Unknown') + '<br>';
|
|
message += 'Timestamp: ' + data.timestamp + '</small>';
|
|
}
|
|
|
|
resultDiv.innerHTML = '<div class="alert ' + alertClass + '">' + message + '</div>';
|
|
|
|
// Auto-hide after 10 seconds for success messages
|
|
if (data.success) {
|
|
setTimeout(() => {
|
|
resultDiv.innerHTML = '';
|
|
}, 10000);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Connection test error:', error);
|
|
resultDiv.innerHTML = '<div class="alert alert-danger">' + LANG.CONNECTION_TEST_FAILED + ': ' + error.message + '</div>';
|
|
})
|
|
.finally(() => {
|
|
button.disabled = false;
|
|
button.innerHTML = LANG.TEST_CONNECTION;
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Synchronize alerts from Wazuh server
|
|
*/
|
|
WazuhPlugin.syncAlerts = function(serverId, showConfirm = true) {
|
|
if (showConfirm && !confirm(LANG.CONFIRM_SYNC_ALERTS)) {
|
|
return;
|
|
}
|
|
|
|
const button = document.querySelector('.sync-alerts-' + serverId);
|
|
if (button) {
|
|
button.disabled = true;
|
|
button.innerHTML = '<span class="loading-spinner"></span>' + LANG.SYNCHRONIZING;
|
|
}
|
|
|
|
const formData = new FormData();
|
|
formData.append('server_id', serverId);
|
|
formData.append('action', 'sync');
|
|
formData.append('_glpi_csrf_token', getAjaxCsrfToken());
|
|
|
|
fetch(CFG_GLPI.root_doc + '/plugins/siem-wazuh/ajax/sync_alerts.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
this.showNotification(data.message, 'success');
|
|
|
|
// Update statistics if available
|
|
if (data.stats) {
|
|
this.updateStatistics(data.stats);
|
|
}
|
|
|
|
// Refresh the page after 2 seconds
|
|
setTimeout(() => {
|
|
location.reload();
|
|
}, 2000);
|
|
} else {
|
|
this.showNotification(LANG.SYNC_FAILED + ' ' + data.message, 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Sync error:', error);
|
|
this.showNotification(LANG.SYNC_ERROR, 'error');
|
|
})
|
|
.finally(() => {
|
|
if (button) {
|
|
button.disabled = false;
|
|
button.innerHTML = LANG.SYNC_ALERTS;
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Sync alerts for specific item
|
|
*/
|
|
WazuhPlugin.syncAlertsForItem = function(itemId, itemType) {
|
|
if (!confirm(LANG.CONFIRM_SYNC_ITEM)) {
|
|
return;
|
|
}
|
|
|
|
const formData = new FormData();
|
|
formData.append('item_id', itemId);
|
|
formData.append('item_type', itemType);
|
|
formData.append('action', 'sync_for_item');
|
|
formData.append('_glpi_csrf_token', getAjaxCsrfToken());
|
|
|
|
fetch(CFG_GLPI.root_doc + '/plugins/siem-wazuh/ajax/sync_alerts.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
this.showNotification(data.message, 'success');
|
|
setTimeout(() => location.reload(), 2000);
|
|
} else {
|
|
this.showNotification(LANG.SYNC_FAILED + ' ' + data.message, 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Item sync error:', error);
|
|
this.showNotification(LANG.SYNC_ERROR, 'error');
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Toggle server active status
|
|
*/
|
|
WazuhPlugin.toggleServerStatus = function(serverId) {
|
|
if (confirm(LANG.CONFIRM_TOGGLE_STATUS)) {
|
|
window.location.href = '?action=toggle_active&id=' + serverId;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Check/uncheck all alerts
|
|
*/
|
|
WazuhPlugin.checkAllAlerts = function(checkbox) {
|
|
const checkboxes = document.querySelectorAll('input[name="selected_alerts[]"]');
|
|
for (let i = 0; i < checkboxes.length; i++) {
|
|
checkboxes[i].checked = checkbox.checked;
|
|
}
|
|
this.updateBulkActionButtons();
|
|
};
|
|
|
|
/**
|
|
* Update bulk action buttons based on selection
|
|
*/
|
|
WazuhPlugin.updateBulkActionButtons = function() {
|
|
const checkboxes = document.querySelectorAll('input[name="selected_alerts[]"]:checked');
|
|
const bulkActions = document.querySelectorAll('.bulk-action-btn');
|
|
|
|
bulkActions.forEach(button => {
|
|
button.disabled = checkboxes.length === 0;
|
|
});
|
|
|
|
// Update counter if exists
|
|
const counter = document.getElementById('selected-count');
|
|
if (counter) {
|
|
counter.textContent = checkboxes.length;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Filter alerts table
|
|
*/
|
|
WazuhPlugin.filterAlerts = function(filters) {
|
|
const table = document.querySelector('.alert-list table');
|
|
if (!table) return;
|
|
|
|
const rows = table.querySelectorAll('tbody tr');
|
|
|
|
rows.forEach(row => {
|
|
let visible = true;
|
|
|
|
// Apply filters
|
|
Object.keys(filters).forEach(filterKey => {
|
|
const filterValue = filters[filterKey];
|
|
if (filterValue && filterValue !== 'all') {
|
|
const cell = row.querySelector('[data-' + filterKey + ']');
|
|
if (cell && cell.getAttribute('data-' + filterKey) !== filterValue) {
|
|
visible = false;
|
|
}
|
|
}
|
|
});
|
|
|
|
row.style.display = visible ? '' : 'none';
|
|
});
|
|
|
|
this.updateFilterStats();
|
|
};
|
|
|
|
/**
|
|
* Update filter statistics
|
|
*/
|
|
WazuhPlugin.updateFilterStats = function() {
|
|
const visibleRows = document.querySelectorAll('.alert-list tbody tr:not([style*="none"])');
|
|
const totalRows = document.querySelectorAll('.alert-list tbody tr');
|
|
|
|
const statsElement = document.getElementById('filter-stats');
|
|
if (statsElement) {
|
|
statsElement.textContent = `${visibleRows.length} of ${totalRows.length} alerts shown`;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Export alerts to CSV
|
|
*/
|
|
WazuhPlugin.exportAlerts = function(params = {}) {
|
|
const url = new URL(CFG_GLPI.root_doc + '/plugins/siem-wazuh/front/wazuhalert.php');
|
|
url.searchParams.append('export', '1');
|
|
|
|
Object.keys(params).forEach(key => {
|
|
url.searchParams.append(key, params[key]);
|
|
});
|
|
|
|
window.open(url.toString(), '_blank');
|
|
};
|
|
|
|
/**
|
|
* Show notification message
|
|
*/
|
|
WazuhPlugin.showNotification = function(message, type = 'info', duration = 5000) {
|
|
// Try to use GLPI's notification system first
|
|
if (typeof displayAjaxMessageAfterRedirect === 'function') {
|
|
displayAjaxMessageAfterRedirect();
|
|
return;
|
|
}
|
|
|
|
// Fallback to custom notification
|
|
const notification = document.createElement('div');
|
|
notification.className = `alert alert-${type === 'error' ? 'danger' : type} wazuh-notification`;
|
|
notification.style.cssText = `
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
z-index: 9999;
|
|
max-width: 400px;
|
|
animation: slideIn 0.3s ease-out;
|
|
`;
|
|
notification.innerHTML = `
|
|
<button type="button" class="close" onclick="this.parentElement.remove()">
|
|
<span>×</span>
|
|
</button>
|
|
${message}
|
|
`;
|
|
|
|
document.body.appendChild(notification);
|
|
|
|
// Auto-remove after duration
|
|
if (duration > 0) {
|
|
setTimeout(() => {
|
|
if (notification.parentNode) {
|
|
notification.remove();
|
|
}
|
|
}, duration);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Update statistics display
|
|
*/
|
|
WazuhPlugin.updateStatistics = function(stats) {
|
|
Object.keys(stats).forEach(key => {
|
|
const element = document.getElementById('stat-' + key);
|
|
if (element) {
|
|
element.textContent = stats[key];
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Initialize tooltips
|
|
*/
|
|
WazuhPlugin.initTooltips = function() {
|
|
// Simple tooltip implementation
|
|
const tooltipElements = document.querySelectorAll('[data-tooltip]');
|
|
|
|
tooltipElements.forEach(element => {
|
|
element.addEventListener('mouseenter', function() {
|
|
const tooltip = document.createElement('div');
|
|
tooltip.className = 'wazuh-tooltip-popup';
|
|
tooltip.textContent = this.getAttribute('data-tooltip');
|
|
tooltip.style.cssText = `
|
|
position: absolute;
|
|
background: #333;
|
|
color: white;
|
|
padding: 5px 10px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
z-index: 1000;
|
|
pointer-events: none;
|
|
`;
|
|
|
|
document.body.appendChild(tooltip);
|
|
|
|
// Position tooltip
|
|
const rect = this.getBoundingClientRect();
|
|
tooltip.style.left = (rect.left + rect.width / 2 - tooltip.offsetWidth / 2) + 'px';
|
|
tooltip.style.top = (rect.top - tooltip.offsetHeight - 5) + 'px';
|
|
|
|
this._tooltip = tooltip;
|
|
});
|
|
|
|
element.addEventListener('mouseleave', function() {
|
|
if (this._tooltip) {
|
|
this._tooltip.remove();
|
|
this._tooltip = null;
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Initialize auto-refresh functionality
|
|
*/
|
|
WazuhPlugin.initAutoRefresh = function() {
|
|
const refreshInterval = parseInt(document.body.getAttribute('data-refresh-interval')) || 0;
|
|
|
|
if (refreshInterval > 0) {
|
|
setInterval(() => {
|
|
// Only refresh if page is visible
|
|
if (!document.hidden) {
|
|
this.refreshData();
|
|
}
|
|
}, refreshInterval * 1000);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Refresh data without full page reload
|
|
*/
|
|
WazuhPlugin.refreshData = function() {
|
|
// Update statistics
|
|
fetch(CFG_GLPI.root_doc + '/plugins/siem-wazuh/ajax/sync_alerts.php?action=status')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
this.updateStatistics(data.stats);
|
|
}
|
|
})
|
|
.catch(error => console.warn('Auto-refresh failed:', error));
|
|
};
|
|
|
|
/**
|
|
* Initialize form validation
|
|
*/
|
|
WazuhPlugin.initFormValidation = function() {
|
|
// Validate server URLs
|
|
const urlInputs = document.querySelectorAll('input[name="wazuh_url"], input[name="indexer_url"]');
|
|
urlInputs.forEach(input => {
|
|
input.addEventListener('blur', function() {
|
|
if (this.value && !this.value.match(/^https?:\/\/.+/)) {
|
|
this.setCustomValidity('Please enter a valid URL starting with http:// or https://');
|
|
} else {
|
|
this.setCustomValidity('');
|
|
}
|
|
});
|
|
});
|
|
|
|
// Validate port numbers
|
|
const portInputs = document.querySelectorAll('input[name="wazuh_port"], input[name="indexer_port"]');
|
|
portInputs.forEach(input => {
|
|
input.addEventListener('blur', function() {
|
|
const port = parseInt(this.value);
|
|
if (this.value && (isNaN(port) || port < 1 || port > 65535)) {
|
|
this.setCustomValidity('Please enter a valid port number (1-65535)');
|
|
} else {
|
|
this.setCustomValidity('');
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Initialize keyboard shortcuts
|
|
*/
|
|
WazuhPlugin.initKeyboardShortcuts = function() {
|
|
document.addEventListener('keydown', function(e) {
|
|
// Ctrl+Shift+S: Sync all servers
|
|
if (e.ctrlKey && e.shiftKey && e.key === 'S') {
|
|
e.preventDefault();
|
|
const syncButton = document.querySelector('.sync-all-btn');
|
|
if (syncButton) {
|
|
syncButton.click();
|
|
}
|
|
}
|
|
|
|
// Ctrl+Shift+T: Test connection
|
|
if (e.ctrlKey && e.shiftKey && e.key === 'T') {
|
|
e.preventDefault();
|
|
const testButton = document.querySelector('.test-connection-btn');
|
|
if (testButton) {
|
|
testButton.click();
|
|
}
|
|
}
|
|
|
|
// Escape: Close modals/notifications
|
|
if (e.key === 'Escape') {
|
|
const notifications = document.querySelectorAll('.wazuh-notification');
|
|
notifications.forEach(notification => notification.remove());
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Utility function to get CSRF token
|
|
*/
|
|
function getAjaxCsrfToken() {
|
|
return $('meta[name="glpi-csrf-token"]').attr('content') || '';
|
|
}
|
|
|
|
/**
|
|
* Language strings (will be populated by PHP)
|
|
*/
|
|
var LANG = LANG || {
|
|
TESTING: 'Testing...',
|
|
SYNCHRONIZING: 'Synchronizing...',
|
|
TEST_CONNECTION: 'Test Connection',
|
|
SYNC_ALERTS: 'Sync Alerts',
|
|
CONNECTION_TEST_FAILED: 'Connection test failed',
|
|
SYNC_FAILED: 'Sync failed:',
|
|
SYNC_ERROR: 'An error occurred during synchronization',
|
|
CONFIRM_SYNC_ALERTS: 'Are you sure you want to synchronize alerts from this server?',
|
|
CONFIRM_SYNC_ITEM: 'Are you sure you want to sync alerts for this item?',
|
|
CONFIRM_TOGGLE_STATUS: 'Are you sure you want to change the status of this server?'
|
|
};
|
|
|
|
// Initialize when DOM is ready
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
WazuhPlugin.init();
|
|
});
|
|
|
|
// Expose to global scope for legacy compatibility
|
|
window.WazuhPlugin = WazuhPlugin;
|
|
window.testWazuhConnection = WazuhPlugin.testConnection.bind(WazuhPlugin);
|
|
window.syncWazuhAlerts = WazuhPlugin.syncAlerts.bind(WazuhPlugin);
|
|
window.syncAlertsForItem = WazuhPlugin.syncAlertsForItem.bind(WazuhPlugin);
|
|
window.toggleServerStatus = WazuhPlugin.toggleServerStatus.bind(WazuhPlugin);
|
|
window.checkAll = WazuhPlugin.checkAllAlerts.bind(WazuhPlugin); |