// src/components/admin/AdminControlsPanel.tsx 'use client'; import { useEffect, useState } from 'react'; import { Typography, Box, Button, Alert, CircularProgress, Snackbar, Dialog, DialogTitle, DialogContent, DialogActions, Select, MenuItem, FormControl, InputLabel, DialogContentText, } from '@mui/material'; import { SwitchTextTrack } from '@/components/SwitchTextTrack'; import CVELogStream from '@/components/CVELogStream'; import api from '@/lib/axios'; export default function AdminControlsPanel() { const [pingEnabled, setPingEnabled] = useState(null); const [message, setMessage] = useState(''); const [drawerOpen, setDrawerOpen] = useState(false); const [logOutput, setLogOutput] = useState(''); const [loading, setLoading] = useState(false); const [toastOpen, setToastOpen] = useState(false); const [toastMessage, setToastMessage] = useState(''); const [clientList, setClientList] = useState>([]); const [selectedClientId, setSelectedClientId] = useState(null); const [dialogOpen, setDialogOpen] = useState(false); const [backfillDialogOpen, setBackfillDialogOpen] = useState(false); const [cveVisible, setCveVisible] = useState(false); const [kevVisible, setKevVisible] = useState(false); const [msrcVisible, setMsrcVisible] = useState(false); useEffect(() => { const fetchInitialState = async () => { try { const res = await api.get("/system/ping-status"); if (res?.data?.acceptPings !== undefined) { setPingEnabled(res.data.acceptPings); } } catch (err) { console.error("❌ Failed to fetch ping status", err); setPingEnabled(false); } }; fetchInitialState(); }, []); const togglePing = async (enabled: boolean) => { try { const res = await api.post(`/admin/toggle-ping?enabled=${enabled}`); setMessage(res.data); setPingEnabled(enabled); } catch (err) { console.error("Toggle failed:", err); setMessage("Failed to update ping status"); } }; useEffect(() => { if (!drawerOpen) return; const interval = setInterval(async () => { const res = await api.get('/admin/scripts/fetch-cve/logs'); setLogOutput(res.data); }, 3000); return () => clearInterval(interval); }, [drawerOpen]); const fetchClients = async () => { try { const res = await api.get('/auth/clients'); setClientList(res.data); } catch (err) { console.error('Failed to fetch clients', err); } }; const runCveSync = async () => { try { setLoading(true); await api.post('/admin/scripts/fetch-cve'); setCveVisible(true); } catch (err: any) { alert("❌ Failed to start CVE sync: " + (err?.response?.data || err.message)); } finally { setLoading(false); } }; const runCveBackfill = async () => { setBackfillDialogOpen(false); try { setLoading(true); await api.post('/admin/scripts/fetch-cve-backfill'); setCveVisible(true); setToastMessage('⏳ CVE backfill started - this will take 20-30 hours to complete!'); setToastOpen(true); } catch (err: any) { setToastMessage("❌ Failed to start CVE backfill: " + (err?.response?.data || err.message)); setToastOpen(true); } finally { setLoading(false); } }; const runKevSync = async () => { try { setLoading(true); await api.post('/admin/scripts/fetch-kev'); setKevVisible(true); setToastMessage('✅ KEV sync started.'); setToastOpen(true); } catch (err: any) { setToastMessage("❌ Failed to sync KEVs: " + (err?.response?.data || err.message)); setToastOpen(true); } finally { setLoading(false); } }; const runMsrcSync = async () => { try { setLoading(true); await api.post('/admin/scripts/fetch-msrc'); setMsrcVisible(true); setToastMessage('✅ MSRC sync started.'); setToastOpen(true); } catch (err: any) { setToastMessage("❌ Failed to fetch Microsoft CVEs: " + (err?.response?.data || err.message)); setToastOpen(true); } finally { setLoading(false); } }; const runVulnCacheRefresh = async () => { try { setLoading(true); const res = await api.post('/admin/vulns/refresh-cache'); setToastMessage(res.data); setToastOpen(true); } catch (err: any) { setToastMessage("❌ Failed to refresh vulnerability cache: " + (err?.response?.data || err.message)); setToastOpen(true); } finally { setLoading(false); } }; const refreshSoftwareCache = async () => { try { setLoading(true); const res = await api.post('/admin/software/refresh-cache'); setToastMessage(res.data); setToastOpen(true); } catch (err: any) { setToastMessage("❌ Failed to refresh installed software cache: " + (err?.response?.data || err.message)); setToastOpen(true); } finally { setLoading(false); } }; const refreshStatistics = async () => { try { setLoading(true); await api.post('/admin/statistics/refresh'); setToastMessage('✅ CVE Statistics refreshed.'); setToastOpen(true); } catch (err: any) { setToastMessage("❌ Failed to refresh statistics: " + (err?.response?.data || err.message)); setToastOpen(true); } finally { setLoading(false); } }; const normalizeSoftware = async () => { try { setLoading(true); const res = await api.post('/admin/software/normalize'); setToastMessage(res.data); setToastOpen(true); } catch (err: any) { setToastMessage("❌ Failed to normalize software entries: " + (err?.response?.data || err.message)); setToastOpen(true); } finally { setLoading(false); } }; const generateDemoDevice = async () => { const clientId = prompt("Enter clientId for the demo device:"); if (!clientId) return; try { setLoading(true); const res = await api.post('/system/devices/demo', { clientId: Number(clientId) }); setToastMessage(`✅ Demo device created: ${res.data.deviceId}`); } catch (err: any) { setToastMessage("❌ Failed to generate demo device: " + (err?.response?.data || err.message)); } finally { setLoading(false); setToastOpen(true); } }; const runCveVerification = async () => { try { setLoading(true); await api.post('/admin/scripts/verify-cve-count'); setCveVisible(true); setToastMessage('🔍 CVE verification started - check logs for comparison results'); setToastOpen(true); } catch (err: any) { setToastMessage("❌ Failed to start CVE verification: " + (err?.response?.data || err.message)); setToastOpen(true); } finally { setLoading(false); } }; const openDialog = async () => { await fetchClients(); setDialogOpen(true); }; return ( Admin Controls Accept pings: {pingEnabled === null ? ( ) : ( togglePing(e.target.checked)} /> )} {message && {message}} setToastOpen(false)} anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} > setToastOpen(false)} severity="info" sx={{ width: '100%' }} > {toastMessage} {/* Backfill Confirmation Dialog */} setBackfillDialogOpen(false)} maxWidth="sm" fullWidth > ⚠️ Confirm CVE Backfill This will download ALL CVEs from 2002 to present (~250,000 CVEs).

Expected runtime: 20-30 hours
API calls: ~8,000-10,000 requests

The process is resumable - if it stops, you can restart it and it will continue from where it left off.

Are you sure you want to proceed?
{/* Demo Device Dialog */} setDialogOpen(false)} maxWidth="xs" fullWidth> Select a Client Client
); }