feat: login IP whitelist, blocks UI and fail2ban sync (0.4.1)

Admin settings for web login whitelist, blocked IP list with unblock,
and optional fail2ban ignoreip sync for SSH jail.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-25 10:06:10 +10:00
parent bda02f67eb
commit 719d5c5719
12 changed files with 863 additions and 2 deletions
+47
View File
@@ -697,6 +697,53 @@ export function testAgentGitRelease(payload?: AgentGitTestPayload): Promise<Agen
});
}
export interface LoginSecuritySettings {
ip_whitelist: string[];
ip_whitelist_text: string;
sync_fail2ban: boolean;
max_failures: number;
window_minutes: number;
fail2ban_available: boolean;
source: string;
}
export interface LoginBlockItem {
ip_address: string;
scope: string;
failure_count: number | null;
usernames: string[];
blocked_until: string | null;
reason: string;
}
export function fetchLoginSecuritySettings(): Promise<LoginSecuritySettings> {
return apiFetch<LoginSecuritySettings>("/api/v1/settings/login-security");
}
export function saveLoginSecuritySettings(payload: {
ip_whitelist_text: string;
sync_fail2ban: boolean;
}): Promise<LoginSecuritySettings> {
return apiFetch<LoginSecuritySettings>("/api/v1/settings/login-security", {
method: "PUT",
body: JSON.stringify(payload),
});
}
export function fetchLoginSecurityBlocks(): Promise<LoginBlockItem[]> {
return apiFetch<LoginBlockItem[]>("/api/v1/settings/login-security/blocks");
}
export function unblockLoginSecurityIp(payload: {
ip_address: string;
scope: "web" | "ssh" | "both";
}): Promise<{ messages: string[] }> {
return apiFetch<{ messages: string[] }>("/api/v1/settings/login-security/unblock", {
method: "POST",
body: JSON.stringify(payload),
});
}
export interface DashboardSummary {
events_last_24h: number;
hosts_total: number;