/** * 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 = '' + 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 += '
Server Info:
'; message += 'Version: ' + (data.server_info.api_version || 'Unknown') + '
'; message += 'Timestamp: ' + data.timestamp + '
'; } resultDiv.innerHTML = '
' + message + '
'; // 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 = '
' + LANG.CONNECTION_TEST_FAILED + ': ' + error.message + '
'; }) .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 = '' + 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 = ` ${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);