From 8c21ad07edb940431ab29ee189a031ad4fd304d4 Mon Sep 17 00:00:00 2001 From: frikky Date: Tue, 6 Dec 2022 14:51:51 +0000 Subject: [PATCH] Made automatic builds of apps happen when an app is selected onprem --- frontend/src/components/AppFramework.jsx | 41 ++++- frontend/src/components/ConfigureWorkflow.jsx | 22 +++ frontend/src/components/UsecaseSearch.jsx | 166 +++++++++++++++++- frontend/src/components/WelcomeForm2.jsx | 4 +- 4 files changed, 225 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/AppFramework.jsx b/frontend/src/components/AppFramework.jsx index 8a51c521..43caf58c 100644 --- a/frontend/src/components/AppFramework.jsx +++ b/frontend/src/components/AppFramework.jsx @@ -1,15 +1,16 @@ import React, { useState, useEffect } from 'react'; -import { securityFramework} from "./LandingpageUsecases.jsx"; import CytoscapeComponent from 'react-cytoscapejs'; import frameworkStyle from '../frameworkStyle.jsx'; -import AppSearch from './Appsearch.jsx'; import { v4 as uuidv4 } from "uuid"; import theme from '../theme'; import { useAlert } from "react-alert"; -import { usecaseTypes } from "../components/UsecaseSearch.jsx" + +import AppSearch from '../components/Appsearch.jsx'; import PaperComponent from "../components/PaperComponent.jsx" +import { usecaseTypes } from "../components/UsecaseSearch.jsx" import SuggestedWorkflows from "../components/SuggestedWorkflows.jsx" +import { securityFramework} from "../components/LandingpageUsecases.jsx"; import { Paper, @@ -751,7 +752,41 @@ const AppFramework = (props) => { }) } + const activateApp = (appid) => { + fetch(globalUrl+"/api/v1/apps/"+appid+"/activate", { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + console.log("Failed to activate") + } + + return response.json() + }) + .then((responseJson) => { + if (responseJson.success === false) { + alert.error("Failed to activate the app") + } else { + //alert.success("App activated for your organization! Refresh the page to use the app.") + } + }) + .catch(error => { + //alert.error(error.toString()) + console.log("Activate app error: ", error.toString()) + }); + } + const setFrameworkItem = (data) => { + console.log("Setting framework item: ", data, isCloud) + if (!isCloud) { + activateApp(data.id) + } + fetch(globalUrl + "/api/v1/apps/frameworkConfiguration", { method: "POST", headers: { diff --git a/frontend/src/components/ConfigureWorkflow.jsx b/frontend/src/components/ConfigureWorkflow.jsx index 09fb5560..0e5cc988 100644 --- a/frontend/src/components/ConfigureWorkflow.jsx +++ b/frontend/src/components/ConfigureWorkflow.jsx @@ -22,6 +22,7 @@ import { CheckCircleRounded as CheckCircleRoundedIcon, } from "@mui/icons-material"; import { FixName } from "../views/Apps.jsx"; +import aa from 'search-insights' // Handles workflow updates on first open to highlight the issues of the workflow // Variables @@ -32,6 +33,7 @@ import { FixName } from "../views/Apps.jsx"; // Specifically used for UNSAVED workflows only? const ConfigureWorkflow = (props) => { const { + userdata, globalUrl, theme, workflow, @@ -526,6 +528,26 @@ const ConfigureWorkflow = (props) => { }; const activateApp = (app_id, app_name, app_version) => { + + if (aa !== undefined) { + aa('init', { + appId: "JNSS5CFDZZ", + apiKey: "db08e40265e2941b9a7d8f644b6e5240", + }) + + const timestamp = new Date().getTime() + aa('sendEvents', [ + { + eventType: 'conversion', + eventName: 'Public App Activated', + index: 'appsearch', + objectIDs: [app_id], + timestamp: timestamp, + userToken: userdata === undefined || userdata === null || userdata.id === undefined ? "unauthenticated" : userdata.id, + } + ]) + } + fetch( `${globalUrl}/api/v1/apps/${app_id}/activate?app_name=${app_name}&app_version=${app_version}`, { diff --git a/frontend/src/components/UsecaseSearch.jsx b/frontend/src/components/UsecaseSearch.jsx index 2bf21a4e..e9edb0f4 100644 --- a/frontend/src/components/UsecaseSearch.jsx +++ b/frontend/src/components/UsecaseSearch.jsx @@ -1,5 +1,6 @@ import React, { useState, useEffect } from "react"; import theme from '../theme'; +import { useNavigate, Link } from "react-router-dom"; import { useAlert } from "react-alert"; import ConfigureWorkflow from "../components/ConfigureWorkflow.jsx"; import PaperComponent from "../components/PaperComponent.jsx" @@ -785,9 +786,90 @@ const UsecaseSearch = (props) => { }) } + // Stolen from /views/Workflows + // Due to states, not easy to just import as component~ + const setNewWorkflow = ( + name, + description, + tags, + defaultReturnValue, + editingWorkflow, + redirect, + currentUsecases, + inputblogpost, + inputstatus, + ) => { + var method = "POST"; + var extraData = ""; + var workflowdata = {}; + + if (editingWorkflow.id !== undefined) { + console.log("Building original workflow"); + method = "PUT"; + extraData = "/" + editingWorkflow.id + "?skip_save=true"; + workflowdata = editingWorkflow; + + console.log("REMOVING OWNER"); + workflowdata["owner"] = ""; + // FIXME: Loop triggers and turn them off? + } + + workflowdata["name"] = name; + workflowdata["description"] = description; + if (tags !== undefined) { + workflowdata["tags"] = tags; + } + workflowdata["blogpost"] = inputblogpost + workflowdata["status"] = inputstatus + + if (defaultReturnValue !== undefined) { + workflowdata["default_return_value"] = defaultReturnValue; + } + + if (currentUsecases !== undefined && currentUsecases !== null) { + workflowdata["usecase_ids"] = currentUsecases + //workflows[0].category = ["detect"] + //workflows[0].usecase_ids = ["Correlate tickets"] + } + + const new_url = `${globalUrl}/api/v1/workflows${extraData}` + return fetch(new_url, { + method: method, + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + body: JSON.stringify(workflowdata), + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + console.log("Status not 200 for workflows :O!"); + return; + } + + return response.json(); + }) + .then((responseJson) => { + if (responseJson.success === false) { + if (responseJson.reason !== undefined) { + alert.error("Error setting workflow: ", responseJson.reason) + } else { + alert.error("Error setting workflow.") + } + + return + } + + return responseJson; + }) + .catch((error) => { + alert.error(error.toString()); + }); + } + const mergeWorkflowUsecases = (usecasedata) => { //const url = `${globalUrl}/api/v1/workflows/merge`; - //const url = `https://0360-178-232-150-183.ngrok.io/api/v1/workflows/merge`; const url = `https://shuffler.io/api/v1/workflows/merge`; fetch(url, { mode: "cors", @@ -845,10 +927,57 @@ const UsecaseSearch = (props) => { } } } else { + // Gets a full workflow that has to be handled from cloud directly + // if (!isCloud) { console.log("Not cloud!") - setFoundWorkflowId(responseJson.id) + if (setFoundWorkflowId !== undefined) { + setFoundWorkflowId(responseJson.id) + } setWorkflow(responseJson) + + setNewWorkflow( + responseJson.name, + responseJson.description, + responseJson.tags, + responseJson.default_return_value, + {}, + false, + [], + "", + responseJson.status, + ) + .then((response) => { + if (response !== undefined) { + // SET THE FULL THING + responseJson.id = response.id; + responseJson.first_save = false; + responseJson.previously_saved = false; + responseJson.is_valid = false; + + // Actually create it + setNewWorkflow( + responseJson.name, + responseJson.description, + responseJson.tags, + responseJson.default_return_value, + responseJson, + false, + [], + "", + responseJson.status, + ).then((response) => { + if (response !== undefined) { + alert.success("Successfully generated " + responseJson.name); + } + }); + } + }) + .catch((error) => { + alert.error("Generate error: " + error.toString()); + }) + + } else if (isCloud) { if (responseJson.workflow_id !== null && responseJson.workflow_id !== undefined) { if (responseJson.added_auth !== undefined && responseJson.added_auth !== null && responseJson.added_auth.length > 0) { @@ -1077,8 +1206,41 @@ const UsecaseSearch = (props) => { }) //console.log("Data: ", data) + const activateApp = (appid) => { + fetch(globalUrl+"/api/v1/apps/"+appid+"/activate", { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + console.log("Failed to activate") + } + + return response.json() + }) + .then((responseJson) => { + if (responseJson.success === false) { + alert.error("Failed to activate the app") + } else { + //alert.success("App activated for your organization! Refresh the page to use the app.") + } + }) + .catch(error => { + //alert.error(error.toString()) + console.log("Activate app error: ", error.toString()) + }); + } const setFrameworkItem = (data) => { + // Making sure the app is being auto-built and added + if (!isCloud) { + activateApp(data.id) + } + fetch(globalUrl + "/api/v1/apps/frameworkConfiguration", { method: "POST", headers: { diff --git a/frontend/src/components/WelcomeForm2.jsx b/frontend/src/components/WelcomeForm2.jsx index 99a5bba4..a3ccf86d 100644 --- a/frontend/src/components/WelcomeForm2.jsx +++ b/frontend/src/components/WelcomeForm2.jsx @@ -161,7 +161,7 @@ const WelcomeForm = (props) => { const foundTab = params["tab"]; if (foundTab !== null && foundTab !== undefined && !isNaN(foundTab)) { if (foundTab === 3 || foundTab === "3") { - console.log("SET SEARCH!!") + //console.log("Set search!") } } else { //navigate(`/welcome?tab=1`) @@ -380,8 +380,6 @@ const WelcomeForm = (props) => { console.log("Selected app changed (effect)") }, [newSelectedApp]) - console.log("Clickdiff: ", clickdiff) - //const buttonWidth = 145 const buttonWidth = 450 const buttonMargin = 10