diff --git a/frontend/src/components/AppFramework.jsx b/frontend/src/components/AppFramework.jsx
index 0d475b0d..39547697 100644
--- a/frontend/src/components/AppFramework.jsx
+++ b/frontend/src/components/AppFramework.jsx
@@ -21,6 +21,8 @@ import {
CircularProgress,
Tooltip,
Dialog,
+ Chip,
+ Avatar,
} from "@material-ui/core";
import {
@@ -38,10 +40,25 @@ import * as cytoscape from "cytoscape";
cytoscape.use(edgehandles);
-const svgSize = 23
+const svgSize = "40px"
const parsedDatatypeImages = {
- "Cases": encodeURI(`data:image/svg+xml;utf-8,`),
+ "SIEM": encodeURI(`data:image/svg+xml;utf-8,`),
+
+ "CASES": encodeURI(`data:image/svg+xml;utf-8,`),
+
"EDR & AV": encodeURI(`data:image/svg+xml;utf-8,`),
+
+ "INTEL": encodeURI(`data:image/svg+xml;utf-8,`),
+
+ "COMMS": encodeURI(`data:image/svg+xml;utf-8,`),
+
+ "NETWORK": encodeURI(`data:image/svg+xml;utf-8,`),
+
+ "INTEL": encodeURI(`data:image/svg+xml;utf-8,`),
+
+ "ASSETS": encodeURI(`data:image/svg+xml;utf-8,`),
+
+ "IAM": encodeURI(`data:image/svg+xml;utf-8,`),
}
export const usecases = {
@@ -541,6 +558,8 @@ const AppFramework = (props) => {
const [usecaseType, setUsecaseType] = React.useState(0)
const [selectedUsecase, setSelectedUsecase] = React.useState(selectedOption !== undefined ? selectedOption : "Phishing")
+ const [injectedApps, setInjectedApps] = React.useState([])
+
const scale = size === undefined ? 1 : size > 5 ? 3 : size
const alert = useAlert()
@@ -549,7 +568,20 @@ const AppFramework = (props) => {
console.log("Should check for next apps to load from App suggestion model")
//fetch(globalUrl + "/api/v1/workflows/usecases", {
//credentials: "include",
+ //cors: "no-cors",
+ const max_suggestions = 5
+ const max_per_category = 2
+ const priorities = {
+ "edr": 1,
+ "siem": 2,
+ "cases": 3,
+ "intel": 4,
+ "comms": 5,
+ }
+
+ // Based on apps recommended from repo https://github.com/Shuffle/app-recommender
+ //fetch("http://localhost:8080/app_recommendations", {
fetch("https://europe-west2-shuffler.cloudfunctions.net/app_recommendations", {
method: "POST",
headers: {
@@ -557,7 +589,6 @@ const AppFramework = (props) => {
Accept: "application/json",
},
body: JSON.stringify(frameworkData),
- cors: "no-cors",
})
.then((response) => {
//if (response.status !== 200) {
@@ -567,20 +598,36 @@ const AppFramework = (props) => {
return response.json();
})
.then((responseJson) => {
- console.log("Response: ", responseJson)
- //if (responseJson.success === false) {
- // if (responseJson.reason !== undefined) {
- // alert.error("Failed updating: " + responseJson.reason)
- // } else {
- // alert.error("Failed to update framework for your org.")
- // }
- //} else {
- // alert.info("Updated usecase.")
- //}
+ // Loop the response dict
+ var suggestions = []
+ var suggestion_cnt = 0
+ var category_count = {}
+ for (const [key, value] of Object.entries(responseJson)) {
+ if (suggestion_cnt >= max_suggestions) {
+ break
+ }
+
+ if (category_count[key] === undefined) {
+ category_count[key] = 1
+ } else {
+ category_count[key] += 1
+ }
+
+ if (category_count[key] > max_per_category) {
+ continue
+ }
+
+ //console.log("Found: " + key + " with value of len: " + value.length)
+
+ //suggestion_cnt += value.slice(0,1).length
+ suggestions.push(value.slice(0,1))
+ }
+
+ console.log("SUGG: ", suggestions)
+ setInjectedApps(suggestions)
})
.catch((error) => {
- //alert.error(error.toString());
- //setFrameworkLoaded(true)
+ console.log("Recommendation error: ", error);
})
}
@@ -1318,7 +1365,7 @@ const AppFramework = (props) => {
const baselocationY = 50*scale
const shiftmodifier = 3*scale
//const svgSize = `${40*scale}px`
- const svgSize = `${40}px`
+ //const svgSize = `${40}px`
const fontSize = `${12*scale}px`
const defaultSize = `${85*scale}px`
@@ -1343,9 +1390,8 @@ const AppFramework = (props) => {
margin_y: parsedFrameworkData.Cases.large_image === undefined ? `${19*scale}px` : `0px`,
width: parsedFrameworkData.Cases.large_image === undefined ? iconSize : defaultSize,
height: parsedFrameworkData.Cases.large_image === undefined ? iconSize : defaultSize,
- large_image: parsedFrameworkData.Cases.large_image === undefined ? encodeURI(`data:image/svg+xml;utf-8,`) : parsedFrameworkData.Cases.large_image,
+ large_image: parsedFrameworkData.Cases.large_image === undefined ? parsedDatatypeImages["CASES"] : parsedFrameworkData.Cases.large_image,
+
label: securityFramework[0].text.toUpperCase(),
id: securityFramework[0].text.toUpperCase(),
animate: true,
@@ -1372,9 +1418,8 @@ const AppFramework = (props) => {
margin_y: parsedFrameworkData.IAM.large_image === undefined ? `${19*scale}px` : `0px`,
width: parsedFrameworkData.IAM.large_image === undefined ? iconSize : defaultSize,
height: parsedFrameworkData.IAM.large_image === undefined ? iconSize : defaultSize,
- large_image: parsedFrameworkData.IAM.large_image === undefined ? encodeURI(`data:image/svg+xml;utf-8,`) : parsedFrameworkData.IAM.large_image,
+ large_image: parsedFrameworkData.IAM.large_image === undefined ? parsedDatatypeImages["IAM"] : parsedFrameworkData.IAM.large_image,
+
label: securityFramework[3].text.toUpperCase(),
id: securityFramework[3].text.toUpperCase(),
animate: false,
@@ -1401,9 +1446,8 @@ const AppFramework = (props) => {
margin_y: parsedFrameworkData.Assets.large_image === undefined ? `${19*scale}px` : `0px`,
width: parsedFrameworkData.Assets.large_image === undefined ? iconSize : defaultSize,
height: parsedFrameworkData.Assets.large_image === undefined ? iconSize : defaultSize,
- large_image: parsedFrameworkData.Assets.large_image === undefined ? encodeURI(`data:image/svg+xml;utf-8,`) : parsedFrameworkData.Assets.large_image,
+ large_image: parsedFrameworkData.Assets.large_image === undefined ? parsedDatatypeImages["ASSETS"] : parsedFrameworkData.Assets.large_image,
+
label: securityFramework[2].text.toUpperCase(),
id: securityFramework[2].text.toUpperCase(),
animate: false,
@@ -1430,9 +1474,8 @@ const AppFramework = (props) => {
margin_y: parsedFrameworkData.Intel.large_image === undefined ? `${19*scale}px` : `0px`,
width: parsedFrameworkData.Intel.large_image === undefined ? iconSize : defaultSize,
height: parsedFrameworkData.Intel.large_image === undefined ? iconSize : defaultSize,
- large_image: parsedFrameworkData.Intel.large_image === undefined ? encodeURI(`data:image/svg+xml;utf-8,`): parsedFrameworkData.Intel.large_image,
+ large_image: parsedFrameworkData.Intel.large_image === undefined ? parsedDatatypeImages["INTEL"] : parsedFrameworkData.Intel.large_image,
+
label: securityFramework[4].text.toUpperCase(),
id: securityFramework[4].text.toUpperCase(),
animate: false,
@@ -1459,9 +1502,8 @@ const AppFramework = (props) => {
margin_y: parsedFrameworkData.Comms.large_image === undefined ? `${19*scale}px` : `0px`,
width: parsedFrameworkData.Comms.large_image === undefined ? iconSize : defaultSize,
height: parsedFrameworkData.Comms.large_image === undefined ? iconSize : defaultSize,
- large_image: parsedFrameworkData.Comms.large_image === undefined ? encodeURI(`data:image/svg+xml;utf-8,`) : parsedFrameworkData.Comms.large_image,
+ large_image: parsedFrameworkData.Comms.large_image === undefined ? parsedDatatypeImages["COMMS"] : parsedFrameworkData.Comms.large_image,
+
label: securityFramework[5].text.toUpperCase(),
id: securityFramework[5].text.toUpperCase(),
animate: false,
@@ -1488,9 +1530,8 @@ const AppFramework = (props) => {
margin_y: parsedFrameworkData["EDR & AV"].large_image === undefined ? `${19*scale}px` : `0px`,
width: parsedFrameworkData["EDR & AV"].large_image === undefined ? iconSize : defaultSize,
height: parsedFrameworkData["EDR & AV"].large_image === undefined ? iconSize : defaultSize,
- large_image: parsedFrameworkData["EDR & AV"].large_image === undefined ? encodeURI(`data:image/svg+xml;utf-8,`) : parsedFrameworkData["EDR & AV"].large_image,
+ large_image: parsedFrameworkData["EDR & AV"].large_image === undefined ? parsedDatatypeImages["EDR & AV"] : parsedFrameworkData["EDR & AV"].large_image,
+
label: securityFramework[7].text.toUpperCase(),
id: securityFramework[7].text.toUpperCase(),
animate: false,
@@ -1517,9 +1558,7 @@ const AppFramework = (props) => {
margin_y: parsedFrameworkData.Network.large_image === undefined ? `${19*scale}px` : `0px`,
width: parsedFrameworkData.Network.large_image === undefined ? iconSize : defaultSize,
height: parsedFrameworkData.Network.large_image === undefined ? iconSize : defaultSize,
- large_image: parsedFrameworkData.Network.large_image === undefined ? encodeURI(`data:image/svg+xml;utf-8,`) : parsedFrameworkData.Network.large_image,
+ large_image: parsedFrameworkData.Network.large_image === undefined ? parsedDatatypeImages["NETWORK"] : parsedFrameworkData.Network.large_image,
label: securityFramework[6].text.toUpperCase(),
id: securityFramework[6].text.toUpperCase(),
animate: false,
@@ -1546,9 +1585,7 @@ const AppFramework = (props) => {
margin_y: parsedFrameworkData.SIEM.large_image === undefined ? `${19*scale}px` : `0px`,
width: parsedFrameworkData.SIEM.large_image === undefined ? iconSize : defaultSize,
height: parsedFrameworkData.SIEM.large_image === undefined ? iconSize : defaultSize,
- large_image: parsedFrameworkData.SIEM.large_image === undefined ? encodeURI(`data:image/svg+xml;utf-8,`) : parsedFrameworkData.SIEM.large_image,
+ large_image: parsedFrameworkData.SIEM.large_image === undefined ? parsedDatatypeImages["SIEM"] : parsedFrameworkData.SIEM.large_image,
label: securityFramework[1].text.toUpperCase(),
id: securityFramework[1].text.toUpperCase(),
animate: false,
@@ -1683,8 +1720,8 @@ const AppFramework = (props) => {
const UsecaseHandler = (props) => {
const { data, index, diff } = props
- const leftImage = data.left_image !== undefined ? parsedDatatypeImages[data.left_image] : undefined
- const rightImage = data.right_image !== undefined ? parsedDatatypeImages[data.right_image] : undefined
+ const leftImage = data.left_image !== undefined ? parsedDatatypeImages[data.left_image.toUpperCase()] : undefined
+ const rightImage = data.right_image !== undefined ? parsedDatatypeImages[data.right_image.toUpperCase()] : undefined
if (leftImage === undefined) {
console.log("LEFT MISSING: ", leftImage)
@@ -1700,7 +1737,6 @@ const AppFramework = (props) => {
const parsedLeftImage =
const parsedLeftText =