Skip to content

Commit

Permalink
Cleanup final (#17)
Browse files Browse the repository at this point in the history
* Updates for docker

* Different vuln and component label

* Remove qualifiers if present

* Add support for Maven

* Remove unused code

* Clean unused variables and imports

* Add DepVis logo

* Add comments

* FIx issue with parsing

* Remove logging

* Vuln fetching

* Remove unused package

* Add SBOM

---------

Co-authored-by: Matej Groman <[email protected]>
  • Loading branch information
Matej4545 and Matej Groman authored May 12, 2023
1 parent 51ddb02 commit 0e7d67e
Show file tree
Hide file tree
Showing 63 changed files with 20,488 additions and 831 deletions.
1 change: 1 addition & 0 deletions docker-compose-azure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ services:
REDIS_PASSWORD: ${REDIS_PASSWORD:?error}
NEXT_PUBLIC_SONATYPE_OSS_AUTH: ${SONATYPE_OSS_AUTH}
NEXT_PUBLIC_SERVER_URI: ${NEXT_PUBLIC_SERVER_URI:-http://localhost:3000}
NEXT_PUBLIC_GRAPH_EXCLUDED_REGEX: ${GRAPH_EXCLUDED_REGEX:-" "}
VULN_DB: ${VULN_DB:-Sonatype}
CORS_ORIGIN: ${CORS_ORIGIN:-http://localhost:3000}
volumes:
Expand Down
8 changes: 5 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ services:
- 7474:7474
- 7687:7687
volumes:
- ./runtime/data:/data
- ./runtime/logs:/logs
- ./runtime/plugins:/var/lib/neo4j/plugins
- neo4j:/data
restart: unless-stopped
environment:
- NEO4J_AUTH=neo4j/${NEO4J_PASSWORD:?error}
Expand Down Expand Up @@ -48,7 +46,11 @@ services:
NEXT_PUBLIC_SONATYPE_OSS_AUTH: ${SONATYPE_OSS_AUTH}
NEXT_PUBLIC_SERVER_URI: ${NEXT_PUBLIC_SERVER_URI:-http://localhost:3000}
VULN_DB: ${VULN_DB:-Sonatype}
NEXT_PUBLIC_GRAPH_EXCLUDED_REGEX: ${GRAPH_EXCLUDED_REGEX:-" "}
CORS_ORIGIN: ${CORS_ORIGIN:-http://localhost:3000}
volumes:
cache:
driver: local
neo4j:
driver: local

10 changes: 2 additions & 8 deletions src/depvis-next/apollo/ApolloClient.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import {
ApolloClient,
createHttpLink,
InMemoryCache,
NormalizedCacheObject,
} from "@apollo/client";
import { GraphQLUri } from "./ApolloServer";
import { ApolloClient, createHttpLink, InMemoryCache } from "@apollo/client";
import { useMemo } from "react";
import urlJoin from "url-join";
import { GraphQLUri } from "./ApolloServer";

let httpApolloClient;
let ssrApolloClient;
Expand All @@ -26,7 +21,6 @@ const httpLink = createHttpLink({
});

const createHttpApolloClient = (ssr: boolean = false) => {
const link = ssr ? ssrHttpLink : httpLink;
console.log("Creating new Apollo Client (ssr: %s)", ssr);
return new ApolloClient({
ssrMode: ssr,
Expand Down
3 changes: 1 addition & 2 deletions src/depvis-next/apollo/ApolloServer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Driver } from "neo4j-driver";
import neo4j, { Driver } from "neo4j-driver";
import { env } from "process";
import neo4j from "neo4j-driver";

export const GraphQLUri = "/api/graphql";

Expand Down
10 changes: 10 additions & 0 deletions src/depvis-next/components/Details/DescriptionList.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { OverlayTrigger, Stack, Tooltip } from "react-bootstrap";

/**
* DataItem Wrapper
* @param props React children
* @returns
*/
const DL = (props) => {
return <dl>{props.children}</dl>;
};

/**
* Data Item which creates a text with label component
* @param props a props object containing label, value, alwaysShow, tooltipText, horizontal attributes
* @returns
*/
const DLItem = (props) => {
const { label, value, alwaysShow, tooltipText, horizontal } = props;
if (!label || (!alwaysShow && !value)) return;
Expand Down
10 changes: 1 addition & 9 deletions src/depvis-next/components/Details/Details.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
import { useState } from "react";
import {
Button,
Col,
Collapse,
Container,
Row,
Stack,
Table,
} from "react-bootstrap";
import { Button, Collapse, Stack, Table } from "react-bootstrap";

export default function Details(props) {
const [open, setOpen] = useState(false);
Expand Down
2 changes: 0 additions & 2 deletions src/depvis-next/components/Details/VulnerabilityDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { gql, useQuery } from "@apollo/client";
import Link from "next/link";
import { Badge, Container } from "react-bootstrap";
import urlJoin from "url-join";
import { vulnerabilityColorByCVSS } from "../../helpers/GraphHelper";
import Loading from "../Loading/Loading";
import { DL, DLItem } from "./DescriptionList";
Expand Down
4 changes: 2 additions & 2 deletions src/depvis-next/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { useState } from "react";
import { Container, Form } from "react-bootstrap";

export type DropdownItem = {
Expand All @@ -19,7 +19,7 @@ export default function Dropdown(props) {
<Form>
{title && <Form.Label>{title}</Form.Label>}
<Form.Select
value={selectedId && selectedId}
value={selectedId}
disabled={disabled}
onChange={(e) => {
setSelectedId(e.target.value);
Expand Down
8 changes: 3 additions & 5 deletions src/depvis-next/components/Error/GenericError.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import Link from 'next/link';
import { useRouter } from 'next/router';
import { Container } from 'react-bootstrap';
import Link from "next/link";
import { Container } from "react-bootstrap";

export default function GenericError(props) {
const router = useRouter();
return (
<Container className="mx-auto my-5 text-center">
<p className="fs-4 fw-bold">{props.error.message || 'Error occured!'}</p>
<p className="fs-4 fw-bold">{props.error.message || "Error occured!"}</p>
<pre>{JSON.stringify(props.error)}</pre>
<Link href="/">Go to homepage</Link>
</Container>
Expand Down
2 changes: 1 addition & 1 deletion src/depvis-next/components/Error/NoProjectFoundError.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Link from "next/link";
import { Button, Container } from "react-bootstrap";

export default function NoProjectFoundError(props) {
export default function NoProjectFoundError() {
return (
<Container className="mx-auto my-5 text-center">
<p className="fs-4 fw-bold">No project found!</p>
Expand Down
5 changes: 5 additions & 0 deletions src/depvis-next/components/Graph/GraphFloatControl.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* Responsible for the position of graph overlay control button stack
* @param props children
* @returns
*/
const GraphFloatControl = (props) => {
return (
<div className="graph-float-container">
Expand Down
12 changes: 6 additions & 6 deletions src/depvis-next/components/Graph/NoSSRGraph.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { forceCollide, forceManyBody, forceX, forceY } from "d3-force";
import { useEffect, useRef, useState } from "react";
import ReactForceGraph2d, { ForceGraphMethods } from "react-force-graph-2d";
import GraphFloatControl from "./GraphFloatControl";
import { Button } from "react-bootstrap";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faEarth,
faLocationCrosshairs,
faMagnifyingGlassMinus,
faMagnifyingGlassPlus,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { forceCollide, forceManyBody, forceX, forceY } from "d3-force";
import { useEffect, useRef, useState } from "react";
import { Button } from "react-bootstrap";
import ReactForceGraph2d, { ForceGraphMethods } from "react-force-graph-2d";
import GraphFloatControl from "./GraphFloatControl";

export default function NoSSRGraph(props) {
const graphRef = useRef<ForceGraphMethods>();
Expand Down
7 changes: 5 additions & 2 deletions src/depvis-next/components/Graph/NoSSRGraphWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import dynamic from 'next/dynamic';
/**
* Wrapper for react-force-graph - workaround for Next.js SSR rendering
*/
import dynamic from "next/dynamic";

const NoSSRGraphWrapper = dynamic(() => import('./NoSSRGraph'), { ssr: false });
const NoSSRGraphWrapper = dynamic(() => import("./NoSSRGraph"), { ssr: false });

export default NoSSRGraphWrapper;
22 changes: 22 additions & 0 deletions src/depvis-next/components/GraphControl/GraphControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ const GraphControl = (props) => {

const [graphConfig, setGraphConfig] =
useState<GraphConfig>(defaultGraphConfig);
const [vulnFetch, setVulnFetch] = useState(false);

//Callback to parent component when the config change
useEffect(() => {
props.onGraphConfigChange(graphConfig);
}, [graphConfig]);

const handleNodeValToggle = (e) => {
e.preventDefault();
if (typeof graphConfig.nodeVal === "function") {
setGraphConfig({ ...graphConfig, nodeVal: 1 });
} else {
Expand All @@ -29,18 +32,27 @@ const GraphControl = (props) => {
};

const handleShowOnlyVulnerableToggle = (e) => {
e.preventDefault();
setGraphConfig({
...graphConfig,
showOnlyVulnerable: !graphConfig.showOnlyVulnerable,
});
};

const handleShowConnectNodesToRoot = (e) => {
e.preventDefault();
setGraphConfig({
...graphConfig,
connectNodesToRoot: !graphConfig.connectNodesToRoot,
});
};
async function onRefetchVulnsClick() {
setVulnFetch(true);
fetch("/api/vuln").then(() => {
setVulnFetch(false);
});
}

return (
<Container id="control" className="px-0">
<Stack direction="horizontal">
Expand Down Expand Up @@ -154,6 +166,16 @@ const GraphControl = (props) => {
>
Refetch graph
</Button>
<Button
onClick={() => {
onRefetchVulnsClick();
}}
disabled={vulnFetch}
>
{vulnFetch
? "Fetching..."
: "Refetch vulnerabilities for all components"}
</Button>
</Stack>
</Container>
);
Expand Down
40 changes: 10 additions & 30 deletions src/depvis-next/components/Import/ImportForm.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import { faCheck, faX } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useState } from "react";
import { Alert, Button, Container, Form, Row } from "react-bootstrap";
import { Alert, Button, Form, Row } from "react-bootstrap";
import {
allowedExtensionsRegex,
projectStats,
tryParseFile,
} from "../../helpers/ImportFormHelper";
import { ImportFormData } from "./types";
import { parseXml } from "../../helpers/xmlParserHelper";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCheck, faX } from "@fortawesome/free-solid-svg-icons";

const allowedExtensionsRegex = /(\.xml)$/i;

interface projectStats {
componentsCount: number;
dependenciesCount: number;
error: boolean;
}

const ImportForm = (props) => {
const { onSubmitCallback } = props;
Expand All @@ -21,8 +17,10 @@ const ImportForm = (props) => {
const [projectName, setProjectName] = useState<string>("");
const [projectVersion, setProjectVersion] = useState<string>("1.0.0");
const [projectStats, setProjectStats] = useState<projectStats>(undefined);

const handleFiles = async (e: any) => {
const files = e.target.files;
// Check if there is some issue with the file
if (!files || !files[0] || !allowedExtensionsRegex.exec(files[0].name)) {
setFile(undefined);
setValidated(true);
Expand All @@ -34,24 +32,6 @@ const ImportForm = (props) => {
setFile(file);
};

const tryParseFile = async (fileXml): Promise<projectStats> => {
try {
const parsedXml = await parseXml(fileXml);
const dependencies =
parsedXml.bom.dependencies &&
parsedXml.bom.dependencies.dependency
.map((d) => (d.dependency ? d.dependency.length : 0))
.reduce((sum, current) => sum + current, 0);
console.log(dependencies);
return {
componentsCount: parsedXml.bom.components.component.length,
dependenciesCount: dependencies,
error: false,
};
} catch {
return { componentsCount: 0, dependenciesCount: 0, error: true };
}
};
const handleSubmit = async (e: any) => {
e.preventDefault();
const form = e.currentTarget;
Expand Down
2 changes: 1 addition & 1 deletion src/depvis-next/components/Import/ImportResult.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import { Alert, Container, ProgressBar, Row, Spinner } from "react-bootstrap";
import { Alert, Container, ProgressBar, Row } from "react-bootstrap";
import { ImportStatusReponse } from "../../pages/api/import/status";

const fetchInterval = 500;
Expand Down
2 changes: 1 addition & 1 deletion src/depvis-next/components/Layout/GraphContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useEffect, useRef, useState } from "react";
import { Col, Container } from "react-bootstrap";
import GraphError from "../Error/GraphError";
import { GraphConfig } from "../Graph/GraphConfig";
import NoSSRGraphWrapper from "../Graph/NoSSRGraphWrapper";
import Loading from "../Loading/Loading";
import GraphError from "../Error/GraphError";
const GraphContainer = (props) => {
const [graphDimensions, setGraphDimensions] = useState({
width: 0,
Expand Down
3 changes: 1 addition & 2 deletions src/depvis-next/components/Layout/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Container } from 'react-bootstrap';
import MainNavBar from '../NavBar/MainNavBar';
import MainNavBar from "../NavBar/MainNavBar";

export const Layout = (props: any) => {
return (
Expand Down
4 changes: 2 additions & 2 deletions src/depvis-next/components/Layout/NodeDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Container } from 'react-bootstrap';
import Details from '../Details/Details';
import { Container } from "react-bootstrap";
import Details from "../Details/Details";

export default function NodeDetail(props) {
const node = { name: props.name, ...props };
Expand Down
13 changes: 11 additions & 2 deletions src/depvis-next/components/NavBar/MainNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { useRouter } from "next/router";
import { Button } from "react-bootstrap";
import Container from "react-bootstrap/Container";
import Nav from "react-bootstrap/Nav";
import Navbar from "react-bootstrap/Navbar";
import NavDropdown from "react-bootstrap/NavDropdown";
import Navbar from "react-bootstrap/Navbar";
import { DeleteAllData } from "../../helpers/DbDataHelper";
const MainNavbar = () => {
const router = useRouter();
Expand All @@ -17,7 +17,16 @@ const MainNavbar = () => {
<Navbar bg="dark" expand="lg" variant="dark">
<Container>
<Link href="/" passHref>
<Navbar.Brand>DepVis</Navbar.Brand>
<Navbar.Brand>
<img
src="/depvis.png"
width="30"
height="30"
className="d-inline-block align-top"
alt="React Bootstrap logo"
/>{" "}
DepVis
</Navbar.Brand>
</Link>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse className="justify-content-end">
Expand Down
8 changes: 1 addition & 7 deletions src/depvis-next/components/Search/Search.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import React, { useState } from "react";
import { useState } from "react";
import { Button, Container, Dropdown, Form } from "react-bootstrap";
import DropdownContext from "react-bootstrap/esm/DropdownContext";
import DropdownItem from "react-bootstrap/esm/DropdownItem";

const SearchComponent = (props) => {
const [searchValue, setSearchValue] = useState("");
Expand All @@ -11,10 +9,6 @@ const SearchComponent = (props) => {
setSearchValue(e.target.value);
};

// const resetInputField = () => {
// setSearchValue('');
// };

const callSearchFunction = (e) => {
e.preventDefault();
const { objects } = props;
Expand Down
Loading

0 comments on commit 0e7d67e

Please sign in to comment.