Added new backfill button for CVE sync.
Some checks failed
Deploy Frontend / deploy (push) Failing after 36s
Some checks failed
Deploy Frontend / deploy (push) Failing after 36s
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
|||||||
MenuItem,
|
MenuItem,
|
||||||
FormControl,
|
FormControl,
|
||||||
InputLabel,
|
InputLabel,
|
||||||
|
DialogContentText,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { SwitchTextTrack } from '@/components/SwitchTextTrack';
|
import { SwitchTextTrack } from '@/components/SwitchTextTrack';
|
||||||
import CVELogStream from '@/components/CVELogStream';
|
import CVELogStream from '@/components/CVELogStream';
|
||||||
@@ -34,6 +35,7 @@ export default function AdminControlsPanel() {
|
|||||||
const [clientList, setClientList] = useState<Array<{clientId: number;clientIdentifier: string;clientName: string;}>>([]);
|
const [clientList, setClientList] = useState<Array<{clientId: number;clientIdentifier: string;clientName: string;}>>([]);
|
||||||
const [selectedClientId, setSelectedClientId] = useState<number | null>(null);
|
const [selectedClientId, setSelectedClientId] = useState<number | null>(null);
|
||||||
const [dialogOpen, setDialogOpen] = useState(false);
|
const [dialogOpen, setDialogOpen] = useState(false);
|
||||||
|
const [backfillDialogOpen, setBackfillDialogOpen] = useState(false);
|
||||||
const [cveVisible, setCveVisible] = useState(false);
|
const [cveVisible, setCveVisible] = useState(false);
|
||||||
const [kevVisible, setKevVisible] = useState(false);
|
const [kevVisible, setKevVisible] = useState(false);
|
||||||
const [msrcVisible, setMsrcVisible] = useState(false);
|
const [msrcVisible, setMsrcVisible] = useState(false);
|
||||||
@@ -83,8 +85,8 @@ export default function AdminControlsPanel() {
|
|||||||
|
|
||||||
const fetchClients = async () => {
|
const fetchClients = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await api.get('/auth/clients'); // Adjust endpoint if needed
|
const res = await api.get('/auth/clients');
|
||||||
setClientList(res.data); // Expected: [{ clientId, name }]
|
setClientList(res.data);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to fetch clients', err);
|
console.error('Failed to fetch clients', err);
|
||||||
}
|
}
|
||||||
@@ -94,18 +96,35 @@ export default function AdminControlsPanel() {
|
|||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
await api.post('/admin/scripts/fetch-cve');
|
await api.post('/admin/scripts/fetch-cve');
|
||||||
setCveVisible(true); // 👈 Spawn CVE console
|
setCveVisible(true);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
alert("❌ Failed to start CVE sync: " + (err?.response?.data || err.message));
|
alert("❌ Failed to start CVE sync: " + (err?.response?.data || err.message));
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
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 () => {
|
const runKevSync = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
await api.post('/admin/scripts/fetch-kev');
|
await api.post('/admin/scripts/fetch-kev');
|
||||||
setKevVisible(true); // 👈 Spawn KEV console
|
setKevVisible(true);
|
||||||
setToastMessage('✅ KEV sync started.');
|
setToastMessage('✅ KEV sync started.');
|
||||||
setToastOpen(true);
|
setToastOpen(true);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
@@ -120,7 +139,7 @@ export default function AdminControlsPanel() {
|
|||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
await api.post('/admin/scripts/fetch-msrc');
|
await api.post('/admin/scripts/fetch-msrc');
|
||||||
setMsrcVisible(true); // 👈 Spawn MSRC console
|
setMsrcVisible(true);
|
||||||
setToastMessage('✅ MSRC sync started.');
|
setToastMessage('✅ MSRC sync started.');
|
||||||
setToastOpen(true);
|
setToastOpen(true);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
@@ -135,7 +154,7 @@ export default function AdminControlsPanel() {
|
|||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const res = await api.post('/admin/vulns/refresh-cache');
|
const res = await api.post('/admin/vulns/refresh-cache');
|
||||||
setToastMessage(res.data); // Show backend result in toast
|
setToastMessage(res.data);
|
||||||
setToastOpen(true);
|
setToastOpen(true);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
setToastMessage("❌ Failed to refresh vulnerability cache: " + (err?.response?.data || err.message));
|
setToastMessage("❌ Failed to refresh vulnerability cache: " + (err?.response?.data || err.message));
|
||||||
@@ -177,7 +196,7 @@ export default function AdminControlsPanel() {
|
|||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const res = await api.post('/admin/software/normalize');
|
const res = await api.post('/admin/software/normalize');
|
||||||
setToastMessage(res.data); // ✅ show result
|
setToastMessage(res.data);
|
||||||
setToastOpen(true);
|
setToastOpen(true);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
setToastMessage("❌ Failed to normalize software entries: " + (err?.response?.data || err.message));
|
setToastMessage("❌ Failed to normalize software entries: " + (err?.response?.data || err.message));
|
||||||
@@ -237,7 +256,17 @@ export default function AdminControlsPanel() {
|
|||||||
disabled={loading}
|
disabled={loading}
|
||||||
sx={{ mt: 2 }}
|
sx={{ mt: 2 }}
|
||||||
>
|
>
|
||||||
{loading ? 'Running Sync...' : 'Run CVE Sync'}
|
{loading ? 'Running Sync...' : 'Run CVE Sync (Last 30 Days)'}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="warning"
|
||||||
|
onClick={() => setBackfillDialogOpen(true)}
|
||||||
|
disabled={loading}
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
>
|
||||||
|
{loading ? 'Starting Backfill...' : 'Backfill All CVEs (2002-Present)'}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@@ -343,6 +372,44 @@ export default function AdminControlsPanel() {
|
|||||||
{toastMessage}
|
{toastMessage}
|
||||||
</Alert>
|
</Alert>
|
||||||
</Snackbar>
|
</Snackbar>
|
||||||
|
|
||||||
|
{/* Backfill Confirmation Dialog */}
|
||||||
|
<Dialog
|
||||||
|
open={backfillDialogOpen}
|
||||||
|
onClose={() => setBackfillDialogOpen(false)}
|
||||||
|
maxWidth="sm"
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
<DialogTitle>⚠️ Confirm CVE Backfill</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogContentText>
|
||||||
|
<strong>This will download ALL CVEs from 2002 to present (~250,000 CVEs).</strong>
|
||||||
|
<br /><br />
|
||||||
|
Expected runtime: <strong>20-30 hours</strong>
|
||||||
|
<br />
|
||||||
|
API calls: <strong>~8,000-10,000 requests</strong>
|
||||||
|
<br /><br />
|
||||||
|
The process is resumable - if it stops, you can restart it and it will continue from where it left off.
|
||||||
|
<br /><br />
|
||||||
|
Are you sure you want to proceed?
|
||||||
|
</DialogContentText>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={() => setBackfillDialogOpen(false)}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="warning"
|
||||||
|
onClick={runCveBackfill}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
Start Backfill
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
|
{/* Demo Device Dialog */}
|
||||||
<Dialog open={dialogOpen} onClose={() => setDialogOpen(false)} maxWidth="xs" fullWidth>
|
<Dialog open={dialogOpen} onClose={() => setDialogOpen(false)} maxWidth="xs" fullWidth>
|
||||||
<DialogTitle>Select a Client</DialogTitle>
|
<DialogTitle>Select a Client</DialogTitle>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
|
|||||||
Reference in New Issue
Block a user