Minor fixes for admin & oauth2

This commit is contained in:
Frikky
2024-06-20 23:59:15 +02:00
parent ed6ecc0bf4
commit fab2c95696
5 changed files with 231 additions and 118 deletions
+7 -8
View File
@@ -476,15 +476,15 @@ const AuthenticationOauth2 = (props) => {
var defaultPrompt = "login"
if (prompt !== undefined && prompt !== null && prompt.length > 0) {
defaultPrompt = prompt
}
}
var url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&prompt=${defaultPrompt}&scope=${resources}&state=${state}&access_type=offline`;
var url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&prompt=${defaultPrompt}&scope=${resources}&state=${state}&access_type=offline`;
if (admin_consent === true) {
console.log("Running Oauth2 WITH admin consent")
//url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&prompt=consent&scope=${resources}&state=${state}&access_type=offline`;
url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&prompt=admin_consent&scope=${resources}&state=${state}&access_type=offline`;
}
if (admin_consent === true) {
console.log("Running Oauth2 WITH admin consent")
//url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&prompt=consent&scope=${resources}&state=${state}&access_type=offline`;
url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&prompt=admin_consent&scope=${resources}&state=${state}&access_type=offline`;
}
// Force new consent
//const url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&scope=${resources}&prompt=consent&state=${state}&access_type=offline`;
@@ -997,7 +997,6 @@ const AuthenticationOauth2 = (props) => {
color: "white",
padding: 5,
minWidth: 300,
maxWidth: 300,
}}
onChange={(e, value) => {
//handleScopeChange(e)
+1 -1
View File
@@ -3745,7 +3745,7 @@ If you're interested, please let me know a time that works for you, or set up a
aria-label="disabled tabs example"
>
<Tab label=<span>Edit Details</span> />
<Tab label=<span>Cloud Synchronization</span> />
<Tab label=<span>Org Limits & Cloud Sync</span> />
<Tab label=<span>Priorities</span> />
<Tab label=<span>Billing & Stats</span> />
<Tab disabled={!isCloud} label=<span>Branding (Beta)</span> />
+188 -97
View File
@@ -2144,23 +2144,25 @@ const releaseToConnectLabel = "Release to Connect"
const executeWorkflow = (executionArgument, startNode, hasSaved) => {
if (hasSaved === false) {
setExecutionRequestStarted(true)
saveWorkflow(workflow, executionArgument, startNode);
//console.log("FIXME: Might have forgotten to save before executing.");
return;
}
if (workflow.public) {
toast("Save it to get a new version");
}
var returncheck = monitorUpdates();
if (!returncheck) {
toast("No startnode set.");
return;
}
ReactDOM.unstable_batchedUpdates(() => {
if (hasSaved === false) {
setExecutionRequestStarted(true);
saveWorkflow(workflow, executionArgument, startNode);
//console.log("FIXME: Might have forgotten to save before executing.");
return;
}
if (workflow.public) {
toast("Save it to get a new version");
}
var returncheck = monitorUpdates();
if (!returncheck) {
toast("No startnode set.");
return;
}
setVisited([])
setExecutionRequest({})
@@ -2168,38 +2170,49 @@ const releaseToConnectLabel = "Release to Connect"
// FIXME: Check if any node contains $exec in a param
// If they do, show a popup asking if they want to execute it without an execution argument, or to use a previous one
if (executionArgument === undefined || executionArgument === null || executionArgument.length === 0 && workflow.actions !== undefined && workflow.actions !== null && workflow.actions.length > 0) {
var foundmissing = false
for (let actionkey in workflow.actions) {
if (workflow.actions[actionkey].parameters === undefined || workflow.actions[actionkey].parameters === null || workflow.actions[actionkey].parameters.length === 0) {
continue
}
if (executionArgument === undefined || executionArgument === null || executionArgument.length === 0)
for (let paramkey in workflow.actions[actionkey].parameters) {
const param = workflow.actions[actionkey].parameters[paramkey]
if (param.value === undefined || param.value === null || param.value.length === 0) {
if (workflow.actions !== undefined && workflow.actions !== null && workflow.actions.length > 0) {
var foundmissing = false
for (let actionkey in workflow.actions) {
if (workflow.actions[actionkey].parameters === undefined || workflow.actions[actionkey].parameters === null || workflow.actions[actionkey].parameters.length === 0) {
continue
}
if (param.value.indexOf("$exec") !== -1) {
foundmissing = true
for (let paramkey in workflow.actions[actionkey].parameters) {
const param = workflow.actions[actionkey].parameters[paramkey]
if (param.value === undefined || param.value === null || param.value.length === 0) {
continue
}
if (param.value.indexOf("$exec") !== -1) {
foundmissing = true
break
}
}
if (foundmissing) {
break
}
}
if (foundmissing) {
break
//toast("This workflow contains a node that requires an execution argument. Please provide one.")
if (workflow.input_questions !== undefined && workflow.input_questions !== null && workflow.input_questions.length > 0) {
setExecutionRequestStarted(false)
setExecutionArgumentModalOpen(true)
return
}
if (workflowExecutions.length > 0) {
setExecutionRequestStarted(false)
setExecutionArgumentModalOpen(true)
return
}
}
}
if (foundmissing) {
//toast("This workflow contains a node that requires an execution argument. Please provide one.")
setExecutionRequestStarted(false)
setExecutionArgumentModalOpen(true)
return
}
}
var curelements = cy.elements();
for (let i = 0; i < curelements.length; i++) {
curelements[i].addClass("not-executing-highlight");
@@ -10738,7 +10751,7 @@ const releaseToConnectLabel = "Release to Connect"
padding: 30,
pointerEvents: "auto",
color: "white",
minWidth: isMobile ? "90%" : 800,
minWidth: isMobile ? "90%" : 650,
border: theme.palette.defaultBorder,
},
}}
@@ -10754,77 +10767,120 @@ const releaseToConnectLabel = "Release to Connect"
style={{ zIndex: 5000, position: "absolute", top: 34, right: 34 }}
onClick={(e) => {
e.preventDefault();
setExecutionArgumentModalOpen(false);
setExecutionArgumentModalOpen(false)
}}
>
<CloseIcon style={{ color: "white" }} />
</IconButton>
</Tooltip>
<DialogTitle id="draggable-dialog-title" style={{ cursor: "move", }}>
<span style={{ color: "white" }}>Provide a runtime argument</span>
<span style={{ color: "white" }}>Provide an execution argument</span>
</DialogTitle>
<DialogContent>
<Typography variant="body1" color="textSecondary">
At least one node in this workflow requires a runtime argument ($exec). Please select one below, or provide a custom one in the text field next to the run button.
</Typography>
{/*
<div style={{marginTop: 10, }}>
<Tooltip
color="primary"
title="An argument to be used for execution. This is a variable available to every node in your workflow."
placement="top"
>
<TextField
id="execution_argument_input_field"
style={theme.palette.textFieldStyle}
disabled={workflow.public}
color="secondary"
placeholder={"Execution Argument"}
defaultValue={executionText}
onBlur={(e) => {
setExecutionText(e.target.value);
}}
/>
</Tooltip>
</div>
*/}
<Divider style={{marginTop: 10, marginBottom: 20, }}/>
{availableArguments.length > 0 ?
<div>
<Typography variant="body1" style={{}}>
Previously used arguments:
</Typography>
{availableArguments.map((data) => {
return (
<Paper style={{ padding: 10, marginTop: 10, backgroundColor: theme.palette.platformColor, maxHeight: 70, overflow: "auto", cursor: "pointer", position: "relative", }}
onClick={() => {
setExecutionText(data)
executeWorkflow(data, workflow.start, lastSaved);
setExecutionArgumentModalOpen(false)
{workflow.input_questions !== undefined && workflow.input_questions !== null && workflow.input_questions.length > 0 ?
<div style={{marginBottom: 5, }}>
{workflow.input_questions.map((question, index) => {
return (
<div style={{marginBottom: 5}} key={index}>
{question.name}
<TextField
color="primary"
style={{backgroundColor: theme.palette.inputColor, marginTop: 5, }}
multiLine
maxRows={2}
InputProps={{
style:{
height: "50px",
color: "white",
fontSize: "1em",
},
}}
>
<div style={{height: "100%", width: 2, backgroundColor: "rgba(255, 255, 255, 0.5)", position: "absolute", left: 0, top: 0}} />
<Typography variant="body1" color="textSecondary">
{data}
</Typography>
</Paper>
)
})}
</div>
: null}
fullWidth={true}
placeholder=""
id="emailfield"
margin="normal"
variant="outlined"
onBlur={(e) => {
var newtext = {}
if (executionText.length > 0) {
try {
newtext = JSON.parse(executionText)
// Check if list or object, then make it object only
if (Array.isArray(newtext)) {
newtext = {}
}
} catch (e) {
console.log("Error parsing JSON: ", e)
}
}
<Button
variant="outlined"
color="primary"
onClick={() => {
executeWorkflow(" ", workflow.start, lastSaved);
setExecutionArgumentModalOpen(false);
}}
style={{ marginTop: 20, marginBottom: 20 }}
>
Run anyway
</Button>
newtext[question.value] = e.target.value
setExecutionText(JSON.stringify(newtext))
}}
/>
</div>
)
})}
<Button
variant="outlined"
color="primary"
onClick={() => {
executeWorkflow(executionText, workflow.start, lastSaved);
setExecutionArgumentModalOpen(false)
}}
style={{ marginTop: 20, marginBottom: 20 }}
>
Run Workflow
</Button>
</div>
:
<div>
<Typography variant="body1" color="textSecondary">
At least one node in this workflow requires an execution argument ($exec). Please select one below, or provide a custom one in the text field next to the run button.
</Typography>
<Divider style={{marginTop: 10, marginBottom: 20, }}/>
{availableArguments.length > 0 ?
<div>
<Typography variant="body1" style={{}}>
Previously used arguments:
</Typography>
{availableArguments.map((data) => {
return (
<Paper style={{ padding: 10, marginTop: 10, backgroundColor: theme.palette.platformColor, maxHeight: 70, overflow: "auto", cursor: "pointer", position: "relative", }}
onClick={() => {
setExecutionText(data)
executeWorkflow(data, workflow.start, lastSaved);
setExecutionArgumentModalOpen(false)
}}
>
<div style={{height: "100%", width: 2, backgroundColor: "rgba(255, 255, 255, 0.5)", position: "absolute", left: 0, top: 0}} />
<Typography variant="body1" color="textSecondary">
{data}
</Typography>
</Paper>
)
})}
</div>
: null}
<Button
variant="outlined"
color="primary"
onClick={() => {
executeWorkflow(" ", workflow.start, lastSaved);
setExecutionArgumentModalOpen(false)
}}
style={{ marginTop: 20, marginBottom: 20 }}
>
Run anyway
</Button>
</div>
}
</DialogContent>
</Dialog>
@@ -14811,6 +14867,7 @@ const releaseToConnectLabel = "Release to Connect"
</div>
) : null}
{workflow.triggers[selectedTriggerIndex].parameters[2] !==
undefined &&
workflow.triggers[selectedTriggerIndex].parameters[2].value.includes("email") ? (
@@ -14842,6 +14899,7 @@ const releaseToConnectLabel = "Release to Connect"
}}
/>
) : null}
{workflow.triggers[selectedTriggerIndex].parameters[2] !==
undefined &&
workflow.triggers[
@@ -14874,6 +14932,39 @@ const releaseToConnectLabel = "Release to Connect"
) : null}
</div>
<div style={{marginTop: 20, }} />
<b>Enabled Input-Questions</b>
{workflow.input_questions !== undefined && workflow.input_questions !== null && workflow.input_questions.length > 0 ?
<div>
{workflow.input_questions.map((question, index) => {
const selectionClick = () => {
console.log("Clicked input question: ", question)
console.log("PARAMS: ", workflow.triggers[selectedTriggerIndex].parameters)
}
return (
<div key={index} style={{ display: "flex", cursor: "pointer", }} onClick={() => {
selectionClick()
}}>
<Checkbox
checked={false}
/>
<Typography variant="body2" style={{marginTop: 10, }}>
{question.name}
</Typography>
</div>
)
})}
</div>
:
<div style={{cursor: "pointer", color: "#f85a3e", marginTop: 10, }} onClick={() => {
setEditWorkflowModalOpen(true)
}}>
<Typography variant="body2">No Input-Questions found. Click to add them!</Typography>
</div>
}
</div>
const PipelineSidebar = Object.getOwnPropertyNames(selectedTrigger).length === 0 || workflow.triggers[selectedTriggerIndex] === undefined && selectedTrigger.trigger_type !== "SCHEDULE" ? null :
@@ -16441,7 +16532,7 @@ const releaseToConnectLabel = "Release to Connect"
<PlayArrowIcon style={{ fontSize: isMobile ? 30 : 60 }} />
</Button>
</span>
);
)
return (
<div style={bottomBarStyle}>
+1 -1
View File
@@ -166,7 +166,7 @@ const LoginDialog = (props) => {
} else {
if (responseJson["reason"] === "MFA_REDIRECT") {
setLoginInfo(
"MFA required. Please the 6-digit code from your authenticator"
"MFA required. Please enter the 6-digit code from your authenticator"
);
setMFAField(true);
return;
+34 -11
View File
@@ -976,15 +976,16 @@ const Workflows = (props) => {
}, 1000);
} else if (selectedWorkflowIndexes.length > 0) {
// Do backwards so it doesn't change
toast("Starting deletion of workflows. This might take a while.")
for (var i = selectedWorkflowIndexes.length - 1; i >= 0; i--) {
const workflow = filteredWorkflows[selectedWorkflowIndexes[i]-1]
if (workflow !== undefined && workflow !== null && workflow.id !== undefined && workflow.id !== null) {
deleteWorkflow(workflow.id);
deleteWorkflow(workflow.id, true)
}
}
setTimeout(() => {
getAvailableWorkflows();
getAvailableWorkflows()
}, 1000);
setSelectedWorkflowIndexes([]);
@@ -1115,7 +1116,7 @@ const Workflows = (props) => {
})
}
const getAvailableWorkflows = () => {
const getAvailableWorkflows = (amount) => {
var storageWorkflows = []
try {
const storagewf = localStorage.getItem("workflows")
@@ -1132,7 +1133,12 @@ const Workflows = (props) => {
//console.log("Failed to get workflows from localstorage: ", e)
}
fetch(globalUrl + "/api/v1/workflows", {
var url = `${globalUrl}/api/v1/workflows`
if (amount !== undefined && amount !== null) {
url += `?top=${amount}`
}
fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
@@ -1338,8 +1344,21 @@ const Workflows = (props) => {
setView(tmpView);
}
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
const foundTab = params["top"];
if (foundTab !== null && foundTab !== undefined) {
// Check if it's a number
if (isNaN(foundTab)) {
getAvailableWorkflows()
} else {
getAvailableWorkflows(foundTab)
}
} else {
getAvailableWorkflows()
}
getApps()
getAvailableWorkflows();
getFramework()
}
}, [])
@@ -1836,7 +1855,7 @@ const Workflows = (props) => {
})
}
const deleteWorkflow = (id) => {
const deleteWorkflow = (id, bulk) => {
fetch(globalUrl + "/api/v1/workflows/" + id, {
method: "DELETE",
headers: {
@@ -1850,15 +1869,19 @@ const Workflows = (props) => {
console.log("Status not 200 for setting workflows :O!");
toast("Failed deleting workflow. Do you have access?");
} else {
toast("Deleted workflow " + id);
if (bulk !== true) {
toast("Deleted workflow " + id);
}
}
return response.json();
})
.then(() => {
setTimeout(() => {
getAvailableWorkflows();
}, 1000);
if (bulk !== true) {
setTimeout(() => {
getAvailableWorkflows();
}, 1000);
}
})
.catch((error) => {
toast(error.toString());
@@ -2962,7 +2985,7 @@ const Workflows = (props) => {
className={classes.datagrid}
rows={rows}
columns={columns}
pageSize={25}
pageSize={100}
checkboxSelection
autoHeight
density="standard"