diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 27517625..668cb557 100755 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -15,7 +15,7 @@ import HealthPage from "./components/HealthPage.jsx"; import theme from "./theme"; import Apps from "./views/Apps"; import AppCreator from "./views/AppCreator"; -import Dectection from "./views/Detection.jsx"; +import DetectionDashBoard from "./views/DetectionDashboard.jsx"; import Welcome from "./views/Welcome.jsx"; import Dashboard from "./views/Dashboard.jsx"; @@ -418,7 +418,7 @@ const App = (message, props) => { } + element={} /> { - const [additionalProps, setAdditionalProps] = React.useState(otherProps); - - const handleSwitchChange = (event) => { - const isEnabled = event.target.checked; - toggleRule(file_id, !isEnabled, globalUrl, () => { - setAdditionalProps((prevProps) => ({ - ...prevProps, - is_enabled: isEnabled, - })); - }); - }; - - return ( - - -
- {ruleName} -
- - - - -
-
- - {description} - -
-
- ); -}; - -const toggleRule = (fileId, isCurrentlyEnabled, globalUrl, callback) => { - const action = isCurrentlyEnabled ? "disable" : "enable"; - const url = `${globalUrl}/api/v1/files/${fileId}/${action}_rule`; - - fetch(url, { - method: "PUT", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - }) - .then((response) => - response.json().then((responseJson) => { - if (responseJson["success"] === false) { - toast(`Failed to ${action} the rule`); - } else { - toast(`Rule ${action}d successfully`); - callback(); - } - }) - ) - .catch((error) => { - console.log(`Error in ${action}ing the rule: `, error); - toast(`An error occurred while ${action}ing the rule`); - }); -}; - -const Detection = (props) => { - const { globalUrl } = props; - const [ruleInfo, setRuleInfo] = React.useState([]); - - const getSigmaInfo = () => { - const url = globalUrl + "/api/v1/files/detection/sigma_rules"; - - fetch(url, { - method: "GET", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - }) - .then((response) => - response.json().then((responseJson) => { - if (responseJson["success"] === false) { - toast("Failed to get sigma rules"); - } else { - setRuleInfo(responseJson); - } - }) - ) - .catch((error) => { - console.log("Error in getting sigma files: ", error); - toast("An error occurred while fetching sigma rules"); - }); - }; - - React.useEffect(() => { - getSigmaInfo(); - }, []); - +const Detection = ({ globalUrl, ruleInfo, openEditBar }) => { return ( @@ -164,6 +58,7 @@ const Detection = (props) => { description={card.description} file_id={card.file_id} globalUrl={globalUrl} + openEditBar={() => openEditBar(card)} {...card} /> ))} diff --git a/frontend/src/views/DetectionDashboard.jsx b/frontend/src/views/DetectionDashboard.jsx new file mode 100644 index 00000000..50771d63 --- /dev/null +++ b/frontend/src/views/DetectionDashboard.jsx @@ -0,0 +1,102 @@ +import React, { useState, useEffect } from "react"; +import { Container} from "@mui/material"; +import { toast } from "react-toastify"; +import Detection from "./Detection"; +import EditComponent from "./EditRules"; + +const getSigmaInfo = (globalUrl, setRuleInfo) => { + const url = globalUrl + "/api/v1/files/detection/sigma_rules"; + + fetch(url, { + method: "GET", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + }) + .then((response) => + response.json().then((responseJson) => { + if (responseJson["success"] === false) { + toast("Failed to get sigma rules"); + } else { + setRuleInfo(responseJson); + } + }) + ) + .catch((error) => { + console.log("Error in getting sigma files: ", error); + toast("An error occurred while fetching sigma rules"); + }); +}; + +const DetectionDashBoard = (props) => { + const { globalUrl } = props; + const [ruleInfo, setRuleInfo] = useState([]); + const [selectedRule, setSelectedRule] = useState(null); + const [fileData, setFileData] = useState("") + + useEffect(() => { + getSigmaInfo(globalUrl, setRuleInfo); + }, [globalUrl]); + + const openEditBar = (rule) => { + setSelectedRule(rule); + getFileContent(rule.file_id) + }; + + const handleSave = (updatedContent) => { + toast("this will be saved"); + setSelectedRule(null); // Close the edit bar after saving + }; + + const getFileContent = (file_id) => { + fetch(globalUrl + "/api/v1/files/" + file_id + "/content", { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + console.log("Status not 200 for file :O!"); + return ""; + } + return response.text(); + }) + .then((respdata) => { + if (respdata.length === 0) { + toast("Failed getting file. Is it deleted?"); + return; + } + return respdata + }) + .then((responseData) => { + + setFileData(responseData); + }) + .catch((error) => { + toast(error.toString()); + }); + }; + + return ( + + {selectedRule ? ( + + ) : null} + + + ); +}; + +export default DetectionDashBoard; diff --git a/frontend/src/views/EditRules.jsx b/frontend/src/views/EditRules.jsx new file mode 100644 index 00000000..501bb6cc --- /dev/null +++ b/frontend/src/views/EditRules.jsx @@ -0,0 +1,46 @@ +import React, { useState } from 'react'; +import { Box, Typography, Button, Switch, TextField } from '@mui/material'; + +const EditComponent = ({ ruleName, description, content, setContent, lastEdited, editedBy, onSave }) => { + + const handleSave = () => { + onSave(content); + }; + + return ( + + + {ruleName} + + + + + + {description} + + + Last edited: {lastEdited} + + + Edited By: {editedBy} + + + setContent(e.target.value)} + variant="outlined" + fullWidth + /> + + + + + + ); +}; + +export default EditComponent; diff --git a/frontend/src/views/RuleCard.jsx b/frontend/src/views/RuleCard.jsx new file mode 100644 index 00000000..e166ce6b --- /dev/null +++ b/frontend/src/views/RuleCard.jsx @@ -0,0 +1,82 @@ +import React from "react"; +import { + Card, + CardContent, + IconButton, + Typography, + Switch, +} from "@mui/material"; +import EditIcon from "@mui/icons-material/Edit"; +import { toast } from "react-toastify"; + +const RuleCard = ({ ruleName, description, file_id, globalUrl, openEditBar, ...otherProps }) => { + const [additionalProps, setAdditionalProps] = React.useState(otherProps); + + const handleSwitchChange = (event) => { + const isEnabled = event.target.checked; + toggleRule(file_id, !isEnabled, globalUrl, () => { + setAdditionalProps((prevProps) => ({ + ...prevProps, + is_enabled: isEnabled, + })); + }); + }; + + return ( + + +
+ {ruleName} +
+ openEditBar({ ruleName, description, file_id, ...additionalProps })}> + + + +
+
+ + {description} + +
+
+ ); +}; + +const toggleRule = (fileId, isCurrentlyEnabled, globalUrl, callback) => { + const action = isCurrentlyEnabled ? "disable" : "enable"; + const url = `${globalUrl}/api/v1/files/${fileId}/${action}_rule`; + + fetch(url, { + method: "PUT", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + }) + .then((response) => + response.json().then((responseJson) => { + if (responseJson["success"] === false) { + toast(`Failed to ${action} the rule`); + } else { + toast(`Rule ${action}d successfully`); + callback(); + } + }) + ) + .catch((error) => { + console.log(`Error in ${action}ing the rule: `, error); + toast(`An error occurred while ${action}ing the rule`); + }); +}; + +export default RuleCard;