import React, { forwardRef, memo, useContext, useEffect } from 'react'; import theme from "../theme.jsx"; import { toast } from "react-toastify" ; import { Divider, List, ListItem, ListItemText, Button, Tooltip, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, TextField, } from '@mui/material'; import { FileCopy as FileCopyIcon, OpenInNew as OpenInNewIcon, Padding, } from "@mui/icons-material" import { Box, Skeleton, Typography } from '@mui/material'; import { Context } from '../context/ContextApi.jsx'; const SchedulesTab = memo((props) => { const {globalUrl, users, } = props; const [webHooks, setWebHooks] = React.useState([]); const [allSchedules, setAllSchedules] = React.useState([]); const [pipelines, setPipelines] = React.useState([]); const [showLoader, setShowLoader] = React.useState(true); const [pipelineModalOpen, setPipelineModalOpen] = React.useState(false); const [newPipelineValue, setNewPipelineValue] = React.useState("export | sigma /tmp/sigma_rules | to SHUFFLE_WEBHOOK"); useEffect(() => { if (allSchedules.length === 0 && webHooks.length === 0 && pipelines.length === 0) { handleGetAllTriggers() } }, []) const textColor = "#9E9E9E !important"; const changePipelineState = (pipeline, state) => { if (state.trim() === "") { toast("state is not defined"); return; } const data = { name: pipeline.name, id: pipeline.id, type: state, command: pipeline.definition, environment: pipeline.environment, }; if (state === "start") toast("starting the pipeline"); else toast.info("Stopping the pipeline. This may take a few minutes to propagate.") const url = `${globalUrl}/api/v1/triggers/pipeline`; fetch(url, { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json", }, body: JSON.stringify(data), credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for stream results :O!"); toast("Failed to update the pipeline state"); } return response.json(); }) .then((responseJson) => { if (!responseJson.success) { toast.error("Failed to update the pipeline: " + responseJson.reason); } else { setTimeout(() => { handleGetAllTriggers() }, 5000) setTimeout(() => { handleGetAllTriggers() }, 10000) setTimeout(() => { handleGetAllTriggers() }, 20000) setTimeout(() => { handleGetAllTriggers() }, 120000) /* if (state === "start") { toast("Successfully created pipeline"); } else { toast("Sucessfully stopped the pipeline"); } */ } }) .catch((error) => { //toast(error.toString()); console.log("Get schedule error: ", error.toString()); }) } const submitPipelineWrapper = (pipelineValue) => { submitPipeline(pipelineValue) } const NewPipelineView = ( ) const submitPipeline = (pipeline, environment) => { var pipelineConfig = { command: pipeline, name: pipeline, type: "create", environment: "", workflow_id: "", trigger_id: "", start_node: "", } if (environment !== undefined && environment !== "") { pipelineConfig.environment = environment } const url = `${globalUrl}/api/v1/triggers/pipeline`; fetch(url, { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json", }, body: JSON.stringify(pipelineConfig), credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for stream results :O!"); } return response.json(); }) .then((responseJson) => { if (!responseJson.success && pipelineConfig.type !== "delete") { toast("Failed to set pipeline: " + responseJson.reason); } else { if (pipelineConfig.type === "create") { toast("Pipeline will be created: " + responseJson.reason) setPipelineModalOpen(false) } else if (pipelineConfig.type === "stop") { toast("Pipeline will be stopped: " + responseJson.reason) setPipelineModalOpen(false) } else { toast("Unknown pipeline type: " + pipelineConfig.type) } } setTimeout(() => { handleGetAllTriggers() }, 5000) setTimeout(() => { handleGetAllTriggers() }, 10000) setTimeout(() => { handleGetAllTriggers() }, 15000) setTimeout(() => { handleGetAllTriggers() }, 20000) }) .catch((error) => { console.log("Get pipeline error: ", error.toString()); }); } const deleteSchedule = (data) => { // FIXME - add some check here ROFL console.log("INPUT: ", data); // Just use this one? const url = globalUrl + "/api/v1/workflows/" + data["workflow_id"] + "/schedule/" + data.id; fetch(url, { method: "DELETE", credentials: "include", headers: { "Content-Type": "application/json", }, }) .then((response) => response.json().then((responseJson) => { if (responseJson["success"] === false) { toast("Failed stopping schedule"); } else { setTimeout(() => { handleGetAllTriggers(); }, 1500); //toast("Successfully stopped schedule!") } }) ) .catch((error) => { console.log("Error in userdata: ", error); }); }; const deleteWebhook = (trigger) => { if (trigger === undefined) { return; } fetch(globalUrl + "/api/v1/hooks/" + trigger.id + "/delete", { method: "DELETE", headers: { "Content-Type": "application/json", Accept: "application/json", }, credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for stream results :O!"); } return response.json(); }) .then((responseJson) => { if (responseJson.success) { toast("Successfully stopped webhook"); } else { if (responseJson.reason !== undefined) { toast("Failed stopping webhook: " + responseJson.reason); } } setTimeout(handleGetAllTriggers, 1000); }) .catch((error) => { toast( "Delete webhook error. Contact support or check logs if this persists.", ); }); }; const handleGetAllTriggers = () => { fetch(globalUrl + "/api/v1/triggers", { method: "GET", headers: { "Content-Type": "application/json", Accept: "application/json", }, credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for getting all triggers"); } return response.json(); }) .then((responseJson) => { setWebHooks(responseJson.webhooks || []); setAllSchedules(responseJson.schedules || []); setPipelines(responseJson.pipelines || []); setShowLoader(false); }) .catch((error) => { // toast(error.toString()); }); }; const startSchedule = (trigger) => { if (trigger.name.length <= 0) { toast("Error: name can't be empty"); return; } toast("Creating schedule"); const data = { name: trigger.name, frequency: trigger.frequency, execution_argument: trigger.argument, environment: trigger.environment, id: trigger.id, start: trigger.start_node, }; fetch(`${globalUrl}/api/v1/workflows/${trigger.workflow_id}/schedule`, { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json", }, body: JSON.stringify(data), credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for stream results :O!"); } return response.json(); }) .then((responseJson) => { if (!responseJson.success) { toast("Failed to set schedule: " + responseJson.reason); } else { toast("Successfully created schedule"); } setTimeout(handleGetAllTriggers, 1000); }) .catch((error) => { //toast(error.toString()); console.log("Get schedule error: ", error.toString()); }); }; const startWebHook = (trigger) => { const hookname = trigger.info.name; if (hookname.length === 0) { toast("Missing name"); return; } if (trigger.id.length !== 36) { toast("Missing id"); return; } toast("Starting webhook"); const data = { name: hookname, type: "webhook", id: trigger.id, workflow: trigger.workflows[0], start: trigger.start, environment: trigger.environment, auth: trigger.auth, custom_response: trigger.custom_response, version: trigger.version, version_timeout: 15, }; fetch(globalUrl + "/api/v1/hooks/new", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(data), credentials: "include", }) .then((response) => response.json()) .then((responseJson) => { if (responseJson.success) { // Set the status toast("Successfully started webhook"); } else { toast("Failed starting webhook: " + responseJson.reason); } setTimeout(handleGetAllTriggers, 1000); }) .catch((error) => { //console.log(error.toString()); console.log("New webhook error: ", error.toString()); }); }; return (