330
src/hooks/use-csf-api.ts
Archivo normal
330
src/hooks/use-csf-api.ts
Archivo normal
@@ -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
|
||||
}
|
||||
}
|
||||
Referencia en una nueva incidencia
Block a user