initial commit

Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-09-20 18:42:04 +02:00
padre 319658038a
commit dce8b73888
Se han modificado 29 ficheros con 4173 adiciones y 6067 borrados

330
src/hooks/use-csf-api.ts Archivo normal
Ver fichero

@@ -0,0 +1,330 @@
import { useState, useEffect, useCallback } from 'react'
import { ApiResponse, CSFStatus, FirewallRule, LogEntry, ServerStats, CSFConfig } from '@/types/csf'
interface UseCSFApiResult {
// Status
status: CSFStatus | null
getStatus: () => Promise<void>
// Control
startFirewall: () => Promise<boolean>
stopFirewall: () => Promise<boolean>
restartFirewall: () => Promise<boolean>
enableFirewall: () => Promise<boolean>
disableFirewall: () => Promise<boolean>
// Rules
rules: FirewallRule[]
getRules: (type?: 'allow' | 'deny' | 'temp' | 'all') => Promise<void>
addRule: (ip: string, type: 'allow' | 'deny', comment?: string) => Promise<boolean>
removeRule: (ip: string, type: 'allow' | 'deny') => Promise<boolean>
addTempBlock: (ip: string, duration: string, comment?: string) => Promise<boolean>
// Config
config: CSFConfig | null
getConfig: () => Promise<void>
updateConfig: (updates: Record<string, any>) => Promise<boolean>
// Logs
logs: LogEntry[]
getLogs: (type?: string, limit?: number) => Promise<void>
// Stats
stats: ServerStats | null
getStats: () => Promise<void>
// State
loading: boolean
error: string | null
clearError: () => void
}
export function useCSFApi(): UseCSFApiResult {
const [status, setStatus] = useState<CSFStatus | null>(null)
const [rules, setRules] = useState<FirewallRule[]>([])
const [config, setConfig] = useState<CSFConfig | null>(null)
const [logs, setLogs] = useState<LogEntry[]>([])
const [stats, setStats] = useState<ServerStats | null>(null)
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const clearError = useCallback(() => setError(null), [])
const apiRequest = useCallback(async <T>(
endpoint: string,
options: RequestInit = {}
): Promise<ApiResponse<T>> => {
try {
setLoading(true)
clearError()
const response = await fetch(endpoint, {
headers: {
'Content-Type': 'application/json',
...options.headers,
},
...options,
})
const data: ApiResponse<T> = await response.json()
if (!data.success) {
throw new Error(data.error || 'API request failed')
}
return data
} catch (err: any) {
const errorMessage = err.message || 'Network error'
setError(errorMessage)
throw new Error(errorMessage)
} finally {
setLoading(false)
}
}, [clearError])
// Status operations
const getStatus = useCallback(async () => {
try {
const response = await apiRequest<{ output: string; running: boolean }>('/api/csf?action=status')
if (response.data) {
// Get version info as well
const versionResponse = await apiRequest<{ version: string }>('/api/csf?action=version')
setStatus({
running: response.data.running,
version: versionResponse.data?.version || 'Unknown',
ipv4_active: response.data.running,
ipv6_active: response.data.running,
testing_mode: false // This would need to be parsed from config
})
}
} catch (err) {
console.error('Failed to get status:', err)
}
}, [apiRequest])
// Control operations
const startFirewall = useCallback(async (): Promise<boolean> => {
try {
const response = await apiRequest('/api/csf', {
method: 'POST',
body: JSON.stringify({ action: 'start' })
})
await getStatus() // Refresh status
return response.success
} catch (err) {
console.error('Failed to start firewall:', err)
return false
}
}, [apiRequest, getStatus])
const stopFirewall = useCallback(async (): Promise<boolean> => {
try {
const response = await apiRequest('/api/csf', {
method: 'POST',
body: JSON.stringify({ action: 'stop' })
})
await getStatus() // Refresh status
return response.success
} catch (err) {
console.error('Failed to stop firewall:', err)
return false
}
}, [apiRequest, getStatus])
const restartFirewall = useCallback(async (): Promise<boolean> => {
try {
const response = await apiRequest('/api/csf', {
method: 'POST',
body: JSON.stringify({ action: 'restart' })
})
await getStatus() // Refresh status
return response.success
} catch (err) {
console.error('Failed to restart firewall:', err)
return false
}
}, [apiRequest, getStatus])
const enableFirewall = useCallback(async (): Promise<boolean> => {
try {
const response = await apiRequest('/api/csf', {
method: 'POST',
body: JSON.stringify({ action: 'enable' })
})
await getStatus() // Refresh status
return response.success
} catch (err) {
console.error('Failed to enable firewall:', err)
return false
}
}, [apiRequest, getStatus])
const disableFirewall = useCallback(async (): Promise<boolean> => {
try {
const response = await apiRequest('/api/csf', {
method: 'POST',
body: JSON.stringify({ action: 'disable' })
})
await getStatus() // Refresh status
return response.success
} catch (err) {
console.error('Failed to disable firewall:', err)
return false
}
}, [apiRequest, getStatus])
// Rules operations
const getRules = useCallback(async (type: 'allow' | 'deny' | 'temp' | 'all' = 'all') => {
try {
const response = await apiRequest<FirewallRule[]>(`/api/rules?type=${type}`)
if (response.data) {
setRules(response.data)
}
} catch (err) {
console.error('Failed to get rules:', err)
}
}, [apiRequest])
const addRule = useCallback(async (ip: string, type: 'allow' | 'deny', comment?: string): Promise<boolean> => {
try {
const action = type === 'allow' ? 'add_allow' : 'add_deny'
const response = await apiRequest('/api/rules', {
method: 'POST',
body: JSON.stringify({ action, ip, comment })
})
await getRules() // Refresh rules
return response.success
} catch (err) {
console.error('Failed to add rule:', err)
return false
}
}, [apiRequest, getRules])
const removeRule = useCallback(async (ip: string, type: 'allow' | 'deny'): Promise<boolean> => {
try {
const response = await apiRequest(`/api/rules?ip=${encodeURIComponent(ip)}&type=${type}`, {
method: 'DELETE'
})
await getRules() // Refresh rules
return response.success
} catch (err) {
console.error('Failed to remove rule:', err)
return false
}
}, [apiRequest, getRules])
const addTempBlock = useCallback(async (ip: string, duration: string, comment?: string): Promise<boolean> => {
try {
const response = await apiRequest('/api/rules', {
method: 'POST',
body: JSON.stringify({ action: 'add_temp_deny', ip, duration, comment })
})
await getRules() // Refresh rules
return response.success
} catch (err) {
console.error('Failed to add temporary block:', err)
return false
}
}, [apiRequest, getRules])
// Config operations
const getConfig = useCallback(async () => {
try {
const response = await apiRequest<CSFConfig>('/api/config')
if (response.data) {
setConfig(response.data)
}
} catch (err) {
console.error('Failed to get config:', err)
}
}, [apiRequest])
const updateConfig = useCallback(async (updates: Record<string, any>): Promise<boolean> => {
try {
const response = await apiRequest('/api/config', {
method: 'POST',
body: JSON.stringify({ updates })
})
await getConfig() // Refresh config
return response.success
} catch (err) {
console.error('Failed to update config:', err)
return false
}
}, [apiRequest, getConfig])
// Logs operations
const getLogs = useCallback(async (type: string = 'all', limit: number = 100) => {
try {
const response = await apiRequest<{ logs: LogEntry[]; total: number; type: string }>(`/api/logs?type=${type}&limit=${limit}`)
if (response.data) {
setLogs(response.data.logs)
}
} catch (err) {
console.error('Failed to get logs:', err)
}
}, [apiRequest])
// Stats operations
const getStats = useCallback(async () => {
try {
const response = await apiRequest<ServerStats>('/api/stats')
if (response.data) {
setStats(response.data)
}
} catch (err) {
console.error('Failed to get stats:', err)
}
}, [apiRequest])
// Auto-refresh data periodically
useEffect(() => {
const interval = setInterval(() => {
if (!loading) {
getStatus()
getStats()
}
}, 10000) // Refresh every 10 seconds
return () => clearInterval(interval)
}, [loading, getStatus, getStats])
return {
// Status
status,
getStatus,
// Control
startFirewall,
stopFirewall,
restartFirewall,
enableFirewall,
disableFirewall,
// Rules
rules,
getRules,
addRule,
removeRule,
addTempBlock,
// Config
config,
getConfig,
updateConfig,
// Logs
logs,
getLogs,
// Stats
stats,
getStats,
// State
loading,
error,
clearError
}
}