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 ?
+ () : null
+
+const notificationWorkflowModalValid = () => {
+return selectedAuth && webhookInputValue;
+};
+
+const modalView = notificationWorkflowModal ? (
+
+) : 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 (
}
+ />
+ }
+ />
+ ))}
+