Cache contains, Variables, App Activation and Subflow fixes

This commit is contained in:
frikky
2023-04-14 08:43:04 +02:00
parent 27457637c1
commit 30ba687d60
8 changed files with 770 additions and 487 deletions
+21 -29
View File
@@ -842,7 +842,7 @@ func handleRemoteDownloadApp(resp http.ResponseWriter, ctx context.Context, user
app := tmpapp{} app := tmpapp{}
err := json.Unmarshal(respBody, &app) err := json.Unmarshal(respBody, &app)
if err != nil || app.Success == false || len(app.OpenAPI) == 0 { if err != nil || app.Success == false || len(app.OpenAPI) == 0 {
log.Printf("[ERROR] Failed app unmarshal during auto-download. Success%#v. Applength: %d: %s", app.Success, len(app.OpenAPI), err) log.Printf("[ERROR] Failed app unmarshal during auto-download. Success: %#v. Applength: %d: %s", app.Success, len(app.OpenAPI), err)
resp.WriteHeader(401) resp.WriteHeader(401)
resp.Write([]byte(`{"success": false, "reason": "App doesn't exist"}`)) resp.Write([]byte(`{"success": false, "reason": "App doesn't exist"}`))
return return
@@ -960,37 +960,29 @@ func activateWorkflowAppDocker(resp http.ResponseWriter, request *http.Request)
} }
} }
if app.Sharing || app.Public { // Just making sure it's being built properly
org, err := shuffle.GetOrg(ctx, user.ActiveOrg.Id) if app == nil {
if err == nil { log.Printf("[WARNING] App is nil. This shouldn't happen. Starting remote download(3)")
added := false handleRemoteDownloadApp(resp, ctx, user, fileId)
if !shuffle.ArrayContains(org.ActiveApps, app.ID) {
org.ActiveApps = append(org.ActiveApps, app.ID)
added = true
}
if added {
err = shuffle.SetOrg(ctx, *org, org.Id)
if err != nil {
log.Printf("[WARNING] Failed setting org when autoadding apps on save: %s", err)
} else {
log.Printf("[INFO] Added public app %s (%s) to org %s (%s)", app.Name, app.ID, user.ActiveOrg.Name, user.ActiveOrg.Id)
cacheKey := fmt.Sprintf("apps_%s", user.Id)
shuffle.DeleteCache(ctx, cacheKey)
}
}
}
} else {
log.Printf("[WARNING] User is trying to activate %s which is NOT public", app.Name)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return return
} }
log.Printf("[DEBUG] App %s (%s) activated for org %s by user %s", app.Name, app.ID, user.ActiveOrg.Id, user.Username) // Check the app.. hmm
openApiApp, err := shuffle.GetOpenApiDatastore(ctx, app.ID)
if err != nil {
log.Printf("[WARNING] Error getting app %s (openapi config): %s", app.ID, err)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false, "reason": "Couldn't find app OpenAPI"}`))
return
}
// If onprem, it should autobuild the container(s) from here log.Printf("[INFO] User %s (%s) is activating %s. Public: %t, Shared: %t", user.Username, user.Id, app.Name, app.Public, app.Sharing)
buildSwaggerApp(resp, []byte(openApiApp.Body), user, true)
resp.WriteHeader(200) //app.Active = true
resp.Write([]byte(`{"success": true}`)) //app.Generated = true
//app, err := shuffle.SetApp(ctx, app)
//resp.WriteHeader(200)
//resp.Write([]byte(`{"success": true}`))
} }
+1 -1
View File
@@ -19,7 +19,7 @@ require (
github.com/gorilla/mux v1.8.0 github.com/gorilla/mux v1.8.0
github.com/h2non/filetype v1.1.3 github.com/h2non/filetype v1.1.3
github.com/satori/go.uuid v1.2.0 github.com/satori/go.uuid v1.2.0
github.com/shuffle/shuffle-shared v0.4.1 github.com/shuffle/shuffle-shared v0.4.2
golang.org/x/crypto v0.3.0 golang.org/x/crypto v0.3.0
google.golang.org/api v0.103.0 google.golang.org/api v0.103.0
google.golang.org/appengine v1.6.7 google.golang.org/appengine v1.6.7
+1 -1
View File
@@ -1161,7 +1161,7 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) {
} }
} }
log.Printf("[INFO] Starting execution of %s!", fileId) log.Printf("[AUDIT] Starting execution of workflow '%s' by user %s (%s)!", fileId, user.Username, user.Id)
user.ActiveOrg.Users = []shuffle.UserMini{} user.ActiveOrg.Users = []shuffle.UserMini{}
workflow.ExecutingOrg = user.ActiveOrg workflow.ExecutingOrg = user.ActiveOrg
+14 -16
View File
@@ -146,17 +146,18 @@ const ConfigureWorkflow = (props) => {
app: {}, app: {},
steps: [], steps: [],
show_steps: false, show_steps: false,
}; }
const app = apps.find( //console.log("Action: ", key, keyval)
(app) =>
app.name === action.app_name && const app = apps.find((app) =>
(app.app_version === action.app_version || app.id === action.app_id ||
(app.loop_versions !== null && (app.name === action.app_name &&
app.loop_versions.includes(action.app_version))) (app.app_version === action.app_version || (app.loop_versions !== null && app.loop_versions.includes(action.app_version))))
) )
//newaction.steps = wazuhSteps //console.log("FOUND APP: ", app)
if (app === undefined || app === null) { if (app === undefined || app === null) {
const subapp = apps.find(app => app.name === action.app_name) const subapp = apps.find(app => app.name === action.app_name)
if (subapp !== undefined && subapp !== null) { if (subapp !== undefined && subapp !== null) {
@@ -265,17 +266,14 @@ const ConfigureWorkflow = (props) => {
if (workflow.workflow_variables !== undefined && workflow.workflow_variables !== null && workflow.workflow_variables.length !== 0) { if (workflow.workflow_variables !== undefined && workflow.workflow_variables !== null && workflow.workflow_variables.length !== 0) {
for (let [key,keyval] in Object.entries(workflow.workflow_variables)) { for (let [key,keyval] in Object.entries(workflow.workflow_variables)) {
const variable = workflow.workflow_variables[key]; const variable = workflow.workflow_variables[key];
if ( if (variable.value === undefined || variable.value === undefined || variable.value.length === 0) {
variable.value === undefined ||
variable.value === undefined ||
variable.value.length < 2
) {
variable.value = ""; variable.value = "";
variable.index = key;
requiredVariables.push(variable); requiredVariables.push(variable);
} }
variable.index = key;
} }
} }
if (workflow.triggers !== undefined && workflow.triggers !== null && workflow.triggers.length !== 0) { if (workflow.triggers !== undefined && workflow.triggers !== null && workflow.triggers.length !== 0) {
for (let [key,keyval] in Object.entries(workflow.triggers)) { for (let [key,keyval] in Object.entries(workflow.triggers)) {
@@ -1015,7 +1013,7 @@ const ConfigureWorkflow = (props) => {
<List> <List>
{requiredActions.map((data, index) => { {requiredActions.map((data, index) => {
return ( return (
<div> <div key={index}>
{data.steps !== undefined && data.steps !== null && data.show_steps === true ? {data.steps !== undefined && data.steps !== null && data.show_steps === true ?
<AppWrapper data={data} parentindex={index} /> <AppWrapper data={data} parentindex={index} />
: :
+221 -230
View File
@@ -1909,7 +1909,7 @@ const AngularWorkflow = (defaultprops) => {
}; };
const getWorkflow = (workflow_id, sourcenode) => { const getWorkflow = (workflow_id, sourcenode) => {
fetch(globalUrl + "/api/v1/workflows/" + workflow_id, { fetch(`${globalUrl}/api/v1/workflows/${workflow_id}`, {
method: "GET", method: "GET",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@@ -1920,12 +1920,25 @@ const AngularWorkflow = (defaultprops) => {
.then((response) => { .then((response) => {
if (response.status !== 200) { if (response.status !== 200) {
console.log("Status not 200 for workflows :O!"); console.log("Status not 200 for workflows :O!");
window.location.pathname = "/workflows";
if (response.status >= 500) {
alert.info("Something went wrong while loading the workflow. Please reload.")
} else {
alert.info("You don't access to this workflow or loading failed.")
window.location.pathname = "/workflows";
}
} }
// Read text from stream
//return response.text();
return response.json(); return response.json();
}) })
.then((responseJson) => { .then((responseJson) => {
// Load as JSON
//console.log("Got workflow TXT: ", responseText)
//const responseJson = JSON.parse(responseText)
//console.log("Got workflow JSON: ", responseJson)
// Not sure why this is necessary. // Not sure why this is necessary.
if (responseJson.isValid === undefined) { if (responseJson.isValid === undefined) {
responseJson.isValid = true; responseJson.isValid = true;
@@ -2145,7 +2158,6 @@ const AngularWorkflow = (defaultprops) => {
setWorkflowDone(true); setWorkflowDone(true);
// Add error checks // Add error checks
console.log("Workflow: ", responseJson);
if (!responseJson.public) { if (!responseJson.public) {
if ( if (
!responseJson.previously_saved || !responseJson.previously_saved ||
@@ -2517,8 +2529,6 @@ const AngularWorkflow = (defaultprops) => {
cy.add(decoratorNode) cy.add(decoratorNode)
} }
} else { } else {
// Readding the icon after moving the node // Readding the icon after moving the node
if (!found) { if (!found) {
const iconInfo = GetIconInfo(nodedata); const iconInfo = GetIconInfo(nodedata);
@@ -3187,7 +3197,7 @@ const AngularWorkflow = (defaultprops) => {
} }
const activateApp = (appid, refresh) => { const activateApp = (appid, refresh) => {
fetch(globalUrl + "/api/v1/apps/" + appid + "/activate", { fetch(`${globalUrl}/api/v1/apps/${appid}/activate`, {
method: 'GET', method: 'GET',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -3204,11 +3214,10 @@ const AngularWorkflow = (defaultprops) => {
}) })
.then((responseJson) => { .then((responseJson) => {
if (responseJson.success === false) { if (responseJson.success === false) {
alert.error("Failed to activate the app") alert.error("Failed to auto-activate the app. Go to /apps and activate it.")
} else { } else {
alert.success("App activated for your organization! Refresh the page to use the app.")
if (refresh === true) { if (refresh === true) {
alert.success("App activated for your organization! Refresh the page to use the app.")
getApps() getApps()
} }
} }
@@ -3939,6 +3948,7 @@ const AngularWorkflow = (defaultprops) => {
workflow.branches = workflow.branches.filter( workflow.branches = workflow.branches.filter(
(a) => a.id !== edge.data().id (a) => a.id !== edge.data().id
); );
setWorkflow(workflow); setWorkflow(workflow);
event.target.remove(); event.target.remove();
@@ -5591,7 +5601,9 @@ const AngularWorkflow = (defaultprops) => {
display: "flex", display: "flex",
}; };
const VariablesView = () => { const VariableItem = (props) => {
const { variable, index, type } = props;
const [open, setOpen] = React.useState(false); const [open, setOpen] = React.useState(false);
const [anchorEl, setAnchorEl] = React.useState(null); const [anchorEl, setAnchorEl] = React.useState(null);
@@ -5600,29 +5612,148 @@ const AngularWorkflow = (defaultprops) => {
setAnchorEl(event.currentTarget); setAnchorEl(event.currentTarget);
}; };
const deleteVariable = (variableIndex) => { const deleteVariable = (type, variableIndex) => {
//console.log("Delete:", variableName);
if (workflow.workflow_variables !== undefined && workflow.workflow_variables !== null && workflow.workflow_variables.length > variableIndex) {
workflow.workflow_variables.splice(variableIndex, 1)
}
//workflow.workflow_variables = workflow.workflow_variables.filter( console.log("Delete type: ", type, variableIndex)
// (data) => data.name !== variableName
//); if (type === "normal") {
setWorkflow(workflow); if (workflow.workflow_variables !== undefined && workflow.workflow_variables !== null && workflow.workflow_variables.length > variableIndex) {
var vars = JSON.parse(JSON.stringify(workflow.workflow_variables))
vars.splice(variableIndex, 1)
workflow.workflow_variables = vars
console.log("Workflow after del: ", workflow)
setWorkflow(workflow);
setUpdate(Math.random());
}
} else if (type === "exec") {
if (workflow.execution_variables !== undefined && workflow.execution_variables !== null && workflow.execution_variables.length > variableIndex) {
var vars = JSON.parse(JSON.stringify(workflow.execution_variables))
vars.splice(variableIndex, 1)
workflow.execution_variables = vars
console.log("Workflow after del: ", workflow)
setWorkflow(workflow);
setUpdate(Math.random());
}
}
}; };
const deleteExecutionVariable = (variableIndex) => { return (
if (workflow.execution_variables !== undefined && workflow.execution_variables !== null && workflow.execution_variables.length > variableIndex) { <div key={index}>
workflow.execution_variables.splice(variableIndex, 1) <Paper square style={paperVariableStyle} onClick={() => { }}>
} <div
style={{
marginLeft: "10px",
marginTop: "5px",
marginBottom: "5px",
width: "2px",
backgroundColor: yellow,
marginRight: "5px",
}}
/>
<div style={{ display: "flex", width: "100%" }}>
<div
style={{
flex: "10",
marginTop: "15px",
marginLeft: "10px",
overflow: "hidden",
}}
onClick={() => {
setVariableInfo({
"name": variable.name,
"description": variable.description,
"value": variable.value,
"index": index,
})
//workflow.execution_variables = workflow.execution_variables.filter( if (type === "normal") {
// (data) => data.name !== variableName setVariablesModalOpen(true);
//); } else if (type === "exec") {
setWorkflow(workflow); setExecutionVariablesModalOpen(true);
}; } else {
console.log("Unknown type: ", type)
}
}}
>
Name: {variable.name}
</div>
<div style={{ flex: "1", marginLeft: "0px" }}>
<IconButton
aria-label="more"
aria-controls="long-menu"
aria-haspopup="true"
onClick={menuClick}
style={{ color: "white" }}
>
<MoreVertIcon />
</IconButton>
<Menu
id="long-menu"
anchorEl={anchorEl}
keepMounted
open={open}
PaperProps={{
style: {
backgroundColor: surfaceColor,
},
}}
onClose={() => {
setOpen(false);
setAnchorEl(null);
}}
>
<MenuItem
style={{
backgroundColor: inputColor,
color: "white",
}}
onClick={() => {
setOpen(false);
setVariableInfo({
"name": variable.name,
"description": variable.description,
"value": variable.value,
"index": index,
})
if (type === "normal") {
setVariablesModalOpen(true);
} else if (type === "exec") {
setExecutionVariablesModalOpen(true);
} else {
console.log("Unknown type: ", type)
}
}}
key={"Edit"}
>
{"Edit"}
</MenuItem>
<MenuItem
style={{
backgroundColor: inputColor,
color: "white",
}}
onClick={() => {
deleteVariable(type, index);
setOpen(false);
}}
key={"Delete"}
>
{"Delete"}
</MenuItem>
</Menu>
</div>
</div>
</Paper>
</div>
)
}
const VariablesView = () => {
const variableScrollStyle = { const variableScrollStyle = {
margin: 15, margin: 15,
overflow: "scroll", overflow: "scroll",
@@ -5642,108 +5773,20 @@ const AngularWorkflow = (defaultprops) => {
target="_blank" target="_blank"
style={{ textDecoration: "none", color: "#f85a3e" }} style={{ textDecoration: "none", color: "#f85a3e" }}
> >
WORKFLOW variables? Workflow variables?
</a> </a>
{workflow.workflow_variables === null {workflow.workflow_variables === null
? null ? null
: workflow.workflow_variables.map((variable, index) => { : workflow.workflow_variables.map((variable, varindex) => {
return ( return (
<div key={index}> <VariableItem
<Paper square style={paperVariableStyle} onClick={() => { }}> variable={variable}
<div index={varindex}
style={{ type={"normal"}
marginLeft: "10px", />
marginTop: "5px",
marginBottom: "5px",
width: "2px",
backgroundColor: yellow,
marginRight: "5px",
}}
/>
<div style={{ display: "flex", width: "100%" }}>
<div
style={{
flex: "10",
marginTop: "15px",
marginLeft: "10px",
overflow: "hidden",
}}
onClick={() => {
setVariableInfo({
"name": variable.name,
"description": variable.description,
"value": variable.value,
"index": index,
})
setVariablesModalOpen(true);
}}
>
Name: {variable.name}
</div>
<div style={{ flex: "1", marginLeft: "0px" }}>
<IconButton
aria-label="more"
aria-controls="long-menu"
aria-haspopup="true"
onClick={menuClick}
style={{ color: "white" }}
>
<MoreVertIcon />
</IconButton>
<Menu
id="long-menu"
anchorEl={anchorEl}
keepMounted
open={open}
PaperProps={{
style: {
backgroundColor: surfaceColor,
},
}}
onClose={() => {
setOpen(false);
setAnchorEl(null);
}}
>
<MenuItem
style={{
backgroundColor: inputColor,
color: "white",
}}
onClick={() => {
setOpen(false);
setVariableInfo({
"name": variable.name,
"description": variable.description,
"value": variable.value,
"index": index,
})
setVariablesModalOpen(true);
}}
key={"Edit"}
>
{"Edit"}
</MenuItem>
<MenuItem
style={{
backgroundColor: inputColor,
color: "white",
}}
onClick={() => {
deleteVariable(index);
setOpen(false);
}}
key={"Delete"}
>
{"Delete"}
</MenuItem>
</Menu>
</div>
</div>
</Paper>
</div>
); );
})} })}
<div style={{ flex: "1" }}> <div style={{ flex: "1" }}>
<Button <Button
fullWidth fullWidth
@@ -5753,6 +5796,12 @@ const AngularWorkflow = (defaultprops) => {
onClick={() => { onClick={() => {
setVariablesModalOpen(true); setVariablesModalOpen(true);
setLastSaved(false); setLastSaved(false);
setVariableInfo({
"name": "",
"description": "",
"value": "",
})
}} }}
> >
New workflow variable New workflow variable
@@ -5774,109 +5823,18 @@ const AngularWorkflow = (defaultprops) => {
target="_blank" target="_blank"
style={{ textDecoration: "none", color: "#f85a3e" }} style={{ textDecoration: "none", color: "#f85a3e" }}
> >
EXECUTION variables? Runtime variables?
</a> </a>
{workflow.execution_variables === null || {workflow.execution_variables === null ||
workflow.execution_variables === undefined workflow.execution_variables === undefined
? null ? null
: workflow.execution_variables.map((variable, index) => { : workflow.execution_variables.map((variable, varindex2) => {
return ( return (
<div> <VariableItem
<Paper square style={paperVariableStyle} onClick={() => { }}> variable={variable}
<div index={varindex2}
style={{ type={"exec"}
marginLeft: "10px", />
marginTop: "5px",
marginBottom: "5px",
width: "2px",
backgroundColor: yellow,
marginRight: "5px",
}}
/>
<div style={{ display: "flex", width: "100%" }}>
<div
style={{
flex: "10",
marginTop: "15px",
marginLeft: "10px",
overflow: "hidden",
}}
onClick={() => {
//setNewVariableName(variable.name);
setVariableInfo({
"name": variable.name,
"description": variable.description,
"value": variable.value,
"index": index,
})
setExecutionVariablesModalOpen(true);
}}
>
Name: {variable.name}
</div>
<div style={{ flex: "1", marginLeft: "0px" }}>
<IconButton
aria-label="more"
aria-controls="long-menu"
aria-haspopup="true"
onClick={menuClick}
style={{ color: "white" }}
>
<MoreVertIcon />
</IconButton>
<Menu
id="long-menu"
anchorEl={anchorEl}
keepMounted
open={open}
PaperProps={{
style: {
backgroundColor: surfaceColor,
},
}}
onClose={() => {
setOpen(false);
setAnchorEl(null);
}}
>
<MenuItem
style={{
backgroundColor: inputColor,
color: "white",
}}
onClick={() => {
setOpen(false);
//setNewVariableName(variable.name);
setVariableInfo({
"name": variable.name,
"description": variable.description,
"value": variable.value,
"index": index,
})
setExecutionVariablesModalOpen(true);
}}
key={"Edit"}
>
{"Edit"}
</MenuItem>
<MenuItem
style={{
backgroundColor: inputColor,
color: "white",
}}
onClick={() => {
deleteExecutionVariable(index);
setOpen(false);
}}
key={"Delete"}
>
{"Delete"}
</MenuItem>
</Menu>
</div>
</div>
</Paper>
</div>
); );
})} })}
<div style={{ flex: "1" }}> <div style={{ flex: "1" }}>
@@ -5888,6 +5846,12 @@ const AngularWorkflow = (defaultprops) => {
onClick={() => { onClick={() => {
setExecutionVariablesModalOpen(true); setExecutionVariablesModalOpen(true);
setLastSaved(false); setLastSaved(false);
setVariableInfo({
"name": "",
"description": "",
"value": "",
})
}} }}
> >
New execution variable New execution variable
@@ -6401,6 +6365,13 @@ const AngularWorkflow = (defaultprops) => {
}; };
// FIXME: overwrite category if the ACTION chosen has a different category // FIXME: overwrite category if the ACTION chosen has a different category
//
if (!isCloud && (!app.is_valid || (!app.activated && app.generated))) {
console.log("NOT VALID: Activate!")
activateApp(app.id, false)
}
// const image = "url("+app.large_image+")" // const image = "url("+app.large_image+")"
// FIXME - find the cytoscape offset position // FIXME - find the cytoscape offset position
@@ -7539,11 +7510,7 @@ const AngularWorkflow = (defaultprops) => {
example: "tmp", example: "tmp",
}) })
if ( if (workflow.workflow_variables !== null && workflow.workflow_variables !== undefined && workflow.workflow_variables.length > 0) {
workflow.workflow_variables !== null &&
workflow.workflow_variables !== undefined &&
workflow.workflow_variables.length > 0
) {
for (let varkey in workflow.workflow_variables) { for (let varkey in workflow.workflow_variables) {
const item = workflow.workflow_variables[varkey]; const item = workflow.workflow_variables[varkey];
actionlist.push({ actionlist.push({
@@ -14841,6 +14808,8 @@ const AngularWorkflow = (defaultprops) => {
aria-labelledby="draggable-dialog-title" aria-labelledby="draggable-dialog-title"
onClose={() => { onClose={() => {
setNewVariableName(""); setNewVariableName("");
setNewVariableValue("");
setExecutionVariablesModalOpen(false); setExecutionVariablesModalOpen(false);
}} }}
PaperProps={{ PaperProps={{
@@ -14849,7 +14818,8 @@ const AngularWorkflow = (defaultprops) => {
backgroundColor: surfaceColor, backgroundColor: surfaceColor,
color: "white", color: "white",
border: theme.palette.defaultBorder, border: theme.palette.defaultBorder,
maxWidth: "100%", maxWidth: isMobile ? bodyWidth - 100 : 800,
minWidth: isMobile ? bodyWidth - 100 : 800,
}, },
}} }}
> >
@@ -14879,15 +14849,32 @@ const AngularWorkflow = (defaultprops) => {
}, },
}} }}
margin="dense" margin="dense"
label="Name"
fullWidth fullWidth
defaultValue={newVariableName} defaultValue={newVariableName}
/> />
<TextField
onBlur={(event) => setNewVariableValue(event.target.value)}
color="primary"
placeholder="Default Value (optional)"
style={{ marginTop: 25 }}
InputProps={{
style: {
color: "white",
},
}}
margin="dense"
label="Default Value (optional)"
fullWidth
defaultValue={newVariableValue}
/>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<Button <Button
style={{ borderRadius: "0px" }} style={{ borderRadius: "0px" }}
onClick={() => { onClick={() => {
setNewVariableName(""); setNewVariableName("");
setNewVariableValue("");
setExecutionVariablesModalOpen(false); setExecutionVariablesModalOpen(false);
}} }}
color="primary" color="primary"
@@ -14916,11 +14903,15 @@ const AngularWorkflow = (defaultprops) => {
if (newVariableName.length > 0) { if (newVariableName.length > 0) {
workflow.execution_variables[found].name = newVariableName; workflow.execution_variables[found].name = newVariableName;
} }
if (newVariableValue.length > 0) {
workflow.execution_variables[found].value = newVariableValue;
}
} else { } else {
workflow.execution_variables.push({ workflow.execution_variables.push({
name: newVariableName, name: newVariableName,
value: newVariableValue,
description: "An execution variable", description: "An execution variable",
value: "",
id: uuidv4(), id: uuidv4(),
}); });
} }
+1 -1
View File
@@ -11,7 +11,7 @@ require (
github.com/gorilla/mux v1.8.0 github.com/gorilla/mux v1.8.0
github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/satori/go.uuid v1.2.0 github.com/satori/go.uuid v1.2.0
github.com/shuffle/shuffle-shared v0.3.75 github.com/shuffle/shuffle-shared v0.4.2
) )
require ( require (
+2
View File
@@ -216,6 +216,8 @@ github.com/shuffle/shuffle-shared v0.3.51 h1:+JPEGw6R4a320who+SrGP/VqBxZdKPdcLw/
github.com/shuffle/shuffle-shared v0.3.51/go.mod h1:jQrYySmvp/0De5ftrAaY6xwwr7TMfqBmBxQ2AX9yrjQ= github.com/shuffle/shuffle-shared v0.3.51/go.mod h1:jQrYySmvp/0De5ftrAaY6xwwr7TMfqBmBxQ2AX9yrjQ=
github.com/shuffle/shuffle-shared v0.3.74 h1:i7M1Gug9j2Wa02WuSxKDbXoLvBWKW5Pxf/EpFy6v38Y= github.com/shuffle/shuffle-shared v0.3.74 h1:i7M1Gug9j2Wa02WuSxKDbXoLvBWKW5Pxf/EpFy6v38Y=
github.com/shuffle/shuffle-shared v0.3.74/go.mod h1:jQrYySmvp/0De5ftrAaY6xwwr7TMfqBmBxQ2AX9yrjQ= github.com/shuffle/shuffle-shared v0.3.74/go.mod h1:jQrYySmvp/0De5ftrAaY6xwwr7TMfqBmBxQ2AX9yrjQ=
github.com/shuffle/shuffle-shared v0.4.2 h1:GzDAOHN4YMMLzRmmToyO/KSYDziRuEuxLheawlAY3Rk=
github.com/shuffle/shuffle-shared v0.4.2/go.mod h1:jQrYySmvp/0De5ftrAaY6xwwr7TMfqBmBxQ2AX9yrjQ=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
File diff suppressed because it is too large Load Diff