diff --git a/frontend/src/components/OrgHeaderexpanded.jsx b/frontend/src/components/OrgHeaderexpanded.jsx index 268350a2..7729057d 100644 --- a/frontend/src/components/OrgHeaderexpanded.jsx +++ b/frontend/src/components/OrgHeaderexpanded.jsx @@ -2,7 +2,9 @@ import React, { useEffect } from "react"; import { makeStyles } from "@mui/styles"; import theme from '../theme.jsx'; -import { toast } from "react-toastify" +import { toast } from "react-toastify" +import Chip from '@mui/material/Chip'; +import Stack from '@mui/material/Stack'; import { FormControl, @@ -25,6 +27,11 @@ import { Grid, IconButton, Autocomplete, + Dialog, + DialogTitle, + DialogActions, + DialogContent, + Box } from "@mui/material"; import { @@ -158,6 +165,19 @@ const OrgHeaderexpanded = (props) => { const [workflows, setWorkflows] = React.useState([]) const [workflow, setWorkflow] = React.useState({}) + // notification workflow + const [notificationApp, setNotificationApp] = React.useState("") + const [notificationWorkflowModal, setNotificationWorkflowModal] = React.useState(false); + const [selectedAppDetails, setSelectedAppDetails] = React.useState({}); + const [notificationWorkflowTestModal, setNotificationWorkflowTestModal] = React.useState(false); + const [webhookInputValue, setWebhookInputValue] = React.useState(""); + const [authOptions, setAuthOptions] = React.useState([]); + const [selectedAuth, setSelectedAuth] = React.useState(''); + + // for jira modal + const [jiraIssueType, setJiraIssueType] = React.useState(""); + const [jiraProjectKey, setJiraProjectKey] = React.useState(""); + const getAvailableWorkflows = (trigger_index) => { fetch(globalUrl + "/api/v1/workflows", { method: "GET", @@ -295,12 +315,455 @@ const OrgHeaderexpanded = (props) => { ); + const executeTestWorkflow = async (workflowid) => { + const data = { "execution_argument": '{"title":"THIS IS TEST ALERT","description":"TEST ALERT FROM SHUFFLE","reference_url": "shuffler.io"}' } + fetch(globalUrl + `/api/v1/workflows/${workflowid}/execute`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + body: JSON.stringify(data), + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + toast("Failed setting notification workflow: ", response.reason); + console.log("Status not 200 for workflows :O!"); + return; + } + toast("Notification workflow ran successfully"); + return response.json(); + }).catch((error) => { + console.log("Error getting workflows: " + error); + }) +} + +const generateNotificationWorkflow = async (appname,appImage,appAuthId,projectId,issuetype) => { + //currently only supports JIRA figure out a way to support more apps + var workflowName = `[GENARATED] ${appname} notification workflow` + var workflowDescription = "Generated by Shuffle for sending error notifications." + var data = { + "name": workflowName, + "description": workflowDescription, + } + + fetch(globalUrl + "/api/v1/workflows", { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + body: JSON.stringify(data), + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + toast("Failed setting notification workflow: ", response.reason); + console.log("Status not 200 for workflows :O!"); + return; + } + return response.json(); + }).then((responseJson)=>{ + if (responseJson !== undefined) { + console.log("Notification workflow created successfully") + var workflow_id = responseJson.id + if (appname.toLowerCase() === "jira"){ + console.log("updating workflow for JIRA") + var workflowBody = { + "name": workflowName, + "Description": workflowDescription, + "id": workflow_id, + "actions": [ + { + "app_name": "Jira", + "name": "post_create_issue", + "authentication_id":appAuthId, + "large_image":appImage, + "isStartNode": true, + "label": "create_issue", + "app_version": "1.1.0", + "parameters": [ + { + "name": "body", + "value": `{"fields": { "project": {"key": "${projectId}"},"summary": "$exec.title","issuetype": {"name": "${issuetype}"},"description": {"content": [{"content":[{"type":"text","text":"$exec.description"}],"type": "paragraph"}],"type": "doc","version": 1}}}` + }, + { + "name": "username_basic", + "value": "" + }, + { + "name": "password_basic", + "value": "" + }, + { + "name": "url", + "value": "" + }, + { + "name": "headers", + "value": "Content-type=application/json \nAccept=application/json" + }, + { + "name": "queries", + "value": "" + }, + { + "name": "ssl_verify", + "value": "False" + } + ] + } + ] + } + } + fetch(globalUrl + `/api/v1/workflows/${workflow_id}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + body: JSON.stringify(workflowBody), + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + toast("Failed setting notification workflow: ", response.reason); + console.log("Status not 200 for workflows :O!"); + return; + } + return response.json(); + }).then((responseJson)=>{ + if (responseJson !== undefined) { + handleEditOrg( + orgName, + orgDescription, + selectedOrganization.id, + selectedOrganization.image, + { + app_download_repo: appDownloadUrl, + app_download_branch: appDownloadBranch, + workflow_download_repo: workflowDownloadUrl, + workflow_download_branch: workflowDownloadBranch, + notification_workflow: workflow_id, + documentation_reference: documentationReference, + }, + { + sso_entrypoint: ssoEntrypoint, + sso_certificate: ssoCertificate, + client_id: openidClientId, + client_secret: openidClientSecret, + openid_authorization: openidAuthorization, + openid_token: openidToken, + } + ) + console.log("Notification workflow updated successfully") + toast("Notification workflow updated successfully") + } + }) + } + }).catch((error) => { + console.log("Error setting workflows: " + error); + }) +} + +const getAppAuth = async (appName) => { + fetch(globalUrl + "/api/v1/apps/authentication", { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + toast(`Failed getting auth for ${appName}: `, response.reason); + console.log("Status not 200 for app auth :O!"); + return; + } + return response.json(); + }).then((responseJson) => { + if (!responseJson.success) { + console.log("Could not get app auth") + return; + } + var authList = responseJson.data.filter(entry => entry.app.name === appName) + console.log("authList: ", authList) + setAuthOptions(authList); + + }).catch((error) => { + console.log("Error getting app auth: " + error); + }) +} + +const testWorkflowModal = notificationWorkflowTestModal ? + ( { + setNotificationWorkflowTestModal(false); + }} + > + + {/* +
+ Notification workflow +
+
*/} + + We have updated the Notification workflow. Do you want to test it? + + + + + +
+
) : null + +const notificationWorkflowModalValid = () => { +return selectedAuth && webhookInputValue; +}; + +const modalView = notificationWorkflowModal ? ( + { + setNotificationWorkflowModal(false); + }} + > + + +
+ {`Configure ${selectedAppDetails.name} workflow`} +
+
+ + + + {authOptions.length > 0 ? + <> + + + Pick an authentication method from the list + + + Available authentications + + + + + + Provide additional required details: + + { + setJiraProjectKey(e.target.value) + }} + InputProps={{ + classes: { + notchedOutline: classes.notchedOutline, + }, + style: { + color: "white", + }, + }} /> + { + setJiraIssueType(e.target.value) + }} + InputProps={{ + classes: { + notchedOutline: classes.notchedOutline, + }, + style: { + color: "white", + }, + }} /> + + : <> + + {`No ${selectedAppDetails.name} auth found. Click below to set one up.`} + + + + } + + + + + +
+
+) : null + +// getting comms & cases app from app framework +var notificationAppList = []; +if (selectedOrganization.security_framework.cases && selectedOrganization.security_framework.cases.name.length > 0) { +notificationAppList = notificationAppList.concat(selectedOrganization.security_framework.cases); +} +if (selectedOrganization.security_framework.communication && selectedOrganization.security_framework.communication.name.length > 0) { +notificationAppList = notificationAppList.concat(selectedOrganization.security_framework.communication); +} + +const renderChips = (apps) => { +if (!apps || apps.length === 0) { + return ( + { + console.log(`Clicked EMAIL`) + setNotificationWorkflowModal(true) + }} + avatar={{"email} + /> + ) +} + +return ( + + {apps.map((app) => ( + { + console.log(`Clicked ${app.name}`) + setSelectedAppDetails(app) + setNotificationWorkflowModal(true) + getAppAuth(app.name) + console.log(selectedAppDetails) + }} + avatar={{app.name}} + /> + ))} + +); +}; + + return (
Notification Workflow + {modalView} + {/*{testWorkflowModal} */} +
+ {renderChips(notificationAppList)}
{/* Add a Workflow that receives notifications from Shuffle when an error occurs in one of your workflows