first sync
This commit is contained in:
0
js/config.js
Normal file
0
js/config.js
Normal file
487
js/wazuh.js
Normal file
487
js/wazuh.js
Normal file
@@ -0,0 +1,487 @@
|
||||
/**
|
||||
* 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);
|
Reference in New Issue
Block a user