#168: Fixed a lot of the tiny annoyances of Oauth2 apps

This commit is contained in:
frikky
2021-12-31 01:01:36 +01:00
parent 15fc6f5bcb
commit e386709118
3 changed files with 177 additions and 54 deletions
+35 -33
View File
@@ -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
+8 -3
View File
@@ -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 (
+134 -18
View File
@@ -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={{