mirror of
https://github.com/swissmakers/fail2ban-ui.git
synced 2026-04-17 05:53:15 +02:00
Added new clear function-calls for the recent-stored-events and as well the permanent-block list
This commit is contained in:
@@ -555,6 +555,16 @@ func BanInsightsHandler(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// Deletes all stored ban event records.
|
||||
func ClearBanEventsHandler(c *gin.Context) {
|
||||
deleted, err := storage.ClearBanEvents(c.Request.Context())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"deleted": deleted})
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Fail2ban Servers Management
|
||||
// =========================================================================
|
||||
@@ -1631,6 +1641,16 @@ func ListPermanentBlocksHandler(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"blocks": records})
|
||||
}
|
||||
|
||||
// Deletes all permanent block records.
|
||||
func ClearPermanentBlocksHandler(c *gin.Context) {
|
||||
deleted, err := storage.ClearPermanentBlocks(c.Request.Context())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"deleted": deleted})
|
||||
}
|
||||
|
||||
// Allows manual block/unblock against the configured integration.
|
||||
func AdvancedActionsTestHandler(c *gin.Context) {
|
||||
var req struct {
|
||||
|
||||
@@ -80,6 +80,7 @@ func RegisterRoutes(r *gin.Engine, hub *Hub) {
|
||||
|
||||
// Internal API calls for advanced actions
|
||||
api.GET("/advanced-actions/blocks", ListPermanentBlocksHandler)
|
||||
api.DELETE("/advanced-actions/blocks", ClearPermanentBlocksHandler)
|
||||
api.POST("/advanced-actions/test", AdvancedActionsTestHandler)
|
||||
|
||||
// Internal API calls for Fail2ban-UI server management
|
||||
@@ -95,6 +96,7 @@ func RegisterRoutes(r *gin.Engine, hub *Hub) {
|
||||
|
||||
// Internal API calls to get the stats of the bans
|
||||
api.GET("/events/bans", ListBanEventsHandler)
|
||||
api.DELETE("/events/bans", ClearBanEventsHandler)
|
||||
api.GET("/events/bans/stats", BanStatisticsHandler)
|
||||
api.GET("/events/bans/insights", BanInsightsHandler)
|
||||
|
||||
|
||||
@@ -483,7 +483,7 @@ function renderLogOverviewContent() {
|
||||
var todayCount = totalBansToday();
|
||||
var weekCount = totalBansWeek();
|
||||
if (statsKeys.length === 0 && totalStored === 0) {
|
||||
html += '<p class="text-gray-500" data-i18n="logs.overview.empty">No ban events recorded yet.</p>';
|
||||
//html += '<p class="text-gray-500" data-i18n="logs.overview.empty">No ban events recorded yet.</p>';
|
||||
} else {
|
||||
html += ''
|
||||
+ '<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">'
|
||||
@@ -531,7 +531,10 @@ function renderLogOverviewContent() {
|
||||
}
|
||||
html += ' </tbody></table></div></div>';
|
||||
}
|
||||
html += '<h4 class="text-md font-semibold text-gray-800 mb-3" data-i18n="logs.overview.recent_events_title">Recent stored events</h4>';
|
||||
html += '<div class="flex items-center justify-between mb-3">'
|
||||
+ '<h4 class="text-md font-semibold text-gray-800" data-i18n="logs.overview.recent_events_title">Recent stored events</h4>'
|
||||
+ '<button type="button" class="px-3 py-1.5 text-xs rounded border border-red-300 text-red-600 hover:bg-red-50" onclick="clearStoredBanEvents()" data-i18n="logs.overview.clear_events">Clear</button>'
|
||||
+ '</div>';
|
||||
var countries = getBanEventCountries();
|
||||
var recurringMap = getRecurringIPMap();
|
||||
var searchQuery = (banEventsFilterText || '').trim();
|
||||
@@ -649,6 +652,28 @@ function loadMoreBanEvents() {
|
||||
});
|
||||
}
|
||||
|
||||
function clearStoredBanEvents() {
|
||||
var msg = t('logs.overview.clear_events_confirm',
|
||||
'This will permanently delete all stored ban events. Statistics, insights, and the event history will be reset to zero.\n\nThis action cannot be undone. Continue?');
|
||||
if (!confirm(msg)) return;
|
||||
fetch('/api/events/bans', { method: 'DELETE', headers: serverHeaders() })
|
||||
.then(function(res) { return res.json(); })
|
||||
.then(function(data) {
|
||||
if (data.error) {
|
||||
showToast(data.error, 'error');
|
||||
return;
|
||||
}
|
||||
showToast(t('logs.overview.clear_events_success', 'All stored ban events cleared.'), 'success');
|
||||
latestBanEvents = [];
|
||||
latestBanStats = {};
|
||||
latestBanInsights = null;
|
||||
banEventsTotal = 0;
|
||||
banEventsHasMore = false;
|
||||
renderLogOverviewSection();
|
||||
})
|
||||
.catch(function(err) { showToast(String(err), 'error'); });
|
||||
}
|
||||
|
||||
// Filtering function for the banned IPs for the dashboard.
|
||||
function filterIPs() {
|
||||
const input = document.getElementById("ipSearch");
|
||||
|
||||
@@ -479,6 +479,23 @@ function refreshPermanentBlockLog() {
|
||||
loadPermanentBlockLog();
|
||||
}
|
||||
|
||||
function clearPermanentBlockLog() {
|
||||
var msg = t('settings.advanced.clear_log_confirm',
|
||||
'This will permanently delete the entire block log. Fail2ban UI will assume that no IPs are currently blocked on the external firewall.\n\nThis action cannot be undone. Continue?');
|
||||
if (!confirm(msg)) return;
|
||||
fetch('/api/advanced-actions/blocks', { method: 'DELETE', headers: serverHeaders() })
|
||||
.then(function(res) { return res.json(); })
|
||||
.then(function(data) {
|
||||
if (data.error) {
|
||||
showToast(data.error, 'error');
|
||||
return;
|
||||
}
|
||||
showToast(t('settings.advanced.clear_log_success', 'Permanent block log cleared.'), 'success');
|
||||
loadPermanentBlockLog();
|
||||
})
|
||||
.catch(function(err) { showToast(String(err), 'error'); });
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Advanced Test
|
||||
// =========================================================================
|
||||
|
||||
@@ -454,7 +454,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<h4 class="text-md font-semibold text-gray-800 mb-2" data-i18n="settings.advanced.log_title">Permanent Block Log</h4>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<h4 class="text-md font-semibold text-gray-800" data-i18n="settings.advanced.log_title">Permanent Block Log</h4>
|
||||
<button type="button" class="px-3 py-1.5 text-xs rounded border border-red-300 text-red-600 hover:bg-red-50" onclick="clearPermanentBlockLog()" data-i18n="settings.advanced.clear_log">Clear</button>
|
||||
</div>
|
||||
<div id="permanentBlockLog" class="overflow-x-auto border border-gray-200 rounded-md">
|
||||
<p class="text-sm text-gray-500 p-4" data-i18n="settings.advanced.log_empty">No permanent blocks recorded yet.</p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user