Init commit

Signed-off-by: Andrea Pavone <info@andreapavone.com>
This commit is contained in:
2024-11-10 16:10:14 +01:00
parent b39a51c625
commit 0e18b53f91
71 changed files with 4358 additions and 2756 deletions

View File

@ -1,26 +1,204 @@
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
import { Head } from '@inertiajs/react';
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import {
Card,
CardContent,
CardHeader,
CardTitle,
CardDescription
} from '@/Components/ui/card';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/Components/ui/tabs';
import { Button } from "@/Components/ui/button";
import { Progress } from '@/Components/ui/progress';
import { Alert, AlertDescription, AlertTitle } from '@/Components/ui/alert';
import { ShieldAlert, Globe, Database, ChevronLeft, ChevronRight, Check, Copy } from 'lucide-react';
import Markdown from 'react-markdown';
import {
SecuritySummaryReportResultType, SecuritySummaryResponseType,
} from '@/types/security-summary';
import NumberOfVulnerabilitiesPieChart from "@/Components/NumberOfVulnerabilitiesPieChart";
import SecurityScoresOverviewBarChart from "@/Components/SecurityScoresOverviewBarChart";
import PortExposureAnalysis from "@/Components/PortExposureAnalysis";
import { useClipboard } from "use-clipboard-copy"
import DashboardHeader from "@/Components/DashboardHeader";
export default function Dashboard() {
return (
<AuthenticatedLayout
header={
<h2 className="text-xl font-semibold leading-tight text-gray-800">
Dashboard
</h2>
}
>
<Head title="Dashboard" />
const [securitySummaryResponse, setSecuritySummaryResponse] = useState<SecuritySummaryResponseType | null>(null);
const [reportData, setReportData] = useState<SecuritySummaryReportResultType | null>(null);
const [currentPage, setCurrentPage] = useState<number>(0);
<div className="py-12">
<div className="mx-auto max-w-7xl sm:px-6 lg:px-8">
<div className="overflow-hidden bg-white shadow-sm sm:rounded-lg">
<div className="p-6 text-gray-900">
You're logged in!
</div>
useEffect(() => {
axios.get<SecuritySummaryResponseType>('/api/v1/security/summary')
.then(response => {
setSecuritySummaryResponse(response.data);
// Set initial report data
setReportData(response.data.results[0] ?? null);
})
.catch(error => {
console.error("Error fetching the report data", error);
});
}, []);
// Handle page changes
useEffect(() => {
if (securitySummaryResponse) {
setReportData(securitySummaryResponse.results[currentPage] ?? null);
}
}, [currentPage, securitySummaryResponse]);
const handlePrevPage = () => {
setCurrentPage(prev => Math.max(0, prev - 1));
};
const handleNextPage = () => {
if (securitySummaryResponse) {
setCurrentPage(prev => Math.min(securitySummaryResponse.results.length - 1, prev + 1));
}
};
if (!reportData) return <div>Loading...</div>;
return (
<div className="container mx-auto p-4">
<DashboardHeader reportData={reportData} />
<Tabs defaultValue="overview" className="space-y-4">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="vulnerabilities">Vulnerabilities</TabsTrigger>
<TabsTrigger value="services">Exposed Services</TabsTrigger>
<TabsTrigger value="leaks">Data Leaks</TabsTrigger>
</TabsList>
<TabsContent value="overview">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<ShieldAlert className="w-5 h-5"/>
Vulnerability Score
</CardTitle>
<CardDescription>Active and passive vulnerability scores</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-2">
<div>
<div className="text-xs text-muted-foreground">Active Score</div>
<Progress value={reportData.vulnerability_score_active} className="mt-1"/>
<div className="text-sm font-medium">{reportData.vulnerability_score_active}%
</div>
</div>
<div>
<div className="text-xs text-muted-foreground">Passive Score</div>
<Progress value={reportData.vulnerability_score_passive} className="mt-1"/>
<div className="text-sm font-medium">{reportData.vulnerability_score_passive}%
</div>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Globe className="w-5 h-5"/>
Network Assets
</CardTitle>
<CardDescription>Total assets and IP addresses</CardDescription>
</CardHeader>
<CardContent>
<div className="text-3xl font-bold">{reportData.n_asset}</div>
<div className="flex justify-between text-xs text-muted-foreground mt-1">
<span>IPv4: {reportData.unique_ipv4}</span>
<span>IPv6: {reportData.unique_ipv6}</span>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Database className="w-5 h-5"/>
Data Leaks
</CardTitle>
<CardDescription>Unresolved data leak incidents</CardDescription>
</CardHeader>
<CardContent>
<div
className="text-3xl font-bold">{reportData.n_dataleak.unresolved.potential_stealer}</div>
<div className="text-xs text-muted-foreground mt-1">
Including {reportData.n_dataleak.unresolved.domain_stealer} domain stealer
and {reportData.n_dataleak.unresolved.other_stealer} other leaks
</div>
</CardContent>
</Card>
</div>
</div>
</div>
</AuthenticatedLayout>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-6">
<PortExposureAnalysis reportData={reportData}/>
<NumberOfVulnerabilitiesPieChart reportData={reportData}/>
</div>
<div className="grid grid-cols-1 gap-4 mt-6">
<SecurityScoresOverviewBarChart reportData={reportData}/>
</div>
<Card className="mt-6">
<Tabs defaultValue="lang-en">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<ShieldAlert className="h-5 w-5 text-red-500"/>
Security Summary
<TabsList>
<TabsTrigger value="lang-en">EN</TabsTrigger>
<TabsTrigger value="lang-it">IT</TabsTrigger>
</TabsList>
</CardTitle>
</CardHeader>
<CardContent>
<Alert variant="destructive">
<AlertDescription>
<TabsContent value="lang-en">
<Markdown>{reportData.summary_text_en}</Markdown>
</TabsContent>
<TabsContent value="lang-it">
<Markdown>{reportData.summary_text}</Markdown>
</TabsContent>
</AlertDescription>
</Alert>
</CardContent>
</Tabs>
</Card>
<div className="flex items-center justify-center gap-4 mt-6">
<Button
onClick={handlePrevPage}
disabled={currentPage === 0}
variant="outline"
className="flex items-center gap-2"
>
<ChevronLeft className="w-4 h-4"/>
Previous
</Button>
<div className="text-sm text-muted-foreground">
Page {currentPage + 1} of {securitySummaryResponse?.results.length}
</div>
<Button
onClick={handleNextPage}
disabled={!securitySummaryResponse || currentPage === securitySummaryResponse.results.length - 1}
variant="outline"
className="flex items-center gap-2"
>
Next
<ChevronRight className="w-4 h-4"/>
</Button>
</div>
</TabsContent>
</Tabs>
</div>
);
}
};