diff --git a/frontend/src/components/Oauth2Auth.jsx b/frontend/src/components/Oauth2Auth.jsx
index 204af1c6..b70e536a 100755
--- a/frontend/src/components/Oauth2Auth.jsx
+++ b/frontend/src/components/Oauth2Auth.jsx
@@ -93,10 +93,10 @@ const AuthenticationOauth2 = (props) => {
appAuthentication,
setSelectedAction,
setNewAppAuth,
- isCloud,
- autoAuth,
- authButtonOnly,
- isLoggedIn,
+ isCloud,
+ autoAuth,
+ authButtonOnly,
+ isLoggedIn,
} = props;
let navigate = useNavigate();
@@ -297,15 +297,74 @@ const AuthenticationOauth2 = (props) => {
const handleOauth2Request = (client_id, client_secret, oauth_url, scopes, admin_consent, prompt) => {
- setButtonClicked(true);
- //console.log("SCOPES: ", scopes);
+
+ if ((authenticationType.redirect_uri === undefined || authenticationType.redirect_uri === null || authenticationType.redirect_uri.length === 0) && (authenticationType.token_uri !== undefined && authenticationType.token_uri !== null && authenticationType.token_uri.length > 0)) {
+ console.log("No redirect URI found, and token URI found. Assuming client credentials flow and saving directly in the database")
+
+ // Find app.configuration=true fields in the app.paramters
+ var parsedFields = [{
+ "key": "client_id",
+ "value": client_id,
+ },
+ {
+ "key": "client_secret",
+ "value": client_secret,
+ },
+ {
+ "key": "scope",
+ "value": scopes.join(","),
+ },
+ {
+ "key": "token_uri",
+ "value": authenticationType.token_uri,
+ }]
+
+ // Not necessary yet to do something like this due to not showing the fields anyway
+ /*
+ if (selectedApp.parameters !== undefined && selectedApp.parameters !== null && selectedApp.parameters.length > 0) {
+
+ for (var i = 0; i < selectedApp.parameters.length; i++) {
+ if (selectedApp.parameters[i].configuration !== true) {
+ continue
+ }
+
+ console.log("Found configuration field: ", selectedApp.parameters[i].key, " with example: ", selectedApp.parameters[i].example)
+ parsedFields.push({
+ "key": selectedApp.parameters[i].key,
+ "value": selectedApp.parameters[i].example,
+ })
+ }
+ }
+ */
+
+
+ const appAuthData = {
+ "label": "OAuth2 for " + selectedApp.name,
+ "app": {
+ "id": selectedApp.id,
+ "name": selectedApp.name,
+ "version": selectedApp.version,
+ "large_image": selectedApp.large_image,
+ },
+ "fields": parsedFields,
+ "type": "oauth2-app",
+ "reference_workflow": workflowId,
+ }
+ setNewAppAuth(appAuthData)
+
+ return
+ }
+
+
+ setButtonClicked(true);
+ //console.log("SCOPES: ", scopes);
client_id = client_id.trim()
client_secret = client_secret.trim()
oauth_url = oauth_url.trim()
- var resources = "";
- if (scopes !== undefined && (scopes !== null) & (scopes.length > 0)) {
+ var resources = "";
+ if (scopes !== undefined && (scopes !== null) & (scopes.length > 0)) {
console.log("IN scope 1")
if (offlineAccess === true && !scopes.includes("offline_access")) {
@@ -324,26 +383,26 @@ const AuthenticationOauth2 = (props) => {
//console.log("AUTH: ", authenticationType)
//console.log("SCOPES2: ", resources)
const redirectUri = `${window.location.protocol}//${window.location.host}/set_authentication`;
- const workflowId = workflow !== undefined ? workflow.id : "";
+ const workflowId = workflow !== undefined ? workflow.id : "";
var state = `workflow_id%3D${workflowId}%26reference_action_id%3d${selectedAction.app_id}%26app_name%3d${selectedAction.app_name}%26app_id%3d${selectedAction.app_id}%26app_version%3d${selectedAction.app_version}%26authentication_url%3d${authentication_url}%26scope%3d${resources}%26client_id%3d${client_id}%26client_secret%3d${client_secret}`;
- // This is to make sure authorization can be handled WITHOUT being logged in,
- // kind of making it act like an api key
- // https://shuffler.io/authorization -> 3rd party integration auth
- const urlParams = new URLSearchParams(window.location.search);
- const userAuth = urlParams.get("authorization");
- if (userAuth !== undefined && userAuth !== null && userAuth.length > 0) {
- console.log("Adding authorization from user side")
- state += `%26authorization%3d${userAuth}`;
- }
+ // This is to make sure authorization can be handled WITHOUT being logged in,
+ // kind of making it act like an api key
+ // https://shuffler.io/authorization -> 3rd party integration auth
+ const urlParams = new URLSearchParams(window.location.search);
+ const userAuth = urlParams.get("authorization");
+ if (userAuth !== undefined && userAuth !== null && userAuth.length > 0) {
+ console.log("Adding authorization from user side")
+ state += `%26authorization%3d${userAuth}`;
+ }
- // Check for org_id
- const orgId = urlParams.get("org_id");
- if (orgId !== undefined && orgId !== null && orgId.length > 0) {
- console.log("Adding org_id from user side")
- state += `%26org_id%3d${orgId}`;
- }
+ // Check for org_id
+ const orgId = urlParams.get("org_id");
+ if (orgId !== undefined && orgId !== null && orgId.length > 0) {
+ console.log("Adding org_id from user side")
+ state += `%26org_id%3d${orgId}`;
+ }
if (oauth_url !== undefined && oauth_url !== null && oauth_url.length > 0) {
state += `%26oauth_url%3d${oauth_url}`;
@@ -363,7 +422,7 @@ const AuthenticationOauth2 = (props) => {
// No prompt forcing
//var url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&prompt=login&scope=${resources}&state=${state}&access_type=offline`;
- var defaultPrompt = "login"
+ var defaultPrompt = "login"
if (prompt !== undefined && prompt !== null && prompt.length > 0) {
defaultPrompt = prompt
}
@@ -798,6 +857,7 @@ const AuthenticationOauth2 = (props) => {
}}
fullWidth
color="primary"
+ label={"Client ID"}
placeholder={"Client ID"}
onChange={(event) => {
setClientId(event.target.value);
@@ -816,20 +876,22 @@ const AuthenticationOauth2 = (props) => {
}}
fullWidth
color="primary"
+ label={"Client Secret"}
placeholder={"Client Secret"}
onChange={(event) => {
setClientSecret(event.target.value);
//authenticationOption.label = event.target.value
}}
/>
+ {allscopes.length === 0 ? null : "Scopes"}
{allscopes.length === 0 ? null : (
- Scopes
-
-
- {
- setOfflineAccess(!offlineAccess)
- }}/>
-
-
+
+ {((authenticationType.redirect_uri === undefined || authenticationType.redirect_uri === null || authenticationType.redirect_uri.length === 0) && (authenticationType.token_uri !== undefined && authenticationType.token_uri !== null && authenticationType.token_uri.length > 0)) ? null :
+
+
+ {
+ setOfflineAccess(!offlineAccess)
+ }}/>
+
+
+ }
)}
@@ -882,19 +947,14 @@ const AuthenticationOauth2 = (props) => {
variant="contained"
fullWidth
onClick={() => {
- handleOauth2Request(
- clientId,
- clientSecret,
- oauthUrl,
- selectedScopes
- );
+ handleOauth2Request(clientId, clientSecret, oauthUrl, selectedScopes);
}}
color="primary"
>
{buttonClicked ? (
) : (
- "Manually Authenticate"
+ "Authenticate"
)}
diff --git a/frontend/src/components/Searchfield.jsx b/frontend/src/components/Searchfield.jsx
index 7edef2ca..726a2fa8 100644
--- a/frontend/src/components/Searchfield.jsx
+++ b/frontend/src/components/Searchfield.jsx
@@ -81,7 +81,7 @@ const SearchField = props => {
style: {
color: "white",
minWidth: 750,
- height: 685,
+ height: 785,
borderRadius: 16,
border: "1px solid var(--Container-Stroke, #494949)",
background: "var(--Container, #000000)",
diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx
index ad643a9b..27ba8f18 100755
--- a/frontend/src/views/AngularWorkflow.jsx
+++ b/frontend/src/views/AngularWorkflow.jsx
@@ -4593,7 +4593,6 @@ const AngularWorkflow = (defaultprops) => {
}
}
- console.log("NODE: ", nodedata)
if (nodedata.decorator !== true && nodedata.attachedTo === undefined) {
var newdata = JSON.parse(JSON.stringify(nodedata))
newdata.large_image = ""
diff --git a/frontend/src/views/AppCreator.jsx b/frontend/src/views/AppCreator.jsx
index 980e10c2..4cd2dfc7 100755
--- a/frontend/src/views/AppCreator.jsx
+++ b/frontend/src/views/AppCreator.jsx
@@ -374,8 +374,8 @@ const AppCreator = (defaultprops) => {
"API key",
"Bearer auth",
"Basic auth",
- "Oauth2",
"JWT",
+ "Oauth2",
];
const apikeySelection = ["Header", "Query"];
@@ -411,6 +411,7 @@ const AppCreator = (defaultprops) => {
const [appBuilding, setAppBuilding] = useState(false);
const [fileDownloadEnabled, setFileDownloadEnabled] = useState(false);
const [actionAmount, setActionAmount] = useState(increaseAmount);
+ const [oauth2Type, setOauth2Type] = useState("application");
const defaultAuth = {
name: "",
type: "header",
@@ -1678,7 +1679,7 @@ const AppCreator = (defaultprops) => {
value.in.length > 0
) {
setParameterName(value.in);
- optionset = true
+ optionset = true
}
} else if (value.scheme === "bearer") {
@@ -1709,24 +1710,24 @@ const AppCreator = (defaultprops) => {
newauth.push({
"name": key,
"type": value.in.toLowerCase(),
- "in": value.in.toLowerCase(),
+ "in": value.in.toLowerCase(),
"example": "",
- })
- } else {
- newauth.push({
- "name": key,
- "type": value.in.toLowerCase(),
- "in": value.in.toLowerCase(),
- "example": "",
- })
- }
+ })
+ } else {
+ newauth.push({
+ "name": key,
+ "type": value.in.toLowerCase(),
+ "in": value.in.toLowerCase(),
+ "example": "",
+ })
+ }
if (value.description !== undefined && value.description !== null && value.description.length > 0) {
- // Don't want a real description - just the ones we're replacing with
- if ((value.description.split(" ").length - 1) <= 2) {
- setRefreshUrl(value.description)
- }
- }
+ // Don't want a real description - just the ones we're replacing with
+ if ((value.description.split(" ").length - 1) <= 2) {
+ setRefreshUrl(value.description)
+ }
+ }
} else if (value.scheme === "basic") {
setAuthenticationOption("Basic auth");
@@ -1734,15 +1735,15 @@ const AppCreator = (defaultprops) => {
optionset = true
} else if (value.scheme === "oauth2") {
- setAuthenticationOption("Oauth2");
- setAuthenticationRequired(true);
- optionset = true
+ setAuthenticationOption("Oauth2");
+ setAuthenticationRequired(true);
+ optionset = true
} else if (value.type === "oauth2" || key === "Oauth2" || key === "Oauth2c" || (key !== undefined && key !== null && key.toLowerCase().includes("oauth2"))) {
//toast("Can't handle Oauth2 auth yet.")
setAuthenticationOption("Oauth2");
setAuthenticationRequired(true);
- optionset = true
+ optionset = true
//console.log("FLOW-1: ", value)
const flowkey = value.flow === undefined ? "flows" : "flow";
@@ -1754,12 +1755,11 @@ const AppCreator = (defaultprops) => {
//console.log("FLOW2: ", value[flowkey][basekey])
if (value[flowkey] !== undefined && value[flowkey][basekey] !== undefined
) {
- if (
- value[flowkey][basekey].authorizationUrl !== undefined &&
- parameterName.length === 0
- ) {
- setParameterName(value[flowkey][basekey].authorizationUrl);
- }
+ if (value[flowkey][basekey].authorizationUrl !== undefined && parameterName.length === 0) {
+ setParameterName(value[flowkey][basekey].authorizationUrl);
+ } else {
+ setOauth2Type("application")
+ }
var tokenUrl = "";
if (value[flowkey][basekey].tokenUrl !== undefined) {
@@ -2846,7 +2846,6 @@ const AppCreator = (defaultprops) => {
style={{ margin: 0, flex: "1", backgroundColor: inputColor }}
fullWidth={true}
placeholder="/security/user/authenticate"
- type="name"
id="standard-required"
margin="normal"
variant="outlined"
@@ -2866,6 +2865,40 @@ const AppCreator = (defaultprops) => {
},
}}
/>
+
+ Optional: Authentication queries
+
+ {/*
+
+ Must use 'key=value&key=value' format
+
+ }
+ onBlur={(e) => {
+ //setParameterName(e.target.value)
+ }}
+ InputProps={{
+ classes: {
+ notchedOutline: classes.notchedOutline,
+ },
+ style: {
+ color: "white",
+ },
+ }}
+ />
+ */}
) : null;
@@ -2878,56 +2911,64 @@ const AppCreator = (defaultprops) => {
color="textSecondary"
style={{ marginTop: 10 }}
>
- Find the Authorization URL, Token URL and scopes in question for the API. Ensure the app in question is pointed at https://shuffler.io/set_authentication
+ {oauth2Type === "delegated" ?
+ "Find the Authorization URL, Token URL and scopes in question for the API. Ensure your app in the service uses redirect url https://shuffler.io/set_authentication"
+ :
+ "Find the Token URL and scopes in question for the API"
+ }
-
- Base Authorization URL for Oauth2
-
- setParameterName(e.target.value)}
+ {oauth2Type === "delegated" ?
+
+
+ Base Authorization URL for Oauth2
+
+ setParameterName(e.target.value)}
onBlur={(event) => {
- var tmpstring = event.target.value.trim();
+ var tmpstring = event.target.value.trim();
- if (
- tmpstring.length > 4 &&
- !tmpstring.startsWith("http") &&
- !tmpstring.startsWith("ftp")
- ) {
- toast("Auth URL must start with http(s)://");
- }
+ if (
+ tmpstring.length > 4 &&
+ !tmpstring.startsWith("http") &&
+ !tmpstring.startsWith("ftp")
+ ) {
+ toast("Auth URL must start with http(s)://");
+ }
- if (tmpstring.includes("?")) {
- var newtmp = tmpstring.split("?")
- if (tmpstring.length > 1) {
- tmpstring = newtmp[0]
- }
- }
+ if (tmpstring.includes("?")) {
+ var newtmp = tmpstring.split("?")
+ if (tmpstring.length > 1) {
+ tmpstring = newtmp[0]
+ }
+ }
- setParameterName(tmpstring)
- }}
- InputProps={{
- classes: {
- notchedOutline: classes.notchedOutline,
- },
- style: {
- color: "white",
- },
- }}
- />
+ setParameterName(tmpstring)
+ }}
+ InputProps={{
+ classes: {
+ notchedOutline: classes.notchedOutline,
+ },
+ style: {
+ color: "white",
+ },
+ }}
+ />
+
+ : null}
{
},
}}
/>
-
- Refresh-token URL for Oauth2 (Optional)
-
- setRefreshUrl(e.target.value)}
- onBlur={(event) => {
- var tmpstring = event.target.value.trim();
+ {oauth2Type === "delegated" ?
+
+
+ Refresh-token URL for Oauth2 (Optional)
+
+ setRefreshUrl(e.target.value)}
+ onBlur={(event) => {
+ var tmpstring = event.target.value.trim();
- if (
- tmpstring.length > 4 &&
- !tmpstring.startsWith("http") &&
- !tmpstring.startsWith("ftp")
- ) {
- toast("Refresh URL must start with http(s)://");
- }
+ if (
+ tmpstring.length > 4 &&
+ !tmpstring.startsWith("http") &&
+ !tmpstring.startsWith("ftp")
+ ) {
+ toast("Refresh URL must start with http(s)://");
+ }
- if (tmpstring.includes("?")) {
- var newtmp = tmpstring.split("?")
- if (tmpstring.length > 1) {
- tmpstring = newtmp[0]
- }
- }
+ if (tmpstring.includes("?")) {
+ var newtmp = tmpstring.split("?")
+ if (tmpstring.length > 1) {
+ tmpstring = newtmp[0]
+ }
+ }
- setRefreshUrl(tmpstring)
- }}
- InputProps={{
- style: {
- color: "white",
- },
- }}
- />
-
- Scopes for Oauth2
-
-
+
+ : null}
+
+ Scopes for Oauth2
+
+ {
setOauth2Scopes(chips)
setUpdate(Math.random())
}}
- />
+ />
) : null;
@@ -5865,6 +5910,7 @@ const AppCreator = (defaultprops) => {
}}
/>