File size: 3,814 Bytes
56b6519
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable import/extensions */
import { ArcElement, Chart as ChartJS, Legend, Tooltip } from 'chart.js';
import { t } from 'i18next';
import React, { useEffect, useState } from 'react';
import { Pie } from 'react-chartjs-2';
import { useParams } from 'react-router-dom';

import { cvssStringToSeverity } from '@/lib/utils';
import { getAuditById } from '@/services/audits';

ChartJS.register(ArcElement, Tooltip, Legend);

type CVSSScoreProps = {
  auditId?: string;
};

const CVSSScore: React.FC<CVSSScoreProps> = ({ auditId }) => {
  const paramId = useParams().auditId;
  if (!auditId) {
    auditId = paramId;
  }
  const [pieChartData, setPieChartData] = useState({
    labels: [
      t('critical'),
      t('cvss.high'),
      t('cvss.medium'),
      t('cvss.low'),
      'Informative',
    ],
    datasets: [
      {
        data: [0, 0, 0, 0],
        backgroundColor: ['#FF4136', '#FF851B', '#FFDC00', '#2ECC40'],
        borderColor: ['#FF4136', '#FF851B', '#FFDC00', '#2ECC40'],
        borderWidth: 1,
      },
    ],
  });
  useEffect(() => {
    getAuditById(auditId)
      .then(audit => {
        setPieChartData({
          labels: [
            t('critical'),
            t('cvss.high'),
            t('cvss.medium'),
            t('cvss.low'),
            'Informative',
          ],
          datasets: [
            {
              data: [
                audit.datas.findings.filter(
                  finding => cvssStringToSeverity(finding.cvssv3 ?? '') === 'C',
                ).length,
                audit.datas.findings.filter(
                  finding => cvssStringToSeverity(finding.cvssv3 ?? '') === 'H',
                ).length,
                audit.datas.findings.filter(
                  finding => cvssStringToSeverity(finding.cvssv3 ?? '') === 'M',
                ).length,
                audit.datas.findings.filter(
                  finding => cvssStringToSeverity(finding.cvssv3 ?? '') === 'L',
                ).length,
                audit.datas.findings.filter(
                  finding => cvssStringToSeverity(finding.cvssv3 ?? '') === 'I',
                ).length,
              ],
              backgroundColor: [
                '#FF4136',
                '#FF851B',
                '#FFDC00',
                '#2ECC40',
                '#53AA33',
              ],
              borderColor: [
                '#FF4136',
                '#FF851B',
                '#FFDC00',
                '#2ECC40',
                '#53AA33',
              ],
              borderWidth: 1,
            },
          ],
        });
      })
      .catch(console.error);
  }, [auditId]);

  const pieChartOptions = {
    responsive: true,
    maintainAspectRatio: false,
    plugins: {
      legend: {
        position: 'right' as const,
        title: {
          display: true,
          text: t('filters'),
          color: 'white' as const,
          font: {
            weight: 'bold' as const,
            size: 15,
          },
        },
        labels: {
          color: 'white' as const,
        },
      },
      datalabels: {
        formatter: (value: number) => {
          let total = 0;
          pieChartData.datasets[0].data.forEach(d => {
            total += d;
          });
          const percentage = ((value / total) * 100).toFixed(2);
          if (percentage === '0.00' || percentage === 'NaN') {
            return '';
          }
          return percentage + '%';
        },
        color: '#eee' as const,
      },
    },
  };

  return (
    <div className="bg-gray-800 rounded-lg p-6">
      <div className="chart-container" style={{ height: '400px' }}>
        <Pie data={pieChartData} options={pieChartOptions} />
      </div>
    </div>
  );
};

export default CVSSScore;