types#Vulnerability TypeScript Examples
The following examples show how to use
types#Vulnerability.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: columns.tsx From crossfeed with Creative Commons Zero v1.0 Universal | 6 votes |
createGroupedColumns = () =>
[
{
Header: 'Vulnerability',
accessor: 'title',
Cell: ({ value, row }: CellProps<Vulnerability>) =>
row.original.cve ? (
<a
href={`https://nvd.nist.gov/vuln/detail/${row.original.cve}`}
target="_blank"
rel="noopener noreferrer"
>
{value} {extLink}
</a>
) : (
<p>{row.original.title}</p>
),
width: 800,
Filter: ColumnFilter
},
{
Header: 'Severity',
id: 'severity',
accessor: ({ severity }) => (
<span
style={{
borderBottom: `6px solid ${getSeverityColor({
id: severity ?? ''
})}`,
width: '80px'
}}
>
{severity}
</span>
),
width: 100,
Filter: selectFilter(['Low', 'Medium', 'High', 'Critical', 'None'])
},
{
Header: 'Count',
accessor: 'cnt',
disableFilters: true
},
{
Header: 'Description',
accessor: 'description',
disableFilters: true
}
] as Column<Vulnerability>[]
Example #2
Source File: Dashboard.tsx From crossfeed with Creative Commons Zero v1.0 Universal | 4 votes |
DashboardUI: React.FC<ContextType & { location: any }> = (
props
) => {
const {
current,
setCurrent,
resultsPerPage,
setResultsPerPage,
filters,
addFilter,
removeFilter,
results,
facets,
clearFilters,
sortDirection,
sortField,
setSort,
totalPages,
totalResults,
setSearchTerm,
searchTerm,
noResults
} = props;
const classes = useStyles();
const [selectedDomain, setSelectedDomain] = useState('');
const [resultsScrolled, setResultsScrolled] = useState(false);
const {
apiPost,
apiPut,
setLoading,
showAllOrganizations,
currentOrganization
} = useAuthContext();
const search:
| (SavedSearch & {
editing?: boolean;
})
| undefined = localStorage.getItem('savedSearch')
? JSON.parse(localStorage.getItem('savedSearch')!)
: undefined;
const [showSaveSearch, setShowSaveSearch] = useState<Boolean>(
search && search.editing ? true : false
);
const [savedSearchValues, setSavedSearchValues] = useState<
Partial<SavedSearch> & {
name: string;
vulnerabilityTemplate: Partial<Vulnerability>;
}
>(
search
? search
: {
name: '',
vulnerabilityTemplate: {},
createVulnerabilities: false
}
);
const onTextChange: React.ChangeEventHandler<
HTMLInputElement | HTMLSelectElement
> = (e) => onChange(e.target.name, e.target.value);
const onChange = (name: string, value: any) => {
setSavedSearchValues((values) => ({
...values,
[name]: value
}));
};
const onVulnerabilityTemplateChange = (e: any) => {
(savedSearchValues.vulnerabilityTemplate as any)[e.target.name] =
e.target.value;
setSavedSearchValues(savedSearchValues);
};
const handleResultScroll = (e: React.UIEvent<HTMLElement>) => {
if (e.currentTarget.scrollTop > 0) {
setResultsScrolled(true);
} else {
setResultsScrolled(false);
}
};
useEffect(() => {
if (props.location.search === '') {
// Search on initial load
setSearchTerm('');
}
return () => {
localStorage.removeItem('savedSearch');
};
}, [setSearchTerm, props.location.search]);
useBeforeunload((event) => {
localStorage.removeItem('savedSearch');
});
const fetchDomainsExport = async (): Promise<string> => {
try {
const body: any = {
current,
filters,
resultsPerPage,
searchTerm,
sortDirection,
sortField
};
if (!showAllOrganizations && currentOrganization) {
if ('rootDomains' in currentOrganization)
body.organizationId = currentOrganization.id;
else body.tagId = currentOrganization.id;
}
const { url } = await apiPost('/search/export', {
body
});
return url!;
} catch (e) {
console.error(e);
return '';
}
};
return (
<div className={classes.root}>
<FilterDrawer
addFilter={addFilter}
removeFilter={removeFilter}
filters={filters}
facets={facets}
clearFilters={filters.length > 0 ? () => clearFilters([]) : undefined}
/>
<div className={classes.contentWrapper}>
<Subnav
items={[
{ title: 'Search Results', path: '/inventory', exact: true },
{ title: 'All Domains', path: '/inventory/domains' },
{ title: 'All Vulnerabilities', path: '/inventory/vulnerabilities' }
]}
styles={{
paddingLeft: '0%'
}}
>
<FilterTags filters={filters} removeFilter={removeFilter} />
</Subnav>
<SortBar
sortField={sortField}
sortDirection={sortDirection}
setSort={setSort}
isFixed={resultsScrolled}
saveSearch={
filters.length > 0 || searchTerm
? () => setShowSaveSearch(true)
: undefined
}
existingSavedSearch={search}
/>
{noResults && (
<NoResults
message={"We don't see any results that match your criteria."}
></NoResults>
)}
<div className={classes.content}>
<div className={classes.panel} onScroll={handleResultScroll}>
{results.map((result) => (
<ResultCard
key={result.id.raw}
{...result}
onDomainSelected={(id) => setSelectedDomain(id)}
selected={result.id.raw === selectedDomain}
/>
))}
</div>
<div className={classes.panel}>
{selectedDomain && <DomainDetails domainId={selectedDomain} />}
</div>
</div>
<Paper classes={{ root: classes.pagination }}>
<span>
<strong>
{(totalResults === 0
? 0
: (current - 1) * resultsPerPage + 1
).toLocaleString()}{' '}
-{' '}
{Math.min(
(current - 1) * resultsPerPage + resultsPerPage,
totalResults
).toLocaleString()}
</strong>{' '}
of <strong>{totalResults.toLocaleString()}</strong>
</span>
<Pagination
count={totalPages}
page={current}
onChange={(_, page) => setCurrent(page)}
color="primary"
size="small"
/>
<FormControl
variant="outlined"
className={classes.pageSize}
size="small"
>
<Typography id="results-per-page-label">
Results per page:
</Typography>
<Select
id="teststa"
labelId="results-per-page-label"
value={resultsPerPage}
onChange={(e) => setResultsPerPage(e.target.value as number)}
>
{[15, 45, 90].map((perPage) => (
<MenuItem key={perPage} value={perPage}>
{perPage}
</MenuItem>
))}
</Select>
</FormControl>
<USWDSButton
className={classes.exportButton}
outline
type="button"
onClick={() =>
exportCSV(
{
name: 'domains',
getDataToExport: fetchDomainsExport
},
setLoading
)
}
>
Export Results
</USWDSButton>
</Paper>
</div>
{showSaveSearch && (
<div>
<Overlay />
<ModalContainer>
<Modal
className={classes.saveSearchModal}
actions={
<>
<USWDSButton
outline
type="button"
onClick={() => {
setShowSaveSearch(false);
}}
>
Cancel
</USWDSButton>
<USWDSButton
type="button"
onClick={async () => {
const body = {
body: {
...savedSearchValues,
searchTerm,
filters,
count: totalResults,
searchPath: window.location.search,
sortField,
sortDirection
}
};
if (search) {
await apiPut('/saved-searches/' + search.id, body);
} else {
await apiPost('/saved-searches/', body);
}
setShowSaveSearch(false);
}}
>
Save
</USWDSButton>
</>
}
title={search ? <h2>Update Search</h2> : <h2>Save Search</h2>}
>
<FormGroup>
<Label htmlFor="name">Name Your Search</Label>
<TextInput
required
id="name"
name="name"
type="text"
value={savedSearchValues.name}
onChange={onTextChange}
/>
<p>When a new result is found:</p>
{/* <FormControlLabel
control={
<Checkbox
// checked={gilad}
// onChange={handleChange}
name="email"
/>
}
label="Email me"
/> */}
<FormControlLabel
control={
<Checkbox
checked={savedSearchValues.createVulnerabilities}
onChange={(e) =>
onChange(e.target.name, e.target.checked)
}
id="createVulnerabilities"
name="createVulnerabilities"
/>
}
label="Create a vulnerability"
/>
{savedSearchValues.createVulnerabilities && (
<>
<Label htmlFor="title">Title</Label>
<TextInput
required
id="title"
name="title"
type="text"
value={savedSearchValues.vulnerabilityTemplate.title}
onChange={onVulnerabilityTemplateChange}
/>
<Label htmlFor="description">Description</Label>
<TextareaAutosize
required
id="description"
name="description"
style={{ padding: 10 }}
rowsMin={2}
value={
savedSearchValues.vulnerabilityTemplate.description
}
onChange={onVulnerabilityTemplateChange}
/>
<Label htmlFor="description">Severity</Label>
<Dropdown
id="severity"
name="severity"
onChange={onVulnerabilityTemplateChange}
value={
savedSearchValues.vulnerabilityTemplate
.severity as string
}
style={{ display: 'inline-block', width: '150px' }}
>
<option value="None">None</option>
<option value="Low">Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
<option value="Critical">Critical</option>
</Dropdown>
</>
)}
{/* <h3>Collaborators</h3>
<p>
Collaborators can view vulnerabilities, and domains within
this search. Adding a team will make all members
collaborators.
</p>
<button className={classes.addButton} >
<AddCircleOutline></AddCircleOutline> ADD
</button> */}
</FormGroup>
</Modal>
</ModalContainer>
</div>
)}
</div>
);
}
Example #3
Source File: Vulnerabilities.tsx From crossfeed with Creative Commons Zero v1.0 Universal | 4 votes |
Vulnerabilities: React.FC<{ groupBy?: string }> = ({
groupBy = undefined
}: {
children?: React.ReactNode;
groupBy?: string;
}) => {
const {
currentOrganization,
apiPost,
apiPut,
showAllOrganizations
} = useAuthContext();
const [vulnerabilities, setVulnerabilities] = useState<Vulnerability[]>([]);
const [totalResults, setTotalResults] = useState(0);
const tableRef = useRef<TableInstance<Vulnerability>>(null);
const listClasses = useStyles();
const [noResults, setNoResults] = useState(false);
const updateVulnerability = useCallback(
async (index: number, body: { [key: string]: string }) => {
try {
const res = await apiPut<Vulnerability>(
'/vulnerabilities/' + vulnerabilities[index].id,
{
body: body
}
);
const vulnCopy = [...vulnerabilities];
vulnCopy[index].state = res.state;
vulnCopy[index].substate = res.substate;
vulnCopy[index].actions = res.actions;
setVulnerabilities(vulnCopy);
} catch (e) {
console.error(e);
}
},
[setVulnerabilities, apiPut, vulnerabilities]
);
const columns = useMemo(() => createColumns(updateVulnerability), [
updateVulnerability
]);
const groupedColumns = useMemo(() => createGroupedColumns(), []);
const vulnerabilitiesSearch = useCallback(
async ({
filters,
sort,
page,
pageSize = PAGE_SIZE,
doExport = false,
groupBy = undefined
}: {
filters: Filters<Vulnerability>;
sort: SortingRule<Vulnerability>[];
page: number;
pageSize?: number;
doExport?: boolean;
groupBy?: string;
}): Promise<ApiResponse | undefined> => {
try {
const tableFilters: {
[key: string]: string | boolean | undefined;
} = filters
.filter((f) => Boolean(f.value))
.reduce(
(accum, next) => ({
...accum,
[next.id]: next.value
}),
{}
);
// If not open or closed, substitute for appropriate substate
if (
tableFilters['state'] &&
!['open', 'closed'].includes(tableFilters['state'] as string)
) {
const substate = (tableFilters['state'] as string)
.match(/\((.*)\)/)
?.pop();
if (substate)
tableFilters['substate'] = substate.toLowerCase().replace(' ', '-');
delete tableFilters['state'];
}
if (!showAllOrganizations && currentOrganization) {
if ('rootDomains' in currentOrganization)
tableFilters['organization'] = currentOrganization.id;
else tableFilters['tag'] = currentOrganization.id;
}
if (tableFilters['isKev']) {
// Convert string to boolean filter.
tableFilters['isKev'] = tableFilters['isKev'] === 'true';
}
return await apiPost<ApiResponse>(
doExport ? '/vulnerabilities/export' : '/vulnerabilities/search',
{
body: {
page,
sort: sort[0]?.id ?? 'createdAt',
order: sort[0]?.desc ? 'DESC' : 'ASC',
filters: tableFilters,
pageSize,
groupBy
}
}
);
} catch (e) {
console.error(e);
return;
}
},
[apiPost, currentOrganization, showAllOrganizations]
);
const fetchVulnerabilities = useCallback(
async (query: Query<Vulnerability>) => {
const resp = await vulnerabilitiesSearch({
filters: query.filters,
sort: query.sort,
page: query.page,
groupBy
});
if (!resp) return;
const { result, count } = resp;
setVulnerabilities(result);
setTotalResults(count);
setNoResults(count === 0);
},
[vulnerabilitiesSearch, groupBy]
);
const fetchVulnerabilitiesExport = async (): Promise<string> => {
const { sortBy, filters } = tableRef.current?.state ?? {};
const { url } = (await vulnerabilitiesSearch({
filters: filters!,
sort: sortBy!,
page: 1,
pageSize: -1,
doExport: true
})) as ApiResponse;
return url!;
};
const renderPagination = (table: TableInstance<Vulnerability>) => (
<Paginator
table={table}
totalResults={totalResults}
export={{
name: 'vulnerabilities',
getDataToExport: fetchVulnerabilitiesExport
}}
/>
);
const initialFilterBy: Filters<Vulnerability> = [];
let initialSortBy: SortingRule<Vulnerability>[] = [];
const params = parse(window.location.search);
if (!('state' in params)) params['state'] = 'open';
for (const param of Object.keys(params)) {
if (param === 'sort') {
initialSortBy = [
{
id: params[param] as string,
desc: 'desc' in params ? params['desc'] === 'true' : true
}
];
} else if (param !== 'desc') {
initialFilterBy.push({
id: param,
value: params[param] as string
});
}
}
return (
<div>
<div className={listClasses.contentWrapper}>
<Subnav
items={[
{ title: 'Search Results', path: '/inventory', exact: true },
{ title: 'All Domains', path: '/inventory/domains' },
{ title: 'All Vulnerabilities', path: '/inventory/vulnerabilities' }
]}
></Subnav>
<br></br>
<div className={classes.root}>
<Table<Vulnerability>
renderPagination={renderPagination}
columns={groupBy ? groupedColumns : columns}
data={vulnerabilities}
pageCount={Math.ceil(totalResults / PAGE_SIZE)}
fetchData={fetchVulnerabilities}
tableRef={tableRef}
initialFilterBy={initialFilterBy}
initialSortBy={initialSortBy}
noResults={noResults}
pageSize={PAGE_SIZE}
noResultsMessage={
"We don't see any vulnerabilities that match your criteria."
}
/>
</div>
</div>
</div>
);
}
Example #4
Source File: columns.tsx From crossfeed with Creative Commons Zero v1.0 Universal | 4 votes |
createColumns = (updateVulnerability: any) =>
[
{
Header: 'Vulnerability',
accessor: 'title',
Cell: ({ value, row }: CellProps<Vulnerability>) =>
row.original.cve ? (
<a
href={`https://nvd.nist.gov/vuln/detail/${row.original.cve}`}
target="_blank"
rel="noopener noreferrer"
>
{value} {extLink}
</a>
) : (
<p>{row.original.title}</p>
),
width: 800,
Filter: ColumnFilter
},
{
Header: 'Severity',
id: 'severity',
accessor: ({ severity, substate }) => (
<span
style={{
borderBottom: `6px solid ${getSeverityColor({
id: severity ?? ''
})}`,
width: '80px'
}}
// className={substate === 'unconfirmed' ? classes.severity : undefined}
>
{severity}
</span>
),
width: 100,
Filter: selectFilter(['Low', 'Medium', 'High', 'Critical', 'None'])
},
{
Header: 'KEV',
accessor: 'isKev',
Cell: ({ value, row }: CellProps<Vulnerability>) =>
value ? (
<a
href={`https://www.cisa.gov/known-exploited-vulnerabilities-catalog`}
target="_blank"
rel="noopener noreferrer"
>
Yes {extLink}
</a>
) : (
<p>No</p>
),
width: 50,
Filter: selectFilter([
{ value: 'true', label: 'Yes' },
{ value: 'false', label: 'No' }
])
},
{
Header: 'Domain',
id: 'domain',
accessor: ({ domain }) => (
<Link to={`/inventory/domain/${domain?.id}`}>{domain?.name}</Link>
),
width: 800,
Filter: ColumnFilter
},
{
Header: 'Product',
id: 'cpe',
accessor: ({ cpe, service }) => {
const product =
service &&
service.products.find(
(product) => cpe && product.cpe && cpe.includes(product.cpe)
);
if (product)
return product.name + (product.version ? ' ' + product.version : '');
else return cpe;
},
width: 100,
Filter: ColumnFilter
},
{
Header: 'Days Open',
id: 'createdAt',
accessor: ({ createdAt, actions = [] }) => {
// Calculates the total number of days a vulnerability has been open
let daysOpen = 0;
let lastOpenDate = createdAt;
let lastState = 'open';
actions.reverse();
for (const action of actions) {
if (action.state === 'closed' && lastState === 'open') {
daysOpen += differenceInCalendarDays(
parseISO(action.date),
parseISO(lastOpenDate)
);
lastState = 'closed';
} else if (action.state === 'open' && lastState === 'closed') {
lastOpenDate = action.date;
lastState = 'open';
}
}
if (lastState === 'open') {
daysOpen += differenceInCalendarDays(
new Date(),
parseISO(lastOpenDate)
);
}
return daysOpen;
},
disableFilters: true
},
{
Header: 'Status',
id: 'state',
width: 100,
maxWidth: 200,
accessor: 'state',
Filter: selectFilter([
'open',
'open (unconfirmed)',
'open (exploitable)',
'closed',
'closed (false positive)',
'closed (accepted risk)',
'closed (remediated)'
]),
Cell: ({ row }: CellProps<Vulnerability>) => (
<Dropdown
id="state-dropdown"
name="state-dropdown"
onChange={(e) => {
updateVulnerability(row.index, {
substate: e.target.value
});
}}
value={row.original.substate}
style={{ display: 'inline-block', width: '200px' }}
>
<option value="unconfirmed">Open (Unconfirmed)</option>
<option value="exploitable">Open (Exploitable)</option>
<option value="false-positive">Closed (False Positive)</option>
<option value="accepted-risk">Closed (Accepted Risk)</option>
<option value="remediated">Closed (Remediated)</option>
</Dropdown>
)
},
{
Header: 'Details',
Cell: ({ row }: CellProps<Vulnerability>) => (
<Link
to={`/inventory/vulnerability/${row.original.id}`}
style={{
fontSize: '14px',
cursor: 'pointer',
color: '#484D51',
textDecoration: 'none'
}}
>
DETAILS
</Link>
),
disableFilters: true
}
] as Column<Vulnerability>[]