fix settings page csrf
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Initialize variables
|
||||
let currentPage = 1;
|
||||
let currentPage = parseInt(document.getElementById('currentPage').textContent) || 1;
|
||||
let totalPages = parseInt(document.getElementById('totalPages').textContent) || 1;
|
||||
let isFetching = false;
|
||||
|
||||
@@ -32,107 +32,191 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
window.history.replaceState({}, '', `${window.location.pathname}?${params.toString()}`);
|
||||
}
|
||||
|
||||
// Function to update pagination UI
|
||||
function updatePaginationUI(page, total) {
|
||||
currentPage = page;
|
||||
totalPages = total;
|
||||
currentPageSpan.textContent = currentPage;
|
||||
totalPagesSpan.textContent = totalPages;
|
||||
prevPageBtn.disabled = currentPage === 1;
|
||||
nextPageBtn.disabled = currentPage === totalPages;
|
||||
}
|
||||
|
||||
// Function to fetch filtered events
|
||||
function fetchEvents() {
|
||||
if (isFetching) return;
|
||||
isFetching = true;
|
||||
|
||||
// Show loading state
|
||||
eventsTableBody.innerHTML = '<tr><td colspan="5" class="text-center">Loading...</td></tr>';
|
||||
if (eventsTableBody) {
|
||||
eventsTableBody.innerHTML = '<tr><td colspan="5" class="text-center">Loading...</td></tr>';
|
||||
}
|
||||
|
||||
const params = new URLSearchParams({
|
||||
tab: 'events',
|
||||
page: currentPage,
|
||||
event_type: eventTypeFilter.value,
|
||||
date_range: dateRangeFilter.value,
|
||||
user_id: userFilter.value,
|
||||
ajax: 'true'
|
||||
page: currentPage
|
||||
});
|
||||
|
||||
fetch(`${window.location.pathname}?${params.toString()}`, {
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
|
||||
fetch(`/api/events?${params.toString()}`, {
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'X-CSRF-Token': csrfToken
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.text();
|
||||
return response.json();
|
||||
})
|
||||
.then(html => {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(html, 'text/html');
|
||||
const newTableBody = doc.getElementById('eventsTableBody');
|
||||
.then(data => {
|
||||
console.log('Received events data:', data);
|
||||
|
||||
if (newTableBody) {
|
||||
eventsTableBody.innerHTML = newTableBody.innerHTML;
|
||||
|
||||
// Update pagination
|
||||
const newCurrentPage = parseInt(doc.getElementById('currentPage').textContent) || 1;
|
||||
const newTotalPages = parseInt(doc.getElementById('totalPages').textContent) || 1;
|
||||
currentPage = newCurrentPage;
|
||||
totalPages = newTotalPages;
|
||||
currentPageSpan.textContent = currentPage;
|
||||
totalPagesSpan.textContent = totalPages;
|
||||
|
||||
// Update pagination buttons
|
||||
prevPageBtn.disabled = currentPage <= 1;
|
||||
nextPageBtn.disabled = currentPage >= totalPages;
|
||||
|
||||
// Update URL
|
||||
updateURL();
|
||||
} else {
|
||||
console.error('Could not find events table in response');
|
||||
eventsTableBody.innerHTML = '<tr><td colspan="5" class="text-center">Error loading events</td></tr>';
|
||||
if (!eventsTableBody) {
|
||||
console.error('Could not find events table body element');
|
||||
return;
|
||||
}
|
||||
|
||||
// Update table content
|
||||
let tableHtml = '';
|
||||
if (data.events && data.events.length > 0) {
|
||||
data.events.forEach(event => {
|
||||
tableHtml += `
|
||||
<tr>
|
||||
<td>${new Date(event.timestamp).toLocaleString()}</td>
|
||||
<td>
|
||||
<span class="badge ${getEventBadgeClass(event.event_type)}">
|
||||
${formatEventType(event.event_type)}
|
||||
</span>
|
||||
</td>
|
||||
<td>${event.user ? `${event.user.username} ${event.user.last_name}` : 'Unknown'}</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-outline-secondary"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#eventDetailsModal"
|
||||
data-event-id="${event.id}">
|
||||
<i class="fas fa-info-circle"></i> View Details
|
||||
</button>
|
||||
</td>
|
||||
<td>${event.ip_address || '-'}</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
} else {
|
||||
tableHtml = '<tr><td colspan="5" class="text-center">No events found</td></tr>';
|
||||
}
|
||||
|
||||
// Update the table body
|
||||
eventsTableBody.innerHTML = tableHtml;
|
||||
console.log('Updated table content with', data.events.length, 'events');
|
||||
|
||||
// Update pagination
|
||||
updatePaginationUI(data.current_page, data.total_pages);
|
||||
|
||||
// Update URL
|
||||
updateURL();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching events:', error);
|
||||
eventsTableBody.innerHTML = '<tr><td colspan="5" class="text-center">Error loading events</td></tr>';
|
||||
if (eventsTableBody) {
|
||||
eventsTableBody.innerHTML = '<tr><td colspan="5" class="text-center">Error loading events</td></tr>';
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
isFetching = false;
|
||||
});
|
||||
}
|
||||
|
||||
// Helper function to get badge class based on event type
|
||||
function getEventBadgeClass(eventType) {
|
||||
const badgeClasses = {
|
||||
'user_login': 'bg-info',
|
||||
'user_logout': 'bg-info',
|
||||
'user_create': 'bg-success',
|
||||
'user_delete': 'bg-danger',
|
||||
'user_update': 'bg-warning',
|
||||
'file_upload': 'bg-success',
|
||||
'file_delete': 'bg-danger',
|
||||
'file_download': 'bg-info',
|
||||
'file_preview': 'bg-info',
|
||||
'file_restore': 'bg-warning',
|
||||
'file_move': 'bg-warning',
|
||||
'file_rename': 'bg-warning',
|
||||
'file_star': 'bg-warning',
|
||||
'file_unstar': 'bg-warning',
|
||||
'file_delete_permanent': 'bg-danger',
|
||||
'folder_create': 'bg-success',
|
||||
'room_create': 'bg-success',
|
||||
'room_delete': 'bg-danger',
|
||||
'room_update': 'bg-warning',
|
||||
'room_open': 'bg-info',
|
||||
'room_member_add': 'bg-success',
|
||||
'room_member_remove': 'bg-danger',
|
||||
'room_member_permissions_update': 'bg-warning',
|
||||
'room_permission_update': 'bg-warning',
|
||||
'conversation_create': 'bg-success',
|
||||
'conversation_update': 'bg-warning',
|
||||
'conversation_delete': 'bg-danger',
|
||||
'conversation_open': 'bg-info',
|
||||
'message_create': 'bg-success',
|
||||
'attachment_download': 'bg-info'
|
||||
};
|
||||
return badgeClasses[eventType] || 'bg-secondary';
|
||||
}
|
||||
|
||||
// Helper function to format event type for display
|
||||
function formatEventType(eventType) {
|
||||
return eventType.split('_')
|
||||
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
// Function to load event details
|
||||
function loadEventDetails(eventId) {
|
||||
console.log('Loading details for event:', eventId);
|
||||
fetch(`/api/events/${eventId}`)
|
||||
.then(response => {
|
||||
console.log('Response status:', response.status);
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
console.log('Received event data:', data);
|
||||
|
||||
// Format the details for display
|
||||
const formattedDetails = {};
|
||||
|
||||
// Handle details separately
|
||||
if (data.details) {
|
||||
if (typeof data.details === 'object') {
|
||||
formattedDetails['Details'] = JSON.stringify(data.details, null, 2);
|
||||
} else {
|
||||
formattedDetails['Details'] = data.details;
|
||||
}
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
|
||||
fetch(`/api/events/${eventId}`, {
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'X-CSRF-Token': csrfToken
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
console.log('Response status:', response.status);
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
console.log('Received event data:', data);
|
||||
|
||||
// Format the details for display
|
||||
const formattedDetails = {};
|
||||
|
||||
// Handle details separately
|
||||
if (data.details) {
|
||||
if (typeof data.details === 'object') {
|
||||
formattedDetails['Details'] = JSON.stringify(data.details, null, 2);
|
||||
} else {
|
||||
formattedDetails['Details'] = 'No additional details';
|
||||
formattedDetails['Details'] = data.details;
|
||||
}
|
||||
|
||||
// Convert to formatted string
|
||||
const detailsText = Object.entries(formattedDetails)
|
||||
.map(([key, value]) => `${key}: ${value}`)
|
||||
.join('\n\n');
|
||||
|
||||
console.log('Formatted details:', detailsText);
|
||||
eventDetailsContent.textContent = detailsText;
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error loading event details:', error);
|
||||
eventDetailsContent.textContent = 'Error loading event details. Please try again.';
|
||||
});
|
||||
} else {
|
||||
formattedDetails['Details'] = 'No additional details';
|
||||
}
|
||||
|
||||
// Convert to formatted string
|
||||
const detailsText = Object.entries(formattedDetails)
|
||||
.map(([key, value]) => `${key}: ${value}`)
|
||||
.join('\n\n');
|
||||
|
||||
console.log('Formatted details:', detailsText);
|
||||
eventDetailsContent.textContent = detailsText;
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error loading event details:', error);
|
||||
eventDetailsContent.textContent = 'Error loading event details. Please try again.';
|
||||
});
|
||||
}
|
||||
|
||||
// Add event listeners for filters with debounce
|
||||
@@ -187,8 +271,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
userFilter.value = urlParams.get('user_id') || '';
|
||||
currentPage = parseInt(urlParams.get('page')) || 1;
|
||||
|
||||
// Initial fetch if filters are set
|
||||
if (eventTypeFilter.value || dateRangeFilter.value !== '24h' || userFilter.value) {
|
||||
fetchEvents();
|
||||
}
|
||||
// Initial fetch to ensure pagination is correct
|
||||
fetchEvents();
|
||||
});
|
||||
Reference in New Issue
Block a user