#168: Fixed a lot of the tiny annoyances of Oauth2 apps
This commit is contained in:
@@ -311,10 +311,7 @@ const AuthenticationOauth2 = (props) => {
|
|||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<span style={{}}>
|
<span style={{}}>
|
||||||
<b>
|
Oauth2 requires a client ID and secret to authenticate, defined in the remote system. Your redirect URL is <b>https://shuffler.io/set_authentication</b>.
|
||||||
Oauth2 requires a client ID and secret to authenticate. This is
|
|
||||||
usually made in the remote system.
|
|
||||||
</b>
|
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="norefferer"
|
rel="norefferer"
|
||||||
@@ -452,32 +449,6 @@ const AuthenticationOauth2 = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{allscopes.length === 0 ? null : (
|
|
||||||
<Select
|
|
||||||
multiple
|
|
||||||
value={selectedScopes}
|
|
||||||
style={{
|
|
||||||
backgroundColor: theme.palette.inputColor,
|
|
||||||
color: "white",
|
|
||||||
}}
|
|
||||||
onChange={(e) => {
|
|
||||||
handleScopeChange(e);
|
|
||||||
}}
|
|
||||||
fullWidth
|
|
||||||
input={<Input id="select-multiple-native" />}
|
|
||||||
renderValue={(selected) => selected.join(", ")}
|
|
||||||
MenuProps={MenuProps}
|
|
||||||
>
|
|
||||||
{allscopes.map((data, index) => {
|
|
||||||
return (
|
|
||||||
<MenuItem key={index} value={data}>
|
|
||||||
<Checkbox checked={selectedScopes.indexOf(data) > -1} />
|
|
||||||
<ListItemText primary={data} />
|
|
||||||
</MenuItem>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Select>
|
|
||||||
)}
|
|
||||||
<TextField
|
<TextField
|
||||||
style={{
|
style={{
|
||||||
marginTop: 20,
|
marginTop: 20,
|
||||||
@@ -489,8 +460,8 @@ const AuthenticationOauth2 = (props) => {
|
|||||||
color: "white",
|
color: "white",
|
||||||
marginLeft: "5px",
|
marginLeft: "5px",
|
||||||
maxWidth: "95%",
|
maxWidth: "95%",
|
||||||
height: 50,
|
|
||||||
fontSize: "1em",
|
fontSize: "1em",
|
||||||
|
height: "50px",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
fullWidth
|
fullWidth
|
||||||
@@ -505,14 +476,15 @@ const AuthenticationOauth2 = (props) => {
|
|||||||
style={{
|
style={{
|
||||||
backgroundColor: theme.palette.inputColor,
|
backgroundColor: theme.palette.inputColor,
|
||||||
borderRadius: theme.palette.borderRadius,
|
borderRadius: theme.palette.borderRadius,
|
||||||
|
marginBottom: 10,
|
||||||
}}
|
}}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
marginLeft: "5px",
|
marginLeft: "5px",
|
||||||
maxWidth: "95%",
|
maxWidth: "95%",
|
||||||
height: 50,
|
|
||||||
fontSize: "1em",
|
fontSize: "1em",
|
||||||
|
height: "50px",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
fullWidth
|
fullWidth
|
||||||
@@ -523,6 +495,36 @@ const AuthenticationOauth2 = (props) => {
|
|||||||
//authenticationOption.label = event.target.value
|
//authenticationOption.label = event.target.value
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{allscopes.length === 0 ? null : (
|
||||||
|
<span style={{marginTop: 10}}>
|
||||||
|
Scopes
|
||||||
|
<Select
|
||||||
|
multiple
|
||||||
|
value={selectedScopes}
|
||||||
|
style={{
|
||||||
|
backgroundColor: theme.palette.inputColor,
|
||||||
|
color: "white",
|
||||||
|
padding: 5,
|
||||||
|
}}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleScopeChange(e);
|
||||||
|
}}
|
||||||
|
fullWidth
|
||||||
|
input={<Input id="select-multiple-native" />}
|
||||||
|
renderValue={(selected) => selected.join(", ")}
|
||||||
|
MenuProps={MenuProps}
|
||||||
|
>
|
||||||
|
{allscopes.map((data, index) => {
|
||||||
|
return (
|
||||||
|
<MenuItem key={index} value={data}>
|
||||||
|
<Checkbox checked={selectedScopes.indexOf(data) > -1} />
|
||||||
|
<ListItemText primary={data} />
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<Button
|
<Button
|
||||||
@@ -532,7 +534,7 @@ const AuthenticationOauth2 = (props) => {
|
|||||||
borderRadius: theme.palette.borderRadius,
|
borderRadius: theme.palette.borderRadius,
|
||||||
}}
|
}}
|
||||||
disabled={
|
disabled={
|
||||||
clientSecret.length === 0 || clientId.length === 0 || buttonClicked
|
clientSecret.length === 0 || clientId.length === 0 || buttonClicked || selectedScopes.length === 0
|
||||||
}
|
}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
fullWidth
|
fullWidth
|
||||||
|
|||||||
@@ -978,9 +978,14 @@ const ParsedAction = (props) => {
|
|||||||
return helperText
|
return helperText
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log("D: ", selectedAction)
|
console.log("AUTH: ", authenticationType)
|
||||||
//console.log("DESC: ", selectedAction.description)
|
if (authenticationType.type === "oauth2") {
|
||||||
//console.log("DESC2: ", selectedApp.description)
|
return (
|
||||||
|
<Typography variant="body1" color="textSecondary" style={{marginTop: 15}}>
|
||||||
|
You must authenticate before using oauth2 apps.
|
||||||
|
</Typography>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Issue #40 - selectedActionParameters not reset
|
// FIXME: Issue #40 - selectedActionParameters not reset
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import {
|
|||||||
CircularProgress,
|
CircularProgress,
|
||||||
Chip,
|
Chip,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
LockOpen as LockOpenIcon,
|
LockOpen as LockOpenIcon,
|
||||||
FileCopy as FileCopyIcon,
|
FileCopy as FileCopyIcon,
|
||||||
@@ -2202,7 +2203,8 @@ const AppCreator = (props) => {
|
|||||||
//console.log("Option: ", authenticationOption)
|
//console.log("Option: ", authenticationOption)
|
||||||
//console.log("Location: ", parameterLocation)
|
//console.log("Location: ", parameterLocation)
|
||||||
//console.log("Name: ", parameterName)
|
//console.log("Name: ", parameterName)
|
||||||
const extraKeys = (
|
//const extraKeys = authenticationOption === "Oauth2" ? null :
|
||||||
|
const extraKeys =
|
||||||
<div style={{ marginTop: 50, marginRight: 25, }}>
|
<div style={{ marginTop: 50, marginRight: 25, }}>
|
||||||
<div style={{ display: "flex" }}>
|
<div style={{ display: "flex" }}>
|
||||||
<Typography variant="body1">Extra authentication</Typography>
|
<Typography variant="body1">Extra authentication</Typography>
|
||||||
@@ -2367,7 +2369,7 @@ const AppCreator = (props) => {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
);
|
//);
|
||||||
|
|
||||||
const jwtAuth =
|
const jwtAuth =
|
||||||
authenticationOption === "JWT" ? (
|
authenticationOption === "JWT" ? (
|
||||||
@@ -2417,7 +2419,15 @@ const AppCreator = (props) => {
|
|||||||
color="textSecondary"
|
color="textSecondary"
|
||||||
style={{ marginTop: 10 }}
|
style={{ marginTop: 10 }}
|
||||||
>
|
>
|
||||||
Base Authorization URL
|
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
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
color="textSecondary"
|
||||||
|
style={{ marginTop: 10 }}
|
||||||
|
>
|
||||||
|
Base Authorization URL for Oauth2
|
||||||
</Typography>
|
</Typography>
|
||||||
<TextField
|
<TextField
|
||||||
required
|
required
|
||||||
@@ -2430,6 +2440,26 @@ const AppCreator = (props) => {
|
|||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={parameterName}
|
value={parameterName}
|
||||||
onChange={(e) => setParameterName(e.target.value)}
|
onChange={(e) => setParameterName(e.target.value)}
|
||||||
|
onBlur={(event) => {
|
||||||
|
var tmpstring = event.target.value.trim();
|
||||||
|
|
||||||
|
if (
|
||||||
|
tmpstring.length > 4 &&
|
||||||
|
!tmpstring.startsWith("http") &&
|
||||||
|
!tmpstring.startsWith("ftp")
|
||||||
|
) {
|
||||||
|
alert.error("Auth URL must start with http(s)://");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmpstring.includes("?")) {
|
||||||
|
var newtmp = tmpstring.split("?")
|
||||||
|
if (tmpstring.length > 1) {
|
||||||
|
tmpstring = newtmp[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setParameterName(tmpstring)
|
||||||
|
}}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
classes: {
|
classes: {
|
||||||
notchedOutline: classes.notchedOutline,
|
notchedOutline: classes.notchedOutline,
|
||||||
@@ -2444,7 +2474,7 @@ const AppCreator = (props) => {
|
|||||||
color="textSecondary"
|
color="textSecondary"
|
||||||
style={{ marginTop: 10 }}
|
style={{ marginTop: 10 }}
|
||||||
>
|
>
|
||||||
Token URL
|
Token URL for Oauth2
|
||||||
</Typography>
|
</Typography>
|
||||||
<TextField
|
<TextField
|
||||||
required
|
required
|
||||||
@@ -2456,7 +2486,29 @@ const AppCreator = (props) => {
|
|||||||
margin="normal"
|
margin="normal"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={parameterLocation}
|
value={parameterLocation}
|
||||||
onChange={(e) => setParameterLocation(e.target.value)}
|
onChange={(e) => {
|
||||||
|
setParameterLocation(e.target.value)
|
||||||
|
}}
|
||||||
|
onBlur={(event) => {
|
||||||
|
var tmpstring = event.target.value.trim();
|
||||||
|
|
||||||
|
if (
|
||||||
|
tmpstring.length > 4 &&
|
||||||
|
!tmpstring.startsWith("http") &&
|
||||||
|
!tmpstring.startsWith("ftp")
|
||||||
|
) {
|
||||||
|
alert.error("Token URL must start with http(s)://");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmpstring.includes("?")) {
|
||||||
|
var newtmp = tmpstring.split("?")
|
||||||
|
if (tmpstring.length > 1) {
|
||||||
|
tmpstring = newtmp[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setParameterLocation(tmpstring)
|
||||||
|
}}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
classes: {
|
classes: {
|
||||||
notchedOutline: classes.notchedOutline,
|
notchedOutline: classes.notchedOutline,
|
||||||
@@ -2471,7 +2523,7 @@ const AppCreator = (props) => {
|
|||||||
color="textSecondary"
|
color="textSecondary"
|
||||||
style={{ marginTop: 10 }}
|
style={{ marginTop: 10 }}
|
||||||
>
|
>
|
||||||
Refresh-token URL
|
Refresh-token URL for Oauth2 (Optional)
|
||||||
</Typography>
|
</Typography>
|
||||||
<TextField
|
<TextField
|
||||||
style={{ margin: 0, flex: "1", backgroundColor: inputColor }}
|
style={{ margin: 0, flex: "1", backgroundColor: inputColor }}
|
||||||
@@ -2483,6 +2535,26 @@ const AppCreator = (props) => {
|
|||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={refreshUrl}
|
value={refreshUrl}
|
||||||
onChange={(e) => setRefreshUrl(e.target.value)}
|
onChange={(e) => setRefreshUrl(e.target.value)}
|
||||||
|
onBlur={(event) => {
|
||||||
|
var tmpstring = event.target.value.trim();
|
||||||
|
|
||||||
|
if (
|
||||||
|
tmpstring.length > 4 &&
|
||||||
|
!tmpstring.startsWith("http") &&
|
||||||
|
!tmpstring.startsWith("ftp")
|
||||||
|
) {
|
||||||
|
alert.error("Refresh URL must start with http(s)://");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmpstring.includes("?")) {
|
||||||
|
var newtmp = tmpstring.split("?")
|
||||||
|
if (tmpstring.length > 1) {
|
||||||
|
tmpstring = newtmp[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setRefreshUrl(tmpstring)
|
||||||
|
}}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
@@ -2494,10 +2566,11 @@ const AppCreator = (props) => {
|
|||||||
color="textSecondary"
|
color="textSecondary"
|
||||||
style={{ marginTop: 10 }}
|
style={{ marginTop: 10 }}
|
||||||
>
|
>
|
||||||
Scopes
|
Scopes for Oauth2
|
||||||
</Typography>
|
</Typography>
|
||||||
<ChipInput
|
<ChipInput
|
||||||
style={{}}
|
style={{border: "2px solid #f86a3e", borderRadius: theme.palette.borderRadius,}}
|
||||||
|
required
|
||||||
InputProps={{
|
InputProps={{
|
||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
@@ -2505,7 +2578,7 @@ const AppCreator = (props) => {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
style={{ maxHeight: 80, overflowX: "hidden", overflowY: "auto" }}
|
style={{ maxHeight: 80, overflowX: "hidden", overflowY: "auto" }}
|
||||||
placeholder="Scopes"
|
placeholder="Available Oauth2 Scopes"
|
||||||
color="primary"
|
color="primary"
|
||||||
fullWidth
|
fullWidth
|
||||||
value={oauth2Scopes}
|
value={oauth2Scopes}
|
||||||
@@ -3325,7 +3398,6 @@ const AppCreator = (props) => {
|
|||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setActionField("url", e.target.value);
|
setActionField("url", e.target.value);
|
||||||
setUrlPath(e.target.value);
|
setUrlPath(e.target.value);
|
||||||
console.log(e.target.value);
|
|
||||||
}}
|
}}
|
||||||
helperText={
|
helperText={
|
||||||
<span style={{ color: "white", marginBottom: "2px" }}>
|
<span style={{ color: "white", marginBottom: "2px" }}>
|
||||||
@@ -3404,6 +3476,23 @@ const AppCreator = (props) => {
|
|||||||
if (request.header !== undefined && request.header !== null) {
|
if (request.header !== undefined && request.header !== null) {
|
||||||
var headers = [];
|
var headers = [];
|
||||||
for (let [key, value] of Object.entries(request.header)) {
|
for (let [key, value] of Object.entries(request.header)) {
|
||||||
|
if (value === undefined) {
|
||||||
|
if (key.includes(":")) {
|
||||||
|
const keysplit = key.split(":")
|
||||||
|
key = keysplit[0].trim()
|
||||||
|
value = keysplit[1].trim()
|
||||||
|
|
||||||
|
} else if (key.includes("=")) {
|
||||||
|
const keysplit = key.split("=")
|
||||||
|
key = keysplit[0].trim()
|
||||||
|
value = keysplit[1].trim()
|
||||||
|
|
||||||
|
} else {
|
||||||
|
alert.error("Removed key: ", key)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
parameterName !== undefined &&
|
parameterName !== undefined &&
|
||||||
key.toLowerCase() === parameterName.toLowerCase()
|
key.toLowerCase() === parameterName.toLowerCase()
|
||||||
@@ -3411,17 +3500,14 @@ const AppCreator = (props) => {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (key === "Authorization") {
|
||||||
key === "Authorization" &&
|
|
||||||
authenticationOption === "Bearer auth"
|
|
||||||
) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
headers += key + "=" + value + "\n";
|
headers += key + "=" + value + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
setActionField("headers", headers);
|
setActionField("headers", headers.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.body !== undefined && request.body !== null) {
|
if (request.body !== undefined && request.body !== null) {
|
||||||
@@ -3503,6 +3589,15 @@ const AppCreator = (props) => {
|
|||||||
|
|
||||||
// Found that dashes in the URL doesn't work
|
// Found that dashes in the URL doesn't work
|
||||||
parsedurl = parsedurl.replace("-", "_")
|
parsedurl = parsedurl.replace("-", "_")
|
||||||
|
console.log("Actions: ", actions)
|
||||||
|
|
||||||
|
if (baseUrl.length === 0 && parsedurl.includes("http")) {
|
||||||
|
const newurl = new URL(encodeURI(parsedurl))
|
||||||
|
newurl.searchParams.delete(parameterName)
|
||||||
|
console.log("New url: ", newurl)
|
||||||
|
parsedurl = newurl.pathname
|
||||||
|
setBaseUrl(newurl.origin)
|
||||||
|
}
|
||||||
|
|
||||||
if (event.target.value !== parsedurl) {
|
if (event.target.value !== parsedurl) {
|
||||||
setUrlPath(parsedurl);
|
setUrlPath(parsedurl);
|
||||||
@@ -3635,7 +3730,7 @@ const AppCreator = (props) => {
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
color="primary"
|
color="primary"
|
||||||
variant="outlined"
|
variant={urlPath.length > 0 ? "contained" : "outlined"}
|
||||||
style={{ borderRadius: "0px" }}
|
style={{ borderRadius: "0px" }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
//console.log(urlPathQueries)
|
//console.log(urlPathQueries)
|
||||||
@@ -4353,7 +4448,7 @@ const AppCreator = (props) => {
|
|||||||
<Button
|
<Button
|
||||||
color="primary"
|
color="primary"
|
||||||
style={{ marginTop: "20px", borderRadius: "0px" }}
|
style={{ marginTop: "20px", borderRadius: "0px" }}
|
||||||
variant="outlined"
|
variant={actions.length === 0 ? "contained" : "outlined"}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setCurrentAction({
|
setCurrentAction({
|
||||||
name: "",
|
name: "",
|
||||||
@@ -4850,6 +4945,7 @@ const AppCreator = (props) => {
|
|||||||
if (tmpstring.endsWith("/")) {
|
if (tmpstring.endsWith("/")) {
|
||||||
tmpstring = tmpstring.slice(0, -1);
|
tmpstring = tmpstring.slice(0, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
tmpstring.length > 4 &&
|
tmpstring.length > 4 &&
|
||||||
!tmpstring.startsWith("http") &&
|
!tmpstring.startsWith("http") &&
|
||||||
@@ -4858,7 +4954,12 @@ const AppCreator = (props) => {
|
|||||||
alert.error("URL must start with http(s)://");
|
alert.error("URL must start with http(s)://");
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (authenticationOption === "No authentication" &&
|
if (tmpstring.includes("?")) {
|
||||||
|
var newtmp = tmpstring.split("?")
|
||||||
|
if (tmpstring.length > 1) {
|
||||||
|
tmpstring = newtmp[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setBaseUrl(tmpstring);
|
setBaseUrl(tmpstring);
|
||||||
}}
|
}}
|
||||||
@@ -4866,6 +4967,13 @@ const AppCreator = (props) => {
|
|||||||
<div style={{padding: 25, border: "2px solid rgba(255,255,255,0.7)", borderRadius: theme.palette.borderRadius, }}>
|
<div style={{padding: 25, border: "2px solid rgba(255,255,255,0.7)", borderRadius: theme.palette.borderRadius, }}>
|
||||||
<FormControl style={{ }} variant="outlined">
|
<FormControl style={{ }} variant="outlined">
|
||||||
<Typography variant="h6">Authentication</Typography>
|
<Typography variant="h6">Authentication</Typography>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
href="https://shuffler.io/docs/app_creation#authentication"
|
||||||
|
style={{ textDecoration: "none", color: "#f85a3e" }}
|
||||||
|
>
|
||||||
|
Learn more about app authentication
|
||||||
|
</a>
|
||||||
<Select
|
<Select
|
||||||
fullWidth
|
fullWidth
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
@@ -4875,6 +4983,14 @@ const AppCreator = (props) => {
|
|||||||
} else {
|
} else {
|
||||||
setAuthenticationRequired(true);
|
setAuthenticationRequired(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.target.value === "Oauth2") {
|
||||||
|
if (parameterLocation === "Header") {
|
||||||
|
setParameterLocation("")
|
||||||
|
}
|
||||||
|
|
||||||
|
setExtraAuth([])
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
value={authenticationOption}
|
value={authenticationOption}
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
Reference in New Issue
Block a user